summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/drivers/hid')
-rw-r--r--ANDROID_3.4.5/drivers/hid/Kconfig670
-rw-r--r--ANDROID_3.4.5/drivers/hid/Makefile92
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-a4tech.c163
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-apple.c562
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-axff.c211
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-belkin.c103
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-cherry.c86
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-chicony.c85
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-core.c2254
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-cypress.c159
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-debug.c1104
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-dr.c313
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-elecom.c57
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-emsff.c167
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-ezkey.c93
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-gaff.c192
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-gyration.c105
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-holtekff.c241
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-hyperv.c587
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-ids.h797
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-input.c1255
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-kensington.c63
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-keytouch.c66
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-kye.c435
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-lcpower.c70
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-lg.c508
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-lg.h30
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-lg2ff.c116
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-lg3ff.c175
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-lg4ff.c488
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-lgff.c176
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-magicmouse.c615
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-microsoft.c230
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-monterey.c80
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-multitouch.c1081
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-ntrig.c1042
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-ortek.c66
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-petalynx.c120
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-picolcd.c2752
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-pl.c232
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-primax.c117
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-prodikeys.c911
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-arvo.c453
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-arvo.h85
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-common.c69
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-common.h23
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-isku.c487
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-isku.h147
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-kone.c913
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-kone.h226
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-koneplus.c811
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-koneplus.h218
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-kovaplus.c731
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-kovaplus.h148
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-pyra.c704
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat-pyra.h172
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-roccat.c451
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-saitek.c70
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-samsung.c213
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-sjoy.c195
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-sony.c246
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-speedlink.c89
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-sunplus.c80
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-tivo.c90
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-tmff.c277
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-topseed.c92
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-twinhan.c147
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-uclogic.c427
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-wacom.c697
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-waltop.c666
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-wiimote-core.c1318
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-wiimote-debug.c221
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-wiimote-ext.c752
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-wiimote.h208
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-zpff.c168
-rw-r--r--ANDROID_3.4.5/drivers/hid/hid-zydacron.c235
-rw-r--r--ANDROID_3.4.5/drivers/hid/hidraw.c570
-rw-r--r--ANDROID_3.4.5/drivers/hid/uhid.c572
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/Kconfig84
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/Makefile20
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/hid-core.c1609
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/hid-pidff.c1323
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/hid-quirks.c331
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/hiddev.c938
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/usbhid.h107
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/usbkbd.c411
-rw-r--r--ANDROID_3.4.5/drivers/hid/usbhid/usbmouse.c244
87 files changed, 0 insertions, 36707 deletions
diff --git a/ANDROID_3.4.5/drivers/hid/Kconfig b/ANDROID_3.4.5/drivers/hid/Kconfig
deleted file mode 100644
index 1283fa3b..00000000
--- a/ANDROID_3.4.5/drivers/hid/Kconfig
+++ /dev/null
@@ -1,670 +0,0 @@
-#
-# HID driver configuration
-#
-menuconfig HID_SUPPORT
- bool "HID Devices"
- depends on INPUT
- default y
- ---help---
- Say Y here to get to see options for various computer-human interface
- device drivers. This option alone does not add any kernel code.
-
- If you say N, all options in this submenu will be skipped and disabled.
-
-if HID_SUPPORT
-
-config HID
- tristate "Generic HID support"
- depends on INPUT
- default y
- ---help---
- A human interface device (HID) is a type of computer device that
- interacts directly with and takes input from humans. The term "HID"
- most commonly used to refer to the USB-HID specification, but other
- devices (such as, but not strictly limited to, Bluetooth) are
- designed using HID specification (this involves certain keyboards,
- mice, tablets, etc). This option compiles into kernel the generic
- HID layer code (parser, usages, etc.), which can then be used by
- transport-specific HID implementation (like USB or Bluetooth).
-
- For docs and specs, see http://www.usb.org/developers/hidpage/
-
- If unsure, say Y.
-
-config HID_BATTERY_STRENGTH
- bool
- depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
- default n
-
-config HIDRAW
- bool "/dev/hidraw raw HID device support"
- depends on HID
- ---help---
- Say Y here if you want to support HID devices (from the USB
- specification standpoint) that aren't strictly user interface
- devices, like monitor controls and Uninterruptable Power Supplies.
-
- This module supports these devices separately using a separate
- event interface on /dev/hidraw.
-
- There is also a /dev/hiddev configuration option in the USB HID
- configuration menu. In comparison to hiddev, this device does not process
- the hid events at all (no parsing, no lookups). This lets applications
- to work on raw hid events when they want to, and avoid using transport-specific
- userspace libhid/libusb libraries.
-
- If unsure, say Y.
-
-config UHID
- tristate "User-space I/O driver support for HID subsystem"
- depends on HID
- default n
- ---help---
- Say Y here if you want to provide HID I/O Drivers from user-space.
- This allows to write I/O drivers in user-space and feed the data from
- the device into the kernel. The kernel parses the HID reports, loads the
- corresponding HID Device Driver or provides input devices on top of your
- user-space device.
-
- This driver cannot be used to parse HID-reports in user-space and write
- special HID-drivers. You should use hidraw for that.
- Instead, this driver allows to write the transport-layer driver in
- user-space like USB-HID and Bluetooth-HID do in kernel-space.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called uhid.
-
-source "drivers/hid/usbhid/Kconfig"
-
-menu "Special HID drivers"
- depends on HID
-
-config HID_A4TECH
- tristate "A4 tech mice" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for A4 tech X5 and WOP-35 / Trust 450L mice.
-
-config HID_ACRUX
- tristate "ACRUX game controller support"
- depends on USB_HID
- ---help---
- Say Y here if you want to enable support for ACRUX game controllers.
-
-config HID_ACRUX_FF
- bool "ACRUX force feedback support"
- depends on HID_ACRUX
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you want to enable force feedback support for ACRUX
- game controllers.
-
-config HID_APPLE
- tristate "Apple {i,Power,Mac}Books" if EXPERT
- depends on (USB_HID || BT_HIDP)
- default !EXPERT
- ---help---
- Support for some Apple devices which less or more break
- HID specification.
-
- Say Y here if you want support for keyboards of Apple iBooks, PowerBooks,
- MacBooks, MacBook Pros and Apple Aluminum.
-
-config HID_BELKIN
- tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for Belkin Flip KVM and Wireless keyboard.
-
-config HID_CHERRY
- tristate "Cherry Cymotion keyboard" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for Cherry Cymotion keyboard.
-
-config HID_CHICONY
- tristate "Chicony Tactical pad" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for Chicony Tactical pad.
-
-config HID_PRODIKEYS
- tristate "Prodikeys PC-MIDI Keyboard support"
- depends on USB_HID && SND
- select SND_RAWMIDI
- ---help---
- Support for Prodikeys PC-MIDI Keyboard device support.
- Say Y here to enable support for this device.
- - Prodikeys PC-MIDI keyboard.
- The Prodikeys PC-MIDI acts as a USB Audio device, with one MIDI
- input and one MIDI output. These MIDI jacks appear as
- a sound "card" in the ALSA sound system.
- Note: if you say N here, this device will still function as a basic
- multimedia keyboard, but will lack support for the musical keyboard
- and some additional multimedia keys.
-
-config HID_CYPRESS
- tristate "Cypress mouse and barcode readers" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for cypress mouse and barcode readers.
-
-config HID_DRAGONRISE
- tristate "DragonRise Inc. game controller"
- depends on USB_HID
- ---help---
- Say Y here if you have DragonRise Inc. game controllers.
- These might be branded as:
- - Tesun USB-703
- - Media-tech MT1504 "Rogue"
- - DVTech JS19 "Gear"
- - Defender Game Master
-
-config DRAGONRISE_FF
- bool "DragonRise Inc. force feedback"
- depends on HID_DRAGONRISE
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you want to enable force feedback support for DragonRise Inc.
- game controllers.
-
-config HID_EMS_FF
- tristate "EMS Production Inc. force feedback support"
- depends on USB_HID
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you want to enable force feedback support for devices by
- EMS Production Ltd.
- Currently the following devices are known to be supported:
- - Trio Linker Plus II
-
-config HID_ELECOM
- tristate "ELECOM BM084 bluetooth mouse"
- depends on BT_HIDP
- ---help---
- Support for the ELECOM BM084 (bluetooth mouse).
-
-config HID_EZKEY
- tristate "Ezkey BTC 8193 keyboard" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for Ezkey BTC 8193 keyboard.
-
-config HID_HOLTEK
- tristate "Holtek On Line Grip based game controller support"
- depends on USB_HID
- ---help---
- Say Y here if you have a Holtek On Line Grip based game controller.
-
-config HOLTEK_FF
- bool "Holtek On Line Grip force feedback support"
- depends on HID_HOLTEK
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you have a Holtek On Line Grip based game controller
- and want to have force feedback support for it.
-
-config HID_KEYTOUCH
- tristate "Keytouch HID devices"
- depends on USB_HID
- ---help---
- Support for Keytouch HID devices not fully compliant with
- the specification. Currently supported:
- - Keytouch IEC 60945
-
-config HID_KYE
- tristate "KYE/Genius devices"
- depends on USB_HID
- ---help---
- Support for KYE/Genius devices not fully compliant with HID standard:
- - Ergo Mouse
- - EasyPen i405X tablet
- - MousePen i608X tablet
- - EasyPen M610X tablet
-
-config HID_UCLOGIC
- tristate "UC-Logic"
- depends on USB_HID
- ---help---
- Support for UC-Logic tablets.
-
-config HID_WALTOP
- tristate "Waltop"
- depends on USB_HID
- ---help---
- Support for Waltop tablets.
-
-config HID_GYRATION
- tristate "Gyration remote control"
- depends on USB_HID
- ---help---
- Support for Gyration remote control.
-
-config HID_TWINHAN
- tristate "Twinhan IR remote control"
- depends on USB_HID
- ---help---
- Support for Twinhan IR remote control.
-
-config HID_KENSINGTON
- tristate "Kensington Slimblade Trackball" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for Kensington Slimblade Trackball.
-
-config HID_LCPOWER
- tristate "LC-Power"
- depends on USB_HID
- ---help---
- Support for LC-Power RC1000MCE RF remote control.
-
-config HID_LOGITECH
- tristate "Logitech devices" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for Logitech devices that are not fully compliant with HID standard.
-
-config HID_LOGITECH_DJ
- tristate "Logitech Unifying receivers full support"
- depends on HID_LOGITECH
- default m
- ---help---
- Say Y if you want support for Logitech Unifying receivers and devices.
- Unifying receivers are capable of pairing up to 6 Logitech compliant
- devices to the same receiver. Without this driver it will be handled by
- generic USB_HID driver and all incomming events will be multiplexed
- into a single mouse and a single keyboard device.
-
-config LOGITECH_FF
- bool "Logitech force feedback support"
- depends on HID_LOGITECH
- select INPUT_FF_MEMLESS
- help
- Say Y here if you have one of these devices:
- - Logitech WingMan Cordless RumblePad
- - Logitech WingMan Cordless RumblePad 2
- - Logitech WingMan Force 3D
- - Logitech Formula Force EX
- - Logitech WingMan Formula Force GP
- - Logitech MOMO Force wheel
-
- and if you want to enable force feedback for them.
- Note: if you say N here, this device will still be supported, but without
- force feedback.
-
-config LOGIRUMBLEPAD2_FF
- bool "Logitech RumblePad/Rumblepad 2 force feedback support"
- depends on HID_LOGITECH
- select INPUT_FF_MEMLESS
- help
- Say Y here if you want to enable force feedback support for Logitech
- RumblePad and Rumblepad 2 devices.
-
-config LOGIG940_FF
- bool "Logitech Flight System G940 force feedback support"
- depends on HID_LOGITECH
- select INPUT_FF_MEMLESS
- help
- Say Y here if you want to enable force feedback support for Logitech
- Flight System G940 devices.
-
-config LOGIWHEELS_FF
- bool "Logitech wheels configuration and force feedback support"
- depends on HID_LOGITECH
- select INPUT_FF_MEMLESS
- default LOGITECH_FF
- help
- Say Y here if you want to enable force feedback and range setting
- support for following Logitech wheels:
- - Logitech Driving Force
- - Logitech Driving Force Pro
- - Logitech Driving Force GT
- - Logitech G25
- - Logitech G27
- - Logitech MOMO/MOMO 2
- - Logitech Formula Force EX
-
-config HID_MAGICMOUSE
- tristate "Apple MagicMouse multi-touch support"
- depends on BT_HIDP
- ---help---
- Support for the Apple Magic Mouse multi-touch.
-
- Say Y here if you want support for the multi-touch features of the
- Apple Wireless "Magic" Mouse.
-
-config HID_MICROSOFT
- tristate "Microsoft non-fully HID-compliant devices" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for Microsoft devices that are not fully compliant with HID standard.
-
-config HID_MONTEREY
- tristate "Monterey Genius KB29E keyboard" if EXPERT
- depends on USB_HID
- default !EXPERT
- ---help---
- Support for Monterey Genius KB29E.
-
-config HID_MULTITOUCH
- tristate "HID Multitouch panels"
- depends on USB_HID
- ---help---
- Generic support for HID multitouch panels.
-
- Say Y here if you have one of the following devices:
- - 3M PCT touch screens
- - ActionStar dual touch panels
- - Atmel panels
- - Cando dual touch panels
- - Chunghwa panels
- - CVTouch panels
- - Cypress TrueTouch panels
- - Elo TouchSystems IntelliTouch Plus panels
- - GeneralTouch 'Sensing Win7-TwoFinger' panels
- - GoodTouch panels
- - Hanvon dual touch panels
- - Ilitek dual touch panels
- - IrTouch Infrared USB panels
- - LG Display panels (Dell ST2220Tc)
- - Lumio CrystalTouch panels
- - MosArt dual-touch panels
- - Panasonic multitouch panels
- - PenMount dual touch panels
- - Perixx Peripad 701 touchpad
- - PixArt optical touch screen
- - Pixcir dual touch panels
- - Quanta panels
- - eGalax dual-touch panels, including the Joojoo and Wetab tablets
- - Stantum multitouch panels
- - Touch International Panels
- - Unitec Panels
- - XAT optical touch panels
- - Xiroku optical touch panels
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called hid-multitouch.
-
-config HID_NTRIG
- tristate "N-Trig touch screen"
- depends on USB_HID
- ---help---
- Support for N-Trig touch screen.
-
-config HID_ORTEK
- tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad"
- depends on USB_HID
- ---help---
- There are certain devices which have LogicalMaximum wrong in the keyboard
- usage page of their report descriptor. The most prevailing ones so far
- are manufactured by Ortek, thus the name of the driver. Currently
- supported devices by this driver are
-
- - Ortek PKB-1700
- - Ortek WKB-2000
- - Skycable wireless presenter
-
-config HID_PANTHERLORD
- tristate "Pantherlord/GreenAsia game controller"
- depends on USB_HID
- ---help---
- Say Y here if you have a PantherLord/GreenAsia based game controller
- or adapter.
-
-config PANTHERLORD_FF
- bool "Pantherlord force feedback support"
- depends on HID_PANTHERLORD
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you have a PantherLord/GreenAsia based game controller
- or adapter and want to enable force feedback support for it.
-
-config HID_PETALYNX
- tristate "Petalynx Maxter remote control"
- depends on USB_HID
- ---help---
- Support for Petalynx Maxter remote control.
-
-config HID_PICOLCD
- tristate "PicoLCD (graphic version)"
- depends on USB_HID
- ---help---
- This provides support for Minibox PicoLCD devices, currently
- only the graphical ones are supported.
-
- This includes support for the following device features:
- - Keypad
- - Switching between Firmware and Flash mode
- - EEProm / Flash access (via debugfs)
- Features selectively enabled:
- - Framebuffer for monochrome 256x64 display
- - Backlight control
- - Contrast control
- - General purpose outputs
- Features that are not (yet) supported:
- - IR
-
-config HID_PICOLCD_FB
- bool "Framebuffer support" if EXPERT
- default !EXPERT
- depends on HID_PICOLCD
- depends on HID_PICOLCD=FB || FB=y
- select FB_DEFERRED_IO
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- ---help---
- Provide access to PicoLCD's 256x64 monochrome display via a
- frambuffer device.
-
-config HID_PICOLCD_BACKLIGHT
- bool "Backlight control" if EXPERT
- default !EXPERT
- depends on HID_PICOLCD
- depends on HID_PICOLCD=BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=y
- ---help---
- Provide access to PicoLCD's backlight control via backlight
- class.
-
-config HID_PICOLCD_LCD
- bool "Contrast control" if EXPERT
- default !EXPERT
- depends on HID_PICOLCD
- depends on HID_PICOLCD=LCD_CLASS_DEVICE || LCD_CLASS_DEVICE=y
- ---help---
- Provide access to PicoLCD's LCD contrast via lcd class.
-
-config HID_PICOLCD_LEDS
- bool "GPO via leds class" if EXPERT
- default !EXPERT
- depends on HID_PICOLCD
- depends on HID_PICOLCD=LEDS_CLASS || LEDS_CLASS=y
- ---help---
- Provide access to PicoLCD's GPO pins via leds class.
-
-config HID_PRIMAX
- tristate "Primax non-fully HID-compliant devices"
- depends on USB_HID
- ---help---
- Support for Primax devices that are not fully compliant with the
- HID standard.
-
-config HID_ROCCAT
- tristate "Roccat device support"
- depends on USB_HID
- ---help---
- Support for Roccat devices.
- Say Y here if you have a Roccat mouse or keyboard and want
- support for its special functionalities.
-
-config HID_SAITEK
- tristate "Saitek non-fully HID-compliant devices"
- depends on USB_HID
- ---help---
- Support for Saitek devices that are not fully compliant with the
- HID standard.
-
- Currently only supports the PS1000 controller.
-
-config HID_SAMSUNG
- tristate "Samsung InfraRed remote control or keyboards"
- depends on USB_HID
- ---help---
- Support for Samsung InfraRed remote control or keyboards.
-
-config HID_SONY
- tristate "Sony PS3 controller"
- depends on USB_HID
- ---help---
- Support for Sony PS3 controller.
-
-config HID_SPEEDLINK
- tristate "Speedlink VAD Cezanne mouse support"
- depends on USB_HID
- ---help---
- Support for Speedlink Vicious and Divine Cezanne mouse.
-
-config HID_SUNPLUS
- tristate "Sunplus wireless desktop"
- depends on USB_HID
- ---help---
- Support for Sunplus wireless desktop.
-
-config HID_GREENASIA
- tristate "GreenAsia (Product ID 0x12) game controller support"
- depends on USB_HID
- ---help---
- Say Y here if you have a GreenAsia (Product ID 0x12) based game
- controller or adapter.
-
-config GREENASIA_FF
- bool "GreenAsia (Product ID 0x12) force feedback support"
- depends on HID_GREENASIA
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
- (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
- and want to enable force feedback support for it.
-
-config HID_HYPERV_MOUSE
- tristate "Microsoft Hyper-V mouse driver"
- depends on HYPERV
- ---help---
- Select this option to enable the Hyper-V mouse driver.
-
-config HID_SMARTJOYPLUS
- tristate "SmartJoy PLUS PS2/USB adapter support"
- depends on USB_HID
- ---help---
- Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box,
- Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro.
-
- Note that DDR (Dance Dance Revolution) mode is not supported, nor
- is pressure sensitive buttons on the pro models.
-
-config SMARTJOYPLUS_FF
- bool "SmartJoy PLUS PS2/USB adapter force feedback support"
- depends on HID_SMARTJOYPLUS
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to
- enable force feedback support for it.
-
-config HID_TIVO
- tristate "TiVo Slide Bluetooth remote control support"
- depends on (USB_HID || BT_HIDP)
- ---help---
- Say Y if you have a TiVo Slide Bluetooth remote control.
-
-config HID_TOPSEED
- tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support"
- depends on USB_HID
- ---help---
- Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
- CLLRCMCE remote control.
-
-config HID_THRUSTMASTER
- tristate "ThrustMaster devices support"
- depends on USB_HID
- ---help---
- Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
- a THRUSTMASTER Ferrari GT Rumble Wheel.
-
-config THRUSTMASTER_FF
- bool "ThrustMaster devices force feedback support"
- depends on HID_THRUSTMASTER
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3,
- a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT
- Rumble Force or Force Feedback Wheel.
-
-config HID_WACOM
- tristate "Wacom Bluetooth devices support"
- depends on BT_HIDP
- ---help---
- Support for Wacom Graphire Bluetooth tablet.
-
-config HID_WACOM_POWER_SUPPLY
- bool "Wacom Bluetooth devices power supply status support"
- depends on HID_WACOM
- select POWER_SUPPLY
- ---help---
- Say Y here if you want to enable power supply status monitoring for
- Wacom Bluetooth devices.
-
-config HID_WIIMOTE
- tristate "Nintendo Wii Remote support"
- depends on BT_HIDP
- depends on LEDS_CLASS
- select POWER_SUPPLY
- select INPUT_FF_MEMLESS
- ---help---
- Support for the Nintendo Wii Remote bluetooth device.
-
-config HID_WIIMOTE_EXT
- bool "Nintendo Wii Remote Extension support"
- depends on HID_WIIMOTE
- default HID_WIIMOTE
- ---help---
- Support for extension controllers of the Nintendo Wii Remote. Say yes
- here if you want to use the Nintendo Motion+, Nunchuck or Classic
- extension controllers with your Wii Remote.
-
-config HID_ZEROPLUS
- tristate "Zeroplus based game controller support"
- depends on USB_HID
- ---help---
- Say Y here if you have a Zeroplus based game controller.
-
-config ZEROPLUS_FF
- bool "Zeroplus based game controller force feedback support"
- depends on HID_ZEROPLUS
- select INPUT_FF_MEMLESS
- ---help---
- Say Y here if you have a Zeroplus based game controller and want
- to have force feedback support for it.
-
-config HID_ZYDACRON
- tristate "Zydacron remote control support"
- depends on USB_HID
- ---help---
- Support for Zydacron remote control.
-
-endmenu
-
-endif # HID_SUPPORT
diff --git a/ANDROID_3.4.5/drivers/hid/Makefile b/ANDROID_3.4.5/drivers/hid/Makefile
deleted file mode 100644
index 9dca8459..00000000
--- a/ANDROID_3.4.5/drivers/hid/Makefile
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-# Makefile for the HID driver
-#
-hid-y := hid-core.o hid-input.o
-
-ifdef CONFIG_DEBUG_FS
- hid-objs += hid-debug.o
-endif
-
-obj-$(CONFIG_HID) += hid.o
-obj-$(CONFIG_UHID) += uhid.o
-
-hid-$(CONFIG_HIDRAW) += hidraw.o
-
-hid-logitech-y := hid-lg.o
-ifdef CONFIG_LOGITECH_FF
- hid-logitech-y += hid-lgff.o
-endif
-ifdef CONFIG_LOGIRUMBLEPAD2_FF
- hid-logitech-y += hid-lg2ff.o
-endif
-ifdef CONFIG_LOGIG940_FF
- hid-logitech-y += hid-lg3ff.o
-endif
-ifdef CONFIG_LOGIWHEELS_FF
- hid-logitech-y += hid-lg4ff.o
-endif
-
-hid-wiimote-y := hid-wiimote-core.o
-ifdef CONFIG_HID_WIIMOTE_EXT
- hid-wiimote-y += hid-wiimote-ext.o
-endif
-ifdef CONFIG_DEBUG_FS
- hid-wiimote-y += hid-wiimote-debug.o
-endif
-
-obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
-obj-$(CONFIG_HID_ACRUX) += hid-axff.o
-obj-$(CONFIG_HID_APPLE) += hid-apple.o
-obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
-obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
-obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
-obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
-obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o
-obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
-obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
-obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
-obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
-obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
-obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
-obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
-obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
-obj-$(CONFIG_HID_KYE) += hid-kye.o
-obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
-obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
-obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
-obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
-obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
-obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
-obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
-obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o
-obj-$(CONFIG_HID_ORTEK) += hid-ortek.o
-obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o
-obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
-obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
-obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
-obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
-obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
- hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
- hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o
-obj-$(CONFIG_HID_SAITEK) += hid-saitek.o
-obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
-obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
-obj-$(CONFIG_HID_SONY) += hid-sony.o
-obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o
-obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
-obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
-obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
-obj-$(CONFIG_HID_TIVO) += hid-tivo.o
-obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
-obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
-obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o
-obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
-obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
-obj-$(CONFIG_HID_WACOM) += hid-wacom.o
-obj-$(CONFIG_HID_WALTOP) += hid-waltop.o
-obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
-
-obj-$(CONFIG_USB_HID) += usbhid/
-obj-$(CONFIG_USB_MOUSE) += usbhid/
-obj-$(CONFIG_USB_KBD) += usbhid/
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-a4tech.c b/ANDROID_3.4.5/drivers/hid/hid-a4tech.c
deleted file mode 100644
index 902d1dfe..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-a4tech.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * HID driver for some a4tech "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "hid-ids.h"
-
-#define A4_2WHEEL_MOUSE_HACK_7 0x01
-#define A4_2WHEEL_MOUSE_HACK_B8 0x02
-
-struct a4tech_sc {
- unsigned long quirks;
- unsigned int hw_wheel;
- __s32 delayed_value;
-};
-
-static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- struct a4tech_sc *a4 = hid_get_drvdata(hdev);
-
- if (usage->type == EV_REL && usage->code == REL_WHEEL)
- set_bit(REL_HWHEEL, *bit);
-
- if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007)
- return -1;
-
- return 0;
-}
-
-static int a4_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- struct a4tech_sc *a4 = hid_get_drvdata(hdev);
- struct input_dev *input;
-
- if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
- !usage->type)
- return 0;
-
- input = field->hidinput->input;
-
- if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) {
- if (usage->type == EV_REL && usage->code == REL_WHEEL) {
- a4->delayed_value = value;
- return 1;
- }
-
- if (usage->hid == 0x000100b8) {
- input_event(input, EV_REL, value ? REL_HWHEEL :
- REL_WHEEL, a4->delayed_value);
- return 1;
- }
- }
-
- if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) {
- a4->hw_wheel = !!value;
- return 1;
- }
-
- if (usage->code == REL_WHEEL && a4->hw_wheel) {
- input_event(input, usage->type, REL_HWHEEL, value);
- return 1;
- }
-
- return 0;
-}
-
-static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- struct a4tech_sc *a4;
- int ret;
-
- a4 = kzalloc(sizeof(*a4), GFP_KERNEL);
- if (a4 == NULL) {
- hid_err(hdev, "can't alloc device descriptor\n");
- ret = -ENOMEM;
- goto err_free;
- }
-
- a4->quirks = id->driver_data;
-
- hid_set_drvdata(hdev, a4);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- return 0;
-err_free:
- kfree(a4);
- return ret;
-}
-
-static void a4_remove(struct hid_device *hdev)
-{
- struct a4tech_sc *a4 = hid_get_drvdata(hdev);
-
- hid_hw_stop(hdev);
- kfree(a4);
-}
-
-static const struct hid_device_id a4_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU),
- .driver_data = A4_2WHEEL_MOUSE_HACK_7 },
- { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D),
- .driver_data = A4_2WHEEL_MOUSE_HACK_B8 },
- { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649),
- .driver_data = A4_2WHEEL_MOUSE_HACK_B8 },
- { }
-};
-MODULE_DEVICE_TABLE(hid, a4_devices);
-
-static struct hid_driver a4_driver = {
- .name = "a4tech",
- .id_table = a4_devices,
- .input_mapped = a4_input_mapped,
- .event = a4_event,
- .probe = a4_probe,
- .remove = a4_remove,
-};
-
-static int __init a4_init(void)
-{
- return hid_register_driver(&a4_driver);
-}
-
-static void __exit a4_exit(void)
-{
- hid_unregister_driver(&a4_driver);
-}
-
-module_init(a4_init);
-module_exit(a4_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-apple.c b/ANDROID_3.4.5/drivers/hid/hid-apple.c
deleted file mode 100644
index 299d2387..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-apple.c
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * USB HID quirks support for Linux
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "hid-ids.h"
-
-#define APPLE_RDESC_JIS 0x0001
-#define APPLE_IGNORE_MOUSE 0x0002
-#define APPLE_HAS_FN 0x0004
-#define APPLE_HIDDEV 0x0008
-#define APPLE_ISO_KEYBOARD 0x0010
-#define APPLE_MIGHTYMOUSE 0x0020
-#define APPLE_INVERT_HWHEEL 0x0040
-#define APPLE_IGNORE_HIDINPUT 0x0080
-#define APPLE_NUMLOCK_EMULATION 0x0100
-
-#define APPLE_FLAG_FKEY 0x01
-
-static unsigned int fnmode = 1;
-module_param(fnmode, uint, 0644);
-MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
- "[1] = fkeyslast, 2 = fkeysfirst)");
-
-static unsigned int iso_layout = 1;
-module_param(iso_layout, uint, 0644);
-MODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. "
- "(0 = disabled, [1] = enabled)");
-
-struct apple_sc {
- unsigned long quirks;
- unsigned int fn_on;
- DECLARE_BITMAP(pressed_fn, KEY_CNT);
- DECLARE_BITMAP(pressed_numlock, KEY_CNT);
-};
-
-struct apple_key_translation {
- u16 from;
- u16 to;
- u8 flags;
-};
-
-static const struct apple_key_translation macbookair_fn_keys[] = {
- { KEY_BACKSPACE, KEY_DELETE },
- { KEY_ENTER, KEY_INSERT },
- { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
- { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
- { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
- { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
- { KEY_F6, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
- { KEY_F7, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
- { KEY_F8, KEY_NEXTSONG, APPLE_FLAG_FKEY },
- { KEY_F9, KEY_MUTE, APPLE_FLAG_FKEY },
- { KEY_F10, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
- { KEY_F11, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
- { KEY_F12, KEY_EJECTCD, APPLE_FLAG_FKEY },
- { KEY_UP, KEY_PAGEUP },
- { KEY_DOWN, KEY_PAGEDOWN },
- { KEY_LEFT, KEY_HOME },
- { KEY_RIGHT, KEY_END },
- { }
-};
-
-static const struct apple_key_translation apple_fn_keys[] = {
- { KEY_BACKSPACE, KEY_DELETE },
- { KEY_ENTER, KEY_INSERT },
- { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
- { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
- { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
- { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
- { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
- { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
- { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
- { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
- { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
- { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
- { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
- { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
- { KEY_UP, KEY_PAGEUP },
- { KEY_DOWN, KEY_PAGEDOWN },
- { KEY_LEFT, KEY_HOME },
- { KEY_RIGHT, KEY_END },
- { }
-};
-
-static const struct apple_key_translation powerbook_fn_keys[] = {
- { KEY_BACKSPACE, KEY_DELETE },
- { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
- { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
- { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY },
- { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
- { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
- { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY },
- { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY },
- { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY },
- { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
- { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
- { KEY_UP, KEY_PAGEUP },
- { KEY_DOWN, KEY_PAGEDOWN },
- { KEY_LEFT, KEY_HOME },
- { KEY_RIGHT, KEY_END },
- { }
-};
-
-static const struct apple_key_translation powerbook_numlock_keys[] = {
- { KEY_J, KEY_KP1 },
- { KEY_K, KEY_KP2 },
- { KEY_L, KEY_KP3 },
- { KEY_U, KEY_KP4 },
- { KEY_I, KEY_KP5 },
- { KEY_O, KEY_KP6 },
- { KEY_7, KEY_KP7 },
- { KEY_8, KEY_KP8 },
- { KEY_9, KEY_KP9 },
- { KEY_M, KEY_KP0 },
- { KEY_DOT, KEY_KPDOT },
- { KEY_SLASH, KEY_KPPLUS },
- { KEY_SEMICOLON, KEY_KPMINUS },
- { KEY_P, KEY_KPASTERISK },
- { KEY_MINUS, KEY_KPEQUAL },
- { KEY_0, KEY_KPSLASH },
- { KEY_F6, KEY_NUMLOCK },
- { KEY_KPENTER, KEY_KPENTER },
- { KEY_BACKSPACE, KEY_BACKSPACE },
- { }
-};
-
-static const struct apple_key_translation apple_iso_keyboard[] = {
- { KEY_GRAVE, KEY_102ND },
- { KEY_102ND, KEY_GRAVE },
- { }
-};
-
-static const struct apple_key_translation *apple_find_translation(
- const struct apple_key_translation *table, u16 from)
-{
- const struct apple_key_translation *trans;
-
- /* Look for the translation */
- for (trans = table; trans->from; trans++)
- if (trans->from == from)
- return trans;
-
- return NULL;
-}
-
-static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
- struct hid_usage *usage, __s32 value)
-{
- struct apple_sc *asc = hid_get_drvdata(hid);
- const struct apple_key_translation *trans, *table;
-
- if (usage->code == KEY_FN) {
- asc->fn_on = !!value;
- input_event(input, usage->type, usage->code, value);
- return 1;
- }
-
- if (fnmode) {
- int do_translate;
-
- if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
- hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
- table = macbookair_fn_keys;
- else if (hid->product < 0x21d || hid->product >= 0x300)
- table = powerbook_fn_keys;
- else
- table = apple_fn_keys;
-
- trans = apple_find_translation (table, usage->code);
-
- if (trans) {
- if (test_bit(usage->code, asc->pressed_fn))
- do_translate = 1;
- else if (trans->flags & APPLE_FLAG_FKEY)
- do_translate = (fnmode == 2 && asc->fn_on) ||
- (fnmode == 1 && !asc->fn_on);
- else
- do_translate = asc->fn_on;
-
- if (do_translate) {
- if (value)
- set_bit(usage->code, asc->pressed_fn);
- else
- clear_bit(usage->code, asc->pressed_fn);
-
- input_event(input, usage->type, trans->to,
- value);
-
- return 1;
- }
- }
-
- if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
- (test_bit(usage->code, asc->pressed_numlock) ||
- test_bit(LED_NUML, input->led))) {
- trans = apple_find_translation(powerbook_numlock_keys,
- usage->code);
-
- if (trans) {
- if (value)
- set_bit(usage->code,
- asc->pressed_numlock);
- else
- clear_bit(usage->code,
- asc->pressed_numlock);
-
- input_event(input, usage->type, trans->to,
- value);
- }
-
- return 1;
- }
- }
-
- if (iso_layout) {
- if (asc->quirks & APPLE_ISO_KEYBOARD) {
- trans = apple_find_translation(apple_iso_keyboard, usage->code);
- if (trans) {
- input_event(input, usage->type, trans->to, value);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static int apple_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- struct apple_sc *asc = hid_get_drvdata(hdev);
-
- if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
- !usage->type)
- return 0;
-
- if ((asc->quirks & APPLE_INVERT_HWHEEL) &&
- usage->code == REL_HWHEEL) {
- input_event(field->hidinput->input, usage->type, usage->code,
- -value);
- return 1;
- }
-
- if ((asc->quirks & APPLE_HAS_FN) &&
- hidinput_apple_event(hdev, field->hidinput->input,
- usage, value))
- return 1;
-
-
- return 0;
-}
-
-/*
- * MacBook JIS keyboard has wrong logical maximum
- */
-static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- struct apple_sc *asc = hid_get_drvdata(hdev);
-
- if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
- rdesc[53] == 0x65 && rdesc[59] == 0x65) {
- hid_info(hdev,
- "fixing up MacBook JIS keyboard report descriptor\n");
- rdesc[53] = rdesc[59] = 0xe7;
- }
- return rdesc;
-}
-
-static void apple_setup_input(struct input_dev *input)
-{
- const struct apple_key_translation *trans;
-
- set_bit(KEY_NUMLOCK, input->keybit);
-
- /* Enable all needed keys */
- for (trans = apple_fn_keys; trans->from; trans++)
- set_bit(trans->to, input->keybit);
-
- for (trans = powerbook_fn_keys; trans->from; trans++)
- set_bit(trans->to, input->keybit);
-
- for (trans = powerbook_numlock_keys; trans->from; trans++)
- set_bit(trans->to, input->keybit);
-
- for (trans = apple_iso_keyboard; trans->from; trans++)
- set_bit(trans->to, input->keybit);
-}
-
-static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if (usage->hid == (HID_UP_CUSTOM | 0x0003)) {
- /* The fn key on Apple USB keyboards */
- set_bit(EV_REP, hi->input->evbit);
- hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
- apple_setup_input(hi->input);
- return 1;
- }
-
- /* we want the hid layer to go through standard path (set and ignore) */
- return 0;
-}
-
-static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- struct apple_sc *asc = hid_get_drvdata(hdev);
-
- if (asc->quirks & APPLE_MIGHTYMOUSE) {
- if (usage->hid == HID_GD_Z)
- hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
- else if (usage->code == BTN_1)
- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2);
- else if (usage->code == BTN_2)
- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1);
- }
-
- return 0;
-}
-
-static int apple_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- unsigned long quirks = id->driver_data;
- struct apple_sc *asc;
- unsigned int connect_mask = HID_CONNECT_DEFAULT;
- int ret;
-
- asc = kzalloc(sizeof(*asc), GFP_KERNEL);
- if (asc == NULL) {
- hid_err(hdev, "can't alloc apple descriptor\n");
- return -ENOMEM;
- }
-
- asc->quirks = quirks;
-
- hid_set_drvdata(hdev, asc);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- if (quirks & APPLE_HIDDEV)
- connect_mask |= HID_CONNECT_HIDDEV_FORCE;
- if (quirks & APPLE_IGNORE_HIDINPUT)
- connect_mask &= ~HID_CONNECT_HIDINPUT;
-
- ret = hid_hw_start(hdev, connect_mask);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- return 0;
-err_free:
- kfree(asc);
- return ret;
-}
-
-static void apple_remove(struct hid_device *hdev)
-{
- hid_hw_stop(hdev);
- kfree(hid_get_drvdata(hdev));
-}
-
-static const struct hid_device_id apple_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL),
- .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4),
- .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
- .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
-
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
- .driver_data = APPLE_HAS_FN },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_ISO_KEYBOARD },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_ISO_KEYBOARD },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI),
- .driver_data = APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO),
- .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS),
- .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
- APPLE_ISO_KEYBOARD },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
- .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
-
- { }
-};
-MODULE_DEVICE_TABLE(hid, apple_devices);
-
-static struct hid_driver apple_driver = {
- .name = "apple",
- .id_table = apple_devices,
- .report_fixup = apple_report_fixup,
- .probe = apple_probe,
- .remove = apple_remove,
- .event = apple_event,
- .input_mapping = apple_input_mapping,
- .input_mapped = apple_input_mapped,
-};
-
-static int __init apple_init(void)
-{
- int ret;
-
- ret = hid_register_driver(&apple_driver);
- if (ret)
- pr_err("can't register apple driver\n");
-
- return ret;
-}
-
-static void __exit apple_exit(void)
-{
- hid_unregister_driver(&apple_driver);
-}
-
-module_init(apple_init);
-module_exit(apple_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-axff.c b/ANDROID_3.4.5/drivers/hid/hid-axff.c
deleted file mode 100644
index 5be858dd..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-axff.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Force feedback support for ACRUX game controllers
- *
- * From what I have gathered, these devices are mass produced in China
- * by several vendors. They often share the same design as the original
- * Xbox 360 controller.
- *
- * 1a34:0802 "ACRUX USB GAMEPAD 8116"
- * - tested with an EXEQ EQ-PCU-02090 game controller.
- *
- * Copyright (c) 2010 Sergei Kolzun <x0r@dv-life.ru>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#ifdef CONFIG_HID_ACRUX_FF
-#include "usbhid/usbhid.h"
-
-struct axff_device {
- struct hid_report *report;
-};
-
-static int axff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct axff_device *axff = data;
- struct hid_report *report = axff->report;
- int field_count = 0;
- int left, right;
- int i, j;
-
- left = effect->u.rumble.strong_magnitude;
- right = effect->u.rumble.weak_magnitude;
-
- dbg_hid("called with 0x%04x 0x%04x", left, right);
-
- left = left * 0xff / 0xffff;
- right = right * 0xff / 0xffff;
-
- for (i = 0; i < report->maxfield; i++) {
- for (j = 0; j < report->field[i]->report_count; j++) {
- report->field[i]->value[j] =
- field_count % 2 ? right : left;
- field_count++;
- }
- }
-
- dbg_hid("running with 0x%02x 0x%02x", left, right);
- usbhid_submit_report(hid, axff->report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int axff_init(struct hid_device *hid)
-{
- struct axff_device *axff;
- struct hid_report *report;
- struct hid_input *hidinput = list_first_entry(&hid->inputs, struct hid_input, list);
- struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- int field_count = 0;
- int i, j;
- int error;
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output reports found\n");
- return -ENODEV;
- }
-
- report = list_first_entry(report_list, struct hid_report, list);
- for (i = 0; i < report->maxfield; i++) {
- for (j = 0; j < report->field[i]->report_count; j++) {
- report->field[i]->value[j] = 0x00;
- field_count++;
- }
- }
-
- if (field_count < 4) {
- hid_err(hid, "not enough fields in the report: %d\n",
- field_count);
- return -ENODEV;
- }
-
- axff = kzalloc(sizeof(struct axff_device), GFP_KERNEL);
- if (!axff)
- return -ENOMEM;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- error = input_ff_create_memless(dev, axff, axff_play);
- if (error)
- goto err_free_mem;
-
- axff->report = report;
- usbhid_submit_report(hid, axff->report, USB_DIR_OUT);
-
- hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun <x0r@dv-life.ru>\n");
-
- return 0;
-
-err_free_mem:
- kfree(axff);
- return error;
-}
-#else
-static inline int axff_init(struct hid_device *hid)
-{
- return 0;
-}
-#endif
-
-static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int error;
-
- dev_dbg(&hdev->dev, "ACRUX HID hardware probe...\n");
-
- error = hid_parse(hdev);
- if (error) {
- hid_err(hdev, "parse failed\n");
- return error;
- }
-
- error = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (error) {
- hid_err(hdev, "hw start failed\n");
- return error;
- }
-
- error = axff_init(hdev);
- if (error) {
- /*
- * Do not fail device initialization completely as device
- * may still be partially operable, just warn.
- */
- hid_warn(hdev,
- "Failed to enable force feedback support, error: %d\n",
- error);
- }
-
- /*
- * We need to start polling device right away, otherwise
- * it will go into a coma.
- */
- error = hid_hw_open(hdev);
- if (error) {
- dev_err(&hdev->dev, "hw open failed\n");
- hid_hw_stop(hdev);
- return error;
- }
-
- return 0;
-}
-
-static void ax_remove(struct hid_device *hdev)
-{
- hid_hw_close(hdev);
- hid_hw_stop(hdev);
-}
-
-static const struct hid_device_id ax_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ax_devices);
-
-static struct hid_driver ax_driver = {
- .name = "acrux",
- .id_table = ax_devices,
- .probe = ax_probe,
- .remove = ax_remove,
-};
-
-static int __init ax_init(void)
-{
- return hid_register_driver(&ax_driver);
-}
-
-static void __exit ax_exit(void)
-{
- hid_unregister_driver(&ax_driver);
-}
-
-module_init(ax_init);
-module_exit(ax_exit);
-
-MODULE_AUTHOR("Sergei Kolzun");
-MODULE_DESCRIPTION("Force feedback support for ACRUX game controllers");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-belkin.c b/ANDROID_3.4.5/drivers/hid/hid-belkin.c
deleted file mode 100644
index a1a765a5..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-belkin.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * HID driver for some belkin "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define BELKIN_HIDDEV 0x01
-#define BELKIN_WKBD 0x02
-
-#define belkin_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int belkin_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER ||
- !(quirks & BELKIN_WKBD))
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x03a: belkin_map_key_clear(KEY_SOUND); break;
- case 0x03b: belkin_map_key_clear(KEY_CAMERA); break;
- case 0x03c: belkin_map_key_clear(KEY_DOCUMENTS); break;
- default:
- return 0;
- }
- return 1;
-}
-
-static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- unsigned long quirks = id->driver_data;
- int ret;
-
- hid_set_drvdata(hdev, (void *)quirks);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
- ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0));
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- return 0;
-err_free:
- return ret;
-}
-
-static const struct hid_device_id belkin_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM),
- .driver_data = BELKIN_HIDDEV },
- { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD),
- .driver_data = BELKIN_WKBD },
- { }
-};
-MODULE_DEVICE_TABLE(hid, belkin_devices);
-
-static struct hid_driver belkin_driver = {
- .name = "belkin",
- .id_table = belkin_devices,
- .input_mapping = belkin_input_mapping,
- .probe = belkin_probe,
-};
-
-static int __init belkin_init(void)
-{
- return hid_register_driver(&belkin_driver);
-}
-
-static void __exit belkin_exit(void)
-{
- hid_unregister_driver(&belkin_driver);
-}
-
-module_init(belkin_init);
-module_exit(belkin_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-cherry.c b/ANDROID_3.4.5/drivers/hid/hid-cherry.c
deleted file mode 100644
index 888ece68..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-cherry.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * HID driver for some cherry "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-/*
- * Cherry Cymotion keyboard have an invalid HID report descriptor,
- * that needs fixing before we can parse it.
- */
-static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
- hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n");
- rdesc[11] = rdesc[16] = 0xff;
- rdesc[12] = rdesc[17] = 0x03;
- }
- return rdesc;
-}
-
-#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x301: ch_map_key_clear(KEY_PROG1); break;
- case 0x302: ch_map_key_clear(KEY_PROG2); break;
- case 0x303: ch_map_key_clear(KEY_PROG3); break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static const struct hid_device_id ch_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ch_devices);
-
-static struct hid_driver ch_driver = {
- .name = "cherry",
- .id_table = ch_devices,
- .report_fixup = ch_report_fixup,
- .input_mapping = ch_input_mapping,
-};
-
-static int __init ch_init(void)
-{
- return hid_register_driver(&ch_driver);
-}
-
-static void __exit ch_exit(void)
-{
- hid_unregister_driver(&ch_driver);
-}
-
-module_init(ch_init);
-module_exit(ch_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-chicony.c b/ANDROID_3.4.5/drivers/hid/hid-chicony.c
deleted file mode 100644
index b99af346..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-chicony.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * HID driver for some chicony "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
- return 0;
-
- set_bit(EV_REP, hi->input->evbit);
- switch (usage->hid & HID_USAGE) {
- case 0xff01: ch_map_key_clear(BTN_1); break;
- case 0xff02: ch_map_key_clear(BTN_2); break;
- case 0xff03: ch_map_key_clear(BTN_3); break;
- case 0xff04: ch_map_key_clear(BTN_4); break;
- case 0xff05: ch_map_key_clear(BTN_5); break;
- case 0xff06: ch_map_key_clear(BTN_6); break;
- case 0xff07: ch_map_key_clear(BTN_7); break;
- case 0xff08: ch_map_key_clear(BTN_8); break;
- case 0xff09: ch_map_key_clear(BTN_9); break;
- case 0xff0a: ch_map_key_clear(BTN_A); break;
- case 0xff0b: ch_map_key_clear(BTN_B); break;
- case 0x00f1: ch_map_key_clear(KEY_WLAN); break;
- case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break;
- case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break;
- case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break;
- case 0x00f7: ch_map_key_clear(KEY_CAMERA); break;
- case 0x00f8: ch_map_key_clear(KEY_PROG1); break;
- default:
- return 0;
- }
- return 1;
-}
-
-static const struct hid_device_id ch_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ch_devices);
-
-static struct hid_driver ch_driver = {
- .name = "chicony",
- .id_table = ch_devices,
- .input_mapping = ch_input_mapping,
-};
-
-static int __init ch_init(void)
-{
- return hid_register_driver(&ch_driver);
-}
-
-static void __exit ch_exit(void)
-{
- hid_unregister_driver(&ch_driver);
-}
-
-module_init(ch_init);
-module_exit(ch_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-core.c b/ANDROID_3.4.5/drivers/hid/hid-core.c
deleted file mode 100644
index 4da66b4b..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-core.c
+++ /dev/null
@@ -1,2254 +0,0 @@
-/*
- * HID support for Linux
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2012 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <asm/unaligned.h>
-#include <asm/byteorder.h>
-#include <linux/input.h>
-#include <linux/wait.h>
-#include <linux/vmalloc.h>
-#include <linux/sched.h>
-#include <linux/semaphore.h>
-
-#include <linux/hid.h>
-#include <linux/hiddev.h>
-#include <linux/hid-debug.h>
-#include <linux/hidraw.h>
-
-#include "hid-ids.h"
-
-/*
- * Version Information
- */
-
-#define DRIVER_DESC "HID core driver"
-#define DRIVER_LICENSE "GPL"
-
-int hid_debug = 0;
-module_param_named(debug, hid_debug, int, 0600);
-MODULE_PARM_DESC(debug, "toggle HID debugging messages");
-EXPORT_SYMBOL_GPL(hid_debug);
-
-static int hid_ignore_special_drivers = 0;
-module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600);
-MODULE_PARM_DESC(debug, "Ignore any special drivers and handle all devices by generic driver");
-
-/*
- * Register a new report for a device.
- */
-
-struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id)
-{
- struct hid_report_enum *report_enum = device->report_enum + type;
- struct hid_report *report;
-
- if (report_enum->report_id_hash[id])
- return report_enum->report_id_hash[id];
-
- report = kzalloc(sizeof(struct hid_report), GFP_KERNEL);
- if (!report)
- return NULL;
-
- if (id != 0)
- report_enum->numbered = 1;
-
- report->id = id;
- report->type = type;
- report->size = 0;
- report->device = device;
- report_enum->report_id_hash[id] = report;
-
- list_add_tail(&report->list, &report_enum->report_list);
-
- return report;
-}
-EXPORT_SYMBOL_GPL(hid_register_report);
-
-/*
- * Register a new field for this report.
- */
-
-static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values)
-{
- struct hid_field *field;
-
- if (report->maxfield == HID_MAX_FIELDS) {
- hid_err(report->device, "too many fields in report\n");
- return NULL;
- }
-
- field = kzalloc((sizeof(struct hid_field) +
- usages * sizeof(struct hid_usage) +
- values * sizeof(unsigned)), GFP_KERNEL);
- if (!field)
- return NULL;
-
- field->index = report->maxfield++;
- report->field[field->index] = field;
- field->usage = (struct hid_usage *)(field + 1);
- field->value = (s32 *)(field->usage + usages);
- field->report = report;
-
- return field;
-}
-
-/*
- * Open a collection. The type/usage is pushed on the stack.
- */
-
-static int open_collection(struct hid_parser *parser, unsigned type)
-{
- struct hid_collection *collection;
- unsigned usage;
-
- usage = parser->local.usage[0];
-
- if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
- hid_err(parser->device, "collection stack overflow\n");
- return -1;
- }
-
- if (parser->device->maxcollection == parser->device->collection_size) {
- collection = kmalloc(sizeof(struct hid_collection) *
- parser->device->collection_size * 2, GFP_KERNEL);
- if (collection == NULL) {
- hid_err(parser->device, "failed to reallocate collection array\n");
- return -1;
- }
- memcpy(collection, parser->device->collection,
- sizeof(struct hid_collection) *
- parser->device->collection_size);
- memset(collection + parser->device->collection_size, 0,
- sizeof(struct hid_collection) *
- parser->device->collection_size);
- kfree(parser->device->collection);
- parser->device->collection = collection;
- parser->device->collection_size *= 2;
- }
-
- parser->collection_stack[parser->collection_stack_ptr++] =
- parser->device->maxcollection;
-
- collection = parser->device->collection +
- parser->device->maxcollection++;
- collection->type = type;
- collection->usage = usage;
- collection->level = parser->collection_stack_ptr - 1;
-
- if (type == HID_COLLECTION_APPLICATION)
- parser->device->maxapplication++;
-
- return 0;
-}
-
-/*
- * Close a collection.
- */
-
-static int close_collection(struct hid_parser *parser)
-{
- if (!parser->collection_stack_ptr) {
- hid_err(parser->device, "collection stack underflow\n");
- return -1;
- }
- parser->collection_stack_ptr--;
- return 0;
-}
-
-/*
- * Climb up the stack, search for the specified collection type
- * and return the usage.
- */
-
-static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
-{
- struct hid_collection *collection = parser->device->collection;
- int n;
-
- for (n = parser->collection_stack_ptr - 1; n >= 0; n--) {
- unsigned index = parser->collection_stack[n];
- if (collection[index].type == type)
- return collection[index].usage;
- }
- return 0; /* we know nothing about this usage type */
-}
-
-/*
- * Add a usage to the temporary parser table.
- */
-
-static int hid_add_usage(struct hid_parser *parser, unsigned usage)
-{
- if (parser->local.usage_index >= HID_MAX_USAGES) {
- hid_err(parser->device, "usage index exceeded\n");
- return -1;
- }
- parser->local.usage[parser->local.usage_index] = usage;
- parser->local.collection_index[parser->local.usage_index] =
- parser->collection_stack_ptr ?
- parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
- parser->local.usage_index++;
- return 0;
-}
-
-/*
- * Register a new field for this report.
- */
-
-static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags)
-{
- struct hid_report *report;
- struct hid_field *field;
- int usages;
- unsigned offset;
- int i;
-
- report = hid_register_report(parser->device, report_type, parser->global.report_id);
- if (!report) {
- hid_err(parser->device, "hid_register_report failed\n");
- return -1;
- }
-
- if (parser->global.logical_maximum < parser->global.logical_minimum) {
- hid_err(parser->device, "logical range invalid %d %d\n",
- parser->global.logical_minimum, parser->global.logical_maximum);
- return -1;
- }
-
- offset = report->size;
- report->size += parser->global.report_size * parser->global.report_count;
-
- if (!parser->local.usage_index) /* Ignore padding fields */
- return 0;
-
- usages = max_t(int, parser->local.usage_index, parser->global.report_count);
-
- field = hid_register_field(report, usages, parser->global.report_count);
- if (!field)
- return 0;
-
- field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);
- field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL);
- field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
-
- for (i = 0; i < usages; i++) {
- int j = i;
- /* Duplicate the last usage we parsed if we have excess values */
- if (i >= parser->local.usage_index)
- j = parser->local.usage_index - 1;
- field->usage[i].hid = parser->local.usage[j];
- field->usage[i].collection_index =
- parser->local.collection_index[j];
- }
-
- field->maxusage = usages;
- field->flags = flags;
- field->report_offset = offset;
- field->report_type = report_type;
- field->report_size = parser->global.report_size;
- field->report_count = parser->global.report_count;
- field->logical_minimum = parser->global.logical_minimum;
- field->logical_maximum = parser->global.logical_maximum;
- field->physical_minimum = parser->global.physical_minimum;
- field->physical_maximum = parser->global.physical_maximum;
- field->unit_exponent = parser->global.unit_exponent;
- field->unit = parser->global.unit;
-
- return 0;
-}
-
-/*
- * Read data value from item.
- */
-
-static u32 item_udata(struct hid_item *item)
-{
- switch (item->size) {
- case 1: return item->data.u8;
- case 2: return item->data.u16;
- case 4: return item->data.u32;
- }
- return 0;
-}
-
-static s32 item_sdata(struct hid_item *item)
-{
- switch (item->size) {
- case 1: return item->data.s8;
- case 2: return item->data.s16;
- case 4: return item->data.s32;
- }
- return 0;
-}
-
-/*
- * Process a global item.
- */
-
-static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
-{
- switch (item->tag) {
- case HID_GLOBAL_ITEM_TAG_PUSH:
-
- if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
- hid_err(parser->device, "global environment stack overflow\n");
- return -1;
- }
-
- memcpy(parser->global_stack + parser->global_stack_ptr++,
- &parser->global, sizeof(struct hid_global));
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_POP:
-
- if (!parser->global_stack_ptr) {
- hid_err(parser->device, "global environment stack underflow\n");
- return -1;
- }
-
- memcpy(&parser->global, parser->global_stack +
- --parser->global_stack_ptr, sizeof(struct hid_global));
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
- parser->global.usage_page = item_udata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
- parser->global.logical_minimum = item_sdata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
- if (parser->global.logical_minimum < 0)
- parser->global.logical_maximum = item_sdata(item);
- else
- parser->global.logical_maximum = item_udata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
- parser->global.physical_minimum = item_sdata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
- if (parser->global.physical_minimum < 0)
- parser->global.physical_maximum = item_sdata(item);
- else
- parser->global.physical_maximum = item_udata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
- parser->global.unit_exponent = item_sdata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_UNIT:
- parser->global.unit = item_udata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
- parser->global.report_size = item_udata(item);
- if (parser->global.report_size > 96) {
- hid_err(parser->device, "invalid report_size %d\n",
- parser->global.report_size);
- return -1;
- }
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
- parser->global.report_count = item_udata(item);
- if (parser->global.report_count > HID_MAX_USAGES) {
- hid_err(parser->device, "invalid report_count %d\n",
- parser->global.report_count);
- return -1;
- }
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_REPORT_ID:
- parser->global.report_id = item_udata(item);
- if (parser->global.report_id == 0) {
- hid_err(parser->device, "report_id 0 is invalid\n");
- return -1;
- }
- return 0;
-
- default:
- hid_err(parser->device, "unknown global tag 0x%x\n", item->tag);
- return -1;
- }
-}
-
-/*
- * Process a local item.
- */
-
-static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
-{
- __u32 data;
- unsigned n;
-
- data = item_udata(item);
-
- switch (item->tag) {
- case HID_LOCAL_ITEM_TAG_DELIMITER:
-
- if (data) {
- /*
- * We treat items before the first delimiter
- * as global to all usage sets (branch 0).
- * In the moment we process only these global
- * items and the first delimiter set.
- */
- if (parser->local.delimiter_depth != 0) {
- hid_err(parser->device, "nested delimiters\n");
- return -1;
- }
- parser->local.delimiter_depth++;
- parser->local.delimiter_branch++;
- } else {
- if (parser->local.delimiter_depth < 1) {
- hid_err(parser->device, "bogus close delimiter\n");
- return -1;
- }
- parser->local.delimiter_depth--;
- }
- return 1;
-
- case HID_LOCAL_ITEM_TAG_USAGE:
-
- if (parser->local.delimiter_branch > 1) {
- dbg_hid("alternative usage ignored\n");
- return 0;
- }
-
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
- return hid_add_usage(parser, data);
-
- case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
-
- if (parser->local.delimiter_branch > 1) {
- dbg_hid("alternative usage ignored\n");
- return 0;
- }
-
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
- parser->local.usage_minimum = data;
- return 0;
-
- case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
-
- if (parser->local.delimiter_branch > 1) {
- dbg_hid("alternative usage ignored\n");
- return 0;
- }
-
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
- for (n = parser->local.usage_minimum; n <= data; n++)
- if (hid_add_usage(parser, n)) {
- dbg_hid("hid_add_usage failed\n");
- return -1;
- }
- return 0;
-
- default:
-
- dbg_hid("unknown local item tag 0x%x\n", item->tag);
- return 0;
- }
- return 0;
-}
-
-/*
- * Process a main item.
- */
-
-static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
-{
- __u32 data;
- int ret;
-
- data = item_udata(item);
-
- switch (item->tag) {
- case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
- ret = open_collection(parser, data & 0xff);
- break;
- case HID_MAIN_ITEM_TAG_END_COLLECTION:
- ret = close_collection(parser);
- break;
- case HID_MAIN_ITEM_TAG_INPUT:
- ret = hid_add_field(parser, HID_INPUT_REPORT, data);
- break;
- case HID_MAIN_ITEM_TAG_OUTPUT:
- ret = hid_add_field(parser, HID_OUTPUT_REPORT, data);
- break;
- case HID_MAIN_ITEM_TAG_FEATURE:
- ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
- break;
- default:
- hid_err(parser->device, "unknown main item tag 0x%x\n", item->tag);
- ret = 0;
- }
-
- memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */
-
- return ret;
-}
-
-/*
- * Process a reserved item.
- */
-
-static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
-{
- dbg_hid("reserved item type, tag 0x%x\n", item->tag);
- return 0;
-}
-
-/*
- * Free a report and all registered fields. The field->usage and
- * field->value table's are allocated behind the field, so we need
- * only to free(field) itself.
- */
-
-static void hid_free_report(struct hid_report *report)
-{
- unsigned n;
-
- for (n = 0; n < report->maxfield; n++)
- kfree(report->field[n]);
- kfree(report);
-}
-
-/*
- * Free a device structure, all reports, and all fields.
- */
-
-static void hid_device_release(struct device *dev)
-{
- struct hid_device *device = container_of(dev, struct hid_device, dev);
- unsigned i, j;
-
- for (i = 0; i < HID_REPORT_TYPES; i++) {
- struct hid_report_enum *report_enum = device->report_enum + i;
-
- for (j = 0; j < 256; j++) {
- struct hid_report *report = report_enum->report_id_hash[j];
- if (report)
- hid_free_report(report);
- }
- }
-
- kfree(device->rdesc);
- kfree(device->collection);
- kfree(device);
-}
-
-/*
- * Fetch a report description item from the data stream. We support long
- * items, though they are not used yet.
- */
-
-static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
-{
- u8 b;
-
- if ((end - start) <= 0)
- return NULL;
-
- b = *start++;
-
- item->type = (b >> 2) & 3;
- item->tag = (b >> 4) & 15;
-
- if (item->tag == HID_ITEM_TAG_LONG) {
-
- item->format = HID_ITEM_FORMAT_LONG;
-
- if ((end - start) < 2)
- return NULL;
-
- item->size = *start++;
- item->tag = *start++;
-
- if ((end - start) < item->size)
- return NULL;
-
- item->data.longdata = start;
- start += item->size;
- return start;
- }
-
- item->format = HID_ITEM_FORMAT_SHORT;
- item->size = b & 3;
-
- switch (item->size) {
- case 0:
- return start;
-
- case 1:
- if ((end - start) < 1)
- return NULL;
- item->data.u8 = *start++;
- return start;
-
- case 2:
- if ((end - start) < 2)
- return NULL;
- item->data.u16 = get_unaligned_le16(start);
- start = (__u8 *)((__le16 *)start + 1);
- return start;
-
- case 3:
- item->size++;
- if ((end - start) < 4)
- return NULL;
- item->data.u32 = get_unaligned_le32(start);
- start = (__u8 *)((__le32 *)start + 1);
- return start;
- }
-
- return NULL;
-}
-
-/**
- * hid_parse_report - parse device report
- *
- * @device: hid device
- * @start: report start
- * @size: report size
- *
- * Parse a report description into a hid_device structure. Reports are
- * enumerated, fields are attached to these reports.
- * 0 returned on success, otherwise nonzero error value.
- */
-int hid_parse_report(struct hid_device *device, __u8 *start,
- unsigned size)
-{
- struct hid_parser *parser;
- struct hid_item item;
- __u8 *end;
- int ret;
- static int (*dispatch_type[])(struct hid_parser *parser,
- struct hid_item *item) = {
- hid_parser_main,
- hid_parser_global,
- hid_parser_local,
- hid_parser_reserved
- };
-
- if (device->driver->report_fixup)
- start = device->driver->report_fixup(device, start, &size);
-
- device->rdesc = kmemdup(start, size, GFP_KERNEL);
- if (device->rdesc == NULL)
- return -ENOMEM;
- device->rsize = size;
-
- parser = vzalloc(sizeof(struct hid_parser));
- if (!parser) {
- ret = -ENOMEM;
- goto err;
- }
-
- parser->device = device;
-
- end = start + size;
- ret = -EINVAL;
- while ((start = fetch_item(start, end, &item)) != NULL) {
-
- if (item.format != HID_ITEM_FORMAT_SHORT) {
- hid_err(device, "unexpected long global item\n");
- goto err;
- }
-
- if (dispatch_type[item.type](parser, &item)) {
- hid_err(device, "item %u %u %u %u parsing failed\n",
- item.format, (unsigned)item.size,
- (unsigned)item.type, (unsigned)item.tag);
- goto err;
- }
-
- if (start == end) {
- if (parser->collection_stack_ptr) {
- hid_err(device, "unbalanced collection at end of report description\n");
- goto err;
- }
- if (parser->local.delimiter_depth) {
- hid_err(device, "unbalanced delimiter at end of report description\n");
- goto err;
- }
- vfree(parser);
- return 0;
- }
- }
-
- hid_err(device, "item fetching failed at offset %d\n", (int)(end - start));
-err:
- vfree(parser);
- return ret;
-}
-EXPORT_SYMBOL_GPL(hid_parse_report);
-
-/*
- * Convert a signed n-bit integer to signed 32-bit integer. Common
- * cases are done through the compiler, the screwed things has to be
- * done by hand.
- */
-
-static s32 snto32(__u32 value, unsigned n)
-{
- switch (n) {
- case 8: return ((__s8)value);
- case 16: return ((__s16)value);
- case 32: return ((__s32)value);
- }
- return value & (1 << (n - 1)) ? value | (-1 << n) : value;
-}
-
-/*
- * Convert a signed 32-bit integer to a signed n-bit integer.
- */
-
-static u32 s32ton(__s32 value, unsigned n)
-{
- s32 a = value >> (n - 1);
- if (a && a != -1)
- return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
- return value & ((1 << n) - 1);
-}
-
-/*
- * Extract/implement a data field from/to a little endian report (bit array).
- *
- * Code sort-of follows HID spec:
- * http://www.usb.org/developers/devclass_docs/HID1_11.pdf
- *
- * While the USB HID spec allows unlimited length bit fields in "report
- * descriptors", most devices never use more than 16 bits.
- * One model of UPS is claimed to report "LINEV" as a 32-bit field.
- * Search linux-kernel and linux-usb-devel archives for "hid-core extract".
- */
-
-static __u32 extract(const struct hid_device *hid, __u8 *report,
- unsigned offset, unsigned n)
-{
- u64 x;
-
- if (n > 32)
- hid_warn(hid, "extract() called with n (%d) > 32! (%s)\n",
- n, current->comm);
-
- report += offset >> 3; /* adjust byte index */
- offset &= 7; /* now only need bit offset into one byte */
- x = get_unaligned_le64(report);
- x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */
- return (u32) x;
-}
-
-/*
- * "implement" : set bits in a little endian bit stream.
- * Same concepts as "extract" (see comments above).
- * The data mangled in the bit stream remains in little endian
- * order the whole time. It make more sense to talk about
- * endianness of register values by considering a register
- * a "cached" copy of the little endiad bit stream.
- */
-static void implement(const struct hid_device *hid, __u8 *report,
- unsigned offset, unsigned n, __u32 value)
-{
- u64 x;
- u64 m = (1ULL << n) - 1;
-
- if (n > 32)
- hid_warn(hid, "%s() called with n (%d) > 32! (%s)\n",
- __func__, n, current->comm);
-
- if (value > m)
- hid_warn(hid, "%s() called with too large value %d! (%s)\n",
- __func__, value, current->comm);
- WARN_ON(value > m);
- value &= m;
-
- report += offset >> 3;
- offset &= 7;
-
- x = get_unaligned_le64(report);
- x &= ~(m << offset);
- x |= ((u64)value) << offset;
- put_unaligned_le64(x, report);
-}
-
-/*
- * Search an array for a value.
- */
-
-static int search(__s32 *array, __s32 value, unsigned n)
-{
- while (n--) {
- if (*array++ == value)
- return 0;
- }
- return -1;
-}
-
-/**
- * hid_match_report - check if driver's raw_event should be called
- *
- * @hid: hid device
- * @report_type: type to match against
- *
- * compare hid->driver->report_table->report_type to report->type
- */
-static int hid_match_report(struct hid_device *hid, struct hid_report *report)
-{
- const struct hid_report_id *id = hid->driver->report_table;
-
- if (!id) /* NULL means all */
- return 1;
-
- for (; id->report_type != HID_TERMINATOR; id++)
- if (id->report_type == HID_ANY_ID ||
- id->report_type == report->type)
- return 1;
- return 0;
-}
-
-/**
- * hid_match_usage - check if driver's event should be called
- *
- * @hid: hid device
- * @usage: usage to match against
- *
- * compare hid->driver->usage_table->usage_{type,code} to
- * usage->usage_{type,code}
- */
-static int hid_match_usage(struct hid_device *hid, struct hid_usage *usage)
-{
- const struct hid_usage_id *id = hid->driver->usage_table;
-
- if (!id) /* NULL means all */
- return 1;
-
- for (; id->usage_type != HID_ANY_ID - 1; id++)
- if ((id->usage_hid == HID_ANY_ID ||
- id->usage_hid == usage->hid) &&
- (id->usage_type == HID_ANY_ID ||
- id->usage_type == usage->type) &&
- (id->usage_code == HID_ANY_ID ||
- id->usage_code == usage->code))
- return 1;
- return 0;
-}
-
-static void hid_process_event(struct hid_device *hid, struct hid_field *field,
- struct hid_usage *usage, __s32 value, int interrupt)
-{
- struct hid_driver *hdrv = hid->driver;
- int ret;
-
- hid_dump_input(hid, usage, value);
-
- if (hdrv && hdrv->event && hid_match_usage(hid, usage)) {
- ret = hdrv->event(hid, field, usage, value);
- if (ret != 0) {
- if (ret < 0)
- hid_err(hid, "%s's event failed with %d\n",
- hdrv->name, ret);
- return;
- }
- }
-
- if (hid->claimed & HID_CLAIMED_INPUT)
- hidinput_hid_event(hid, field, usage, value);
- if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event)
- hid->hiddev_hid_event(hid, field, usage, value);
-}
-
-/*
- * Analyse a received field, and fetch the data from it. The field
- * content is stored for next report processing (we do differential
- * reporting to the layer).
- */
-
-static void hid_input_field(struct hid_device *hid, struct hid_field *field,
- __u8 *data, int interrupt)
-{
- unsigned n;
- unsigned count = field->report_count;
- unsigned offset = field->report_offset;
- unsigned size = field->report_size;
- __s32 min = field->logical_minimum;
- __s32 max = field->logical_maximum;
- __s32 *value;
-
- value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC);
- if (!value)
- return;
-
- for (n = 0; n < count; n++) {
-
- value[n] = min < 0 ?
- snto32(extract(hid, data, offset + n * size, size),
- size) :
- extract(hid, data, offset + n * size, size);
-
- /* Ignore report if ErrorRollOver */
- if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
- value[n] >= min && value[n] <= max &&
- field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
- goto exit;
- }
-
- for (n = 0; n < count; n++) {
-
- if (HID_MAIN_ITEM_VARIABLE & field->flags) {
- hid_process_event(hid, field, &field->usage[n], value[n], interrupt);
- continue;
- }
-
- if (field->value[n] >= min && field->value[n] <= max
- && field->usage[field->value[n] - min].hid
- && search(value, field->value[n], count))
- hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
-
- if (value[n] >= min && value[n] <= max
- && field->usage[value[n] - min].hid
- && search(field->value, value[n], count))
- hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
- }
-
- memcpy(field->value, value, count * sizeof(__s32));
-exit:
- kfree(value);
-}
-
-/*
- * Output the field into the report.
- */
-
-static void hid_output_field(const struct hid_device *hid,
- struct hid_field *field, __u8 *data)
-{
- unsigned count = field->report_count;
- unsigned offset = field->report_offset;
- unsigned size = field->report_size;
- unsigned n;
-
- for (n = 0; n < count; n++) {
- if (field->logical_minimum < 0) /* signed values */
- implement(hid, data, offset + n * size, size,
- s32ton(field->value[n], size));
- else /* unsigned values */
- implement(hid, data, offset + n * size, size,
- field->value[n]);
- }
-}
-
-/*
- * Create a report.
- */
-
-void hid_output_report(struct hid_report *report, __u8 *data)
-{
- unsigned n;
-
- if (report->id > 0)
- *data++ = report->id;
-
- memset(data, 0, ((report->size - 1) >> 3) + 1);
- for (n = 0; n < report->maxfield; n++)
- hid_output_field(report->device, report->field[n], data);
-}
-EXPORT_SYMBOL_GPL(hid_output_report);
-
-/*
- * Set a field value. The report this field belongs to has to be
- * created and transferred to the device, to set this value in the
- * device.
- */
-
-int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
-{
- unsigned size = field->report_size;
-
- hid_dump_input(field->report->device, field->usage + offset, value);
-
- if (offset >= field->report_count) {
- hid_err(field->report->device, "offset (%d) exceeds report_count (%d)\n",
- offset, field->report_count);
- return -1;
- }
- if (field->logical_minimum < 0) {
- if (value != snto32(s32ton(value, size), size)) {
- hid_err(field->report->device, "value %d is out of range\n", value);
- return -1;
- }
- }
- field->value[offset] = value;
- return 0;
-}
-EXPORT_SYMBOL_GPL(hid_set_field);
-
-static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
- const u8 *data)
-{
- struct hid_report *report;
- unsigned int n = 0; /* Normally report number is 0 */
-
- /* Device uses numbered reports, data[0] is report number */
- if (report_enum->numbered)
- n = *data;
-
- report = report_enum->report_id_hash[n];
- if (report == NULL)
- dbg_hid("undefined report_id %u received\n", n);
-
- return report;
-}
-
-void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
- int interrupt)
-{
- struct hid_report_enum *report_enum = hid->report_enum + type;
- struct hid_report *report;
- unsigned int a;
- int rsize, csize = size;
- u8 *cdata = data;
-
- report = hid_get_report(report_enum, data);
- if (!report)
- return;
-
- if (report_enum->numbered) {
- cdata++;
- csize--;
- }
-
- rsize = ((report->size - 1) >> 3) + 1;
-
- if (rsize > HID_MAX_BUFFER_SIZE)
- rsize = HID_MAX_BUFFER_SIZE;
-
- if (csize < rsize) {
- dbg_hid("report %d is too short, (%d < %d)\n", report->id,
- csize, rsize);
- memset(cdata + csize, 0, rsize - csize);
- }
-
- if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
- hid->hiddev_report_event(hid, report);
- if (hid->claimed & HID_CLAIMED_HIDRAW)
- hidraw_report_event(hid, data, size);
-
- for (a = 0; a < report->maxfield; a++)
- hid_input_field(hid, report->field[a], cdata, interrupt);
-
- if (hid->claimed & HID_CLAIMED_INPUT)
- hidinput_report_event(hid, report);
-}
-EXPORT_SYMBOL_GPL(hid_report_raw_event);
-
-/**
- * hid_input_report - report data from lower layer (usb, bt...)
- *
- * @hid: hid device
- * @type: HID report type (HID_*_REPORT)
- * @data: report contents
- * @size: size of data parameter
- * @interrupt: distinguish between interrupt and control transfers
- *
- * This is data entry for lower layers.
- */
-int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt)
-{
- struct hid_report_enum *report_enum;
- struct hid_driver *hdrv;
- struct hid_report *report;
- char *buf;
- unsigned int i;
- int ret = 0;
-
- if (!hid)
- return -ENODEV;
-
- if (down_trylock(&hid->driver_lock))
- return -EBUSY;
-
- if (!hid->driver) {
- ret = -ENODEV;
- goto unlock;
- }
- report_enum = hid->report_enum + type;
- hdrv = hid->driver;
-
- if (!size) {
- dbg_hid("empty report\n");
- ret = -1;
- goto unlock;
- }
-
- buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
-
- if (!buf)
- goto nomem;
-
- /* dump the report */
- snprintf(buf, HID_DEBUG_BUFSIZE - 1,
- "\nreport (size %u) (%snumbered) = ", size, report_enum->numbered ? "" : "un");
- hid_debug_event(hid, buf);
-
- for (i = 0; i < size; i++) {
- snprintf(buf, HID_DEBUG_BUFSIZE - 1,
- " %02x", data[i]);
- hid_debug_event(hid, buf);
- }
- hid_debug_event(hid, "\n");
- kfree(buf);
-
-nomem:
- report = hid_get_report(report_enum, data);
-
- if (!report) {
- ret = -1;
- goto unlock;
- }
-
- if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
- ret = hdrv->raw_event(hid, report, data, size);
- if (ret != 0) {
- ret = ret < 0 ? ret : 0;
- goto unlock;
- }
- }
-
- hid_report_raw_event(hid, type, data, size, interrupt);
-
-unlock:
- up(&hid->driver_lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(hid_input_report);
-
-static bool hid_match_one_id(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- return id->bus == hdev->bus &&
- (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) &&
- (id->product == HID_ANY_ID || id->product == hdev->product);
-}
-
-const struct hid_device_id *hid_match_id(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- for (; id->bus; id++)
- if (hid_match_one_id(hdev, id))
- return id;
-
- return NULL;
-}
-
-static const struct hid_device_id hid_hiddev_list[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1) },
- { }
-};
-
-static bool hid_hiddev(struct hid_device *hdev)
-{
- return !!hid_match_id(hdev, hid_hiddev_list);
-}
-
-
-static ssize_t
-read_report_descriptor(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
-
- if (off >= hdev->rsize)
- return 0;
-
- if (off + count > hdev->rsize)
- count = hdev->rsize - off;
-
- memcpy(buf, hdev->rdesc + off, count);
-
- return count;
-}
-
-static struct bin_attribute dev_bin_attr_report_desc = {
- .attr = { .name = "report_descriptor", .mode = 0444 },
- .read = read_report_descriptor,
- .size = HID_MAX_DESCRIPTOR_SIZE,
-};
-
-int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
-{
- static const char *types[] = { "Device", "Pointer", "Mouse", "Device",
- "Joystick", "Gamepad", "Keyboard", "Keypad",
- "Multi-Axis Controller"
- };
- const char *type, *bus;
- char buf[64];
- unsigned int i;
- int len;
- int ret;
-
- if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
- connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
- if (hdev->quirks & HID_QUIRK_HIDINPUT_FORCE)
- connect_mask |= HID_CONNECT_HIDINPUT_FORCE;
- if (hdev->bus != BUS_USB)
- connect_mask &= ~HID_CONNECT_HIDDEV;
- if (hid_hiddev(hdev))
- connect_mask |= HID_CONNECT_HIDDEV_FORCE;
-
- if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev,
- connect_mask & HID_CONNECT_HIDINPUT_FORCE))
- hdev->claimed |= HID_CLAIMED_INPUT;
- if (hdev->quirks & HID_QUIRK_MULTITOUCH) {
- /* this device should be handled by hid-multitouch, skip it */
- return -ENODEV;
- }
-
- if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect &&
- !hdev->hiddev_connect(hdev,
- connect_mask & HID_CONNECT_HIDDEV_FORCE))
- hdev->claimed |= HID_CLAIMED_HIDDEV;
- if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev))
- hdev->claimed |= HID_CLAIMED_HIDRAW;
-
- if (!hdev->claimed) {
- hid_err(hdev, "claimed by neither input, hiddev nor hidraw\n");
- return -ENODEV;
- }
-
- if ((hdev->claimed & HID_CLAIMED_INPUT) &&
- (connect_mask & HID_CONNECT_FF) && hdev->ff_init)
- hdev->ff_init(hdev);
-
- len = 0;
- if (hdev->claimed & HID_CLAIMED_INPUT)
- len += sprintf(buf + len, "input");
- if (hdev->claimed & HID_CLAIMED_HIDDEV)
- len += sprintf(buf + len, "%shiddev%d", len ? "," : "",
- hdev->minor);
- if (hdev->claimed & HID_CLAIMED_HIDRAW)
- len += sprintf(buf + len, "%shidraw%d", len ? "," : "",
- ((struct hidraw *)hdev->hidraw)->minor);
-
- type = "Device";
- for (i = 0; i < hdev->maxcollection; i++) {
- struct hid_collection *col = &hdev->collection[i];
- if (col->type == HID_COLLECTION_APPLICATION &&
- (col->usage & HID_USAGE_PAGE) == HID_UP_GENDESK &&
- (col->usage & 0xffff) < ARRAY_SIZE(types)) {
- type = types[col->usage & 0xffff];
- break;
- }
- }
-
- switch (hdev->bus) {
- case BUS_USB:
- bus = "USB";
- break;
- case BUS_BLUETOOTH:
- bus = "BLUETOOTH";
- break;
- default:
- bus = "<UNKNOWN>";
- }
-
- ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
- if (ret)
- hid_warn(hdev,
- "can't create sysfs report descriptor attribute err: %d\n", ret);
-
- hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n",
- buf, bus, hdev->version >> 8, hdev->version & 0xff,
- type, hdev->name, hdev->phys);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(hid_connect);
-
-void hid_disconnect(struct hid_device *hdev)
-{
- device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
- if (hdev->claimed & HID_CLAIMED_INPUT)
- hidinput_disconnect(hdev);
- if (hdev->claimed & HID_CLAIMED_HIDDEV)
- hdev->hiddev_disconnect(hdev);
- if (hdev->claimed & HID_CLAIMED_HIDRAW)
- hidraw_disconnect(hdev);
-}
-EXPORT_SYMBOL_GPL(hid_disconnect);
-
-/* a list of devices for which there is a specialized driver on HID bus */
-static const struct hid_device_id hid_have_special_driver[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
- { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
- { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
- { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
- { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, USB_DEVICE_ID_ACTIONSTAR_1011) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
- { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) },
- { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
- { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_FRUCTEL, USB_DEVICE_ID_GAMETEL_MT_MODE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, USB_DEVICE_ID_GOODTOUCH_000f) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
- { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6650) },
- { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) },
-#if IS_ENABLED(CONFIG_HID_LOGITECH_DJ)
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2) },
-#endif
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT780) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT880) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) },
- { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
- { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_PID_0038) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
-
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
- { }
-};
-
-struct hid_dynid {
- struct list_head list;
- struct hid_device_id id;
-};
-
-/**
- * store_new_id - add a new HID device ID to this driver and re-probe devices
- * @driver: target device driver
- * @buf: buffer for scanning device ID data
- * @count: input size
- *
- * Adds a new dynamic hid device ID to this driver,
- * and causes the driver to probe for all devices again.
- */
-static ssize_t store_new_id(struct device_driver *drv, const char *buf,
- size_t count)
-{
- struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
- struct hid_dynid *dynid;
- __u32 bus, vendor, product;
- unsigned long driver_data = 0;
- int ret;
-
- ret = sscanf(buf, "%x %x %x %lx",
- &bus, &vendor, &product, &driver_data);
- if (ret < 3)
- return -EINVAL;
-
- dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
- if (!dynid)
- return -ENOMEM;
-
- dynid->id.bus = bus;
- dynid->id.vendor = vendor;
- dynid->id.product = product;
- dynid->id.driver_data = driver_data;
-
- spin_lock(&hdrv->dyn_lock);
- list_add_tail(&dynid->list, &hdrv->dyn_list);
- spin_unlock(&hdrv->dyn_lock);
-
- ret = driver_attach(&hdrv->driver);
-
- return ret ? : count;
-}
-static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
-
-static void hid_free_dynids(struct hid_driver *hdrv)
-{
- struct hid_dynid *dynid, *n;
-
- spin_lock(&hdrv->dyn_lock);
- list_for_each_entry_safe(dynid, n, &hdrv->dyn_list, list) {
- list_del(&dynid->list);
- kfree(dynid);
- }
- spin_unlock(&hdrv->dyn_lock);
-}
-
-static const struct hid_device_id *hid_match_device(struct hid_device *hdev,
- struct hid_driver *hdrv)
-{
- struct hid_dynid *dynid;
-
- spin_lock(&hdrv->dyn_lock);
- list_for_each_entry(dynid, &hdrv->dyn_list, list) {
- if (hid_match_one_id(hdev, &dynid->id)) {
- spin_unlock(&hdrv->dyn_lock);
- return &dynid->id;
- }
- }
- spin_unlock(&hdrv->dyn_lock);
-
- return hid_match_id(hdev, hdrv->id_table);
-}
-
-static int hid_bus_match(struct device *dev, struct device_driver *drv)
-{
- struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
-
- if ((hdev->quirks & HID_QUIRK_MULTITOUCH) &&
- !strncmp(hdrv->name, "hid-multitouch", 14))
- return 1;
-
- if (!hid_match_device(hdev, hdrv))
- return 0;
-
- /* generic wants all that don't have specialized driver */
- if (!strncmp(hdrv->name, "generic-", 8) && !hid_ignore_special_drivers)
- return !hid_match_id(hdev, hid_have_special_driver);
-
- return 1;
-}
-
-static int hid_device_probe(struct device *dev)
-{
- struct hid_driver *hdrv = container_of(dev->driver,
- struct hid_driver, driver);
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- const struct hid_device_id *id;
- int ret = 0;
-
- if (down_interruptible(&hdev->driver_lock))
- return -EINTR;
-
- if (!hdev->driver) {
- id = hid_match_device(hdev, hdrv);
- if (id == NULL) {
- if (!((hdev->quirks & HID_QUIRK_MULTITOUCH) &&
- !strncmp(hdrv->name, "hid-multitouch", 14))) {
- ret = -ENODEV;
- goto unlock;
- }
- }
-
- hdev->driver = hdrv;
- if (hdrv->probe) {
- ret = hdrv->probe(hdev, id);
- } else { /* default probe */
- ret = hid_parse(hdev);
- if (!ret)
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- }
- if (ret)
- hdev->driver = NULL;
- }
-unlock:
- up(&hdev->driver_lock);
- return ret;
-}
-
-static int hid_device_remove(struct device *dev)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct hid_driver *hdrv;
-
- if (down_interruptible(&hdev->driver_lock))
- return -EINTR;
-
- hdrv = hdev->driver;
- if (hdrv) {
- if (hdrv->remove)
- hdrv->remove(hdev);
- else /* default remove */
- hid_hw_stop(hdev);
- hdev->driver = NULL;
- }
-
- up(&hdev->driver_lock);
- return 0;
-}
-
-static int hid_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
-
- if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X",
- hdev->bus, hdev->vendor, hdev->product))
- return -ENOMEM;
-
- if (add_uevent_var(env, "HID_NAME=%s", hdev->name))
- return -ENOMEM;
-
- if (add_uevent_var(env, "HID_PHYS=%s", hdev->phys))
- return -ENOMEM;
-
- if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq))
- return -ENOMEM;
-
- if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X",
- hdev->bus, hdev->vendor, hdev->product))
- return -ENOMEM;
-
- return 0;
-}
-
-static struct bus_type hid_bus_type = {
- .name = "hid",
- .match = hid_bus_match,
- .probe = hid_device_probe,
- .remove = hid_device_remove,
- .uevent = hid_uevent,
-};
-
-/* a list of devices that shouldn't be handled by HID core at all */
-static const struct hid_device_id hid_ignore_list[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X) },
- { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01) },
- { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10) },
- { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20) },
- { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21) },
- { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22) },
- { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23) },
- { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) },
- { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)},
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)},
- { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) },
- { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x0004) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x000a) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) },
- { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_KYE, 0x0058) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYVOLTAGE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYCURRENT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIC) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIB) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOTOR) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOSTANALYSER) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOSTANALYSER2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_ABSESP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_AUTODATABUS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MCT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) },
- { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0001) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
- { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
-#if defined(CONFIG_MOUSE_SYNAPTICS_USB) || defined(CONFIG_MOUSE_SYNAPTICS_USB_MODULE)
- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_INT_TP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_CPAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_STICK) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_COMP_TP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WTP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DPAD) },
-#endif
- { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) },
- { }
-};
-
-/**
- * hid_mouse_ignore_list - mouse devices which should not be handled by the hid layer
- *
- * There are composite devices for which we want to ignore only a certain
- * interface. This is a list of devices for which only the mouse interface will
- * be ignored. This allows a dedicated driver to take care of the interface.
- */
-static const struct hid_device_id hid_mouse_ignore_list[] = {
- /* appletouch driver */
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
- { }
-};
-
-static bool hid_ignore(struct hid_device *hdev)
-{
- switch (hdev->vendor) {
- case USB_VENDOR_ID_CODEMERCS:
- /* ignore all Code Mercenaries IOWarrior devices */
- if (hdev->product >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST &&
- hdev->product <= USB_DEVICE_ID_CODEMERCS_IOW_LAST)
- return true;
- break;
- case USB_VENDOR_ID_LOGITECH:
- if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST &&
- hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST)
- return true;
- /*
- * The Keene FM transmitter USB device has the same USB ID as
- * the Logitech AudioHub Speaker, but it should ignore the hid.
- * Check if the name is that of the Keene device.
- * For reference: the name of the AudioHub is
- * "HOLTEK AudioHub Speaker".
- */
- if (hdev->product == USB_DEVICE_ID_LOGITECH_AUDIOHUB &&
- !strcmp(hdev->name, "HOLTEK B-LINK USB Audio "))
- return true;
- break;
- case USB_VENDOR_ID_SOUNDGRAPH:
- if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
- hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST)
- return true;
- break;
- case USB_VENDOR_ID_HANWANG:
- if (hdev->product >= USB_DEVICE_ID_HANWANG_TABLET_FIRST &&
- hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST)
- return true;
- break;
- case USB_VENDOR_ID_JESS:
- if (hdev->product == USB_DEVICE_ID_JESS_YUREX &&
- hdev->type == HID_TYPE_USBNONE)
- return true;
- break;
- }
-
- if (hdev->type == HID_TYPE_USBMOUSE &&
- hid_match_id(hdev, hid_mouse_ignore_list))
- return true;
-
- return !!hid_match_id(hdev, hid_ignore_list);
-}
-
-int hid_add_device(struct hid_device *hdev)
-{
- static atomic_t id = ATOMIC_INIT(0);
- int ret;
-
- if (WARN_ON(hdev->status & HID_STAT_ADDED))
- return -EBUSY;
-
- /* we need to kill them here, otherwise they will stay allocated to
- * wait for coming driver */
- if (!(hdev->quirks & HID_QUIRK_NO_IGNORE)
- && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE)))
- return -ENODEV;
-
- /* XXX hack, any other cleaner solution after the driver core
- * is converted to allow more than 20 bytes as the device name? */
- dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
- hdev->vendor, hdev->product, atomic_inc_return(&id));
-
- hid_debug_register(hdev, dev_name(&hdev->dev));
- ret = device_add(&hdev->dev);
- if (!ret)
- hdev->status |= HID_STAT_ADDED;
- else
- hid_debug_unregister(hdev);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(hid_add_device);
-
-/**
- * hid_allocate_device - allocate new hid device descriptor
- *
- * Allocate and initialize hid device, so that hid_destroy_device might be
- * used to free it.
- *
- * New hid_device pointer is returned on success, otherwise ERR_PTR encoded
- * error value.
- */
-struct hid_device *hid_allocate_device(void)
-{
- struct hid_device *hdev;
- unsigned int i;
- int ret = -ENOMEM;
-
- hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
- if (hdev == NULL)
- return ERR_PTR(ret);
-
- device_initialize(&hdev->dev);
- hdev->dev.release = hid_device_release;
- hdev->dev.bus = &hid_bus_type;
-
- hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS,
- sizeof(struct hid_collection), GFP_KERNEL);
- if (hdev->collection == NULL)
- goto err;
- hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
-
- for (i = 0; i < HID_REPORT_TYPES; i++)
- INIT_LIST_HEAD(&hdev->report_enum[i].report_list);
-
- init_waitqueue_head(&hdev->debug_wait);
- INIT_LIST_HEAD(&hdev->debug_list);
- sema_init(&hdev->driver_lock, 1);
-
- return hdev;
-err:
- put_device(&hdev->dev);
- return ERR_PTR(ret);
-}
-EXPORT_SYMBOL_GPL(hid_allocate_device);
-
-static void hid_remove_device(struct hid_device *hdev)
-{
- if (hdev->status & HID_STAT_ADDED) {
- device_del(&hdev->dev);
- hid_debug_unregister(hdev);
- hdev->status &= ~HID_STAT_ADDED;
- }
-}
-
-/**
- * hid_destroy_device - free previously allocated device
- *
- * @hdev: hid device
- *
- * If you allocate hid_device through hid_allocate_device, you should ever
- * free by this function.
- */
-void hid_destroy_device(struct hid_device *hdev)
-{
- hid_remove_device(hdev);
- put_device(&hdev->dev);
-}
-EXPORT_SYMBOL_GPL(hid_destroy_device);
-
-int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
- const char *mod_name)
-{
- int ret;
-
- hdrv->driver.name = hdrv->name;
- hdrv->driver.bus = &hid_bus_type;
- hdrv->driver.owner = owner;
- hdrv->driver.mod_name = mod_name;
-
- INIT_LIST_HEAD(&hdrv->dyn_list);
- spin_lock_init(&hdrv->dyn_lock);
-
- ret = driver_register(&hdrv->driver);
- if (ret)
- return ret;
-
- ret = driver_create_file(&hdrv->driver, &driver_attr_new_id);
- if (ret)
- driver_unregister(&hdrv->driver);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(__hid_register_driver);
-
-void hid_unregister_driver(struct hid_driver *hdrv)
-{
- driver_remove_file(&hdrv->driver, &driver_attr_new_id);
- driver_unregister(&hdrv->driver);
- hid_free_dynids(hdrv);
-}
-EXPORT_SYMBOL_GPL(hid_unregister_driver);
-
-int hid_check_keys_pressed(struct hid_device *hid)
-{
- struct hid_input *hidinput;
- int i;
-
- if (!(hid->claimed & HID_CLAIMED_INPUT))
- return 0;
-
- list_for_each_entry(hidinput, &hid->inputs, list) {
- for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++)
- if (hidinput->input->key[i])
- return 1;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
-
-static int __init hid_init(void)
-{
- int ret;
-
- if (hid_debug)
- pr_warn("hid_debug is now used solely for parser and driver debugging.\n"
- "debugfs is now used for inspecting the device (report descriptor, reports)\n");
-
- ret = bus_register(&hid_bus_type);
- if (ret) {
- pr_err("can't register hid bus\n");
- goto err;
- }
-
- ret = hidraw_init();
- if (ret)
- goto err_bus;
-
- hid_debug_init();
-
- return 0;
-err_bus:
- bus_unregister(&hid_bus_type);
-err:
- return ret;
-}
-
-static void __exit hid_exit(void)
-{
- hid_debug_exit();
- hidraw_exit();
- bus_unregister(&hid_bus_type);
-}
-
-module_init(hid_init);
-module_exit(hid_exit);
-
-MODULE_AUTHOR("Andreas Gal");
-MODULE_AUTHOR("Vojtech Pavlik");
-MODULE_AUTHOR("Jiri Kosina");
-MODULE_LICENSE(DRIVER_LICENSE);
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-cypress.c b/ANDROID_3.4.5/drivers/hid/hid-cypress.c
deleted file mode 100644
index 2f0be4c6..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-cypress.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * HID driver for some cypress "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define CP_RDESC_SWAPPED_MIN_MAX 0x01
-#define CP_2WHEEL_MOUSE_HACK 0x02
-#define CP_2WHEEL_MOUSE_HACK_ON 0x04
-
-/*
- * Some USB barcode readers from cypress have usage min and usage max in
- * the wrong order
- */
-static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
- unsigned int i;
-
- if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
- return rdesc;
-
- for (i = 0; i < *rsize - 4; i++)
- if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) {
- __u8 tmp;
-
- rdesc[i] = 0x19;
- rdesc[i + 2] = 0x29;
- tmp = rdesc[i + 3];
- rdesc[i + 3] = rdesc[i + 1];
- rdesc[i + 1] = tmp;
- }
- return rdesc;
-}
-
-static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if (!(quirks & CP_2WHEEL_MOUSE_HACK))
- return 0;
-
- if (usage->type == EV_REL && usage->code == REL_WHEEL)
- set_bit(REL_HWHEEL, *bit);
- if (usage->hid == 0x00090005)
- return -1;
-
- return 0;
-}
-
-static int cp_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
- !usage->type || !(quirks & CP_2WHEEL_MOUSE_HACK))
- return 0;
-
- if (usage->hid == 0x00090005) {
- if (value)
- quirks |= CP_2WHEEL_MOUSE_HACK_ON;
- else
- quirks &= ~CP_2WHEEL_MOUSE_HACK_ON;
- hid_set_drvdata(hdev, (void *)quirks);
- return 1;
- }
-
- if (usage->code == REL_WHEEL && (quirks & CP_2WHEEL_MOUSE_HACK_ON)) {
- struct input_dev *input = field->hidinput->input;
-
- input_event(input, usage->type, REL_HWHEEL, value);
- return 1;
- }
-
- return 0;
-}
-
-static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- unsigned long quirks = id->driver_data;
- int ret;
-
- hid_set_drvdata(hdev, (void *)quirks);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- return 0;
-err_free:
- return ret;
-}
-
-static const struct hid_device_id cp_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1),
- .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2),
- .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3),
- .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE),
- .driver_data = CP_2WHEEL_MOUSE_HACK },
- { }
-};
-MODULE_DEVICE_TABLE(hid, cp_devices);
-
-static struct hid_driver cp_driver = {
- .name = "cypress",
- .id_table = cp_devices,
- .report_fixup = cp_report_fixup,
- .input_mapped = cp_input_mapped,
- .event = cp_event,
- .probe = cp_probe,
-};
-
-static int __init cp_init(void)
-{
- return hid_register_driver(&cp_driver);
-}
-
-static void __exit cp_exit(void)
-{
- hid_unregister_driver(&cp_driver);
-}
-
-module_init(cp_init);
-module_exit(cp_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-debug.c b/ANDROID_3.4.5/drivers/hid/hid-debug.c
deleted file mode 100644
index 01dd9a7d..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-debug.c
+++ /dev/null
@@ -1,1104 +0,0 @@
-/*
- * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de>
- * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
- * (c) 2007-2009 Jiri Kosina
- *
- * HID debugging support
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/sched.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/poll.h>
-
-#include <linux/hid.h>
-#include <linux/hid-debug.h>
-
-static struct dentry *hid_debug_root;
-
-struct hid_usage_entry {
- unsigned page;
- unsigned usage;
- const char *description;
-};
-
-static const struct hid_usage_entry hid_usage_table[] = {
- { 0, 0, "Undefined" },
- { 1, 0, "GenericDesktop" },
- {0, 0x01, "Pointer"},
- {0, 0x02, "Mouse"},
- {0, 0x04, "Joystick"},
- {0, 0x05, "GamePad"},
- {0, 0x06, "Keyboard"},
- {0, 0x07, "Keypad"},
- {0, 0x08, "MultiAxis"},
- {0, 0x30, "X"},
- {0, 0x31, "Y"},
- {0, 0x32, "Z"},
- {0, 0x33, "Rx"},
- {0, 0x34, "Ry"},
- {0, 0x35, "Rz"},
- {0, 0x36, "Slider"},
- {0, 0x37, "Dial"},
- {0, 0x38, "Wheel"},
- {0, 0x39, "HatSwitch"},
- {0, 0x3a, "CountedBuffer"},
- {0, 0x3b, "ByteCount"},
- {0, 0x3c, "MotionWakeup"},
- {0, 0x3d, "Start"},
- {0, 0x3e, "Select"},
- {0, 0x40, "Vx"},
- {0, 0x41, "Vy"},
- {0, 0x42, "Vz"},
- {0, 0x43, "Vbrx"},
- {0, 0x44, "Vbry"},
- {0, 0x45, "Vbrz"},
- {0, 0x46, "Vno"},
- {0, 0x80, "SystemControl"},
- {0, 0x81, "SystemPowerDown"},
- {0, 0x82, "SystemSleep"},
- {0, 0x83, "SystemWakeUp"},
- {0, 0x84, "SystemContextMenu"},
- {0, 0x85, "SystemMainMenu"},
- {0, 0x86, "SystemAppMenu"},
- {0, 0x87, "SystemMenuHelp"},
- {0, 0x88, "SystemMenuExit"},
- {0, 0x89, "SystemMenuSelect"},
- {0, 0x8a, "SystemMenuRight"},
- {0, 0x8b, "SystemMenuLeft"},
- {0, 0x8c, "SystemMenuUp"},
- {0, 0x8d, "SystemMenuDown"},
- {0, 0x90, "D-PadUp"},
- {0, 0x91, "D-PadDown"},
- {0, 0x92, "D-PadRight"},
- {0, 0x93, "D-PadLeft"},
- { 2, 0, "Simulation" },
- {0, 0xb0, "Aileron"},
- {0, 0xb1, "AileronTrim"},
- {0, 0xb2, "Anti-Torque"},
- {0, 0xb3, "Autopilot"},
- {0, 0xb4, "Chaff"},
- {0, 0xb5, "Collective"},
- {0, 0xb6, "DiveBrake"},
- {0, 0xb7, "ElectronicCountermeasures"},
- {0, 0xb8, "Elevator"},
- {0, 0xb9, "ElevatorTrim"},
- {0, 0xba, "Rudder"},
- {0, 0xbb, "Throttle"},
- {0, 0xbc, "FlightCommunications"},
- {0, 0xbd, "FlareRelease"},
- {0, 0xbe, "LandingGear"},
- {0, 0xbf, "ToeBrake"},
- { 6, 0, "GenericDeviceControls" },
- {0, 0x20, "BatteryStrength" },
- {0, 0x21, "WirelessChannel" },
- {0, 0x22, "WirelessID" },
- {0, 0x23, "DiscoverWirelessControl" },
- {0, 0x24, "SecurityCodeCharacterEntered" },
- {0, 0x25, "SecurityCodeCharactedErased" },
- {0, 0x26, "SecurityCodeCleared" },
- { 7, 0, "Keyboard" },
- { 8, 0, "LED" },
- {0, 0x01, "NumLock"},
- {0, 0x02, "CapsLock"},
- {0, 0x03, "ScrollLock"},
- {0, 0x04, "Compose"},
- {0, 0x05, "Kana"},
- {0, 0x4b, "GenericIndicator"},
- { 9, 0, "Button" },
- { 10, 0, "Ordinal" },
- { 12, 0, "Consumer" },
- {0, 0x238, "HorizontalWheel"},
- { 13, 0, "Digitizers" },
- {0, 0x01, "Digitizer"},
- {0, 0x02, "Pen"},
- {0, 0x03, "LightPen"},
- {0, 0x04, "TouchScreen"},
- {0, 0x05, "TouchPad"},
- {0, 0x20, "Stylus"},
- {0, 0x21, "Puck"},
- {0, 0x22, "Finger"},
- {0, 0x30, "TipPressure"},
- {0, 0x31, "BarrelPressure"},
- {0, 0x32, "InRange"},
- {0, 0x33, "Touch"},
- {0, 0x34, "UnTouch"},
- {0, 0x35, "Tap"},
- {0, 0x39, "TabletFunctionKey"},
- {0, 0x3a, "ProgramChangeKey"},
- {0, 0x3c, "Invert"},
- {0, 0x42, "TipSwitch"},
- {0, 0x43, "SecondaryTipSwitch"},
- {0, 0x44, "BarrelSwitch"},
- {0, 0x45, "Eraser"},
- {0, 0x46, "TabletPick"},
- {0, 0x47, "Confidence"},
- {0, 0x48, "Width"},
- {0, 0x49, "Height"},
- {0, 0x51, "ContactID"},
- {0, 0x52, "InputMode"},
- {0, 0x53, "DeviceIndex"},
- {0, 0x54, "ContactCount"},
- {0, 0x55, "ContactMaximumNumber"},
- { 15, 0, "PhysicalInterfaceDevice" },
- {0, 0x00, "Undefined"},
- {0, 0x01, "Physical_Interface_Device"},
- {0, 0x20, "Normal"},
- {0, 0x21, "Set_Effect_Report"},
- {0, 0x22, "Effect_Block_Index"},
- {0, 0x23, "Parameter_Block_Offset"},
- {0, 0x24, "ROM_Flag"},
- {0, 0x25, "Effect_Type"},
- {0, 0x26, "ET_Constant_Force"},
- {0, 0x27, "ET_Ramp"},
- {0, 0x28, "ET_Custom_Force_Data"},
- {0, 0x30, "ET_Square"},
- {0, 0x31, "ET_Sine"},
- {0, 0x32, "ET_Triangle"},
- {0, 0x33, "ET_Sawtooth_Up"},
- {0, 0x34, "ET_Sawtooth_Down"},
- {0, 0x40, "ET_Spring"},
- {0, 0x41, "ET_Damper"},
- {0, 0x42, "ET_Inertia"},
- {0, 0x43, "ET_Friction"},
- {0, 0x50, "Duration"},
- {0, 0x51, "Sample_Period"},
- {0, 0x52, "Gain"},
- {0, 0x53, "Trigger_Button"},
- {0, 0x54, "Trigger_Repeat_Interval"},
- {0, 0x55, "Axes_Enable"},
- {0, 0x56, "Direction_Enable"},
- {0, 0x57, "Direction"},
- {0, 0x58, "Type_Specific_Block_Offset"},
- {0, 0x59, "Block_Type"},
- {0, 0x5A, "Set_Envelope_Report"},
- {0, 0x5B, "Attack_Level"},
- {0, 0x5C, "Attack_Time"},
- {0, 0x5D, "Fade_Level"},
- {0, 0x5E, "Fade_Time"},
- {0, 0x5F, "Set_Condition_Report"},
- {0, 0x60, "CP_Offset"},
- {0, 0x61, "Positive_Coefficient"},
- {0, 0x62, "Negative_Coefficient"},
- {0, 0x63, "Positive_Saturation"},
- {0, 0x64, "Negative_Saturation"},
- {0, 0x65, "Dead_Band"},
- {0, 0x66, "Download_Force_Sample"},
- {0, 0x67, "Isoch_Custom_Force_Enable"},
- {0, 0x68, "Custom_Force_Data_Report"},
- {0, 0x69, "Custom_Force_Data"},
- {0, 0x6A, "Custom_Force_Vendor_Defined_Data"},
- {0, 0x6B, "Set_Custom_Force_Report"},
- {0, 0x6C, "Custom_Force_Data_Offset"},
- {0, 0x6D, "Sample_Count"},
- {0, 0x6E, "Set_Periodic_Report"},
- {0, 0x6F, "Offset"},
- {0, 0x70, "Magnitude"},
- {0, 0x71, "Phase"},
- {0, 0x72, "Period"},
- {0, 0x73, "Set_Constant_Force_Report"},
- {0, 0x74, "Set_Ramp_Force_Report"},
- {0, 0x75, "Ramp_Start"},
- {0, 0x76, "Ramp_End"},
- {0, 0x77, "Effect_Operation_Report"},
- {0, 0x78, "Effect_Operation"},
- {0, 0x79, "Op_Effect_Start"},
- {0, 0x7A, "Op_Effect_Start_Solo"},
- {0, 0x7B, "Op_Effect_Stop"},
- {0, 0x7C, "Loop_Count"},
- {0, 0x7D, "Device_Gain_Report"},
- {0, 0x7E, "Device_Gain"},
- {0, 0x7F, "PID_Pool_Report"},
- {0, 0x80, "RAM_Pool_Size"},
- {0, 0x81, "ROM_Pool_Size"},
- {0, 0x82, "ROM_Effect_Block_Count"},
- {0, 0x83, "Simultaneous_Effects_Max"},
- {0, 0x84, "Pool_Alignment"},
- {0, 0x85, "PID_Pool_Move_Report"},
- {0, 0x86, "Move_Source"},
- {0, 0x87, "Move_Destination"},
- {0, 0x88, "Move_Length"},
- {0, 0x89, "PID_Block_Load_Report"},
- {0, 0x8B, "Block_Load_Status"},
- {0, 0x8C, "Block_Load_Success"},
- {0, 0x8D, "Block_Load_Full"},
- {0, 0x8E, "Block_Load_Error"},
- {0, 0x8F, "Block_Handle"},
- {0, 0x90, "PID_Block_Free_Report"},
- {0, 0x91, "Type_Specific_Block_Handle"},
- {0, 0x92, "PID_State_Report"},
- {0, 0x94, "Effect_Playing"},
- {0, 0x95, "PID_Device_Control_Report"},
- {0, 0x96, "PID_Device_Control"},
- {0, 0x97, "DC_Enable_Actuators"},
- {0, 0x98, "DC_Disable_Actuators"},
- {0, 0x99, "DC_Stop_All_Effects"},
- {0, 0x9A, "DC_Device_Reset"},
- {0, 0x9B, "DC_Device_Pause"},
- {0, 0x9C, "DC_Device_Continue"},
- {0, 0x9F, "Device_Paused"},
- {0, 0xA0, "Actuators_Enabled"},
- {0, 0xA4, "Safety_Switch"},
- {0, 0xA5, "Actuator_Override_Switch"},
- {0, 0xA6, "Actuator_Power"},
- {0, 0xA7, "Start_Delay"},
- {0, 0xA8, "Parameter_Block_Size"},
- {0, 0xA9, "Device_Managed_Pool"},
- {0, 0xAA, "Shared_Parameter_Blocks"},
- {0, 0xAB, "Create_New_Effect_Report"},
- {0, 0xAC, "RAM_Pool_Available"},
- { 0x84, 0, "Power Device" },
- { 0x84, 0x02, "PresentStatus" },
- { 0x84, 0x03, "ChangeStatus" },
- { 0x84, 0x04, "UPS" },
- { 0x84, 0x05, "PowerSupply" },
- { 0x84, 0x10, "BatterySystem" },
- { 0x84, 0x11, "BatterySystemID" },
- { 0x84, 0x12, "Battery" },
- { 0x84, 0x13, "BatteryID" },
- { 0x84, 0x14, "Charger" },
- { 0x84, 0x15, "ChargerID" },
- { 0x84, 0x16, "PowerConverter" },
- { 0x84, 0x17, "PowerConverterID" },
- { 0x84, 0x18, "OutletSystem" },
- { 0x84, 0x19, "OutletSystemID" },
- { 0x84, 0x1a, "Input" },
- { 0x84, 0x1b, "InputID" },
- { 0x84, 0x1c, "Output" },
- { 0x84, 0x1d, "OutputID" },
- { 0x84, 0x1e, "Flow" },
- { 0x84, 0x1f, "FlowID" },
- { 0x84, 0x20, "Outlet" },
- { 0x84, 0x21, "OutletID" },
- { 0x84, 0x22, "Gang" },
- { 0x84, 0x24, "PowerSummary" },
- { 0x84, 0x25, "PowerSummaryID" },
- { 0x84, 0x30, "Voltage" },
- { 0x84, 0x31, "Current" },
- { 0x84, 0x32, "Frequency" },
- { 0x84, 0x33, "ApparentPower" },
- { 0x84, 0x35, "PercentLoad" },
- { 0x84, 0x40, "ConfigVoltage" },
- { 0x84, 0x41, "ConfigCurrent" },
- { 0x84, 0x43, "ConfigApparentPower" },
- { 0x84, 0x53, "LowVoltageTransfer" },
- { 0x84, 0x54, "HighVoltageTransfer" },
- { 0x84, 0x56, "DelayBeforeStartup" },
- { 0x84, 0x57, "DelayBeforeShutdown" },
- { 0x84, 0x58, "Test" },
- { 0x84, 0x5a, "AudibleAlarmControl" },
- { 0x84, 0x60, "Present" },
- { 0x84, 0x61, "Good" },
- { 0x84, 0x62, "InternalFailure" },
- { 0x84, 0x65, "Overload" },
- { 0x84, 0x66, "OverCharged" },
- { 0x84, 0x67, "OverTemperature" },
- { 0x84, 0x68, "ShutdownRequested" },
- { 0x84, 0x69, "ShutdownImminent" },
- { 0x84, 0x6b, "SwitchOn/Off" },
- { 0x84, 0x6c, "Switchable" },
- { 0x84, 0x6d, "Used" },
- { 0x84, 0x6e, "Boost" },
- { 0x84, 0x73, "CommunicationLost" },
- { 0x84, 0xfd, "iManufacturer" },
- { 0x84, 0xfe, "iProduct" },
- { 0x84, 0xff, "iSerialNumber" },
- { 0x85, 0, "Battery System" },
- { 0x85, 0x01, "SMBBatteryMode" },
- { 0x85, 0x02, "SMBBatteryStatus" },
- { 0x85, 0x03, "SMBAlarmWarning" },
- { 0x85, 0x04, "SMBChargerMode" },
- { 0x85, 0x05, "SMBChargerStatus" },
- { 0x85, 0x06, "SMBChargerSpecInfo" },
- { 0x85, 0x07, "SMBSelectorState" },
- { 0x85, 0x08, "SMBSelectorPresets" },
- { 0x85, 0x09, "SMBSelectorInfo" },
- { 0x85, 0x29, "RemainingCapacityLimit" },
- { 0x85, 0x2c, "CapacityMode" },
- { 0x85, 0x42, "BelowRemainingCapacityLimit" },
- { 0x85, 0x44, "Charging" },
- { 0x85, 0x45, "Discharging" },
- { 0x85, 0x4b, "NeedReplacement" },
- { 0x85, 0x66, "RemainingCapacity" },
- { 0x85, 0x68, "RunTimeToEmpty" },
- { 0x85, 0x6a, "AverageTimeToFull" },
- { 0x85, 0x83, "DesignCapacity" },
- { 0x85, 0x85, "ManufacturerDate" },
- { 0x85, 0x89, "iDeviceChemistry" },
- { 0x85, 0x8b, "Rechargeable" },
- { 0x85, 0x8f, "iOEMInformation" },
- { 0x85, 0x8d, "CapacityGranularity1" },
- { 0x85, 0xd0, "ACPresent" },
- /* pages 0xff00 to 0xffff are vendor-specific */
- { 0xffff, 0, "Vendor-specific-FF" },
- { 0, 0, NULL }
-};
-
-/* Either output directly into simple seq_file, or (if f == NULL)
- * allocate a separate buffer that will then be passed to the 'events'
- * ringbuffer.
- *
- * This is because these functions can be called both for "one-shot"
- * "rdesc" while resolving, or for blocking "events".
- *
- * This holds both for resolv_usage_page() and hid_resolv_usage().
- */
-static char *resolv_usage_page(unsigned page, struct seq_file *f) {
- const struct hid_usage_entry *p;
- char *buf = NULL;
-
- if (!f) {
- buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
- if (!buf)
- return ERR_PTR(-ENOMEM);
- }
-
- for (p = hid_usage_table; p->description; p++)
- if (p->page == page) {
- if (!f) {
- snprintf(buf, HID_DEBUG_BUFSIZE, "%s",
- p->description);
- return buf;
- }
- else {
- seq_printf(f, "%s", p->description);
- return NULL;
- }
- }
- if (!f)
- snprintf(buf, HID_DEBUG_BUFSIZE, "%04x", page);
- else
- seq_printf(f, "%04x", page);
- return buf;
-}
-
-char *hid_resolv_usage(unsigned usage, struct seq_file *f) {
- const struct hid_usage_entry *p;
- char *buf = NULL;
- int len = 0;
-
- buf = resolv_usage_page(usage >> 16, f);
- if (IS_ERR(buf)) {
- pr_err("error allocating HID debug buffer\n");
- return NULL;
- }
-
-
- if (!f) {
- len = strlen(buf);
- snprintf(buf+len, max(0, HID_DEBUG_BUFSIZE - len), ".");
- len++;
- }
- else {
- seq_printf(f, ".");
- }
- for (p = hid_usage_table; p->description; p++)
- if (p->page == (usage >> 16)) {
- for(++p; p->description && p->usage != 0; p++)
- if (p->usage == (usage & 0xffff)) {
- if (!f)
- snprintf(buf + len,
- max(0,HID_DEBUG_BUFSIZE - len - 1),
- "%s", p->description);
- else
- seq_printf(f,
- "%s",
- p->description);
- return buf;
- }
- break;
- }
- if (!f)
- snprintf(buf + len, max(0, HID_DEBUG_BUFSIZE - len - 1),
- "%04x", usage & 0xffff);
- else
- seq_printf(f, "%04x", usage & 0xffff);
- return buf;
-}
-EXPORT_SYMBOL_GPL(hid_resolv_usage);
-
-static void tab(int n, struct seq_file *f) {
- seq_printf(f, "%*s", n, "");
-}
-
-void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
- int j;
-
- if (field->physical) {
- tab(n, f);
- seq_printf(f, "Physical(");
- hid_resolv_usage(field->physical, f); seq_printf(f, ")\n");
- }
- if (field->logical) {
- tab(n, f);
- seq_printf(f, "Logical(");
- hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
- }
- if (field->application) {
- tab(n, f);
- seq_printf(f, "Application(");
- hid_resolv_usage(field->application, f); seq_printf(f, ")\n");
- }
- tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
- for (j = 0; j < field->maxusage; j++) {
- tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
- }
- if (field->logical_minimum != field->logical_maximum) {
- tab(n, f); seq_printf(f, "Logical Minimum(%d)\n", field->logical_minimum);
- tab(n, f); seq_printf(f, "Logical Maximum(%d)\n", field->logical_maximum);
- }
- if (field->physical_minimum != field->physical_maximum) {
- tab(n, f); seq_printf(f, "Physical Minimum(%d)\n", field->physical_minimum);
- tab(n, f); seq_printf(f, "Physical Maximum(%d)\n", field->physical_maximum);
- }
- if (field->unit_exponent) {
- tab(n, f); seq_printf(f, "Unit Exponent(%d)\n", field->unit_exponent);
- }
- if (field->unit) {
- static const char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
- static const char *units[5][8] = {
- { "None", "None", "None", "None", "None", "None", "None", "None" },
- { "None", "Centimeter", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
- { "None", "Radians", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
- { "None", "Inch", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" },
- { "None", "Degrees", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }
- };
-
- int i;
- int sys;
- __u32 data = field->unit;
-
- /* First nibble tells us which system we're in. */
- sys = data & 0xf;
- data >>= 4;
-
- if(sys > 4) {
- tab(n, f); seq_printf(f, "Unit(Invalid)\n");
- }
- else {
- int earlier_unit = 0;
-
- tab(n, f); seq_printf(f, "Unit(%s : ", systems[sys]);
-
- for (i=1 ; i<sizeof(__u32)*2 ; i++) {
- char nibble = data & 0xf;
- data >>= 4;
- if (nibble != 0) {
- if(earlier_unit++ > 0)
- seq_printf(f, "*");
- seq_printf(f, "%s", units[sys][i]);
- if(nibble != 1) {
- /* This is a _signed_ nibble(!) */
-
- int val = nibble & 0x7;
- if(nibble & 0x08)
- val = -((0x7 & ~val) +1);
- seq_printf(f, "^%d", val);
- }
- }
- }
- seq_printf(f, ")\n");
- }
- }
- tab(n, f); seq_printf(f, "Report Size(%u)\n", field->report_size);
- tab(n, f); seq_printf(f, "Report Count(%u)\n", field->report_count);
- tab(n, f); seq_printf(f, "Report Offset(%u)\n", field->report_offset);
-
- tab(n, f); seq_printf(f, "Flags( ");
- j = field->flags;
- seq_printf(f, "%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
- seq_printf(f, "%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
- seq_printf(f, "%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
- seq_printf(f, "%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
- seq_printf(f, "%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
- seq_printf(f, "%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : "");
- seq_printf(f, "%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
- seq_printf(f, "%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
- seq_printf(f, "%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
- seq_printf(f, ")\n");
-}
-EXPORT_SYMBOL_GPL(hid_dump_field);
-
-void hid_dump_device(struct hid_device *device, struct seq_file *f)
-{
- struct hid_report_enum *report_enum;
- struct hid_report *report;
- struct list_head *list;
- unsigned i,k;
- static const char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
-
- for (i = 0; i < HID_REPORT_TYPES; i++) {
- report_enum = device->report_enum + i;
- list = report_enum->report_list.next;
- while (list != &report_enum->report_list) {
- report = (struct hid_report *) list;
- tab(2, f);
- seq_printf(f, "%s", table[i]);
- if (report->id)
- seq_printf(f, "(%d)", report->id);
- seq_printf(f, "[%s]", table[report->type]);
- seq_printf(f, "\n");
- for (k = 0; k < report->maxfield; k++) {
- tab(4, f);
- seq_printf(f, "Field(%d)\n", k);
- hid_dump_field(report->field[k], 6, f);
- }
- list = list->next;
- }
- }
-}
-EXPORT_SYMBOL_GPL(hid_dump_device);
-
-/* enqueue string to 'events' ring buffer */
-void hid_debug_event(struct hid_device *hdev, char *buf)
-{
- int i;
- struct hid_debug_list *list;
-
- list_for_each_entry(list, &hdev->debug_list, node) {
- for (i = 0; i < strlen(buf); i++)
- list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] =
- buf[i];
- list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE;
- }
-
- wake_up_interruptible(&hdev->debug_wait);
-}
-EXPORT_SYMBOL_GPL(hid_debug_event);
-
-void hid_dump_input(struct hid_device *hdev, struct hid_usage *usage, __s32 value)
-{
- char *buf;
- int len;
-
- buf = hid_resolv_usage(usage->hid, NULL);
- if (!buf)
- return;
- len = strlen(buf);
- snprintf(buf + len, HID_DEBUG_BUFSIZE - len - 1, " = %d\n", value);
-
- hid_debug_event(hdev, buf);
-
- kfree(buf);
- wake_up_interruptible(&hdev->debug_wait);
-
-}
-EXPORT_SYMBOL_GPL(hid_dump_input);
-
-static const char *events[EV_MAX + 1] = {
- [EV_SYN] = "Sync", [EV_KEY] = "Key",
- [EV_REL] = "Relative", [EV_ABS] = "Absolute",
- [EV_MSC] = "Misc", [EV_LED] = "LED",
- [EV_SND] = "Sound", [EV_REP] = "Repeat",
- [EV_FF] = "ForceFeedback", [EV_PWR] = "Power",
- [EV_FF_STATUS] = "ForceFeedbackStatus",
-};
-
-static const char *syncs[3] = {
- [SYN_REPORT] = "Report", [SYN_CONFIG] = "Config",
- [SYN_MT_REPORT] = "MT Report",
-};
-
-static const char *keys[KEY_MAX + 1] = {
- [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc",
- [KEY_1] = "1", [KEY_2] = "2",
- [KEY_3] = "3", [KEY_4] = "4",
- [KEY_5] = "5", [KEY_6] = "6",
- [KEY_7] = "7", [KEY_8] = "8",
- [KEY_9] = "9", [KEY_0] = "0",
- [KEY_MINUS] = "Minus", [KEY_EQUAL] = "Equal",
- [KEY_BACKSPACE] = "Backspace", [KEY_TAB] = "Tab",
- [KEY_Q] = "Q", [KEY_W] = "W",
- [KEY_E] = "E", [KEY_R] = "R",
- [KEY_T] = "T", [KEY_Y] = "Y",
- [KEY_U] = "U", [KEY_I] = "I",
- [KEY_O] = "O", [KEY_P] = "P",
- [KEY_LEFTBRACE] = "LeftBrace", [KEY_RIGHTBRACE] = "RightBrace",
- [KEY_ENTER] = "Enter", [KEY_LEFTCTRL] = "LeftControl",
- [KEY_A] = "A", [KEY_S] = "S",
- [KEY_D] = "D", [KEY_F] = "F",
- [KEY_G] = "G", [KEY_H] = "H",
- [KEY_J] = "J", [KEY_K] = "K",
- [KEY_L] = "L", [KEY_SEMICOLON] = "Semicolon",
- [KEY_APOSTROPHE] = "Apostrophe", [KEY_GRAVE] = "Grave",
- [KEY_LEFTSHIFT] = "LeftShift", [KEY_BACKSLASH] = "BackSlash",
- [KEY_Z] = "Z", [KEY_X] = "X",
- [KEY_C] = "C", [KEY_V] = "V",
- [KEY_B] = "B", [KEY_N] = "N",
- [KEY_M] = "M", [KEY_COMMA] = "Comma",
- [KEY_DOT] = "Dot", [KEY_SLASH] = "Slash",
- [KEY_RIGHTSHIFT] = "RightShift", [KEY_KPASTERISK] = "KPAsterisk",
- [KEY_LEFTALT] = "LeftAlt", [KEY_SPACE] = "Space",
- [KEY_CAPSLOCK] = "CapsLock", [KEY_F1] = "F1",
- [KEY_F2] = "F2", [KEY_F3] = "F3",
- [KEY_F4] = "F4", [KEY_F5] = "F5",
- [KEY_F6] = "F6", [KEY_F7] = "F7",
- [KEY_F8] = "F8", [KEY_F9] = "F9",
- [KEY_F10] = "F10", [KEY_NUMLOCK] = "NumLock",
- [KEY_SCROLLLOCK] = "ScrollLock", [KEY_KP7] = "KP7",
- [KEY_KP8] = "KP8", [KEY_KP9] = "KP9",
- [KEY_KPMINUS] = "KPMinus", [KEY_KP4] = "KP4",
- [KEY_KP5] = "KP5", [KEY_KP6] = "KP6",
- [KEY_KPPLUS] = "KPPlus", [KEY_KP1] = "KP1",
- [KEY_KP2] = "KP2", [KEY_KP3] = "KP3",
- [KEY_KP0] = "KP0", [KEY_KPDOT] = "KPDot",
- [KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd",
- [KEY_F11] = "F11", [KEY_F12] = "F12",
- [KEY_RO] = "RO", [KEY_KATAKANA] = "Katakana",
- [KEY_HIRAGANA] = "HIRAGANA", [KEY_HENKAN] = "Henkan",
- [KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = "Muhenkan",
- [KEY_KPJPCOMMA] = "KPJpComma", [KEY_KPENTER] = "KPEnter",
- [KEY_RIGHTCTRL] = "RightCtrl", [KEY_KPSLASH] = "KPSlash",
- [KEY_SYSRQ] = "SysRq", [KEY_RIGHTALT] = "RightAlt",
- [KEY_LINEFEED] = "LineFeed", [KEY_HOME] = "Home",
- [KEY_UP] = "Up", [KEY_PAGEUP] = "PageUp",
- [KEY_LEFT] = "Left", [KEY_RIGHT] = "Right",
- [KEY_END] = "End", [KEY_DOWN] = "Down",
- [KEY_PAGEDOWN] = "PageDown", [KEY_INSERT] = "Insert",
- [KEY_DELETE] = "Delete", [KEY_MACRO] = "Macro",
- [KEY_MUTE] = "Mute", [KEY_VOLUMEDOWN] = "VolumeDown",
- [KEY_VOLUMEUP] = "VolumeUp", [KEY_POWER] = "Power",
- [KEY_KPEQUAL] = "KPEqual", [KEY_KPPLUSMINUS] = "KPPlusMinus",
- [KEY_PAUSE] = "Pause", [KEY_KPCOMMA] = "KPComma",
- [KEY_HANGUEL] = "Hangeul", [KEY_HANJA] = "Hanja",
- [KEY_YEN] = "Yen", [KEY_LEFTMETA] = "LeftMeta",
- [KEY_RIGHTMETA] = "RightMeta", [KEY_COMPOSE] = "Compose",
- [KEY_STOP] = "Stop", [KEY_AGAIN] = "Again",
- [KEY_PROPS] = "Props", [KEY_UNDO] = "Undo",
- [KEY_FRONT] = "Front", [KEY_COPY] = "Copy",
- [KEY_OPEN] = "Open", [KEY_PASTE] = "Paste",
- [KEY_FIND] = "Find", [KEY_CUT] = "Cut",
- [KEY_HELP] = "Help", [KEY_MENU] = "Menu",
- [KEY_CALC] = "Calc", [KEY_SETUP] = "Setup",
- [KEY_SLEEP] = "Sleep", [KEY_WAKEUP] = "WakeUp",
- [KEY_FILE] = "File", [KEY_SENDFILE] = "SendFile",
- [KEY_DELETEFILE] = "DeleteFile", [KEY_XFER] = "X-fer",
- [KEY_PROG1] = "Prog1", [KEY_PROG2] = "Prog2",
- [KEY_WWW] = "WWW", [KEY_MSDOS] = "MSDOS",
- [KEY_COFFEE] = "Coffee", [KEY_DIRECTION] = "Direction",
- [KEY_CYCLEWINDOWS] = "CycleWindows", [KEY_MAIL] = "Mail",
- [KEY_BOOKMARKS] = "Bookmarks", [KEY_COMPUTER] = "Computer",
- [KEY_BACK] = "Back", [KEY_FORWARD] = "Forward",
- [KEY_CLOSECD] = "CloseCD", [KEY_EJECTCD] = "EjectCD",
- [KEY_EJECTCLOSECD] = "EjectCloseCD", [KEY_NEXTSONG] = "NextSong",
- [KEY_PLAYPAUSE] = "PlayPause", [KEY_PREVIOUSSONG] = "PreviousSong",
- [KEY_STOPCD] = "StopCD", [KEY_RECORD] = "Record",
- [KEY_REWIND] = "Rewind", [KEY_PHONE] = "Phone",
- [KEY_ISO] = "ISOKey", [KEY_CONFIG] = "Config",
- [KEY_HOMEPAGE] = "HomePage", [KEY_REFRESH] = "Refresh",
- [KEY_EXIT] = "Exit", [KEY_MOVE] = "Move",
- [KEY_EDIT] = "Edit", [KEY_SCROLLUP] = "ScrollUp",
- [KEY_SCROLLDOWN] = "ScrollDown", [KEY_KPLEFTPAREN] = "KPLeftParenthesis",
- [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_NEW] = "New",
- [KEY_REDO] = "Redo", [KEY_F13] = "F13",
- [KEY_F14] = "F14", [KEY_F15] = "F15",
- [KEY_F16] = "F16", [KEY_F17] = "F17",
- [KEY_F18] = "F18", [KEY_F19] = "F19",
- [KEY_F20] = "F20", [KEY_F21] = "F21",
- [KEY_F22] = "F22", [KEY_F23] = "F23",
- [KEY_F24] = "F24", [KEY_PLAYCD] = "PlayCD",
- [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3",
- [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend",
- [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play",
- [KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost",
- [KEY_PRINT] = "Print", [KEY_HP] = "HP",
- [KEY_CAMERA] = "Camera", [KEY_SOUND] = "Sound",
- [KEY_QUESTION] = "Question", [KEY_EMAIL] = "Email",
- [KEY_CHAT] = "Chat", [KEY_SEARCH] = "Search",
- [KEY_CONNECT] = "Connect", [KEY_FINANCE] = "Finance",
- [KEY_SPORT] = "Sport", [KEY_SHOP] = "Shop",
- [KEY_ALTERASE] = "AlternateErase", [KEY_CANCEL] = "Cancel",
- [KEY_BRIGHTNESSDOWN] = "BrightnessDown", [KEY_BRIGHTNESSUP] = "BrightnessUp",
- [KEY_MEDIA] = "Media", [KEY_UNKNOWN] = "Unknown",
- [BTN_0] = "Btn0", [BTN_1] = "Btn1",
- [BTN_2] = "Btn2", [BTN_3] = "Btn3",
- [BTN_4] = "Btn4", [BTN_5] = "Btn5",
- [BTN_6] = "Btn6", [BTN_7] = "Btn7",
- [BTN_8] = "Btn8", [BTN_9] = "Btn9",
- [BTN_LEFT] = "LeftBtn", [BTN_RIGHT] = "RightBtn",
- [BTN_MIDDLE] = "MiddleBtn", [BTN_SIDE] = "SideBtn",
- [BTN_EXTRA] = "ExtraBtn", [BTN_FORWARD] = "ForwardBtn",
- [BTN_BACK] = "BackBtn", [BTN_TASK] = "TaskBtn",
- [BTN_TRIGGER] = "Trigger", [BTN_THUMB] = "ThumbBtn",
- [BTN_THUMB2] = "ThumbBtn2", [BTN_TOP] = "TopBtn",
- [BTN_TOP2] = "TopBtn2", [BTN_PINKIE] = "PinkieBtn",
- [BTN_BASE] = "BaseBtn", [BTN_BASE2] = "BaseBtn2",
- [BTN_BASE3] = "BaseBtn3", [BTN_BASE4] = "BaseBtn4",
- [BTN_BASE5] = "BaseBtn5", [BTN_BASE6] = "BaseBtn6",
- [BTN_DEAD] = "BtnDead", [BTN_A] = "BtnA",
- [BTN_B] = "BtnB", [BTN_C] = "BtnC",
- [BTN_X] = "BtnX", [BTN_Y] = "BtnY",
- [BTN_Z] = "BtnZ", [BTN_TL] = "BtnTL",
- [BTN_TR] = "BtnTR", [BTN_TL2] = "BtnTL2",
- [BTN_TR2] = "BtnTR2", [BTN_SELECT] = "BtnSelect",
- [BTN_START] = "BtnStart", [BTN_MODE] = "BtnMode",
- [BTN_THUMBL] = "BtnThumbL", [BTN_THUMBR] = "BtnThumbR",
- [BTN_TOOL_PEN] = "ToolPen", [BTN_TOOL_RUBBER] = "ToolRubber",
- [BTN_TOOL_BRUSH] = "ToolBrush", [BTN_TOOL_PENCIL] = "ToolPencil",
- [BTN_TOOL_AIRBRUSH] = "ToolAirbrush", [BTN_TOOL_FINGER] = "ToolFinger",
- [BTN_TOOL_MOUSE] = "ToolMouse", [BTN_TOOL_LENS] = "ToolLens",
- [BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus",
- [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "ToolDoubleTap",
- [BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_GEAR_DOWN] = "WheelBtn",
- [BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok",
- [KEY_SELECT] = "Select", [KEY_GOTO] = "Goto",
- [KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2",
- [KEY_OPTION] = "Option", [KEY_INFO] = "Info",
- [KEY_TIME] = "Time", [KEY_VENDOR] = "Vendor",
- [KEY_ARCHIVE] = "Archive", [KEY_PROGRAM] = "Program",
- [KEY_CHANNEL] = "Channel", [KEY_FAVORITES] = "Favorites",
- [KEY_EPG] = "EPG", [KEY_PVR] = "PVR",
- [KEY_MHP] = "MHP", [KEY_LANGUAGE] = "Language",
- [KEY_TITLE] = "Title", [KEY_SUBTITLE] = "Subtitle",
- [KEY_ANGLE] = "Angle", [KEY_ZOOM] = "Zoom",
- [KEY_MODE] = "Mode", [KEY_KEYBOARD] = "Keyboard",
- [KEY_SCREEN] = "Screen", [KEY_PC] = "PC",
- [KEY_TV] = "TV", [KEY_TV2] = "TV2",
- [KEY_VCR] = "VCR", [KEY_VCR2] = "VCR2",
- [KEY_SAT] = "Sat", [KEY_SAT2] = "Sat2",
- [KEY_CD] = "CD", [KEY_TAPE] = "Tape",
- [KEY_RADIO] = "Radio", [KEY_TUNER] = "Tuner",
- [KEY_PLAYER] = "Player", [KEY_TEXT] = "Text",
- [KEY_DVD] = "DVD", [KEY_AUX] = "Aux",
- [KEY_MP3] = "MP3", [KEY_AUDIO] = "Audio",
- [KEY_VIDEO] = "Video", [KEY_DIRECTORY] = "Directory",
- [KEY_LIST] = "List", [KEY_MEMO] = "Memo",
- [KEY_CALENDAR] = "Calendar", [KEY_RED] = "Red",
- [KEY_GREEN] = "Green", [KEY_YELLOW] = "Yellow",
- [KEY_BLUE] = "Blue", [KEY_CHANNELUP] = "ChannelUp",
- [KEY_CHANNELDOWN] = "ChannelDown", [KEY_FIRST] = "First",
- [KEY_LAST] = "Last", [KEY_AB] = "AB",
- [KEY_NEXT] = "Next", [KEY_RESTART] = "Restart",
- [KEY_SLOW] = "Slow", [KEY_SHUFFLE] = "Shuffle",
- [KEY_BREAK] = "Break", [KEY_PREVIOUS] = "Previous",
- [KEY_DIGITS] = "Digits", [KEY_TEEN] = "TEEN",
- [KEY_TWEN] = "TWEN", [KEY_DEL_EOL] = "DeleteEOL",
- [KEY_DEL_EOS] = "DeleteEOS", [KEY_INS_LINE] = "InsertLine",
- [KEY_DEL_LINE] = "DeleteLine",
- [KEY_SEND] = "Send", [KEY_REPLY] = "Reply",
- [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save",
- [KEY_DOCUMENTS] = "Documents", [KEY_SPELLCHECK] = "SpellCheck",
- [KEY_LOGOFF] = "Logoff",
- [KEY_FN] = "Fn", [KEY_FN_ESC] = "Fn+ESC",
- [KEY_FN_1] = "Fn+1", [KEY_FN_2] = "Fn+2",
- [KEY_FN_B] = "Fn+B", [KEY_FN_D] = "Fn+D",
- [KEY_FN_E] = "Fn+E", [KEY_FN_F] = "Fn+F",
- [KEY_FN_S] = "Fn+S",
- [KEY_FN_F1] = "Fn+F1", [KEY_FN_F2] = "Fn+F2",
- [KEY_FN_F3] = "Fn+F3", [KEY_FN_F4] = "Fn+F4",
- [KEY_FN_F5] = "Fn+F5", [KEY_FN_F6] = "Fn+F6",
- [KEY_FN_F7] = "Fn+F7", [KEY_FN_F8] = "Fn+F8",
- [KEY_FN_F9] = "Fn+F9", [KEY_FN_F10] = "Fn+F10",
- [KEY_FN_F11] = "Fn+F11", [KEY_FN_F12] = "Fn+F12",
- [KEY_KBDILLUMTOGGLE] = "KbdIlluminationToggle",
- [KEY_KBDILLUMDOWN] = "KbdIlluminationDown",
- [KEY_KBDILLUMUP] = "KbdIlluminationUp",
- [KEY_SWITCHVIDEOMODE] = "SwitchVideoMode",
-};
-
-static const char *relatives[REL_MAX + 1] = {
- [REL_X] = "X", [REL_Y] = "Y",
- [REL_Z] = "Z", [REL_RX] = "Rx",
- [REL_RY] = "Ry", [REL_RZ] = "Rz",
- [REL_HWHEEL] = "HWheel", [REL_DIAL] = "Dial",
- [REL_WHEEL] = "Wheel", [REL_MISC] = "Misc",
-};
-
-static const char *absolutes[ABS_CNT] = {
- [ABS_X] = "X", [ABS_Y] = "Y",
- [ABS_Z] = "Z", [ABS_RX] = "Rx",
- [ABS_RY] = "Ry", [ABS_RZ] = "Rz",
- [ABS_THROTTLE] = "Throttle", [ABS_RUDDER] = "Rudder",
- [ABS_WHEEL] = "Wheel", [ABS_GAS] = "Gas",
- [ABS_BRAKE] = "Brake", [ABS_HAT0X] = "Hat0X",
- [ABS_HAT0Y] = "Hat0Y", [ABS_HAT1X] = "Hat1X",
- [ABS_HAT1Y] = "Hat1Y", [ABS_HAT2X] = "Hat2X",
- [ABS_HAT2Y] = "Hat2Y", [ABS_HAT3X] = "Hat3X",
- [ABS_HAT3Y] = "Hat 3Y", [ABS_PRESSURE] = "Pressure",
- [ABS_DISTANCE] = "Distance", [ABS_TILT_X] = "XTilt",
- [ABS_TILT_Y] = "YTilt", [ABS_TOOL_WIDTH] = "ToolWidth",
- [ABS_VOLUME] = "Volume", [ABS_MISC] = "Misc",
- [ABS_MT_TOUCH_MAJOR] = "MTMajor",
- [ABS_MT_TOUCH_MINOR] = "MTMinor",
- [ABS_MT_WIDTH_MAJOR] = "MTMajorW",
- [ABS_MT_WIDTH_MINOR] = "MTMinorW",
- [ABS_MT_ORIENTATION] = "MTOrientation",
- [ABS_MT_POSITION_X] = "MTPositionX",
- [ABS_MT_POSITION_Y] = "MTPositionY",
- [ABS_MT_TOOL_TYPE] = "MTToolType",
- [ABS_MT_BLOB_ID] = "MTBlobID",
-};
-
-static const char *misc[MSC_MAX + 1] = {
- [MSC_SERIAL] = "Serial", [MSC_PULSELED] = "Pulseled",
- [MSC_GESTURE] = "Gesture", [MSC_RAW] = "RawData"
-};
-
-static const char *leds[LED_MAX + 1] = {
- [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock",
- [LED_SCROLLL] = "ScrollLock", [LED_COMPOSE] = "Compose",
- [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep",
- [LED_SUSPEND] = "Suspend", [LED_MUTE] = "Mute",
- [LED_MISC] = "Misc",
-};
-
-static const char *repeats[REP_MAX + 1] = {
- [REP_DELAY] = "Delay", [REP_PERIOD] = "Period"
-};
-
-static const char *sounds[SND_MAX + 1] = {
- [SND_CLICK] = "Click", [SND_BELL] = "Bell",
- [SND_TONE] = "Tone"
-};
-
-static const char **names[EV_MAX + 1] = {
- [EV_SYN] = syncs, [EV_KEY] = keys,
- [EV_REL] = relatives, [EV_ABS] = absolutes,
- [EV_MSC] = misc, [EV_LED] = leds,
- [EV_SND] = sounds, [EV_REP] = repeats,
-};
-
-static void hid_resolv_event(__u8 type, __u16 code, struct seq_file *f)
-{
- seq_printf(f, "%s.%s", events[type] ? events[type] : "?",
- names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
-}
-
-static void hid_dump_input_mapping(struct hid_device *hid, struct seq_file *f)
-{
- int i, j, k;
- struct hid_report *report;
- struct hid_usage *usage;
-
- for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
- list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
- for (i = 0; i < report->maxfield; i++) {
- for ( j = 0; j < report->field[i]->maxusage; j++) {
- usage = report->field[i]->usage + j;
- hid_resolv_usage(usage->hid, f);
- seq_printf(f, " ---> ");
- hid_resolv_event(usage->type, usage->code, f);
- seq_printf(f, "\n");
- }
- }
- }
- }
-
-}
-
-
-static int hid_debug_rdesc_show(struct seq_file *f, void *p)
-{
- struct hid_device *hdev = f->private;
- int i;
-
- /* dump HID report descriptor */
- for (i = 0; i < hdev->rsize; i++)
- seq_printf(f, "%02x ", hdev->rdesc[i]);
- seq_printf(f, "\n\n");
-
- /* dump parsed data and input mappings */
- hid_dump_device(hdev, f);
- seq_printf(f, "\n");
- hid_dump_input_mapping(hdev, f);
-
- return 0;
-}
-
-static int hid_debug_rdesc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, hid_debug_rdesc_show, inode->i_private);
-}
-
-static int hid_debug_events_open(struct inode *inode, struct file *file)
-{
- int err = 0;
- struct hid_debug_list *list;
-
- if (!(list = kzalloc(sizeof(struct hid_debug_list), GFP_KERNEL))) {
- err = -ENOMEM;
- goto out;
- }
-
- if (!(list->hid_debug_buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_KERNEL))) {
- err = -ENOMEM;
- kfree(list);
- goto out;
- }
- list->hdev = (struct hid_device *) inode->i_private;
- file->private_data = list;
- mutex_init(&list->read_mutex);
-
- list_add_tail(&list->node, &list->hdev->debug_list);
-
-out:
- return err;
-}
-
-static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct hid_debug_list *list = file->private_data;
- int ret = 0, len;
- DECLARE_WAITQUEUE(wait, current);
-
- mutex_lock(&list->read_mutex);
- while (ret == 0) {
- if (list->head == list->tail) {
- add_wait_queue(&list->hdev->debug_wait, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- while (list->head == list->tail) {
- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
-
- if (!list->hdev || !list->hdev->debug) {
- ret = -EIO;
- break;
- }
-
- /* allow O_NONBLOCK from other threads */
- mutex_unlock(&list->read_mutex);
- schedule();
- mutex_lock(&list->read_mutex);
- set_current_state(TASK_INTERRUPTIBLE);
- }
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&list->hdev->debug_wait, &wait);
- }
-
- if (ret)
- goto out;
-
- /* pass the ringbuffer contents to userspace */
-copy_rest:
- if (list->tail == list->head)
- goto out;
- if (list->tail > list->head) {
- len = list->tail - list->head;
-
- if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
- ret = -EFAULT;
- goto out;
- }
- ret += len;
- list->head += len;
- } else {
- len = HID_DEBUG_BUFSIZE - list->head;
-
- if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
- ret = -EFAULT;
- goto out;
- }
- list->head = 0;
- ret += len;
- goto copy_rest;
- }
-
- }
-out:
- mutex_unlock(&list->read_mutex);
- return ret;
-}
-
-static unsigned int hid_debug_events_poll(struct file *file, poll_table *wait)
-{
- struct hid_debug_list *list = file->private_data;
-
- poll_wait(file, &list->hdev->debug_wait, wait);
- if (list->head != list->tail)
- return POLLIN | POLLRDNORM;
- if (!list->hdev->debug)
- return POLLERR | POLLHUP;
- return 0;
-}
-
-static int hid_debug_events_release(struct inode *inode, struct file *file)
-{
- struct hid_debug_list *list = file->private_data;
-
- list_del(&list->node);
- kfree(list->hid_debug_buf);
- kfree(list);
-
- return 0;
-}
-
-static const struct file_operations hid_debug_rdesc_fops = {
- .open = hid_debug_rdesc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations hid_debug_events_fops = {
- .owner = THIS_MODULE,
- .open = hid_debug_events_open,
- .read = hid_debug_events_read,
- .poll = hid_debug_events_poll,
- .release = hid_debug_events_release,
- .llseek = noop_llseek,
-};
-
-
-void hid_debug_register(struct hid_device *hdev, const char *name)
-{
- hdev->debug_dir = debugfs_create_dir(name, hid_debug_root);
- hdev->debug_rdesc = debugfs_create_file("rdesc", 0400,
- hdev->debug_dir, hdev, &hid_debug_rdesc_fops);
- hdev->debug_events = debugfs_create_file("events", 0400,
- hdev->debug_dir, hdev, &hid_debug_events_fops);
- hdev->debug = 1;
-}
-
-void hid_debug_unregister(struct hid_device *hdev)
-{
- hdev->debug = 0;
- wake_up_interruptible(&hdev->debug_wait);
- debugfs_remove(hdev->debug_rdesc);
- debugfs_remove(hdev->debug_events);
- debugfs_remove(hdev->debug_dir);
-}
-
-void hid_debug_init(void)
-{
- hid_debug_root = debugfs_create_dir("hid", NULL);
-}
-
-void hid_debug_exit(void)
-{
- debugfs_remove_recursive(hid_debug_root);
-}
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-dr.c b/ANDROID_3.4.5/drivers/hid/hid-dr.c
deleted file mode 100644
index e832f44a..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-dr.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Force feedback support for DragonRise Inc. game controllers
- *
- * From what I have gathered, these devices are mass produced in China and are
- * distributed under several vendors. They often share the same design as
- * the original PlayStation DualShock controller.
- *
- * 0079:0006 "DragonRise Inc. Generic USB Joystick "
- * - tested with a Tesun USB-703 game controller.
- *
- * Copyright (c) 2009 Richard Walmsley <richwalm@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#ifdef CONFIG_DRAGONRISE_FF
-#include "usbhid/usbhid.h"
-
-struct drff_device {
- struct hid_report *report;
-};
-
-static int drff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct drff_device *drff = data;
- int strong, weak;
-
- strong = effect->u.rumble.strong_magnitude;
- weak = effect->u.rumble.weak_magnitude;
-
- dbg_hid("called with 0x%04x 0x%04x", strong, weak);
-
- if (strong || weak) {
- strong = strong * 0xff / 0xffff;
- weak = weak * 0xff / 0xffff;
-
- /* While reverse engineering this device, I found that when
- this value is set, it causes the strong rumble to function
- at a near maximum speed, so we'll bypass it. */
- if (weak == 0x0a)
- weak = 0x0b;
-
- drff->report->field[0]->value[0] = 0x51;
- drff->report->field[0]->value[1] = 0x00;
- drff->report->field[0]->value[2] = weak;
- drff->report->field[0]->value[4] = strong;
- usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
-
- drff->report->field[0]->value[0] = 0xfa;
- drff->report->field[0]->value[1] = 0xfe;
- } else {
- drff->report->field[0]->value[0] = 0xf3;
- drff->report->field[0]->value[1] = 0x00;
- }
-
- drff->report->field[0]->value[2] = 0x00;
- drff->report->field[0]->value[4] = 0x00;
- dbg_hid("running with 0x%02x 0x%02x", strong, weak);
- usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int drff_init(struct hid_device *hid)
-{
- struct drff_device *drff;
- struct hid_report *report;
- struct hid_input *hidinput = list_first_entry(&hid->inputs,
- struct hid_input, list);
- struct list_head *report_list =
- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- int error;
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output reports found\n");
- return -ENODEV;
- }
-
- report = list_first_entry(report_list, struct hid_report, list);
- if (report->maxfield < 1) {
- hid_err(hid, "no fields in the report\n");
- return -ENODEV;
- }
-
- if (report->field[0]->report_count < 7) {
- hid_err(hid, "not enough values in the field\n");
- return -ENODEV;
- }
-
- drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL);
- if (!drff)
- return -ENOMEM;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- error = input_ff_create_memless(dev, drff, drff_play);
- if (error) {
- kfree(drff);
- return error;
- }
-
- drff->report = report;
- drff->report->field[0]->value[0] = 0xf3;
- drff->report->field[0]->value[1] = 0x00;
- drff->report->field[0]->value[2] = 0x00;
- drff->report->field[0]->value[3] = 0x00;
- drff->report->field[0]->value[4] = 0x00;
- drff->report->field[0]->value[5] = 0x00;
- drff->report->field[0]->value[6] = 0x00;
- usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
-
- hid_info(hid, "Force Feedback for DragonRise Inc. "
- "game controllers by Richard Walmsley <richwalm@gmail.com>\n");
-
- return 0;
-}
-#else
-static inline int drff_init(struct hid_device *hid)
-{
- return 0;
-}
-#endif
-
-/*
- * The original descriptor of joystick with PID 0x0011, represented by DVTech PC
- * JS19. It seems both copied from another device and a result of confusion
- * either about the specification or about the program used to create the
- * descriptor. In any case, it's a wonder it works on Windows.
- *
- * Usage Page (Desktop), ; Generic desktop controls (01h)
- * Usage (Joystik), ; Joystik (04h, application collection)
- * Collection (Application),
- * Collection (Logical),
- * Report Size (8),
- * Report Count (5),
- * Logical Minimum (0),
- * Logical Maximum (255),
- * Physical Minimum (0),
- * Physical Maximum (255),
- * Usage (X), ; X (30h, dynamic value)
- * Usage (X), ; X (30h, dynamic value)
- * Usage (X), ; X (30h, dynamic value)
- * Usage (X), ; X (30h, dynamic value)
- * Usage (Y), ; Y (31h, dynamic value)
- * Input (Variable),
- * Report Size (4),
- * Report Count (1),
- * Logical Maximum (7),
- * Physical Maximum (315),
- * Unit (Degrees),
- * Usage (00h),
- * Input (Variable, Null State),
- * Unit,
- * Report Size (1),
- * Report Count (10),
- * Logical Maximum (1),
- * Physical Maximum (1),
- * Usage Page (Button), ; Button (09h)
- * Usage Minimum (01h),
- * Usage Maximum (0Ah),
- * Input (Variable),
- * Usage Page (FF00h), ; FF00h, vendor-defined
- * Report Size (1),
- * Report Count (10),
- * Logical Maximum (1),
- * Physical Maximum (1),
- * Usage (01h),
- * Input (Variable),
- * End Collection,
- * Collection (Logical),
- * Report Size (8),
- * Report Count (4),
- * Physical Maximum (255),
- * Logical Maximum (255),
- * Usage (02h),
- * Output (Variable),
- * End Collection,
- * End Collection
- */
-
-/* Size of the original descriptor of the PID 0x0011 joystick */
-#define PID0011_RDESC_ORIG_SIZE 101
-
-/* Fixed report descriptor for PID 0x011 joystick */
-static __u8 pid0011_rdesc_fixed[] = {
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x09, 0x04, /* Usage (Joystik), */
- 0xA1, 0x01, /* Collection (Application), */
- 0xA1, 0x02, /* Collection (Logical), */
- 0x14, /* Logical Minimum (0), */
- 0x75, 0x08, /* Report Size (8), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x01, /* Input (Constant), */
- 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
- 0x95, 0x02, /* Report Count (2), */
- 0x09, 0x30, /* Usage (X), */
- 0x09, 0x31, /* Usage (Y), */
- 0x81, 0x02, /* Input (Variable), */
- 0x75, 0x01, /* Report Size (1), */
- 0x95, 0x04, /* Report Count (4), */
- 0x81, 0x01, /* Input (Constant), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x0A, /* Report Count (10), */
- 0x05, 0x09, /* Usage Page (Button), */
- 0x19, 0x01, /* Usage Minimum (01h), */
- 0x29, 0x0A, /* Usage Maximum (0Ah), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x0A, /* Report Count (10), */
- 0x81, 0x01, /* Input (Constant), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- switch (hdev->product) {
- case 0x0011:
- if (*rsize == PID0011_RDESC_ORIG_SIZE) {
- rdesc = pid0011_rdesc_fixed;
- *rsize = sizeof(pid0011_rdesc_fixed);
- }
- break;
- }
- return rdesc;
-}
-
-static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- dev_dbg(&hdev->dev, "DragonRise Inc. HID hardware probe...");
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- switch (hdev->product) {
- case 0x0006:
- ret = drff_init(hdev);
- if (ret) {
- dev_err(&hdev->dev, "force feedback init failed\n");
- hid_hw_stop(hdev);
- goto err;
- }
- break;
- }
-
- return 0;
-err:
- return ret;
-}
-
-static const struct hid_device_id dr_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006), },
- { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011), },
- { }
-};
-MODULE_DEVICE_TABLE(hid, dr_devices);
-
-static struct hid_driver dr_driver = {
- .name = "dragonrise",
- .id_table = dr_devices,
- .report_fixup = dr_report_fixup,
- .probe = dr_probe,
-};
-
-static int __init dr_init(void)
-{
- return hid_register_driver(&dr_driver);
-}
-
-static void __exit dr_exit(void)
-{
- hid_unregister_driver(&dr_driver);
-}
-
-module_init(dr_init);
-module_exit(dr_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-elecom.c b/ANDROID_3.4.5/drivers/hid/hid-elecom.c
deleted file mode 100644
index 79d0c61e..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-elecom.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * HID driver for Elecom BM084 (bluetooth mouse).
- * Removes a non-existing horizontal wheel from
- * the HID descriptor.
- * (This module is based on "hid-ortek".)
- *
- * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
- hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n");
- rdesc[47] = 0x00;
- }
- return rdesc;
-}
-
-static const struct hid_device_id elecom_devices[] = {
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084)},
- { }
-};
-MODULE_DEVICE_TABLE(hid, elecom_devices);
-
-static struct hid_driver elecom_driver = {
- .name = "elecom",
- .id_table = elecom_devices,
- .report_fixup = elecom_report_fixup
-};
-
-static int __init elecom_init(void)
-{
- return hid_register_driver(&elecom_driver);
-}
-
-static void __exit elecom_exit(void)
-{
- hid_unregister_driver(&elecom_driver);
-}
-
-module_init(elecom_init);
-module_exit(elecom_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-emsff.c b/ANDROID_3.4.5/drivers/hid/hid-emsff.c
deleted file mode 100644
index 2630d483..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-emsff.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Force feedback support for EMS Trio Linker Plus II
- *
- * Copyright (c) 2010 Ignaz Forster <ignaz.forster@gmx.de>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-#include "usbhid/usbhid.h"
-
-struct emsff_device {
- struct hid_report *report;
-};
-
-static int emsff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct emsff_device *emsff = data;
- int weak, strong;
-
- weak = effect->u.rumble.weak_magnitude;
- strong = effect->u.rumble.strong_magnitude;
-
- dbg_hid("called with 0x%04x 0x%04x\n", strong, weak);
-
- weak = weak * 0xff / 0xffff;
- strong = strong * 0xff / 0xffff;
-
- emsff->report->field[0]->value[1] = weak;
- emsff->report->field[0]->value[2] = strong;
-
- dbg_hid("running with 0x%02x 0x%02x\n", strong, weak);
- usbhid_submit_report(hid, emsff->report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int emsff_init(struct hid_device *hid)
-{
- struct emsff_device *emsff;
- struct hid_report *report;
- struct hid_input *hidinput = list_first_entry(&hid->inputs,
- struct hid_input, list);
- struct list_head *report_list =
- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- int error;
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output reports found\n");
- return -ENODEV;
- }
-
- report = list_first_entry(report_list, struct hid_report, list);
- if (report->maxfield < 1) {
- hid_err(hid, "no fields in the report\n");
- return -ENODEV;
- }
-
- if (report->field[0]->report_count < 7) {
- hid_err(hid, "not enough values in the field\n");
- return -ENODEV;
- }
-
- emsff = kzalloc(sizeof(struct emsff_device), GFP_KERNEL);
- if (!emsff)
- return -ENOMEM;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- error = input_ff_create_memless(dev, emsff, emsff_play);
- if (error) {
- kfree(emsff);
- return error;
- }
-
- emsff->report = report;
- emsff->report->field[0]->value[0] = 0x01;
- emsff->report->field[0]->value[1] = 0x00;
- emsff->report->field[0]->value[2] = 0x00;
- emsff->report->field[0]->value[3] = 0x00;
- emsff->report->field[0]->value[4] = 0x00;
- emsff->report->field[0]->value[5] = 0x00;
- emsff->report->field[0]->value[6] = 0x00;
- usbhid_submit_report(hid, emsff->report, USB_DIR_OUT);
-
- hid_info(hid, "force feedback for EMS based devices by Ignaz Forster <ignaz.forster@gmx.de>\n");
-
- return 0;
-}
-
-static int ems_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- ret = emsff_init(hdev);
- if (ret) {
- dev_err(&hdev->dev, "force feedback init failed\n");
- hid_hw_stop(hdev);
- goto err;
- }
-
- return 0;
-err:
- return ret;
-}
-
-static const struct hid_device_id ems_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ems_devices);
-
-static struct hid_driver ems_driver = {
- .name = "hkems",
- .id_table = ems_devices,
- .probe = ems_probe,
-};
-
-static int ems_init(void)
-{
- return hid_register_driver(&ems_driver);
-}
-
-static void ems_exit(void)
-{
- hid_unregister_driver(&ems_driver);
-}
-
-module_init(ems_init);
-module_exit(ems_exit);
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-ezkey.c b/ANDROID_3.4.5/drivers/hid/hid-ezkey.c
deleted file mode 100644
index ca1163e9..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-ezkey.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * HID driver for some ezkey "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define ez_map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c))
-#define ez_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
-
-static int ez_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x230: ez_map_key(BTN_MOUSE); break;
- case 0x231: ez_map_rel(REL_WHEEL); break;
- /*
- * this keyboard has a scrollwheel implemented in
- * totally broken way. We map this usage temporarily
- * to HWHEEL and handle it in the event quirk handler
- */
- case 0x232: ez_map_rel(REL_HWHEEL); break;
- default:
- return 0;
- }
- return 1;
-}
-
-static int ez_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
- !usage->type)
- return 0;
-
- /* handle the temporary quirky mapping to HWHEEL */
- if (usage->type == EV_REL && usage->code == REL_HWHEEL) {
- struct input_dev *input = field->hidinput->input;
- input_event(input, usage->type, REL_WHEEL, -value);
- return 1;
- }
-
- return 0;
-}
-
-static const struct hid_device_id ez_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ez_devices);
-
-static struct hid_driver ez_driver = {
- .name = "ezkey",
- .id_table = ez_devices,
- .input_mapping = ez_input_mapping,
- .event = ez_event,
-};
-
-static int __init ez_init(void)
-{
- return hid_register_driver(&ez_driver);
-}
-
-static void __exit ez_exit(void)
-{
- hid_unregister_driver(&ez_driver);
-}
-
-module_init(ez_init);
-module_exit(ez_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-gaff.c b/ANDROID_3.4.5/drivers/hid/hid-gaff.c
deleted file mode 100644
index f1e1bcf6..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-gaff.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Force feedback support for GreenAsia (Product ID 0x12) based devices
- *
- * The devices are distributed under various names and the same USB device ID
- * can be used in many game controllers.
- *
- *
- * 0e8f:0012 "GreenAsia Inc. USB Joystick "
- * - tested with MANTA Warior MM816 and SpeedLink Strike2 SL-6635.
- *
- * Copyright (c) 2008 Lukasz Lubojanski <lukasz@lubojanski.info>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include "hid-ids.h"
-
-#ifdef CONFIG_GREENASIA_FF
-#include "usbhid/usbhid.h"
-
-struct gaff_device {
- struct hid_report *report;
-};
-
-static int hid_gaff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct gaff_device *gaff = data;
- int left, right;
-
- left = effect->u.rumble.strong_magnitude;
- right = effect->u.rumble.weak_magnitude;
-
- dbg_hid("called with 0x%04x 0x%04x", left, right);
-
- left = left * 0xfe / 0xffff;
- right = right * 0xfe / 0xffff;
-
- gaff->report->field[0]->value[0] = 0x51;
- gaff->report->field[0]->value[1] = 0x0;
- gaff->report->field[0]->value[2] = right;
- gaff->report->field[0]->value[3] = 0;
- gaff->report->field[0]->value[4] = left;
- gaff->report->field[0]->value[5] = 0;
- dbg_hid("running with 0x%02x 0x%02x", left, right);
- usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
-
- gaff->report->field[0]->value[0] = 0xfa;
- gaff->report->field[0]->value[1] = 0xfe;
- gaff->report->field[0]->value[2] = 0x0;
- gaff->report->field[0]->value[4] = 0x0;
-
- usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int gaff_init(struct hid_device *hid)
-{
- struct gaff_device *gaff;
- struct hid_report *report;
- struct hid_input *hidinput = list_entry(hid->inputs.next,
- struct hid_input, list);
- struct list_head *report_list =
- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct list_head *report_ptr = report_list;
- struct input_dev *dev = hidinput->input;
- int error;
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output reports found\n");
- return -ENODEV;
- }
-
- report_ptr = report_ptr->next;
-
- report = list_entry(report_ptr, struct hid_report, list);
- if (report->maxfield < 1) {
- hid_err(hid, "no fields in the report\n");
- return -ENODEV;
- }
-
- if (report->field[0]->report_count < 6) {
- hid_err(hid, "not enough values in the field\n");
- return -ENODEV;
- }
-
- gaff = kzalloc(sizeof(struct gaff_device), GFP_KERNEL);
- if (!gaff)
- return -ENOMEM;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- error = input_ff_create_memless(dev, gaff, hid_gaff_play);
- if (error) {
- kfree(gaff);
- return error;
- }
-
- gaff->report = report;
- gaff->report->field[0]->value[0] = 0x51;
- gaff->report->field[0]->value[1] = 0x00;
- gaff->report->field[0]->value[2] = 0x00;
- gaff->report->field[0]->value[3] = 0x00;
- usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
-
- gaff->report->field[0]->value[0] = 0xfa;
- gaff->report->field[0]->value[1] = 0xfe;
-
- usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
-
- hid_info(hid, "Force Feedback for GreenAsia 0x12 devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n");
-
- return 0;
-}
-#else
-static inline int gaff_init(struct hid_device *hdev)
-{
- return 0;
-}
-#endif
-
-static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- dev_dbg(&hdev->dev, "Greenasia HID hardware probe...");
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- gaff_init(hdev);
-
- return 0;
-err:
- return ret;
-}
-
-static const struct hid_device_id ga_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012), },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ga_devices);
-
-static struct hid_driver ga_driver = {
- .name = "greenasia",
- .id_table = ga_devices,
- .probe = ga_probe,
-};
-
-static int __init ga_init(void)
-{
- return hid_register_driver(&ga_driver);
-}
-
-static void __exit ga_exit(void)
-{
- hid_unregister_driver(&ga_driver);
-}
-
-module_init(ga_init);
-module_exit(ga_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-gyration.c b/ANDROID_3.4.5/drivers/hid/hid-gyration.c
deleted file mode 100644
index e88b951c..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-gyration.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * HID driver for some gyration "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- * Copyright (c) 2006-2008 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define gy_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
- return 0;
-
- set_bit(EV_REP, hi->input->evbit);
- switch (usage->hid & HID_USAGE) {
- /* Reported on Gyration MCE Remote */
- case 0x00d: gy_map_key_clear(KEY_HOME); break;
- case 0x024: gy_map_key_clear(KEY_DVD); break;
- case 0x025: gy_map_key_clear(KEY_PVR); break;
- case 0x046: gy_map_key_clear(KEY_MEDIA); break;
- case 0x047: gy_map_key_clear(KEY_MP3); break;
- case 0x048: gy_map_key_clear(KEY_MEDIA); break;
- case 0x049: gy_map_key_clear(KEY_CAMERA); break;
- case 0x04a: gy_map_key_clear(KEY_VIDEO); break;
- case 0x05a: gy_map_key_clear(KEY_TEXT); break;
- case 0x05b: gy_map_key_clear(KEY_RED); break;
- case 0x05c: gy_map_key_clear(KEY_GREEN); break;
- case 0x05d: gy_map_key_clear(KEY_YELLOW); break;
- case 0x05e: gy_map_key_clear(KEY_BLUE); break;
-
- default:
- return 0;
- }
- return 1;
-}
-
-static int gyration_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
-
- if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput)
- return 0;
-
- if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK &&
- (usage->hid & 0xff) == 0x82) {
- struct input_dev *input = field->hidinput->input;
- input_event(input, usage->type, usage->code, 1);
- input_sync(input);
- input_event(input, usage->type, usage->code, 0);
- input_sync(input);
- return 1;
- }
-
- return 0;
-}
-
-static const struct hid_device_id gyration_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, gyration_devices);
-
-static struct hid_driver gyration_driver = {
- .name = "gyration",
- .id_table = gyration_devices,
- .input_mapping = gyration_input_mapping,
- .event = gyration_event,
-};
-
-static int __init gyration_init(void)
-{
- return hid_register_driver(&gyration_driver);
-}
-
-static void __exit gyration_exit(void)
-{
- hid_unregister_driver(&gyration_driver);
-}
-
-module_init(gyration_init);
-module_exit(gyration_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-holtekff.c b/ANDROID_3.4.5/drivers/hid/hid-holtekff.c
deleted file mode 100644
index 4e754215..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-holtekff.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Force feedback support for Holtek On Line Grip based gamepads
- *
- * These include at least a Brazilian "Clone Joypad Super Power Fire"
- * which uses vendor ID 0x1241 and identifies as "HOLTEK On Line Grip".
- *
- * Copyright (c) 2011 Anssi Hannula <anssi.hannula@iki.fi>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "hid-ids.h"
-
-#ifdef CONFIG_HOLTEK_FF
-#include "usbhid/usbhid.h"
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");
-MODULE_DESCRIPTION("Force feedback support for Holtek On Line Grip based devices");
-
-/*
- * These commands and parameters are currently known:
- *
- * byte 0: command id:
- * 01 set effect parameters
- * 02 play specified effect
- * 03 stop specified effect
- * 04 stop all effects
- * 06 stop all effects
- * (the difference between 04 and 06 isn't known; win driver
- * sends 06,04 on application init, and 06 otherwise)
- *
- * Commands 01 and 02 need to be sent as pairs, i.e. you need to send 01
- * before each 02.
- *
- * The rest of the bytes are parameters. Command 01 takes all of them, and
- * commands 02,03 take only the effect id.
- *
- * byte 1:
- * bits 0-3: effect id:
- * 1: very strong rumble
- * 2: periodic rumble, short intervals
- * 3: very strong rumble
- * 4: periodic rumble, long intervals
- * 5: weak periodic rumble, long intervals
- * 6: weak periodic rumble, short intervals
- * 7: periodic rumble, short intervals
- * 8: strong periodic rumble, short intervals
- * 9: very strong rumble
- * a: causes an error
- * b: very strong periodic rumble, very short intervals
- * c-f: nothing
- * bit 6: right (weak) motor enabled
- * bit 7: left (strong) motor enabled
- *
- * bytes 2-3: time in milliseconds, big-endian
- * bytes 5-6: unknown (win driver seems to use at least 10e0 with effect 1
- * and 0014 with effect 6)
- * byte 7:
- * bits 0-3: effect magnitude
- */
-
-#define HOLTEKFF_MSG_LENGTH 7
-
-static const u8 start_effect_1[] = { 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const u8 stop_all4[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const u8 stop_all6[] = { 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-struct holtekff_device {
- struct hid_field *field;
-};
-
-static void holtekff_send(struct holtekff_device *holtekff,
- struct hid_device *hid,
- const u8 data[HOLTEKFF_MSG_LENGTH])
-{
- int i;
-
- for (i = 0; i < HOLTEKFF_MSG_LENGTH; i++) {
- holtekff->field->value[i] = data[i];
- }
-
- dbg_hid("sending %02x %02x %02x %02x %02x %02x %02x\n", data[0],
- data[1], data[2], data[3], data[4], data[5], data[6]);
-
- usbhid_submit_report(hid, holtekff->field->report, USB_DIR_OUT);
-}
-
-static int holtekff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct holtekff_device *holtekff = data;
- int left, right;
- /* effect type 1, length 65535 msec */
- u8 buf[HOLTEKFF_MSG_LENGTH] =
- { 0x01, 0x01, 0xff, 0xff, 0x10, 0xe0, 0x00 };
-
- left = effect->u.rumble.strong_magnitude;
- right = effect->u.rumble.weak_magnitude;
- dbg_hid("called with 0x%04x 0x%04x\n", left, right);
-
- if (!left && !right) {
- holtekff_send(holtekff, hid, stop_all6);
- return 0;
- }
-
- if (left)
- buf[1] |= 0x80;
- if (right)
- buf[1] |= 0x40;
-
- /* The device takes a single magnitude, so we just sum them up. */
- buf[6] = min(0xf, (left >> 12) + (right >> 12));
-
- holtekff_send(holtekff, hid, buf);
- holtekff_send(holtekff, hid, start_effect_1);
-
- return 0;
-}
-
-static int holtekff_init(struct hid_device *hid)
-{
- struct holtekff_device *holtekff;
- struct hid_report *report;
- struct hid_input *hidinput = list_entry(hid->inputs.next,
- struct hid_input, list);
- struct list_head *report_list =
- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- int error;
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output report found\n");
- return -ENODEV;
- }
-
- report = list_entry(report_list->next, struct hid_report, list);
-
- if (report->maxfield < 1 || report->field[0]->report_count != 7) {
- hid_err(hid, "unexpected output report layout\n");
- return -ENODEV;
- }
-
- holtekff = kzalloc(sizeof(*holtekff), GFP_KERNEL);
- if (!holtekff)
- return -ENOMEM;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- holtekff->field = report->field[0];
-
- /* initialize the same way as win driver does */
- holtekff_send(holtekff, hid, stop_all4);
- holtekff_send(holtekff, hid, stop_all6);
-
- error = input_ff_create_memless(dev, holtekff, holtekff_play);
- if (error) {
- kfree(holtekff);
- return error;
- }
-
- hid_info(hid, "Force feedback for Holtek On Line Grip based devices by Anssi Hannula <anssi.hannula@iki.fi>\n");
-
- return 0;
-}
-#else
-static inline int holtekff_init(struct hid_device *hid)
-{
- return 0;
-}
-#endif
-
-static int holtek_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- holtekff_init(hdev);
-
- return 0;
-err:
- return ret;
-}
-
-static const struct hid_device_id holtek_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, holtek_devices);
-
-static struct hid_driver holtek_driver = {
- .name = "holtek",
- .id_table = holtek_devices,
- .probe = holtek_probe,
-};
-
-static int __init holtek_init(void)
-{
- return hid_register_driver(&holtek_driver);
-}
-
-static void __exit holtek_exit(void)
-{
- hid_unregister_driver(&holtek_driver);
-}
-
-module_init(holtek_init);
-module_exit(holtek_exit);
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-hyperv.c b/ANDROID_3.4.5/drivers/hid/hid-hyperv.c
deleted file mode 100644
index 40663247..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-hyperv.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Copyright (c) 2009, Citrix Systems, Inc.
- * Copyright (c) 2010, Microsoft Corporation.
- * Copyright (c) 2011, Novell Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/completion.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/hiddev.h>
-#include <linux/hyperv.h>
-
-
-struct hv_input_dev_info {
- unsigned int size;
- unsigned short vendor;
- unsigned short product;
- unsigned short version;
- unsigned short reserved[11];
-};
-
-/* The maximum size of a synthetic input message. */
-#define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
-
-/*
- * Current version
- *
- * History:
- * Beta, RC < 2008/1/22 1,0
- * RC > 2008/1/22 2,0
- */
-#define SYNTHHID_INPUT_VERSION_MAJOR 2
-#define SYNTHHID_INPUT_VERSION_MINOR 0
-#define SYNTHHID_INPUT_VERSION (SYNTHHID_INPUT_VERSION_MINOR | \
- (SYNTHHID_INPUT_VERSION_MAJOR << 16))
-
-
-#pragma pack(push, 1)
-/*
- * Message types in the synthetic input protocol
- */
-enum synthhid_msg_type {
- SYNTH_HID_PROTOCOL_REQUEST,
- SYNTH_HID_PROTOCOL_RESPONSE,
- SYNTH_HID_INITIAL_DEVICE_INFO,
- SYNTH_HID_INITIAL_DEVICE_INFO_ACK,
- SYNTH_HID_INPUT_REPORT,
- SYNTH_HID_MAX
-};
-
-/*
- * Basic message structures.
- */
-struct synthhid_msg_hdr {
- enum synthhid_msg_type type;
- u32 size;
-};
-
-struct synthhid_msg {
- struct synthhid_msg_hdr header;
- char data[1]; /* Enclosed message */
-};
-
-union synthhid_version {
- struct {
- u16 minor_version;
- u16 major_version;
- };
- u32 version;
-};
-
-/*
- * Protocol messages
- */
-struct synthhid_protocol_request {
- struct synthhid_msg_hdr header;
- union synthhid_version version_requested;
-};
-
-struct synthhid_protocol_response {
- struct synthhid_msg_hdr header;
- union synthhid_version version_requested;
- unsigned char approved;
-};
-
-struct synthhid_device_info {
- struct synthhid_msg_hdr header;
- struct hv_input_dev_info hid_dev_info;
- struct hid_descriptor hid_descriptor;
-};
-
-struct synthhid_device_info_ack {
- struct synthhid_msg_hdr header;
- unsigned char reserved;
-};
-
-struct synthhid_input_report {
- struct synthhid_msg_hdr header;
- char buffer[1];
-};
-
-#pragma pack(pop)
-
-#define INPUTVSC_SEND_RING_BUFFER_SIZE (10*PAGE_SIZE)
-#define INPUTVSC_RECV_RING_BUFFER_SIZE (10*PAGE_SIZE)
-
-
-enum pipe_prot_msg_type {
- PIPE_MESSAGE_INVALID,
- PIPE_MESSAGE_DATA,
- PIPE_MESSAGE_MAXIMUM
-};
-
-
-struct pipe_prt_msg {
- enum pipe_prot_msg_type type;
- u32 size;
- char data[1];
-};
-
-struct mousevsc_prt_msg {
- enum pipe_prot_msg_type type;
- u32 size;
- union {
- struct synthhid_protocol_request request;
- struct synthhid_protocol_response response;
- struct synthhid_device_info_ack ack;
- };
-};
-
-/*
- * Represents an mousevsc device
- */
-struct mousevsc_dev {
- struct hv_device *device;
- bool init_complete;
- bool connected;
- struct mousevsc_prt_msg protocol_req;
- struct mousevsc_prt_msg protocol_resp;
- /* Synchronize the request/response if needed */
- struct completion wait_event;
- int dev_info_status;
-
- struct hid_descriptor *hid_desc;
- unsigned char *report_desc;
- u32 report_desc_size;
- struct hv_input_dev_info hid_dev_info;
- struct hid_device *hid_device;
-};
-
-
-static struct mousevsc_dev *mousevsc_alloc_device(struct hv_device *device)
-{
- struct mousevsc_dev *input_dev;
-
- input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
-
- if (!input_dev)
- return NULL;
-
- input_dev->device = device;
- hv_set_drvdata(device, input_dev);
- init_completion(&input_dev->wait_event);
- input_dev->init_complete = false;
-
- return input_dev;
-}
-
-static void mousevsc_free_device(struct mousevsc_dev *device)
-{
- kfree(device->hid_desc);
- kfree(device->report_desc);
- hv_set_drvdata(device->device, NULL);
- kfree(device);
-}
-
-static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
- struct synthhid_device_info *device_info)
-{
- int ret = 0;
- struct hid_descriptor *desc;
- struct mousevsc_prt_msg ack;
-
- input_device->dev_info_status = -ENOMEM;
-
- input_device->hid_dev_info = device_info->hid_dev_info;
- desc = &device_info->hid_descriptor;
- if (desc->bLength == 0)
- goto cleanup;
-
- input_device->hid_desc = kzalloc(desc->bLength, GFP_ATOMIC);
-
- if (!input_device->hid_desc)
- goto cleanup;
-
- memcpy(input_device->hid_desc, desc, desc->bLength);
-
- input_device->report_desc_size = desc->desc[0].wDescriptorLength;
- if (input_device->report_desc_size == 0) {
- input_device->dev_info_status = -EINVAL;
- goto cleanup;
- }
-
- input_device->report_desc = kzalloc(input_device->report_desc_size,
- GFP_ATOMIC);
-
- if (!input_device->report_desc) {
- input_device->dev_info_status = -ENOMEM;
- goto cleanup;
- }
-
- memcpy(input_device->report_desc,
- ((unsigned char *)desc) + desc->bLength,
- desc->desc[0].wDescriptorLength);
-
- /* Send the ack */
- memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
-
- ack.type = PIPE_MESSAGE_DATA;
- ack.size = sizeof(struct synthhid_device_info_ack);
-
- ack.ack.header.type = SYNTH_HID_INITIAL_DEVICE_INFO_ACK;
- ack.ack.header.size = 1;
- ack.ack.reserved = 0;
-
- ret = vmbus_sendpacket(input_device->device->channel,
- &ack,
- sizeof(struct pipe_prt_msg) - sizeof(unsigned char) +
- sizeof(struct synthhid_device_info_ack),
- (unsigned long)&ack,
- VM_PKT_DATA_INBAND,
- VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-
- if (!ret)
- input_device->dev_info_status = 0;
-
-cleanup:
- complete(&input_device->wait_event);
-
- return;
-}
-
-static void mousevsc_on_receive(struct hv_device *device,
- struct vmpacket_descriptor *packet)
-{
- struct pipe_prt_msg *pipe_msg;
- struct synthhid_msg *hid_msg;
- struct mousevsc_dev *input_dev = hv_get_drvdata(device);
- struct synthhid_input_report *input_report;
-
- pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
- (packet->offset8 << 3));
-
- if (pipe_msg->type != PIPE_MESSAGE_DATA)
- return;
-
- hid_msg = (struct synthhid_msg *)pipe_msg->data;
-
- switch (hid_msg->header.type) {
- case SYNTH_HID_PROTOCOL_RESPONSE:
- /*
- * While it will be impossible for us to protect against
- * malicious/buggy hypervisor/host, add a check here to
- * ensure we don't corrupt memory.
- */
- if ((pipe_msg->size + sizeof(struct pipe_prt_msg)
- - sizeof(unsigned char))
- > sizeof(struct mousevsc_prt_msg)) {
- WARN_ON(1);
- break;
- }
-
- memcpy(&input_dev->protocol_resp, pipe_msg,
- pipe_msg->size + sizeof(struct pipe_prt_msg) -
- sizeof(unsigned char));
- complete(&input_dev->wait_event);
- break;
-
- case SYNTH_HID_INITIAL_DEVICE_INFO:
- WARN_ON(pipe_msg->size < sizeof(struct hv_input_dev_info));
-
- /*
- * Parse out the device info into device attr,
- * hid desc and report desc
- */
- mousevsc_on_receive_device_info(input_dev,
- (struct synthhid_device_info *)pipe_msg->data);
- break;
- case SYNTH_HID_INPUT_REPORT:
- input_report =
- (struct synthhid_input_report *)pipe_msg->data;
- if (!input_dev->init_complete)
- break;
- hid_input_report(input_dev->hid_device,
- HID_INPUT_REPORT, input_report->buffer,
- input_report->header.size, 1);
- break;
- default:
- pr_err("unsupported hid msg type - type %d len %d",
- hid_msg->header.type, hid_msg->header.size);
- break;
- }
-
-}
-
-static void mousevsc_on_channel_callback(void *context)
-{
- const int packet_size = 0x100;
- int ret;
- struct hv_device *device = context;
- u32 bytes_recvd;
- u64 req_id;
- struct vmpacket_descriptor *desc;
- unsigned char *buffer;
- int bufferlen = packet_size;
-
- buffer = kmalloc(bufferlen, GFP_ATOMIC);
- if (!buffer)
- return;
-
- do {
- ret = vmbus_recvpacket_raw(device->channel, buffer,
- bufferlen, &bytes_recvd, &req_id);
-
- switch (ret) {
- case 0:
- if (bytes_recvd <= 0) {
- kfree(buffer);
- return;
- }
- desc = (struct vmpacket_descriptor *)buffer;
-
- switch (desc->type) {
- case VM_PKT_COMP:
- break;
-
- case VM_PKT_DATA_INBAND:
- mousevsc_on_receive(device, desc);
- break;
-
- default:
- pr_err("unhandled packet type %d, tid %llx len %d\n",
- desc->type, req_id, bytes_recvd);
- break;
- }
-
- break;
-
- case -ENOBUFS:
- kfree(buffer);
- /* Handle large packet */
- bufferlen = bytes_recvd;
- buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
-
- if (!buffer)
- return;
-
- break;
- }
- } while (1);
-
-}
-
-static int mousevsc_connect_to_vsp(struct hv_device *device)
-{
- int ret = 0;
- int t;
- struct mousevsc_dev *input_dev = hv_get_drvdata(device);
- struct mousevsc_prt_msg *request;
- struct mousevsc_prt_msg *response;
-
- request = &input_dev->protocol_req;
- memset(request, 0, sizeof(struct mousevsc_prt_msg));
-
- request->type = PIPE_MESSAGE_DATA;
- request->size = sizeof(struct synthhid_protocol_request);
- request->request.header.type = SYNTH_HID_PROTOCOL_REQUEST;
- request->request.header.size = sizeof(unsigned int);
- request->request.version_requested.version = SYNTHHID_INPUT_VERSION;
-
- ret = vmbus_sendpacket(device->channel, request,
- sizeof(struct pipe_prt_msg) -
- sizeof(unsigned char) +
- sizeof(struct synthhid_protocol_request),
- (unsigned long)request,
- VM_PKT_DATA_INBAND,
- VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
- if (ret)
- goto cleanup;
-
- t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
- if (!t) {
- ret = -ETIMEDOUT;
- goto cleanup;
- }
-
- response = &input_dev->protocol_resp;
-
- if (!response->response.approved) {
- pr_err("synthhid protocol request failed (version %d)\n",
- SYNTHHID_INPUT_VERSION);
- ret = -ENODEV;
- goto cleanup;
- }
-
- t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
- if (!t) {
- ret = -ETIMEDOUT;
- goto cleanup;
- }
-
- /*
- * We should have gotten the device attr, hid desc and report
- * desc at this point
- */
- ret = input_dev->dev_info_status;
-
-cleanup:
- return ret;
-}
-
-static int mousevsc_hid_open(struct hid_device *hid)
-{
- return 0;
-}
-
-static int mousevsc_hid_start(struct hid_device *hid)
-{
- return 0;
-}
-
-static void mousevsc_hid_close(struct hid_device *hid)
-{
-}
-
-static void mousevsc_hid_stop(struct hid_device *hid)
-{
-}
-
-static struct hid_ll_driver mousevsc_ll_driver = {
- .open = mousevsc_hid_open,
- .close = mousevsc_hid_close,
- .start = mousevsc_hid_start,
- .stop = mousevsc_hid_stop,
-};
-
-static struct hid_driver mousevsc_hid_driver;
-
-static int mousevsc_probe(struct hv_device *device,
- const struct hv_vmbus_device_id *dev_id)
-{
- int ret;
- struct mousevsc_dev *input_dev;
- struct hid_device *hid_dev;
-
- input_dev = mousevsc_alloc_device(device);
-
- if (!input_dev)
- return -ENOMEM;
-
- ret = vmbus_open(device->channel,
- INPUTVSC_SEND_RING_BUFFER_SIZE,
- INPUTVSC_RECV_RING_BUFFER_SIZE,
- NULL,
- 0,
- mousevsc_on_channel_callback,
- device
- );
-
- if (ret)
- goto probe_err0;
-
- ret = mousevsc_connect_to_vsp(device);
-
- if (ret)
- goto probe_err1;
-
- /* workaround SA-167 */
- if (input_dev->report_desc[14] == 0x25)
- input_dev->report_desc[14] = 0x29;
-
- hid_dev = hid_allocate_device();
- if (IS_ERR(hid_dev)) {
- ret = PTR_ERR(hid_dev);
- goto probe_err1;
- }
-
- hid_dev->ll_driver = &mousevsc_ll_driver;
- hid_dev->driver = &mousevsc_hid_driver;
- hid_dev->bus = BUS_VIRTUAL;
- hid_dev->vendor = input_dev->hid_dev_info.vendor;
- hid_dev->product = input_dev->hid_dev_info.product;
- hid_dev->version = input_dev->hid_dev_info.version;
- input_dev->hid_device = hid_dev;
-
- sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse");
-
- ret = hid_add_device(hid_dev);
- if (ret)
- goto probe_err1;
-
- ret = hid_parse_report(hid_dev, input_dev->report_desc,
- input_dev->report_desc_size);
-
- if (ret) {
- hid_err(hid_dev, "parse failed\n");
- goto probe_err2;
- }
-
- ret = hid_hw_start(hid_dev, HID_CONNECT_HIDINPUT | HID_CONNECT_HIDDEV);
-
- if (ret) {
- hid_err(hid_dev, "hw start failed\n");
- goto probe_err2;
- }
-
- input_dev->connected = true;
- input_dev->init_complete = true;
-
- return ret;
-
-probe_err2:
- hid_destroy_device(hid_dev);
-
-probe_err1:
- vmbus_close(device->channel);
-
-probe_err0:
- mousevsc_free_device(input_dev);
-
- return ret;
-}
-
-
-static int mousevsc_remove(struct hv_device *dev)
-{
- struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
-
- vmbus_close(dev->channel);
- hid_hw_stop(input_dev->hid_device);
- hid_destroy_device(input_dev->hid_device);
- mousevsc_free_device(input_dev);
-
- return 0;
-}
-
-static const struct hv_vmbus_device_id id_table[] = {
- /* Mouse guid */
- { VMBUS_DEVICE(0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
- 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A) },
- { },
-};
-
-MODULE_DEVICE_TABLE(vmbus, id_table);
-
-static struct hv_driver mousevsc_drv = {
- .name = KBUILD_MODNAME,
- .id_table = id_table,
- .probe = mousevsc_probe,
- .remove = mousevsc_remove,
-};
-
-static int __init mousevsc_init(void)
-{
- return vmbus_driver_register(&mousevsc_drv);
-}
-
-static void __exit mousevsc_exit(void)
-{
- vmbus_driver_unregister(&mousevsc_drv);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_VERSION(HV_DRV_VERSION);
-module_init(mousevsc_init);
-module_exit(mousevsc_exit);
diff --git a/ANDROID_3.4.5/drivers/hid/hid-ids.h b/ANDROID_3.4.5/drivers/hid/hid-ids.h
deleted file mode 100644
index e39aecb1..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-ids.h
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * USB HID quirks support for Linux
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#ifndef HID_IDS_H_FILE
-#define HID_IDS_H_FILE
-
-#define USB_VENDOR_ID_3M 0x0596
-#define USB_DEVICE_ID_3M1968 0x0500
-#define USB_DEVICE_ID_3M2256 0x0502
-#define USB_DEVICE_ID_3M3266 0x0506
-
-#define USB_VENDOR_ID_A4TECH 0x09da
-#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
-#define USB_DEVICE_ID_A4TECH_X5_005D 0x000a
-#define USB_DEVICE_ID_A4TECH_RP_649 0x001a
-
-#define USB_VENDOR_ID_AASHIMA 0x06d6
-#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025
-#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026
-
-#define USB_VENDOR_ID_ACECAD 0x0460
-#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
-#define USB_DEVICE_ID_ACECAD_302 0x0008
-
-#define USB_VENDOR_ID_ACRUX 0x1a34
-
-#define USB_VENDOR_ID_ACTIONSTAR 0x2101
-#define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011
-
-#define USB_VENDOR_ID_ADS_TECH 0x06e1
-#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
-
-#define USB_VENDOR_ID_AFATECH 0x15a4
-#define USB_DEVICE_ID_AFATECH_AF9016 0x9016
-
-#define USB_VENDOR_ID_AIPTEK 0x08ca
-#define USB_DEVICE_ID_AIPTEK_01 0x0001
-#define USB_DEVICE_ID_AIPTEK_10 0x0010
-#define USB_DEVICE_ID_AIPTEK_20 0x0020
-#define USB_DEVICE_ID_AIPTEK_21 0x0021
-#define USB_DEVICE_ID_AIPTEK_22 0x0022
-#define USB_DEVICE_ID_AIPTEK_23 0x0023
-#define USB_DEVICE_ID_AIPTEK_24 0x0024
-
-#define USB_VENDOR_ID_AIRCABLE 0x16CA
-#define USB_DEVICE_ID_AIRCABLE1 0x1502
-
-#define USB_VENDOR_ID_AIREN 0x1a2c
-#define USB_DEVICE_ID_AIREN_SLIMPLUS 0x0002
-
-#define USB_VENDOR_ID_ALCOR 0x058f
-#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
-
-#define USB_VENDOR_ID_ALPS 0x0433
-#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
-
-#define USB_VENDOR_ID_APPLE 0x05ac
-#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
-#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
-#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
-#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
-#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
-#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
-#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215
-#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216
-#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217
-#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218
-#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219
-#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
-#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
-#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
-#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d
-#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e
-#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f
-#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
-#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
-#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
-#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
-#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
-#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
-#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
-#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
-#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
-#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
-#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
-#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
-#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
-#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
-#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
-#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f
-#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240
-#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241
-#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242
-#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243
-#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244
-#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245
-#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246
-#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247
-#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI 0x024f
-#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO 0x0250
-#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS 0x0251
-#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252
-#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253
-#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254
-#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249
-#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a
-#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b
-#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c
-#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d
-#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256
-#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
-#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
-#define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241
-#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
-
-#define USB_VENDOR_ID_ASUS 0x0486
-#define USB_DEVICE_ID_ASUS_T91MT 0x0185
-#define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186
-
-#define USB_VENDOR_ID_ASUSTEK 0x0b05
-#define USB_DEVICE_ID_ASUSTEK_LCM 0x1726
-#define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b
-
-#define USB_VENDOR_ID_ATEN 0x0557
-#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
-#define USB_DEVICE_ID_ATEN_CS124U 0x2202
-#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204
-#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205
-#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208
-
-#define USB_VENDOR_ID_ATMEL 0x03eb
-#define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c
-#define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118
-
-#define USB_VENDOR_ID_AVERMEDIA 0x07ca
-#define USB_DEVICE_ID_AVER_FM_MR800 0xb800
-
-#define USB_VENDOR_ID_BELKIN 0x050d
-#define USB_DEVICE_ID_FLIP_KVM 0x3201
-
-#define USB_VENDOR_ID_BERKSHIRE 0x0c98
-#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
-
-#define USB_VENDOR_ID_BTC 0x046e
-#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
-#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577
-
-#define USB_VENDOR_ID_CANDO 0x2087
-#define USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH 0x0703
-#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01
-#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1 0x0a02
-#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03
-#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01
-
-#define USB_VENDOR_ID_CH 0x068e
-#define USB_DEVICE_ID_CH_PRO_THROTTLE 0x00f1
-#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2
-#define USB_DEVICE_ID_CH_FIGHTERSTICK 0x00f3
-#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4
-#define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051
-#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff
-#define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK 0x00d3
-#define USB_DEVICE_ID_CH_AXIS_295 0x001c
-
-#define USB_VENDOR_ID_CHERRY 0x046a
-#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
-#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027
-
-#define USB_VENDOR_ID_CHIC 0x05fe
-#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014
-
-#define USB_VENDOR_ID_CHICONY 0x04f2
-#define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418
-#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
-#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
-#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123
-
-#define USB_VENDOR_ID_CHUNGHWAT 0x2247
-#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001
-
-#define USB_VENDOR_ID_CIDC 0x1677
-
-#define USB_VENDOR_ID_CMEDIA 0x0d8c
-#define USB_DEVICE_ID_CM109 0x000e
-
-#define USB_VENDOR_ID_CODEMERCS 0x07c0
-#define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500
-#define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff
-
-#define USB_VENDOR_ID_CREATIVELABS 0x041e
-#define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801
-
-#define USB_VENDOR_ID_CVTOUCH 0x1ff7
-#define USB_DEVICE_ID_CVTOUCH_SCREEN 0x0013
-
-#define USB_VENDOR_ID_CYGNAL 0x10c4
-#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a
-
-#define USB_VENDOR_ID_CYPRESS 0x04b4
-#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
-#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
-#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
-#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
-#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
-#define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1
-#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001
-
-#define USB_VENDOR_ID_DEALEXTREAME 0x10c5
-#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a
-
-#define USB_VENDOR_ID_DELORME 0x1163
-#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
-#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
-
-#define USB_VENDOR_ID_DMI 0x0c0b
-#define USB_DEVICE_ID_DMI_ENC 0x5fab
-
-#define USB_VENDOR_ID_DRAGONRISE 0x0079
-
-#define USB_VENDOR_ID_DWAV 0x0eef
-#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A 0x722A
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001
-
-#define USB_VENDOR_ID_ELECOM 0x056e
-#define USB_DEVICE_ID_ELECOM_BM084 0x0061
-
-#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34
-
-#define USB_VENDOR_ID_ELO 0x04E7
-#define USB_DEVICE_ID_ELO_TS2515 0x0022
-#define USB_DEVICE_ID_ELO_TS2700 0x0020
-
-#define USB_VENDOR_ID_EMS 0x2006
-#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118
-
-#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
-#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
-
-#define USB_VENDOR_ID_ETT 0x0664
-#define USB_DEVICE_ID_TC5UH 0x0309
-#define USB_DEVICE_ID_TC4UM 0x0306
-
-#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
-#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
-
-#define USB_VENDOR_ID_EZKEY 0x0518
-#define USB_DEVICE_ID_BTC_8193 0x0002
-
-#define USB_VENDOR_ID_FRUCTEL 0x25B6
-#define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002
-
-#define USB_VENDOR_ID_GAMERON 0x0810
-#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
-#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
-
-#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc
-#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
-
-#define USB_VENDOR_ID_GLAB 0x06c2
-#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
-#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039
-#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040
-#define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044
-#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045
-#define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051
-#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053
-#define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058
-
-#define USB_VENDOR_ID_GOODTOUCH 0x1aad
-#define USB_DEVICE_ID_GOODTOUCH_000f 0x000f
-
-#define USB_VENDOR_ID_GOTOP 0x08f2
-#define USB_DEVICE_ID_SUPER_Q2 0x007f
-#define USB_DEVICE_ID_GOGOPEN 0x00ce
-#define USB_DEVICE_ID_PENPOWER 0x00f4
-
-#define USB_VENDOR_ID_GREENASIA 0x0e8f
-#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013
-
-#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
-#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005
-
-#define USB_VENDOR_ID_GRIFFIN 0x077d
-#define USB_DEVICE_ID_POWERMATE 0x0410
-#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
-
-#define USB_VENDOR_ID_GTCO 0x078c
-#define USB_DEVICE_ID_GTCO_90 0x0090
-#define USB_DEVICE_ID_GTCO_100 0x0100
-#define USB_DEVICE_ID_GTCO_101 0x0101
-#define USB_DEVICE_ID_GTCO_103 0x0103
-#define USB_DEVICE_ID_GTCO_104 0x0104
-#define USB_DEVICE_ID_GTCO_105 0x0105
-#define USB_DEVICE_ID_GTCO_106 0x0106
-#define USB_DEVICE_ID_GTCO_107 0x0107
-#define USB_DEVICE_ID_GTCO_108 0x0108
-#define USB_DEVICE_ID_GTCO_200 0x0200
-#define USB_DEVICE_ID_GTCO_201 0x0201
-#define USB_DEVICE_ID_GTCO_202 0x0202
-#define USB_DEVICE_ID_GTCO_203 0x0203
-#define USB_DEVICE_ID_GTCO_204 0x0204
-#define USB_DEVICE_ID_GTCO_205 0x0205
-#define USB_DEVICE_ID_GTCO_206 0x0206
-#define USB_DEVICE_ID_GTCO_207 0x0207
-#define USB_DEVICE_ID_GTCO_300 0x0300
-#define USB_DEVICE_ID_GTCO_301 0x0301
-#define USB_DEVICE_ID_GTCO_302 0x0302
-#define USB_DEVICE_ID_GTCO_303 0x0303
-#define USB_DEVICE_ID_GTCO_304 0x0304
-#define USB_DEVICE_ID_GTCO_305 0x0305
-#define USB_DEVICE_ID_GTCO_306 0x0306
-#define USB_DEVICE_ID_GTCO_307 0x0307
-#define USB_DEVICE_ID_GTCO_308 0x0308
-#define USB_DEVICE_ID_GTCO_309 0x0309
-#define USB_DEVICE_ID_GTCO_400 0x0400
-#define USB_DEVICE_ID_GTCO_401 0x0401
-#define USB_DEVICE_ID_GTCO_402 0x0402
-#define USB_DEVICE_ID_GTCO_403 0x0403
-#define USB_DEVICE_ID_GTCO_404 0x0404
-#define USB_DEVICE_ID_GTCO_405 0x0405
-#define USB_DEVICE_ID_GTCO_500 0x0500
-#define USB_DEVICE_ID_GTCO_501 0x0501
-#define USB_DEVICE_ID_GTCO_502 0x0502
-#define USB_DEVICE_ID_GTCO_503 0x0503
-#define USB_DEVICE_ID_GTCO_504 0x0504
-#define USB_DEVICE_ID_GTCO_1000 0x1000
-#define USB_DEVICE_ID_GTCO_1001 0x1001
-#define USB_DEVICE_ID_GTCO_1002 0x1002
-#define USB_DEVICE_ID_GTCO_1003 0x1003
-#define USB_DEVICE_ID_GTCO_1004 0x1004
-#define USB_DEVICE_ID_GTCO_1005 0x1005
-#define USB_DEVICE_ID_GTCO_1006 0x1006
-#define USB_DEVICE_ID_GTCO_1007 0x1007
-
-#define USB_VENDOR_ID_GYRATION 0x0c16
-#define USB_DEVICE_ID_GYRATION_REMOTE 0x0002
-#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
-#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
-
-#define USB_VENDOR_ID_HANWANG 0x0b57
-#define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000
-#define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff
-
-#define USB_VENDOR_ID_HANVON 0x20b3
-#define USB_DEVICE_ID_HANVON_MULTITOUCH 0x0a18
-
-#define USB_VENDOR_ID_HANVON_ALT 0x22ed
-#define USB_DEVICE_ID_HANVON_ALT_MULTITOUCH 0x1010
-
-#define USB_VENDOR_ID_HAPP 0x078b
-#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
-#define USB_DEVICE_ID_UGCI_FLYING 0x0020
-#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
-
-#define USB_VENDOR_ID_IDEACOM 0x1cb6
-#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
-#define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651
-
-#define USB_VENDOR_ID_ILITEK 0x222a
-#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
-
-#define USB_VENDOR_ID_HOLTEK 0x1241
-#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015
-
-#define USB_VENDOR_ID_IMATION 0x0718
-#define USB_DEVICE_ID_DISC_STAKKA 0xd000
-
-#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615
-#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070
-
-#define USB_VENDOR_ID_JESS 0x0c45
-#define USB_DEVICE_ID_JESS_YUREX 0x1010
-
-#define USB_VENDOR_ID_KBGEAR 0x084e
-#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
-
-#define USB_VENDOR_ID_KENSINGTON 0x047d
-#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
-
-#define USB_VENDOR_ID_KWORLD 0x1b80
-#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
-
-#define USB_VENDOR_ID_KEYTOUCH 0x0926
-#define USB_DEVICE_ID_KEYTOUCH_IEC 0x3333
-
-#define USB_VENDOR_ID_KYE 0x0458
-#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
-#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
-#define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010
-#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011
-#define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013
-
-#define USB_VENDOR_ID_LABTEC 0x1020
-#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
-
-#define USB_VENDOR_ID_LCPOWER 0x1241
-#define USB_DEVICE_ID_LCPOWER_LC1000 0xf767
-
-#define USB_VENDOR_ID_LD 0x0f11
-#define USB_DEVICE_ID_LD_CASSY 0x1000
-#define USB_DEVICE_ID_LD_CASSY2 0x1001
-#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010
-#define USB_DEVICE_ID_LD_POCKETCASSY2 0x1011
-#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020
-#define USB_DEVICE_ID_LD_MOBILECASSY2 0x1021
-#define USB_DEVICE_ID_LD_MICROCASSYVOLTAGE 0x1031
-#define USB_DEVICE_ID_LD_MICROCASSYCURRENT 0x1032
-#define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033
-#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035
-#define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038
-#define USB_DEVICE_ID_LD_JWM 0x1080
-#define USB_DEVICE_ID_LD_DMMP 0x1081
-#define USB_DEVICE_ID_LD_UMIP 0x1090
-#define USB_DEVICE_ID_LD_UMIC 0x10A0
-#define USB_DEVICE_ID_LD_UMIB 0x10B0
-#define USB_DEVICE_ID_LD_XRAY 0x1100
-#define USB_DEVICE_ID_LD_XRAY2 0x1101
-#define USB_DEVICE_ID_LD_XRAYCT 0x1110
-#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200
-#define USB_DEVICE_ID_LD_MOTOR 0x1210
-#define USB_DEVICE_ID_LD_COM3LAB 0x2000
-#define USB_DEVICE_ID_LD_TELEPORT 0x2010
-#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020
-#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
-#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
-#define USB_DEVICE_ID_LD_MOSTANALYSER 0x2050
-#define USB_DEVICE_ID_LD_MOSTANALYSER2 0x2051
-#define USB_DEVICE_ID_LD_ABSESP 0x2060
-#define USB_DEVICE_ID_LD_AUTODATABUS 0x2070
-#define USB_DEVICE_ID_LD_MCT 0x2080
-#define USB_DEVICE_ID_LD_HYBRID 0x2090
-#define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0
-
-#define USB_VENDOR_ID_LG 0x1fd2
-#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
-
-#define USB_VENDOR_ID_LOGITECH 0x046d
-#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
-#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
-#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
-#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
-#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
-#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
-#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
-#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218
-#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219
-#define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283
-#define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286
-#define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287
-#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
-#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
-#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
-#define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298
-#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299
-#define USB_DEVICE_ID_LOGITECH_DFGT_WHEEL 0xc29a
-#define USB_DEVICE_ID_LOGITECH_G27_WHEEL 0xc29b
-#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c
-#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
-#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
-#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
-#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
-#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
-#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER 0xc52b
-#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2 0xc532
-#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
-#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
-#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
-#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
-#define USB_DEVICE_ID_DINOVO_MINI 0xc71f
-#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03
-
-#define USB_VENDOR_ID_LUMIO 0x202e
-#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006
-#define USB_DEVICE_ID_CRYSTALTOUCH_DUAL 0x0007
-
-#define USB_VENDOR_ID_MCC 0x09db
-#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
-#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a
-
-#define USB_VENDOR_ID_MGE 0x0463
-#define USB_DEVICE_ID_MGE_UPS 0xffff
-#define USB_DEVICE_ID_MGE_UPS1 0x0001
-
-#define USB_VENDOR_ID_MICROCHIP 0x04d8
-#define USB_DEVICE_ID_PICKIT1 0x0032
-#define USB_DEVICE_ID_PICKIT2 0x0033
-#define USB_DEVICE_ID_PICOLCD 0xc002
-#define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002
-
-#define USB_VENDOR_ID_MICROSOFT 0x045e
-#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
-#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
-#define USB_DEVICE_ID_MS_NE4K 0x00db
-#define USB_DEVICE_ID_MS_LK6K 0x00f9
-#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701
-#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
-#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730
-#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
-
-#define USB_VENDOR_ID_MOJO 0x8282
-#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
-
-#define USB_VENDOR_ID_MONTEREY 0x0566
-#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
-
-#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
-#define USB_DEVICE_ID_N_S_HARMONY 0xc359
-
-#define USB_VENDOR_ID_NATSU 0x08b7
-#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
-
-#define USB_VENDOR_ID_NCR 0x0404
-#define USB_DEVICE_ID_NCR_FIRST 0x0300
-#define USB_DEVICE_ID_NCR_LAST 0x03ff
-
-#define USB_VENDOR_ID_NEC 0x073e
-#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
-
-#define USB_VENDOR_ID_NEXTWINDOW 0x1926
-#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
-
-#define USB_VENDOR_ID_NINTENDO 0x057e
-#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
-
-#define USB_VENDOR_ID_NTRIG 0x1b96
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3 0x0005
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4 0x0006
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5 0x0007
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6 0x0008
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7 0x0009
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8 0x000A
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9 0x000B
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10 0x000C
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11 0x000D
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12 0x000E
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13 0x000F
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14 0x0010
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15 0x0011
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013
-#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014
-
-#define USB_VENDOR_ID_ONTRAK 0x0a07
-#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
-
-#define USB_VENDOR_ID_ORTEK 0x05a4
-#define USB_DEVICE_ID_ORTEK_PKB1700 0x1700
-#define USB_DEVICE_ID_ORTEK_WKB2000 0x2000
-
-#define USB_VENDOR_ID_PANASONIC 0x04da
-#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
-#define USB_DEVICE_ID_PANABOARD_UBT880 0x104d
-
-#define USB_VENDOR_ID_PANJIT 0x134c
-
-#define USB_VENDOR_ID_PANTHERLORD 0x0810
-#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
-
-#define USB_VENDOR_ID_PENMOUNT 0x14e1
-#define USB_DEVICE_ID_PENMOUNT_PCI 0x3500
-
-#define USB_VENDOR_ID_PETALYNX 0x18b1
-#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
-
-#define USB_VENDOR_ID_PHILIPS 0x0471
-#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
-
-#define USB_VENDOR_ID_PI_ENGINEERING 0x05f3
-#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff
-
-#define USB_VENDOR_ID_PIXART 0x093a
-#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN 0x8001
-#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1 0x8002
-#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2 0x8003
-
-#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
-#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
-
-#define USB_VENDOR_ID_POWERCOM 0x0d9f
-#define USB_DEVICE_ID_POWERCOM_UPS 0x0002
-
-#define USB_VENDOR_ID_PRODIGE 0x05af
-#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
-
-#define USB_VENDOR_ID_QUANTA 0x0408
-#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
-#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001
-#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
-#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
-
-#define USB_VENDOR_ID_ROCCAT 0x1e7d
-#define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4
-#define USB_DEVICE_ID_ROCCAT_ISKU 0x319c
-#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
-#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51
-#define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50
-#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
-#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
-
-#define USB_VENDOR_ID_SAITEK 0x06a3
-#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
-#define USB_DEVICE_ID_SAITEK_PS1000 0x0621
-
-#define USB_VENDOR_ID_SAMSUNG 0x0419
-#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
-#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
-
-#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
-#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
-
-#define USB_VENDOR_ID_SKYCABLE 0x1223
-#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
-
-#define USB_VENDOR_ID_SONY 0x054c
-#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
-#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
-#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
-
-#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST 0x0046
-
-#define USB_VENDOR_ID_STANTUM 0x1f87
-#define USB_DEVICE_ID_MTP 0x0002
-
-#define USB_VENDOR_ID_STANTUM_STM 0x0483
-#define USB_DEVICE_ID_MTP_STM 0x3261
-
-#define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403
-#define USB_DEVICE_ID_MTP_SITRONIX 0x5001
-
-#define USB_VENDOR_ID_SUN 0x0430
-#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
-
-#define USB_VENDOR_ID_SUNPLUS 0x04fc
-#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
-
-#define USB_VENDOR_ID_SYMBOL 0x05e0
-#define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800
-#define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300
-
-#define USB_VENDOR_ID_SYNAPTICS 0x06cb
-#define USB_DEVICE_ID_SYNAPTICS_TP 0x0001
-#define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002
-#define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003
-#define USB_DEVICE_ID_SYNAPTICS_TS 0x0006
-#define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007
-#define USB_DEVICE_ID_SYNAPTICS_WP 0x0008
-#define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009
-#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010
-#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013
-
-#define USB_VENDOR_ID_THRUSTMASTER 0x044f
-
-#define USB_VENDOR_ID_TIVO 0x150a
-#define USB_DEVICE_ID_TIVO_SLIDE_BT 0x1200
-#define USB_DEVICE_ID_TIVO_SLIDE 0x1201
-
-#define USB_VENDOR_ID_TOPSEED 0x0766
-#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
-
-#define USB_VENDOR_ID_TOPSEED2 0x1784
-#define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004
-#define USB_DEVICE_ID_TOPSEED2_PERIPAD_701 0x0016
-
-#define USB_VENDOR_ID_TOPMAX 0x0663
-#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
-
-#define USB_VENDOR_ID_TOUCH_INTL 0x1e5e
-#define USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH 0x0313
-
-#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
-#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
-
-#define USB_VENDOR_ID_TURBOX 0x062a
-#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
-#define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100
-
-#define USB_VENDOR_ID_TWINHAN 0x6253
-#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
-
-#define USB_VENDOR_ID_UCLOGIC 0x5543
-#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
-#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001
-#define USB_DEVICE_ID_UCLOGIC_TABLET_TWA60 0x0064
-#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
-#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004
-#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
-#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064
-
-#define USB_VENDOR_ID_UNITEC 0x227d
-#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709
-#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19
-
-#define USB_VENDOR_ID_VERNIER 0x08f7
-#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
-#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
-#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
-#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
-#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006
-
-#define USB_VENDOR_ID_WACOM 0x056a
-#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
-#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD
-
-#define USB_VENDOR_ID_WALTOP 0x172f
-#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032
-#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH 0x0034
-#define USB_DEVICE_ID_WALTOP_Q_PAD 0x0037
-#define USB_DEVICE_ID_WALTOP_PID_0038 0x0038
-#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501
-#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500
-
-#define USB_VENDOR_ID_WISEGROUP 0x0925
-#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
-#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
-#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104
-#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201
-#define USB_DEVICE_ID_SUPER_JOY_BOX_3 0x8888
-#define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800
-#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866
-
-#define USB_VENDOR_ID_WISEGROUP_LTD 0x6666
-#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677
-#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
-#define USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO 0x8801
-#define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802
-#define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804
-
-#define USB_VENDOR_ID_X_TENSIONS 0x1ae7
-#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001
-
-#define USB_VENDOR_ID_XAT 0x2505
-#define USB_DEVICE_ID_XAT_CSR 0x0220
-
-#define USB_VENDOR_ID_XIROKU 0x1477
-#define USB_DEVICE_ID_XIROKU_SPX 0x1006
-#define USB_DEVICE_ID_XIROKU_MPX 0x1007
-#define USB_DEVICE_ID_XIROKU_CSR 0x100e
-#define USB_DEVICE_ID_XIROKU_SPX1 0x1021
-#define USB_DEVICE_ID_XIROKU_CSR1 0x1022
-#define USB_DEVICE_ID_XIROKU_MPX1 0x1023
-#define USB_DEVICE_ID_XIROKU_SPX2 0x1024
-#define USB_DEVICE_ID_XIROKU_CSR2 0x1025
-#define USB_DEVICE_ID_XIROKU_MPX2 0x1026
-
-#define USB_VENDOR_ID_YEALINK 0x6993
-#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
-
-#define USB_VENDOR_ID_ZEROPLUS 0x0c12
-
-#define USB_VENDOR_ID_ZYDACRON 0x13EC
-#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
-
-#define USB_VENDOR_ID_PRIMAX 0x0461
-#define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-input.c b/ANDROID_3.4.5/drivers/hid/hid-input.c
deleted file mode 100644
index c19bff70..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-input.c
+++ /dev/null
@@ -1,1255 +0,0 @@
-/*
- * Copyright (c) 2000-2001 Vojtech Pavlik
- * Copyright (c) 2006-2010 Jiri Kosina
- *
- * HID to Linux Input mapping
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-
-#include <linux/hid.h>
-#include <linux/hid-debug.h>
-
-#include "hid-ids.h"
-
-#define unk KEY_UNKNOWN
-
-static const unsigned char hid_keyboard[256] = {
- 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
- 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
- 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
- 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
- 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
- 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
- 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
- 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk,
- 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
- 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
-};
-
-static const struct {
- __s32 x;
- __s32 y;
-} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
-
-#define map_abs(c) hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c))
-#define map_rel(c) hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))
-#define map_key(c) hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))
-#define map_led(c) hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c))
-
-#define map_abs_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
- &max, EV_ABS, (c))
-#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
- &max, EV_KEY, (c))
-
-static bool match_scancode(struct hid_usage *usage,
- unsigned int cur_idx, unsigned int scancode)
-{
- return (usage->hid & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
-}
-
-static bool match_keycode(struct hid_usage *usage,
- unsigned int cur_idx, unsigned int keycode)
-{
- /*
- * We should exclude unmapped usages when doing lookup by keycode.
- */
- return (usage->type == EV_KEY && usage->code == keycode);
-}
-
-static bool match_index(struct hid_usage *usage,
- unsigned int cur_idx, unsigned int idx)
-{
- return cur_idx == idx;
-}
-
-typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
- unsigned int cur_idx, unsigned int val);
-
-static struct hid_usage *hidinput_find_key(struct hid_device *hid,
- hid_usage_cmp_t match,
- unsigned int value,
- unsigned int *usage_idx)
-{
- unsigned int i, j, k, cur_idx = 0;
- struct hid_report *report;
- struct hid_usage *usage;
-
- for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
- list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
- for (i = 0; i < report->maxfield; i++) {
- for (j = 0; j < report->field[i]->maxusage; j++) {
- usage = report->field[i]->usage + j;
- if (usage->type == EV_KEY || usage->type == 0) {
- if (match(usage, cur_idx, value)) {
- if (usage_idx)
- *usage_idx = cur_idx;
- return usage;
- }
- cur_idx++;
- }
- }
- }
- }
- }
- return NULL;
-}
-
-static struct hid_usage *hidinput_locate_usage(struct hid_device *hid,
- const struct input_keymap_entry *ke,
- unsigned int *index)
-{
- struct hid_usage *usage;
- unsigned int scancode;
-
- if (ke->flags & INPUT_KEYMAP_BY_INDEX)
- usage = hidinput_find_key(hid, match_index, ke->index, index);
- else if (input_scancode_to_scalar(ke, &scancode) == 0)
- usage = hidinput_find_key(hid, match_scancode, scancode, index);
- else
- usage = NULL;
-
- return usage;
-}
-
-static int hidinput_getkeycode(struct input_dev *dev,
- struct input_keymap_entry *ke)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct hid_usage *usage;
- unsigned int scancode, index;
-
- usage = hidinput_locate_usage(hid, ke, &index);
- if (usage) {
- ke->keycode = usage->type == EV_KEY ?
- usage->code : KEY_RESERVED;
- ke->index = index;
- scancode = usage->hid & (HID_USAGE_PAGE | HID_USAGE);
- ke->len = sizeof(scancode);
- memcpy(ke->scancode, &scancode, sizeof(scancode));
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int hidinput_setkeycode(struct input_dev *dev,
- const struct input_keymap_entry *ke,
- unsigned int *old_keycode)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct hid_usage *usage;
-
- usage = hidinput_locate_usage(hid, ke, NULL);
- if (usage) {
- *old_keycode = usage->type == EV_KEY ?
- usage->code : KEY_RESERVED;
- usage->code = ke->keycode;
-
- clear_bit(*old_keycode, dev->keybit);
- set_bit(usage->code, dev->keybit);
- dbg_hid("Assigned keycode %d to HID usage code %x\n",
- usage->code, usage->hid);
-
- /*
- * Set the keybit for the old keycode if the old keycode is used
- * by another key
- */
- if (hidinput_find_key(hid, match_keycode, *old_keycode, NULL))
- set_bit(*old_keycode, dev->keybit);
-
- return 0;
- }
-
- return -EINVAL;
-}
-
-
-/**
- * hidinput_calc_abs_res - calculate an absolute axis resolution
- * @field: the HID report field to calculate resolution for
- * @code: axis code
- *
- * The formula is:
- * (logical_maximum - logical_minimum)
- * resolution = ----------------------------------------------------------
- * (physical_maximum - physical_minimum) * 10 ^ unit_exponent
- *
- * as seen in the HID specification v1.11 6.2.2.7 Global Items.
- *
- * Only exponent 1 length units are processed. Centimeters and inches are
- * converted to millimeters. Degrees are converted to radians.
- */
-static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
-{
- __s32 unit_exponent = field->unit_exponent;
- __s32 logical_extents = field->logical_maximum -
- field->logical_minimum;
- __s32 physical_extents = field->physical_maximum -
- field->physical_minimum;
- __s32 prev;
-
- /* Check if the extents are sane */
- if (logical_extents <= 0 || physical_extents <= 0)
- return 0;
-
- /*
- * Verify and convert units.
- * See HID specification v1.11 6.2.2.7 Global Items for unit decoding
- */
- if (code == ABS_X || code == ABS_Y || code == ABS_Z) {
- if (field->unit == 0x11) { /* If centimeters */
- /* Convert to millimeters */
- unit_exponent += 1;
- } else if (field->unit == 0x13) { /* If inches */
- /* Convert to millimeters */
- prev = physical_extents;
- physical_extents *= 254;
- if (physical_extents < prev)
- return 0;
- unit_exponent -= 1;
- } else {
- return 0;
- }
- } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) {
- if (field->unit == 0x14) { /* If degrees */
- /* Convert to radians */
- prev = logical_extents;
- logical_extents *= 573;
- if (logical_extents < prev)
- return 0;
- unit_exponent += 1;
- } else if (field->unit != 0x12) { /* If not radians */
- return 0;
- }
- } else {
- return 0;
- }
-
- /* Apply negative unit exponent */
- for (; unit_exponent < 0; unit_exponent++) {
- prev = logical_extents;
- logical_extents *= 10;
- if (logical_extents < prev)
- return 0;
- }
- /* Apply positive unit exponent */
- for (; unit_exponent > 0; unit_exponent--) {
- prev = physical_extents;
- physical_extents *= 10;
- if (physical_extents < prev)
- return 0;
- }
-
- /* Calculate resolution */
- return logical_extents / physical_extents;
-}
-
-#ifdef CONFIG_HID_BATTERY_STRENGTH
-static enum power_supply_property hidinput_battery_props[] = {
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_MODEL_NAME,
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_SCOPE,
-};
-
-#define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */
-#define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */
-
-static const struct hid_device_id hid_battery_quirks[] = {
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
- USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
- HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
- {}
-};
-
-static unsigned find_battery_quirk(struct hid_device *hdev)
-{
- unsigned quirks = 0;
- const struct hid_device_id *match;
-
- match = hid_match_id(hdev, hid_battery_quirks);
- if (match != NULL)
- quirks = match->driver_data;
-
- return quirks;
-}
-
-static int hidinput_get_battery_property(struct power_supply *psy,
- enum power_supply_property prop,
- union power_supply_propval *val)
-{
- struct hid_device *dev = container_of(psy, struct hid_device, battery);
- int ret = 0;
- __u8 buf[2] = {};
-
- switch (prop) {
- case POWER_SUPPLY_PROP_PRESENT:
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = 1;
- break;
-
- case POWER_SUPPLY_PROP_CAPACITY:
- ret = dev->hid_get_raw_report(dev, dev->battery_report_id,
- buf, sizeof(buf),
- dev->battery_report_type);
-
- if (ret != 2) {
- if (ret >= 0)
- ret = -EINVAL;
- break;
- }
-
- if (dev->battery_min < dev->battery_max &&
- buf[1] >= dev->battery_min &&
- buf[1] <= dev->battery_max)
- val->intval = (100 * (buf[1] - dev->battery_min)) /
- (dev->battery_max - dev->battery_min);
- break;
-
- case POWER_SUPPLY_PROP_MODEL_NAME:
- val->strval = dev->name;
- break;
-
- case POWER_SUPPLY_PROP_STATUS:
- val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- break;
-
- case POWER_SUPPLY_PROP_SCOPE:
- val->intval = POWER_SUPPLY_SCOPE_DEVICE;
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field)
-{
- struct power_supply *battery = &dev->battery;
- int ret;
- unsigned quirks;
- s32 min, max;
-
- if (field->usage->hid != HID_DC_BATTERYSTRENGTH)
- return false; /* no match */
-
- if (battery->name != NULL)
- goto out; /* already initialized? */
-
- battery->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq);
- if (battery->name == NULL)
- goto out;
-
- battery->type = POWER_SUPPLY_TYPE_BATTERY;
- battery->properties = hidinput_battery_props;
- battery->num_properties = ARRAY_SIZE(hidinput_battery_props);
- battery->use_for_apm = 0;
- battery->get_property = hidinput_get_battery_property;
-
- quirks = find_battery_quirk(dev);
-
- hid_dbg(dev, "device %x:%x:%x %d quirks %d\n",
- dev->bus, dev->vendor, dev->product, dev->version, quirks);
-
- min = field->logical_minimum;
- max = field->logical_maximum;
-
- if (quirks & HID_BATTERY_QUIRK_PERCENT) {
- min = 0;
- max = 100;
- }
-
- if (quirks & HID_BATTERY_QUIRK_FEATURE)
- report_type = HID_FEATURE_REPORT;
-
- dev->battery_min = min;
- dev->battery_max = max;
- dev->battery_report_type = report_type;
- dev->battery_report_id = field->report->id;
-
- ret = power_supply_register(&dev->dev, battery);
- if (ret != 0) {
- hid_warn(dev, "can't register power supply: %d\n", ret);
- kfree(battery->name);
- battery->name = NULL;
- }
-
- power_supply_powers(battery, &dev->dev);
-
-out:
- return true;
-}
-
-static void hidinput_cleanup_battery(struct hid_device *dev)
-{
- if (!dev->battery.name)
- return;
-
- power_supply_unregister(&dev->battery);
- kfree(dev->battery.name);
- dev->battery.name = NULL;
-}
-#else /* !CONFIG_HID_BATTERY_STRENGTH */
-static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
- struct hid_field *field)
-{
- return false;
-}
-
-static void hidinput_cleanup_battery(struct hid_device *dev)
-{
-}
-#endif /* CONFIG_HID_BATTERY_STRENGTH */
-
-static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
- struct hid_usage *usage)
-{
- struct input_dev *input = hidinput->input;
- struct hid_device *device = input_get_drvdata(input);
- int max = 0, code;
- unsigned long *bit = NULL;
-
- field->hidinput = hidinput;
-
- if (field->flags & HID_MAIN_ITEM_CONSTANT)
- goto ignore;
-
- /* only LED usages are supported in output fields */
- if (field->report_type == HID_OUTPUT_REPORT &&
- (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
- goto ignore;
- }
-
- if (device->driver->input_mapping) {
- int ret = device->driver->input_mapping(device, hidinput, field,
- usage, &bit, &max);
- if (ret > 0)
- goto mapped;
- if (ret < 0)
- goto ignore;
- }
-
- switch (usage->hid & HID_USAGE_PAGE) {
- case HID_UP_UNDEFINED:
- goto ignore;
-
- case HID_UP_KEYBOARD:
- set_bit(EV_REP, input->evbit);
-
- if ((usage->hid & HID_USAGE) < 256) {
- if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore;
- map_key_clear(hid_keyboard[usage->hid & HID_USAGE]);
- } else
- map_key(KEY_UNKNOWN);
-
- break;
-
- case HID_UP_BUTTON:
- code = ((usage->hid - 1) & HID_USAGE);
-
- switch (field->application) {
- case HID_GD_MOUSE:
- case HID_GD_POINTER: code += BTN_MOUSE; break;
- case HID_GD_JOYSTICK:
- if (code <= 0xf)
- code += BTN_JOYSTICK;
- else
- code += BTN_TRIGGER_HAPPY;
- break;
- case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break;
- default:
- switch (field->physical) {
- case HID_GD_MOUSE:
- case HID_GD_POINTER: code += BTN_MOUSE; break;
- case HID_GD_JOYSTICK: code += BTN_JOYSTICK; break;
- case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break;
- default: code += BTN_MISC;
- }
- }
-
- map_key(code);
- break;
-
- case HID_UP_SIMULATION:
- switch (usage->hid & 0xffff) {
- case 0xba: map_abs(ABS_RUDDER); break;
- case 0xbb: map_abs(ABS_THROTTLE); break;
- case 0xc4: map_abs(ABS_GAS); break;
- case 0xc5: map_abs(ABS_BRAKE); break;
- case 0xc8: map_abs(ABS_WHEEL); break;
- default: goto ignore;
- }
- break;
-
- case HID_UP_GENDESK:
- if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */
- switch (usage->hid & 0xf) {
- case 0x1: map_key_clear(KEY_POWER); break;
- case 0x2: map_key_clear(KEY_SLEEP); break;
- case 0x3: map_key_clear(KEY_WAKEUP); break;
- case 0x4: map_key_clear(KEY_CONTEXT_MENU); break;
- case 0x5: map_key_clear(KEY_MENU); break;
- case 0x6: map_key_clear(KEY_PROG1); break;
- case 0x7: map_key_clear(KEY_HELP); break;
- case 0x8: map_key_clear(KEY_EXIT); break;
- case 0x9: map_key_clear(KEY_SELECT); break;
- case 0xa: map_key_clear(KEY_RIGHT); break;
- case 0xb: map_key_clear(KEY_LEFT); break;
- case 0xc: map_key_clear(KEY_UP); break;
- case 0xd: map_key_clear(KEY_DOWN); break;
- case 0xe: map_key_clear(KEY_POWER2); break;
- case 0xf: map_key_clear(KEY_RESTART); break;
- default: goto unknown;
- }
- break;
- }
-
- if ((usage->hid & 0xf0) == 0x90) { /* D-pad */
- switch (usage->hid) {
- case HID_GD_UP: usage->hat_dir = 1; break;
- case HID_GD_DOWN: usage->hat_dir = 5; break;
- case HID_GD_RIGHT: usage->hat_dir = 3; break;
- case HID_GD_LEFT: usage->hat_dir = 7; break;
- default: goto unknown;
- }
- if (field->dpad) {
- map_abs(field->dpad);
- goto ignore;
- }
- map_abs(ABS_HAT0X);
- break;
- }
-
- switch (usage->hid) {
- /* These usage IDs map directly to the usage codes. */
- case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
- case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
- case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
- if (field->flags & HID_MAIN_ITEM_RELATIVE)
- map_rel(usage->hid & 0xf);
- else
- map_abs(usage->hid & 0xf);
- break;
-
- case HID_GD_HATSWITCH:
- usage->hat_min = field->logical_minimum;
- usage->hat_max = field->logical_maximum;
- map_abs(ABS_HAT0X);
- break;
-
- case HID_GD_START: map_key_clear(BTN_START); break;
- case HID_GD_SELECT: map_key_clear(BTN_SELECT); break;
-
- default: goto unknown;
- }
-
- break;
-
- case HID_UP_LED:
- switch (usage->hid & 0xffff) { /* HID-Value: */
- case 0x01: map_led (LED_NUML); break; /* "Num Lock" */
- case 0x02: map_led (LED_CAPSL); break; /* "Caps Lock" */
- case 0x03: map_led (LED_SCROLLL); break; /* "Scroll Lock" */
- case 0x04: map_led (LED_COMPOSE); break; /* "Compose" */
- case 0x05: map_led (LED_KANA); break; /* "Kana" */
- case 0x27: map_led (LED_SLEEP); break; /* "Stand-By" */
- case 0x4c: map_led (LED_SUSPEND); break; /* "System Suspend" */
- case 0x09: map_led (LED_MUTE); break; /* "Mute" */
- case 0x4b: map_led (LED_MISC); break; /* "Generic Indicator" */
- case 0x19: map_led (LED_MAIL); break; /* "Message Waiting" */
- case 0x4d: map_led (LED_CHARGING); break; /* "External Power Connected" */
-
- default: goto ignore;
- }
- break;
-
- case HID_UP_DIGITIZER:
- switch (usage->hid & 0xff) {
- case 0x00: /* Undefined */
- goto ignore;
-
- case 0x30: /* TipPressure */
- if (!test_bit(BTN_TOUCH, input->keybit)) {
- device->quirks |= HID_QUIRK_NOTOUCH;
- set_bit(EV_KEY, input->evbit);
- set_bit(BTN_TOUCH, input->keybit);
- }
- map_abs_clear(ABS_PRESSURE);
- break;
-
- case 0x32: /* InRange */
- switch (field->physical & 0xff) {
- case 0x21: map_key(BTN_TOOL_MOUSE); break;
- case 0x22: map_key(BTN_TOOL_FINGER); break;
- default: map_key(BTN_TOOL_PEN); break;
- }
- break;
-
- case 0x3c: /* Invert */
- map_key_clear(BTN_TOOL_RUBBER);
- break;
-
- case 0x33: /* Touch */
- case 0x42: /* TipSwitch */
- case 0x43: /* TipSwitch2 */
- device->quirks &= ~HID_QUIRK_NOTOUCH;
- map_key_clear(BTN_TOUCH);
- break;
-
- case 0x44: /* BarrelSwitch */
- map_key_clear(BTN_STYLUS);
- break;
-
- case 0x46: /* TabletPick */
- map_key_clear(BTN_STYLUS2);
- break;
-
- case 0x51: /* ContactID */
- device->quirks |= HID_QUIRK_MULTITOUCH;
- goto unknown;
-
- default: goto unknown;
- }
- break;
-
- case HID_UP_CONSUMER: /* USB HUT v1.12, pages 75-84 */
- switch (usage->hid & HID_USAGE) {
- case 0x000: goto ignore;
- case 0x030: map_key_clear(KEY_POWER); break;
- case 0x031: map_key_clear(KEY_RESTART); break;
- case 0x032: map_key_clear(KEY_SLEEP); break;
- case 0x034: map_key_clear(KEY_SLEEP); break;
- case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE); break;
- case 0x036: map_key_clear(BTN_MISC); break;
-
- case 0x040: map_key_clear(KEY_MENU); break; /* Menu */
- case 0x041: map_key_clear(KEY_SELECT); break; /* Menu Pick */
- case 0x042: map_key_clear(KEY_UP); break; /* Menu Up */
- case 0x043: map_key_clear(KEY_DOWN); break; /* Menu Down */
- case 0x044: map_key_clear(KEY_LEFT); break; /* Menu Left */
- case 0x045: map_key_clear(KEY_RIGHT); break; /* Menu Right */
- case 0x046: map_key_clear(KEY_ESC); break; /* Menu Escape */
- case 0x047: map_key_clear(KEY_KPPLUS); break; /* Menu Value Increase */
- case 0x048: map_key_clear(KEY_KPMINUS); break; /* Menu Value Decrease */
-
- case 0x060: map_key_clear(KEY_INFO); break; /* Data On Screen */
- case 0x061: map_key_clear(KEY_SUBTITLE); break; /* Closed Caption */
- case 0x063: map_key_clear(KEY_VCR); break; /* VCR/TV */
- case 0x065: map_key_clear(KEY_CAMERA); break; /* Snapshot */
- case 0x069: map_key_clear(KEY_RED); break;
- case 0x06a: map_key_clear(KEY_GREEN); break;
- case 0x06b: map_key_clear(KEY_BLUE); break;
- case 0x06c: map_key_clear(KEY_YELLOW); break;
- case 0x06d: map_key_clear(KEY_ZOOM); break;
-
- case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
- case 0x083: map_key_clear(KEY_LAST); break;
- case 0x084: map_key_clear(KEY_ENTER); break;
- case 0x088: map_key_clear(KEY_PC); break;
- case 0x089: map_key_clear(KEY_TV); break;
- case 0x08a: map_key_clear(KEY_WWW); break;
- case 0x08b: map_key_clear(KEY_DVD); break;
- case 0x08c: map_key_clear(KEY_PHONE); break;
- case 0x08d: map_key_clear(KEY_PROGRAM); break;
- case 0x08e: map_key_clear(KEY_VIDEOPHONE); break;
- case 0x08f: map_key_clear(KEY_GAMES); break;
- case 0x090: map_key_clear(KEY_MEMO); break;
- case 0x091: map_key_clear(KEY_CD); break;
- case 0x092: map_key_clear(KEY_VCR); break;
- case 0x093: map_key_clear(KEY_TUNER); break;
- case 0x094: map_key_clear(KEY_EXIT); break;
- case 0x095: map_key_clear(KEY_HELP); break;
- case 0x096: map_key_clear(KEY_TAPE); break;
- case 0x097: map_key_clear(KEY_TV2); break;
- case 0x098: map_key_clear(KEY_SAT); break;
- case 0x09a: map_key_clear(KEY_PVR); break;
-
- case 0x09c: map_key_clear(KEY_CHANNELUP); break;
- case 0x09d: map_key_clear(KEY_CHANNELDOWN); break;
- case 0x0a0: map_key_clear(KEY_VCR2); break;
-
- case 0x0b0: map_key_clear(KEY_PLAY); break;
- case 0x0b1: map_key_clear(KEY_PAUSE); break;
- case 0x0b2: map_key_clear(KEY_RECORD); break;
- case 0x0b3: map_key_clear(KEY_FASTFORWARD); break;
- case 0x0b4: map_key_clear(KEY_REWIND); break;
- case 0x0b5: map_key_clear(KEY_NEXTSONG); break;
- case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break;
- case 0x0b7: map_key_clear(KEY_STOPCD); break;
- case 0x0b8: map_key_clear(KEY_EJECTCD); break;
- case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break;
- case 0x0b9: map_key_clear(KEY_SHUFFLE); break;
- case 0x0bf: map_key_clear(KEY_SLOW); break;
-
- case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
- case 0x0e0: map_abs_clear(ABS_VOLUME); break;
- case 0x0e2: map_key_clear(KEY_MUTE); break;
- case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
- case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
- case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
- case 0x0f5: map_key_clear(KEY_SLOW); break;
-
- case 0x182: map_key_clear(KEY_BOOKMARKS); break;
- case 0x183: map_key_clear(KEY_CONFIG); break;
- case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
- case 0x185: map_key_clear(KEY_EDITOR); break;
- case 0x186: map_key_clear(KEY_SPREADSHEET); break;
- case 0x187: map_key_clear(KEY_GRAPHICSEDITOR); break;
- case 0x188: map_key_clear(KEY_PRESENTATION); break;
- case 0x189: map_key_clear(KEY_DATABASE); break;
- case 0x18a: map_key_clear(KEY_MAIL); break;
- case 0x18b: map_key_clear(KEY_NEWS); break;
- case 0x18c: map_key_clear(KEY_VOICEMAIL); break;
- case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break;
- case 0x18e: map_key_clear(KEY_CALENDAR); break;
- case 0x191: map_key_clear(KEY_FINANCE); break;
- case 0x192: map_key_clear(KEY_CALC); break;
- case 0x193: map_key_clear(KEY_PLAYER); break;
- case 0x194: map_key_clear(KEY_FILE); break;
- case 0x196: map_key_clear(KEY_WWW); break;
- case 0x199: map_key_clear(KEY_CHAT); break;
- case 0x19c: map_key_clear(KEY_LOGOFF); break;
- case 0x19e: map_key_clear(KEY_COFFEE); break;
- case 0x1a6: map_key_clear(KEY_HELP); break;
- case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
- case 0x1ab: map_key_clear(KEY_SPELLCHECK); break;
- case 0x1ae: map_key_clear(KEY_KEYBOARD); break;
- case 0x1b6: map_key_clear(KEY_IMAGES); break;
- case 0x1b7: map_key_clear(KEY_AUDIO); break;
- case 0x1b8: map_key_clear(KEY_VIDEO); break;
- case 0x1bc: map_key_clear(KEY_MESSENGER); break;
- case 0x1bd: map_key_clear(KEY_INFO); break;
- case 0x201: map_key_clear(KEY_NEW); break;
- case 0x202: map_key_clear(KEY_OPEN); break;
- case 0x203: map_key_clear(KEY_CLOSE); break;
- case 0x204: map_key_clear(KEY_EXIT); break;
- case 0x207: map_key_clear(KEY_SAVE); break;
- case 0x208: map_key_clear(KEY_PRINT); break;
- case 0x209: map_key_clear(KEY_PROPS); break;
- case 0x21a: map_key_clear(KEY_UNDO); break;
- case 0x21b: map_key_clear(KEY_COPY); break;
- case 0x21c: map_key_clear(KEY_CUT); break;
- case 0x21d: map_key_clear(KEY_PASTE); break;
- case 0x21f: map_key_clear(KEY_FIND); break;
- case 0x221: map_key_clear(KEY_SEARCH); break;
- case 0x222: map_key_clear(KEY_GOTO); break;
- case 0x223: map_key_clear(KEY_HOMEPAGE); break;
- case 0x224: map_key_clear(KEY_BACK); break;
- case 0x225: map_key_clear(KEY_FORWARD); break;
- case 0x226: map_key_clear(KEY_STOP); break;
- case 0x227: map_key_clear(KEY_REFRESH); break;
- case 0x22a: map_key_clear(KEY_BOOKMARKS); break;
- case 0x22d: map_key_clear(KEY_ZOOMIN); break;
- case 0x22e: map_key_clear(KEY_ZOOMOUT); break;
- case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
- case 0x233: map_key_clear(KEY_SCROLLUP); break;
- case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
- case 0x238: map_rel(REL_HWHEEL); break;
- case 0x23d: map_key_clear(KEY_EDIT); break;
- case 0x25f: map_key_clear(KEY_CANCEL); break;
- case 0x269: map_key_clear(KEY_INSERT); break;
- case 0x26a: map_key_clear(KEY_DELETE); break;
- case 0x279: map_key_clear(KEY_REDO); break;
-
- case 0x289: map_key_clear(KEY_REPLY); break;
- case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
- case 0x28c: map_key_clear(KEY_SEND); break;
-
- default: goto ignore;
- }
- break;
-
- case HID_UP_GENDEVCTRLS:
- if (hidinput_setup_battery(device, HID_INPUT_REPORT, field))
- goto ignore;
- else
- goto unknown;
- break;
-
- case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */
- set_bit(EV_REP, input->evbit);
- switch (usage->hid & HID_USAGE) {
- case 0x021: map_key_clear(KEY_PRINT); break;
- case 0x070: map_key_clear(KEY_HP); break;
- case 0x071: map_key_clear(KEY_CAMERA); break;
- case 0x072: map_key_clear(KEY_SOUND); break;
- case 0x073: map_key_clear(KEY_QUESTION); break;
- case 0x080: map_key_clear(KEY_EMAIL); break;
- case 0x081: map_key_clear(KEY_CHAT); break;
- case 0x082: map_key_clear(KEY_SEARCH); break;
- case 0x083: map_key_clear(KEY_CONNECT); break;
- case 0x084: map_key_clear(KEY_FINANCE); break;
- case 0x085: map_key_clear(KEY_SPORT); break;
- case 0x086: map_key_clear(KEY_SHOP); break;
- default: goto ignore;
- }
- break;
-
- case HID_UP_MSVENDOR:
- goto ignore;
-
- case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */
- set_bit(EV_REP, input->evbit);
- goto ignore;
-
- case HID_UP_LOGIVENDOR:
- goto ignore;
-
- case HID_UP_PID:
- switch (usage->hid & HID_USAGE) {
- case 0xa4: map_key_clear(BTN_DEAD); break;
- default: goto ignore;
- }
- break;
-
- default:
- unknown:
- if (field->report_size == 1) {
- if (field->report->type == HID_OUTPUT_REPORT) {
- map_led(LED_MISC);
- break;
- }
- map_key(BTN_MISC);
- break;
- }
- if (field->flags & HID_MAIN_ITEM_RELATIVE) {
- map_rel(REL_MISC);
- break;
- }
- map_abs(ABS_MISC);
- break;
- }
-
-mapped:
- if (device->driver->input_mapped && device->driver->input_mapped(device,
- hidinput, field, usage, &bit, &max) < 0)
- goto ignore;
-
- set_bit(usage->type, input->evbit);
-
- while (usage->code <= max && test_and_set_bit(usage->code, bit))
- usage->code = find_next_zero_bit(bit, max + 1, usage->code);
-
- if (usage->code > max)
- goto ignore;
-
-
- if (usage->type == EV_ABS) {
-
- int a = field->logical_minimum;
- int b = field->logical_maximum;
-
- if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) {
- a = field->logical_minimum = 0;
- b = field->logical_maximum = 255;
- }
-
- if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK)
- input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
- else input_set_abs_params(input, usage->code, a, b, 0, 0);
-
- input_abs_set_res(input, usage->code,
- hidinput_calc_abs_res(field, usage->code));
-
- /* use a larger default input buffer for MT devices */
- if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0)
- input_set_events_per_packet(input, 60);
- }
-
- if (usage->type == EV_ABS &&
- (usage->hat_min < usage->hat_max || usage->hat_dir)) {
- int i;
- for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
- input_set_abs_params(input, i, -1, 1, 0, 0);
- set_bit(i, input->absbit);
- }
- if (usage->hat_dir && !field->dpad)
- field->dpad = usage->code;
- }
-
- /* for those devices which produce Consumer volume usage as relative,
- * we emulate pressing volumeup/volumedown appropriate number of times
- * in hidinput_hid_event()
- */
- if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
- (usage->code == ABS_VOLUME)) {
- set_bit(KEY_VOLUMEUP, input->keybit);
- set_bit(KEY_VOLUMEDOWN, input->keybit);
- }
-
- if (usage->type == EV_KEY) {
- set_bit(EV_MSC, input->evbit);
- set_bit(MSC_SCAN, input->mscbit);
- }
-
-ignore:
- return;
-
-}
-
-void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
-{
- struct input_dev *input;
- unsigned *quirks = &hid->quirks;
-
- if (!field->hidinput)
- return;
-
- input = field->hidinput->input;
-
- if (!usage->type)
- return;
-
- if (usage->hat_min < usage->hat_max || usage->hat_dir) {
- int hat_dir = usage->hat_dir;
- if (!hat_dir)
- hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
- if (hat_dir < 0 || hat_dir > 8) hat_dir = 0;
- input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x);
- input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y);
- return;
- }
-
- if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */
- *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT);
- return;
- }
-
- if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */
- if (value) {
- input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);
- return;
- }
- input_event(input, usage->type, usage->code, 0);
- input_event(input, usage->type, BTN_TOOL_RUBBER, 0);
- return;
- }
-
- if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */
- int a = field->logical_minimum;
- int b = field->logical_maximum;
- input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3));
- }
-
- if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
- dbg_hid("Maximum Effects - %d\n",value);
- return;
- }
-
- if (usage->hid == (HID_UP_PID | 0x7fUL)) {
- dbg_hid("PID Pool Report\n");
- return;
- }
-
- if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
- return;
-
- if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
- (usage->code == ABS_VOLUME)) {
- int count = abs(value);
- int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN;
- int i;
-
- for (i = 0; i < count; i++) {
- input_event(input, EV_KEY, direction, 1);
- input_sync(input);
- input_event(input, EV_KEY, direction, 0);
- input_sync(input);
- }
- return;
- }
-
- /*
- * Ignore out-of-range values as per HID specification,
- * section 5.10 and 6.2.25
- */
- if ((field->flags & HID_MAIN_ITEM_VARIABLE) &&
- (value < field->logical_minimum ||
- value > field->logical_maximum)) {
- dbg_hid("Ignoring out-of-range value %x\n", value);
- return;
- }
-
- /* report the usage code as scancode if the key status has changed */
- if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
- input_event(input, EV_MSC, MSC_SCAN, usage->hid);
-
- input_event(input, usage->type, usage->code, value);
-
- if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
- input_event(input, usage->type, usage->code, 0);
-}
-
-void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
-{
- struct hid_input *hidinput;
-
- if (hid->quirks & HID_QUIRK_NO_INPUT_SYNC)
- return;
-
- list_for_each_entry(hidinput, &hid->inputs, list)
- input_sync(hidinput->input);
-}
-EXPORT_SYMBOL_GPL(hidinput_report_event);
-
-int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
-{
- struct hid_report *report;
- int i, j;
-
- list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
- for (i = 0; i < report->maxfield; i++) {
- *field = report->field[i];
- for (j = 0; j < (*field)->maxusage; j++)
- if ((*field)->usage[j].type == type && (*field)->usage[j].code == code)
- return j;
- }
- }
- return -1;
-}
-EXPORT_SYMBOL_GPL(hidinput_find_field);
-
-struct hid_field *hidinput_get_led_field(struct hid_device *hid)
-{
- struct hid_report *report;
- struct hid_field *field;
- int i, j;
-
- list_for_each_entry(report,
- &hid->report_enum[HID_OUTPUT_REPORT].report_list,
- list) {
- for (i = 0; i < report->maxfield; i++) {
- field = report->field[i];
- for (j = 0; j < field->maxusage; j++)
- if (field->usage[j].type == EV_LED)
- return field;
- }
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(hidinput_get_led_field);
-
-unsigned int hidinput_count_leds(struct hid_device *hid)
-{
- struct hid_report *report;
- struct hid_field *field;
- int i, j;
- unsigned int count = 0;
-
- list_for_each_entry(report,
- &hid->report_enum[HID_OUTPUT_REPORT].report_list,
- list) {
- for (i = 0; i < report->maxfield; i++) {
- field = report->field[i];
- for (j = 0; j < field->maxusage; j++)
- if (field->usage[j].type == EV_LED &&
- field->value[j])
- count += 1;
- }
- }
- return count;
-}
-EXPORT_SYMBOL_GPL(hidinput_count_leds);
-
-static int hidinput_open(struct input_dev *dev)
-{
- struct hid_device *hid = input_get_drvdata(dev);
-
- return hid_hw_open(hid);
-}
-
-static void hidinput_close(struct input_dev *dev)
-{
- struct hid_device *hid = input_get_drvdata(dev);
-
- hid_hw_close(hid);
-}
-
-static void report_features(struct hid_device *hid)
-{
- struct hid_driver *drv = hid->driver;
- struct hid_report_enum *rep_enum;
- struct hid_report *rep;
- int i, j;
-
- rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
- list_for_each_entry(rep, &rep_enum->report_list, list)
- for (i = 0; i < rep->maxfield; i++)
- for (j = 0; j < rep->field[i]->maxusage; j++) {
- /* Verify if Battery Strength feature is available */
- hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]);
-
- if (drv->feature_mapping)
- drv->feature_mapping(hid, rep->field[i],
- rep->field[i]->usage + j);
- }
-}
-
-/*
- * Register the input device; print a message.
- * Configure the input layer interface
- * Read all reports and initialize the absolute field values.
- */
-
-int hidinput_connect(struct hid_device *hid, unsigned int force)
-{
- struct hid_report *report;
- struct hid_input *hidinput = NULL;
- struct input_dev *input_dev;
- int i, j, k;
-
- INIT_LIST_HEAD(&hid->inputs);
-
- if (!force) {
- for (i = 0; i < hid->maxcollection; i++) {
- struct hid_collection *col = &hid->collection[i];
- if (col->type == HID_COLLECTION_APPLICATION ||
- col->type == HID_COLLECTION_PHYSICAL)
- if (IS_INPUT_APPLICATION(col->usage))
- break;
- }
-
- if (i == hid->maxcollection)
- return -1;
- }
-
- report_features(hid);
-
- for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
- if (k == HID_OUTPUT_REPORT &&
- hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
- continue;
-
- list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
-
- if (!report->maxfield)
- continue;
-
- if (!hidinput) {
- hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!hidinput || !input_dev) {
- kfree(hidinput);
- input_free_device(input_dev);
- hid_err(hid, "Out of memory during hid input probe\n");
- goto out_unwind;
- }
-
- input_set_drvdata(input_dev, hid);
- input_dev->event =
- hid->ll_driver->hidinput_input_event;
- input_dev->open = hidinput_open;
- input_dev->close = hidinput_close;
- input_dev->setkeycode = hidinput_setkeycode;
- input_dev->getkeycode = hidinput_getkeycode;
-
- input_dev->name = hid->name;
- input_dev->phys = hid->phys;
- input_dev->uniq = hid->uniq;
- input_dev->id.bustype = hid->bus;
- input_dev->id.vendor = hid->vendor;
- input_dev->id.product = hid->product;
- input_dev->id.version = hid->version;
- input_dev->dev.parent = hid->dev.parent;
- hidinput->input = input_dev;
- list_add_tail(&hidinput->list, &hid->inputs);
- }
-
- for (i = 0; i < report->maxfield; i++)
- for (j = 0; j < report->field[i]->maxusage; j++)
- hidinput_configure_usage(hidinput, report->field[i],
- report->field[i]->usage + j);
-
- if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
- /* This will leave hidinput NULL, so that it
- * allocates another one if we have more inputs on
- * the same interface. Some devices (e.g. Happ's
- * UGCI) cram a lot of unrelated inputs into the
- * same interface. */
- hidinput->report = report;
- if (hid->driver->input_register &&
- hid->driver->input_register(hid, hidinput))
- goto out_cleanup;
- if (input_register_device(hidinput->input))
- goto out_cleanup;
- hidinput = NULL;
- }
- }
- }
-
- if (hid->quirks & HID_QUIRK_MULTITOUCH) {
- /* generic hid does not know how to handle multitouch devices */
- if (hidinput)
- goto out_cleanup;
- goto out_unwind;
- }
-
- if (hidinput && hid->driver->input_register &&
- hid->driver->input_register(hid, hidinput))
- goto out_cleanup;
-
- if (hidinput && input_register_device(hidinput->input))
- goto out_cleanup;
-
- return 0;
-
-out_cleanup:
- list_del(&hidinput->list);
- input_free_device(hidinput->input);
- kfree(hidinput);
-out_unwind:
- /* unwind the ones we already registered */
- hidinput_disconnect(hid);
-
- return -1;
-}
-EXPORT_SYMBOL_GPL(hidinput_connect);
-
-void hidinput_disconnect(struct hid_device *hid)
-{
- struct hid_input *hidinput, *next;
-
- hidinput_cleanup_battery(hid);
-
- list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
- list_del(&hidinput->list);
- input_unregister_device(hidinput->input);
- kfree(hidinput);
- }
-}
-EXPORT_SYMBOL_GPL(hidinput_disconnect);
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-kensington.c b/ANDROID_3.4.5/drivers/hid/hid-kensington.c
deleted file mode 100644
index a5b4016e..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-kensington.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * HID driver for Kensigton Slimblade Trackball
- *
- * Copyright (c) 2009 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define ks_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
-
-static int ks_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x01: ks_map_key(BTN_MIDDLE); break;
- case 0x02: ks_map_key(BTN_SIDE); break;
- default:
- return 0;
- }
- return 1;
-}
-
-static const struct hid_device_id ks_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ks_devices);
-
-static struct hid_driver ks_driver = {
- .name = "kensington",
- .id_table = ks_devices,
- .input_mapping = ks_input_mapping,
-};
-
-static int __init ks_init(void)
-{
- return hid_register_driver(&ks_driver);
-}
-
-static void __exit ks_exit(void)
-{
- hid_unregister_driver(&ks_driver);
-}
-
-module_init(ks_init);
-module_exit(ks_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-keytouch.c b/ANDROID_3.4.5/drivers/hid/hid-keytouch.c
deleted file mode 100644
index 07cd825f..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-keytouch.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * HID driver for Keytouch devices not fully compliant with HID standard
- *
- * Copyright (c) 2011 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-/* Replace the broken report descriptor of this device with rather
- * a default one */
-static __u8 keytouch_fixed_rdesc[] = {
-0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15,
-0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08,
-0x81, 0x01, 0x95, 0x03, 0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x91,
-0x02, 0x95, 0x05, 0x75, 0x01, 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00,
-0x26, 0xff, 0x00, 0x05, 0x07, 0x19, 0x00, 0x2a, 0xff, 0x00, 0x81, 0x00, 0xc0
-};
-
-static __u8 *keytouch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- hid_info(hdev, "fixing up Keytouch IEC report descriptor\n");
-
- rdesc = keytouch_fixed_rdesc;
- *rsize = sizeof(keytouch_fixed_rdesc);
-
- return rdesc;
-}
-
-static const struct hid_device_id keytouch_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, keytouch_devices);
-
-static struct hid_driver keytouch_driver = {
- .name = "keytouch",
- .id_table = keytouch_devices,
- .report_fixup = keytouch_report_fixup,
-};
-
-static int __init keytouch_init(void)
-{
- return hid_register_driver(&keytouch_driver);
-}
-
-static void __exit keytouch_exit(void)
-{
- hid_unregister_driver(&keytouch_driver);
-}
-
-module_init(keytouch_init);
-module_exit(keytouch_exit);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jiri Kosina");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-kye.c b/ANDROID_3.4.5/drivers/hid/hid-kye.c
deleted file mode 100644
index b4f0d821..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-kye.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * HID driver for Kye/Genius devices not fully compliant with HID standard
- *
- * Copyright (c) 2009 Jiri Kosina
- * Copyright (c) 2009 Tomas Hanak
- * Copyright (c) 2012 Nikolai Kondrashov
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include "usbhid/usbhid.h"
-
-#include "hid-ids.h"
-
-/*
- * See EasyPen i405X description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=KYE_EasyPen_i405X
- */
-
-/* Original EasyPen i405X report descriptor size */
-#define EASYPEN_I405X_RDESC_ORIG_SIZE 476
-
-/* Fixed EasyPen i405X report descriptor */
-static __u8 easypen_i405x_rdesc_fixed[] = {
- 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
- 0x09, 0x01, /* Usage (01h), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x05, /* Report ID (5), */
- 0x09, 0x01, /* Usage (01h), */
- 0x15, 0x80, /* Logical Minimum (-128), */
- 0x25, 0x7F, /* Logical Maximum (127), */
- 0x75, 0x08, /* Report Size (8), */
- 0x95, 0x07, /* Report Count (7), */
- 0xB1, 0x02, /* Feature (Variable), */
- 0xC0, /* End Collection, */
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x04, /* Report Count (4), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x09, 0x32, /* Usage (In Range), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
- 0x26, 0x00, 0x37, /* Logical Maximum (14080), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
- 0x26, 0x00, 0x28, /* Logical Maximum (10240), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/*
- * See MousePen i608X description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=KYE_MousePen_i608X
- */
-
-/* Original MousePen i608X report descriptor size */
-#define MOUSEPEN_I608X_RDESC_ORIG_SIZE 476
-
-/* Fixed MousePen i608X report descriptor */
-static __u8 mousepen_i608x_rdesc_fixed[] = {
- 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
- 0x09, 0x01, /* Usage (01h), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x05, /* Report ID (5), */
- 0x09, 0x01, /* Usage (01h), */
- 0x15, 0x80, /* Logical Minimum (-128), */
- 0x25, 0x7F, /* Logical Maximum (127), */
- 0x75, 0x08, /* Report Size (8), */
- 0x95, 0x07, /* Report Count (7), */
- 0xB1, 0x02, /* Feature (Variable), */
- 0xC0, /* End Collection, */
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x04, /* Report Count (4), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x09, 0x32, /* Usage (In Range), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
- 0x26, 0x00, 0x50, /* Logical Maximum (20480), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x70, 0x17, /* Physical Maximum (6000), */
- 0x26, 0x00, 0x3C, /* Logical Maximum (15360), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x09, 0x02, /* Usage (Mouse), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x11, /* Report ID (17), */
- 0x09, 0x01, /* Usage (Pointer), */
- 0xA0, /* Collection (Physical), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x09, /* Usage Page (Button), */
- 0x75, 0x01, /* Report Size (1), */
- 0x19, 0x01, /* Usage Minimum (01h), */
- 0x29, 0x03, /* Usage Maximum (03h), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x05, /* Report Count (5), */
- 0x81, 0x01, /* Input (Constant), */
- 0xB4, /* Pop, */
- 0x95, 0x01, /* Report Count (1), */
- 0xA4, /* Push, */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x75, 0x10, /* Report Size (16), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
- 0x26, 0x00, 0x50, /* Logical Maximum (20480), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x70, 0x17, /* Physical Maximum (6000), */
- 0x26, 0x00, 0x3C, /* Logical Maximum (15360), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x75, 0x08, /* Report Size (8), */
- 0x09, 0x38, /* Usage (Wheel), */
- 0x15, 0xFF, /* Logical Minimum (-1), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x81, 0x01, /* Input (Constant), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/*
- * See EasyPen M610X description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=KYE_EasyPen_M610X
- */
-
-/* Original EasyPen M610X report descriptor size */
-#define EASYPEN_M610X_RDESC_ORIG_SIZE 476
-
-/* Fixed EasyPen M610X report descriptor */
-static __u8 easypen_m610x_rdesc_fixed[] = {
- 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
- 0x09, 0x01, /* Usage (01h), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x05, /* Report ID (5), */
- 0x09, 0x01, /* Usage (01h), */
- 0x15, 0x80, /* Logical Minimum (-128), */
- 0x25, 0x7F, /* Logical Maximum (127), */
- 0x75, 0x08, /* Report Size (8), */
- 0x95, 0x07, /* Report Count (7), */
- 0xB1, 0x02, /* Feature (Variable), */
- 0xC0, /* End Collection, */
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x04, /* Report Count (4), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x09, 0x32, /* Usage (In Range), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x10, 0x27, /* Physical Maximum (10000), */
- 0x27, 0x00, 0xA0, 0x00, 0x00, /* Logical Maximum (40960), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */
- 0x26, 0x00, 0x64, /* Logical Maximum (25600), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x0C, /* Usage Page (Consumer), */
- 0x09, 0x01, /* Usage (Consumer Control), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x12, /* Report ID (18), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x95, 0x04, /* Report Count (4), */
- 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */
- 0x0A, 0x79, 0x02, /* Usage (AC Redo Or Repeat), */
- 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
- 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x01, /* Report Count (1), */
- 0x75, 0x14, /* Report Size (20), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x20, /* Report Size (32), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0xC0 /* End Collection */
-};
-
-static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- switch (hdev->product) {
- case USB_DEVICE_ID_KYE_ERGO_525V:
- /* the fixups that need to be done:
- * - change led usage page to button for extra buttons
- * - report size 8 count 1 must be size 1 count 8 for button
- * bitfield
- * - change the button usage range to 4-7 for the extra
- * buttons
- */
- if (*rsize >= 74 &&
- rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
- rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
- rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
- rdesc[71] == 0x75 && rdesc[72] == 0x08 &&
- rdesc[73] == 0x95 && rdesc[74] == 0x01) {
- hid_info(hdev,
- "fixing up Kye/Genius Ergo Mouse "
- "report descriptor\n");
- rdesc[62] = 0x09;
- rdesc[64] = 0x04;
- rdesc[66] = 0x07;
- rdesc[72] = 0x01;
- rdesc[74] = 0x08;
- }
- break;
- case USB_DEVICE_ID_KYE_EASYPEN_I405X:
- if (*rsize == EASYPEN_I405X_RDESC_ORIG_SIZE) {
- rdesc = easypen_i405x_rdesc_fixed;
- *rsize = sizeof(easypen_i405x_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
- if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) {
- rdesc = mousepen_i608x_rdesc_fixed;
- *rsize = sizeof(mousepen_i608x_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_KYE_EASYPEN_M610X:
- if (*rsize == EASYPEN_M610X_RDESC_ORIG_SIZE) {
- rdesc = easypen_m610x_rdesc_fixed;
- *rsize = sizeof(easypen_m610x_rdesc_fixed);
- }
- break;
- }
- return rdesc;
-}
-
-/**
- * Enable fully-functional tablet mode by setting a special feature report.
- *
- * @hdev: HID device
- *
- * The specific report ID and data were discovered by sniffing the
- * Windows driver traffic.
- */
-static int kye_tablet_enable(struct hid_device *hdev)
-{
- struct list_head *list;
- struct list_head *head;
- struct hid_report *report;
- __s32 *value;
-
- list = &hdev->report_enum[HID_FEATURE_REPORT].report_list;
- list_for_each(head, list) {
- report = list_entry(head, struct hid_report, list);
- if (report->id == 5)
- break;
- }
-
- if (head == list) {
- hid_err(hdev, "tablet-enabling feature report not found\n");
- return -ENODEV;
- }
-
- if (report->maxfield < 1 || report->field[0]->report_count < 7) {
- hid_err(hdev, "invalid tablet-enabling feature report\n");
- return -ENODEV;
- }
-
- value = report->field[0]->value;
-
- value[0] = 0x12;
- value[1] = 0x10;
- value[2] = 0x11;
- value[3] = 0x12;
- value[4] = 0x00;
- value[5] = 0x00;
- value[6] = 0x00;
- usbhid_submit_report(hdev, report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- switch (id->product) {
- case USB_DEVICE_ID_KYE_EASYPEN_I405X:
- case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
- case USB_DEVICE_ID_KYE_EASYPEN_M610X:
- ret = kye_tablet_enable(hdev);
- if (ret) {
- hid_err(hdev, "tablet enabling failed\n");
- goto enabling_err;
- }
- break;
- }
-
- return 0;
-enabling_err:
- hid_hw_stop(hdev);
-err:
- return ret;
-}
-
-static const struct hid_device_id kye_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
- USB_DEVICE_ID_KYE_EASYPEN_I405X) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
- USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
- { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
- USB_DEVICE_ID_KYE_EASYPEN_M610X) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, kye_devices);
-
-static struct hid_driver kye_driver = {
- .name = "kye",
- .id_table = kye_devices,
- .probe = kye_probe,
- .report_fixup = kye_report_fixup,
-};
-
-static int __init kye_init(void)
-{
- return hid_register_driver(&kye_driver);
-}
-
-static void __exit kye_exit(void)
-{
- hid_unregister_driver(&kye_driver);
-}
-
-module_init(kye_init);
-module_exit(kye_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-lcpower.c b/ANDROID_3.4.5/drivers/hid/hid-lcpower.c
deleted file mode 100644
index c4fe9bd0..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-lcpower.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * HID driver for LC Power Model RC1000MCE
- *
- * Copyright (c) 2011 Chris Schlund
- * based on hid-topseed module
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define ts_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != 0x0ffbc0000)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x046: ts_map_key_clear(KEY_YELLOW); break;
- case 0x047: ts_map_key_clear(KEY_GREEN); break;
- case 0x049: ts_map_key_clear(KEY_BLUE); break;
- case 0x04a: ts_map_key_clear(KEY_RED); break;
- case 0x00d: ts_map_key_clear(KEY_HOME); break;
- case 0x025: ts_map_key_clear(KEY_TV); break;
- case 0x048: ts_map_key_clear(KEY_VCR); break;
- case 0x024: ts_map_key_clear(KEY_MENU); break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static const struct hid_device_id ts_devices[] = {
- { HID_USB_DEVICE( USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ts_devices);
-
-static struct hid_driver ts_driver = {
- .name = "LC RC1000MCE",
- .id_table = ts_devices,
- .input_mapping = ts_input_mapping,
-};
-
-static int __init ts_init(void)
-{
- return hid_register_driver(&ts_driver);
-}
-
-static void __exit ts_exit(void)
-{
- hid_unregister_driver(&ts_driver);
-}
-
-module_init(ts_init);
-module_exit(ts_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-lg.c b/ANDROID_3.4.5/drivers/hid/hid-lg.c
deleted file mode 100644
index e7a7bd1e..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-lg.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * HID driver for some logitech "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- * Copyright (c) 2010 Hendrik Iben
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/random.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-
-#include "hid-ids.h"
-#include "hid-lg.h"
-
-#define LG_RDESC 0x001
-#define LG_BAD_RELATIVE_KEYS 0x002
-#define LG_DUPLICATE_USAGES 0x004
-#define LG_EXPANDED_KEYMAP 0x010
-#define LG_IGNORE_DOUBLED_WHEEL 0x020
-#define LG_WIRELESS 0x040
-#define LG_INVERT_HWHEEL 0x080
-#define LG_NOGET 0x100
-#define LG_FF 0x200
-#define LG_FF2 0x400
-#define LG_RDESC_REL_ABS 0x800
-#define LG_FF3 0x1000
-#define LG_FF4 0x2000
-
-/* Size of the original descriptor of the Driving Force Pro wheel */
-#define DFP_RDESC_ORIG_SIZE 97
-
-/* Fixed report descriptor for Logitech Driving Force Pro wheel controller
- *
- * The original descriptor hides the separate throttle and brake axes in
- * a custom vendor usage page, providing only a combined value as
- * GenericDesktop.Y.
- * This descriptor removes the combined Y axis and instead reports
- * separate throttle (Y) and brake (RZ).
- */
-static __u8 dfp_rdesc_fixed[] = {
-0x05, 0x01, /* Usage Page (Desktop), */
-0x09, 0x04, /* Usage (Joystik), */
-0xA1, 0x01, /* Collection (Application), */
-0xA1, 0x02, /* Collection (Logical), */
-0x95, 0x01, /* Report Count (1), */
-0x75, 0x0E, /* Report Size (14), */
-0x14, /* Logical Minimum (0), */
-0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
-0x34, /* Physical Minimum (0), */
-0x46, 0xFF, 0x3F, /* Physical Maximum (16383), */
-0x09, 0x30, /* Usage (X), */
-0x81, 0x02, /* Input (Variable), */
-0x95, 0x0E, /* Report Count (14), */
-0x75, 0x01, /* Report Size (1), */
-0x25, 0x01, /* Logical Maximum (1), */
-0x45, 0x01, /* Physical Maximum (1), */
-0x05, 0x09, /* Usage Page (Button), */
-0x19, 0x01, /* Usage Minimum (01h), */
-0x29, 0x0E, /* Usage Maximum (0Eh), */
-0x81, 0x02, /* Input (Variable), */
-0x05, 0x01, /* Usage Page (Desktop), */
-0x95, 0x01, /* Report Count (1), */
-0x75, 0x04, /* Report Size (4), */
-0x25, 0x07, /* Logical Maximum (7), */
-0x46, 0x3B, 0x01, /* Physical Maximum (315), */
-0x65, 0x14, /* Unit (Degrees), */
-0x09, 0x39, /* Usage (Hat Switch), */
-0x81, 0x42, /* Input (Variable, Nullstate), */
-0x65, 0x00, /* Unit, */
-0x26, 0xFF, 0x00, /* Logical Maximum (255), */
-0x46, 0xFF, 0x00, /* Physical Maximum (255), */
-0x75, 0x08, /* Report Size (8), */
-0x81, 0x01, /* Input (Constant), */
-0x09, 0x31, /* Usage (Y), */
-0x81, 0x02, /* Input (Variable), */
-0x09, 0x35, /* Usage (Rz), */
-0x81, 0x02, /* Input (Variable), */
-0x81, 0x01, /* Input (Constant), */
-0xC0, /* End Collection, */
-0xA1, 0x02, /* Collection (Logical), */
-0x09, 0x02, /* Usage (02h), */
-0x95, 0x07, /* Report Count (7), */
-0x91, 0x02, /* Output (Variable), */
-0xC0, /* End Collection, */
-0xC0 /* End Collection */
-};
-
-
-/*
- * Certain Logitech keyboards send in report #3 keys which are far
- * above the logical maximum described in descriptor. This extends
- * the original value of 0x28c of logical maximum to 0x104d
- */
-static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
- rdesc[84] == 0x8c && rdesc[85] == 0x02) {
- hid_info(hdev,
- "fixing up Logitech keyboard report descriptor\n");
- rdesc[84] = rdesc[89] = 0x4d;
- rdesc[85] = rdesc[90] = 0x10;
- }
- if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
- rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
- rdesc[49] == 0x81 && rdesc[50] == 0x06) {
- hid_info(hdev,
- "fixing up rel/abs in Logitech report descriptor\n");
- rdesc[33] = rdesc[50] = 0x02;
- }
- if ((quirks & LG_FF4) && *rsize >= 101 &&
- rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
- rdesc[47] == 0x05 && rdesc[48] == 0x09) {
- hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n");
- rdesc[41] = 0x05;
- rdesc[42] = 0x09;
- rdesc[47] = 0x95;
- rdesc[48] = 0x0B;
- }
-
- switch (hdev->product) {
- case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
- if (*rsize == DFP_RDESC_ORIG_SIZE) {
- hid_info(hdev,
- "fixing up Logitech Driving Force Pro report descriptor\n");
- rdesc = dfp_rdesc_fixed;
- *rsize = sizeof(dfp_rdesc_fixed);
- }
- break;
- }
-
- return rdesc;
-}
-
-#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-
-static int lg_ultrax_remote_mapping(struct hid_input *hi,
- struct hid_usage *usage, unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
- return 0;
-
- set_bit(EV_REP, hi->input->evbit);
- switch (usage->hid & HID_USAGE) {
- /* Reported on Logitech Ultra X Media Remote */
- case 0x004: lg_map_key_clear(KEY_AGAIN); break;
- case 0x00d: lg_map_key_clear(KEY_HOME); break;
- case 0x024: lg_map_key_clear(KEY_SHUFFLE); break;
- case 0x025: lg_map_key_clear(KEY_TV); break;
- case 0x026: lg_map_key_clear(KEY_MENU); break;
- case 0x031: lg_map_key_clear(KEY_AUDIO); break;
- case 0x032: lg_map_key_clear(KEY_TEXT); break;
- case 0x033: lg_map_key_clear(KEY_LAST); break;
- case 0x047: lg_map_key_clear(KEY_MP3); break;
- case 0x048: lg_map_key_clear(KEY_DVD); break;
- case 0x049: lg_map_key_clear(KEY_MEDIA); break;
- case 0x04a: lg_map_key_clear(KEY_VIDEO); break;
- case 0x04b: lg_map_key_clear(KEY_ANGLE); break;
- case 0x04c: lg_map_key_clear(KEY_LANGUAGE); break;
- case 0x04d: lg_map_key_clear(KEY_SUBTITLE); break;
- case 0x051: lg_map_key_clear(KEY_RED); break;
- case 0x052: lg_map_key_clear(KEY_CLOSE); break;
-
- default:
- return 0;
- }
- return 1;
-}
-
-static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
-
- case 0x00d: lg_map_key_clear(KEY_MEDIA); break;
- default:
- return 0;
-
- }
- return 1;
-}
-
-static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x1001: lg_map_key_clear(KEY_MESSENGER); break;
- case 0x1003: lg_map_key_clear(KEY_SOUND); break;
- case 0x1004: lg_map_key_clear(KEY_VIDEO); break;
- case 0x1005: lg_map_key_clear(KEY_AUDIO); break;
- case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break;
- /* The following two entries are Playlist 1 and 2 on the MX3200 */
- case 0x100f: lg_map_key_clear(KEY_FN_1); break;
- case 0x1010: lg_map_key_clear(KEY_FN_2); break;
- case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break;
- case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break;
- case 0x1013: lg_map_key_clear(KEY_CAMERA); break;
- case 0x1014: lg_map_key_clear(KEY_MESSENGER); break;
- case 0x1015: lg_map_key_clear(KEY_RECORD); break;
- case 0x1016: lg_map_key_clear(KEY_PLAYER); break;
- case 0x1017: lg_map_key_clear(KEY_EJECTCD); break;
- case 0x1018: lg_map_key_clear(KEY_MEDIA); break;
- case 0x1019: lg_map_key_clear(KEY_PROG1); break;
- case 0x101a: lg_map_key_clear(KEY_PROG2); break;
- case 0x101b: lg_map_key_clear(KEY_PROG3); break;
- case 0x101c: lg_map_key_clear(KEY_CYCLEWINDOWS); break;
- case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break;
- case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break;
- case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break;
- case 0x1023: lg_map_key_clear(KEY_CLOSE); break;
- case 0x1027: lg_map_key_clear(KEY_MENU); break;
- /* this one is marked as 'Rotate' */
- case 0x1028: lg_map_key_clear(KEY_ANGLE); break;
- case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break;
- case 0x102a: lg_map_key_clear(KEY_BACK); break;
- case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break;
- case 0x102d: lg_map_key_clear(KEY_WWW); break;
- /* The following two are 'Start/answer call' and 'End/reject call'
- on the MX3200 */
- case 0x1031: lg_map_key_clear(KEY_OK); break;
- case 0x1032: lg_map_key_clear(KEY_CANCEL); break;
- case 0x1041: lg_map_key_clear(KEY_BATTERY); break;
- case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break;
- case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break;
- case 0x1044: lg_map_key_clear(KEY_PRESENTATION); break;
- case 0x1045: lg_map_key_clear(KEY_UNDO); break;
- case 0x1046: lg_map_key_clear(KEY_REDO); break;
- case 0x1047: lg_map_key_clear(KEY_PRINT); break;
- case 0x1048: lg_map_key_clear(KEY_SAVE); break;
- case 0x1049: lg_map_key_clear(KEY_PROG1); break;
- case 0x104a: lg_map_key_clear(KEY_PROG2); break;
- case 0x104b: lg_map_key_clear(KEY_PROG3); break;
- case 0x104c: lg_map_key_clear(KEY_PROG4); break;
-
- default:
- return 0;
- }
- return 1;
-}
-
-static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- /* extended mapping for certain Logitech hardware (Logitech cordless
- desktop LX500) */
- static const u8 e_keymap[] = {
- 0,216, 0,213,175,156, 0, 0, 0, 0,
- 144, 0, 0, 0, 0, 0, 0, 0, 0,212,
- 174,167,152,161,112, 0, 0, 0,154, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,183,184,185,186,187,
- 188,189,190,191,192,193,194, 0, 0, 0
- };
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
- unsigned int hid = usage->hid;
-
- if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER &&
- lg_ultrax_remote_mapping(hi, usage, bit, max))
- return 1;
-
- if (hdev->product == USB_DEVICE_ID_DINOVO_MINI &&
- lg_dinovo_mapping(hi, usage, bit, max))
- return 1;
-
- if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
- return 1;
-
- if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
- return 0;
-
- hid &= HID_USAGE;
-
- /* Special handling for Logitech Cordless Desktop */
- if (field->application == HID_GD_MOUSE) {
- if ((quirks & LG_IGNORE_DOUBLED_WHEEL) &&
- (hid == 7 || hid == 8))
- return -1;
- } else {
- if ((quirks & LG_EXPANDED_KEYMAP) &&
- hid < ARRAY_SIZE(e_keymap) &&
- e_keymap[hid] != 0) {
- hid_map_usage(hi, usage, bit, max, EV_KEY,
- e_keymap[hid]);
- return 1;
- }
- }
-
- return 0;
-}
-
-static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY &&
- (field->flags & HID_MAIN_ITEM_RELATIVE))
- field->flags &= ~HID_MAIN_ITEM_RELATIVE;
-
- if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY ||
- usage->type == EV_REL || usage->type == EV_ABS))
- clear_bit(usage->code, *bit);
-
- return 0;
-}
-
-static int lg_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) {
- input_event(field->hidinput->input, usage->type, usage->code,
- -value);
- return 1;
- }
-
- return 0;
-}
-
-static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- unsigned long quirks = id->driver_data;
- unsigned int connect_mask = HID_CONNECT_DEFAULT;
- int ret;
-
- hid_set_drvdata(hdev, (void *)quirks);
-
- if (quirks & LG_NOGET)
- hdev->quirks |= HID_QUIRK_NOGET;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- if (quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4))
- connect_mask &= ~HID_CONNECT_FF;
-
- ret = hid_hw_start(hdev, connect_mask);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- /* Setup wireless link with Logitech Wii wheel */
- if(hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
- unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
-
- if (ret >= 0) {
- /* insert a little delay of 10 jiffies ~ 40ms */
- wait_queue_head_t wait;
- init_waitqueue_head (&wait);
- wait_event_interruptible_timeout(wait, 0, 10);
-
- /* Select random Address */
- buf[1] = 0xB2;
- get_random_bytes(&buf[2], 2);
-
- ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
- }
- }
-
- if (quirks & LG_FF)
- lgff_init(hdev);
- if (quirks & LG_FF2)
- lg2ff_init(hdev);
- if (quirks & LG_FF3)
- lg3ff_init(hdev);
- if (quirks & LG_FF4)
- lg4ff_init(hdev);
-
- return 0;
-err_free:
- return ret;
-}
-
-static void lg_remove(struct hid_device *hdev)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
- if(quirks & LG_FF4)
- lg4ff_deinit(hdev);
-
- hid_hw_stop(hdev);
-}
-
-static const struct hid_device_id lg_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
- .driver_data = LG_RDESC | LG_WIRELESS },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER),
- .driver_data = LG_RDESC | LG_WIRELESS },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2),
- .driver_data = LG_RDESC | LG_WIRELESS },
-
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER),
- .driver_data = LG_BAD_RELATIVE_KEYS },
-
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP),
- .driver_data = LG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE),
- .driver_data = LG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI),
- .driver_data = LG_DUPLICATE_USAGES },
-
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD),
- .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500),
- .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
-
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D),
- .driver_data = LG_NOGET },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL),
- .driver_data = LG_NOGET | LG_FF4 },
-
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD),
- .driver_data = LG_FF2 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD),
- .driver_data = LG_FF },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2),
- .driver_data = LG_FF },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D),
- .driver_data = LG_FF },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO),
- .driver_data = LG_FF },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL),
- .driver_data = LG_FF4 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
- .driver_data = LG_FF4 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
- .driver_data = LG_FF4 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL),
- .driver_data = LG_FF4 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL),
- .driver_data = LG_FF4 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
- .driver_data = LG_NOGET | LG_FF4 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
- .driver_data = LG_FF4 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
- .driver_data = LG_FF },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
- .driver_data = LG_FF2 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940),
- .driver_data = LG_FF3 },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
- .driver_data = LG_RDESC_REL_ABS },
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
- .driver_data = LG_RDESC_REL_ABS },
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, lg_devices);
-
-static struct hid_driver lg_driver = {
- .name = "logitech",
- .id_table = lg_devices,
- .report_fixup = lg_report_fixup,
- .input_mapping = lg_input_mapping,
- .input_mapped = lg_input_mapped,
- .event = lg_event,
- .probe = lg_probe,
- .remove = lg_remove,
-};
-
-static int __init lg_init(void)
-{
- return hid_register_driver(&lg_driver);
-}
-
-static void __exit lg_exit(void)
-{
- hid_unregister_driver(&lg_driver);
-}
-
-module_init(lg_init);
-module_exit(lg_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-lg.h b/ANDROID_3.4.5/drivers/hid/hid-lg.h
deleted file mode 100644
index 4b097286..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-lg.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __HID_LG_H
-#define __HID_LG_H
-
-#ifdef CONFIG_LOGITECH_FF
-int lgff_init(struct hid_device *hdev);
-#else
-static inline int lgff_init(struct hid_device *hdev) { return -1; }
-#endif
-
-#ifdef CONFIG_LOGIRUMBLEPAD2_FF
-int lg2ff_init(struct hid_device *hdev);
-#else
-static inline int lg2ff_init(struct hid_device *hdev) { return -1; }
-#endif
-
-#ifdef CONFIG_LOGIG940_FF
-int lg3ff_init(struct hid_device *hdev);
-#else
-static inline int lg3ff_init(struct hid_device *hdev) { return -1; }
-#endif
-
-#ifdef CONFIG_LOGIWHEELS_FF
-int lg4ff_init(struct hid_device *hdev);
-int lg4ff_deinit(struct hid_device *hdev);
-#else
-static inline int lg4ff_init(struct hid_device *hdev) { return -1; }
-static inline int lg4ff_deinit(struct hid_device *hdev) { return -1; }
-#endif
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-lg2ff.c b/ANDROID_3.4.5/drivers/hid/hid-lg2ff.c
deleted file mode 100644
index 3c31bc65..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-lg2ff.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Force feedback support for Logitech RumblePad and Rumblepad 2
- *
- * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-
-#include "usbhid/usbhid.h"
-#include "hid-lg.h"
-
-struct lg2ff_device {
- struct hid_report *report;
-};
-
-static int play_effect(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct lg2ff_device *lg2ff = data;
- int weak, strong;
-
- strong = effect->u.rumble.strong_magnitude;
- weak = effect->u.rumble.weak_magnitude;
-
- if (weak || strong) {
- weak = weak * 0xff / 0xffff;
- strong = strong * 0xff / 0xffff;
-
- lg2ff->report->field[0]->value[0] = 0x51;
- lg2ff->report->field[0]->value[2] = weak;
- lg2ff->report->field[0]->value[4] = strong;
- } else {
- lg2ff->report->field[0]->value[0] = 0xf3;
- lg2ff->report->field[0]->value[2] = 0x00;
- lg2ff->report->field[0]->value[4] = 0x00;
- }
-
- usbhid_submit_report(hid, lg2ff->report, USB_DIR_OUT);
- return 0;
-}
-
-int lg2ff_init(struct hid_device *hid)
-{
- struct lg2ff_device *lg2ff;
- struct hid_report *report;
- struct hid_input *hidinput = list_entry(hid->inputs.next,
- struct hid_input, list);
- struct list_head *report_list =
- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- int error;
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output report found\n");
- return -ENODEV;
- }
-
- report = list_entry(report_list->next, struct hid_report, list);
-
- if (report->maxfield < 1) {
- hid_err(hid, "output report is empty\n");
- return -ENODEV;
- }
- if (report->field[0]->report_count < 7) {
- hid_err(hid, "not enough values in the field\n");
- return -ENODEV;
- }
-
- lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
- if (!lg2ff)
- return -ENOMEM;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- error = input_ff_create_memless(dev, lg2ff, play_effect);
- if (error) {
- kfree(lg2ff);
- return error;
- }
-
- lg2ff->report = report;
- report->field[0]->value[0] = 0xf3;
- report->field[0]->value[1] = 0x00;
- report->field[0]->value[2] = 0x00;
- report->field[0]->value[3] = 0x00;
- report->field[0]->value[4] = 0x00;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
-
- hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula <anssi.hannula@gmail.com>\n");
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/drivers/hid/hid-lg3ff.c b/ANDROID_3.4.5/drivers/hid/hid-lg3ff.c
deleted file mode 100644
index f98644c2..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-lg3ff.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Force feedback support for Logitech Flight System G940
- *
- * Copyright (c) 2009 Gary Stein <LordCnidarian@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-
-#include "usbhid/usbhid.h"
-#include "hid-lg.h"
-
-/*
- * G940 Theory of Operation (from experimentation)
- *
- * There are 63 fields (only 3 of them currently used)
- * 0 - seems to be command field
- * 1 - 30 deal with the x axis
- * 31 -60 deal with the y axis
- *
- * Field 1 is x axis constant force
- * Field 31 is y axis constant force
- *
- * other interesting fields 1,2,3,4 on x axis
- * (same for 31,32,33,34 on y axis)
- *
- * 0 0 127 127 makes the joystick autocenter hard
- *
- * 127 0 127 127 makes the joystick loose on the right,
- * but stops all movemnt left
- *
- * -127 0 -127 -127 makes the joystick loose on the left,
- * but stops all movement right
- *
- * 0 0 -127 -127 makes the joystick rattle very hard
- *
- * I'm sure these are effects that I don't know enough about them
- */
-
-struct lg3ff_device {
- struct hid_report *report;
-};
-
-static int hid_lg3ff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
- int x, y;
-
-/*
- * Maxusage should always be 63 (maximum fields)
- * likely a better way to ensure this data is clean
- */
- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage);
-
- switch (effect->type) {
- case FF_CONSTANT:
-/*
- * Already clamped in ff_memless
- * 0 is center (different then other logitech)
- */
- x = effect->u.ramp.start_level;
- y = effect->u.ramp.end_level;
-
- /* send command byte */
- report->field[0]->value[0] = 0x51;
-
-/*
- * Sign backwards from other Force3d pro
- * which get recast here in two's complement 8 bits
- */
- report->field[0]->value[1] = (unsigned char)(-x);
- report->field[0]->value[31] = (unsigned char)(-y);
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
- break;
- }
- return 0;
-}
-static void hid_lg3ff_set_autocenter(struct input_dev *dev, u16 magnitude)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
-
-/*
- * Auto Centering probed from device
- * NOTE: deadman's switch on G940 must be covered
- * for effects to work
- */
- report->field[0]->value[0] = 0x51;
- report->field[0]->value[1] = 0x00;
- report->field[0]->value[2] = 0x00;
- report->field[0]->value[3] = 0x7F;
- report->field[0]->value[4] = 0x7F;
- report->field[0]->value[31] = 0x00;
- report->field[0]->value[32] = 0x00;
- report->field[0]->value[33] = 0x7F;
- report->field[0]->value[34] = 0x7F;
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
-}
-
-
-static const signed short ff3_joystick_ac[] = {
- FF_CONSTANT,
- FF_AUTOCENTER,
- -1
-};
-
-int lg3ff_init(struct hid_device *hid)
-{
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- struct hid_report *report;
- struct hid_field *field;
- const signed short *ff_bits = ff3_joystick_ac;
- int error;
- int i;
-
- /* Find the report to use */
- if (list_empty(report_list)) {
- hid_err(hid, "No output report found\n");
- return -1;
- }
-
- /* Check that the report looks ok */
- report = list_entry(report_list->next, struct hid_report, list);
- if (!report) {
- hid_err(hid, "NULL output report\n");
- return -1;
- }
-
- field = report->field[0];
- if (!field) {
- hid_err(hid, "NULL field\n");
- return -1;
- }
-
- /* Assume single fixed device G940 */
- for (i = 0; ff_bits[i] >= 0; i++)
- set_bit(ff_bits[i], dev->ffbit);
-
- error = input_ff_create_memless(dev, NULL, hid_lg3ff_play);
- if (error)
- return error;
-
- if (test_bit(FF_AUTOCENTER, dev->ffbit))
- dev->ff->set_autocenter = hid_lg3ff_set_autocenter;
-
- hid_info(hid, "Force feedback for Logitech Flight System G940 by Gary Stein <LordCnidarian@gmail.com>\n");
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-lg4ff.c b/ANDROID_3.4.5/drivers/hid/hid-lg4ff.c
deleted file mode 100644
index 6ecc9e22..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-lg4ff.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Force feedback support for Logitech Speed Force Wireless
- *
- * http://wiibrew.org/wiki/Logitech_USB_steering_wheel
- *
- * Copyright (c) 2010 Simon Wood <simon@mungewell.org>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-
-#include "usbhid/usbhid.h"
-#include "hid-lg.h"
-#include "hid-ids.h"
-
-#define DFGT_REV_MAJ 0x13
-#define DFGT_REV_MIN 0x22
-#define DFP_REV_MAJ 0x11
-#define DFP_REV_MIN 0x06
-#define FFEX_REV_MAJ 0x21
-#define FFEX_REV_MIN 0x00
-#define G25_REV_MAJ 0x12
-#define G25_REV_MIN 0x22
-#define G27_REV_MAJ 0x12
-#define G27_REV_MIN 0x38
-
-#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev)
-
-static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range);
-static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range);
-static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
-
-static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store);
-
-static bool list_inited;
-
-struct lg4ff_device_entry {
- char *device_id; /* Use name in respective kobject structure's address as the ID */
- __u16 range;
- __u16 min_range;
- __u16 max_range;
- __u8 leds;
- struct list_head list;
- void (*set_range)(struct hid_device *hid, u16 range);
-};
-
-static struct lg4ff_device_entry device_list;
-
-static const signed short lg4ff_wheel_effects[] = {
- FF_CONSTANT,
- FF_AUTOCENTER,
- -1
-};
-
-struct lg4ff_wheel {
- const __u32 product_id;
- const signed short *ff_effects;
- const __u16 min_range;
- const __u16 max_range;
- void (*set_range)(struct hid_device *hid, u16 range);
-};
-
-static const struct lg4ff_wheel lg4ff_devices[] = {
- {USB_DEVICE_ID_LOGITECH_WHEEL, lg4ff_wheel_effects, 40, 270, NULL},
- {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL, lg4ff_wheel_effects, 40, 270, NULL},
- {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, lg4ff_wheel_effects, 40, 900, hid_lg4ff_set_range_dfp},
- {USB_DEVICE_ID_LOGITECH_G25_WHEEL, lg4ff_wheel_effects, 40, 900, hid_lg4ff_set_range_g25},
- {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, lg4ff_wheel_effects, 40, 900, hid_lg4ff_set_range_g25},
- {USB_DEVICE_ID_LOGITECH_G27_WHEEL, lg4ff_wheel_effects, 40, 900, hid_lg4ff_set_range_g25},
- {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL},
- {USB_DEVICE_ID_LOGITECH_WII_WHEEL, lg4ff_wheel_effects, 40, 270, NULL}
-};
-
-struct lg4ff_native_cmd {
- const __u8 cmd_num; /* Number of commands to send */
- const __u8 cmd[];
-};
-
-struct lg4ff_usb_revision {
- const __u16 rev_maj;
- const __u16 rev_min;
- const struct lg4ff_native_cmd *command;
-};
-
-static const struct lg4ff_native_cmd native_dfp = {
- 1,
- {0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}
-};
-
-static const struct lg4ff_native_cmd native_dfgt = {
- 2,
- {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1st command */
- 0xf8, 0x09, 0x03, 0x01, 0x00, 0x00, 0x00} /* 2nd command */
-};
-
-static const struct lg4ff_native_cmd native_g25 = {
- 1,
- {0xf8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}
-};
-
-static const struct lg4ff_native_cmd native_g27 = {
- 2,
- {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1st command */
- 0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00} /* 2nd command */
-};
-
-static const struct lg4ff_usb_revision lg4ff_revs[] = {
- {DFGT_REV_MAJ, DFGT_REV_MIN, &native_dfgt}, /* Driving Force GT */
- {DFP_REV_MAJ, DFP_REV_MIN, &native_dfp}, /* Driving Force Pro */
- {G25_REV_MAJ, G25_REV_MIN, &native_g25}, /* G25 */
- {G27_REV_MAJ, G27_REV_MIN, &native_g27}, /* G27 */
-};
-
-static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
- int x;
-
-#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
-
- switch (effect->type) {
- case FF_CONSTANT:
- x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */
- CLAMP(x);
- report->field[0]->value[0] = 0x11; /* Slot 1 */
- report->field[0]->value[1] = 0x08;
- report->field[0]->value[2] = x;
- report->field[0]->value[3] = 0x80;
- report->field[0]->value[4] = 0x00;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
- break;
- }
- return 0;
-}
-
-/* Sends default autocentering command compatible with
- * all wheels except Formula Force EX */
-static void hid_lg4ff_set_autocenter_default(struct input_dev *dev, u16 magnitude)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
-
- report->field[0]->value[0] = 0xfe;
- report->field[0]->value[1] = 0x0d;
- report->field[0]->value[2] = magnitude >> 13;
- report->field[0]->value[3] = magnitude >> 13;
- report->field[0]->value[4] = magnitude >> 8;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
-}
-
-/* Sends autocentering command compatible with Formula Force EX */
-static void hid_lg4ff_set_autocenter_ffex(struct input_dev *dev, u16 magnitude)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
- magnitude = magnitude * 90 / 65535;
-
-
- report->field[0]->value[0] = 0xfe;
- report->field[0]->value[1] = 0x03;
- report->field[0]->value[2] = magnitude >> 14;
- report->field[0]->value[3] = magnitude >> 14;
- report->field[0]->value[4] = magnitude;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
-}
-
-/* Sends command to set range compatible with G25/G27/Driving Force GT */
-static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range)
-{
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
- dbg_hid("G25/G27/DFGT: setting range to %u\n", range);
-
- report->field[0]->value[0] = 0xf8;
- report->field[0]->value[1] = 0x81;
- report->field[0]->value[2] = range & 0x00ff;
- report->field[0]->value[3] = (range & 0xff00) >> 8;
- report->field[0]->value[4] = 0x00;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
-}
-
-/* Sends commands to set range compatible with Driving Force Pro wheel */
-static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range)
-{
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
- int start_left, start_right, full_range;
- dbg_hid("Driving Force Pro: setting range to %u\n", range);
-
- /* Prepare "coarse" limit command */
- report->field[0]->value[0] = 0xf8;
- report->field[0]->value[1] = 0x00; /* Set later */
- report->field[0]->value[2] = 0x00;
- report->field[0]->value[3] = 0x00;
- report->field[0]->value[4] = 0x00;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
-
- if (range > 200) {
- report->field[0]->value[1] = 0x03;
- full_range = 900;
- } else {
- report->field[0]->value[1] = 0x02;
- full_range = 200;
- }
- usbhid_submit_report(hid, report, USB_DIR_OUT);
-
- /* Prepare "fine" limit command */
- report->field[0]->value[0] = 0x81;
- report->field[0]->value[1] = 0x0b;
- report->field[0]->value[2] = 0x00;
- report->field[0]->value[3] = 0x00;
- report->field[0]->value[4] = 0x00;
- report->field[0]->value[5] = 0x00;
- report->field[0]->value[6] = 0x00;
-
- if (range == 200 || range == 900) { /* Do not apply any fine limit */
- usbhid_submit_report(hid, report, USB_DIR_OUT);
- return;
- }
-
- /* Construct fine limit command */
- start_left = (((full_range - range + 1) * 2047) / full_range);
- start_right = 0xfff - start_left;
-
- report->field[0]->value[2] = start_left >> 4;
- report->field[0]->value[3] = start_right >> 4;
- report->field[0]->value[4] = 0xff;
- report->field[0]->value[5] = (start_right & 0xe) << 4 | (start_left & 0xe);
- report->field[0]->value[6] = 0xff;
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
-}
-
-static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_native_cmd *cmd)
-{
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
- __u8 i, j;
-
- j = 0;
- while (j < 7*cmd->cmd_num) {
- for (i = 0; i < 7; i++)
- report->field[0]->value[i] = cmd->cmd[j++];
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
- }
-}
-
-/* Read current range and display it in terminal */
-static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct lg4ff_device_entry *uninitialized_var(entry);
- struct list_head *h;
- struct hid_device *hid = to_hid_device(dev);
- size_t count;
-
- list_for_each(h, &device_list.list) {
- entry = list_entry(h, struct lg4ff_device_entry, list);
- if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0)
- break;
- }
- if (h == &device_list.list) {
- dbg_hid("Device not found!");
- return 0;
- }
-
- count = scnprintf(buf, PAGE_SIZE, "%u\n", entry->range);
- return count;
-}
-
-/* Set range to user specified value, call appropriate function
- * according to the type of the wheel */
-static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct lg4ff_device_entry *uninitialized_var(entry);
- struct list_head *h;
- struct hid_device *hid = to_hid_device(dev);
- __u16 range = simple_strtoul(buf, NULL, 10);
-
- list_for_each(h, &device_list.list) {
- entry = list_entry(h, struct lg4ff_device_entry, list);
- if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0)
- break;
- }
- if (h == &device_list.list) {
- dbg_hid("Device not found!");
- return count;
- }
-
- if (range == 0)
- range = entry->max_range;
-
- /* Check if the wheel supports range setting
- * and that the range is within limits for the wheel */
- if (entry->set_range != NULL && range >= entry->min_range && range <= entry->max_range) {
- entry->set_range(hid, range);
- entry->range = range;
- }
-
- return count;
-}
-
-int lg4ff_init(struct hid_device *hid)
-{
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- struct hid_report *report;
- struct hid_field *field;
- struct lg4ff_device_entry *entry;
- struct usb_device_descriptor *udesc;
- int error, i, j;
- __u16 bcdDevice, rev_maj, rev_min;
-
- /* Find the report to use */
- if (list_empty(report_list)) {
- hid_err(hid, "No output report found\n");
- return -1;
- }
-
- /* Check that the report looks ok */
- report = list_entry(report_list->next, struct hid_report, list);
- if (!report) {
- hid_err(hid, "NULL output report\n");
- return -1;
- }
-
- field = report->field[0];
- if (!field) {
- hid_err(hid, "NULL field\n");
- return -1;
- }
-
- /* Check what wheel has been connected */
- for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) {
- if (hid->product == lg4ff_devices[i].product_id) {
- dbg_hid("Found compatible device, product ID %04X\n", lg4ff_devices[i].product_id);
- break;
- }
- }
-
- if (i == ARRAY_SIZE(lg4ff_devices)) {
- hid_err(hid, "Device is not supported by lg4ff driver. If you think it should be, consider reporting a bug to"
- "LKML, Simon Wood <simon@mungewell.org> or Michal Maly <madcatxster@gmail.com>\n");
- return -1;
- }
-
- /* Attempt to switch wheel to native mode when applicable */
- udesc = &(hid_to_usb_dev(hid)->descriptor);
- if (!udesc) {
- hid_err(hid, "NULL USB device descriptor\n");
- return -1;
- }
- bcdDevice = le16_to_cpu(udesc->bcdDevice);
- rev_maj = bcdDevice >> 8;
- rev_min = bcdDevice & 0xff;
-
- if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_WHEEL) {
- dbg_hid("Generic wheel detected, can it do native?\n");
- dbg_hid("USB revision: %2x.%02x\n", rev_maj, rev_min);
-
- for (j = 0; j < ARRAY_SIZE(lg4ff_revs); j++) {
- if (lg4ff_revs[j].rev_maj == rev_maj && lg4ff_revs[j].rev_min == rev_min) {
- hid_lg4ff_switch_native(hid, lg4ff_revs[j].command);
- hid_info(hid, "Switched to native mode\n");
- }
- }
- }
-
- /* Set supported force feedback capabilities */
- for (j = 0; lg4ff_devices[i].ff_effects[j] >= 0; j++)
- set_bit(lg4ff_devices[i].ff_effects[j], dev->ffbit);
-
- error = input_ff_create_memless(dev, NULL, hid_lg4ff_play);
-
- if (error)
- return error;
-
- /* Check if autocentering is available and
- * set the centering force to zero by default */
- if (test_bit(FF_AUTOCENTER, dev->ffbit)) {
- if(rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN) /* Formula Force EX expects different autocentering command */
- dev->ff->set_autocenter = hid_lg4ff_set_autocenter_ffex;
- else
- dev->ff->set_autocenter = hid_lg4ff_set_autocenter_default;
-
- dev->ff->set_autocenter(dev, 0);
- }
-
- /* Initialize device_list if this is the first device to handle by lg4ff */
- if (!list_inited) {
- INIT_LIST_HEAD(&device_list.list);
- list_inited = 1;
- }
-
- /* Add the device to device_list */
- entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL);
- if (!entry) {
- hid_err(hid, "Cannot add device, insufficient memory.\n");
- return -ENOMEM;
- }
- entry->device_id = kstrdup((&hid->dev)->kobj.name, GFP_KERNEL);
- if (!entry->device_id) {
- hid_err(hid, "Cannot set device_id, insufficient memory.\n");
- kfree(entry);
- return -ENOMEM;
- }
- entry->min_range = lg4ff_devices[i].min_range;
- entry->max_range = lg4ff_devices[i].max_range;
- entry->set_range = lg4ff_devices[i].set_range;
- list_add(&entry->list, &device_list.list);
-
- /* Create sysfs interface */
- error = device_create_file(&hid->dev, &dev_attr_range);
- if (error)
- return error;
- dbg_hid("sysfs interface created\n");
-
- /* Set the maximum range to start with */
- entry->range = entry->max_range;
- if (entry->set_range != NULL)
- entry->set_range(hid, entry->range);
-
- hid_info(hid, "Force feedback for Logitech Speed Force Wireless by Simon Wood <simon@mungewell.org>\n");
- return 0;
-}
-
-int lg4ff_deinit(struct hid_device *hid)
-{
- bool found = 0;
- struct lg4ff_device_entry *entry;
- struct list_head *h, *g;
- list_for_each_safe(h, g, &device_list.list) {
- entry = list_entry(h, struct lg4ff_device_entry, list);
- if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) {
- list_del(h);
- kfree(entry->device_id);
- kfree(entry);
- found = 1;
- break;
- }
- }
-
- if (!found) {
- dbg_hid("Device entry not found!\n");
- return -1;
- }
-
- device_remove_file(&hid->dev, &dev_attr_range);
- dbg_hid("Device successfully unregistered\n");
- return 0;
-}
diff --git a/ANDROID_3.4.5/drivers/hid/hid-lgff.c b/ANDROID_3.4.5/drivers/hid/hid-lgff.c
deleted file mode 100644
index 27bc54f9..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-lgff.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Force feedback support for hid-compliant for some of the devices from
- * Logitech, namely:
- * - WingMan Cordless RumblePad
- * - WingMan Force 3D
- *
- * Copyright (c) 2002-2004 Johann Deneux
- * Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <johann.deneux@it.uu.se>
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-
-#include "usbhid/usbhid.h"
-#include "hid-lg.h"
-
-struct dev_type {
- u16 idVendor;
- u16 idProduct;
- const signed short *ff;
-};
-
-static const signed short ff_rumble[] = {
- FF_RUMBLE,
- -1
-};
-
-static const signed short ff_joystick[] = {
- FF_CONSTANT,
- -1
-};
-
-static const signed short ff_joystick_ac[] = {
- FF_CONSTANT,
- FF_AUTOCENTER,
- -1
-};
-
-static const struct dev_type devices[] = {
- { 0x046d, 0xc211, ff_rumble },
- { 0x046d, 0xc219, ff_rumble },
- { 0x046d, 0xc283, ff_joystick },
- { 0x046d, 0xc286, ff_joystick_ac },
- { 0x046d, 0xc287, ff_joystick_ac },
- { 0x046d, 0xc293, ff_joystick },
- { 0x046d, 0xc295, ff_joystick },
-};
-
-static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
- int x, y;
- unsigned int left, right;
-
-#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
-
- switch (effect->type) {
- case FF_CONSTANT:
- x = effect->u.ramp.start_level + 0x7f; /* 0x7f is center */
- y = effect->u.ramp.end_level + 0x7f;
- CLAMP(x);
- CLAMP(y);
- report->field[0]->value[0] = 0x51;
- report->field[0]->value[1] = 0x08;
- report->field[0]->value[2] = x;
- report->field[0]->value[3] = y;
- dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
- usbhid_submit_report(hid, report, USB_DIR_OUT);
- break;
-
- case FF_RUMBLE:
- right = effect->u.rumble.strong_magnitude;
- left = effect->u.rumble.weak_magnitude;
- right = right * 0xff / 0xffff;
- left = left * 0xff / 0xffff;
- CLAMP(left);
- CLAMP(right);
- report->field[0]->value[0] = 0x42;
- report->field[0]->value[1] = 0x00;
- report->field[0]->value[2] = left;
- report->field[0]->value[3] = right;
- dbg_hid("(left, right)=(%04x, %04x)\n", left, right);
- usbhid_submit_report(hid, report, USB_DIR_OUT);
- break;
- }
- return 0;
-}
-
-static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
- __s32 *value = report->field[0]->value;
- magnitude = (magnitude >> 12) & 0xf;
- *value++ = 0xfe;
- *value++ = 0x0d;
- *value++ = magnitude; /* clockwise strength */
- *value++ = magnitude; /* counter-clockwise strength */
- *value++ = 0x80;
- *value++ = 0x00;
- *value = 0x00;
- usbhid_submit_report(hid, report, USB_DIR_OUT);
-}
-
-int lgff_init(struct hid_device* hid)
-{
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- struct hid_report *report;
- struct hid_field *field;
- const signed short *ff_bits = ff_joystick;
- int error;
- int i;
-
- /* Find the report to use */
- if (list_empty(report_list)) {
- hid_err(hid, "No output report found\n");
- return -1;
- }
-
- /* Check that the report looks ok */
- report = list_entry(report_list->next, struct hid_report, list);
- field = report->field[0];
- if (!field) {
- hid_err(hid, "NULL field\n");
- return -1;
- }
-
- for (i = 0; i < ARRAY_SIZE(devices); i++) {
- if (dev->id.vendor == devices[i].idVendor &&
- dev->id.product == devices[i].idProduct) {
- ff_bits = devices[i].ff;
- break;
- }
- }
-
- for (i = 0; ff_bits[i] >= 0; i++)
- set_bit(ff_bits[i], dev->ffbit);
-
- error = input_ff_create_memless(dev, NULL, hid_lgff_play);
- if (error)
- return error;
-
- if ( test_bit(FF_AUTOCENTER, dev->ffbit) )
- dev->ff->set_autocenter = hid_lgff_set_autocenter;
-
- pr_info("Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/drivers/hid/hid-magicmouse.c b/ANDROID_3.4.5/drivers/hid/hid-magicmouse.c
deleted file mode 100644
index 8427463b..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-magicmouse.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Apple "Magic" Wireless Mouse driver
- *
- * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
- * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "hid-ids.h"
-
-static bool emulate_3button = true;
-module_param(emulate_3button, bool, 0644);
-MODULE_PARM_DESC(emulate_3button, "Emulate a middle button");
-
-static int middle_button_start = -350;
-static int middle_button_stop = +350;
-
-static bool emulate_scroll_wheel = true;
-module_param(emulate_scroll_wheel, bool, 0644);
-MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
-
-static unsigned int scroll_speed = 32;
-static int param_set_scroll_speed(const char *val, struct kernel_param *kp) {
- unsigned long speed;
- if (!val || strict_strtoul(val, 0, &speed) || speed > 63)
- return -EINVAL;
- scroll_speed = speed;
- return 0;
-}
-module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644);
-MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)");
-
-static bool scroll_acceleration = false;
-module_param(scroll_acceleration, bool, 0644);
-MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
-
-static bool report_touches = true;
-module_param(report_touches, bool, 0644);
-MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)");
-
-static bool report_undeciphered;
-module_param(report_undeciphered, bool, 0644);
-MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
-
-#define TRACKPAD_REPORT_ID 0x28
-#define MOUSE_REPORT_ID 0x29
-#define DOUBLE_REPORT_ID 0xf7
-/* These definitions are not precise, but they're close enough. (Bits
- * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
- * to be some kind of bit mask -- 0x20 may be a near-field reading,
- * and 0x40 is actual contact, and 0x10 may be a start/stop or change
- * indication.)
- */
-#define TOUCH_STATE_MASK 0xf0
-#define TOUCH_STATE_NONE 0x00
-#define TOUCH_STATE_START 0x30
-#define TOUCH_STATE_DRAG 0x40
-
-#define SCROLL_ACCEL_DEFAULT 7
-
-/* Single touch emulation should only begin when no touches are currently down.
- * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
- * are down and the touch providing for single touch emulation is lifted,
- * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
- * occurring, single_touch_id corresponds with the tracking id of the touch used.
- */
-#define NO_TOUCHES -1
-#define SINGLE_TOUCH_UP -2
-
-/* Touch surface information. Dimension is in hundredths of a mm, min and max
- * are in units. */
-#define MOUSE_DIMENSION_X (float)9056
-#define MOUSE_MIN_X -1100
-#define MOUSE_MAX_X 1258
-#define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100))
-#define MOUSE_DIMENSION_Y (float)5152
-#define MOUSE_MIN_Y -1589
-#define MOUSE_MAX_Y 2047
-#define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100))
-
-#define TRACKPAD_DIMENSION_X (float)13000
-#define TRACKPAD_MIN_X -2909
-#define TRACKPAD_MAX_X 3167
-#define TRACKPAD_RES_X \
- ((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100))
-#define TRACKPAD_DIMENSION_Y (float)11000
-#define TRACKPAD_MIN_Y -2456
-#define TRACKPAD_MAX_Y 2565
-#define TRACKPAD_RES_Y \
- ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100))
-
-/**
- * struct magicmouse_sc - Tracks Magic Mouse-specific data.
- * @input: Input device through which we report events.
- * @quirks: Currently unused.
- * @ntouches: Number of touches in most recent touch report.
- * @scroll_accel: Number of consecutive scroll motions.
- * @scroll_jiffies: Time of last scroll motion.
- * @touches: Most recent data for a touch, indexed by tracking ID.
- * @tracking_ids: Mapping of current touch input data to @touches.
- */
-struct magicmouse_sc {
- struct input_dev *input;
- unsigned long quirks;
-
- int ntouches;
- int scroll_accel;
- unsigned long scroll_jiffies;
-
- struct {
- short x;
- short y;
- short scroll_x;
- short scroll_y;
- u8 size;
- } touches[16];
- int tracking_ids[16];
- int single_touch_id;
-};
-
-static int magicmouse_firm_touch(struct magicmouse_sc *msc)
-{
- int touch = -1;
- int ii;
-
- /* If there is only one "firm" touch, set touch to its
- * tracking ID.
- */
- for (ii = 0; ii < msc->ntouches; ii++) {
- int idx = msc->tracking_ids[ii];
- if (msc->touches[idx].size < 8) {
- /* Ignore this touch. */
- } else if (touch >= 0) {
- touch = -1;
- break;
- } else {
- touch = idx;
- }
- }
-
- return touch;
-}
-
-static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
-{
- int last_state = test_bit(BTN_LEFT, msc->input->key) << 0 |
- test_bit(BTN_RIGHT, msc->input->key) << 1 |
- test_bit(BTN_MIDDLE, msc->input->key) << 2;
-
- if (emulate_3button) {
- int id;
-
- /* If some button was pressed before, keep it held
- * down. Otherwise, if there's exactly one firm
- * touch, use that to override the mouse's guess.
- */
- if (state == 0) {
- /* The button was released. */
- } else if (last_state != 0) {
- state = last_state;
- } else if ((id = magicmouse_firm_touch(msc)) >= 0) {
- int x = msc->touches[id].x;
- if (x < middle_button_start)
- state = 1;
- else if (x > middle_button_stop)
- state = 2;
- else
- state = 4;
- } /* else: we keep the mouse's guess */
-
- input_report_key(msc->input, BTN_MIDDLE, state & 4);
- }
-
- input_report_key(msc->input, BTN_LEFT, state & 1);
- input_report_key(msc->input, BTN_RIGHT, state & 2);
-
- if (state != last_state)
- msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
-}
-
-static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
-{
- struct input_dev *input = msc->input;
- int id, x, y, size, orientation, touch_major, touch_minor, state, down;
-
- if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
- id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
- x = (tdata[1] << 28 | tdata[0] << 20) >> 20;
- y = -((tdata[2] << 24 | tdata[1] << 16) >> 20);
- size = tdata[5] & 0x3f;
- orientation = (tdata[6] >> 2) - 32;
- touch_major = tdata[3];
- touch_minor = tdata[4];
- state = tdata[7] & TOUCH_STATE_MASK;
- down = state != TOUCH_STATE_NONE;
- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
- id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf;
- x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
- y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
- size = tdata[6] & 0x3f;
- orientation = (tdata[7] >> 2) - 32;
- touch_major = tdata[4];
- touch_minor = tdata[5];
- state = tdata[8] & TOUCH_STATE_MASK;
- down = state != TOUCH_STATE_NONE;
- }
-
- /* Store tracking ID and other fields. */
- msc->tracking_ids[raw_id] = id;
- msc->touches[id].x = x;
- msc->touches[id].y = y;
- msc->touches[id].size = size;
-
- /* If requested, emulate a scroll wheel by detecting small
- * vertical touch motions.
- */
- if (emulate_scroll_wheel) {
- unsigned long now = jiffies;
- int step_x = msc->touches[id].scroll_x - x;
- int step_y = msc->touches[id].scroll_y - y;
-
- /* Calculate and apply the scroll motion. */
- switch (state) {
- case TOUCH_STATE_START:
- msc->touches[id].scroll_x = x;
- msc->touches[id].scroll_y = y;
-
- /* Reset acceleration after half a second. */
- if (scroll_acceleration && time_before(now,
- msc->scroll_jiffies + HZ / 2))
- msc->scroll_accel = max_t(int,
- msc->scroll_accel - 1, 1);
- else
- msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
-
- break;
- case TOUCH_STATE_DRAG:
- step_x /= (64 - (int)scroll_speed) * msc->scroll_accel;
- if (step_x != 0) {
- msc->touches[id].scroll_x -= step_x *
- (64 - scroll_speed) * msc->scroll_accel;
- msc->scroll_jiffies = now;
- input_report_rel(input, REL_HWHEEL, -step_x);
- }
-
- step_y /= (64 - (int)scroll_speed) * msc->scroll_accel;
- if (step_y != 0) {
- msc->touches[id].scroll_y -= step_y *
- (64 - scroll_speed) * msc->scroll_accel;
- msc->scroll_jiffies = now;
- input_report_rel(input, REL_WHEEL, step_y);
- }
- break;
- }
- }
-
- if (down) {
- msc->ntouches++;
- if (msc->single_touch_id == NO_TOUCHES)
- msc->single_touch_id = id;
- } else if (msc->single_touch_id == id)
- msc->single_touch_id = SINGLE_TOUCH_UP;
-
- /* Generate the input events for this touch. */
- if (report_touches && down) {
- input_report_abs(input, ABS_MT_TRACKING_ID, id);
- input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
- input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
- input_report_abs(input, ABS_MT_ORIENTATION, -orientation);
- input_report_abs(input, ABS_MT_POSITION_X, x);
- input_report_abs(input, ABS_MT_POSITION_Y, y);
-
- if (report_undeciphered) {
- if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
- input_event(input, EV_MSC, MSC_RAW, tdata[7]);
- else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
- input_event(input, EV_MSC, MSC_RAW, tdata[8]);
- }
-
- input_mt_sync(input);
- }
-}
-
-static int magicmouse_raw_event(struct hid_device *hdev,
- struct hid_report *report, u8 *data, int size)
-{
- struct magicmouse_sc *msc = hid_get_drvdata(hdev);
- struct input_dev *input = msc->input;
- int x = 0, y = 0, ii, clicks = 0, npoints;
-
- switch (data[0]) {
- case TRACKPAD_REPORT_ID:
- /* Expect four bytes of prefix, and N*9 bytes of touch data. */
- if (size < 4 || ((size - 4) % 9) != 0)
- return 0;
- npoints = (size - 4) / 9;
- msc->ntouches = 0;
- for (ii = 0; ii < npoints; ii++)
- magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
-
- /* We don't need an MT sync here because trackpad emits a
- * BTN_TOUCH event in a new frame when all touches are released.
- */
- if (msc->ntouches == 0)
- msc->single_touch_id = NO_TOUCHES;
-
- clicks = data[1];
-
- /* The following bits provide a device specific timestamp. They
- * are unused here.
- *
- * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
- */
- break;
- case MOUSE_REPORT_ID:
- /* Expect six bytes of prefix, and N*8 bytes of touch data. */
- if (size < 6 || ((size - 6) % 8) != 0)
- return 0;
- npoints = (size - 6) / 8;
- msc->ntouches = 0;
- for (ii = 0; ii < npoints; ii++)
- magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
-
- if (report_touches && msc->ntouches == 0)
- input_mt_sync(input);
-
- /* When emulating three-button mode, it is important
- * to have the current touch information before
- * generating a click event.
- */
- x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22;
- y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22;
- clicks = data[3];
-
- /* The following bits provide a device specific timestamp. They
- * are unused here.
- *
- * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
- */
- break;
- case DOUBLE_REPORT_ID:
- /* Sometimes the trackpad sends two touch reports in one
- * packet.
- */
- magicmouse_raw_event(hdev, report, data + 2, data[1]);
- magicmouse_raw_event(hdev, report, data + 2 + data[1],
- size - 2 - data[1]);
- break;
- default:
- return 0;
- }
-
- if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
- magicmouse_emit_buttons(msc, clicks & 3);
- input_report_rel(input, REL_X, x);
- input_report_rel(input, REL_Y, y);
- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
- input_report_key(input, BTN_MOUSE, clicks & 1);
- input_report_key(input, BTN_TOUCH, msc->ntouches > 0);
- input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
- input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
- input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
- input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
- if (msc->single_touch_id >= 0) {
- input_report_abs(input, ABS_X,
- msc->touches[msc->single_touch_id].x);
- input_report_abs(input, ABS_Y,
- msc->touches[msc->single_touch_id].y);
- }
- }
-
- input_sync(input);
- return 1;
-}
-
-static int magicmouse_setup_input(struct hid_device *hdev, struct hid_input *hi)
-{
- struct input_dev *input = hi->input;
-
- __set_bit(EV_KEY, input->evbit);
-
- if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
- __set_bit(BTN_LEFT, input->keybit);
- __set_bit(BTN_RIGHT, input->keybit);
- if (emulate_3button)
- __set_bit(BTN_MIDDLE, input->keybit);
-
- __set_bit(EV_REL, input->evbit);
- __set_bit(REL_X, input->relbit);
- __set_bit(REL_Y, input->relbit);
- if (emulate_scroll_wheel) {
- __set_bit(REL_WHEEL, input->relbit);
- __set_bit(REL_HWHEEL, input->relbit);
- }
- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
- /* input->keybit is initialized with incorrect button info
- * for Magic Trackpad. There really is only one physical
- * button (BTN_LEFT == BTN_MOUSE). Make sure we don't
- * advertise buttons that don't exist...
- */
- __clear_bit(BTN_RIGHT, input->keybit);
- __clear_bit(BTN_MIDDLE, input->keybit);
- __set_bit(BTN_MOUSE, input->keybit);
- __set_bit(BTN_TOOL_FINGER, input->keybit);
- __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
- __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
- __set_bit(BTN_TOOL_QUADTAP, input->keybit);
- __set_bit(BTN_TOUCH, input->keybit);
- __set_bit(INPUT_PROP_POINTER, input->propbit);
- __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
- }
-
- if (report_touches) {
- __set_bit(EV_ABS, input->evbit);
-
- input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0);
- input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
- input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
- input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
-
- /* Note: Touch Y position from the device is inverted relative
- * to how pointer motion is reported (and relative to how USB
- * HID recommends the coordinates work). This driver keeps
- * the origin at the same position, and just uses the additive
- * inverse of the reported Y.
- */
- if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
- input_set_abs_params(input, ABS_MT_POSITION_X,
- MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
- input_set_abs_params(input, ABS_MT_POSITION_Y,
- MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
-
- input_abs_set_res(input, ABS_MT_POSITION_X,
- MOUSE_RES_X);
- input_abs_set_res(input, ABS_MT_POSITION_Y,
- MOUSE_RES_Y);
- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
- input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
- TRACKPAD_MAX_X, 4, 0);
- input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
- TRACKPAD_MAX_Y, 4, 0);
- input_set_abs_params(input, ABS_MT_POSITION_X,
- TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
- input_set_abs_params(input, ABS_MT_POSITION_Y,
- TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
-
- input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
- input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
- input_abs_set_res(input, ABS_MT_POSITION_X,
- TRACKPAD_RES_X);
- input_abs_set_res(input, ABS_MT_POSITION_Y,
- TRACKPAD_RES_Y);
- }
-
- input_set_events_per_packet(input, 60);
- }
-
- if (report_undeciphered) {
- __set_bit(EV_MSC, input->evbit);
- __set_bit(MSC_RAW, input->mscbit);
- }
-
- return 0;
-}
-
-static int magicmouse_input_mapping(struct hid_device *hdev,
- struct hid_input *hi, struct hid_field *field,
- struct hid_usage *usage, unsigned long **bit, int *max)
-{
- struct magicmouse_sc *msc = hid_get_drvdata(hdev);
-
- if (!msc->input)
- msc->input = hi->input;
-
- /* Magic Trackpad does not give relative data after switching to MT */
- if (hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
- field->flags & HID_MAIN_ITEM_RELATIVE)
- return -1;
-
- return 0;
-}
-
-static int magicmouse_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- __u8 feature[] = { 0xd7, 0x01 };
- struct magicmouse_sc *msc;
- struct hid_report *report;
- int ret;
-
- msc = kzalloc(sizeof(*msc), GFP_KERNEL);
- if (msc == NULL) {
- hid_err(hdev, "can't alloc magicmouse descriptor\n");
- return -ENOMEM;
- }
-
- msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
-
- msc->quirks = id->driver_data;
- hid_set_drvdata(hdev, msc);
-
- msc->single_touch_id = NO_TOUCHES;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "magicmouse hid parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "magicmouse hw start failed\n");
- goto err_free;
- }
-
- if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
- report = hid_register_report(hdev, HID_INPUT_REPORT,
- MOUSE_REPORT_ID);
- else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
- report = hid_register_report(hdev, HID_INPUT_REPORT,
- TRACKPAD_REPORT_ID);
- report = hid_register_report(hdev, HID_INPUT_REPORT,
- DOUBLE_REPORT_ID);
- }
-
- if (!report) {
- hid_err(hdev, "unable to register touch report\n");
- ret = -ENOMEM;
- goto err_stop_hw;
- }
- report->size = 6;
-
- /*
- * Some devices repond with 'invalid report id' when feature
- * report switching it into multitouch mode is sent to it.
- *
- * This results in -EIO from the _raw low-level transport callback,
- * but there seems to be no other way of switching the mode.
- * Thus the super-ugly hacky success check below.
- */
- ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
- HID_FEATURE_REPORT);
- if (ret != -EIO && ret != sizeof(feature)) {
- hid_err(hdev, "unable to request touch data (%d)\n", ret);
- goto err_stop_hw;
- }
-
- return 0;
-err_stop_hw:
- hid_hw_stop(hdev);
-err_free:
- kfree(msc);
- return ret;
-}
-
-static void magicmouse_remove(struct hid_device *hdev)
-{
- struct magicmouse_sc *msc = hid_get_drvdata(hdev);
-
- hid_hw_stop(hdev);
- kfree(msc);
-}
-
-static const struct hid_device_id magic_mice[] = {
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
- USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
- USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
- { }
-};
-MODULE_DEVICE_TABLE(hid, magic_mice);
-
-static struct hid_driver magicmouse_driver = {
- .name = "magicmouse",
- .id_table = magic_mice,
- .probe = magicmouse_probe,
- .remove = magicmouse_remove,
- .raw_event = magicmouse_raw_event,
- .input_mapping = magicmouse_input_mapping,
- .input_register = magicmouse_setup_input,
-};
-
-static int __init magicmouse_init(void)
-{
- int ret;
-
- ret = hid_register_driver(&magicmouse_driver);
- if (ret)
- pr_err("can't register magicmouse driver\n");
-
- return ret;
-}
-
-static void __exit magicmouse_exit(void)
-{
- hid_unregister_driver(&magicmouse_driver);
-}
-
-module_init(magicmouse_init);
-module_exit(magicmouse_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-microsoft.c b/ANDROID_3.4.5/drivers/hid/hid-microsoft.c
deleted file mode 100644
index e5c699b6..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-microsoft.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * HID driver for some microsoft "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define MS_HIDINPUT 0x01
-#define MS_ERGONOMY 0x02
-#define MS_PRESENTER 0x04
-#define MS_RDESC 0x08
-#define MS_NOGET 0x10
-#define MS_DUPLICATE_USAGES 0x20
-
-/*
- * Microsoft Wireless Desktop Receiver (Model 1028) has
- * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
- */
-static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
- rdesc[559] == 0x29) {
- hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
- rdesc[557] = 0x35;
- rdesc[559] = 0x45;
- }
- return rdesc;
-}
-
-#define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- struct input_dev *input = hi->input;
-
- switch (usage->hid & HID_USAGE) {
- case 0xfd06: ms_map_key_clear(KEY_CHAT); break;
- case 0xfd07: ms_map_key_clear(KEY_PHONE); break;
- case 0xff05:
- set_bit(EV_REP, input->evbit);
- ms_map_key_clear(KEY_F13);
- set_bit(KEY_F14, input->keybit);
- set_bit(KEY_F15, input->keybit);
- set_bit(KEY_F16, input->keybit);
- set_bit(KEY_F17, input->keybit);
- set_bit(KEY_F18, input->keybit);
- default:
- return 0;
- }
- return 1;
-}
-
-static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- set_bit(EV_REP, hi->input->evbit);
- switch (usage->hid & HID_USAGE) {
- case 0xfd08: ms_map_key_clear(KEY_FORWARD); break;
- case 0xfd09: ms_map_key_clear(KEY_BACK); break;
- case 0xfd0b: ms_map_key_clear(KEY_PLAYPAUSE); break;
- case 0xfd0e: ms_map_key_clear(KEY_CLOSE); break;
- case 0xfd0f: ms_map_key_clear(KEY_PLAY); break;
- default:
- return 0;
- }
- return 1;
-}
-
-static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
- return 0;
-
- if (quirks & MS_ERGONOMY) {
- int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
- if (ret)
- return ret;
- }
-
- if ((quirks & MS_PRESENTER) &&
- ms_presenter_8k_quirk(hi, usage, bit, max))
- return 1;
-
- return 0;
-}
-
-static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if (quirks & MS_DUPLICATE_USAGES)
- clear_bit(usage->code, *bit);
-
- return 0;
-}
-
-static int ms_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
-
- if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
- !usage->type)
- return 0;
-
- /* Handling MS keyboards special buttons */
- if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
- struct input_dev *input = field->hidinput->input;
- static unsigned int last_key = 0;
- unsigned int key = 0;
- switch (value) {
- case 0x01: key = KEY_F14; break;
- case 0x02: key = KEY_F15; break;
- case 0x04: key = KEY_F16; break;
- case 0x08: key = KEY_F17; break;
- case 0x10: key = KEY_F18; break;
- }
- if (key) {
- input_event(input, usage->type, key, 1);
- last_key = key;
- } else
- input_event(input, usage->type, last_key, 0);
-
- return 1;
- }
-
- return 0;
-}
-
-static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- unsigned long quirks = id->driver_data;
- int ret;
-
- hid_set_drvdata(hdev, (void *)quirks);
-
- if (quirks & MS_NOGET)
- hdev->quirks |= HID_QUIRK_NOGET;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ?
- HID_CONNECT_HIDINPUT_FORCE : 0));
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- return 0;
-err_free:
- return ret;
-}
-
-static const struct hid_device_id ms_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
- .driver_data = MS_HIDINPUT },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
- .driver_data = MS_ERGONOMY },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K),
- .driver_data = MS_ERGONOMY | MS_RDESC },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB),
- .driver_data = MS_PRESENTER },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K),
- .driver_data = MS_ERGONOMY },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0),
- .driver_data = MS_NOGET },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
- .driver_data = MS_DUPLICATE_USAGES },
-
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
- .driver_data = MS_PRESENTER },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ms_devices);
-
-static struct hid_driver ms_driver = {
- .name = "microsoft",
- .id_table = ms_devices,
- .report_fixup = ms_report_fixup,
- .input_mapping = ms_input_mapping,
- .input_mapped = ms_input_mapped,
- .event = ms_event,
- .probe = ms_probe,
-};
-
-static int __init ms_init(void)
-{
- return hid_register_driver(&ms_driver);
-}
-
-static void __exit ms_exit(void)
-{
- hid_unregister_driver(&ms_driver);
-}
-
-module_init(ms_init);
-module_exit(ms_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-monterey.c b/ANDROID_3.4.5/drivers/hid/hid-monterey.c
deleted file mode 100644
index dedf7577..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-monterey.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * HID driver for some monterey "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) {
- hid_info(hdev, "fixing up button/consumer in HID report descriptor\n");
- rdesc[30] = 0x0c;
- }
- return rdesc;
-}
-
-#define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int mr_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x156: mr_map_key_clear(KEY_WORDPROCESSOR); break;
- case 0x157: mr_map_key_clear(KEY_SPREADSHEET); break;
- case 0x158: mr_map_key_clear(KEY_PRESENTATION); break;
- case 0x15c: mr_map_key_clear(KEY_STOP); break;
- default:
- return 0;
- }
- return 1;
-}
-
-static const struct hid_device_id mr_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, mr_devices);
-
-static struct hid_driver mr_driver = {
- .name = "monterey",
- .id_table = mr_devices,
- .report_fixup = mr_report_fixup,
- .input_mapping = mr_input_mapping,
-};
-
-static int __init mr_init(void)
-{
- return hid_register_driver(&mr_driver);
-}
-
-static void __exit mr_exit(void)
-{
- hid_unregister_driver(&mr_driver);
-}
-
-module_init(mr_init);
-module_exit(mr_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-multitouch.c b/ANDROID_3.4.5/drivers/hid/hid-multitouch.c
deleted file mode 100644
index 8cf4310a..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-multitouch.c
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * HID driver for multitouch panels
- *
- * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
- * Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
- * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France
- *
- * This code is partly based on hid-egalax.c:
- *
- * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
- * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
- * Copyright (c) 2010 Canonical, Ltd.
- *
- * This code is partly based on hid-3m-pct.c:
- *
- * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
- * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
- * Copyright (c) 2010 Canonical, Ltd.
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/input/mt.h>
-#include "usbhid/usbhid.h"
-
-
-MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
-MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
-MODULE_DESCRIPTION("HID multitouch panels");
-MODULE_LICENSE("GPL");
-
-#include "hid-ids.h"
-
-/* quirks to control the device */
-#define MT_QUIRK_NOT_SEEN_MEANS_UP (1 << 0)
-#define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1)
-#define MT_QUIRK_CYPRESS (1 << 2)
-#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3)
-#define MT_QUIRK_ALWAYS_VALID (1 << 4)
-#define MT_QUIRK_VALID_IS_INRANGE (1 << 5)
-#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6)
-#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
-
-struct mt_slot {
- __s32 x, y, p, w, h;
- __s32 contactid; /* the device ContactID assigned to this slot */
- bool touch_state; /* is the touch valid? */
- bool seen_in_this_frame;/* has this slot been updated */
-};
-
-struct mt_class {
- __s32 name; /* MT_CLS */
- __s32 quirks;
- __s32 sn_move; /* Signal/noise ratio for move events */
- __s32 sn_width; /* Signal/noise ratio for width events */
- __s32 sn_height; /* Signal/noise ratio for height events */
- __s32 sn_pressure; /* Signal/noise ratio for pressure events */
- __u8 maxcontacts;
- bool is_indirect; /* true for touchpads */
-};
-
-struct mt_fields {
- unsigned usages[HID_MAX_FIELDS];
- unsigned int length;
-};
-
-struct mt_device {
- struct mt_slot curdata; /* placeholder of incoming data */
- struct mt_class mtclass; /* our mt device class */
- struct mt_fields *fields; /* temporary placeholder for storing the
- multitouch fields */
- unsigned last_field_index; /* last field index of the report */
- unsigned last_slot_field; /* the last field of a slot */
- __s8 inputmode; /* InputMode HID feature, -1 if non-existent */
- __s8 maxcontact_report_id; /* Maximum Contact Number HID feature,
- -1 if non-existent */
- __u8 num_received; /* how many contacts we received */
- __u8 num_expected; /* expected last contact index */
- __u8 maxcontacts;
- __u8 touches_by_report; /* how many touches are present in one report:
- * 1 means we should use a serial protocol
- * > 1 means hybrid (multitouch) protocol */
- bool curvalid; /* is the current contact valid? */
- struct mt_slot *slots;
-};
-
-/* classes of device behavior */
-#define MT_CLS_DEFAULT 0x0001
-
-#define MT_CLS_SERIAL 0x0002
-#define MT_CLS_CONFIDENCE 0x0003
-#define MT_CLS_CONFIDENCE_CONTACT_ID 0x0004
-#define MT_CLS_CONFIDENCE_MINUS_ONE 0x0005
-#define MT_CLS_DUAL_INRANGE_CONTACTID 0x0006
-#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007
-#define MT_CLS_DUAL_NSMU_CONTACTID 0x0008
-#define MT_CLS_INRANGE_CONTACTNUMBER 0x0009
-
-/* vendor specific classes */
-#define MT_CLS_3M 0x0101
-#define MT_CLS_CYPRESS 0x0102
-#define MT_CLS_EGALAX 0x0103
-#define MT_CLS_EGALAX_SERIAL 0x0104
-#define MT_CLS_TOPSEED 0x0105
-#define MT_CLS_PANASONIC 0x0106
-
-#define MT_DEFAULT_MAXCONTACT 10
-
-/*
- * these device-dependent functions determine what slot corresponds
- * to a valid contact that was just read.
- */
-
-static int cypress_compute_slot(struct mt_device *td)
-{
- if (td->curdata.contactid != 0 || td->num_received == 0)
- return td->curdata.contactid;
- else
- return -1;
-}
-
-static int find_slot_from_contactid(struct mt_device *td)
-{
- int i;
- for (i = 0; i < td->maxcontacts; ++i) {
- if (td->slots[i].contactid == td->curdata.contactid &&
- td->slots[i].touch_state)
- return i;
- }
- for (i = 0; i < td->maxcontacts; ++i) {
- if (!td->slots[i].seen_in_this_frame &&
- !td->slots[i].touch_state)
- return i;
- }
- /* should not occurs. If this happens that means
- * that the device sent more touches that it says
- * in the report descriptor. It is ignored then. */
- return -1;
-}
-
-static struct mt_class mt_classes[] = {
- { .name = MT_CLS_DEFAULT,
- .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
- { .name = MT_CLS_SERIAL,
- .quirks = MT_QUIRK_ALWAYS_VALID},
- { .name = MT_CLS_CONFIDENCE,
- .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
- { .name = MT_CLS_CONFIDENCE_CONTACT_ID,
- .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
- MT_QUIRK_SLOT_IS_CONTACTID },
- { .name = MT_CLS_CONFIDENCE_MINUS_ONE,
- .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
- MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE },
- { .name = MT_CLS_DUAL_INRANGE_CONTACTID,
- .quirks = MT_QUIRK_VALID_IS_INRANGE |
- MT_QUIRK_SLOT_IS_CONTACTID,
- .maxcontacts = 2 },
- { .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
- .quirks = MT_QUIRK_VALID_IS_INRANGE |
- MT_QUIRK_SLOT_IS_CONTACTNUMBER,
- .maxcontacts = 2 },
- { .name = MT_CLS_DUAL_NSMU_CONTACTID,
- .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
- MT_QUIRK_SLOT_IS_CONTACTID,
- .maxcontacts = 2 },
- { .name = MT_CLS_INRANGE_CONTACTNUMBER,
- .quirks = MT_QUIRK_VALID_IS_INRANGE |
- MT_QUIRK_SLOT_IS_CONTACTNUMBER },
-
- /*
- * vendor specific classes
- */
- { .name = MT_CLS_3M,
- .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
- MT_QUIRK_SLOT_IS_CONTACTID,
- .sn_move = 2048,
- .sn_width = 128,
- .sn_height = 128 },
- { .name = MT_CLS_CYPRESS,
- .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
- MT_QUIRK_CYPRESS,
- .maxcontacts = 10 },
- { .name = MT_CLS_EGALAX,
- .quirks = MT_QUIRK_SLOT_IS_CONTACTID |
- MT_QUIRK_VALID_IS_INRANGE,
- .sn_move = 4096,
- .sn_pressure = 32,
- },
- { .name = MT_CLS_EGALAX_SERIAL,
- .quirks = MT_QUIRK_SLOT_IS_CONTACTID |
- MT_QUIRK_ALWAYS_VALID,
- .sn_move = 4096,
- .sn_pressure = 32,
- },
- { .name = MT_CLS_TOPSEED,
- .quirks = MT_QUIRK_ALWAYS_VALID,
- .is_indirect = true,
- .maxcontacts = 2,
- },
- { .name = MT_CLS_PANASONIC,
- .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
- .maxcontacts = 4 },
-
- { }
-};
-
-static ssize_t mt_show_quirks(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct mt_device *td = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%u\n", td->mtclass.quirks);
-}
-
-static ssize_t mt_set_quirks(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct mt_device *td = hid_get_drvdata(hdev);
-
- unsigned long val;
-
- if (kstrtoul(buf, 0, &val))
- return -EINVAL;
-
- td->mtclass.quirks = val;
-
- return count;
-}
-
-static DEVICE_ATTR(quirks, S_IWUSR | S_IRUGO, mt_show_quirks, mt_set_quirks);
-
-static struct attribute *sysfs_attrs[] = {
- &dev_attr_quirks.attr,
- NULL
-};
-
-static struct attribute_group mt_attribute_group = {
- .attrs = sysfs_attrs
-};
-
-static void mt_feature_mapping(struct hid_device *hdev,
- struct hid_field *field, struct hid_usage *usage)
-{
- struct mt_device *td = hid_get_drvdata(hdev);
-
- switch (usage->hid) {
- case HID_DG_INPUTMODE:
- td->inputmode = field->report->id;
- break;
- case HID_DG_CONTACTMAX:
- td->maxcontact_report_id = field->report->id;
- td->maxcontacts = field->value[0];
- if (td->mtclass.maxcontacts)
- /* check if the maxcontacts is given by the class */
- td->maxcontacts = td->mtclass.maxcontacts;
-
- break;
- }
-}
-
-static void set_abs(struct input_dev *input, unsigned int code,
- struct hid_field *field, int snratio)
-{
- int fmin = field->logical_minimum;
- int fmax = field->logical_maximum;
- int fuzz = snratio ? (fmax - fmin) / snratio : 0;
- input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
-}
-
-static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
- struct hid_input *hi)
-{
- struct mt_fields *f = td->fields;
-
- if (f->length >= HID_MAX_FIELDS)
- return;
-
- f->usages[f->length++] = usage->hid;
-}
-
-static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- struct mt_device *td = hid_get_drvdata(hdev);
- struct mt_class *cls = &td->mtclass;
- int code;
-
- /* Only map fields from TouchScreen or TouchPad collections.
- * We need to ignore fields that belong to other collections
- * such as Mouse that might have the same GenericDesktop usages. */
- if (field->application == HID_DG_TOUCHSCREEN)
- set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
- else if (field->application != HID_DG_TOUCHPAD)
- return 0;
-
- /* In case of an indirect device (touchpad), we need to add
- * specific BTN_TOOL_* to be handled by the synaptics xorg
- * driver.
- * We also consider that touchscreens providing buttons are touchpads.
- */
- if (field->application == HID_DG_TOUCHPAD ||
- (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON ||
- cls->is_indirect) {
- set_bit(INPUT_PROP_POINTER, hi->input->propbit);
- set_bit(BTN_TOOL_FINGER, hi->input->keybit);
- set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit);
- set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit);
- set_bit(BTN_TOOL_QUADTAP, hi->input->keybit);
- }
-
- /* eGalax devices provide a Digitizer.Stylus input which overrides
- * the correct Digitizers.Finger X/Y ranges.
- * Let's just ignore this input. */
- if (field->physical == HID_DG_STYLUS)
- return -1;
-
- /* Only map fields from TouchScreen or TouchPad collections.
- * We need to ignore fields that belong to other collections
- * such as Mouse that might have the same GenericDesktop usages. */
- if (field->application == HID_DG_TOUCHSCREEN)
- set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
- else if (field->application == HID_DG_TOUCHPAD)
- set_bit(INPUT_PROP_POINTER, hi->input->propbit);
- else
- return 0;
-
- switch (usage->hid & HID_USAGE_PAGE) {
-
- case HID_UP_GENDESK:
- switch (usage->hid) {
- case HID_GD_X:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_POSITION_X);
- set_abs(hi->input, ABS_MT_POSITION_X, field,
- cls->sn_move);
- /* touchscreen emulation */
- set_abs(hi->input, ABS_X, field, cls->sn_move);
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- return 1;
- case HID_GD_Y:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_POSITION_Y);
- set_abs(hi->input, ABS_MT_POSITION_Y, field,
- cls->sn_move);
- /* touchscreen emulation */
- set_abs(hi->input, ABS_Y, field, cls->sn_move);
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- return 1;
- }
- return 0;
-
- case HID_UP_DIGITIZER:
- switch (usage->hid) {
- case HID_DG_INRANGE:
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- return 1;
- case HID_DG_CONFIDENCE:
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- return 1;
- case HID_DG_TIPSWITCH:
- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
- input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- return 1;
- case HID_DG_CONTACTID:
- if (!td->maxcontacts)
- td->maxcontacts = MT_DEFAULT_MAXCONTACT;
- input_mt_init_slots(hi->input, td->maxcontacts);
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- td->touches_by_report++;
- return 1;
- case HID_DG_WIDTH:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TOUCH_MAJOR);
- set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
- cls->sn_width);
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- return 1;
- case HID_DG_HEIGHT:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TOUCH_MINOR);
- set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
- cls->sn_height);
- input_set_abs_params(hi->input,
- ABS_MT_ORIENTATION, 0, 1, 0, 0);
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- return 1;
- case HID_DG_TIPPRESSURE:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_PRESSURE);
- set_abs(hi->input, ABS_MT_PRESSURE, field,
- cls->sn_pressure);
- /* touchscreen emulation */
- set_abs(hi->input, ABS_PRESSURE, field,
- cls->sn_pressure);
- mt_store_field(usage, td, hi);
- td->last_field_index = field->index;
- return 1;
- case HID_DG_CONTACTCOUNT:
- td->last_field_index = field->index;
- return 1;
- case HID_DG_CONTACTMAX:
- /* we don't set td->last_slot_field as contactcount and
- * contact max are global to the report */
- td->last_field_index = field->index;
- return -1;
- }
- case HID_DG_TOUCH:
- /* Legacy devices use TIPSWITCH and not TOUCH.
- * Let's just ignore this field. */
- return -1;
- /* let hid-input decide for the others */
- return 0;
-
- case HID_UP_BUTTON:
- code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
- hid_map_usage(hi, usage, bit, max, EV_KEY, code);
- input_set_capability(hi->input, EV_KEY, code);
- return 1;
-
- case 0xff000000:
- /* we do not want to map these: no input-oriented meaning */
- return -1;
- }
-
- return 0;
-}
-
-static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if (usage->type == EV_KEY || usage->type == EV_ABS)
- set_bit(usage->type, hi->input->evbit);
-
- return -1;
-}
-
-static int mt_compute_slot(struct mt_device *td)
-{
- __s32 quirks = td->mtclass.quirks;
-
- if (quirks & MT_QUIRK_SLOT_IS_CONTACTID)
- return td->curdata.contactid;
-
- if (quirks & MT_QUIRK_CYPRESS)
- return cypress_compute_slot(td);
-
- if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
- return td->num_received;
-
- if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
- return td->curdata.contactid - 1;
-
- return find_slot_from_contactid(td);
-}
-
-/*
- * this function is called when a whole contact has been processed,
- * so that it can assign it to a slot and store the data there
- */
-static void mt_complete_slot(struct mt_device *td)
-{
- td->curdata.seen_in_this_frame = true;
- if (td->curvalid) {
- int slotnum = mt_compute_slot(td);
-
- if (slotnum >= 0 && slotnum < td->maxcontacts)
- td->slots[slotnum] = td->curdata;
- }
- td->num_received++;
-}
-
-
-/*
- * this function is called when a whole packet has been received and processed,
- * so that it can decide what to send to the input layer.
- */
-static void mt_emit_event(struct mt_device *td, struct input_dev *input)
-{
- int i;
-
- for (i = 0; i < td->maxcontacts; ++i) {
- struct mt_slot *s = &(td->slots[i]);
- if ((td->mtclass.quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
- !s->seen_in_this_frame) {
- s->touch_state = false;
- }
-
- input_mt_slot(input, i);
- input_mt_report_slot_state(input, MT_TOOL_FINGER,
- s->touch_state);
- if (s->touch_state) {
- /* this finger is on the screen */
- int wide = (s->w > s->h);
- /* divided by two to match visual scale of touch */
- int major = max(s->w, s->h) >> 1;
- int minor = min(s->w, s->h) >> 1;
-
- input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
- input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
- input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
- input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
- input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
- }
- s->seen_in_this_frame = false;
-
- }
-
- input_mt_report_pointer_emulation(input, true);
- input_sync(input);
- td->num_received = 0;
-}
-
-
-
-static int mt_event(struct hid_device *hid, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- struct mt_device *td = hid_get_drvdata(hid);
- __s32 quirks = td->mtclass.quirks;
-
- if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
- switch (usage->hid) {
- case HID_DG_INRANGE:
- if (quirks & MT_QUIRK_ALWAYS_VALID)
- td->curvalid = true;
- else if (quirks & MT_QUIRK_VALID_IS_INRANGE)
- td->curvalid = value;
- break;
- case HID_DG_TIPSWITCH:
- if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
- td->curvalid = value;
- td->curdata.touch_state = value;
- break;
- case HID_DG_CONFIDENCE:
- if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
- td->curvalid = value;
- break;
- case HID_DG_CONTACTID:
- td->curdata.contactid = value;
- break;
- case HID_DG_TIPPRESSURE:
- td->curdata.p = value;
- break;
- case HID_GD_X:
- td->curdata.x = value;
- break;
- case HID_GD_Y:
- td->curdata.y = value;
- break;
- case HID_DG_WIDTH:
- td->curdata.w = value;
- break;
- case HID_DG_HEIGHT:
- td->curdata.h = value;
- break;
- case HID_DG_CONTACTCOUNT:
- /*
- * Includes multi-packet support where subsequent
- * packets are sent with zero contactcount.
- */
- if (value)
- td->num_expected = value;
- break;
- case HID_DG_TOUCH:
- /* do nothing */
- break;
-
- default:
- /* fallback to the generic hidinput handling */
- return 0;
- }
-
- if (usage->hid == td->last_slot_field)
- mt_complete_slot(td);
-
- if (field->index == td->last_field_index
- && td->num_received >= td->num_expected)
- mt_emit_event(td, field->hidinput->input);
-
- }
-
- /* we have handled the hidinput part, now remains hiddev */
- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
- hid->hiddev_hid_event(hid, field, usage, value);
-
- return 1;
-}
-
-static void mt_set_input_mode(struct hid_device *hdev)
-{
- struct mt_device *td = hid_get_drvdata(hdev);
- struct hid_report *r;
- struct hid_report_enum *re;
-
- if (td->inputmode < 0)
- return;
-
- re = &(hdev->report_enum[HID_FEATURE_REPORT]);
- r = re->report_id_hash[td->inputmode];
- if (r) {
- r->field[0]->value[0] = 0x02;
- usbhid_submit_report(hdev, r, USB_DIR_OUT);
- }
-}
-
-static void mt_set_maxcontacts(struct hid_device *hdev)
-{
- struct mt_device *td = hid_get_drvdata(hdev);
- struct hid_report *r;
- struct hid_report_enum *re;
- int fieldmax, max;
-
- if (td->maxcontact_report_id < 0)
- return;
-
- if (!td->mtclass.maxcontacts)
- return;
-
- re = &hdev->report_enum[HID_FEATURE_REPORT];
- r = re->report_id_hash[td->maxcontact_report_id];
- if (r) {
- max = td->mtclass.maxcontacts;
- fieldmax = r->field[0]->logical_maximum;
- max = min(fieldmax, max);
- if (r->field[0]->value[0] != max) {
- r->field[0]->value[0] = max;
- usbhid_submit_report(hdev, r, USB_DIR_OUT);
- }
- }
-}
-
-static void mt_post_parse(struct mt_device *td)
-{
- struct mt_fields *f = td->fields;
-
- if (td->touches_by_report > 0) {
- int field_count_per_touch = f->length / td->touches_by_report;
- td->last_slot_field = f->usages[field_count_per_touch - 1];
- }
-}
-
-static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret, i;
- struct mt_device *td;
- struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
-
- if (id) {
- for (i = 0; mt_classes[i].name ; i++) {
- if (id->driver_data == mt_classes[i].name) {
- mtclass = &(mt_classes[i]);
- break;
- }
- }
- }
-
- /* This allows the driver to correctly support devices
- * that emit events over several HID messages.
- */
- hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
- hdev->quirks &= ~HID_QUIRK_MULTITOUCH;
-
- td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
- if (!td) {
- dev_err(&hdev->dev, "cannot allocate multitouch data\n");
- return -ENOMEM;
- }
- td->mtclass = *mtclass;
- td->inputmode = -1;
- td->maxcontact_report_id = -1;
- hid_set_drvdata(hdev, td);
-
- td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL);
- if (!td->fields) {
- dev_err(&hdev->dev, "cannot allocate multitouch fields data\n");
- ret = -ENOMEM;
- goto fail;
- }
-
- ret = hid_parse(hdev);
- if (ret != 0)
- goto fail;
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret)
- goto fail;
-
- mt_post_parse(td);
-
- if (!id && td->touches_by_report == 1) {
- /* the device has been sent by hid-generic */
- mtclass = &td->mtclass;
- mtclass->quirks |= MT_QUIRK_ALWAYS_VALID;
- mtclass->quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
- mtclass->quirks &= ~MT_QUIRK_VALID_IS_INRANGE;
- mtclass->quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE;
- }
-
- td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
- GFP_KERNEL);
- if (!td->slots) {
- dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
- hid_hw_stop(hdev);
- ret = -ENOMEM;
- goto fail;
- }
-
- ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
-
- mt_set_maxcontacts(hdev);
- mt_set_input_mode(hdev);
-
- kfree(td->fields);
- td->fields = NULL;
-
- return 0;
-
-fail:
- kfree(td->fields);
- kfree(td);
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int mt_reset_resume(struct hid_device *hdev)
-{
- mt_set_maxcontacts(hdev);
- mt_set_input_mode(hdev);
- return 0;
-}
-#endif
-
-static void mt_remove(struct hid_device *hdev)
-{
- struct mt_device *td = hid_get_drvdata(hdev);
- sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
- hid_hw_stop(hdev);
- kfree(td->slots);
- kfree(td);
- hid_set_drvdata(hdev, NULL);
-}
-
-static const struct hid_device_id mt_devices[] = {
-
- /* 3M panels */
- { .driver_data = MT_CLS_3M,
- HID_USB_DEVICE(USB_VENDOR_ID_3M,
- USB_DEVICE_ID_3M1968) },
- { .driver_data = MT_CLS_3M,
- HID_USB_DEVICE(USB_VENDOR_ID_3M,
- USB_DEVICE_ID_3M2256) },
- { .driver_data = MT_CLS_3M,
- HID_USB_DEVICE(USB_VENDOR_ID_3M,
- USB_DEVICE_ID_3M3266) },
-
- /* ActionStar panels */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR,
- USB_DEVICE_ID_ACTIONSTAR_1011) },
-
- /* Atmel panels */
- { .driver_data = MT_CLS_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_ATMEL,
- USB_DEVICE_ID_ATMEL_MULTITOUCH) },
- { .driver_data = MT_CLS_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_ATMEL,
- USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) },
-
- /* Cando panels */
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
- USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
- USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
- USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
- USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
-
- /* Chunghwa Telecom touch panels */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
- USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
-
- /* CVTouch panels */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,
- USB_DEVICE_ID_CVTOUCH_SCREEN) },
-
- /* Cypress panel */
- { .driver_data = MT_CLS_CYPRESS,
- HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
- USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
-
- /* eGalax devices (resistive) */
- { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
- { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
-
- /* eGalax devices (capacitive) */
- { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
- { .driver_data = MT_CLS_EGALAX_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) },
- { .driver_data = MT_CLS_EGALAX_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) },
- { .driver_data = MT_CLS_EGALAX_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) },
- { .driver_data = MT_CLS_EGALAX_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) },
- { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
- { .driver_data = MT_CLS_EGALAX_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) },
- { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
- { .driver_data = MT_CLS_EGALAX_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) },
- { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) },
- { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
- { .driver_data = MT_CLS_EGALAX_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349) },
- { .driver_data = MT_CLS_EGALAX_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
-
- /* Elo TouchSystems IntelliTouch Plus panel */
- { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID,
- HID_USB_DEVICE(USB_VENDOR_ID_ELO,
- USB_DEVICE_ID_ELO_TS2515) },
-
- /* GeneralTouch panel */
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
- USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
-
- /* Gametel game controller */
- { .driver_data = MT_CLS_DEFAULT,
- HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_FRUCTEL,
- USB_DEVICE_ID_GAMETEL_MT_MODE) },
-
- /* GoodTouch panels */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
- USB_DEVICE_ID_GOODTOUCH_000f) },
-
- /* Hanvon panels */
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
- HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
- USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
-
- /* Ideacom panel */
- { .driver_data = MT_CLS_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM,
- USB_DEVICE_ID_IDEACOM_IDC6650) },
- { .driver_data = MT_CLS_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM,
- USB_DEVICE_ID_IDEACOM_IDC6651) },
-
- /* Ilitek dual touch panel */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_ILITEK,
- USB_DEVICE_ID_ILITEK_MULTITOUCH) },
-
- /* IRTOUCH panels */
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
- HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
- USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
-
- /* LG Display panels */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_LG,
- USB_DEVICE_ID_LG_MULTITOUCH) },
-
- /* Lumio panels */
- { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
- HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
- USB_DEVICE_ID_CRYSTALTOUCH) },
- { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
- HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
- USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
-
- /* MosArt panels */
- { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
- HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
- USB_DEVICE_ID_ASUS_T91MT)},
- { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
- HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
- USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
- { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
- HID_USB_DEVICE(USB_VENDOR_ID_TURBOX,
- USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
-
- /* Panasonic panels */
- { .driver_data = MT_CLS_PANASONIC,
- HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
- USB_DEVICE_ID_PANABOARD_UBT780) },
- { .driver_data = MT_CLS_PANASONIC,
- HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
- USB_DEVICE_ID_PANABOARD_UBT880) },
-
- /* PenMount panels */
- { .driver_data = MT_CLS_CONFIDENCE,
- HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
- USB_DEVICE_ID_PENMOUNT_PCI) },
-
- /* PixArt optical touch screen */
- { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_PIXART,
- USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) },
- { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_PIXART,
- USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) },
- { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_PIXART,
- USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) },
-
- /* PixCir-based panels */
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
- HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
- USB_DEVICE_ID_HANVON_MULTITOUCH) },
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
- HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
- USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
-
- /* Quanta-based panels */
- { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
- HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
- USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
- { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
- HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
- USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) },
- { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
- HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
- USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) },
-
- /* Stantum panels */
- { .driver_data = MT_CLS_CONFIDENCE,
- HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
- USB_DEVICE_ID_MTP)},
- { .driver_data = MT_CLS_CONFIDENCE,
- HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
- USB_DEVICE_ID_MTP_STM)},
- { .driver_data = MT_CLS_CONFIDENCE,
- HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX,
- USB_DEVICE_ID_MTP_SITRONIX)},
-
- /* TopSeed panels */
- { .driver_data = MT_CLS_TOPSEED,
- HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2,
- USB_DEVICE_ID_TOPSEED2_PERIPAD_701) },
-
- /* Touch International panels */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL,
- USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) },
-
- /* Unitec panels */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
- USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
- USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
- /* XAT */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XAT,
- USB_DEVICE_ID_XAT_CSR) },
-
- /* Xiroku */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_SPX) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_MPX) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_CSR) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_SPX1) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_MPX1) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_CSR1) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_SPX2) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_MPX2) },
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
- USB_DEVICE_ID_XIROKU_CSR2) },
-
- { }
-};
-MODULE_DEVICE_TABLE(hid, mt_devices);
-
-static const struct hid_usage_id mt_grabbed_usages[] = {
- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
-};
-
-static struct hid_driver mt_driver = {
- .name = "hid-multitouch",
- .id_table = mt_devices,
- .probe = mt_probe,
- .remove = mt_remove,
- .input_mapping = mt_input_mapping,
- .input_mapped = mt_input_mapped,
- .feature_mapping = mt_feature_mapping,
- .usage_table = mt_grabbed_usages,
- .event = mt_event,
-#ifdef CONFIG_PM
- .reset_resume = mt_reset_resume,
-#endif
-};
-
-static int __init mt_init(void)
-{
- return hid_register_driver(&mt_driver);
-}
-
-static void __exit mt_exit(void)
-{
- hid_unregister_driver(&mt_driver);
-}
-
-module_init(mt_init);
-module_exit(mt_exit);
diff --git a/ANDROID_3.4.5/drivers/hid/hid-ntrig.c b/ANDROID_3.4.5/drivers/hid/hid-ntrig.c
deleted file mode 100644
index 9fae2ebd..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-ntrig.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- * HID driver for N-Trig touchscreens
- *
- * Copyright (c) 2008-2010 Rafi Rubin
- * Copyright (c) 2009-2010 Stephane Chatty
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/usb.h>
-#include "usbhid/usbhid.h"
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "hid-ids.h"
-
-#define NTRIG_DUPLICATE_USAGES 0x001
-
-static unsigned int min_width;
-module_param(min_width, uint, 0644);
-MODULE_PARM_DESC(min_width, "Minimum touch contact width to accept.");
-
-static unsigned int min_height;
-module_param(min_height, uint, 0644);
-MODULE_PARM_DESC(min_height, "Minimum touch contact height to accept.");
-
-static unsigned int activate_slack = 1;
-module_param(activate_slack, uint, 0644);
-MODULE_PARM_DESC(activate_slack, "Number of touch frames to ignore at "
- "the start of touch input.");
-
-static unsigned int deactivate_slack = 4;
-module_param(deactivate_slack, uint, 0644);
-MODULE_PARM_DESC(deactivate_slack, "Number of empty frames to ignore before "
- "deactivating touch.");
-
-static unsigned int activation_width = 64;
-module_param(activation_width, uint, 0644);
-MODULE_PARM_DESC(activation_width, "Width threshold to immediately start "
- "processing touch events.");
-
-static unsigned int activation_height = 32;
-module_param(activation_height, uint, 0644);
-MODULE_PARM_DESC(activation_height, "Height threshold to immediately start "
- "processing touch events.");
-
-struct ntrig_data {
- /* Incoming raw values for a single contact */
- __u16 x, y, w, h;
- __u16 id;
-
- bool tipswitch;
- bool confidence;
- bool first_contact_touch;
-
- bool reading_mt;
-
- __u8 mt_footer[4];
- __u8 mt_foot_count;
-
- /* The current activation state. */
- __s8 act_state;
-
- /* Empty frames to ignore before recognizing the end of activity */
- __s8 deactivate_slack;
-
- /* Frames to ignore before acknowledging the start of activity */
- __s8 activate_slack;
-
- /* Minimum size contact to accept */
- __u16 min_width;
- __u16 min_height;
-
- /* Threshold to override activation slack */
- __u16 activation_width;
- __u16 activation_height;
-
- __u16 sensor_logical_width;
- __u16 sensor_logical_height;
- __u16 sensor_physical_width;
- __u16 sensor_physical_height;
-};
-
-
-/*
- * This function converts the 4 byte raw firmware code into
- * a string containing 5 comma separated numbers.
- */
-static int ntrig_version_string(unsigned char *raw, char *buf)
-{
- __u8 a = (raw[1] & 0x0e) >> 1;
- __u8 b = (raw[0] & 0x3c) >> 2;
- __u8 c = ((raw[0] & 0x03) << 3) | ((raw[3] & 0xe0) >> 5);
- __u8 d = ((raw[3] & 0x07) << 3) | ((raw[2] & 0xe0) >> 5);
- __u8 e = raw[2] & 0x07;
-
- /*
- * As yet unmapped bits:
- * 0b11000000 0b11110001 0b00011000 0b00011000
- */
-
- return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e);
-}
-
-static inline int ntrig_get_mode(struct hid_device *hdev)
-{
- struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT].
- report_id_hash[0x0d];
-
- if (!report)
- return -EINVAL;
-
- usbhid_submit_report(hdev, report, USB_DIR_IN);
- usbhid_wait_io(hdev);
- return (int)report->field[0]->value[0];
-}
-
-static inline void ntrig_set_mode(struct hid_device *hdev, const int mode)
-{
- struct hid_report *report;
- __u8 mode_commands[4] = { 0xe, 0xf, 0x1b, 0x10 };
-
- if (mode < 0 || mode > 3)
- return;
-
- report = hdev->report_enum[HID_FEATURE_REPORT].
- report_id_hash[mode_commands[mode]];
-
- if (!report)
- return;
-
- usbhid_submit_report(hdev, report, USB_DIR_IN);
-}
-
-static void ntrig_report_version(struct hid_device *hdev)
-{
- int ret;
- char buf[20];
- struct usb_device *usb_dev = hid_to_usb_dev(hdev);
- unsigned char *data = kmalloc(8, GFP_KERNEL);
-
- if (!data)
- goto err_free;
-
- ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
- USB_REQ_CLEAR_FEATURE,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE |
- USB_DIR_IN,
- 0x30c, 1, data, 8,
- USB_CTRL_SET_TIMEOUT);
-
- if (ret == 8) {
- ret = ntrig_version_string(&data[2], buf);
-
- hid_info(hdev, "Firmware version: %s (%02x%02x %02x%02x)\n",
- buf, data[2], data[3], data[4], data[5]);
- }
-
-err_free:
- kfree(data);
-}
-
-static ssize_t show_phys_width(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->sensor_physical_width);
-}
-
-static DEVICE_ATTR(sensor_physical_width, S_IRUGO, show_phys_width, NULL);
-
-static ssize_t show_phys_height(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->sensor_physical_height);
-}
-
-static DEVICE_ATTR(sensor_physical_height, S_IRUGO, show_phys_height, NULL);
-
-static ssize_t show_log_width(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->sensor_logical_width);
-}
-
-static DEVICE_ATTR(sensor_logical_width, S_IRUGO, show_log_width, NULL);
-
-static ssize_t show_log_height(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->sensor_logical_height);
-}
-
-static DEVICE_ATTR(sensor_logical_height, S_IRUGO, show_log_height, NULL);
-
-static ssize_t show_min_width(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->min_width *
- nd->sensor_physical_width /
- nd->sensor_logical_width);
-}
-
-static ssize_t set_min_width(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- unsigned long val;
-
- if (strict_strtoul(buf, 0, &val))
- return -EINVAL;
-
- if (val > nd->sensor_physical_width)
- return -EINVAL;
-
- nd->min_width = val * nd->sensor_logical_width /
- nd->sensor_physical_width;
-
- return count;
-}
-
-static DEVICE_ATTR(min_width, S_IWUSR | S_IRUGO, show_min_width, set_min_width);
-
-static ssize_t show_min_height(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->min_height *
- nd->sensor_physical_height /
- nd->sensor_logical_height);
-}
-
-static ssize_t set_min_height(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- unsigned long val;
-
- if (strict_strtoul(buf, 0, &val))
- return -EINVAL;
-
- if (val > nd->sensor_physical_height)
- return -EINVAL;
-
- nd->min_height = val * nd->sensor_logical_height /
- nd->sensor_physical_height;
-
- return count;
-}
-
-static DEVICE_ATTR(min_height, S_IWUSR | S_IRUGO, show_min_height,
- set_min_height);
-
-static ssize_t show_activate_slack(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->activate_slack);
-}
-
-static ssize_t set_activate_slack(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- unsigned long val;
-
- if (strict_strtoul(buf, 0, &val))
- return -EINVAL;
-
- if (val > 0x7f)
- return -EINVAL;
-
- nd->activate_slack = val;
-
- return count;
-}
-
-static DEVICE_ATTR(activate_slack, S_IWUSR | S_IRUGO, show_activate_slack,
- set_activate_slack);
-
-static ssize_t show_activation_width(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->activation_width *
- nd->sensor_physical_width /
- nd->sensor_logical_width);
-}
-
-static ssize_t set_activation_width(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- unsigned long val;
-
- if (strict_strtoul(buf, 0, &val))
- return -EINVAL;
-
- if (val > nd->sensor_physical_width)
- return -EINVAL;
-
- nd->activation_width = val * nd->sensor_logical_width /
- nd->sensor_physical_width;
-
- return count;
-}
-
-static DEVICE_ATTR(activation_width, S_IWUSR | S_IRUGO, show_activation_width,
- set_activation_width);
-
-static ssize_t show_activation_height(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", nd->activation_height *
- nd->sensor_physical_height /
- nd->sensor_logical_height);
-}
-
-static ssize_t set_activation_height(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- unsigned long val;
-
- if (strict_strtoul(buf, 0, &val))
- return -EINVAL;
-
- if (val > nd->sensor_physical_height)
- return -EINVAL;
-
- nd->activation_height = val * nd->sensor_logical_height /
- nd->sensor_physical_height;
-
- return count;
-}
-
-static DEVICE_ATTR(activation_height, S_IWUSR | S_IRUGO,
- show_activation_height, set_activation_height);
-
-static ssize_t show_deactivate_slack(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- return sprintf(buf, "%d\n", -nd->deactivate_slack);
-}
-
-static ssize_t set_deactivate_slack(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- unsigned long val;
-
- if (strict_strtoul(buf, 0, &val))
- return -EINVAL;
-
- /*
- * No more than 8 terminal frames have been observed so far
- * and higher slack is highly likely to leave the single
- * touch emulation stuck down.
- */
- if (val > 7)
- return -EINVAL;
-
- nd->deactivate_slack = -val;
-
- return count;
-}
-
-static DEVICE_ATTR(deactivate_slack, S_IWUSR | S_IRUGO, show_deactivate_slack,
- set_deactivate_slack);
-
-static struct attribute *sysfs_attrs[] = {
- &dev_attr_sensor_physical_width.attr,
- &dev_attr_sensor_physical_height.attr,
- &dev_attr_sensor_logical_width.attr,
- &dev_attr_sensor_logical_height.attr,
- &dev_attr_min_height.attr,
- &dev_attr_min_width.attr,
- &dev_attr_activate_slack.attr,
- &dev_attr_activation_width.attr,
- &dev_attr_activation_height.attr,
- &dev_attr_deactivate_slack.attr,
- NULL
-};
-
-static struct attribute_group ntrig_attribute_group = {
- .attrs = sysfs_attrs
-};
-
-/*
- * this driver is aimed at two firmware versions in circulation:
- * - dual pen/finger single touch
- * - finger multitouch, pen not working
- */
-
-static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- struct ntrig_data *nd = hid_get_drvdata(hdev);
-
- /* No special mappings needed for the pen and single touch */
- if (field->physical)
- return 0;
-
- switch (usage->hid & HID_USAGE_PAGE) {
- case HID_UP_GENDESK:
- switch (usage->hid) {
- case HID_GD_X:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_POSITION_X);
- input_set_abs_params(hi->input, ABS_X,
- field->logical_minimum,
- field->logical_maximum, 0, 0);
-
- if (!nd->sensor_logical_width) {
- nd->sensor_logical_width =
- field->logical_maximum -
- field->logical_minimum;
- nd->sensor_physical_width =
- field->physical_maximum -
- field->physical_minimum;
- nd->activation_width = activation_width *
- nd->sensor_logical_width /
- nd->sensor_physical_width;
- nd->min_width = min_width *
- nd->sensor_logical_width /
- nd->sensor_physical_width;
- }
- return 1;
- case HID_GD_Y:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_POSITION_Y);
- input_set_abs_params(hi->input, ABS_Y,
- field->logical_minimum,
- field->logical_maximum, 0, 0);
-
- if (!nd->sensor_logical_height) {
- nd->sensor_logical_height =
- field->logical_maximum -
- field->logical_minimum;
- nd->sensor_physical_height =
- field->physical_maximum -
- field->physical_minimum;
- nd->activation_height = activation_height *
- nd->sensor_logical_height /
- nd->sensor_physical_height;
- nd->min_height = min_height *
- nd->sensor_logical_height /
- nd->sensor_physical_height;
- }
- return 1;
- }
- return 0;
-
- case HID_UP_DIGITIZER:
- switch (usage->hid) {
- /* we do not want to map these for now */
- case HID_DG_CONTACTID: /* Not trustworthy, squelch for now */
- case HID_DG_INPUTMODE:
- case HID_DG_DEVICEINDEX:
- case HID_DG_CONTACTMAX:
- return -1;
-
- /* width/height mapped on TouchMajor/TouchMinor/Orientation */
- case HID_DG_WIDTH:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TOUCH_MAJOR);
- return 1;
- case HID_DG_HEIGHT:
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TOUCH_MINOR);
- input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
- 0, 1, 0, 0);
- return 1;
- }
- return 0;
-
- case 0xff000000:
- /* we do not want to map these: no input-oriented meaning */
- return -1;
- }
-
- return 0;
-}
-
-static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- /* No special mappings needed for the pen and single touch */
- if (field->physical)
- return 0;
-
- if (usage->type == EV_KEY || usage->type == EV_REL
- || usage->type == EV_ABS)
- clear_bit(usage->code, *bit);
-
- return 0;
-}
-
-/*
- * this function is called upon all reports
- * so that we can filter contact point information,
- * decide whether we are in multi or single touch mode
- * and call input_mt_sync after each point if necessary
- */
-static int ntrig_event (struct hid_device *hid, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- struct ntrig_data *nd = hid_get_drvdata(hid);
- struct input_dev *input;
-
- /* Skip processing if not a claimed input */
- if (!(hid->claimed & HID_CLAIMED_INPUT))
- goto not_claimed_input;
-
- /* This function is being called before the structures are fully
- * initialized */
- if(!(field->hidinput && field->hidinput->input))
- return -EINVAL;
-
- input = field->hidinput->input;
-
- /* No special handling needed for the pen */
- if (field->application == HID_DG_PEN)
- return 0;
-
- switch (usage->hid) {
- case 0xff000001:
- /* Tag indicating the start of a multitouch group */
- nd->reading_mt = 1;
- nd->first_contact_touch = 0;
- break;
- case HID_DG_TIPSWITCH:
- nd->tipswitch = value;
- /* Prevent emission of touch until validated */
- return 1;
- case HID_DG_CONFIDENCE:
- nd->confidence = value;
- break;
- case HID_GD_X:
- nd->x = value;
- /* Clear the contact footer */
- nd->mt_foot_count = 0;
- break;
- case HID_GD_Y:
- nd->y = value;
- break;
- case HID_DG_CONTACTID:
- nd->id = value;
- break;
- case HID_DG_WIDTH:
- nd->w = value;
- break;
- case HID_DG_HEIGHT:
- nd->h = value;
- /*
- * when in single touch mode, this is the last
- * report received in a finger event. We want
- * to emit a normal (X, Y) position
- */
- if (!nd->reading_mt) {
- /*
- * TipSwitch indicates the presence of a
- * finger in single touch mode.
- */
- input_report_key(input, BTN_TOUCH,
- nd->tipswitch);
- input_report_key(input, BTN_TOOL_DOUBLETAP,
- nd->tipswitch);
- input_event(input, EV_ABS, ABS_X, nd->x);
- input_event(input, EV_ABS, ABS_Y, nd->y);
- }
- break;
- case 0xff000002:
- /*
- * we receive this when the device is in multitouch
- * mode. The first of the three values tagged with
- * this usage tells if the contact point is real
- * or a placeholder
- */
-
- /* Shouldn't get more than 4 footer packets, so skip */
- if (nd->mt_foot_count >= 4)
- break;
-
- nd->mt_footer[nd->mt_foot_count++] = value;
-
- /* if the footer isn't complete break */
- if (nd->mt_foot_count != 4)
- break;
-
- /* Pen activity signal. */
- if (nd->mt_footer[2]) {
- /*
- * When the pen deactivates touch, we see a
- * bogus frame with ContactCount > 0.
- * We can
- * save a bit of work by ensuring act_state < 0
- * even if deactivation slack is turned off.
- */
- nd->act_state = deactivate_slack - 1;
- nd->confidence = 0;
- break;
- }
-
- /*
- * The first footer value indicates the presence of a
- * finger.
- */
- if (nd->mt_footer[0]) {
- /*
- * We do not want to process contacts under
- * the size threshold, but do not want to
- * ignore them for activation state
- */
- if (nd->w < nd->min_width ||
- nd->h < nd->min_height)
- nd->confidence = 0;
- } else
- break;
-
- if (nd->act_state > 0) {
- /*
- * Contact meets the activation size threshold
- */
- if (nd->w >= nd->activation_width &&
- nd->h >= nd->activation_height) {
- if (nd->id)
- /*
- * first contact, activate now
- */
- nd->act_state = 0;
- else {
- /*
- * avoid corrupting this frame
- * but ensure next frame will
- * be active
- */
- nd->act_state = 1;
- break;
- }
- } else
- /*
- * Defer adjusting the activation state
- * until the end of the frame.
- */
- break;
- }
-
- /* Discarding this contact */
- if (!nd->confidence)
- break;
-
- /* emit a normal (X, Y) for the first point only */
- if (nd->id == 0) {
- /*
- * TipSwitch is superfluous in multitouch
- * mode. The footer events tell us
- * if there is a finger on the screen or
- * not.
- */
- nd->first_contact_touch = nd->confidence;
- input_event(input, EV_ABS, ABS_X, nd->x);
- input_event(input, EV_ABS, ABS_Y, nd->y);
- }
-
- /* Emit MT events */
- input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y);
-
- /*
- * Translate from height and width to size
- * and orientation.
- */
- if (nd->w > nd->h) {
- input_event(input, EV_ABS,
- ABS_MT_ORIENTATION, 1);
- input_event(input, EV_ABS,
- ABS_MT_TOUCH_MAJOR, nd->w);
- input_event(input, EV_ABS,
- ABS_MT_TOUCH_MINOR, nd->h);
- } else {
- input_event(input, EV_ABS,
- ABS_MT_ORIENTATION, 0);
- input_event(input, EV_ABS,
- ABS_MT_TOUCH_MAJOR, nd->h);
- input_event(input, EV_ABS,
- ABS_MT_TOUCH_MINOR, nd->w);
- }
- input_mt_sync(field->hidinput->input);
- break;
-
- case HID_DG_CONTACTCOUNT: /* End of a multitouch group */
- if (!nd->reading_mt) /* Just to be sure */
- break;
-
- nd->reading_mt = 0;
-
-
- /*
- * Activation state machine logic:
- *
- * Fundamental states:
- * state > 0: Inactive
- * state <= 0: Active
- * state < -deactivate_slack:
- * Pen termination of touch
- *
- * Specific values of interest
- * state == activate_slack
- * no valid input since the last reset
- *
- * state == 0
- * general operational state
- *
- * state == -deactivate_slack
- * read sufficient empty frames to accept
- * the end of input and reset
- */
-
- if (nd->act_state > 0) { /* Currently inactive */
- if (value)
- /*
- * Consider each live contact as
- * evidence of intentional activity.
- */
- nd->act_state = (nd->act_state > value)
- ? nd->act_state - value
- : 0;
- else
- /*
- * Empty frame before we hit the
- * activity threshold, reset.
- */
- nd->act_state = nd->activate_slack;
-
- /*
- * Entered this block inactive and no
- * coordinates sent this frame, so hold off
- * on button state.
- */
- break;
- } else { /* Currently active */
- if (value && nd->act_state >=
- nd->deactivate_slack)
- /*
- * Live point: clear accumulated
- * deactivation count.
- */
- nd->act_state = 0;
- else if (nd->act_state <= nd->deactivate_slack)
- /*
- * We've consumed the deactivation
- * slack, time to deactivate and reset.
- */
- nd->act_state =
- nd->activate_slack;
- else { /* Move towards deactivation */
- nd->act_state--;
- break;
- }
- }
-
- if (nd->first_contact_touch && nd->act_state <= 0) {
- /*
- * Check to see if we're ready to start
- * emitting touch events.
- *
- * Note: activation slack will decrease over
- * the course of the frame, and it will be
- * inconsistent from the start to the end of
- * the frame. However if the frame starts
- * with slack, first_contact_touch will still
- * be 0 and we will not get to this point.
- */
- input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
- input_report_key(input, BTN_TOUCH, 1);
- } else {
- input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
- input_report_key(input, BTN_TOUCH, 0);
- }
- break;
-
- default:
- /* fall-back to the generic hidinput handling */
- return 0;
- }
-
-not_claimed_input:
-
- /* we have handled the hidinput part, now remains hiddev */
- if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event)
- hid->hiddev_hid_event(hid, field, usage, value);
-
- return 1;
-}
-
-static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
- struct ntrig_data *nd;
- struct hid_input *hidinput;
- struct input_dev *input;
- struct hid_report *report;
-
- if (id->driver_data)
- hdev->quirks |= HID_QUIRK_MULTI_INPUT
- | HID_QUIRK_NO_INIT_REPORTS;
-
- nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL);
- if (!nd) {
- hid_err(hdev, "cannot allocate N-Trig data\n");
- return -ENOMEM;
- }
-
- nd->reading_mt = 0;
- nd->min_width = 0;
- nd->min_height = 0;
- nd->activate_slack = activate_slack;
- nd->act_state = activate_slack;
- nd->deactivate_slack = -deactivate_slack;
- nd->sensor_logical_width = 0;
- nd->sensor_logical_height = 0;
- nd->sensor_physical_width = 0;
- nd->sensor_physical_height = 0;
-
- hid_set_drvdata(hdev, nd);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
-
- list_for_each_entry(hidinput, &hdev->inputs, list) {
- if (hidinput->report->maxfield < 1)
- continue;
-
- input = hidinput->input;
- switch (hidinput->report->field[0]->application) {
- case HID_DG_PEN:
- input->name = "N-Trig Pen";
- break;
- case HID_DG_TOUCHSCREEN:
- /* These keys are redundant for fingers, clear them
- * to prevent incorrect identification */
- __clear_bit(BTN_TOOL_PEN, input->keybit);
- __clear_bit(BTN_TOOL_FINGER, input->keybit);
- __clear_bit(BTN_0, input->keybit);
- __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
- /*
- * The physical touchscreen (single touch)
- * input has a value for physical, whereas
- * the multitouch only has logical input
- * fields.
- */
- input->name =
- (hidinput->report->field[0]
- ->physical) ?
- "N-Trig Touchscreen" :
- "N-Trig MultiTouch";
- break;
- }
- }
-
- /* This is needed for devices with more recent firmware versions */
- report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a];
- if (report) {
- /* Let the device settle to ensure the wakeup message gets
- * through */
- usbhid_wait_io(hdev);
- usbhid_submit_report(hdev, report, USB_DIR_IN);
-
- /*
- * Sanity check: if the current mode is invalid reset it to
- * something reasonable.
- */
- if (ntrig_get_mode(hdev) >= 4)
- ntrig_set_mode(hdev, 3);
- }
-
- ntrig_report_version(hdev);
-
- ret = sysfs_create_group(&hdev->dev.kobj,
- &ntrig_attribute_group);
-
- return 0;
-err_free:
- kfree(nd);
- return ret;
-}
-
-static void ntrig_remove(struct hid_device *hdev)
-{
- sysfs_remove_group(&hdev->dev.kobj,
- &ntrig_attribute_group);
- hid_hw_stop(hdev);
- kfree(hid_get_drvdata(hdev));
-}
-
-static const struct hid_device_id ntrig_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18),
- .driver_data = NTRIG_DUPLICATE_USAGES },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ntrig_devices);
-
-static const struct hid_usage_id ntrig_grabbed_usages[] = {
- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 }
-};
-
-static struct hid_driver ntrig_driver = {
- .name = "ntrig",
- .id_table = ntrig_devices,
- .probe = ntrig_probe,
- .remove = ntrig_remove,
- .input_mapping = ntrig_input_mapping,
- .input_mapped = ntrig_input_mapped,
- .usage_table = ntrig_grabbed_usages,
- .event = ntrig_event,
-};
-
-static int __init ntrig_init(void)
-{
- return hid_register_driver(&ntrig_driver);
-}
-
-static void __exit ntrig_exit(void)
-{
- hid_unregister_driver(&ntrig_driver);
-}
-
-module_init(ntrig_init);
-module_exit(ntrig_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-ortek.c b/ANDROID_3.4.5/drivers/hid/hid-ortek.c
deleted file mode 100644
index 0ffa1d2d..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-ortek.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * HID driver for various devices which are apparently based on the same chipset
- * from certain vendor which produces chips that contain wrong LogicalMaximum
- * value in their HID report descriptor. Currently supported devices are:
- *
- * Ortek PKB-1700
- * Ortek WKB-2000
- * Skycable wireless presenter
- *
- * Copyright (c) 2010 Johnathon Harris <jmharris@gmail.com>
- * Copyright (c) 2011 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
- hid_info(hdev, "Fixing up logical minimum in report descriptor (Ortek)\n");
- rdesc[55] = 0x92;
- } else if (*rsize >= 54 && rdesc[52] == 0x25 && rdesc[53] == 0x01) {
- hid_info(hdev, "Fixing up logical minimum in report descriptor (Skycable)\n");
- rdesc[53] = 0x65;
- }
- return rdesc;
-}
-
-static const struct hid_device_id ortek_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ortek_devices);
-
-static struct hid_driver ortek_driver = {
- .name = "ortek",
- .id_table = ortek_devices,
- .report_fixup = ortek_report_fixup
-};
-
-static int __init ortek_init(void)
-{
- return hid_register_driver(&ortek_driver);
-}
-
-static void __exit ortek_exit(void)
-{
- hid_unregister_driver(&ortek_driver);
-}
-
-module_init(ortek_init);
-module_exit(ortek_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-petalynx.c b/ANDROID_3.4.5/drivers/hid/hid-petalynx.c
deleted file mode 100644
index f1ea3ff8..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-petalynx.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * HID driver for some petalynx "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-/* Petalynx Maxter Remote has maximum for consumer page set too low */
-static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
- rdesc[41] == 0x00 && rdesc[59] == 0x26 &&
- rdesc[60] == 0xf9 && rdesc[61] == 0x00) {
- hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n");
- rdesc[60] = 0xfa;
- rdesc[40] = 0xfa;
- }
- return rdesc;
-}
-
-#define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int pl_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) {
- switch (usage->hid & HID_USAGE) {
- case 0x05a: pl_map_key_clear(KEY_TEXT); break;
- case 0x05b: pl_map_key_clear(KEY_RED); break;
- case 0x05c: pl_map_key_clear(KEY_GREEN); break;
- case 0x05d: pl_map_key_clear(KEY_YELLOW); break;
- case 0x05e: pl_map_key_clear(KEY_BLUE); break;
- default:
- return 0;
- }
- return 1;
- }
-
- if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
- switch (usage->hid & HID_USAGE) {
- case 0x0f6: pl_map_key_clear(KEY_NEXT); break;
- case 0x0fa: pl_map_key_clear(KEY_BACK); break;
- default:
- return 0;
- }
- return 1;
- }
-
- return 0;
-}
-
-static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- hdev->quirks |= HID_QUIRK_NOGET;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- return 0;
-err_free:
- return ret;
-}
-
-static const struct hid_device_id pl_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, pl_devices);
-
-static struct hid_driver pl_driver = {
- .name = "petalynx",
- .id_table = pl_devices,
- .report_fixup = pl_report_fixup,
- .input_mapping = pl_input_mapping,
- .probe = pl_probe,
-};
-
-static int __init pl_init(void)
-{
- return hid_register_driver(&pl_driver);
-}
-
-static void __exit pl_exit(void)
-{
- hid_unregister_driver(&pl_driver);
-}
-
-module_init(pl_init);
-module_exit(pl_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-picolcd.c b/ANDROID_3.4.5/drivers/hid/hid-picolcd.c
deleted file mode 100644
index 45c3433f..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-picolcd.c
+++ /dev/null
@@ -1,2752 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2010 by Bruno Prémont <bonbons@linux-vserver.org> *
- * *
- * Based on Logitech G13 driver (v0.4) *
- * Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu> *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, version 2 of the License. *
- * *
- * This driver is distributed in the hope that it will be useful, but *
- * WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this software. If not see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include <linux/hid.h>
-#include <linux/hid-debug.h>
-#include <linux/input.h>
-#include "hid-ids.h"
-#include "usbhid/usbhid.h"
-#include <linux/usb.h>
-
-#include <linux/fb.h>
-#include <linux/vmalloc.h>
-#include <linux/backlight.h>
-#include <linux/lcd.h>
-
-#include <linux/leds.h>
-
-#include <linux/seq_file.h>
-#include <linux/debugfs.h>
-
-#include <linux/completion.h>
-#include <linux/uaccess.h>
-#include <linux/module.h>
-
-#define PICOLCD_NAME "PicoLCD (graphic)"
-
-/* Report numbers */
-#define REPORT_ERROR_CODE 0x10 /* LCD: IN[16] */
-#define ERR_SUCCESS 0x00
-#define ERR_PARAMETER_MISSING 0x01
-#define ERR_DATA_MISSING 0x02
-#define ERR_BLOCK_READ_ONLY 0x03
-#define ERR_BLOCK_NOT_ERASABLE 0x04
-#define ERR_BLOCK_TOO_BIG 0x05
-#define ERR_SECTION_OVERFLOW 0x06
-#define ERR_INVALID_CMD_LEN 0x07
-#define ERR_INVALID_DATA_LEN 0x08
-#define REPORT_KEY_STATE 0x11 /* LCD: IN[2] */
-#define REPORT_IR_DATA 0x21 /* LCD: IN[63] */
-#define REPORT_EE_DATA 0x32 /* LCD: IN[63] */
-#define REPORT_MEMORY 0x41 /* LCD: IN[63] */
-#define REPORT_LED_STATE 0x81 /* LCD: OUT[1] */
-#define REPORT_BRIGHTNESS 0x91 /* LCD: OUT[1] */
-#define REPORT_CONTRAST 0x92 /* LCD: OUT[1] */
-#define REPORT_RESET 0x93 /* LCD: OUT[2] */
-#define REPORT_LCD_CMD 0x94 /* LCD: OUT[63] */
-#define REPORT_LCD_DATA 0x95 /* LCD: OUT[63] */
-#define REPORT_LCD_CMD_DATA 0x96 /* LCD: OUT[63] */
-#define REPORT_EE_READ 0xa3 /* LCD: OUT[63] */
-#define REPORT_EE_WRITE 0xa4 /* LCD: OUT[63] */
-#define REPORT_ERASE_MEMORY 0xb2 /* LCD: OUT[2] */
-#define REPORT_READ_MEMORY 0xb3 /* LCD: OUT[3] */
-#define REPORT_WRITE_MEMORY 0xb4 /* LCD: OUT[63] */
-#define REPORT_SPLASH_RESTART 0xc1 /* LCD: OUT[1] */
-#define REPORT_EXIT_KEYBOARD 0xef /* LCD: OUT[2] */
-#define REPORT_VERSION 0xf1 /* LCD: IN[2],OUT[1] Bootloader: IN[2],OUT[1] */
-#define REPORT_BL_ERASE_MEMORY 0xf2 /* Bootloader: IN[36],OUT[4] */
-#define REPORT_BL_READ_MEMORY 0xf3 /* Bootloader: IN[36],OUT[4] */
-#define REPORT_BL_WRITE_MEMORY 0xf4 /* Bootloader: IN[36],OUT[36] */
-#define REPORT_DEVID 0xf5 /* LCD: IN[5], OUT[1] Bootloader: IN[5],OUT[1] */
-#define REPORT_SPLASH_SIZE 0xf6 /* LCD: IN[4], OUT[1] */
-#define REPORT_HOOK_VERSION 0xf7 /* LCD: IN[2], OUT[1] */
-#define REPORT_EXIT_FLASHER 0xff /* Bootloader: OUT[2] */
-
-#ifdef CONFIG_HID_PICOLCD_FB
-/* Framebuffer
- *
- * The PicoLCD use a Topway LCD module of 256x64 pixel
- * This display area is tiled over 4 controllers with 8 tiles
- * each. Each tile has 8x64 pixel, each data byte representing
- * a 1-bit wide vertical line of the tile.
- *
- * The display can be updated at a tile granularity.
- *
- * Chip 1 Chip 2 Chip 3 Chip 4
- * +----------------+----------------+----------------+----------------+
- * | Tile 1 | Tile 1 | Tile 1 | Tile 1 |
- * +----------------+----------------+----------------+----------------+
- * | Tile 2 | Tile 2 | Tile 2 | Tile 2 |
- * +----------------+----------------+----------------+----------------+
- * ...
- * +----------------+----------------+----------------+----------------+
- * | Tile 8 | Tile 8 | Tile 8 | Tile 8 |
- * +----------------+----------------+----------------+----------------+
- */
-#define PICOLCDFB_NAME "picolcdfb"
-#define PICOLCDFB_WIDTH (256)
-#define PICOLCDFB_HEIGHT (64)
-#define PICOLCDFB_SIZE (PICOLCDFB_WIDTH * PICOLCDFB_HEIGHT / 8)
-
-#define PICOLCDFB_UPDATE_RATE_LIMIT 10
-#define PICOLCDFB_UPDATE_RATE_DEFAULT 2
-
-/* Framebuffer visual structures */
-static const struct fb_fix_screeninfo picolcdfb_fix = {
- .id = PICOLCDFB_NAME,
- .type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_MONO01,
- .xpanstep = 0,
- .ypanstep = 0,
- .ywrapstep = 0,
- .line_length = PICOLCDFB_WIDTH / 8,
- .accel = FB_ACCEL_NONE,
-};
-
-static const struct fb_var_screeninfo picolcdfb_var = {
- .xres = PICOLCDFB_WIDTH,
- .yres = PICOLCDFB_HEIGHT,
- .xres_virtual = PICOLCDFB_WIDTH,
- .yres_virtual = PICOLCDFB_HEIGHT,
- .width = 103,
- .height = 26,
- .bits_per_pixel = 1,
- .grayscale = 1,
- .red = {
- .offset = 0,
- .length = 1,
- .msb_right = 0,
- },
- .green = {
- .offset = 0,
- .length = 1,
- .msb_right = 0,
- },
- .blue = {
- .offset = 0,
- .length = 1,
- .msb_right = 0,
- },
- .transp = {
- .offset = 0,
- .length = 0,
- .msb_right = 0,
- },
-};
-#endif /* CONFIG_HID_PICOLCD_FB */
-
-/* Input device
- *
- * The PicoLCD has an IR receiver header, a built-in keypad with 5 keys
- * and header for 4x4 key matrix. The built-in keys are part of the matrix.
- */
-static const unsigned short def_keymap[] = {
- KEY_RESERVED, /* none */
- KEY_BACK, /* col 4 + row 1 */
- KEY_HOMEPAGE, /* col 3 + row 1 */
- KEY_RESERVED, /* col 2 + row 1 */
- KEY_RESERVED, /* col 1 + row 1 */
- KEY_SCROLLUP, /* col 4 + row 2 */
- KEY_OK, /* col 3 + row 2 */
- KEY_SCROLLDOWN, /* col 2 + row 2 */
- KEY_RESERVED, /* col 1 + row 2 */
- KEY_RESERVED, /* col 4 + row 3 */
- KEY_RESERVED, /* col 3 + row 3 */
- KEY_RESERVED, /* col 2 + row 3 */
- KEY_RESERVED, /* col 1 + row 3 */
- KEY_RESERVED, /* col 4 + row 4 */
- KEY_RESERVED, /* col 3 + row 4 */
- KEY_RESERVED, /* col 2 + row 4 */
- KEY_RESERVED, /* col 1 + row 4 */
-};
-#define PICOLCD_KEYS ARRAY_SIZE(def_keymap)
-
-/* Description of in-progress IO operation, used for operations
- * that trigger response from device */
-struct picolcd_pending {
- struct hid_report *out_report;
- struct hid_report *in_report;
- struct completion ready;
- int raw_size;
- u8 raw_data[64];
-};
-
-/* Per device data structure */
-struct picolcd_data {
- struct hid_device *hdev;
-#ifdef CONFIG_DEBUG_FS
- struct dentry *debug_reset;
- struct dentry *debug_eeprom;
- struct dentry *debug_flash;
- struct mutex mutex_flash;
- int addr_sz;
-#endif
- u8 version[2];
- unsigned short opmode_delay;
- /* input stuff */
- u8 pressed_keys[2];
- struct input_dev *input_keys;
- struct input_dev *input_cir;
- unsigned short keycode[PICOLCD_KEYS];
-
-#ifdef CONFIG_HID_PICOLCD_FB
- /* Framebuffer stuff */
- u8 fb_update_rate;
- u8 fb_bpp;
- u8 fb_force;
- u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */
- u8 *fb_bitmap; /* framebuffer */
- struct fb_info *fb_info;
- struct fb_deferred_io fb_defio;
-#endif /* CONFIG_HID_PICOLCD_FB */
-#ifdef CONFIG_HID_PICOLCD_LCD
- struct lcd_device *lcd;
- u8 lcd_contrast;
-#endif /* CONFIG_HID_PICOLCD_LCD */
-#ifdef CONFIG_HID_PICOLCD_BACKLIGHT
- struct backlight_device *backlight;
- u8 lcd_brightness;
- u8 lcd_power;
-#endif /* CONFIG_HID_PICOLCD_BACKLIGHT */
-#ifdef CONFIG_HID_PICOLCD_LEDS
- /* LED stuff */
- u8 led_state;
- struct led_classdev *led[8];
-#endif /* CONFIG_HID_PICOLCD_LEDS */
-
- /* Housekeeping stuff */
- spinlock_t lock;
- struct mutex mutex;
- struct picolcd_pending *pending;
- int status;
-#define PICOLCD_BOOTLOADER 1
-#define PICOLCD_FAILED 2
-#define PICOLCD_READY_FB 4
-};
-
-
-/* Find a given report */
-#define picolcd_in_report(id, dev) picolcd_report(id, dev, HID_INPUT_REPORT)
-#define picolcd_out_report(id, dev) picolcd_report(id, dev, HID_OUTPUT_REPORT)
-
-static struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir)
-{
- struct list_head *feature_report_list = &hdev->report_enum[dir].report_list;
- struct hid_report *report = NULL;
-
- list_for_each_entry(report, feature_report_list, list) {
- if (report->id == id)
- return report;
- }
- hid_warn(hdev, "No report with id 0x%x found\n", id);
- return NULL;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static void picolcd_debug_out_report(struct picolcd_data *data,
- struct hid_device *hdev, struct hid_report *report);
-#define usbhid_submit_report(a, b, c) \
- do { \
- picolcd_debug_out_report(hid_get_drvdata(a), a, b); \
- usbhid_submit_report(a, b, c); \
- } while (0)
-#endif
-
-/* Submit a report and wait for a reply from device - if device fades away
- * or does not respond in time, return NULL */
-static struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev,
- int report_id, const u8 *raw_data, int size)
-{
- struct picolcd_data *data = hid_get_drvdata(hdev);
- struct picolcd_pending *work;
- struct hid_report *report = picolcd_out_report(report_id, hdev);
- unsigned long flags;
- int i, j, k;
-
- if (!report || !data)
- return NULL;
- if (data->status & PICOLCD_FAILED)
- return NULL;
- work = kzalloc(sizeof(*work), GFP_KERNEL);
- if (!work)
- return NULL;
-
- init_completion(&work->ready);
- work->out_report = report;
- work->in_report = NULL;
- work->raw_size = 0;
-
- mutex_lock(&data->mutex);
- spin_lock_irqsave(&data->lock, flags);
- for (i = k = 0; i < report->maxfield; i++)
- for (j = 0; j < report->field[i]->report_count; j++) {
- hid_set_field(report->field[i], j, k < size ? raw_data[k] : 0);
- k++;
- }
- data->pending = work;
- usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
- spin_unlock_irqrestore(&data->lock, flags);
- wait_for_completion_interruptible_timeout(&work->ready, HZ*2);
- spin_lock_irqsave(&data->lock, flags);
- data->pending = NULL;
- spin_unlock_irqrestore(&data->lock, flags);
- mutex_unlock(&data->mutex);
- return work;
-}
-
-#ifdef CONFIG_HID_PICOLCD_FB
-/* Send a given tile to PicoLCD */
-static int picolcd_fb_send_tile(struct hid_device *hdev, int chip, int tile)
-{
- struct picolcd_data *data = hid_get_drvdata(hdev);
- struct hid_report *report1 = picolcd_out_report(REPORT_LCD_CMD_DATA, hdev);
- struct hid_report *report2 = picolcd_out_report(REPORT_LCD_DATA, hdev);
- unsigned long flags;
- u8 *tdata;
- int i;
-
- if (!report1 || report1->maxfield != 1 || !report2 || report2->maxfield != 1)
- return -ENODEV;
-
- spin_lock_irqsave(&data->lock, flags);
- hid_set_field(report1->field[0], 0, chip << 2);
- hid_set_field(report1->field[0], 1, 0x02);
- hid_set_field(report1->field[0], 2, 0x00);
- hid_set_field(report1->field[0], 3, 0x00);
- hid_set_field(report1->field[0], 4, 0xb8 | tile);
- hid_set_field(report1->field[0], 5, 0x00);
- hid_set_field(report1->field[0], 6, 0x00);
- hid_set_field(report1->field[0], 7, 0x40);
- hid_set_field(report1->field[0], 8, 0x00);
- hid_set_field(report1->field[0], 9, 0x00);
- hid_set_field(report1->field[0], 10, 32);
-
- hid_set_field(report2->field[0], 0, (chip << 2) | 0x01);
- hid_set_field(report2->field[0], 1, 0x00);
- hid_set_field(report2->field[0], 2, 0x00);
- hid_set_field(report2->field[0], 3, 32);
-
- tdata = data->fb_vbitmap + (tile * 4 + chip) * 64;
- for (i = 0; i < 64; i++)
- if (i < 32)
- hid_set_field(report1->field[0], 11 + i, tdata[i]);
- else
- hid_set_field(report2->field[0], 4 + i - 32, tdata[i]);
-
- usbhid_submit_report(data->hdev, report1, USB_DIR_OUT);
- usbhid_submit_report(data->hdev, report2, USB_DIR_OUT);
- spin_unlock_irqrestore(&data->lock, flags);
- return 0;
-}
-
-/* Translate a single tile*/
-static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
- int chip, int tile)
-{
- int i, b, changed = 0;
- u8 tdata[64];
- u8 *vdata = vbitmap + (tile * 4 + chip) * 64;
-
- if (bpp == 1) {
- for (b = 7; b >= 0; b--) {
- const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32;
- for (i = 0; i < 64; i++) {
- tdata[i] <<= 1;
- tdata[i] |= (bdata[i/8] >> (i % 8)) & 0x01;
- }
- }
- } else if (bpp == 8) {
- for (b = 7; b >= 0; b--) {
- const u8 *bdata = bitmap + (tile * 256 + chip * 8 + b * 32) * 8;
- for (i = 0; i < 64; i++) {
- tdata[i] <<= 1;
- tdata[i] |= (bdata[i] & 0x80) ? 0x01 : 0x00;
- }
- }
- } else {
- /* Oops, we should never get here! */
- WARN_ON(1);
- return 0;
- }
-
- for (i = 0; i < 64; i++)
- if (tdata[i] != vdata[i]) {
- changed = 1;
- vdata[i] = tdata[i];
- }
- return changed;
-}
-
-/* Reconfigure LCD display */
-static int picolcd_fb_reset(struct picolcd_data *data, int clear)
-{
- struct hid_report *report = picolcd_out_report(REPORT_LCD_CMD, data->hdev);
- int i, j;
- unsigned long flags;
- static const u8 mapcmd[8] = { 0x00, 0x02, 0x00, 0x64, 0x3f, 0x00, 0x64, 0xc0 };
-
- if (!report || report->maxfield != 1)
- return -ENODEV;
-
- spin_lock_irqsave(&data->lock, flags);
- for (i = 0; i < 4; i++) {
- for (j = 0; j < report->field[0]->maxusage; j++)
- if (j == 0)
- hid_set_field(report->field[0], j, i << 2);
- else if (j < sizeof(mapcmd))
- hid_set_field(report->field[0], j, mapcmd[j]);
- else
- hid_set_field(report->field[0], j, 0);
- usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
- }
-
- data->status |= PICOLCD_READY_FB;
- spin_unlock_irqrestore(&data->lock, flags);
-
- if (data->fb_bitmap) {
- if (clear) {
- memset(data->fb_vbitmap, 0, PICOLCDFB_SIZE);
- memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp);
- }
- data->fb_force = 1;
- }
-
- /* schedule first output of framebuffer */
- if (data->fb_info)
- schedule_delayed_work(&data->fb_info->deferred_work, 0);
-
- return 0;
-}
-
-/* Update fb_vbitmap from the screen_base and send changed tiles to device */
-static void picolcd_fb_update(struct picolcd_data *data)
-{
- int chip, tile, n;
- unsigned long flags;
-
- if (!data)
- return;
-
- spin_lock_irqsave(&data->lock, flags);
- if (!(data->status & PICOLCD_READY_FB)) {
- spin_unlock_irqrestore(&data->lock, flags);
- picolcd_fb_reset(data, 0);
- } else {
- spin_unlock_irqrestore(&data->lock, flags);
- }
-
- /*
- * Translate the framebuffer into the format needed by the PicoLCD.
- * See display layout above.
- * Do this one tile after the other and push those tiles that changed.
- *
- * Wait for our IO to complete as otherwise we might flood the queue!
- */
- n = 0;
- for (chip = 0; chip < 4; chip++)
- for (tile = 0; tile < 8; tile++)
- if (picolcd_fb_update_tile(data->fb_vbitmap,
- data->fb_bitmap, data->fb_bpp, chip, tile) ||
- data->fb_force) {
- n += 2;
- if (!data->fb_info->par)
- return; /* device lost! */
- if (n >= HID_OUTPUT_FIFO_SIZE / 2) {
- usbhid_wait_io(data->hdev);
- n = 0;
- }
- picolcd_fb_send_tile(data->hdev, chip, tile);
- }
- data->fb_force = false;
- if (n)
- usbhid_wait_io(data->hdev);
-}
-
-/* Stub to call the system default and update the image on the picoLCD */
-static void picolcd_fb_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect)
-{
- if (!info->par)
- return;
- sys_fillrect(info, rect);
-
- schedule_delayed_work(&info->deferred_work, 0);
-}
-
-/* Stub to call the system default and update the image on the picoLCD */
-static void picolcd_fb_copyarea(struct fb_info *info,
- const struct fb_copyarea *area)
-{
- if (!info->par)
- return;
- sys_copyarea(info, area);
-
- schedule_delayed_work(&info->deferred_work, 0);
-}
-
-/* Stub to call the system default and update the image on the picoLCD */
-static void picolcd_fb_imageblit(struct fb_info *info, const struct fb_image *image)
-{
- if (!info->par)
- return;
- sys_imageblit(info, image);
-
- schedule_delayed_work(&info->deferred_work, 0);
-}
-
-/*
- * this is the slow path from userspace. they can seek and write to
- * the fb. it's inefficient to do anything less than a full screen draw
- */
-static ssize_t picolcd_fb_write(struct fb_info *info, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- ssize_t ret;
- if (!info->par)
- return -ENODEV;
- ret = fb_sys_write(info, buf, count, ppos);
- if (ret >= 0)
- schedule_delayed_work(&info->deferred_work, 0);
- return ret;
-}
-
-static int picolcd_fb_blank(int blank, struct fb_info *info)
-{
- if (!info->par)
- return -ENODEV;
- /* We let fb notification do this for us via lcd/backlight device */
- return 0;
-}
-
-static void picolcd_fb_destroy(struct fb_info *info)
-{
- struct picolcd_data *data = info->par;
- u32 *ref_cnt = info->pseudo_palette;
- int may_release;
-
- info->par = NULL;
- if (data)
- data->fb_info = NULL;
- fb_deferred_io_cleanup(info);
-
- ref_cnt--;
- mutex_lock(&info->lock);
- (*ref_cnt)--;
- may_release = !*ref_cnt;
- mutex_unlock(&info->lock);
- if (may_release) {
- vfree((u8 *)info->fix.smem_start);
- framebuffer_release(info);
- }
-}
-
-static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
- __u32 bpp = var->bits_per_pixel;
- __u32 activate = var->activate;
-
- /* only allow 1/8 bit depth (8-bit is grayscale) */
- *var = picolcdfb_var;
- var->activate = activate;
- if (bpp >= 8) {
- var->bits_per_pixel = 8;
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- } else {
- var->bits_per_pixel = 1;
- var->red.length = 1;
- var->green.length = 1;
- var->blue.length = 1;
- }
- return 0;
-}
-
-static int picolcd_set_par(struct fb_info *info)
-{
- struct picolcd_data *data = info->par;
- u8 *tmp_fb, *o_fb;
- if (!data)
- return -ENODEV;
- if (info->var.bits_per_pixel == data->fb_bpp)
- return 0;
- /* switch between 1/8 bit depths */
- if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8)
- return -EINVAL;
-
- o_fb = data->fb_bitmap;
- tmp_fb = kmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel, GFP_KERNEL);
- if (!tmp_fb)
- return -ENOMEM;
-
- /* translate FB content to new bits-per-pixel */
- if (info->var.bits_per_pixel == 1) {
- int i, b;
- for (i = 0; i < PICOLCDFB_SIZE; i++) {
- u8 p = 0;
- for (b = 0; b < 8; b++) {
- p <<= 1;
- p |= o_fb[i*8+b] ? 0x01 : 0x00;
- }
- tmp_fb[i] = p;
- }
- memcpy(o_fb, tmp_fb, PICOLCDFB_SIZE);
- info->fix.visual = FB_VISUAL_MONO01;
- info->fix.line_length = PICOLCDFB_WIDTH / 8;
- } else {
- int i;
- memcpy(tmp_fb, o_fb, PICOLCDFB_SIZE);
- for (i = 0; i < PICOLCDFB_SIZE * 8; i++)
- o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
- info->fix.visual = FB_VISUAL_DIRECTCOLOR;
- info->fix.line_length = PICOLCDFB_WIDTH;
- }
-
- kfree(tmp_fb);
- data->fb_bpp = info->var.bits_per_pixel;
- return 0;
-}
-
-/* Do refcounting on our FB and cleanup per worker if FB is
- * closed after unplug of our device
- * (fb_release holds info->lock and still touches info after
- * we return so we can't release it immediately.
- */
-struct picolcd_fb_cleanup_item {
- struct fb_info *info;
- struct picolcd_fb_cleanup_item *next;
-};
-static struct picolcd_fb_cleanup_item *fb_pending;
-static DEFINE_SPINLOCK(fb_pending_lock);
-
-static void picolcd_fb_do_cleanup(struct work_struct *data)
-{
- struct picolcd_fb_cleanup_item *item;
- unsigned long flags;
-
- do {
- spin_lock_irqsave(&fb_pending_lock, flags);
- item = fb_pending;
- fb_pending = item ? item->next : NULL;
- spin_unlock_irqrestore(&fb_pending_lock, flags);
-
- if (item) {
- u8 *fb = (u8 *)item->info->fix.smem_start;
- /* make sure we do not race against fb core when
- * releasing */
- mutex_lock(&item->info->lock);
- mutex_unlock(&item->info->lock);
- framebuffer_release(item->info);
- vfree(fb);
- }
- } while (item);
-}
-
-static DECLARE_WORK(picolcd_fb_cleanup, picolcd_fb_do_cleanup);
-
-static int picolcd_fb_open(struct fb_info *info, int u)
-{
- u32 *ref_cnt = info->pseudo_palette;
- ref_cnt--;
-
- (*ref_cnt)++;
- return 0;
-}
-
-static int picolcd_fb_release(struct fb_info *info, int u)
-{
- u32 *ref_cnt = info->pseudo_palette;
- ref_cnt--;
-
- (*ref_cnt)++;
- if (!*ref_cnt) {
- unsigned long flags;
- struct picolcd_fb_cleanup_item *item = (struct picolcd_fb_cleanup_item *)ref_cnt;
- item--;
- spin_lock_irqsave(&fb_pending_lock, flags);
- item->next = fb_pending;
- fb_pending = item;
- spin_unlock_irqrestore(&fb_pending_lock, flags);
- schedule_work(&picolcd_fb_cleanup);
- }
- return 0;
-}
-
-/* Note this can't be const because of struct fb_info definition */
-static struct fb_ops picolcdfb_ops = {
- .owner = THIS_MODULE,
- .fb_destroy = picolcd_fb_destroy,
- .fb_open = picolcd_fb_open,
- .fb_release = picolcd_fb_release,
- .fb_read = fb_sys_read,
- .fb_write = picolcd_fb_write,
- .fb_blank = picolcd_fb_blank,
- .fb_fillrect = picolcd_fb_fillrect,
- .fb_copyarea = picolcd_fb_copyarea,
- .fb_imageblit = picolcd_fb_imageblit,
- .fb_check_var = picolcd_fb_check_var,
- .fb_set_par = picolcd_set_par,
-};
-
-
-/* Callback from deferred IO workqueue */
-static void picolcd_fb_deferred_io(struct fb_info *info, struct list_head *pagelist)
-{
- picolcd_fb_update(info->par);
-}
-
-static const struct fb_deferred_io picolcd_fb_defio = {
- .delay = HZ / PICOLCDFB_UPDATE_RATE_DEFAULT,
- .deferred_io = picolcd_fb_deferred_io,
-};
-
-
-/*
- * The "fb_update_rate" sysfs attribute
- */
-static ssize_t picolcd_fb_update_rate_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct picolcd_data *data = dev_get_drvdata(dev);
- unsigned i, fb_update_rate = data->fb_update_rate;
- size_t ret = 0;
-
- for (i = 1; i <= PICOLCDFB_UPDATE_RATE_LIMIT; i++)
- if (ret >= PAGE_SIZE)
- break;
- else if (i == fb_update_rate)
- ret += snprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i);
- else
- ret += snprintf(buf+ret, PAGE_SIZE-ret, "%u ", i);
- if (ret > 0)
- buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n';
- return ret;
-}
-
-static ssize_t picolcd_fb_update_rate_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct picolcd_data *data = dev_get_drvdata(dev);
- int i;
- unsigned u;
-
- if (count < 1 || count > 10)
- return -EINVAL;
-
- i = sscanf(buf, "%u", &u);
- if (i != 1)
- return -EINVAL;
-
- if (u > PICOLCDFB_UPDATE_RATE_LIMIT)
- return -ERANGE;
- else if (u == 0)
- u = PICOLCDFB_UPDATE_RATE_DEFAULT;
-
- data->fb_update_rate = u;
- data->fb_defio.delay = HZ / data->fb_update_rate;
- return count;
-}
-
-static DEVICE_ATTR(fb_update_rate, 0666, picolcd_fb_update_rate_show,
- picolcd_fb_update_rate_store);
-
-/* initialize Framebuffer device */
-static int picolcd_init_framebuffer(struct picolcd_data *data)
-{
- struct device *dev = &data->hdev->dev;
- struct fb_info *info = NULL;
- int i, error = -ENOMEM;
- u8 *fb_vbitmap = NULL;
- u8 *fb_bitmap = NULL;
- u32 *palette;
-
- fb_bitmap = vmalloc(PICOLCDFB_SIZE*8);
- if (fb_bitmap == NULL) {
- dev_err(dev, "can't get a free page for framebuffer\n");
- goto err_nomem;
- }
-
- fb_vbitmap = kmalloc(PICOLCDFB_SIZE, GFP_KERNEL);
- if (fb_vbitmap == NULL) {
- dev_err(dev, "can't alloc vbitmap image buffer\n");
- goto err_nomem;
- }
-
- data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT;
- data->fb_defio = picolcd_fb_defio;
- /* The extra memory is:
- * - struct picolcd_fb_cleanup_item
- * - u32 for ref_count
- * - 256*u32 for pseudo_palette
- */
- info = framebuffer_alloc(257 * sizeof(u32) + sizeof(struct picolcd_fb_cleanup_item), dev);
- if (info == NULL) {
- dev_err(dev, "failed to allocate a framebuffer\n");
- goto err_nomem;
- }
-
- palette = info->par + sizeof(struct picolcd_fb_cleanup_item);
- *palette = 1;
- palette++;
- for (i = 0; i < 256; i++)
- palette[i] = i > 0 && i < 16 ? 0xff : 0;
- info->pseudo_palette = palette;
- info->fbdefio = &data->fb_defio;
- info->screen_base = (char __force __iomem *)fb_bitmap;
- info->fbops = &picolcdfb_ops;
- info->var = picolcdfb_var;
- info->fix = picolcdfb_fix;
- info->fix.smem_len = PICOLCDFB_SIZE*8;
- info->fix.smem_start = (unsigned long)fb_bitmap;
- info->par = data;
- info->flags = FBINFO_FLAG_DEFAULT;
-
- data->fb_vbitmap = fb_vbitmap;
- data->fb_bitmap = fb_bitmap;
- data->fb_bpp = picolcdfb_var.bits_per_pixel;
- error = picolcd_fb_reset(data, 1);
- if (error) {
- dev_err(dev, "failed to configure display\n");
- goto err_cleanup;
- }
- error = device_create_file(dev, &dev_attr_fb_update_rate);
- if (error) {
- dev_err(dev, "failed to create sysfs attributes\n");
- goto err_cleanup;
- }
- fb_deferred_io_init(info);
- data->fb_info = info;
- error = register_framebuffer(info);
- if (error) {
- dev_err(dev, "failed to register framebuffer\n");
- goto err_sysfs;
- }
- /* schedule first output of framebuffer */
- data->fb_force = 1;
- schedule_delayed_work(&info->deferred_work, 0);
- return 0;
-
-err_sysfs:
- fb_deferred_io_cleanup(info);
- device_remove_file(dev, &dev_attr_fb_update_rate);
-err_cleanup:
- data->fb_vbitmap = NULL;
- data->fb_bitmap = NULL;
- data->fb_bpp = 0;
- data->fb_info = NULL;
-
-err_nomem:
- framebuffer_release(info);
- vfree(fb_bitmap);
- kfree(fb_vbitmap);
- return error;
-}
-
-static void picolcd_exit_framebuffer(struct picolcd_data *data)
-{
- struct fb_info *info = data->fb_info;
- u8 *fb_vbitmap = data->fb_vbitmap;
-
- if (!info)
- return;
-
- info->par = NULL;
- device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
- unregister_framebuffer(info);
- data->fb_vbitmap = NULL;
- data->fb_bitmap = NULL;
- data->fb_bpp = 0;
- data->fb_info = NULL;
- kfree(fb_vbitmap);
-}
-
-#define picolcd_fbinfo(d) ((d)->fb_info)
-#else
-static inline int picolcd_fb_reset(struct picolcd_data *data, int clear)
-{
- return 0;
-}
-static inline int picolcd_init_framebuffer(struct picolcd_data *data)
-{
- return 0;
-}
-static inline void picolcd_exit_framebuffer(struct picolcd_data *data)
-{
-}
-#define picolcd_fbinfo(d) NULL
-#endif /* CONFIG_HID_PICOLCD_FB */
-
-#ifdef CONFIG_HID_PICOLCD_BACKLIGHT
-/*
- * backlight class device
- */
-static int picolcd_get_brightness(struct backlight_device *bdev)
-{
- struct picolcd_data *data = bl_get_data(bdev);
- return data->lcd_brightness;
-}
-
-static int picolcd_set_brightness(struct backlight_device *bdev)
-{
- struct picolcd_data *data = bl_get_data(bdev);
- struct hid_report *report = picolcd_out_report(REPORT_BRIGHTNESS, data->hdev);
- unsigned long flags;
-
- if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
- return -ENODEV;
-
- data->lcd_brightness = bdev->props.brightness & 0x0ff;
- data->lcd_power = bdev->props.power;
- spin_lock_irqsave(&data->lock, flags);
- hid_set_field(report->field[0], 0, data->lcd_power == FB_BLANK_UNBLANK ? data->lcd_brightness : 0);
- usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
- spin_unlock_irqrestore(&data->lock, flags);
- return 0;
-}
-
-static int picolcd_check_bl_fb(struct backlight_device *bdev, struct fb_info *fb)
-{
- return fb && fb == picolcd_fbinfo((struct picolcd_data *)bl_get_data(bdev));
-}
-
-static const struct backlight_ops picolcd_blops = {
- .update_status = picolcd_set_brightness,
- .get_brightness = picolcd_get_brightness,
- .check_fb = picolcd_check_bl_fb,
-};
-
-static int picolcd_init_backlight(struct picolcd_data *data, struct hid_report *report)
-{
- struct device *dev = &data->hdev->dev;
- struct backlight_device *bdev;
- struct backlight_properties props;
- if (!report)
- return -ENODEV;
- if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
- report->field[0]->report_size != 8) {
- dev_err(dev, "unsupported BRIGHTNESS report");
- return -EINVAL;
- }
-
- memset(&props, 0, sizeof(props));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = 0xff;
- bdev = backlight_device_register(dev_name(dev), dev, data,
- &picolcd_blops, &props);
- if (IS_ERR(bdev)) {
- dev_err(dev, "failed to register backlight\n");
- return PTR_ERR(bdev);
- }
- bdev->props.brightness = 0xff;
- data->lcd_brightness = 0xff;
- data->backlight = bdev;
- picolcd_set_brightness(bdev);
- return 0;
-}
-
-static void picolcd_exit_backlight(struct picolcd_data *data)
-{
- struct backlight_device *bdev = data->backlight;
-
- data->backlight = NULL;
- if (bdev)
- backlight_device_unregister(bdev);
-}
-
-static inline int picolcd_resume_backlight(struct picolcd_data *data)
-{
- if (!data->backlight)
- return 0;
- return picolcd_set_brightness(data->backlight);
-}
-
-#ifdef CONFIG_PM
-static void picolcd_suspend_backlight(struct picolcd_data *data)
-{
- int bl_power = data->lcd_power;
- if (!data->backlight)
- return;
-
- data->backlight->props.power = FB_BLANK_POWERDOWN;
- picolcd_set_brightness(data->backlight);
- data->lcd_power = data->backlight->props.power = bl_power;
-}
-#endif /* CONFIG_PM */
-#else
-static inline int picolcd_init_backlight(struct picolcd_data *data,
- struct hid_report *report)
-{
- return 0;
-}
-static inline void picolcd_exit_backlight(struct picolcd_data *data)
-{
-}
-static inline int picolcd_resume_backlight(struct picolcd_data *data)
-{
- return 0;
-}
-static inline void picolcd_suspend_backlight(struct picolcd_data *data)
-{
-}
-#endif /* CONFIG_HID_PICOLCD_BACKLIGHT */
-
-#ifdef CONFIG_HID_PICOLCD_LCD
-/*
- * lcd class device
- */
-static int picolcd_get_contrast(struct lcd_device *ldev)
-{
- struct picolcd_data *data = lcd_get_data(ldev);
- return data->lcd_contrast;
-}
-
-static int picolcd_set_contrast(struct lcd_device *ldev, int contrast)
-{
- struct picolcd_data *data = lcd_get_data(ldev);
- struct hid_report *report = picolcd_out_report(REPORT_CONTRAST, data->hdev);
- unsigned long flags;
-
- if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
- return -ENODEV;
-
- data->lcd_contrast = contrast & 0x0ff;
- spin_lock_irqsave(&data->lock, flags);
- hid_set_field(report->field[0], 0, data->lcd_contrast);
- usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
- spin_unlock_irqrestore(&data->lock, flags);
- return 0;
-}
-
-static int picolcd_check_lcd_fb(struct lcd_device *ldev, struct fb_info *fb)
-{
- return fb && fb == picolcd_fbinfo((struct picolcd_data *)lcd_get_data(ldev));
-}
-
-static struct lcd_ops picolcd_lcdops = {
- .get_contrast = picolcd_get_contrast,
- .set_contrast = picolcd_set_contrast,
- .check_fb = picolcd_check_lcd_fb,
-};
-
-static int picolcd_init_lcd(struct picolcd_data *data, struct hid_report *report)
-{
- struct device *dev = &data->hdev->dev;
- struct lcd_device *ldev;
-
- if (!report)
- return -ENODEV;
- if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
- report->field[0]->report_size != 8) {
- dev_err(dev, "unsupported CONTRAST report");
- return -EINVAL;
- }
-
- ldev = lcd_device_register(dev_name(dev), dev, data, &picolcd_lcdops);
- if (IS_ERR(ldev)) {
- dev_err(dev, "failed to register LCD\n");
- return PTR_ERR(ldev);
- }
- ldev->props.max_contrast = 0x0ff;
- data->lcd_contrast = 0xe5;
- data->lcd = ldev;
- picolcd_set_contrast(ldev, 0xe5);
- return 0;
-}
-
-static void picolcd_exit_lcd(struct picolcd_data *data)
-{
- struct lcd_device *ldev = data->lcd;
-
- data->lcd = NULL;
- if (ldev)
- lcd_device_unregister(ldev);
-}
-
-static inline int picolcd_resume_lcd(struct picolcd_data *data)
-{
- if (!data->lcd)
- return 0;
- return picolcd_set_contrast(data->lcd, data->lcd_contrast);
-}
-#else
-static inline int picolcd_init_lcd(struct picolcd_data *data,
- struct hid_report *report)
-{
- return 0;
-}
-static inline void picolcd_exit_lcd(struct picolcd_data *data)
-{
-}
-static inline int picolcd_resume_lcd(struct picolcd_data *data)
-{
- return 0;
-}
-#endif /* CONFIG_HID_PICOLCD_LCD */
-
-#ifdef CONFIG_HID_PICOLCD_LEDS
-/**
- * LED class device
- */
-static void picolcd_leds_set(struct picolcd_data *data)
-{
- struct hid_report *report;
- unsigned long flags;
-
- if (!data->led[0])
- return;
- report = picolcd_out_report(REPORT_LED_STATE, data->hdev);
- if (!report || report->maxfield != 1 || report->field[0]->report_count != 1)
- return;
-
- spin_lock_irqsave(&data->lock, flags);
- hid_set_field(report->field[0], 0, data->led_state);
- usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
- spin_unlock_irqrestore(&data->lock, flags);
-}
-
-static void picolcd_led_set_brightness(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct device *dev;
- struct hid_device *hdev;
- struct picolcd_data *data;
- int i, state = 0;
-
- dev = led_cdev->dev->parent;
- hdev = container_of(dev, struct hid_device, dev);
- data = hid_get_drvdata(hdev);
- for (i = 0; i < 8; i++) {
- if (led_cdev != data->led[i])
- continue;
- state = (data->led_state >> i) & 1;
- if (value == LED_OFF && state) {
- data->led_state &= ~(1 << i);
- picolcd_leds_set(data);
- } else if (value != LED_OFF && !state) {
- data->led_state |= 1 << i;
- picolcd_leds_set(data);
- }
- break;
- }
-}
-
-static enum led_brightness picolcd_led_get_brightness(struct led_classdev *led_cdev)
-{
- struct device *dev;
- struct hid_device *hdev;
- struct picolcd_data *data;
- int i, value = 0;
-
- dev = led_cdev->dev->parent;
- hdev = container_of(dev, struct hid_device, dev);
- data = hid_get_drvdata(hdev);
- for (i = 0; i < 8; i++)
- if (led_cdev == data->led[i]) {
- value = (data->led_state >> i) & 1;
- break;
- }
- return value ? LED_FULL : LED_OFF;
-}
-
-static int picolcd_init_leds(struct picolcd_data *data, struct hid_report *report)
-{
- struct device *dev = &data->hdev->dev;
- struct led_classdev *led;
- size_t name_sz = strlen(dev_name(dev)) + 8;
- char *name;
- int i, ret = 0;
-
- if (!report)
- return -ENODEV;
- if (report->maxfield != 1 || report->field[0]->report_count != 1 ||
- report->field[0]->report_size != 8) {
- dev_err(dev, "unsupported LED_STATE report");
- return -EINVAL;
- }
-
- for (i = 0; i < 8; i++) {
- led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL);
- if (!led) {
- dev_err(dev, "can't allocate memory for LED %d\n", i);
- ret = -ENOMEM;
- goto err;
- }
- name = (void *)(&led[1]);
- snprintf(name, name_sz, "%s::GPO%d", dev_name(dev), i);
- led->name = name;
- led->brightness = 0;
- led->max_brightness = 1;
- led->brightness_get = picolcd_led_get_brightness;
- led->brightness_set = picolcd_led_set_brightness;
-
- data->led[i] = led;
- ret = led_classdev_register(dev, data->led[i]);
- if (ret) {
- data->led[i] = NULL;
- kfree(led);
- dev_err(dev, "can't register LED %d\n", i);
- goto err;
- }
- }
- return 0;
-err:
- for (i = 0; i < 8; i++)
- if (data->led[i]) {
- led = data->led[i];
- data->led[i] = NULL;
- led_classdev_unregister(led);
- kfree(led);
- }
- return ret;
-}
-
-static void picolcd_exit_leds(struct picolcd_data *data)
-{
- struct led_classdev *led;
- int i;
-
- for (i = 0; i < 8; i++) {
- led = data->led[i];
- data->led[i] = NULL;
- if (!led)
- continue;
- led_classdev_unregister(led);
- kfree(led);
- }
-}
-
-#else
-static inline int picolcd_init_leds(struct picolcd_data *data,
- struct hid_report *report)
-{
- return 0;
-}
-static inline void picolcd_exit_leds(struct picolcd_data *data)
-{
-}
-static inline int picolcd_leds_set(struct picolcd_data *data)
-{
- return 0;
-}
-#endif /* CONFIG_HID_PICOLCD_LEDS */
-
-/*
- * input class device
- */
-static int picolcd_raw_keypad(struct picolcd_data *data,
- struct hid_report *report, u8 *raw_data, int size)
-{
- /*
- * Keypad event
- * First and second data bytes list currently pressed keys,
- * 0x00 means no key and at most 2 keys may be pressed at same time
- */
- int i, j;
-
- /* determine newly pressed keys */
- for (i = 0; i < size; i++) {
- unsigned int key_code;
- if (raw_data[i] == 0)
- continue;
- for (j = 0; j < sizeof(data->pressed_keys); j++)
- if (data->pressed_keys[j] == raw_data[i])
- goto key_already_down;
- for (j = 0; j < sizeof(data->pressed_keys); j++)
- if (data->pressed_keys[j] == 0) {
- data->pressed_keys[j] = raw_data[i];
- break;
- }
- input_event(data->input_keys, EV_MSC, MSC_SCAN, raw_data[i]);
- if (raw_data[i] < PICOLCD_KEYS)
- key_code = data->keycode[raw_data[i]];
- else
- key_code = KEY_UNKNOWN;
- if (key_code != KEY_UNKNOWN) {
- dbg_hid(PICOLCD_NAME " got key press for %u:%d",
- raw_data[i], key_code);
- input_report_key(data->input_keys, key_code, 1);
- }
- input_sync(data->input_keys);
-key_already_down:
- continue;
- }
-
- /* determine newly released keys */
- for (j = 0; j < sizeof(data->pressed_keys); j++) {
- unsigned int key_code;
- if (data->pressed_keys[j] == 0)
- continue;
- for (i = 0; i < size; i++)
- if (data->pressed_keys[j] == raw_data[i])
- goto key_still_down;
- input_event(data->input_keys, EV_MSC, MSC_SCAN, data->pressed_keys[j]);
- if (data->pressed_keys[j] < PICOLCD_KEYS)
- key_code = data->keycode[data->pressed_keys[j]];
- else
- key_code = KEY_UNKNOWN;
- if (key_code != KEY_UNKNOWN) {
- dbg_hid(PICOLCD_NAME " got key release for %u:%d",
- data->pressed_keys[j], key_code);
- input_report_key(data->input_keys, key_code, 0);
- }
- input_sync(data->input_keys);
- data->pressed_keys[j] = 0;
-key_still_down:
- continue;
- }
- return 1;
-}
-
-static int picolcd_raw_cir(struct picolcd_data *data,
- struct hid_report *report, u8 *raw_data, int size)
-{
- /* Need understanding of CIR data format to implement ... */
- return 1;
-}
-
-static int picolcd_check_version(struct hid_device *hdev)
-{
- struct picolcd_data *data = hid_get_drvdata(hdev);
- struct picolcd_pending *verinfo;
- int ret = 0;
-
- if (!data)
- return -ENODEV;
-
- verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0);
- if (!verinfo) {
- hid_err(hdev, "no version response from PicoLCD\n");
- return -ENODEV;
- }
-
- if (verinfo->raw_size == 2) {
- data->version[0] = verinfo->raw_data[1];
- data->version[1] = verinfo->raw_data[0];
- if (data->status & PICOLCD_BOOTLOADER) {
- hid_info(hdev, "PicoLCD, bootloader version %d.%d\n",
- verinfo->raw_data[1], verinfo->raw_data[0]);
- } else {
- hid_info(hdev, "PicoLCD, firmware version %d.%d\n",
- verinfo->raw_data[1], verinfo->raw_data[0]);
- }
- } else {
- hid_err(hdev, "confused, got unexpected version response from PicoLCD\n");
- ret = -EINVAL;
- }
- kfree(verinfo);
- return ret;
-}
-
-/*
- * Reset our device and wait for answer to VERSION request
- */
-static int picolcd_reset(struct hid_device *hdev)
-{
- struct picolcd_data *data = hid_get_drvdata(hdev);
- struct hid_report *report = picolcd_out_report(REPORT_RESET, hdev);
- unsigned long flags;
- int error;
-
- if (!data || !report || report->maxfield != 1)
- return -ENODEV;
-
- spin_lock_irqsave(&data->lock, flags);
- if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
- data->status |= PICOLCD_BOOTLOADER;
-
- /* perform the reset */
- hid_set_field(report->field[0], 0, 1);
- usbhid_submit_report(hdev, report, USB_DIR_OUT);
- spin_unlock_irqrestore(&data->lock, flags);
-
- error = picolcd_check_version(hdev);
- if (error)
- return error;
-
- picolcd_resume_lcd(data);
- picolcd_resume_backlight(data);
-#ifdef CONFIG_HID_PICOLCD_FB
- if (data->fb_info)
- schedule_delayed_work(&data->fb_info->deferred_work, 0);
-#endif /* CONFIG_HID_PICOLCD_FB */
-
- picolcd_leds_set(data);
- return 0;
-}
-
-/*
- * The "operation_mode" sysfs attribute
- */
-static ssize_t picolcd_operation_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct picolcd_data *data = dev_get_drvdata(dev);
-
- if (data->status & PICOLCD_BOOTLOADER)
- return snprintf(buf, PAGE_SIZE, "[bootloader] lcd\n");
- else
- return snprintf(buf, PAGE_SIZE, "bootloader [lcd]\n");
-}
-
-static ssize_t picolcd_operation_mode_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct picolcd_data *data = dev_get_drvdata(dev);
- struct hid_report *report = NULL;
- size_t cnt = count;
- int timeout = data->opmode_delay;
- unsigned long flags;
-
- if (cnt >= 3 && strncmp("lcd", buf, 3) == 0) {
- if (data->status & PICOLCD_BOOTLOADER)
- report = picolcd_out_report(REPORT_EXIT_FLASHER, data->hdev);
- buf += 3;
- cnt -= 3;
- } else if (cnt >= 10 && strncmp("bootloader", buf, 10) == 0) {
- if (!(data->status & PICOLCD_BOOTLOADER))
- report = picolcd_out_report(REPORT_EXIT_KEYBOARD, data->hdev);
- buf += 10;
- cnt -= 10;
- }
- if (!report)
- return -EINVAL;
-
- while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r'))
- cnt--;
- if (cnt != 0)
- return -EINVAL;
-
- spin_lock_irqsave(&data->lock, flags);
- hid_set_field(report->field[0], 0, timeout & 0xff);
- hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff);
- usbhid_submit_report(data->hdev, report, USB_DIR_OUT);
- spin_unlock_irqrestore(&data->lock, flags);
- return count;
-}
-
-static DEVICE_ATTR(operation_mode, 0644, picolcd_operation_mode_show,
- picolcd_operation_mode_store);
-
-/*
- * The "operation_mode_delay" sysfs attribute
- */
-static ssize_t picolcd_operation_mode_delay_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct picolcd_data *data = dev_get_drvdata(dev);
-
- return snprintf(buf, PAGE_SIZE, "%hu\n", data->opmode_delay);
-}
-
-static ssize_t picolcd_operation_mode_delay_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct picolcd_data *data = dev_get_drvdata(dev);
- unsigned u;
- if (sscanf(buf, "%u", &u) != 1)
- return -EINVAL;
- if (u > 30000)
- return -EINVAL;
- else
- data->opmode_delay = u;
- return count;
-}
-
-static DEVICE_ATTR(operation_mode_delay, 0644, picolcd_operation_mode_delay_show,
- picolcd_operation_mode_delay_store);
-
-
-#ifdef CONFIG_DEBUG_FS
-/*
- * The "reset" file
- */
-static int picolcd_debug_reset_show(struct seq_file *f, void *p)
-{
- if (picolcd_fbinfo((struct picolcd_data *)f->private))
- seq_printf(f, "all fb\n");
- else
- seq_printf(f, "all\n");
- return 0;
-}
-
-static int picolcd_debug_reset_open(struct inode *inode, struct file *f)
-{
- return single_open(f, picolcd_debug_reset_show, inode->i_private);
-}
-
-static ssize_t picolcd_debug_reset_write(struct file *f, const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct picolcd_data *data = ((struct seq_file *)f->private_data)->private;
- char buf[32];
- size_t cnt = min(count, sizeof(buf)-1);
- if (copy_from_user(buf, user_buf, cnt))
- return -EFAULT;
-
- while (cnt > 0 && (buf[cnt-1] == ' ' || buf[cnt-1] == '\n'))
- cnt--;
- buf[cnt] = '\0';
- if (strcmp(buf, "all") == 0) {
- picolcd_reset(data->hdev);
- picolcd_fb_reset(data, 1);
- } else if (strcmp(buf, "fb") == 0) {
- picolcd_fb_reset(data, 1);
- } else {
- return -EINVAL;
- }
- return count;
-}
-
-static const struct file_operations picolcd_debug_reset_fops = {
- .owner = THIS_MODULE,
- .open = picolcd_debug_reset_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = picolcd_debug_reset_write,
- .release = single_release,
-};
-
-/*
- * The "eeprom" file
- */
-static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u,
- size_t s, loff_t *off)
-{
- struct picolcd_data *data = f->private_data;
- struct picolcd_pending *resp;
- u8 raw_data[3];
- ssize_t ret = -EIO;
-
- if (s == 0)
- return -EINVAL;
- if (*off > 0x0ff)
- return 0;
-
- /* prepare buffer with info about what we want to read (addr & len) */
- raw_data[0] = *off & 0xff;
- raw_data[1] = (*off >> 8) & 0xff;
- raw_data[2] = s < 20 ? s : 20;
- if (*off + raw_data[2] > 0xff)
- raw_data[2] = 0x100 - *off;
- resp = picolcd_send_and_wait(data->hdev, REPORT_EE_READ, raw_data,
- sizeof(raw_data));
- if (!resp)
- return -EIO;
-
- if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
- /* successful read :) */
- ret = resp->raw_data[2];
- if (ret > s)
- ret = s;
- if (copy_to_user(u, resp->raw_data+3, ret))
- ret = -EFAULT;
- else
- *off += ret;
- } /* anything else is some kind of IO error */
-
- kfree(resp);
- return ret;
-}
-
-static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u,
- size_t s, loff_t *off)
-{
- struct picolcd_data *data = f->private_data;
- struct picolcd_pending *resp;
- ssize_t ret = -EIO;
- u8 raw_data[23];
-
- if (s == 0)
- return -EINVAL;
- if (*off > 0x0ff)
- return -ENOSPC;
-
- memset(raw_data, 0, sizeof(raw_data));
- raw_data[0] = *off & 0xff;
- raw_data[1] = (*off >> 8) & 0xff;
- raw_data[2] = min((size_t)20, s);
- if (*off + raw_data[2] > 0xff)
- raw_data[2] = 0x100 - *off;
-
- if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2])))
- return -EFAULT;
- resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data,
- sizeof(raw_data));
-
- if (!resp)
- return -EIO;
-
- if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
- /* check if written data matches */
- if (memcmp(raw_data, resp->raw_data, 3+raw_data[2]) == 0) {
- *off += raw_data[2];
- ret = raw_data[2];
- }
- }
- kfree(resp);
- return ret;
-}
-
-/*
- * Notes:
- * - read/write happens in chunks of at most 20 bytes, it's up to userspace
- * to loop in order to get more data.
- * - on write errors on otherwise correct write request the bytes
- * that should have been written are in undefined state.
- */
-static const struct file_operations picolcd_debug_eeprom_fops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = picolcd_debug_eeprom_read,
- .write = picolcd_debug_eeprom_write,
- .llseek = generic_file_llseek,
-};
-
-/*
- * The "flash" file
- */
-/* record a flash address to buf (bounds check to be done by caller) */
-static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off)
-{
- buf[0] = off & 0xff;
- buf[1] = (off >> 8) & 0xff;
- if (data->addr_sz == 3)
- buf[2] = (off >> 16) & 0xff;
- return data->addr_sz == 2 ? 2 : 3;
-}
-
-/* read a given size of data (bounds check to be done by caller) */
-static ssize_t _picolcd_flash_read(struct picolcd_data *data, int report_id,
- char __user *u, size_t s, loff_t *off)
-{
- struct picolcd_pending *resp;
- u8 raw_data[4];
- ssize_t ret = 0;
- int len_off, err = -EIO;
-
- while (s > 0) {
- err = -EIO;
- len_off = _picolcd_flash_setaddr(data, raw_data, *off);
- raw_data[len_off] = s > 32 ? 32 : s;
- resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off+1);
- if (!resp || !resp->in_report)
- goto skip;
- if (resp->in_report->id == REPORT_MEMORY ||
- resp->in_report->id == REPORT_BL_READ_MEMORY) {
- if (memcmp(raw_data, resp->raw_data, len_off+1) != 0)
- goto skip;
- if (copy_to_user(u+ret, resp->raw_data+len_off+1, raw_data[len_off])) {
- err = -EFAULT;
- goto skip;
- }
- *off += raw_data[len_off];
- s -= raw_data[len_off];
- ret += raw_data[len_off];
- err = 0;
- }
-skip:
- kfree(resp);
- if (err)
- return ret > 0 ? ret : err;
- }
- return ret;
-}
-
-static ssize_t picolcd_debug_flash_read(struct file *f, char __user *u,
- size_t s, loff_t *off)
-{
- struct picolcd_data *data = f->private_data;
-
- if (s == 0)
- return -EINVAL;
- if (*off > 0x05fff)
- return 0;
- if (*off + s > 0x05fff)
- s = 0x06000 - *off;
-
- if (data->status & PICOLCD_BOOTLOADER)
- return _picolcd_flash_read(data, REPORT_BL_READ_MEMORY, u, s, off);
- else
- return _picolcd_flash_read(data, REPORT_READ_MEMORY, u, s, off);
-}
-
-/* erase block aligned to 64bytes boundary */
-static ssize_t _picolcd_flash_erase64(struct picolcd_data *data, int report_id,
- loff_t *off)
-{
- struct picolcd_pending *resp;
- u8 raw_data[3];
- int len_off;
- ssize_t ret = -EIO;
-
- if (*off & 0x3f)
- return -EINVAL;
-
- len_off = _picolcd_flash_setaddr(data, raw_data, *off);
- resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off);
- if (!resp || !resp->in_report)
- goto skip;
- if (resp->in_report->id == REPORT_MEMORY ||
- resp->in_report->id == REPORT_BL_ERASE_MEMORY) {
- if (memcmp(raw_data, resp->raw_data, len_off) != 0)
- goto skip;
- ret = 0;
- }
-skip:
- kfree(resp);
- return ret;
-}
-
-/* write a given size of data (bounds check to be done by caller) */
-static ssize_t _picolcd_flash_write(struct picolcd_data *data, int report_id,
- const char __user *u, size_t s, loff_t *off)
-{
- struct picolcd_pending *resp;
- u8 raw_data[36];
- ssize_t ret = 0;
- int len_off, err = -EIO;
-
- while (s > 0) {
- err = -EIO;
- len_off = _picolcd_flash_setaddr(data, raw_data, *off);
- raw_data[len_off] = s > 32 ? 32 : s;
- if (copy_from_user(raw_data+len_off+1, u, raw_data[len_off])) {
- err = -EFAULT;
- break;
- }
- resp = picolcd_send_and_wait(data->hdev, report_id, raw_data,
- len_off+1+raw_data[len_off]);
- if (!resp || !resp->in_report)
- goto skip;
- if (resp->in_report->id == REPORT_MEMORY ||
- resp->in_report->id == REPORT_BL_WRITE_MEMORY) {
- if (memcmp(raw_data, resp->raw_data, len_off+1+raw_data[len_off]) != 0)
- goto skip;
- *off += raw_data[len_off];
- s -= raw_data[len_off];
- ret += raw_data[len_off];
- err = 0;
- }
-skip:
- kfree(resp);
- if (err)
- break;
- }
- return ret > 0 ? ret : err;
-}
-
-static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u,
- size_t s, loff_t *off)
-{
- struct picolcd_data *data = f->private_data;
- ssize_t err, ret = 0;
- int report_erase, report_write;
-
- if (s == 0)
- return -EINVAL;
- if (*off > 0x5fff)
- return -ENOSPC;
- if (s & 0x3f)
- return -EINVAL;
- if (*off & 0x3f)
- return -EINVAL;
-
- if (data->status & PICOLCD_BOOTLOADER) {
- report_erase = REPORT_BL_ERASE_MEMORY;
- report_write = REPORT_BL_WRITE_MEMORY;
- } else {
- report_erase = REPORT_ERASE_MEMORY;
- report_write = REPORT_WRITE_MEMORY;
- }
- mutex_lock(&data->mutex_flash);
- while (s > 0) {
- err = _picolcd_flash_erase64(data, report_erase, off);
- if (err)
- break;
- err = _picolcd_flash_write(data, report_write, u, 64, off);
- if (err < 0)
- break;
- ret += err;
- *off += err;
- s -= err;
- if (err != 64)
- break;
- }
- mutex_unlock(&data->mutex_flash);
- return ret > 0 ? ret : err;
-}
-
-/*
- * Notes:
- * - concurrent writing is prevented by mutex and all writes must be
- * n*64 bytes and 64-byte aligned, each write being preceded by an
- * ERASE which erases a 64byte block.
- * If less than requested was written or an error is returned for an
- * otherwise correct write request the next 64-byte block which should
- * have been written is in undefined state (mostly: original, erased,
- * (half-)written with write error)
- * - reading can happen without special restriction
- */
-static const struct file_operations picolcd_debug_flash_fops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = picolcd_debug_flash_read,
- .write = picolcd_debug_flash_write,
- .llseek = generic_file_llseek,
-};
-
-
-/*
- * Helper code for HID report level dumping/debugging
- */
-static const char *error_codes[] = {
- "success", "parameter missing", "data_missing", "block readonly",
- "block not erasable", "block too big", "section overflow",
- "invalid command length", "invalid data length",
-};
-
-static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data,
- const size_t data_len)
-{
- int i, j;
- for (i = j = 0; i < data_len && j + 3 < dst_sz; i++) {
- dst[j++] = hex_asc[(data[i] >> 4) & 0x0f];
- dst[j++] = hex_asc[data[i] & 0x0f];
- dst[j++] = ' ';
- }
- if (j < dst_sz) {
- dst[j--] = '\0';
- dst[j] = '\n';
- } else
- dst[j] = '\0';
-}
-
-static void picolcd_debug_out_report(struct picolcd_data *data,
- struct hid_device *hdev, struct hid_report *report)
-{
- u8 raw_data[70];
- int raw_size = (report->size >> 3) + 1;
- char *buff;
-#define BUFF_SZ 256
-
- /* Avoid unnecessary overhead if debugfs is disabled */
- if (!hdev->debug_events)
- return;
-
- buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
- if (!buff)
- return;
-
- snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ",
- report->id, raw_size);
- hid_debug_event(hdev, buff);
- if (raw_size + 5 > sizeof(raw_data)) {
- kfree(buff);
- hid_debug_event(hdev, " TOO BIG\n");
- return;
- } else {
- raw_data[0] = report->id;
- hid_output_report(report, raw_data);
- dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
- hid_debug_event(hdev, buff);
- }
-
- switch (report->id) {
- case REPORT_LED_STATE:
- /* 1 data byte with GPO state */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_LED_STATE", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_BRIGHTNESS:
- /* 1 data byte with brightness */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_BRIGHTNESS", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_CONTRAST:
- /* 1 data byte with contrast */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_CONTRAST", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_RESET:
- /* 2 data bytes with reset duration in ms */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_RESET", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n",
- raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_LCD_CMD:
- /* 63 data bytes with LCD commands */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_LCD_CMD", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- /* TODO: format decoding */
- break;
- case REPORT_LCD_DATA:
- /* 63 data bytes with LCD data */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_LCD_CMD", report->id, raw_size-1);
- /* TODO: format decoding */
- hid_debug_event(hdev, buff);
- break;
- case REPORT_LCD_CMD_DATA:
- /* 63 data bytes with LCD commands and data */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_LCD_CMD", report->id, raw_size-1);
- /* TODO: format decoding */
- hid_debug_event(hdev, buff);
- break;
- case REPORT_EE_READ:
- /* 3 data bytes with read area description */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_EE_READ", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_EE_WRITE:
- /* 3+1..20 data bytes with write area description */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_EE_WRITE", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
- hid_debug_event(hdev, buff);
- if (raw_data[3] == 0) {
- snprintf(buff, BUFF_SZ, "\tNo data\n");
- } else if (raw_data[3] + 4 <= raw_size) {
- snprintf(buff, BUFF_SZ, "\tData: ");
- hid_debug_event(hdev, buff);
- dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
- } else {
- snprintf(buff, BUFF_SZ, "\tData overflowed\n");
- }
- hid_debug_event(hdev, buff);
- break;
- case REPORT_ERASE_MEMORY:
- case REPORT_BL_ERASE_MEMORY:
- /* 3 data bytes with pointer inside erase block */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_ERASE_MEMORY", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- switch (data->addr_sz) {
- case 2:
- snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n",
- raw_data[2], raw_data[1]);
- break;
- case 3:
- snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n",
- raw_data[3], raw_data[2], raw_data[1]);
- break;
- default:
- snprintf(buff, BUFF_SZ, "\tNot supported\n");
- }
- hid_debug_event(hdev, buff);
- break;
- case REPORT_READ_MEMORY:
- case REPORT_BL_READ_MEMORY:
- /* 4 data bytes with read area description */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_READ_MEMORY", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- switch (data->addr_sz) {
- case 2:
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
- break;
- case 3:
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
- raw_data[3], raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
- break;
- default:
- snprintf(buff, BUFF_SZ, "\tNot supported\n");
- }
- hid_debug_event(hdev, buff);
- break;
- case REPORT_WRITE_MEMORY:
- case REPORT_BL_WRITE_MEMORY:
- /* 4+1..32 data bytes with write adrea description */
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_WRITE_MEMORY", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- switch (data->addr_sz) {
- case 2:
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
- hid_debug_event(hdev, buff);
- if (raw_data[3] == 0) {
- snprintf(buff, BUFF_SZ, "\tNo data\n");
- } else if (raw_data[3] + 4 <= raw_size) {
- snprintf(buff, BUFF_SZ, "\tData: ");
- hid_debug_event(hdev, buff);
- dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
- } else {
- snprintf(buff, BUFF_SZ, "\tData overflowed\n");
- }
- break;
- case 3:
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
- raw_data[3], raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
- hid_debug_event(hdev, buff);
- if (raw_data[4] == 0) {
- snprintf(buff, BUFF_SZ, "\tNo data\n");
- } else if (raw_data[4] + 5 <= raw_size) {
- snprintf(buff, BUFF_SZ, "\tData: ");
- hid_debug_event(hdev, buff);
- dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
- } else {
- snprintf(buff, BUFF_SZ, "\tData overflowed\n");
- }
- break;
- default:
- snprintf(buff, BUFF_SZ, "\tNot supported\n");
- }
- hid_debug_event(hdev, buff);
- break;
- case REPORT_SPLASH_RESTART:
- /* TODO */
- break;
- case REPORT_EXIT_KEYBOARD:
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_EXIT_KEYBOARD", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
- raw_data[1] | (raw_data[2] << 8),
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_VERSION:
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_VERSION", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_DEVID:
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_DEVID", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_SPLASH_SIZE:
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_SPLASH_SIZE", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_HOOK_VERSION:
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_HOOK_VERSION", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_EXIT_FLASHER:
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "REPORT_VERSION", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
- raw_data[1] | (raw_data[2] << 8),
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- break;
- default:
- snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
- "<unknown>", report->id, raw_size-1);
- hid_debug_event(hdev, buff);
- break;
- }
- wake_up_interruptible(&hdev->debug_wait);
- kfree(buff);
-}
-
-static void picolcd_debug_raw_event(struct picolcd_data *data,
- struct hid_device *hdev, struct hid_report *report,
- u8 *raw_data, int size)
-{
- char *buff;
-
-#define BUFF_SZ 256
- /* Avoid unnecessary overhead if debugfs is disabled */
- if (!hdev->debug_events)
- return;
-
- buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
- if (!buff)
- return;
-
- switch (report->id) {
- case REPORT_ERROR_CODE:
- /* 2 data bytes with affected report and error code */
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_ERROR_CODE", report->id, size-1);
- hid_debug_event(hdev, buff);
- if (raw_data[2] < ARRAY_SIZE(error_codes))
- snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
- raw_data[2], error_codes[raw_data[2]], raw_data[1]);
- else
- snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_KEY_STATE:
- /* 2 data bytes with key state */
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_KEY_STATE", report->id, size-1);
- hid_debug_event(hdev, buff);
- if (raw_data[1] == 0)
- snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
- else if (raw_data[2] == 0)
- snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
- raw_data[1], raw_data[1]);
- else
- snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
- raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_IR_DATA:
- /* Up to 20 byes of IR scancode data */
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_IR_DATA", report->id, size-1);
- hid_debug_event(hdev, buff);
- if (raw_data[1] == 0) {
- snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
- hid_debug_event(hdev, buff);
- } else if (raw_data[1] + 1 <= size) {
- snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
- raw_data[1]-1);
- hid_debug_event(hdev, buff);
- dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]-1);
- hid_debug_event(hdev, buff);
- } else {
- snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
- raw_data[1]-1);
- hid_debug_event(hdev, buff);
- }
- break;
- case REPORT_EE_DATA:
- /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_EE_DATA", report->id, size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
- hid_debug_event(hdev, buff);
- if (raw_data[3] == 0) {
- snprintf(buff, BUFF_SZ, "\tNo data\n");
- hid_debug_event(hdev, buff);
- } else if (raw_data[3] + 4 <= size) {
- snprintf(buff, BUFF_SZ, "\tData: ");
- hid_debug_event(hdev, buff);
- dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
- hid_debug_event(hdev, buff);
- } else {
- snprintf(buff, BUFF_SZ, "\tData overflowed\n");
- hid_debug_event(hdev, buff);
- }
- break;
- case REPORT_MEMORY:
- /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRTIE_MEMORY */
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_MEMORY", report->id, size-1);
- hid_debug_event(hdev, buff);
- switch (data->addr_sz) {
- case 2:
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
- hid_debug_event(hdev, buff);
- if (raw_data[3] == 0) {
- snprintf(buff, BUFF_SZ, "\tNo data\n");
- } else if (raw_data[3] + 4 <= size) {
- snprintf(buff, BUFF_SZ, "\tData: ");
- hid_debug_event(hdev, buff);
- dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
- } else {
- snprintf(buff, BUFF_SZ, "\tData overflowed\n");
- }
- break;
- case 3:
- snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
- raw_data[3], raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
- hid_debug_event(hdev, buff);
- if (raw_data[4] == 0) {
- snprintf(buff, BUFF_SZ, "\tNo data\n");
- } else if (raw_data[4] + 5 <= size) {
- snprintf(buff, BUFF_SZ, "\tData: ");
- hid_debug_event(hdev, buff);
- dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
- } else {
- snprintf(buff, BUFF_SZ, "\tData overflowed\n");
- }
- break;
- default:
- snprintf(buff, BUFF_SZ, "\tNot supported\n");
- }
- hid_debug_event(hdev, buff);
- break;
- case REPORT_VERSION:
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_VERSION", report->id, size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
- raw_data[2], raw_data[1]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_BL_ERASE_MEMORY:
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_BL_ERASE_MEMORY", report->id, size-1);
- hid_debug_event(hdev, buff);
- /* TODO */
- break;
- case REPORT_BL_READ_MEMORY:
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_BL_READ_MEMORY", report->id, size-1);
- hid_debug_event(hdev, buff);
- /* TODO */
- break;
- case REPORT_BL_WRITE_MEMORY:
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_BL_WRITE_MEMORY", report->id, size-1);
- hid_debug_event(hdev, buff);
- /* TODO */
- break;
- case REPORT_DEVID:
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_DEVID", report->id, size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
- raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
- raw_data[5]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_SPLASH_SIZE:
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_SPLASH_SIZE", report->id, size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
- (raw_data[2] << 8) | raw_data[1]);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
- (raw_data[4] << 8) | raw_data[3]);
- hid_debug_event(hdev, buff);
- break;
- case REPORT_HOOK_VERSION:
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "REPORT_HOOK_VERSION", report->id, size-1);
- hid_debug_event(hdev, buff);
- snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
- raw_data[1], raw_data[2]);
- hid_debug_event(hdev, buff);
- break;
- default:
- snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
- "<unknown>", report->id, size-1);
- hid_debug_event(hdev, buff);
- break;
- }
- wake_up_interruptible(&hdev->debug_wait);
- kfree(buff);
-}
-
-static void picolcd_init_devfs(struct picolcd_data *data,
- struct hid_report *eeprom_r, struct hid_report *eeprom_w,
- struct hid_report *flash_r, struct hid_report *flash_w,
- struct hid_report *reset)
-{
- struct hid_device *hdev = data->hdev;
-
- mutex_init(&data->mutex_flash);
-
- /* reset */
- if (reset)
- data->debug_reset = debugfs_create_file("reset", 0600,
- hdev->debug_dir, data, &picolcd_debug_reset_fops);
-
- /* eeprom */
- if (eeprom_r || eeprom_w)
- data->debug_eeprom = debugfs_create_file("eeprom",
- (eeprom_w ? S_IWUSR : 0) | (eeprom_r ? S_IRUSR : 0),
- hdev->debug_dir, data, &picolcd_debug_eeprom_fops);
-
- /* flash */
- if (flash_r && flash_r->maxfield == 1 && flash_r->field[0]->report_size == 8)
- data->addr_sz = flash_r->field[0]->report_count - 1;
- else
- data->addr_sz = -1;
- if (data->addr_sz == 2 || data->addr_sz == 3) {
- data->debug_flash = debugfs_create_file("flash",
- (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0),
- hdev->debug_dir, data, &picolcd_debug_flash_fops);
- } else if (flash_r || flash_w)
- hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n");
-}
-
-static void picolcd_exit_devfs(struct picolcd_data *data)
-{
- struct dentry *dent;
-
- dent = data->debug_reset;
- data->debug_reset = NULL;
- if (dent)
- debugfs_remove(dent);
- dent = data->debug_eeprom;
- data->debug_eeprom = NULL;
- if (dent)
- debugfs_remove(dent);
- dent = data->debug_flash;
- data->debug_flash = NULL;
- if (dent)
- debugfs_remove(dent);
- mutex_destroy(&data->mutex_flash);
-}
-#else
-static inline void picolcd_debug_raw_event(struct picolcd_data *data,
- struct hid_device *hdev, struct hid_report *report,
- u8 *raw_data, int size)
-{
-}
-static inline void picolcd_init_devfs(struct picolcd_data *data,
- struct hid_report *eeprom_r, struct hid_report *eeprom_w,
- struct hid_report *flash_r, struct hid_report *flash_w,
- struct hid_report *reset)
-{
-}
-static inline void picolcd_exit_devfs(struct picolcd_data *data)
-{
-}
-#endif /* CONFIG_DEBUG_FS */
-
-/*
- * Handle raw report as sent by device
- */
-static int picolcd_raw_event(struct hid_device *hdev,
- struct hid_report *report, u8 *raw_data, int size)
-{
- struct picolcd_data *data = hid_get_drvdata(hdev);
- unsigned long flags;
- int ret = 0;
-
- if (!data)
- return 1;
-
- if (report->id == REPORT_KEY_STATE) {
- if (data->input_keys)
- ret = picolcd_raw_keypad(data, report, raw_data+1, size-1);
- } else if (report->id == REPORT_IR_DATA) {
- if (data->input_cir)
- ret = picolcd_raw_cir(data, report, raw_data+1, size-1);
- } else {
- spin_lock_irqsave(&data->lock, flags);
- /*
- * We let the caller of picolcd_send_and_wait() check if the
- * report we got is one of the expected ones or not.
- */
- if (data->pending) {
- memcpy(data->pending->raw_data, raw_data+1, size-1);
- data->pending->raw_size = size-1;
- data->pending->in_report = report;
- complete(&data->pending->ready);
- }
- spin_unlock_irqrestore(&data->lock, flags);
- }
-
- picolcd_debug_raw_event(data, hdev, report, raw_data, size);
- return 1;
-}
-
-#ifdef CONFIG_PM
-static int picolcd_suspend(struct hid_device *hdev, pm_message_t message)
-{
- if (PMSG_IS_AUTO(message))
- return 0;
-
- picolcd_suspend_backlight(hid_get_drvdata(hdev));
- dbg_hid(PICOLCD_NAME " device ready for suspend\n");
- return 0;
-}
-
-static int picolcd_resume(struct hid_device *hdev)
-{
- int ret;
- ret = picolcd_resume_backlight(hid_get_drvdata(hdev));
- if (ret)
- dbg_hid(PICOLCD_NAME " restoring backlight failed: %d\n", ret);
- return 0;
-}
-
-static int picolcd_reset_resume(struct hid_device *hdev)
-{
- int ret;
- ret = picolcd_reset(hdev);
- if (ret)
- dbg_hid(PICOLCD_NAME " resetting our device failed: %d\n", ret);
- ret = picolcd_fb_reset(hid_get_drvdata(hdev), 0);
- if (ret)
- dbg_hid(PICOLCD_NAME " restoring framebuffer content failed: %d\n", ret);
- ret = picolcd_resume_lcd(hid_get_drvdata(hdev));
- if (ret)
- dbg_hid(PICOLCD_NAME " restoring lcd failed: %d\n", ret);
- ret = picolcd_resume_backlight(hid_get_drvdata(hdev));
- if (ret)
- dbg_hid(PICOLCD_NAME " restoring backlight failed: %d\n", ret);
- picolcd_leds_set(hid_get_drvdata(hdev));
- return 0;
-}
-#endif
-
-/* initialize keypad input device */
-static int picolcd_init_keys(struct picolcd_data *data,
- struct hid_report *report)
-{
- struct hid_device *hdev = data->hdev;
- struct input_dev *idev;
- int error, i;
-
- if (!report)
- return -ENODEV;
- if (report->maxfield != 1 || report->field[0]->report_count != 2 ||
- report->field[0]->report_size != 8) {
- hid_err(hdev, "unsupported KEY_STATE report\n");
- return -EINVAL;
- }
-
- idev = input_allocate_device();
- if (idev == NULL) {
- hid_err(hdev, "failed to allocate input device\n");
- return -ENOMEM;
- }
- input_set_drvdata(idev, hdev);
- memcpy(data->keycode, def_keymap, sizeof(def_keymap));
- idev->name = hdev->name;
- idev->phys = hdev->phys;
- idev->uniq = hdev->uniq;
- idev->id.bustype = hdev->bus;
- idev->id.vendor = hdev->vendor;
- idev->id.product = hdev->product;
- idev->id.version = hdev->version;
- idev->dev.parent = hdev->dev.parent;
- idev->keycode = &data->keycode;
- idev->keycodemax = PICOLCD_KEYS;
- idev->keycodesize = sizeof(data->keycode[0]);
- input_set_capability(idev, EV_MSC, MSC_SCAN);
- set_bit(EV_REP, idev->evbit);
- for (i = 0; i < PICOLCD_KEYS; i++)
- input_set_capability(idev, EV_KEY, data->keycode[i]);
- error = input_register_device(idev);
- if (error) {
- hid_err(hdev, "error registering the input device\n");
- input_free_device(idev);
- return error;
- }
- data->input_keys = idev;
- return 0;
-}
-
-static void picolcd_exit_keys(struct picolcd_data *data)
-{
- struct input_dev *idev = data->input_keys;
-
- data->input_keys = NULL;
- if (idev)
- input_unregister_device(idev);
-}
-
-/* initialize CIR input device */
-static inline int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
-{
- /* support not implemented yet */
- return 0;
-}
-
-static inline void picolcd_exit_cir(struct picolcd_data *data)
-{
-}
-
-static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data)
-{
- int error;
-
- error = picolcd_check_version(hdev);
- if (error)
- return error;
-
- if (data->version[0] != 0 && data->version[1] != 3)
- hid_info(hdev, "Device with untested firmware revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
- dev_name(&hdev->dev));
-
- /* Setup keypad input device */
- error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev));
- if (error)
- goto err;
-
- /* Setup CIR input device */
- error = picolcd_init_cir(data, picolcd_in_report(REPORT_IR_DATA, hdev));
- if (error)
- goto err;
-
- /* Set up the framebuffer device */
- error = picolcd_init_framebuffer(data);
- if (error)
- goto err;
-
- /* Setup lcd class device */
- error = picolcd_init_lcd(data, picolcd_out_report(REPORT_CONTRAST, hdev));
- if (error)
- goto err;
-
- /* Setup backlight class device */
- error = picolcd_init_backlight(data, picolcd_out_report(REPORT_BRIGHTNESS, hdev));
- if (error)
- goto err;
-
- /* Setup the LED class devices */
- error = picolcd_init_leds(data, picolcd_out_report(REPORT_LED_STATE, hdev));
- if (error)
- goto err;
-
- picolcd_init_devfs(data, picolcd_out_report(REPORT_EE_READ, hdev),
- picolcd_out_report(REPORT_EE_WRITE, hdev),
- picolcd_out_report(REPORT_READ_MEMORY, hdev),
- picolcd_out_report(REPORT_WRITE_MEMORY, hdev),
- picolcd_out_report(REPORT_RESET, hdev));
- return 0;
-err:
- picolcd_exit_leds(data);
- picolcd_exit_backlight(data);
- picolcd_exit_lcd(data);
- picolcd_exit_framebuffer(data);
- picolcd_exit_cir(data);
- picolcd_exit_keys(data);
- return error;
-}
-
-static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data *data)
-{
- int error;
-
- error = picolcd_check_version(hdev);
- if (error)
- return error;
-
- if (data->version[0] != 1 && data->version[1] != 0)
- hid_info(hdev, "Device with untested bootloader revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n",
- dev_name(&hdev->dev));
-
- picolcd_init_devfs(data, NULL, NULL,
- picolcd_out_report(REPORT_BL_READ_MEMORY, hdev),
- picolcd_out_report(REPORT_BL_WRITE_MEMORY, hdev), NULL);
- return 0;
-}
-
-static int picolcd_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- struct picolcd_data *data;
- int error = -ENOMEM;
-
- dbg_hid(PICOLCD_NAME " hardware probe...\n");
-
- /*
- * Let's allocate the picolcd data structure, set some reasonable
- * defaults, and associate it with the device
- */
- data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL);
- if (data == NULL) {
- hid_err(hdev, "can't allocate space for Minibox PicoLCD device data\n");
- error = -ENOMEM;
- goto err_no_cleanup;
- }
-
- spin_lock_init(&data->lock);
- mutex_init(&data->mutex);
- data->hdev = hdev;
- data->opmode_delay = 5000;
- if (hdev->product == USB_DEVICE_ID_PICOLCD_BOOTLOADER)
- data->status |= PICOLCD_BOOTLOADER;
- hid_set_drvdata(hdev, data);
-
- /* Parse the device reports and start it up */
- error = hid_parse(hdev);
- if (error) {
- hid_err(hdev, "device report parse failed\n");
- goto err_cleanup_data;
- }
-
- /* We don't use hidinput but hid_hw_start() fails if nothing is
- * claimed. So spoof claimed input. */
- hdev->claimed = HID_CLAIMED_INPUT;
- error = hid_hw_start(hdev, 0);
- hdev->claimed = 0;
- if (error) {
- hid_err(hdev, "hardware start failed\n");
- goto err_cleanup_data;
- }
-
- error = hid_hw_open(hdev);
- if (error) {
- hid_err(hdev, "failed to open input interrupt pipe for key and IR events\n");
- goto err_cleanup_hid_hw;
- }
-
- error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay);
- if (error) {
- hid_err(hdev, "failed to create sysfs attributes\n");
- goto err_cleanup_hid_ll;
- }
-
- error = device_create_file(&hdev->dev, &dev_attr_operation_mode);
- if (error) {
- hid_err(hdev, "failed to create sysfs attributes\n");
- goto err_cleanup_sysfs1;
- }
-
- if (data->status & PICOLCD_BOOTLOADER)
- error = picolcd_probe_bootloader(hdev, data);
- else
- error = picolcd_probe_lcd(hdev, data);
- if (error)
- goto err_cleanup_sysfs2;
-
- dbg_hid(PICOLCD_NAME " activated and initialized\n");
- return 0;
-
-err_cleanup_sysfs2:
- device_remove_file(&hdev->dev, &dev_attr_operation_mode);
-err_cleanup_sysfs1:
- device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
-err_cleanup_hid_ll:
- hid_hw_close(hdev);
-err_cleanup_hid_hw:
- hid_hw_stop(hdev);
-err_cleanup_data:
- kfree(data);
-err_no_cleanup:
- hid_set_drvdata(hdev, NULL);
-
- return error;
-}
-
-static void picolcd_remove(struct hid_device *hdev)
-{
- struct picolcd_data *data = hid_get_drvdata(hdev);
- unsigned long flags;
-
- dbg_hid(PICOLCD_NAME " hardware remove...\n");
- spin_lock_irqsave(&data->lock, flags);
- data->status |= PICOLCD_FAILED;
- spin_unlock_irqrestore(&data->lock, flags);
-#ifdef CONFIG_HID_PICOLCD_FB
- /* short-circuit FB as early as possible in order to
- * avoid long delays if we host console.
- */
- if (data->fb_info)
- data->fb_info->par = NULL;
-#endif
-
- picolcd_exit_devfs(data);
- device_remove_file(&hdev->dev, &dev_attr_operation_mode);
- device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
- hid_hw_close(hdev);
- hid_hw_stop(hdev);
- hid_set_drvdata(hdev, NULL);
-
- /* Shortcut potential pending reply that will never arrive */
- spin_lock_irqsave(&data->lock, flags);
- if (data->pending)
- complete(&data->pending->ready);
- spin_unlock_irqrestore(&data->lock, flags);
-
- /* Cleanup LED */
- picolcd_exit_leds(data);
- /* Clean up the framebuffer */
- picolcd_exit_backlight(data);
- picolcd_exit_lcd(data);
- picolcd_exit_framebuffer(data);
- /* Cleanup input */
- picolcd_exit_cir(data);
- picolcd_exit_keys(data);
-
- mutex_destroy(&data->mutex);
- /* Finally, clean up the picolcd data itself */
- kfree(data);
-}
-
-static const struct hid_device_id picolcd_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, picolcd_devices);
-
-static struct hid_driver picolcd_driver = {
- .name = "hid-picolcd",
- .id_table = picolcd_devices,
- .probe = picolcd_probe,
- .remove = picolcd_remove,
- .raw_event = picolcd_raw_event,
-#ifdef CONFIG_PM
- .suspend = picolcd_suspend,
- .resume = picolcd_resume,
- .reset_resume = picolcd_reset_resume,
-#endif
-};
-
-static int __init picolcd_init(void)
-{
- return hid_register_driver(&picolcd_driver);
-}
-
-static void __exit picolcd_exit(void)
-{
- hid_unregister_driver(&picolcd_driver);
-#ifdef CONFIG_HID_PICOLCD_FB
- flush_work_sync(&picolcd_fb_cleanup);
- WARN_ON(fb_pending);
-#endif
-}
-
-module_init(picolcd_init);
-module_exit(picolcd_exit);
-MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-pl.c b/ANDROID_3.4.5/drivers/hid/hid-pl.c
deleted file mode 100644
index 47ed74c4..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-pl.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Force feedback support for PantherLord/GreenAsia based devices
- *
- * The devices are distributed under various names and the same USB device ID
- * can be used in both adapters and actual game controllers.
- *
- * 0810:0001 "Twin USB Joystick"
- * - tested with PantherLord USB/PS2 2in1 Adapter
- * - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
- *
- * 0e8f:0003 "GreenAsia Inc. USB Joystick "
- * - tested with König Gaming gamepad
- *
- * 0e8f:0003 "GASIA USB Gamepad"
- * - another version of the König gamepad
- *
- * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-/* #define DEBUG */
-
-#define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-
-#include "hid-ids.h"
-
-#ifdef CONFIG_PANTHERLORD_FF
-#include "usbhid/usbhid.h"
-
-struct plff_device {
- struct hid_report *report;
- s32 *strong;
- s32 *weak;
-};
-
-static int hid_plff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct plff_device *plff = data;
- int left, right;
-
- left = effect->u.rumble.strong_magnitude;
- right = effect->u.rumble.weak_magnitude;
- debug("called with 0x%04x 0x%04x", left, right);
-
- left = left * 0x7f / 0xffff;
- right = right * 0x7f / 0xffff;
-
- *plff->strong = left;
- *plff->weak = right;
- debug("running with 0x%02x 0x%02x", left, right);
- usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int plff_init(struct hid_device *hid)
-{
- struct plff_device *plff;
- struct hid_report *report;
- struct hid_input *hidinput;
- struct list_head *report_list =
- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct list_head *report_ptr = report_list;
- struct input_dev *dev;
- int error;
- s32 *strong;
- s32 *weak;
-
- /* The device contains one output report per physical device, all
- containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
- absolute values.
-
- The input reports also contain a field which contains
- 8 ff00.0001 usages and 8 boolean values. Their meaning is
- currently unknown.
-
- A version of the 0e8f:0003 exists that has all the values in
- separate fields and misses the extra input field, thus resembling
- Zeroplus (hid-zpff) devices.
- */
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output reports found\n");
- return -ENODEV;
- }
-
- list_for_each_entry(hidinput, &hid->inputs, list) {
-
- report_ptr = report_ptr->next;
-
- if (report_ptr == report_list) {
- hid_err(hid, "required output report is missing\n");
- return -ENODEV;
- }
-
- report = list_entry(report_ptr, struct hid_report, list);
- if (report->maxfield < 1) {
- hid_err(hid, "no fields in the report\n");
- return -ENODEV;
- }
-
- if (report->field[0]->report_count >= 4) {
- report->field[0]->value[0] = 0x00;
- report->field[0]->value[1] = 0x00;
- strong = &report->field[0]->value[2];
- weak = &report->field[0]->value[3];
- debug("detected single-field device");
- } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
- report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
- report->field[0]->value[0] = 0x00;
- report->field[1]->value[0] = 0x00;
- strong = &report->field[2]->value[0];
- weak = &report->field[3]->value[0];
- debug("detected 4-field device");
- } else {
- hid_err(hid, "not enough fields or values\n");
- return -ENODEV;
- }
-
- plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL);
- if (!plff)
- return -ENOMEM;
-
- dev = hidinput->input;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- error = input_ff_create_memless(dev, plff, hid_plff_play);
- if (error) {
- kfree(plff);
- return error;
- }
-
- plff->report = report;
- plff->strong = strong;
- plff->weak = weak;
-
- *strong = 0x00;
- *weak = 0x00;
- usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
- }
-
- hid_info(hid, "Force feedback for PantherLord/GreenAsia devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
-
- return 0;
-}
-#else
-static inline int plff_init(struct hid_device *hid)
-{
- return 0;
-}
-#endif
-
-static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- if (id->driver_data)
- hdev->quirks |= HID_QUIRK_MULTI_INPUT;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- plff_init(hdev);
-
- return 0;
-err:
- return ret;
-}
-
-static const struct hid_device_id pl_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR),
- .driver_data = 1 }, /* Twin USB Joystick */
- { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR),
- .driver_data = 1 }, /* Twin USB Joystick */
- { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), },
- { }
-};
-MODULE_DEVICE_TABLE(hid, pl_devices);
-
-static struct hid_driver pl_driver = {
- .name = "pantherlord",
- .id_table = pl_devices,
- .probe = pl_probe,
-};
-
-static int __init pl_init(void)
-{
- return hid_register_driver(&pl_driver);
-}
-
-static void __exit pl_exit(void)
-{
- hid_unregister_driver(&pl_driver);
-}
-
-module_init(pl_init);
-module_exit(pl_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-primax.c b/ANDROID_3.4.5/drivers/hid/hid-primax.c
deleted file mode 100644
index 4d3c60d8..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-primax.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * HID driver for primax and similar keyboards with in-band modifiers
- *
- * Copyright 2011 Google Inc. All Rights Reserved
- *
- * Author:
- * Terry Lambert <tlambert@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-static int px_raw_event(struct hid_device *hid, struct hid_report *report,
- u8 *data, int size)
-{
- int idx = size;
-
- switch (report->id) {
- case 0: /* keyboard input */
- /*
- * Convert in-band modifier key values into out of band
- * modifier bits and pull the key strokes from the report.
- * Thus a report data set which looked like:
- *
- * [00][00][E0][30][00][00][00][00]
- * (no modifier bits + "Left Shift" key + "1" key)
- *
- * Would be converted to:
- *
- * [01][00][00][30][00][00][00][00]
- * (Left Shift modifier bit + "1" key)
- *
- * As long as it's in the size range, the upper level
- * drivers don't particularly care if there are in-band
- * 0-valued keys, so they don't stop parsing.
- */
- while (--idx > 1) {
- if (data[idx] < 0xE0 || data[idx] > 0xE7)
- continue;
- data[0] |= (1 << (data[idx] - 0xE0));
- data[idx] = 0;
- }
- hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, 0);
- return 1;
-
- default: /* unknown report */
- /* Unknown report type; pass upstream */
- hid_info(hid, "unknown report type %d\n", report->id);
- break;
- }
-
- return 0;
-}
-
-static int px_probe(struct hid_device *hid, const struct hid_device_id *id)
-{
- int ret;
-
- ret = hid_parse(hid);
- if (ret) {
- hid_err(hid, "parse failed\n");
- goto fail;
- }
-
- ret = hid_hw_start(hid, HID_CONNECT_DEFAULT);
- if (ret)
- hid_err(hid, "hw start failed\n");
-
-fail:
- return ret;
-}
-
-static void px_remove(struct hid_device *hid)
-{
- hid_hw_stop(hid);
-}
-
-static const struct hid_device_id px_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, px_devices);
-
-static struct hid_driver px_driver = {
- .name = "primax",
- .id_table = px_devices,
- .raw_event = px_raw_event,
- .probe = px_probe,
- .remove = px_remove,
-};
-
-static int __init px_init(void)
-{
- return hid_register_driver(&px_driver);
-}
-
-static void __exit px_exit(void)
-{
- hid_unregister_driver(&px_driver);
-}
-
-module_init(px_init);
-module_exit(px_exit);
-MODULE_AUTHOR("Terry Lambert <tlambert@google.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-prodikeys.c b/ANDROID_3.4.5/drivers/hid/hid-prodikeys.c
deleted file mode 100644
index b71b77ab..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-prodikeys.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/*
- * HID driver for the Prodikeys PC-MIDI Keyboard
- * providing midi & extra multimedia keys functionality
- *
- * Copyright (c) 2009 Don Prince <dhprince.devel@yahoo.co.uk>
- *
- * Controls for Octave Shift Up/Down, Channel, and
- * Sustain Duration available via sysfs.
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
-#include <linux/hid.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include "usbhid/usbhid.h"
-#include "hid-ids.h"
-
-
-#define pk_debug(format, arg...) \
- pr_debug("hid-prodikeys: " format "\n" , ## arg)
-#define pk_error(format, arg...) \
- pr_err("hid-prodikeys: " format "\n" , ## arg)
-
-struct pcmidi_snd;
-
-struct pk_device {
- unsigned long quirks;
-
- struct hid_device *hdev;
- struct pcmidi_snd *pm; /* pcmidi device context */
-};
-
-struct pcmidi_sustain {
- unsigned long in_use;
- struct pcmidi_snd *pm;
- struct timer_list timer;
- unsigned char status;
- unsigned char note;
- unsigned char velocity;
-};
-
-#define PCMIDI_SUSTAINED_MAX 32
-struct pcmidi_snd {
- struct pk_device *pk;
- unsigned short ifnum;
- struct hid_report *pcmidi_report6;
- struct input_dev *input_ep82;
- unsigned short midi_mode;
- unsigned short midi_sustain_mode;
- unsigned short midi_sustain;
- unsigned short midi_channel;
- short midi_octave;
- struct pcmidi_sustain sustained_notes[PCMIDI_SUSTAINED_MAX];
- unsigned short fn_state;
- unsigned short last_key[24];
- spinlock_t rawmidi_in_lock;
- struct snd_card *card;
- struct snd_rawmidi *rwmidi;
- struct snd_rawmidi_substream *in_substream;
- struct snd_rawmidi_substream *out_substream;
- unsigned long in_triggered;
- unsigned long out_active;
-};
-
-#define PK_QUIRK_NOGET 0x00010000
-#define PCMIDI_MIDDLE_C 60
-#define PCMIDI_CHANNEL_MIN 0
-#define PCMIDI_CHANNEL_MAX 15
-#define PCMIDI_OCTAVE_MIN (-2)
-#define PCMIDI_OCTAVE_MAX 2
-#define PCMIDI_SUSTAIN_MIN 0
-#define PCMIDI_SUSTAIN_MAX 5000
-
-static const char shortname[] = "PC-MIDI";
-static const char longname[] = "Prodikeys PC-MIDI Keyboard";
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-module_param_array(id, charp, NULL, 0444);
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the PC-MIDI virtual audio driver");
-MODULE_PARM_DESC(id, "ID string for the PC-MIDI virtual audio driver");
-MODULE_PARM_DESC(enable, "Enable for the PC-MIDI virtual audio driver");
-
-
-/* Output routine for the sysfs channel file */
-static ssize_t show_channel(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
-
- dbg_hid("pcmidi sysfs read channel=%u\n", pk->pm->midi_channel);
-
- return sprintf(buf, "%u (min:%u, max:%u)\n", pk->pm->midi_channel,
- PCMIDI_CHANNEL_MIN, PCMIDI_CHANNEL_MAX);
-}
-
-/* Input routine for the sysfs channel file */
-static ssize_t store_channel(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
-
- unsigned channel = 0;
-
- if (sscanf(buf, "%u", &channel) > 0 && channel <= PCMIDI_CHANNEL_MAX) {
- dbg_hid("pcmidi sysfs write channel=%u\n", channel);
- pk->pm->midi_channel = channel;
- return strlen(buf);
- }
- return -EINVAL;
-}
-
-static DEVICE_ATTR(channel, S_IRUGO | S_IWUSR | S_IWGRP , show_channel,
- store_channel);
-
-static struct device_attribute *sysfs_device_attr_channel = {
- &dev_attr_channel,
- };
-
-/* Output routine for the sysfs sustain file */
-static ssize_t show_sustain(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
-
- dbg_hid("pcmidi sysfs read sustain=%u\n", pk->pm->midi_sustain);
-
- return sprintf(buf, "%u (off:%u, max:%u (ms))\n", pk->pm->midi_sustain,
- PCMIDI_SUSTAIN_MIN, PCMIDI_SUSTAIN_MAX);
-}
-
-/* Input routine for the sysfs sustain file */
-static ssize_t store_sustain(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
-
- unsigned sustain = 0;
-
- if (sscanf(buf, "%u", &sustain) > 0 && sustain <= PCMIDI_SUSTAIN_MAX) {
- dbg_hid("pcmidi sysfs write sustain=%u\n", sustain);
- pk->pm->midi_sustain = sustain;
- pk->pm->midi_sustain_mode =
- (0 == sustain || !pk->pm->midi_mode) ? 0 : 1;
- return strlen(buf);
- }
- return -EINVAL;
-}
-
-static DEVICE_ATTR(sustain, S_IRUGO | S_IWUSR | S_IWGRP, show_sustain,
- store_sustain);
-
-static struct device_attribute *sysfs_device_attr_sustain = {
- &dev_attr_sustain,
- };
-
-/* Output routine for the sysfs octave file */
-static ssize_t show_octave(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
-
- dbg_hid("pcmidi sysfs read octave=%d\n", pk->pm->midi_octave);
-
- return sprintf(buf, "%d (min:%d, max:%d)\n", pk->pm->midi_octave,
- PCMIDI_OCTAVE_MIN, PCMIDI_OCTAVE_MAX);
-}
-
-/* Input routine for the sysfs octave file */
-static ssize_t store_octave(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
-
- int octave = 0;
-
- if (sscanf(buf, "%d", &octave) > 0 &&
- octave >= PCMIDI_OCTAVE_MIN && octave <= PCMIDI_OCTAVE_MAX) {
- dbg_hid("pcmidi sysfs write octave=%d\n", octave);
- pk->pm->midi_octave = octave;
- return strlen(buf);
- }
- return -EINVAL;
-}
-
-static DEVICE_ATTR(octave, S_IRUGO | S_IWUSR | S_IWGRP, show_octave,
- store_octave);
-
-static struct device_attribute *sysfs_device_attr_octave = {
- &dev_attr_octave,
- };
-
-
-static void pcmidi_send_note(struct pcmidi_snd *pm,
- unsigned char status, unsigned char note, unsigned char velocity)
-{
- unsigned long flags;
- unsigned char buffer[3];
-
- buffer[0] = status;
- buffer[1] = note;
- buffer[2] = velocity;
-
- spin_lock_irqsave(&pm->rawmidi_in_lock, flags);
-
- if (!pm->in_substream)
- goto drop_note;
- if (!test_bit(pm->in_substream->number, &pm->in_triggered))
- goto drop_note;
-
- snd_rawmidi_receive(pm->in_substream, buffer, 3);
-
-drop_note:
- spin_unlock_irqrestore(&pm->rawmidi_in_lock, flags);
-
- return;
-}
-
-static void pcmidi_sustained_note_release(unsigned long data)
-{
- struct pcmidi_sustain *pms = (struct pcmidi_sustain *)data;
-
- pcmidi_send_note(pms->pm, pms->status, pms->note, pms->velocity);
- pms->in_use = 0;
-}
-
-static void init_sustain_timers(struct pcmidi_snd *pm)
-{
- struct pcmidi_sustain *pms;
- unsigned i;
-
- for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) {
- pms = &pm->sustained_notes[i];
- pms->in_use = 0;
- pms->pm = pm;
- setup_timer(&pms->timer, pcmidi_sustained_note_release,
- (unsigned long)pms);
- }
-}
-
-static void stop_sustain_timers(struct pcmidi_snd *pm)
-{
- struct pcmidi_sustain *pms;
- unsigned i;
-
- for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) {
- pms = &pm->sustained_notes[i];
- pms->in_use = 1;
- del_timer_sync(&pms->timer);
- }
-}
-
-static int pcmidi_get_output_report(struct pcmidi_snd *pm)
-{
- struct hid_device *hdev = pm->pk->hdev;
- struct hid_report *report;
-
- list_for_each_entry(report,
- &hdev->report_enum[HID_OUTPUT_REPORT].report_list, list) {
- if (!(6 == report->id))
- continue;
-
- if (report->maxfield < 1) {
- hid_err(hdev, "output report is empty\n");
- break;
- }
- if (report->field[0]->report_count != 2) {
- hid_err(hdev, "field count too low\n");
- break;
- }
- pm->pcmidi_report6 = report;
- return 0;
- }
- /* should never get here */
- return -ENODEV;
-}
-
-static void pcmidi_submit_output_report(struct pcmidi_snd *pm, int state)
-{
- struct hid_device *hdev = pm->pk->hdev;
- struct hid_report *report = pm->pcmidi_report6;
- report->field[0]->value[0] = 0x01;
- report->field[0]->value[1] = state;
-
- usbhid_submit_report(hdev, report, USB_DIR_OUT);
-}
-
-static int pcmidi_handle_report1(struct pcmidi_snd *pm, u8 *data)
-{
- u32 bit_mask;
-
- bit_mask = data[1];
- bit_mask = (bit_mask << 8) | data[2];
- bit_mask = (bit_mask << 8) | data[3];
-
- dbg_hid("pcmidi mode: %d\n", pm->midi_mode);
-
- /*KEY_MAIL or octave down*/
- if (pm->midi_mode && bit_mask == 0x004000) {
- /* octave down */
- pm->midi_octave--;
- if (pm->midi_octave < -2)
- pm->midi_octave = -2;
- dbg_hid("pcmidi mode: %d octave: %d\n",
- pm->midi_mode, pm->midi_octave);
- return 1;
- }
- /*KEY_WWW or sustain*/
- else if (pm->midi_mode && bit_mask == 0x000004) {
- /* sustain on/off*/
- pm->midi_sustain_mode ^= 0x1;
- return 1;
- }
-
- return 0; /* continue key processing */
-}
-
-static int pcmidi_handle_report3(struct pcmidi_snd *pm, u8 *data, int size)
-{
- struct pcmidi_sustain *pms;
- unsigned i, j;
- unsigned char status, note, velocity;
-
- unsigned num_notes = (size-1)/2;
- for (j = 0; j < num_notes; j++) {
- note = data[j*2+1];
- velocity = data[j*2+2];
-
- if (note < 0x81) { /* note on */
- status = 128 + 16 + pm->midi_channel; /* 1001nnnn */
- note = note - 0x54 + PCMIDI_MIDDLE_C +
- (pm->midi_octave * 12);
- if (0 == velocity)
- velocity = 1; /* force note on */
- } else { /* note off */
- status = 128 + pm->midi_channel; /* 1000nnnn */
- note = note - 0x94 + PCMIDI_MIDDLE_C +
- (pm->midi_octave*12);
-
- if (pm->midi_sustain_mode) {
- for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) {
- pms = &pm->sustained_notes[i];
- if (!pms->in_use) {
- pms->status = status;
- pms->note = note;
- pms->velocity = velocity;
- pms->in_use = 1;
-
- mod_timer(&pms->timer,
- jiffies +
- msecs_to_jiffies(pm->midi_sustain));
- return 1;
- }
- }
- }
- }
- pcmidi_send_note(pm, status, note, velocity);
- }
-
- return 1;
-}
-
-static int pcmidi_handle_report4(struct pcmidi_snd *pm, u8 *data)
-{
- unsigned key;
- u32 bit_mask;
- u32 bit_index;
-
- bit_mask = data[1];
- bit_mask = (bit_mask << 8) | data[2];
- bit_mask = (bit_mask << 8) | data[3];
-
- /* break keys */
- for (bit_index = 0; bit_index < 24; bit_index++) {
- key = pm->last_key[bit_index];
- if (!((0x01 << bit_index) & bit_mask)) {
- input_event(pm->input_ep82, EV_KEY,
- pm->last_key[bit_index], 0);
- pm->last_key[bit_index] = 0;
- }
- }
-
- /* make keys */
- for (bit_index = 0; bit_index < 24; bit_index++) {
- key = 0;
- switch ((0x01 << bit_index) & bit_mask) {
- case 0x000010: /* Fn lock*/
- pm->fn_state ^= 0x000010;
- if (pm->fn_state)
- pcmidi_submit_output_report(pm, 0xc5);
- else
- pcmidi_submit_output_report(pm, 0xc6);
- continue;
- case 0x020000: /* midi launcher..send a key (qwerty) or not? */
- pcmidi_submit_output_report(pm, 0xc1);
- pm->midi_mode ^= 0x01;
-
- dbg_hid("pcmidi mode: %d\n", pm->midi_mode);
- continue;
- case 0x100000: /* KEY_MESSENGER or octave up */
- dbg_hid("pcmidi mode: %d\n", pm->midi_mode);
- if (pm->midi_mode) {
- pm->midi_octave++;
- if (pm->midi_octave > 2)
- pm->midi_octave = 2;
- dbg_hid("pcmidi mode: %d octave: %d\n",
- pm->midi_mode, pm->midi_octave);
- continue;
- } else
- key = KEY_MESSENGER;
- break;
- case 0x400000:
- key = KEY_CALENDAR;
- break;
- case 0x080000:
- key = KEY_ADDRESSBOOK;
- break;
- case 0x040000:
- key = KEY_DOCUMENTS;
- break;
- case 0x800000:
- key = KEY_WORDPROCESSOR;
- break;
- case 0x200000:
- key = KEY_SPREADSHEET;
- break;
- case 0x010000:
- key = KEY_COFFEE;
- break;
- case 0x000100:
- key = KEY_HELP;
- break;
- case 0x000200:
- key = KEY_SEND;
- break;
- case 0x000400:
- key = KEY_REPLY;
- break;
- case 0x000800:
- key = KEY_FORWARDMAIL;
- break;
- case 0x001000:
- key = KEY_NEW;
- break;
- case 0x002000:
- key = KEY_OPEN;
- break;
- case 0x004000:
- key = KEY_CLOSE;
- break;
- case 0x008000:
- key = KEY_SAVE;
- break;
- case 0x000001:
- key = KEY_UNDO;
- break;
- case 0x000002:
- key = KEY_REDO;
- break;
- case 0x000004:
- key = KEY_SPELLCHECK;
- break;
- case 0x000008:
- key = KEY_PRINT;
- break;
- }
- if (key) {
- input_event(pm->input_ep82, EV_KEY, key, 1);
- pm->last_key[bit_index] = key;
- }
- }
-
- return 1;
-}
-
-static int pcmidi_handle_report(
- struct pcmidi_snd *pm, unsigned report_id, u8 *data, int size)
-{
- int ret = 0;
-
- switch (report_id) {
- case 0x01: /* midi keys (qwerty)*/
- ret = pcmidi_handle_report1(pm, data);
- break;
- case 0x03: /* midi keyboard (musical)*/
- ret = pcmidi_handle_report3(pm, data, size);
- break;
- case 0x04: /* multimedia/midi keys (qwerty)*/
- ret = pcmidi_handle_report4(pm, data);
- break;
- }
- return ret;
-}
-
-static void pcmidi_setup_extra_keys(
- struct pcmidi_snd *pm, struct input_dev *input)
-{
- /* reassigned functionality for N/A keys
- MY PICTURES => KEY_WORDPROCESSOR
- MY MUSIC=> KEY_SPREADSHEET
- */
- unsigned int keys[] = {
- KEY_FN,
- KEY_MESSENGER, KEY_CALENDAR,
- KEY_ADDRESSBOOK, KEY_DOCUMENTS,
- KEY_WORDPROCESSOR,
- KEY_SPREADSHEET,
- KEY_COFFEE,
- KEY_HELP, KEY_SEND,
- KEY_REPLY, KEY_FORWARDMAIL,
- KEY_NEW, KEY_OPEN,
- KEY_CLOSE, KEY_SAVE,
- KEY_UNDO, KEY_REDO,
- KEY_SPELLCHECK, KEY_PRINT,
- 0
- };
-
- unsigned int *pkeys = &keys[0];
- unsigned short i;
-
- if (pm->ifnum != 1) /* only set up ONCE for interace 1 */
- return;
-
- pm->input_ep82 = input;
-
- for (i = 0; i < 24; i++)
- pm->last_key[i] = 0;
-
- while (*pkeys != 0) {
- set_bit(*pkeys, pm->input_ep82->keybit);
- ++pkeys;
- }
-}
-
-static int pcmidi_set_operational(struct pcmidi_snd *pm)
-{
- if (pm->ifnum != 1)
- return 0; /* only set up ONCE for interace 1 */
-
- pcmidi_get_output_report(pm);
- pcmidi_submit_output_report(pm, 0xc1);
- return 0;
-}
-
-static int pcmidi_snd_free(struct snd_device *dev)
-{
- return 0;
-}
-
-static int pcmidi_in_open(struct snd_rawmidi_substream *substream)
-{
- struct pcmidi_snd *pm = substream->rmidi->private_data;
-
- dbg_hid("pcmidi in open\n");
- pm->in_substream = substream;
- return 0;
-}
-
-static int pcmidi_in_close(struct snd_rawmidi_substream *substream)
-{
- dbg_hid("pcmidi in close\n");
- return 0;
-}
-
-static void pcmidi_in_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct pcmidi_snd *pm = substream->rmidi->private_data;
-
- dbg_hid("pcmidi in trigger %d\n", up);
-
- pm->in_triggered = up;
-}
-
-static struct snd_rawmidi_ops pcmidi_in_ops = {
- .open = pcmidi_in_open,
- .close = pcmidi_in_close,
- .trigger = pcmidi_in_trigger
-};
-
-static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
-{
- static int dev;
- struct snd_card *card;
- struct snd_rawmidi *rwmidi;
- int err;
-
- static struct snd_device_ops ops = {
- .dev_free = pcmidi_snd_free,
- };
-
- if (pm->ifnum != 1)
- return 0; /* only set up midi device ONCE for interace 1 */
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- /* Setup sound card */
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0) {
- pk_error("failed to create pc-midi sound card\n");
- err = -ENOMEM;
- goto fail;
- }
- pm->card = card;
-
- /* Setup sound device */
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pm, &ops);
- if (err < 0) {
- pk_error("failed to create pc-midi sound device: error %d\n",
- err);
- goto fail;
- }
-
- strncpy(card->driver, shortname, sizeof(card->driver));
- strncpy(card->shortname, shortname, sizeof(card->shortname));
- strncpy(card->longname, longname, sizeof(card->longname));
-
- /* Set up rawmidi */
- err = snd_rawmidi_new(card, card->shortname, 0,
- 0, 1, &rwmidi);
- if (err < 0) {
- pk_error("failed to create pc-midi rawmidi device: error %d\n",
- err);
- goto fail;
- }
- pm->rwmidi = rwmidi;
- strncpy(rwmidi->name, card->shortname, sizeof(rwmidi->name));
- rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT;
- rwmidi->private_data = pm;
-
- snd_rawmidi_set_ops(rwmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &pcmidi_in_ops);
-
- snd_card_set_dev(card, &pm->pk->hdev->dev);
-
- /* create sysfs variables */
- err = device_create_file(&pm->pk->hdev->dev,
- sysfs_device_attr_channel);
- if (err < 0) {
- pk_error("failed to create sysfs attribute channel: error %d\n",
- err);
- goto fail;
- }
-
- err = device_create_file(&pm->pk->hdev->dev,
- sysfs_device_attr_sustain);
- if (err < 0) {
- pk_error("failed to create sysfs attribute sustain: error %d\n",
- err);
- goto fail_attr_sustain;
- }
-
- err = device_create_file(&pm->pk->hdev->dev,
- sysfs_device_attr_octave);
- if (err < 0) {
- pk_error("failed to create sysfs attribute octave: error %d\n",
- err);
- goto fail_attr_octave;
- }
-
- spin_lock_init(&pm->rawmidi_in_lock);
-
- init_sustain_timers(pm);
- pcmidi_set_operational(pm);
-
- /* register it */
- err = snd_card_register(card);
- if (err < 0) {
- pk_error("failed to register pc-midi sound card: error %d\n",
- err);
- goto fail_register;
- }
-
- dbg_hid("pcmidi_snd_initialise finished ok\n");
- return 0;
-
-fail_register:
- stop_sustain_timers(pm);
- device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_octave);
-fail_attr_octave:
- device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_sustain);
-fail_attr_sustain:
- device_remove_file(&pm->pk->hdev->dev, sysfs_device_attr_channel);
-fail:
- if (pm->card) {
- snd_card_free(pm->card);
- pm->card = NULL;
- }
- return err;
-}
-
-static int pcmidi_snd_terminate(struct pcmidi_snd *pm)
-{
- if (pm->card) {
- stop_sustain_timers(pm);
-
- device_remove_file(&pm->pk->hdev->dev,
- sysfs_device_attr_channel);
- device_remove_file(&pm->pk->hdev->dev,
- sysfs_device_attr_sustain);
- device_remove_file(&pm->pk->hdev->dev,
- sysfs_device_attr_octave);
-
- snd_card_disconnect(pm->card);
- snd_card_free_when_closed(pm->card);
- }
-
- return 0;
-}
-
-/*
- * PC-MIDI report descriptor for report id is wrong.
- */
-static __u8 *pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize == 178 &&
- rdesc[111] == 0x06 && rdesc[112] == 0x00 &&
- rdesc[113] == 0xff) {
- hid_info(hdev,
- "fixing up pc-midi keyboard report descriptor\n");
-
- rdesc[144] = 0x18; /* report 4: was 0x10 report count */
- }
- return rdesc;
-}
-
-static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
- struct pcmidi_snd *pm;
-
- pm = pk->pm;
-
- if (HID_UP_MSVENDOR == (usage->hid & HID_USAGE_PAGE) &&
- 1 == pm->ifnum) {
- pcmidi_setup_extra_keys(pm, hi->input);
- return 0;
- }
-
- return 0;
-}
-
-
-static int pk_raw_event(struct hid_device *hdev, struct hid_report *report,
- u8 *data, int size)
-{
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
- int ret = 0;
-
- if (1 == pk->pm->ifnum) {
- if (report->id == data[0])
- switch (report->id) {
- case 0x01: /* midi keys (qwerty)*/
- case 0x03: /* midi keyboard (musical)*/
- case 0x04: /* extra/midi keys (qwerty)*/
- ret = pcmidi_handle_report(pk->pm,
- report->id, data, size);
- break;
- }
- }
-
- return ret;
-}
-
-static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
- unsigned long quirks = id->driver_data;
- struct pk_device *pk;
- struct pcmidi_snd *pm = NULL;
-
- pk = kzalloc(sizeof(*pk), GFP_KERNEL);
- if (pk == NULL) {
- hid_err(hdev, "can't alloc descriptor\n");
- return -ENOMEM;
- }
-
- pk->hdev = hdev;
-
- pm = kzalloc(sizeof(*pm), GFP_KERNEL);
- if (pm == NULL) {
- hid_err(hdev, "can't alloc descriptor\n");
- ret = -ENOMEM;
- goto err_free_pk;
- }
-
- pm->pk = pk;
- pk->pm = pm;
- pm->ifnum = ifnum;
-
- hid_set_drvdata(hdev, pk);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "hid parse failed\n");
- goto err_free;
- }
-
- if (quirks & PK_QUIRK_NOGET) { /* hid_parse cleared all the quirks */
- hdev->quirks |= HID_QUIRK_NOGET;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- ret = pcmidi_snd_initialise(pm);
- if (ret < 0)
- goto err_stop;
-
- return 0;
-err_stop:
- hid_hw_stop(hdev);
-err_free:
- kfree(pm);
-err_free_pk:
- kfree(pk);
-
- return ret;
-}
-
-static void pk_remove(struct hid_device *hdev)
-{
- struct pk_device *pk = (struct pk_device *)hid_get_drvdata(hdev);
- struct pcmidi_snd *pm;
-
- pm = pk->pm;
- if (pm) {
- pcmidi_snd_terminate(pm);
- kfree(pm);
- }
-
- hid_hw_stop(hdev);
-
- kfree(pk);
-}
-
-static const struct hid_device_id pk_devices[] = {
- {HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS,
- USB_DEVICE_ID_PRODIKEYS_PCMIDI),
- .driver_data = PK_QUIRK_NOGET},
- { }
-};
-MODULE_DEVICE_TABLE(hid, pk_devices);
-
-static struct hid_driver pk_driver = {
- .name = "prodikeys",
- .id_table = pk_devices,
- .report_fixup = pk_report_fixup,
- .input_mapping = pk_input_mapping,
- .raw_event = pk_raw_event,
- .probe = pk_probe,
- .remove = pk_remove,
-};
-
-static int pk_init(void)
-{
- int ret;
-
- ret = hid_register_driver(&pk_driver);
- if (ret)
- pr_err("can't register prodikeys driver\n");
-
- return ret;
-}
-
-static void pk_exit(void)
-{
- hid_unregister_driver(&pk_driver);
-}
-
-module_init(pk_init);
-module_exit(pk_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-arvo.c b/ANDROID_3.4.5/drivers/hid/hid-roccat-arvo.c
deleted file mode 100644
index 093bfad0..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-arvo.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Roccat Arvo driver for Linux
- *
- * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-/*
- * Roccat Arvo is a gamer keyboard with 5 macro keys that can be configured in
- * 5 profiles.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/hid-roccat.h>
-#include "hid-ids.h"
-#include "hid-roccat-common.h"
-#include "hid-roccat-arvo.h"
-
-static struct class *arvo_class;
-
-static ssize_t arvo_sysfs_show_mode_key(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct arvo_device *arvo =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- struct usb_device *usb_dev =
- interface_to_usbdev(to_usb_interface(dev->parent->parent));
- struct arvo_mode_key temp_buf;
- int retval;
-
- mutex_lock(&arvo->arvo_lock);
- retval = roccat_common_receive(usb_dev, ARVO_COMMAND_MODE_KEY,
- &temp_buf, sizeof(struct arvo_mode_key));
- mutex_unlock(&arvo->arvo_lock);
- if (retval)
- return retval;
-
- return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.state);
-}
-
-static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
- struct device_attribute *attr, char const *buf, size_t size)
-{
- struct arvo_device *arvo =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- struct usb_device *usb_dev =
- interface_to_usbdev(to_usb_interface(dev->parent->parent));
- struct arvo_mode_key temp_buf;
- unsigned long state;
- int retval;
-
- retval = strict_strtoul(buf, 10, &state);
- if (retval)
- return retval;
-
- temp_buf.command = ARVO_COMMAND_MODE_KEY;
- temp_buf.state = state;
-
- mutex_lock(&arvo->arvo_lock);
- retval = roccat_common_send(usb_dev, ARVO_COMMAND_MODE_KEY,
- &temp_buf, sizeof(struct arvo_mode_key));
- mutex_unlock(&arvo->arvo_lock);
- if (retval)
- return retval;
-
- return size;
-}
-
-static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct arvo_device *arvo =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- struct usb_device *usb_dev =
- interface_to_usbdev(to_usb_interface(dev->parent->parent));
- struct arvo_key_mask temp_buf;
- int retval;
-
- mutex_lock(&arvo->arvo_lock);
- retval = roccat_common_receive(usb_dev, ARVO_COMMAND_KEY_MASK,
- &temp_buf, sizeof(struct arvo_key_mask));
- mutex_unlock(&arvo->arvo_lock);
- if (retval)
- return retval;
-
- return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.key_mask);
-}
-
-static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
- struct device_attribute *attr, char const *buf, size_t size)
-{
- struct arvo_device *arvo =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- struct usb_device *usb_dev =
- interface_to_usbdev(to_usb_interface(dev->parent->parent));
- struct arvo_key_mask temp_buf;
- unsigned long key_mask;
- int retval;
-
- retval = strict_strtoul(buf, 10, &key_mask);
- if (retval)
- return retval;
-
- temp_buf.command = ARVO_COMMAND_KEY_MASK;
- temp_buf.key_mask = key_mask;
-
- mutex_lock(&arvo->arvo_lock);
- retval = roccat_common_send(usb_dev, ARVO_COMMAND_KEY_MASK,
- &temp_buf, sizeof(struct arvo_key_mask));
- mutex_unlock(&arvo->arvo_lock);
- if (retval)
- return retval;
-
- return size;
-}
-
-/* retval is 1-5 on success, < 0 on error */
-static int arvo_get_actual_profile(struct usb_device *usb_dev)
-{
- struct arvo_actual_profile temp_buf;
- int retval;
-
- retval = roccat_common_receive(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE,
- &temp_buf, sizeof(struct arvo_actual_profile));
-
- if (retval)
- return retval;
-
- return temp_buf.actual_profile;
-}
-
-static ssize_t arvo_sysfs_show_actual_profile(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct arvo_device *arvo =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
-
- return snprintf(buf, PAGE_SIZE, "%d\n", arvo->actual_profile);
-}
-
-static ssize_t arvo_sysfs_set_actual_profile(struct device *dev,
- struct device_attribute *attr, char const *buf, size_t size)
-{
- struct arvo_device *arvo =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- struct usb_device *usb_dev =
- interface_to_usbdev(to_usb_interface(dev->parent->parent));
- struct arvo_actual_profile temp_buf;
- unsigned long profile;
- int retval;
-
- retval = strict_strtoul(buf, 10, &profile);
- if (retval)
- return retval;
-
- if (profile < 1 || profile > 5)
- return -EINVAL;
-
- temp_buf.command = ARVO_COMMAND_ACTUAL_PROFILE;
- temp_buf.actual_profile = profile;
-
- mutex_lock(&arvo->arvo_lock);
- retval = roccat_common_send(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE,
- &temp_buf, sizeof(struct arvo_actual_profile));
- if (!retval) {
- arvo->actual_profile = profile;
- retval = size;
- }
- mutex_unlock(&arvo->arvo_lock);
- return retval;
-}
-
-static ssize_t arvo_sysfs_write(struct file *fp,
- struct kobject *kobj, void const *buf,
- loff_t off, size_t count, size_t real_size, uint command)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval;
-
- if (off != 0 || count != real_size)
- return -EINVAL;
-
- mutex_lock(&arvo->arvo_lock);
- retval = roccat_common_send(usb_dev, command, buf, real_size);
- mutex_unlock(&arvo->arvo_lock);
-
- return (retval ? retval : real_size);
-}
-
-static ssize_t arvo_sysfs_read(struct file *fp,
- struct kobject *kobj, void *buf, loff_t off,
- size_t count, size_t real_size, uint command)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval;
-
- if (off >= real_size)
- return 0;
-
- if (off != 0 || count != real_size)
- return -EINVAL;
-
- mutex_lock(&arvo->arvo_lock);
- retval = roccat_common_receive(usb_dev, command, buf, real_size);
- mutex_unlock(&arvo->arvo_lock);
-
- return (retval ? retval : real_size);
-}
-
-static ssize_t arvo_sysfs_write_button(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return arvo_sysfs_write(fp, kobj, buf, off, count,
- sizeof(struct arvo_button), ARVO_COMMAND_BUTTON);
-}
-
-static ssize_t arvo_sysfs_read_info(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return arvo_sysfs_read(fp, kobj, buf, off, count,
- sizeof(struct arvo_info), ARVO_COMMAND_INFO);
-}
-
-
-static struct device_attribute arvo_attributes[] = {
- __ATTR(mode_key, 0660,
- arvo_sysfs_show_mode_key, arvo_sysfs_set_mode_key),
- __ATTR(key_mask, 0660,
- arvo_sysfs_show_key_mask, arvo_sysfs_set_key_mask),
- __ATTR(actual_profile, 0660,
- arvo_sysfs_show_actual_profile,
- arvo_sysfs_set_actual_profile),
- __ATTR_NULL
-};
-
-static struct bin_attribute arvo_bin_attributes[] = {
- {
- .attr = { .name = "button", .mode = 0220 },
- .size = sizeof(struct arvo_button),
- .write = arvo_sysfs_write_button
- },
- {
- .attr = { .name = "info", .mode = 0440 },
- .size = sizeof(struct arvo_info),
- .read = arvo_sysfs_read_info
- },
- __ATTR_NULL
-};
-
-static int arvo_init_arvo_device_struct(struct usb_device *usb_dev,
- struct arvo_device *arvo)
-{
- int retval;
-
- mutex_init(&arvo->arvo_lock);
-
- retval = arvo_get_actual_profile(usb_dev);
- if (retval < 0)
- return retval;
- arvo->actual_profile = retval;
-
- return 0;
-}
-
-static int arvo_init_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct usb_device *usb_dev = interface_to_usbdev(intf);
- struct arvo_device *arvo;
- int retval;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_KEYBOARD) {
- hid_set_drvdata(hdev, NULL);
- return 0;
- }
-
- arvo = kzalloc(sizeof(*arvo), GFP_KERNEL);
- if (!arvo) {
- hid_err(hdev, "can't alloc device descriptor\n");
- return -ENOMEM;
- }
- hid_set_drvdata(hdev, arvo);
-
- retval = arvo_init_arvo_device_struct(usb_dev, arvo);
- if (retval) {
- hid_err(hdev, "couldn't init struct arvo_device\n");
- goto exit_free;
- }
-
- retval = roccat_connect(arvo_class, hdev,
- sizeof(struct arvo_roccat_report));
- if (retval < 0) {
- hid_err(hdev, "couldn't init char dev\n");
- } else {
- arvo->chrdev_minor = retval;
- arvo->roccat_claimed = 1;
- }
-
- return 0;
-exit_free:
- kfree(arvo);
- return retval;
-}
-
-static void arvo_remove_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct arvo_device *arvo;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_KEYBOARD)
- return;
-
- arvo = hid_get_drvdata(hdev);
- if (arvo->roccat_claimed)
- roccat_disconnect(arvo->chrdev_minor);
- kfree(arvo);
-}
-
-static int arvo_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- int retval;
-
- retval = hid_parse(hdev);
- if (retval) {
- hid_err(hdev, "parse failed\n");
- goto exit;
- }
-
- retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (retval) {
- hid_err(hdev, "hw start failed\n");
- goto exit;
- }
-
- retval = arvo_init_specials(hdev);
- if (retval) {
- hid_err(hdev, "couldn't install keyboard\n");
- goto exit_stop;
- }
-
- return 0;
-
-exit_stop:
- hid_hw_stop(hdev);
-exit:
- return retval;
-}
-
-static void arvo_remove(struct hid_device *hdev)
-{
- arvo_remove_specials(hdev);
- hid_hw_stop(hdev);
-}
-
-static void arvo_report_to_chrdev(struct arvo_device const *arvo,
- u8 const *data)
-{
- struct arvo_special_report const *special_report;
- struct arvo_roccat_report roccat_report;
-
- special_report = (struct arvo_special_report const *)data;
-
- roccat_report.profile = arvo->actual_profile;
- roccat_report.button = special_report->event &
- ARVO_SPECIAL_REPORT_EVENT_MASK_BUTTON;
- if ((special_report->event & ARVO_SPECIAL_REPORT_EVENT_MASK_ACTION) ==
- ARVO_SPECIAL_REPORT_EVENT_ACTION_PRESS)
- roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_PRESS;
- else
- roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_RELEASE;
-
- roccat_report_event(arvo->chrdev_minor,
- (uint8_t const *)&roccat_report);
-}
-
-static int arvo_raw_event(struct hid_device *hdev,
- struct hid_report *report, u8 *data, int size)
-{
- struct arvo_device *arvo = hid_get_drvdata(hdev);
-
- if (size != 3)
- return 0;
-
- if (arvo && arvo->roccat_claimed)
- arvo_report_to_chrdev(arvo, data);
-
- return 0;
-}
-
-static const struct hid_device_id arvo_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, arvo_devices);
-
-static struct hid_driver arvo_driver = {
- .name = "arvo",
- .id_table = arvo_devices,
- .probe = arvo_probe,
- .remove = arvo_remove,
- .raw_event = arvo_raw_event
-};
-
-static int __init arvo_init(void)
-{
- int retval;
-
- arvo_class = class_create(THIS_MODULE, "arvo");
- if (IS_ERR(arvo_class))
- return PTR_ERR(arvo_class);
- arvo_class->dev_attrs = arvo_attributes;
- arvo_class->dev_bin_attrs = arvo_bin_attributes;
-
- retval = hid_register_driver(&arvo_driver);
- if (retval)
- class_destroy(arvo_class);
- return retval;
-}
-
-static void __exit arvo_exit(void)
-{
- hid_unregister_driver(&arvo_driver);
- class_destroy(arvo_class);
-}
-
-module_init(arvo_init);
-module_exit(arvo_exit);
-
-MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat Arvo driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-arvo.h b/ANDROID_3.4.5/drivers/hid/hid-roccat-arvo.h
deleted file mode 100644
index ce8415e4..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-arvo.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __HID_ROCCAT_ARVO_H
-#define __HID_ROCCAT_ARVO_H
-
-/*
- * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/types.h>
-
-struct arvo_mode_key { /* 2 bytes */
- uint8_t command; /* ARVO_COMMAND_MODE_KEY */
- uint8_t state;
-} __packed;
-
-struct arvo_button {
- uint8_t unknown[24];
-} __packed;
-
-struct arvo_info {
- uint8_t unknown[8];
-} __packed;
-
-struct arvo_key_mask { /* 2 bytes */
- uint8_t command; /* ARVO_COMMAND_KEY_MASK */
- uint8_t key_mask;
-} __packed;
-
-/* selected profile is persistent */
-struct arvo_actual_profile { /* 2 bytes */
- uint8_t command; /* ARVO_COMMAND_ACTUAL_PROFILE */
- uint8_t actual_profile;
-} __packed;
-
-enum arvo_commands {
- ARVO_COMMAND_MODE_KEY = 0x3,
- ARVO_COMMAND_BUTTON = 0x4,
- ARVO_COMMAND_INFO = 0x5,
- ARVO_COMMAND_KEY_MASK = 0x6,
- ARVO_COMMAND_ACTUAL_PROFILE = 0x7,
-};
-
-struct arvo_special_report {
- uint8_t unknown1; /* always 0x01 */
- uint8_t event;
- uint8_t unknown2; /* always 0x70 */
-} __packed;
-
-enum arvo_special_report_events {
- ARVO_SPECIAL_REPORT_EVENT_ACTION_PRESS = 0x10,
- ARVO_SPECIAL_REPORT_EVENT_ACTION_RELEASE = 0x0,
-};
-
-enum arvo_special_report_event_masks {
- ARVO_SPECIAL_REPORT_EVENT_MASK_ACTION = 0xf0,
- ARVO_SPECIAL_REPORT_EVENT_MASK_BUTTON = 0x0f,
-};
-
-struct arvo_roccat_report {
- uint8_t profile;
- uint8_t button;
- uint8_t action;
-} __packed;
-
-enum arvo_roccat_report_action {
- ARVO_ROCCAT_REPORT_ACTION_RELEASE = 0,
- ARVO_ROCCAT_REPORT_ACTION_PRESS = 1,
-};
-
-struct arvo_device {
- int roccat_claimed;
- int chrdev_minor;
-
- struct mutex arvo_lock;
-
- int actual_profile;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-common.c b/ANDROID_3.4.5/drivers/hid/hid-roccat-common.c
deleted file mode 100644
index a6d93992..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-common.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Roccat common functions for device specific drivers
- *
- * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/hid.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include "hid-roccat-common.h"
-
-static inline uint16_t roccat_common_feature_report(uint8_t report_id)
-{
- return 0x300 | report_id;
-}
-
-int roccat_common_receive(struct usb_device *usb_dev, uint report_id,
- void *data, uint size)
-{
- char *buf;
- int len;
-
- buf = kmalloc(size, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
- HID_REQ_GET_REPORT,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- roccat_common_feature_report(report_id),
- 0, buf, size, USB_CTRL_SET_TIMEOUT);
-
- memcpy(data, buf, size);
- kfree(buf);
- return ((len < 0) ? len : ((len != size) ? -EIO : 0));
-}
-EXPORT_SYMBOL_GPL(roccat_common_receive);
-
-int roccat_common_send(struct usb_device *usb_dev, uint report_id,
- void const *data, uint size)
-{
- char *buf;
- int len;
-
- buf = kmemdup(data, size, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
- HID_REQ_SET_REPORT,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
- roccat_common_feature_report(report_id),
- 0, buf, size, USB_CTRL_SET_TIMEOUT);
-
- kfree(buf);
- return ((len < 0) ? len : ((len != size) ? -EIO : 0));
-}
-EXPORT_SYMBOL_GPL(roccat_common_send);
-
-MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat common driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-common.h b/ANDROID_3.4.5/drivers/hid/hid-roccat-common.h
deleted file mode 100644
index 9a5bc61f..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-common.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __HID_ROCCAT_COMMON_H
-#define __HID_ROCCAT_COMMON_H
-
-/*
- * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/usb.h>
-#include <linux/types.h>
-
-int roccat_common_receive(struct usb_device *usb_dev, uint report_id,
- void *data, uint size);
-int roccat_common_send(struct usb_device *usb_dev, uint report_id,
- void const *data, uint size);
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-isku.c b/ANDROID_3.4.5/drivers/hid/hid-roccat-isku.c
deleted file mode 100644
index 0e4a0ab4..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-isku.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Roccat Isku driver for Linux
- *
- * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-/*
- * Roccat Isku is a gamer keyboard with macro keys that can be configured in
- * 5 profiles.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/hid-roccat.h>
-#include "hid-ids.h"
-#include "hid-roccat-common.h"
-#include "hid-roccat-isku.h"
-
-static struct class *isku_class;
-
-static void isku_profile_activated(struct isku_device *isku, uint new_profile)
-{
- isku->actual_profile = new_profile;
-}
-
-static int isku_receive(struct usb_device *usb_dev, uint command,
- void *buf, uint size)
-{
- return roccat_common_receive(usb_dev, command, buf, size);
-}
-
-static int isku_receive_control_status(struct usb_device *usb_dev)
-{
- int retval;
- struct isku_control control;
-
- do {
- msleep(50);
- retval = isku_receive(usb_dev, ISKU_COMMAND_CONTROL,
- &control, sizeof(struct isku_control));
-
- if (retval)
- return retval;
-
- switch (control.value) {
- case ISKU_CONTROL_VALUE_STATUS_OK:
- return 0;
- case ISKU_CONTROL_VALUE_STATUS_WAIT:
- continue;
- case ISKU_CONTROL_VALUE_STATUS_INVALID:
- /* seems to be critical - replug necessary */
- case ISKU_CONTROL_VALUE_STATUS_OVERLOAD:
- return -EINVAL;
- default:
- hid_err(usb_dev, "isku_receive_control_status: "
- "unknown response value 0x%x\n",
- control.value);
- return -EINVAL;
- }
-
- } while (1);
-}
-
-static int isku_send(struct usb_device *usb_dev, uint command,
- void const *buf, uint size)
-{
- int retval;
-
- retval = roccat_common_send(usb_dev, command, buf, size);
- if (retval)
- return retval;
-
- return isku_receive_control_status(usb_dev);
-}
-
-static int isku_get_actual_profile(struct usb_device *usb_dev)
-{
- struct isku_actual_profile buf;
- int retval;
-
- retval = isku_receive(usb_dev, ISKU_COMMAND_ACTUAL_PROFILE,
- &buf, sizeof(struct isku_actual_profile));
- return retval ? retval : buf.actual_profile;
-}
-
-static int isku_set_actual_profile(struct usb_device *usb_dev, int new_profile)
-{
- struct isku_actual_profile buf;
-
- buf.command = ISKU_COMMAND_ACTUAL_PROFILE;
- buf.size = sizeof(struct isku_actual_profile);
- buf.actual_profile = new_profile;
- return isku_send(usb_dev, ISKU_COMMAND_ACTUAL_PROFILE, &buf,
- sizeof(struct isku_actual_profile));
-}
-
-static ssize_t isku_sysfs_show_actual_profile(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct isku_device *isku =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", isku->actual_profile);
-}
-
-static ssize_t isku_sysfs_set_actual_profile(struct device *dev,
- struct device_attribute *attr, char const *buf, size_t size)
-{
- struct isku_device *isku;
- struct usb_device *usb_dev;
- unsigned long profile;
- int retval;
- struct isku_roccat_report roccat_report;
-
- dev = dev->parent->parent;
- isku = hid_get_drvdata(dev_get_drvdata(dev));
- usb_dev = interface_to_usbdev(to_usb_interface(dev));
-
- retval = strict_strtoul(buf, 10, &profile);
- if (retval)
- return retval;
-
- if (profile > 4)
- return -EINVAL;
-
- mutex_lock(&isku->isku_lock);
-
- retval = isku_set_actual_profile(usb_dev, profile);
- if (retval) {
- mutex_unlock(&isku->isku_lock);
- return retval;
- }
-
- isku_profile_activated(isku, profile);
-
- roccat_report.event = ISKU_REPORT_BUTTON_EVENT_PROFILE;
- roccat_report.data1 = profile + 1;
- roccat_report.data2 = 0;
- roccat_report.profile = profile + 1;
- roccat_report_event(isku->chrdev_minor, (uint8_t const *)&roccat_report);
-
- mutex_unlock(&isku->isku_lock);
-
- return size;
-}
-
-static struct device_attribute isku_attributes[] = {
- __ATTR(actual_profile, 0660,
- isku_sysfs_show_actual_profile,
- isku_sysfs_set_actual_profile),
- __ATTR_NULL
-};
-
-static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj,
- char *buf, loff_t off, size_t count,
- size_t real_size, uint command)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct isku_device *isku = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval;
-
- if (off >= real_size)
- return 0;
-
- if (off != 0 || count != real_size)
- return -EINVAL;
-
- mutex_lock(&isku->isku_lock);
- retval = isku_receive(usb_dev, command, buf, real_size);
- mutex_unlock(&isku->isku_lock);
-
- return retval ? retval : real_size;
-}
-
-static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj,
- void const *buf, loff_t off, size_t count,
- size_t real_size, uint command)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct isku_device *isku = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval;
-
- if (off != 0 || count != real_size)
- return -EINVAL;
-
- mutex_lock(&isku->isku_lock);
- retval = isku_send(usb_dev, command, (void *)buf, real_size);
- mutex_unlock(&isku->isku_lock);
-
- return retval ? retval : real_size;
-}
-
-#define ISKU_SYSFS_W(thingy, THINGY) \
-static ssize_t isku_sysfs_write_ ## thingy(struct file *fp, struct kobject *kobj, \
- struct bin_attribute *attr, char *buf, \
- loff_t off, size_t count) \
-{ \
- return isku_sysfs_write(fp, kobj, buf, off, count, \
- sizeof(struct isku_ ## thingy), ISKU_COMMAND_ ## THINGY); \
-}
-
-#define ISKU_SYSFS_R(thingy, THINGY) \
-static ssize_t isku_sysfs_read_ ## thingy(struct file *fp, struct kobject *kobj, \
- struct bin_attribute *attr, char *buf, \
- loff_t off, size_t count) \
-{ \
- return isku_sysfs_read(fp, kobj, buf, off, count, \
- sizeof(struct isku_ ## thingy), ISKU_COMMAND_ ## THINGY); \
-}
-
-#define ISKU_SYSFS_RW(thingy, THINGY) \
-ISKU_SYSFS_R(thingy, THINGY) \
-ISKU_SYSFS_W(thingy, THINGY)
-
-#define ISKU_BIN_ATTR_RW(thingy) \
-{ \
- .attr = { .name = #thingy, .mode = 0660 }, \
- .size = sizeof(struct isku_ ## thingy), \
- .read = isku_sysfs_read_ ## thingy, \
- .write = isku_sysfs_write_ ## thingy \
-}
-
-#define ISKU_BIN_ATTR_R(thingy) \
-{ \
- .attr = { .name = #thingy, .mode = 0440 }, \
- .size = sizeof(struct isku_ ## thingy), \
- .read = isku_sysfs_read_ ## thingy, \
-}
-
-#define ISKU_BIN_ATTR_W(thingy) \
-{ \
- .attr = { .name = #thingy, .mode = 0220 }, \
- .size = sizeof(struct isku_ ## thingy), \
- .write = isku_sysfs_write_ ## thingy \
-}
-
-ISKU_SYSFS_RW(macro, MACRO)
-ISKU_SYSFS_RW(keys_function, KEYS_FUNCTION)
-ISKU_SYSFS_RW(keys_easyzone, KEYS_EASYZONE)
-ISKU_SYSFS_RW(keys_media, KEYS_MEDIA)
-ISKU_SYSFS_RW(keys_thumbster, KEYS_THUMBSTER)
-ISKU_SYSFS_RW(keys_macro, KEYS_MACRO)
-ISKU_SYSFS_RW(keys_capslock, KEYS_CAPSLOCK)
-ISKU_SYSFS_RW(light, LIGHT)
-ISKU_SYSFS_RW(key_mask, KEY_MASK)
-ISKU_SYSFS_RW(last_set, LAST_SET)
-ISKU_SYSFS_W(talk, TALK)
-ISKU_SYSFS_R(info, INFO)
-ISKU_SYSFS_W(control, CONTROL)
-
-static struct bin_attribute isku_bin_attributes[] = {
- ISKU_BIN_ATTR_RW(macro),
- ISKU_BIN_ATTR_RW(keys_function),
- ISKU_BIN_ATTR_RW(keys_easyzone),
- ISKU_BIN_ATTR_RW(keys_media),
- ISKU_BIN_ATTR_RW(keys_thumbster),
- ISKU_BIN_ATTR_RW(keys_macro),
- ISKU_BIN_ATTR_RW(keys_capslock),
- ISKU_BIN_ATTR_RW(light),
- ISKU_BIN_ATTR_RW(key_mask),
- ISKU_BIN_ATTR_RW(last_set),
- ISKU_BIN_ATTR_W(talk),
- ISKU_BIN_ATTR_R(info),
- ISKU_BIN_ATTR_W(control),
- __ATTR_NULL
-};
-
-static int isku_init_isku_device_struct(struct usb_device *usb_dev,
- struct isku_device *isku)
-{
- int retval;
-
- mutex_init(&isku->isku_lock);
-
- retval = isku_get_actual_profile(usb_dev);
- if (retval < 0)
- return retval;
- isku_profile_activated(isku, retval);
-
- return 0;
-}
-
-static int isku_init_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct usb_device *usb_dev = interface_to_usbdev(intf);
- struct isku_device *isku;
- int retval;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- != ISKU_USB_INTERFACE_PROTOCOL) {
- hid_set_drvdata(hdev, NULL);
- return 0;
- }
-
- isku = kzalloc(sizeof(*isku), GFP_KERNEL);
- if (!isku) {
- hid_err(hdev, "can't alloc device descriptor\n");
- return -ENOMEM;
- }
- hid_set_drvdata(hdev, isku);
-
- retval = isku_init_isku_device_struct(usb_dev, isku);
- if (retval) {
- hid_err(hdev, "couldn't init struct isku_device\n");
- goto exit_free;
- }
-
- retval = roccat_connect(isku_class, hdev,
- sizeof(struct isku_roccat_report));
- if (retval < 0) {
- hid_err(hdev, "couldn't init char dev\n");
- } else {
- isku->chrdev_minor = retval;
- isku->roccat_claimed = 1;
- }
-
- return 0;
-exit_free:
- kfree(isku);
- return retval;
-}
-
-static void isku_remove_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct isku_device *isku;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- != ISKU_USB_INTERFACE_PROTOCOL)
- return;
-
- isku = hid_get_drvdata(hdev);
- if (isku->roccat_claimed)
- roccat_disconnect(isku->chrdev_minor);
- kfree(isku);
-}
-
-static int isku_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- int retval;
-
- retval = hid_parse(hdev);
- if (retval) {
- hid_err(hdev, "parse failed\n");
- goto exit;
- }
-
- retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (retval) {
- hid_err(hdev, "hw start failed\n");
- goto exit;
- }
-
- retval = isku_init_specials(hdev);
- if (retval) {
- hid_err(hdev, "couldn't install keyboard\n");
- goto exit_stop;
- }
-
- return 0;
-
-exit_stop:
- hid_hw_stop(hdev);
-exit:
- return retval;
-}
-
-static void isku_remove(struct hid_device *hdev)
-{
- isku_remove_specials(hdev);
- hid_hw_stop(hdev);
-}
-
-static void isku_keep_values_up_to_date(struct isku_device *isku,
- u8 const *data)
-{
- struct isku_report_button const *button_report;
-
- switch (data[0]) {
- case ISKU_REPORT_NUMBER_BUTTON:
- button_report = (struct isku_report_button const *)data;
- switch (button_report->event) {
- case ISKU_REPORT_BUTTON_EVENT_PROFILE:
- isku_profile_activated(isku, button_report->data1 - 1);
- break;
- }
- break;
- }
-}
-
-static void isku_report_to_chrdev(struct isku_device const *isku,
- u8 const *data)
-{
- struct isku_roccat_report roccat_report;
- struct isku_report_button const *button_report;
-
- if (data[0] != ISKU_REPORT_NUMBER_BUTTON)
- return;
-
- button_report = (struct isku_report_button const *)data;
-
- roccat_report.event = button_report->event;
- roccat_report.data1 = button_report->data1;
- roccat_report.data2 = button_report->data2;
- roccat_report.profile = isku->actual_profile + 1;
- roccat_report_event(isku->chrdev_minor,
- (uint8_t const *)&roccat_report);
-}
-
-static int isku_raw_event(struct hid_device *hdev,
- struct hid_report *report, u8 *data, int size)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct isku_device *isku = hid_get_drvdata(hdev);
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- != ISKU_USB_INTERFACE_PROTOCOL)
- return 0;
-
- if (isku == NULL)
- return 0;
-
- isku_keep_values_up_to_date(isku, data);
-
- if (isku->roccat_claimed)
- isku_report_to_chrdev(isku, data);
-
- return 0;
-}
-
-static const struct hid_device_id isku_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, isku_devices);
-
-static struct hid_driver isku_driver = {
- .name = "isku",
- .id_table = isku_devices,
- .probe = isku_probe,
- .remove = isku_remove,
- .raw_event = isku_raw_event
-};
-
-static int __init isku_init(void)
-{
- int retval;
- isku_class = class_create(THIS_MODULE, "isku");
- if (IS_ERR(isku_class))
- return PTR_ERR(isku_class);
- isku_class->dev_attrs = isku_attributes;
- isku_class->dev_bin_attrs = isku_bin_attributes;
-
- retval = hid_register_driver(&isku_driver);
- if (retval)
- class_destroy(isku_class);
- return retval;
-}
-
-static void __exit isku_exit(void)
-{
- hid_unregister_driver(&isku_driver);
- class_destroy(isku_class);
-}
-
-module_init(isku_init);
-module_exit(isku_exit);
-
-MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat Isku driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-isku.h b/ANDROID_3.4.5/drivers/hid/hid-roccat-isku.h
deleted file mode 100644
index 075f6efa..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-isku.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#ifndef __HID_ROCCAT_ISKU_H
-#define __HID_ROCCAT_ISKU_H
-
-/*
- * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/types.h>
-
-enum {
- ISKU_PROFILE_NUM = 5,
- ISKU_USB_INTERFACE_PROTOCOL = 0,
-};
-
-struct isku_control {
- uint8_t command; /* ISKU_COMMAND_CONTROL */
- uint8_t value;
- uint8_t request;
-} __packed;
-
-enum isku_control_values {
- ISKU_CONTROL_VALUE_STATUS_OVERLOAD = 0,
- ISKU_CONTROL_VALUE_STATUS_OK = 1,
- ISKU_CONTROL_VALUE_STATUS_INVALID = 2,
- ISKU_CONTROL_VALUE_STATUS_WAIT = 3,
-};
-
-struct isku_actual_profile {
- uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */
- uint8_t size; /* always 3 */
- uint8_t actual_profile;
-} __packed;
-
-struct isku_key_mask {
- uint8_t command; /* ISKU_COMMAND_KEY_MASK */
- uint8_t size; /* 6 */
- uint8_t profile_number; /* 0-4 */
- uint8_t mask;
- uint16_t checksum;
-} __packed;
-
-struct isku_keys_function {
- uint8_t data[0x29];
-} __packed;
-
-struct isku_keys_easyzone {
- uint8_t data[0x41];
-} __packed;
-
-struct isku_keys_media {
- uint8_t data[0x1d];
-} __packed;
-
-struct isku_keys_thumbster {
- uint8_t data[0x17];
-} __packed;
-
-struct isku_keys_macro {
- uint8_t data[0x23];
-} __packed;
-
-struct isku_keys_capslock {
- uint8_t data[0x6];
-} __packed;
-
-struct isku_macro {
- uint8_t data[0x823];
-} __packed;
-
-struct isku_light {
- uint8_t data[0xa];
-} __packed;
-
-struct isku_info {
- uint8_t data[2];
- uint8_t firmware_version;
- uint8_t unknown[3];
-} __packed;
-
-struct isku_talk {
- uint8_t data[0x10];
-} __packed;
-
-struct isku_last_set {
- uint8_t data[0x14];
-} __packed;
-
-enum isku_commands {
- ISKU_COMMAND_CONTROL = 0x4,
- ISKU_COMMAND_ACTUAL_PROFILE = 0x5,
- ISKU_COMMAND_KEY_MASK = 0x7,
- ISKU_COMMAND_KEYS_FUNCTION = 0x8,
- ISKU_COMMAND_KEYS_EASYZONE = 0x9,
- ISKU_COMMAND_KEYS_MEDIA = 0xa,
- ISKU_COMMAND_KEYS_THUMBSTER = 0xb,
- ISKU_COMMAND_KEYS_MACRO = 0xd,
- ISKU_COMMAND_MACRO = 0xe,
- ISKU_COMMAND_INFO = 0xf,
- ISKU_COMMAND_LIGHT = 0x10,
- ISKU_COMMAND_KEYS_CAPSLOCK = 0x13,
- ISKU_COMMAND_LAST_SET = 0x14,
- ISKU_COMMAND_15 = 0x15,
- ISKU_COMMAND_TALK = 0x16,
- ISKU_COMMAND_FIRMWARE_WRITE = 0x1b,
- ISKU_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c,
-};
-
-struct isku_report_button {
- uint8_t number; /* ISKU_REPORT_NUMBER_BUTTON */
- uint8_t zero;
- uint8_t event;
- uint8_t data1;
- uint8_t data2;
-};
-
-enum isku_report_numbers {
- ISKU_REPORT_NUMBER_BUTTON = 3,
-};
-
-enum isku_report_button_events {
- ISKU_REPORT_BUTTON_EVENT_PROFILE = 0x2,
-};
-
-struct isku_roccat_report {
- uint8_t event;
- uint8_t data1;
- uint8_t data2;
- uint8_t profile;
-} __packed;
-
-struct isku_device {
- int roccat_claimed;
- int chrdev_minor;
-
- struct mutex isku_lock;
-
- int actual_profile;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-kone.c b/ANDROID_3.4.5/drivers/hid/hid-roccat-kone.c
deleted file mode 100644
index 40090d60..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-kone.c
+++ /dev/null
@@ -1,913 +0,0 @@
-/*
- * Roccat Kone driver for Linux
- *
- * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-/*
- * Roccat Kone is a gamer mouse which consists of a mouse part and a keyboard
- * part. The keyboard part enables the mouse to execute stored macros with mixed
- * key- and button-events.
- *
- * TODO implement on-the-fly polling-rate change
- * The windows driver has the ability to change the polling rate of the
- * device on the press of a mousebutton.
- * Is it possible to remove and reinstall the urb in raw-event- or any
- * other handler, or to defer this action to be executed somewhere else?
- *
- * TODO is it possible to overwrite group for sysfs attributes via udev?
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/hid-roccat.h>
-#include "hid-ids.h"
-#include "hid-roccat-common.h"
-#include "hid-roccat-kone.h"
-
-static uint profile_numbers[5] = {0, 1, 2, 3, 4};
-
-static void kone_profile_activated(struct kone_device *kone, uint new_profile)
-{
- kone->actual_profile = new_profile;
- kone->actual_dpi = kone->profiles[new_profile - 1].startup_dpi;
-}
-
-static void kone_profile_report(struct kone_device *kone, uint new_profile)
-{
- struct kone_roccat_report roccat_report;
- roccat_report.event = kone_mouse_event_switch_profile;
- roccat_report.value = new_profile;
- roccat_report.key = 0;
- roccat_report_event(kone->chrdev_minor, (uint8_t *)&roccat_report);
-}
-
-static int kone_receive(struct usb_device *usb_dev, uint usb_command,
- void *data, uint size)
-{
- char *buf;
- int len;
-
- buf = kmalloc(size, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
- HID_REQ_GET_REPORT,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
-
- memcpy(data, buf, size);
- kfree(buf);
- return ((len < 0) ? len : ((len != size) ? -EIO : 0));
-}
-
-static int kone_send(struct usb_device *usb_dev, uint usb_command,
- void const *data, uint size)
-{
- char *buf;
- int len;
-
- buf = kmemdup(data, size, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
- HID_REQ_SET_REPORT,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
- usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
-
- kfree(buf);
- return ((len < 0) ? len : ((len != size) ? -EIO : 0));
-}
-
-/* kone_class is used for creating sysfs attributes via roccat char device */
-static struct class *kone_class;
-
-static void kone_set_settings_checksum(struct kone_settings *settings)
-{
- uint16_t checksum = 0;
- unsigned char *address = (unsigned char *)settings;
- int i;
-
- for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address)
- checksum += *address;
- settings->checksum = cpu_to_le16(checksum);
-}
-
-/*
- * Checks success after writing data to mouse
- * On success returns 0
- * On failure returns errno
- */
-static int kone_check_write(struct usb_device *usb_dev)
-{
- int retval;
- uint8_t data;
-
- do {
- /*
- * Mouse needs 50 msecs until it says ok, but there are
- * 30 more msecs needed for next write to work.
- */
- msleep(80);
-
- retval = kone_receive(usb_dev,
- kone_command_confirm_write, &data, 1);
- if (retval)
- return retval;
-
- /*
- * value of 3 seems to mean something like
- * "not finished yet, but it looks good"
- * So check again after a moment.
- */
- } while (data == 3);
-
- if (data == 1) /* everything alright */
- return 0;
-
- /* unknown answer */
- hid_err(usb_dev, "got retval %d when checking write\n", data);
- return -EIO;
-}
-
-/*
- * Reads settings from mouse and stores it in @buf
- * On success returns 0
- * On failure returns errno
- */
-static int kone_get_settings(struct usb_device *usb_dev,
- struct kone_settings *buf)
-{
- return kone_receive(usb_dev, kone_command_settings, buf,
- sizeof(struct kone_settings));
-}
-
-/*
- * Writes settings from @buf to mouse
- * On success returns 0
- * On failure returns errno
- */
-static int kone_set_settings(struct usb_device *usb_dev,
- struct kone_settings const *settings)
-{
- int retval;
- retval = kone_send(usb_dev, kone_command_settings,
- settings, sizeof(struct kone_settings));
- if (retval)
- return retval;
- return kone_check_write(usb_dev);
-}
-
-/*
- * Reads profile data from mouse and stores it in @buf
- * @number: profile number to read
- * On success returns 0
- * On failure returns errno
- */
-static int kone_get_profile(struct usb_device *usb_dev,
- struct kone_profile *buf, int number)
-{
- int len;
-
- if (number < 1 || number > 5)
- return -EINVAL;
-
- len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
- USB_REQ_CLEAR_FEATURE,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- kone_command_profile, number, buf,
- sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT);
-
- if (len != sizeof(struct kone_profile))
- return -EIO;
-
- return 0;
-}
-
-/*
- * Writes profile data to mouse.
- * @number: profile number to write
- * On success returns 0
- * On failure returns errno
- */
-static int kone_set_profile(struct usb_device *usb_dev,
- struct kone_profile const *profile, int number)
-{
- int len;
-
- if (number < 1 || number > 5)
- return -EINVAL;
-
- len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
- USB_REQ_SET_CONFIGURATION,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
- kone_command_profile, number, (void *)profile,
- sizeof(struct kone_profile),
- USB_CTRL_SET_TIMEOUT);
-
- if (len != sizeof(struct kone_profile))
- return len;
-
- if (kone_check_write(usb_dev))
- return -EIO;
-
- return 0;
-}
-
-/*
- * Reads value of "fast-clip-weight" and stores it in @result
- * On success returns 0
- * On failure returns errno
- */
-static int kone_get_weight(struct usb_device *usb_dev, int *result)
-{
- int retval;
- uint8_t data;
-
- retval = kone_receive(usb_dev, kone_command_weight, &data, 1);
-
- if (retval)
- return retval;
-
- *result = (int)data;
- return 0;
-}
-
-/*
- * Reads firmware_version of mouse and stores it in @result
- * On success returns 0
- * On failure returns errno
- */
-static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
-{
- int retval;
- uint16_t data;
-
- retval = kone_receive(usb_dev, kone_command_firmware_version,
- &data, 2);
- if (retval)
- return retval;
-
- *result = le16_to_cpu(data);
- return 0;
-}
-
-static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct kone_settings))
- return 0;
-
- if (off + count > sizeof(struct kone_settings))
- count = sizeof(struct kone_settings) - off;
-
- mutex_lock(&kone->kone_lock);
- memcpy(buf, ((char const *)&kone->settings) + off, count);
- mutex_unlock(&kone->kone_lock);
-
- return count;
-}
-
-/*
- * Writing settings automatically activates startup_profile.
- * This function keeps values in kone_device up to date and assumes that in
- * case of error the old data is still valid
- */
-static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count) {
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval = 0, difference, old_profile;
-
- /* I need to get my data in one piece */
- if (off != 0 || count != sizeof(struct kone_settings))
- return -EINVAL;
-
- mutex_lock(&kone->kone_lock);
- difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings));
- if (difference) {
- retval = kone_set_settings(usb_dev,
- (struct kone_settings const *)buf);
- if (retval) {
- mutex_unlock(&kone->kone_lock);
- return retval;
- }
-
- old_profile = kone->settings.startup_profile;
- memcpy(&kone->settings, buf, sizeof(struct kone_settings));
-
- kone_profile_activated(kone, kone->settings.startup_profile);
-
- if (kone->settings.startup_profile != old_profile)
- kone_profile_report(kone, kone->settings.startup_profile);
- }
- mutex_unlock(&kone->kone_lock);
-
- return sizeof(struct kone_settings);
-}
-
-static ssize_t kone_sysfs_read_profilex(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr,
- char *buf, loff_t off, size_t count) {
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct kone_profile))
- return 0;
-
- if (off + count > sizeof(struct kone_profile))
- count = sizeof(struct kone_profile) - off;
-
- mutex_lock(&kone->kone_lock);
- memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count);
- mutex_unlock(&kone->kone_lock);
-
- return count;
-}
-
-/* Writes data only if different to stored data */
-static ssize_t kone_sysfs_write_profilex(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr,
- char *buf, loff_t off, size_t count) {
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- struct kone_profile *profile;
- int retval = 0, difference;
-
- /* I need to get my data in one piece */
- if (off != 0 || count != sizeof(struct kone_profile))
- return -EINVAL;
-
- profile = &kone->profiles[*(uint *)(attr->private)];
-
- mutex_lock(&kone->kone_lock);
- difference = memcmp(buf, profile, sizeof(struct kone_profile));
- if (difference) {
- retval = kone_set_profile(usb_dev,
- (struct kone_profile const *)buf,
- *(uint *)(attr->private) + 1);
- if (!retval)
- memcpy(profile, buf, sizeof(struct kone_profile));
- }
- mutex_unlock(&kone->kone_lock);
-
- if (retval)
- return retval;
-
- return sizeof(struct kone_profile);
-}
-
-static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kone_device *kone =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
-}
-
-static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kone_device *kone =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi);
-}
-
-/* weight is read each time, since we don't get informed when it's changed */
-static ssize_t kone_sysfs_show_weight(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kone_device *kone;
- struct usb_device *usb_dev;
- int weight = 0;
- int retval;
-
- dev = dev->parent->parent;
- kone = hid_get_drvdata(dev_get_drvdata(dev));
- usb_dev = interface_to_usbdev(to_usb_interface(dev));
-
- mutex_lock(&kone->kone_lock);
- retval = kone_get_weight(usb_dev, &weight);
- mutex_unlock(&kone->kone_lock);
-
- if (retval)
- return retval;
- return snprintf(buf, PAGE_SIZE, "%d\n", weight);
-}
-
-static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kone_device *kone =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
-}
-
-static ssize_t kone_sysfs_show_tcu(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kone_device *kone =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu);
-}
-
-static int kone_tcu_command(struct usb_device *usb_dev, int number)
-{
- unsigned char value;
- value = number;
- return kone_send(usb_dev, kone_command_calibrate, &value, 1);
-}
-
-/*
- * Calibrating the tcu is the only action that changes settings data inside the
- * mouse, so this data needs to be reread
- */
-static ssize_t kone_sysfs_set_tcu(struct device *dev,
- struct device_attribute *attr, char const *buf, size_t size)
-{
- struct kone_device *kone;
- struct usb_device *usb_dev;
- int retval;
- unsigned long state;
-
- dev = dev->parent->parent;
- kone = hid_get_drvdata(dev_get_drvdata(dev));
- usb_dev = interface_to_usbdev(to_usb_interface(dev));
-
- retval = strict_strtoul(buf, 10, &state);
- if (retval)
- return retval;
-
- if (state != 0 && state != 1)
- return -EINVAL;
-
- mutex_lock(&kone->kone_lock);
-
- if (state == 1) { /* state activate */
- retval = kone_tcu_command(usb_dev, 1);
- if (retval)
- goto exit_unlock;
- retval = kone_tcu_command(usb_dev, 2);
- if (retval)
- goto exit_unlock;
- ssleep(5); /* tcu needs this time for calibration */
- retval = kone_tcu_command(usb_dev, 3);
- if (retval)
- goto exit_unlock;
- retval = kone_tcu_command(usb_dev, 0);
- if (retval)
- goto exit_unlock;
- retval = kone_tcu_command(usb_dev, 4);
- if (retval)
- goto exit_unlock;
- /*
- * Kone needs this time to settle things.
- * Reading settings too early will result in invalid data.
- * Roccat's driver waits 1 sec, maybe this time could be
- * shortened.
- */
- ssleep(1);
- }
-
- /* calibration changes values in settings, so reread */
- retval = kone_get_settings(usb_dev, &kone->settings);
- if (retval)
- goto exit_no_settings;
-
- /* only write settings back if activation state is different */
- if (kone->settings.tcu != state) {
- kone->settings.tcu = state;
- kone_set_settings_checksum(&kone->settings);
-
- retval = kone_set_settings(usb_dev, &kone->settings);
- if (retval) {
- hid_err(usb_dev, "couldn't set tcu state\n");
- /*
- * try to reread valid settings into buffer overwriting
- * first error code
- */
- retval = kone_get_settings(usb_dev, &kone->settings);
- if (retval)
- goto exit_no_settings;
- goto exit_unlock;
- }
- /* calibration resets profile */
- kone_profile_activated(kone, kone->settings.startup_profile);
- }
-
- retval = size;
-exit_no_settings:
- hid_err(usb_dev, "couldn't read settings\n");
-exit_unlock:
- mutex_unlock(&kone->kone_lock);
- return retval;
-}
-
-static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kone_device *kone =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile);
-}
-
-static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
- struct device_attribute *attr, char const *buf, size_t size)
-{
- struct kone_device *kone;
- struct usb_device *usb_dev;
- int retval;
- unsigned long new_startup_profile;
-
- dev = dev->parent->parent;
- kone = hid_get_drvdata(dev_get_drvdata(dev));
- usb_dev = interface_to_usbdev(to_usb_interface(dev));
-
- retval = strict_strtoul(buf, 10, &new_startup_profile);
- if (retval)
- return retval;
-
- if (new_startup_profile < 1 || new_startup_profile > 5)
- return -EINVAL;
-
- mutex_lock(&kone->kone_lock);
-
- kone->settings.startup_profile = new_startup_profile;
- kone_set_settings_checksum(&kone->settings);
-
- retval = kone_set_settings(usb_dev, &kone->settings);
- if (retval) {
- mutex_unlock(&kone->kone_lock);
- return retval;
- }
-
- /* changing the startup profile immediately activates this profile */
- kone_profile_activated(kone, new_startup_profile);
- kone_profile_report(kone, new_startup_profile);
-
- mutex_unlock(&kone->kone_lock);
- return size;
-}
-
-static struct device_attribute kone_attributes[] = {
- /*
- * Read actual dpi settings.
- * Returns raw value for further processing. Refer to enum
- * kone_polling_rates to get real value.
- */
- __ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL),
- __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL),
-
- /*
- * The mouse can be equipped with one of four supplied weights from 5
- * to 20 grams which are recognized and its value can be read out.
- * This returns the raw value reported by the mouse for easy evaluation
- * by software. Refer to enum kone_weights to get corresponding real
- * weight.
- */
- __ATTR(weight, 0440, kone_sysfs_show_weight, NULL),
-
- /*
- * Prints firmware version stored in mouse as integer.
- * The raw value reported by the mouse is returned for easy evaluation,
- * to get the real version number the decimal point has to be shifted 2
- * positions to the left. E.g. a value of 138 means 1.38.
- */
- __ATTR(firmware_version, 0440,
- kone_sysfs_show_firmware_version, NULL),
-
- /*
- * Prints state of Tracking Control Unit as number where 0 = off and
- * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
- * activates the tcu
- */
- __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu),
-
- /* Prints and takes the number of the profile the mouse starts with */
- __ATTR(startup_profile, 0660,
- kone_sysfs_show_startup_profile,
- kone_sysfs_set_startup_profile),
- __ATTR_NULL
-};
-
-static struct bin_attribute kone_bin_attributes[] = {
- {
- .attr = { .name = "settings", .mode = 0660 },
- .size = sizeof(struct kone_settings),
- .read = kone_sysfs_read_settings,
- .write = kone_sysfs_write_settings
- },
- {
- .attr = { .name = "profile1", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5", .mode = 0660 },
- .size = sizeof(struct kone_profile),
- .read = kone_sysfs_read_profilex,
- .write = kone_sysfs_write_profilex,
- .private = &profile_numbers[4]
- },
- __ATTR_NULL
-};
-
-static int kone_init_kone_device_struct(struct usb_device *usb_dev,
- struct kone_device *kone)
-{
- uint i;
- int retval;
-
- mutex_init(&kone->kone_lock);
-
- for (i = 0; i < 5; ++i) {
- retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1);
- if (retval)
- return retval;
- }
-
- retval = kone_get_settings(usb_dev, &kone->settings);
- if (retval)
- return retval;
-
- retval = kone_get_firmware_version(usb_dev, &kone->firmware_version);
- if (retval)
- return retval;
-
- kone_profile_activated(kone, kone->settings.startup_profile);
-
- return 0;
-}
-
-/*
- * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to
- * mousepart if usb_hid is compiled into the kernel and kone is compiled as
- * module.
- * Secial behaviour is bound only to mousepart since only mouseevents contain
- * additional notifications.
- */
-static int kone_init_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct usb_device *usb_dev = interface_to_usbdev(intf);
- struct kone_device *kone;
- int retval;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_MOUSE) {
-
- kone = kzalloc(sizeof(*kone), GFP_KERNEL);
- if (!kone) {
- hid_err(hdev, "can't alloc device descriptor\n");
- return -ENOMEM;
- }
- hid_set_drvdata(hdev, kone);
-
- retval = kone_init_kone_device_struct(usb_dev, kone);
- if (retval) {
- hid_err(hdev, "couldn't init struct kone_device\n");
- goto exit_free;
- }
-
- retval = roccat_connect(kone_class, hdev,
- sizeof(struct kone_roccat_report));
- if (retval < 0) {
- hid_err(hdev, "couldn't init char dev\n");
- /* be tolerant about not getting chrdev */
- } else {
- kone->roccat_claimed = 1;
- kone->chrdev_minor = retval;
- }
- } else {
- hid_set_drvdata(hdev, NULL);
- }
-
- return 0;
-exit_free:
- kfree(kone);
- return retval;
-}
-
-static void kone_remove_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct kone_device *kone;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_MOUSE) {
- kone = hid_get_drvdata(hdev);
- if (kone->roccat_claimed)
- roccat_disconnect(kone->chrdev_minor);
- kfree(hid_get_drvdata(hdev));
- }
-}
-
-static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int retval;
-
- retval = hid_parse(hdev);
- if (retval) {
- hid_err(hdev, "parse failed\n");
- goto exit;
- }
-
- retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (retval) {
- hid_err(hdev, "hw start failed\n");
- goto exit;
- }
-
- retval = kone_init_specials(hdev);
- if (retval) {
- hid_err(hdev, "couldn't install mouse\n");
- goto exit_stop;
- }
-
- return 0;
-
-exit_stop:
- hid_hw_stop(hdev);
-exit:
- return retval;
-}
-
-static void kone_remove(struct hid_device *hdev)
-{
- kone_remove_specials(hdev);
- hid_hw_stop(hdev);
-}
-
-/* handle special events and keep actual profile and dpi values up to date */
-static void kone_keep_values_up_to_date(struct kone_device *kone,
- struct kone_mouse_event const *event)
-{
- switch (event->event) {
- case kone_mouse_event_switch_profile:
- kone->actual_dpi = kone->profiles[event->value - 1].
- startup_dpi;
- case kone_mouse_event_osd_profile:
- kone->actual_profile = event->value;
- break;
- case kone_mouse_event_switch_dpi:
- case kone_mouse_event_osd_dpi:
- kone->actual_dpi = event->value;
- break;
- }
-}
-
-static void kone_report_to_chrdev(struct kone_device const *kone,
- struct kone_mouse_event const *event)
-{
- struct kone_roccat_report roccat_report;
-
- switch (event->event) {
- case kone_mouse_event_switch_profile:
- case kone_mouse_event_switch_dpi:
- case kone_mouse_event_osd_profile:
- case kone_mouse_event_osd_dpi:
- roccat_report.event = event->event;
- roccat_report.value = event->value;
- roccat_report.key = 0;
- roccat_report_event(kone->chrdev_minor,
- (uint8_t *)&roccat_report);
- break;
- case kone_mouse_event_call_overlong_macro:
- if (event->value == kone_keystroke_action_press) {
- roccat_report.event = kone_mouse_event_call_overlong_macro;
- roccat_report.value = kone->actual_profile;
- roccat_report.key = event->macro_key;
- roccat_report_event(kone->chrdev_minor,
- (uint8_t *)&roccat_report);
- }
- break;
- }
-
-}
-
-/*
- * Is called for keyboard- and mousepart.
- * Only mousepart gets informations about special events in its extended event
- * structure.
- */
-static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,
- u8 *data, int size)
-{
- struct kone_device *kone = hid_get_drvdata(hdev);
- struct kone_mouse_event *event = (struct kone_mouse_event *)data;
-
- /* keyboard events are always processed by default handler */
- if (size != sizeof(struct kone_mouse_event))
- return 0;
-
- if (kone == NULL)
- return 0;
-
- /*
- * Firmware 1.38 introduced new behaviour for tilt and special buttons.
- * Pressed button is reported in each movement event.
- * Workaround sends only one event per press.
- */
- if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5))
- memcpy(&kone->last_mouse_event, event,
- sizeof(struct kone_mouse_event));
- else
- memset(&event->tilt, 0, 5);
-
- kone_keep_values_up_to_date(kone, event);
-
- if (kone->roccat_claimed)
- kone_report_to_chrdev(kone, event);
-
- return 0; /* always do further processing */
-}
-
-static const struct hid_device_id kone_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, kone_devices);
-
-static struct hid_driver kone_driver = {
- .name = "kone",
- .id_table = kone_devices,
- .probe = kone_probe,
- .remove = kone_remove,
- .raw_event = kone_raw_event
-};
-
-static int __init kone_init(void)
-{
- int retval;
-
- /* class name has to be same as driver name */
- kone_class = class_create(THIS_MODULE, "kone");
- if (IS_ERR(kone_class))
- return PTR_ERR(kone_class);
- kone_class->dev_attrs = kone_attributes;
- kone_class->dev_bin_attrs = kone_bin_attributes;
-
- retval = hid_register_driver(&kone_driver);
- if (retval)
- class_destroy(kone_class);
- return retval;
-}
-
-static void __exit kone_exit(void)
-{
- hid_unregister_driver(&kone_driver);
- class_destroy(kone_class);
-}
-
-module_init(kone_init);
-module_exit(kone_exit);
-
-MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat Kone driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-kone.h b/ANDROID_3.4.5/drivers/hid/hid-roccat-kone.h
deleted file mode 100644
index 64abb5b8..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-kone.h
+++ /dev/null
@@ -1,226 +0,0 @@
-#ifndef __HID_ROCCAT_KONE_H
-#define __HID_ROCCAT_KONE_H
-
-/*
- * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/types.h>
-
-struct kone_keystroke {
- uint8_t key;
- uint8_t action;
- uint16_t period; /* in milliseconds */
-} __attribute__ ((__packed__));
-
-enum kone_keystroke_buttons {
- kone_keystroke_button_1 = 0xf0, /* left mouse button */
- kone_keystroke_button_2 = 0xf1, /* right mouse button */
- kone_keystroke_button_3 = 0xf2, /* wheel */
- kone_keystroke_button_9 = 0xf3, /* side button up */
- kone_keystroke_button_8 = 0xf4 /* side button down */
-};
-
-enum kone_keystroke_actions {
- kone_keystroke_action_press = 0,
- kone_keystroke_action_release = 1
-};
-
-struct kone_button_info {
- uint8_t number; /* range 1-8 */
- uint8_t type;
- uint8_t macro_type; /* 0 = short, 1 = overlong */
- uint8_t macro_set_name[16]; /* can be max 15 chars long */
- uint8_t macro_name[16]; /* can be max 15 chars long */
- uint8_t count;
- struct kone_keystroke keystrokes[20];
-} __attribute__ ((__packed__));
-
-enum kone_button_info_types {
- /* valid button types until firmware 1.32 */
- kone_button_info_type_button_1 = 0x1, /* click (left mouse button) */
- kone_button_info_type_button_2 = 0x2, /* menu (right mouse button)*/
- kone_button_info_type_button_3 = 0x3, /* scroll (wheel) */
- kone_button_info_type_double_click = 0x4,
- kone_button_info_type_key = 0x5,
- kone_button_info_type_macro = 0x6,
- kone_button_info_type_off = 0x7,
- /* TODO clarify function and rename */
- kone_button_info_type_osd_xy_prescaling = 0x8,
- kone_button_info_type_osd_dpi = 0x9,
- kone_button_info_type_osd_profile = 0xa,
- kone_button_info_type_button_9 = 0xb, /* ie forward */
- kone_button_info_type_button_8 = 0xc, /* ie backward */
- kone_button_info_type_dpi_up = 0xd, /* internal */
- kone_button_info_type_dpi_down = 0xe, /* internal */
- kone_button_info_type_button_7 = 0xf, /* tilt left */
- kone_button_info_type_button_6 = 0x10, /* tilt right */
- kone_button_info_type_profile_up = 0x11, /* internal */
- kone_button_info_type_profile_down = 0x12, /* internal */
- /* additional valid button types since firmware 1.38 */
- kone_button_info_type_multimedia_open_player = 0x20,
- kone_button_info_type_multimedia_next_track = 0x21,
- kone_button_info_type_multimedia_prev_track = 0x22,
- kone_button_info_type_multimedia_play_pause = 0x23,
- kone_button_info_type_multimedia_stop = 0x24,
- kone_button_info_type_multimedia_mute = 0x25,
- kone_button_info_type_multimedia_volume_up = 0x26,
- kone_button_info_type_multimedia_volume_down = 0x27
-};
-
-enum kone_button_info_numbers {
- kone_button_top = 1,
- kone_button_wheel_tilt_left = 2,
- kone_button_wheel_tilt_right = 3,
- kone_button_forward = 4,
- kone_button_backward = 5,
- kone_button_middle = 6,
- kone_button_plus = 7,
- kone_button_minus = 8,
-};
-
-struct kone_light_info {
- uint8_t number; /* number of light 1-5 */
- uint8_t mod; /* 1 = on, 2 = off */
- uint8_t red; /* range 0x00-0xff */
- uint8_t green; /* range 0x00-0xff */
- uint8_t blue; /* range 0x00-0xff */
-} __attribute__ ((__packed__));
-
-struct kone_profile {
- uint16_t size; /* always 975 */
- uint16_t unused; /* always 0 */
-
- /*
- * range 1-5
- * This number does not need to correspond with location where profile
- * saved
- */
- uint8_t profile; /* range 1-5 */
-
- uint16_t main_sensitivity; /* range 100-1000 */
- uint8_t xy_sensitivity_enabled; /* 1 = on, 2 = off */
- uint16_t x_sensitivity; /* range 100-1000 */
- uint16_t y_sensitivity; /* range 100-1000 */
- uint8_t dpi_rate; /* bit 1 = 800, ... */
- uint8_t startup_dpi; /* range 1-6 */
- uint8_t polling_rate; /* 1 = 125Hz, 2 = 500Hz, 3 = 1000Hz */
- /* kone has no dcu
- * value is always 2 in firmwares <= 1.32 and
- * 1 in firmwares > 1.32
- */
- uint8_t dcu_flag;
- uint8_t light_effect_1; /* range 1-3 */
- uint8_t light_effect_2; /* range 1-5 */
- uint8_t light_effect_3; /* range 1-4 */
- uint8_t light_effect_speed; /* range 0-255 */
-
- struct kone_light_info light_infos[5];
- /* offset is kone_button_info_numbers - 1 */
- struct kone_button_info button_infos[8];
-
- uint16_t checksum; /* \brief holds checksum of struct */
-} __attribute__ ((__packed__));
-
-enum kone_polling_rates {
- kone_polling_rate_125 = 1,
- kone_polling_rate_500 = 2,
- kone_polling_rate_1000 = 3
-};
-
-struct kone_settings {
- uint16_t size; /* always 36 */
- uint8_t startup_profile; /* 1-5 */
- uint8_t unknown1;
- uint8_t tcu; /* 0 = off, 1 = on */
- uint8_t unknown2[23];
- uint8_t calibration_data[4];
- uint8_t unknown3[2];
- uint16_t checksum;
-} __attribute__ ((__packed__));
-
-/*
- * 12 byte mouse event read by interrupt_read
- */
-struct kone_mouse_event {
- uint8_t report_number; /* always 1 */
- uint8_t button;
- uint16_t x;
- uint16_t y;
- uint8_t wheel; /* up = 1, down = -1 */
- uint8_t tilt; /* right = 1, left = -1 */
- uint8_t unknown;
- uint8_t event;
- uint8_t value; /* press = 0, release = 1 */
- uint8_t macro_key; /* 0 to 8 */
-} __attribute__ ((__packed__));
-
-enum kone_mouse_events {
- /* osd events are thought to be display on screen */
- kone_mouse_event_osd_dpi = 0xa0,
- kone_mouse_event_osd_profile = 0xb0,
- /* TODO clarify meaning and occurence of kone_mouse_event_calibration */
- kone_mouse_event_calibration = 0xc0,
- kone_mouse_event_call_overlong_macro = 0xe0,
- /* switch events notify if user changed values with mousebutton click */
- kone_mouse_event_switch_dpi = 0xf0,
- kone_mouse_event_switch_profile = 0xf1
-};
-
-enum kone_commands {
- kone_command_profile = 0x5a,
- kone_command_settings = 0x15a,
- kone_command_firmware_version = 0x25a,
- kone_command_weight = 0x45a,
- kone_command_calibrate = 0x55a,
- kone_command_confirm_write = 0x65a,
- kone_command_firmware = 0xe5a
-};
-
-struct kone_roccat_report {
- uint8_t event;
- uint8_t value; /* holds dpi or profile value */
- uint8_t key; /* macro key on overlong macro execution */
-} __attribute__ ((__packed__));
-
-struct kone_device {
- /*
- * Storing actual values when we get informed about changes since there
- * is no way of getting this information from the device on demand
- */
- int actual_profile, actual_dpi;
- /* Used for neutralizing abnormal button behaviour */
- struct kone_mouse_event last_mouse_event;
-
- /*
- * It's unlikely that multiple sysfs attributes are accessed at a time,
- * so only one mutex is used to secure hardware access and profiles and
- * settings of this struct.
- */
- struct mutex kone_lock;
-
- /*
- * Storing the data here reduces IO and ensures that data is available
- * when its needed (E.g. interrupt handler).
- */
- struct kone_profile profiles[5];
- struct kone_settings settings;
-
- /*
- * firmware doesn't change unless firmware update is implemented,
- * so it's read only once
- */
- int firmware_version;
-
- int roccat_claimed;
- int chrdev_minor;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-koneplus.c b/ANDROID_3.4.5/drivers/hid/hid-roccat-koneplus.c
deleted file mode 100644
index 59e47770..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-koneplus.c
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * Roccat Kone[+] driver for Linux
- *
- * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-/*
- * Roccat Kone[+] is an updated/improved version of the Kone with more memory
- * and functionality and without the non-standard behaviours the Kone had.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/hid-roccat.h>
-#include "hid-ids.h"
-#include "hid-roccat-common.h"
-#include "hid-roccat-koneplus.h"
-
-static uint profile_numbers[5] = {0, 1, 2, 3, 4};
-
-static struct class *koneplus_class;
-
-static void koneplus_profile_activated(struct koneplus_device *koneplus,
- uint new_profile)
-{
- koneplus->actual_profile = new_profile;
-}
-
-static int koneplus_send_control(struct usb_device *usb_dev, uint value,
- enum koneplus_control_requests request)
-{
- struct koneplus_control control;
-
- if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
- request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
- value > 4)
- return -EINVAL;
-
- control.command = KONEPLUS_COMMAND_CONTROL;
- control.value = value;
- control.request = request;
-
- return roccat_common_send(usb_dev, KONEPLUS_COMMAND_CONTROL,
- &control, sizeof(struct koneplus_control));
-}
-
-static int koneplus_receive_control_status(struct usb_device *usb_dev)
-{
- int retval;
- struct koneplus_control control;
-
- do {
- retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_CONTROL,
- &control, sizeof(struct koneplus_control));
-
- /* check if we get a completely wrong answer */
- if (retval)
- return retval;
-
- if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OK)
- return 0;
-
- /* indicates that hardware needs some more time to complete action */
- if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) {
- msleep(500); /* windows driver uses 1000 */
- continue;
- }
-
- /* seems to be critical - replug necessary */
- if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
- return -EINVAL;
-
- hid_err(usb_dev, "koneplus_receive_control_status: "
- "unknown response value 0x%x\n", control.value);
- return -EINVAL;
- } while (1);
-}
-
-static int koneplus_send(struct usb_device *usb_dev, uint command,
- void const *buf, uint size)
-{
- int retval;
-
- retval = roccat_common_send(usb_dev, command, buf, size);
- if (retval)
- return retval;
-
- return koneplus_receive_control_status(usb_dev);
-}
-
-static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
- enum koneplus_control_requests request)
-{
- int retval;
-
- retval = koneplus_send_control(usb_dev, number, request);
- if (retval)
- return retval;
-
- /* allow time to settle things - windows driver uses 500 */
- msleep(100);
-
- retval = koneplus_receive_control_status(usb_dev);
- if (retval)
- return retval;
-
- return 0;
-}
-
-static int koneplus_get_info(struct usb_device *usb_dev,
- struct koneplus_info *buf)
-{
- return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_INFO,
- buf, sizeof(struct koneplus_info));
-}
-
-static int koneplus_get_profile_settings(struct usb_device *usb_dev,
- struct koneplus_profile_settings *buf, uint number)
-{
- int retval;
-
- retval = koneplus_select_profile(usb_dev, number,
- KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
- if (retval)
- return retval;
-
- return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS,
- buf, sizeof(struct koneplus_profile_settings));
-}
-
-static int koneplus_set_profile_settings(struct usb_device *usb_dev,
- struct koneplus_profile_settings const *settings)
-{
- return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS,
- settings, sizeof(struct koneplus_profile_settings));
-}
-
-static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
- struct koneplus_profile_buttons *buf, int number)
-{
- int retval;
-
- retval = koneplus_select_profile(usb_dev, number,
- KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
- if (retval)
- return retval;
-
- return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS,
- buf, sizeof(struct koneplus_profile_buttons));
-}
-
-static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
- struct koneplus_profile_buttons const *buttons)
-{
- return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS,
- buttons, sizeof(struct koneplus_profile_buttons));
-}
-
-/* retval is 0-4 on success, < 0 on error */
-static int koneplus_get_actual_profile(struct usb_device *usb_dev)
-{
- struct koneplus_actual_profile buf;
- int retval;
-
- retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE,
- &buf, sizeof(struct koneplus_actual_profile));
-
- return retval ? retval : buf.actual_profile;
-}
-
-static int koneplus_set_actual_profile(struct usb_device *usb_dev,
- int new_profile)
-{
- struct koneplus_actual_profile buf;
-
- buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE;
- buf.size = sizeof(struct koneplus_actual_profile);
- buf.actual_profile = new_profile;
-
- return koneplus_send(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE,
- &buf, sizeof(struct koneplus_actual_profile));
-}
-
-static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
- char *buf, loff_t off, size_t count,
- size_t real_size, uint command)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval;
-
- if (off >= real_size)
- return 0;
-
- if (off != 0 || count != real_size)
- return -EINVAL;
-
- mutex_lock(&koneplus->koneplus_lock);
- retval = roccat_common_receive(usb_dev, command, buf, real_size);
- mutex_unlock(&koneplus->koneplus_lock);
-
- if (retval)
- return retval;
-
- return real_size;
-}
-
-static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
- void const *buf, loff_t off, size_t count,
- size_t real_size, uint command)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval;
-
- if (off != 0 || count != real_size)
- return -EINVAL;
-
- mutex_lock(&koneplus->koneplus_lock);
- retval = koneplus_send(usb_dev, command, buf, real_size);
- mutex_unlock(&koneplus->koneplus_lock);
-
- if (retval)
- return retval;
-
- return real_size;
-}
-
-static ssize_t koneplus_sysfs_write_talk(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return koneplus_sysfs_write(fp, kobj, buf, off, count,
- sizeof(struct koneplus_talk), KONEPLUS_COMMAND_TALK);
-}
-
-static ssize_t koneplus_sysfs_write_macro(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return koneplus_sysfs_write(fp, kobj, buf, off, count,
- sizeof(struct koneplus_macro), KONEPLUS_COMMAND_MACRO);
-}
-
-static ssize_t koneplus_sysfs_read_sensor(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return koneplus_sysfs_read(fp, kobj, buf, off, count,
- sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR);
-}
-
-static ssize_t koneplus_sysfs_write_sensor(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return koneplus_sysfs_write(fp, kobj, buf, off, count,
- sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR);
-}
-
-static ssize_t koneplus_sysfs_write_tcu(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return koneplus_sysfs_write(fp, kobj, buf, off, count,
- sizeof(struct koneplus_tcu), KONEPLUS_COMMAND_TCU);
-}
-
-static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- return koneplus_sysfs_read(fp, kobj, buf, off, count,
- sizeof(struct koneplus_tcu_image), KONEPLUS_COMMAND_TCU);
-}
-
-static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct koneplus_profile_settings))
- return 0;
-
- if (off + count > sizeof(struct koneplus_profile_settings))
- count = sizeof(struct koneplus_profile_settings) - off;
-
- mutex_lock(&koneplus->koneplus_lock);
- memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off,
- count);
- mutex_unlock(&koneplus->koneplus_lock);
-
- return count;
-}
-
-static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval = 0;
- int difference;
- int profile_number;
- struct koneplus_profile_settings *profile_settings;
-
- if (off != 0 || count != sizeof(struct koneplus_profile_settings))
- return -EINVAL;
-
- profile_number = ((struct koneplus_profile_settings const *)buf)->number;
- profile_settings = &koneplus->profile_settings[profile_number];
-
- mutex_lock(&koneplus->koneplus_lock);
- difference = memcmp(buf, profile_settings,
- sizeof(struct koneplus_profile_settings));
- if (difference) {
- retval = koneplus_set_profile_settings(usb_dev,
- (struct koneplus_profile_settings const *)buf);
- if (!retval)
- memcpy(profile_settings, buf,
- sizeof(struct koneplus_profile_settings));
- }
- mutex_unlock(&koneplus->koneplus_lock);
-
- if (retval)
- return retval;
-
- return sizeof(struct koneplus_profile_settings);
-}
-
-static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct koneplus_profile_buttons))
- return 0;
-
- if (off + count > sizeof(struct koneplus_profile_buttons))
- count = sizeof(struct koneplus_profile_buttons) - off;
-
- mutex_lock(&koneplus->koneplus_lock);
- memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off,
- count);
- mutex_unlock(&koneplus->koneplus_lock);
-
- return count;
-}
-
-static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval = 0;
- int difference;
- uint profile_number;
- struct koneplus_profile_buttons *profile_buttons;
-
- if (off != 0 || count != sizeof(struct koneplus_profile_buttons))
- return -EINVAL;
-
- profile_number = ((struct koneplus_profile_buttons const *)buf)->number;
- profile_buttons = &koneplus->profile_buttons[profile_number];
-
- mutex_lock(&koneplus->koneplus_lock);
- difference = memcmp(buf, profile_buttons,
- sizeof(struct koneplus_profile_buttons));
- if (difference) {
- retval = koneplus_set_profile_buttons(usb_dev,
- (struct koneplus_profile_buttons const *)buf);
- if (!retval)
- memcpy(profile_buttons, buf,
- sizeof(struct koneplus_profile_buttons));
- }
- mutex_unlock(&koneplus->koneplus_lock);
-
- if (retval)
- return retval;
-
- return sizeof(struct koneplus_profile_buttons);
-}
-
-static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct koneplus_device *koneplus =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile);
-}
-
-static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev,
- struct device_attribute *attr, char const *buf, size_t size)
-{
- struct koneplus_device *koneplus;
- struct usb_device *usb_dev;
- unsigned long profile;
- int retval;
- struct koneplus_roccat_report roccat_report;
-
- dev = dev->parent->parent;
- koneplus = hid_get_drvdata(dev_get_drvdata(dev));
- usb_dev = interface_to_usbdev(to_usb_interface(dev));
-
- retval = strict_strtoul(buf, 10, &profile);
- if (retval)
- return retval;
-
- if (profile > 4)
- return -EINVAL;
-
- mutex_lock(&koneplus->koneplus_lock);
-
- retval = koneplus_set_actual_profile(usb_dev, profile);
- if (retval) {
- mutex_unlock(&koneplus->koneplus_lock);
- return retval;
- }
-
- koneplus_profile_activated(koneplus, profile);
-
- roccat_report.type = KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE;
- roccat_report.data1 = profile + 1;
- roccat_report.data2 = 0;
- roccat_report.profile = profile + 1;
- roccat_report_event(koneplus->chrdev_minor,
- (uint8_t const *)&roccat_report);
-
- mutex_unlock(&koneplus->koneplus_lock);
-
- return size;
-}
-
-static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct koneplus_device *koneplus =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version);
-}
-
-static struct device_attribute koneplus_attributes[] = {
- __ATTR(actual_profile, 0660,
- koneplus_sysfs_show_actual_profile,
- koneplus_sysfs_set_actual_profile),
- __ATTR(startup_profile, 0660,
- koneplus_sysfs_show_actual_profile,
- koneplus_sysfs_set_actual_profile),
- __ATTR(firmware_version, 0440,
- koneplus_sysfs_show_firmware_version, NULL),
- __ATTR_NULL
-};
-
-static struct bin_attribute koneplus_bin_attributes[] = {
- {
- .attr = { .name = "sensor", .mode = 0660 },
- .size = sizeof(struct koneplus_sensor),
- .read = koneplus_sysfs_read_sensor,
- .write = koneplus_sysfs_write_sensor
- },
- {
- .attr = { .name = "tcu", .mode = 0220 },
- .size = sizeof(struct koneplus_tcu),
- .write = koneplus_sysfs_write_tcu
- },
- {
- .attr = { .name = "tcu_image", .mode = 0440 },
- .size = sizeof(struct koneplus_tcu_image),
- .read = koneplus_sysfs_read_tcu_image
- },
- {
- .attr = { .name = "profile_settings", .mode = 0220 },
- .size = sizeof(struct koneplus_profile_settings),
- .write = koneplus_sysfs_write_profile_settings
- },
- {
- .attr = { .name = "profile1_settings", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_settings),
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_settings", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_settings),
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_settings", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_settings),
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_settings", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_settings),
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_settings", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_settings),
- .read = koneplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[4]
- },
- {
- .attr = { .name = "profile_buttons", .mode = 0220 },
- .size = sizeof(struct koneplus_profile_buttons),
- .write = koneplus_sysfs_write_profile_buttons
- },
- {
- .attr = { .name = "profile1_buttons", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_buttons),
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_buttons", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_buttons),
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_buttons", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_buttons),
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_buttons", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_buttons),
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_buttons", .mode = 0440 },
- .size = sizeof(struct koneplus_profile_buttons),
- .read = koneplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[4]
- },
- {
- .attr = { .name = "macro", .mode = 0220 },
- .size = sizeof(struct koneplus_macro),
- .write = koneplus_sysfs_write_macro
- },
- {
- .attr = { .name = "talk", .mode = 0220 },
- .size = sizeof(struct koneplus_talk),
- .write = koneplus_sysfs_write_talk
- },
- __ATTR_NULL
-};
-
-static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev,
- struct koneplus_device *koneplus)
-{
- int retval, i;
- static uint wait = 200;
-
- mutex_init(&koneplus->koneplus_lock);
-
- retval = koneplus_get_info(usb_dev, &koneplus->info);
- if (retval)
- return retval;
-
- for (i = 0; i < 5; ++i) {
- msleep(wait);
- retval = koneplus_get_profile_settings(usb_dev,
- &koneplus->profile_settings[i], i);
- if (retval)
- return retval;
-
- msleep(wait);
- retval = koneplus_get_profile_buttons(usb_dev,
- &koneplus->profile_buttons[i], i);
- if (retval)
- return retval;
- }
-
- msleep(wait);
- retval = koneplus_get_actual_profile(usb_dev);
- if (retval < 0)
- return retval;
- koneplus_profile_activated(koneplus, retval);
-
- return 0;
-}
-
-static int koneplus_init_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct usb_device *usb_dev = interface_to_usbdev(intf);
- struct koneplus_device *koneplus;
- int retval;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_MOUSE) {
-
- koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL);
- if (!koneplus) {
- hid_err(hdev, "can't alloc device descriptor\n");
- return -ENOMEM;
- }
- hid_set_drvdata(hdev, koneplus);
-
- retval = koneplus_init_koneplus_device_struct(usb_dev, koneplus);
- if (retval) {
- hid_err(hdev, "couldn't init struct koneplus_device\n");
- goto exit_free;
- }
-
- retval = roccat_connect(koneplus_class, hdev,
- sizeof(struct koneplus_roccat_report));
- if (retval < 0) {
- hid_err(hdev, "couldn't init char dev\n");
- } else {
- koneplus->chrdev_minor = retval;
- koneplus->roccat_claimed = 1;
- }
- } else {
- hid_set_drvdata(hdev, NULL);
- }
-
- return 0;
-exit_free:
- kfree(koneplus);
- return retval;
-}
-
-static void koneplus_remove_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct koneplus_device *koneplus;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_MOUSE) {
- koneplus = hid_get_drvdata(hdev);
- if (koneplus->roccat_claimed)
- roccat_disconnect(koneplus->chrdev_minor);
- kfree(koneplus);
- }
-}
-
-static int koneplus_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- int retval;
-
- retval = hid_parse(hdev);
- if (retval) {
- hid_err(hdev, "parse failed\n");
- goto exit;
- }
-
- retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (retval) {
- hid_err(hdev, "hw start failed\n");
- goto exit;
- }
-
- retval = koneplus_init_specials(hdev);
- if (retval) {
- hid_err(hdev, "couldn't install mouse\n");
- goto exit_stop;
- }
-
- return 0;
-
-exit_stop:
- hid_hw_stop(hdev);
-exit:
- return retval;
-}
-
-static void koneplus_remove(struct hid_device *hdev)
-{
- koneplus_remove_specials(hdev);
- hid_hw_stop(hdev);
-}
-
-static void koneplus_keep_values_up_to_date(struct koneplus_device *koneplus,
- u8 const *data)
-{
- struct koneplus_mouse_report_button const *button_report;
-
- switch (data[0]) {
- case KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON:
- button_report = (struct koneplus_mouse_report_button const *)data;
- switch (button_report->type) {
- case KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE:
- koneplus_profile_activated(koneplus, button_report->data1 - 1);
- break;
- }
- break;
- }
-}
-
-static void koneplus_report_to_chrdev(struct koneplus_device const *koneplus,
- u8 const *data)
-{
- struct koneplus_roccat_report roccat_report;
- struct koneplus_mouse_report_button const *button_report;
-
- if (data[0] != KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON)
- return;
-
- button_report = (struct koneplus_mouse_report_button const *)data;
-
- if ((button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH ||
- button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER) &&
- button_report->data2 != KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS)
- return;
-
- roccat_report.type = button_report->type;
- roccat_report.data1 = button_report->data1;
- roccat_report.data2 = button_report->data2;
- roccat_report.profile = koneplus->actual_profile + 1;
- roccat_report_event(koneplus->chrdev_minor,
- (uint8_t const *)&roccat_report);
-}
-
-static int koneplus_raw_event(struct hid_device *hdev,
- struct hid_report *report, u8 *data, int size)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct koneplus_device *koneplus = hid_get_drvdata(hdev);
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- != USB_INTERFACE_PROTOCOL_MOUSE)
- return 0;
-
- if (koneplus == NULL)
- return 0;
-
- koneplus_keep_values_up_to_date(koneplus, data);
-
- if (koneplus->roccat_claimed)
- koneplus_report_to_chrdev(koneplus, data);
-
- return 0;
-}
-
-static const struct hid_device_id koneplus_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, koneplus_devices);
-
-static struct hid_driver koneplus_driver = {
- .name = "koneplus",
- .id_table = koneplus_devices,
- .probe = koneplus_probe,
- .remove = koneplus_remove,
- .raw_event = koneplus_raw_event
-};
-
-static int __init koneplus_init(void)
-{
- int retval;
-
- /* class name has to be same as driver name */
- koneplus_class = class_create(THIS_MODULE, "koneplus");
- if (IS_ERR(koneplus_class))
- return PTR_ERR(koneplus_class);
- koneplus_class->dev_attrs = koneplus_attributes;
- koneplus_class->dev_bin_attrs = koneplus_bin_attributes;
-
- retval = hid_register_driver(&koneplus_driver);
- if (retval)
- class_destroy(koneplus_class);
- return retval;
-}
-
-static void __exit koneplus_exit(void)
-{
- hid_unregister_driver(&koneplus_driver);
- class_destroy(koneplus_class);
-}
-
-module_init(koneplus_init);
-module_exit(koneplus_exit);
-
-MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat Kone[+] driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-koneplus.h b/ANDROID_3.4.5/drivers/hid/hid-roccat-koneplus.h
deleted file mode 100644
index c03332a4..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-koneplus.h
+++ /dev/null
@@ -1,218 +0,0 @@
-#ifndef __HID_ROCCAT_KONEPLUS_H
-#define __HID_ROCCAT_KONEPLUS_H
-
-/*
- * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/types.h>
-
-struct koneplus_talk {
- uint8_t command; /* KONEPLUS_COMMAND_TALK */
- uint8_t size; /* always 0x10 */
- uint8_t data[14];
-} __packed;
-
-/*
- * case 1: writes request 80 and reads value 1
- *
- */
-struct koneplus_control {
- uint8_t command; /* KONEPLUS_COMMAND_CONTROL */
- /*
- * value is profile number in range 0-4 for requesting settings and buttons
- * 1 if status ok for requesting status
- */
- uint8_t value;
- uint8_t request;
-} __attribute__ ((__packed__));
-
-enum koneplus_control_requests {
- KONEPLUS_CONTROL_REQUEST_STATUS = 0x00,
- KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80,
- KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90,
-};
-
-enum koneplus_control_values {
- KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0,
- KONEPLUS_CONTROL_REQUEST_STATUS_OK = 1,
- KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3,
-};
-
-struct koneplus_actual_profile {
- uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */
- uint8_t size; /* always 3 */
- uint8_t actual_profile; /* Range 0-4! */
-} __attribute__ ((__packed__));
-
-struct koneplus_profile_settings {
- uint8_t command; /* KONEPLUS_COMMAND_PROFILE_SETTINGS */
- uint8_t size; /* always 43 */
- uint8_t number; /* range 0-4 */
- uint8_t advanced_sensitivity;
- uint8_t sensitivity_x;
- uint8_t sensitivity_y;
- uint8_t cpi_levels_enabled;
- uint8_t cpi_levels_x[5];
- uint8_t cpi_startup_level; /* range 0-4 */
- uint8_t cpi_levels_y[5]; /* range 1-60 means 100-6000 cpi */
- uint8_t unknown1;
- uint8_t polling_rate;
- uint8_t lights_enabled;
- uint8_t light_effect_mode;
- uint8_t color_flow_effect;
- uint8_t light_effect_type;
- uint8_t light_effect_speed;
- uint8_t lights[16];
- uint16_t checksum;
-} __attribute__ ((__packed__));
-
-struct koneplus_profile_buttons {
- uint8_t command; /* KONEPLUS_COMMAND_PROFILE_BUTTONS */
- uint8_t size; /* always 77 */
- uint8_t number; /* range 0-4 */
- uint8_t data[72];
- uint16_t checksum;
-} __attribute__ ((__packed__));
-
-struct koneplus_macro {
- uint8_t command; /* KONEPLUS_COMMAND_MACRO */
- uint16_t size; /* always 0x822 little endian */
- uint8_t profile; /* range 0-4 */
- uint8_t button; /* range 0-23 */
- uint8_t data[2075];
- uint16_t checksum;
-} __attribute__ ((__packed__));
-
-struct koneplus_info {
- uint8_t command; /* KONEPLUS_COMMAND_INFO */
- uint8_t size; /* always 6 */
- uint8_t firmware_version;
- uint8_t unknown[3];
-} __attribute__ ((__packed__));
-
-struct koneplus_e {
- uint8_t command; /* KONEPLUS_COMMAND_E */
- uint8_t size; /* always 3 */
- uint8_t unknown; /* TODO 1; 0 before firmware update */
-} __attribute__ ((__packed__));
-
-struct koneplus_sensor {
- uint8_t command; /* KONEPLUS_COMMAND_SENSOR */
- uint8_t size; /* always 6 */
- uint8_t data[4];
-} __attribute__ ((__packed__));
-
-struct koneplus_firmware_write {
- uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE */
- uint8_t unknown[1025];
-} __attribute__ ((__packed__));
-
-struct koneplus_firmware_write_control {
- uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL */
- /*
- * value is 1 on success
- * 3 means "not finished yet"
- */
- uint8_t value;
- uint8_t unknown; /* always 0x75 */
-} __attribute__ ((__packed__));
-
-struct koneplus_tcu {
- uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
- uint8_t data[2];
-} __attribute__ ((__packed__));
-
-struct koneplus_tcu_image {
- uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
- uint8_t data[1024];
- uint16_t checksum;
-} __attribute__ ((__packed__));
-
-enum koneplus_commands {
- KONEPLUS_COMMAND_CONTROL = 0x4,
- KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
- KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
- KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
- KONEPLUS_COMMAND_MACRO = 0x8,
- KONEPLUS_COMMAND_INFO = 0x9,
- KONEPLUS_COMMAND_TCU = 0xc,
- KONEPLUS_COMMAND_E = 0xe,
- KONEPLUS_COMMAND_SENSOR = 0xf,
- KONEPLUS_COMMAND_TALK = 0x10,
- KONEPLUS_COMMAND_FIRMWARE_WRITE = 0x1b,
- KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c,
-};
-
-enum koneplus_mouse_report_numbers {
- KONEPLUS_MOUSE_REPORT_NUMBER_HID = 1,
- KONEPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2,
- KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON = 3,
-};
-
-struct koneplus_mouse_report_button {
- uint8_t report_number; /* always KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON */
- uint8_t zero1;
- uint8_t type;
- uint8_t data1;
- uint8_t data2;
- uint8_t zero2;
- uint8_t unknown[2];
-} __attribute__ ((__packed__));
-
-enum koneplus_mouse_report_button_types {
- /* data1 = new profile range 1-5 */
- KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE = 0x20,
-
- /* data1 = button number range 1-24; data2 = action */
- KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
-
- /* data1 = button number range 1-24; data2 = action */
- KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80,
-
- /* data1 = setting number range 1-5 */
- KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0,
-
- /* data1 and data2 = range 0x1-0xb */
- KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0,
-
- /* data1 = 22 = next track...
- * data2 = action
- */
- KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
- KONEPLUS_MOUSE_REPORT_TALK = 0xff,
-};
-
-enum koneplus_mouse_report_button_action {
- KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS = 0,
- KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_RELEASE = 1,
-};
-
-struct koneplus_roccat_report {
- uint8_t type;
- uint8_t data1;
- uint8_t data2;
- uint8_t profile;
-} __attribute__ ((__packed__));
-
-struct koneplus_device {
- int actual_profile;
-
- int roccat_claimed;
- int chrdev_minor;
-
- struct mutex koneplus_lock;
-
- struct koneplus_info info;
- struct koneplus_profile_settings profile_settings[5];
- struct koneplus_profile_buttons profile_buttons[5];
-};
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-kovaplus.c b/ANDROID_3.4.5/drivers/hid/hid-roccat-kovaplus.c
deleted file mode 100644
index 112d9341..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-kovaplus.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * Roccat Kova[+] driver for Linux
- *
- * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-/*
- * Roccat Kova[+] is a bigger version of the Pyra with two more side buttons.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/hid-roccat.h>
-#include "hid-ids.h"
-#include "hid-roccat-common.h"
-#include "hid-roccat-kovaplus.h"
-
-static uint profile_numbers[5] = {0, 1, 2, 3, 4};
-
-static struct class *kovaplus_class;
-
-static uint kovaplus_convert_event_cpi(uint value)
-{
- return (value == 7 ? 4 : (value == 4 ? 3 : value));
-}
-
-static void kovaplus_profile_activated(struct kovaplus_device *kovaplus,
- uint new_profile_index)
-{
- kovaplus->actual_profile = new_profile_index;
- kovaplus->actual_cpi = kovaplus->profile_settings[new_profile_index].cpi_startup_level;
- kovaplus->actual_x_sensitivity = kovaplus->profile_settings[new_profile_index].sensitivity_x;
- kovaplus->actual_y_sensitivity = kovaplus->profile_settings[new_profile_index].sensitivity_y;
-}
-
-static int kovaplus_send_control(struct usb_device *usb_dev, uint value,
- enum kovaplus_control_requests request)
-{
- int retval;
- struct kovaplus_control control;
-
- if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
- request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
- value > 4)
- return -EINVAL;
-
- control.command = KOVAPLUS_COMMAND_CONTROL;
- control.value = value;
- control.request = request;
-
- retval = roccat_common_send(usb_dev, KOVAPLUS_COMMAND_CONTROL,
- &control, sizeof(struct kovaplus_control));
-
- return retval;
-}
-
-static int kovaplus_receive_control_status(struct usb_device *usb_dev)
-{
- int retval;
- struct kovaplus_control control;
-
- do {
- retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_CONTROL,
- &control, sizeof(struct kovaplus_control));
-
- /* check if we get a completely wrong answer */
- if (retval)
- return retval;
-
- if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OK)
- return 0;
-
- /* indicates that hardware needs some more time to complete action */
- if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT) {
- msleep(500); /* windows driver uses 1000 */
- continue;
- }
-
- /* seems to be critical - replug necessary */
- if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
- return -EINVAL;
-
- hid_err(usb_dev, "roccat_common_receive_control_status: "
- "unknown response value 0x%x\n", control.value);
- return -EINVAL;
- } while (1);
-}
-
-static int kovaplus_send(struct usb_device *usb_dev, uint command,
- void const *buf, uint size)
-{
- int retval;
-
- retval = roccat_common_send(usb_dev, command, buf, size);
- if (retval)
- return retval;
-
- msleep(100);
-
- return kovaplus_receive_control_status(usb_dev);
-}
-
-static int kovaplus_select_profile(struct usb_device *usb_dev, uint number,
- enum kovaplus_control_requests request)
-{
- return kovaplus_send_control(usb_dev, number, request);
-}
-
-static int kovaplus_get_info(struct usb_device *usb_dev,
- struct kovaplus_info *buf)
-{
- return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_INFO,
- buf, sizeof(struct kovaplus_info));
-}
-
-static int kovaplus_get_profile_settings(struct usb_device *usb_dev,
- struct kovaplus_profile_settings *buf, uint number)
-{
- int retval;
-
- retval = kovaplus_select_profile(usb_dev, number,
- KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
- if (retval)
- return retval;
-
- return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS,
- buf, sizeof(struct kovaplus_profile_settings));
-}
-
-static int kovaplus_set_profile_settings(struct usb_device *usb_dev,
- struct kovaplus_profile_settings const *settings)
-{
- return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS,
- settings, sizeof(struct kovaplus_profile_settings));
-}
-
-static int kovaplus_get_profile_buttons(struct usb_device *usb_dev,
- struct kovaplus_profile_buttons *buf, int number)
-{
- int retval;
-
- retval = kovaplus_select_profile(usb_dev, number,
- KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
- if (retval)
- return retval;
-
- return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS,
- buf, sizeof(struct kovaplus_profile_buttons));
-}
-
-static int kovaplus_set_profile_buttons(struct usb_device *usb_dev,
- struct kovaplus_profile_buttons const *buttons)
-{
- return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS,
- buttons, sizeof(struct kovaplus_profile_buttons));
-}
-
-/* retval is 0-4 on success, < 0 on error */
-static int kovaplus_get_actual_profile(struct usb_device *usb_dev)
-{
- struct kovaplus_actual_profile buf;
- int retval;
-
- retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE,
- &buf, sizeof(struct kovaplus_actual_profile));
-
- return retval ? retval : buf.actual_profile;
-}
-
-static int kovaplus_set_actual_profile(struct usb_device *usb_dev,
- int new_profile)
-{
- struct kovaplus_actual_profile buf;
-
- buf.command = KOVAPLUS_COMMAND_ACTUAL_PROFILE;
- buf.size = sizeof(struct kovaplus_actual_profile);
- buf.actual_profile = new_profile;
-
- return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE,
- &buf, sizeof(struct kovaplus_actual_profile));
-}
-
-static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct kovaplus_profile_settings))
- return 0;
-
- if (off + count > sizeof(struct kovaplus_profile_settings))
- count = sizeof(struct kovaplus_profile_settings) - off;
-
- mutex_lock(&kovaplus->kovaplus_lock);
- memcpy(buf, ((char const *)&kovaplus->profile_settings[*(uint *)(attr->private)]) + off,
- count);
- mutex_unlock(&kovaplus->kovaplus_lock);
-
- return count;
-}
-
-static ssize_t kovaplus_sysfs_write_profile_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval = 0;
- int difference;
- int profile_index;
- struct kovaplus_profile_settings *profile_settings;
-
- if (off != 0 || count != sizeof(struct kovaplus_profile_settings))
- return -EINVAL;
-
- profile_index = ((struct kovaplus_profile_settings const *)buf)->profile_index;
- profile_settings = &kovaplus->profile_settings[profile_index];
-
- mutex_lock(&kovaplus->kovaplus_lock);
- difference = memcmp(buf, profile_settings,
- sizeof(struct kovaplus_profile_settings));
- if (difference) {
- retval = kovaplus_set_profile_settings(usb_dev,
- (struct kovaplus_profile_settings const *)buf);
- if (!retval)
- memcpy(profile_settings, buf,
- sizeof(struct kovaplus_profile_settings));
- }
- mutex_unlock(&kovaplus->kovaplus_lock);
-
- if (retval)
- return retval;
-
- return sizeof(struct kovaplus_profile_settings);
-}
-
-static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct kovaplus_profile_buttons))
- return 0;
-
- if (off + count > sizeof(struct kovaplus_profile_buttons))
- count = sizeof(struct kovaplus_profile_buttons) - off;
-
- mutex_lock(&kovaplus->kovaplus_lock);
- memcpy(buf, ((char const *)&kovaplus->profile_buttons[*(uint *)(attr->private)]) + off,
- count);
- mutex_unlock(&kovaplus->kovaplus_lock);
-
- return count;
-}
-
-static ssize_t kovaplus_sysfs_write_profile_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval = 0;
- int difference;
- uint profile_index;
- struct kovaplus_profile_buttons *profile_buttons;
-
- if (off != 0 || count != sizeof(struct kovaplus_profile_buttons))
- return -EINVAL;
-
- profile_index = ((struct kovaplus_profile_buttons const *)buf)->profile_index;
- profile_buttons = &kovaplus->profile_buttons[profile_index];
-
- mutex_lock(&kovaplus->kovaplus_lock);
- difference = memcmp(buf, profile_buttons,
- sizeof(struct kovaplus_profile_buttons));
- if (difference) {
- retval = kovaplus_set_profile_buttons(usb_dev,
- (struct kovaplus_profile_buttons const *)buf);
- if (!retval)
- memcpy(profile_buttons, buf,
- sizeof(struct kovaplus_profile_buttons));
- }
- mutex_unlock(&kovaplus->kovaplus_lock);
-
- if (retval)
- return retval;
-
- return sizeof(struct kovaplus_profile_buttons);
-}
-
-static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kovaplus_device *kovaplus =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_profile);
-}
-
-static ssize_t kovaplus_sysfs_set_actual_profile(struct device *dev,
- struct device_attribute *attr, char const *buf, size_t size)
-{
- struct kovaplus_device *kovaplus;
- struct usb_device *usb_dev;
- unsigned long profile;
- int retval;
- struct kovaplus_roccat_report roccat_report;
-
- dev = dev->parent->parent;
- kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
- usb_dev = interface_to_usbdev(to_usb_interface(dev));
-
- retval = strict_strtoul(buf, 10, &profile);
- if (retval)
- return retval;
-
- if (profile >= 5)
- return -EINVAL;
-
- mutex_lock(&kovaplus->kovaplus_lock);
- retval = kovaplus_set_actual_profile(usb_dev, profile);
- if (retval) {
- mutex_unlock(&kovaplus->kovaplus_lock);
- return retval;
- }
-
- kovaplus_profile_activated(kovaplus, profile);
-
- roccat_report.type = KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_1;
- roccat_report.profile = profile + 1;
- roccat_report.button = 0;
- roccat_report.data1 = profile + 1;
- roccat_report.data2 = 0;
- roccat_report_event(kovaplus->chrdev_minor,
- (uint8_t const *)&roccat_report);
-
- mutex_unlock(&kovaplus->kovaplus_lock);
-
- return size;
-}
-
-static ssize_t kovaplus_sysfs_show_actual_cpi(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kovaplus_device *kovaplus =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_cpi);
-}
-
-static ssize_t kovaplus_sysfs_show_actual_sensitivity_x(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kovaplus_device *kovaplus =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_x_sensitivity);
-}
-
-static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kovaplus_device *kovaplus =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_y_sensitivity);
-}
-
-static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kovaplus_device *kovaplus =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->info.firmware_version);
-}
-
-static struct device_attribute kovaplus_attributes[] = {
- __ATTR(actual_cpi, 0440,
- kovaplus_sysfs_show_actual_cpi, NULL),
- __ATTR(firmware_version, 0440,
- kovaplus_sysfs_show_firmware_version, NULL),
- __ATTR(actual_profile, 0660,
- kovaplus_sysfs_show_actual_profile,
- kovaplus_sysfs_set_actual_profile),
- __ATTR(actual_sensitivity_x, 0440,
- kovaplus_sysfs_show_actual_sensitivity_x, NULL),
- __ATTR(actual_sensitivity_y, 0440,
- kovaplus_sysfs_show_actual_sensitivity_y, NULL),
- __ATTR_NULL
-};
-
-static struct bin_attribute kovaplus_bin_attributes[] = {
- {
- .attr = { .name = "profile_settings", .mode = 0220 },
- .size = sizeof(struct kovaplus_profile_settings),
- .write = kovaplus_sysfs_write_profile_settings
- },
- {
- .attr = { .name = "profile1_settings", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_settings),
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_settings", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_settings),
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_settings", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_settings),
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_settings", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_settings),
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_settings", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_settings),
- .read = kovaplus_sysfs_read_profilex_settings,
- .private = &profile_numbers[4]
- },
- {
- .attr = { .name = "profile_buttons", .mode = 0220 },
- .size = sizeof(struct kovaplus_profile_buttons),
- .write = kovaplus_sysfs_write_profile_buttons
- },
- {
- .attr = { .name = "profile1_buttons", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_buttons),
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_buttons", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_buttons),
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_buttons", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_buttons),
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_buttons", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_buttons),
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_buttons", .mode = 0440 },
- .size = sizeof(struct kovaplus_profile_buttons),
- .read = kovaplus_sysfs_read_profilex_buttons,
- .private = &profile_numbers[4]
- },
- __ATTR_NULL
-};
-
-static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev,
- struct kovaplus_device *kovaplus)
-{
- int retval, i;
- static uint wait = 70; /* device will freeze with just 60 */
-
- mutex_init(&kovaplus->kovaplus_lock);
-
- retval = kovaplus_get_info(usb_dev, &kovaplus->info);
- if (retval)
- return retval;
-
- for (i = 0; i < 5; ++i) {
- msleep(wait);
- retval = kovaplus_get_profile_settings(usb_dev,
- &kovaplus->profile_settings[i], i);
- if (retval)
- return retval;
-
- msleep(wait);
- retval = kovaplus_get_profile_buttons(usb_dev,
- &kovaplus->profile_buttons[i], i);
- if (retval)
- return retval;
- }
-
- msleep(wait);
- retval = kovaplus_get_actual_profile(usb_dev);
- if (retval < 0)
- return retval;
- kovaplus_profile_activated(kovaplus, retval);
-
- return 0;
-}
-
-static int kovaplus_init_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct usb_device *usb_dev = interface_to_usbdev(intf);
- struct kovaplus_device *kovaplus;
- int retval;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_MOUSE) {
-
- kovaplus = kzalloc(sizeof(*kovaplus), GFP_KERNEL);
- if (!kovaplus) {
- hid_err(hdev, "can't alloc device descriptor\n");
- return -ENOMEM;
- }
- hid_set_drvdata(hdev, kovaplus);
-
- retval = kovaplus_init_kovaplus_device_struct(usb_dev, kovaplus);
- if (retval) {
- hid_err(hdev, "couldn't init struct kovaplus_device\n");
- goto exit_free;
- }
-
- retval = roccat_connect(kovaplus_class, hdev,
- sizeof(struct kovaplus_roccat_report));
- if (retval < 0) {
- hid_err(hdev, "couldn't init char dev\n");
- } else {
- kovaplus->chrdev_minor = retval;
- kovaplus->roccat_claimed = 1;
- }
-
- } else {
- hid_set_drvdata(hdev, NULL);
- }
-
- return 0;
-exit_free:
- kfree(kovaplus);
- return retval;
-}
-
-static void kovaplus_remove_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct kovaplus_device *kovaplus;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_MOUSE) {
- kovaplus = hid_get_drvdata(hdev);
- if (kovaplus->roccat_claimed)
- roccat_disconnect(kovaplus->chrdev_minor);
- kfree(kovaplus);
- }
-}
-
-static int kovaplus_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- int retval;
-
- retval = hid_parse(hdev);
- if (retval) {
- hid_err(hdev, "parse failed\n");
- goto exit;
- }
-
- retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (retval) {
- hid_err(hdev, "hw start failed\n");
- goto exit;
- }
-
- retval = kovaplus_init_specials(hdev);
- if (retval) {
- hid_err(hdev, "couldn't install mouse\n");
- goto exit_stop;
- }
-
- return 0;
-
-exit_stop:
- hid_hw_stop(hdev);
-exit:
- return retval;
-}
-
-static void kovaplus_remove(struct hid_device *hdev)
-{
- kovaplus_remove_specials(hdev);
- hid_hw_stop(hdev);
-}
-
-static void kovaplus_keep_values_up_to_date(struct kovaplus_device *kovaplus,
- u8 const *data)
-{
- struct kovaplus_mouse_report_button const *button_report;
-
- if (data[0] != KOVAPLUS_MOUSE_REPORT_NUMBER_BUTTON)
- return;
-
- button_report = (struct kovaplus_mouse_report_button const *)data;
-
- switch (button_report->type) {
- case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_1:
- kovaplus_profile_activated(kovaplus, button_report->data1 - 1);
- break;
- case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI:
- kovaplus->actual_cpi = kovaplus_convert_event_cpi(button_report->data1);
- case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY:
- kovaplus->actual_x_sensitivity = button_report->data1;
- kovaplus->actual_y_sensitivity = button_report->data2;
- }
-}
-
-static void kovaplus_report_to_chrdev(struct kovaplus_device const *kovaplus,
- u8 const *data)
-{
- struct kovaplus_roccat_report roccat_report;
- struct kovaplus_mouse_report_button const *button_report;
-
- if (data[0] != KOVAPLUS_MOUSE_REPORT_NUMBER_BUTTON)
- return;
-
- button_report = (struct kovaplus_mouse_report_button const *)data;
-
- if (button_report->type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_2)
- return;
-
- roccat_report.type = button_report->type;
- roccat_report.profile = kovaplus->actual_profile + 1;
-
- if (roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_MACRO ||
- roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SHORTCUT ||
- roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH ||
- roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER)
- roccat_report.button = button_report->data1;
- else
- roccat_report.button = 0;
-
- if (roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI)
- roccat_report.data1 = kovaplus_convert_event_cpi(button_report->data1);
- else
- roccat_report.data1 = button_report->data1;
-
- roccat_report.data2 = button_report->data2;
-
- roccat_report_event(kovaplus->chrdev_minor,
- (uint8_t const *)&roccat_report);
-}
-
-static int kovaplus_raw_event(struct hid_device *hdev,
- struct hid_report *report, u8 *data, int size)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct kovaplus_device *kovaplus = hid_get_drvdata(hdev);
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- != USB_INTERFACE_PROTOCOL_MOUSE)
- return 0;
-
- if (kovaplus == NULL)
- return 0;
-
- kovaplus_keep_values_up_to_date(kovaplus, data);
-
- if (kovaplus->roccat_claimed)
- kovaplus_report_to_chrdev(kovaplus, data);
-
- return 0;
-}
-
-static const struct hid_device_id kovaplus_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, kovaplus_devices);
-
-static struct hid_driver kovaplus_driver = {
- .name = "kovaplus",
- .id_table = kovaplus_devices,
- .probe = kovaplus_probe,
- .remove = kovaplus_remove,
- .raw_event = kovaplus_raw_event
-};
-
-static int __init kovaplus_init(void)
-{
- int retval;
-
- kovaplus_class = class_create(THIS_MODULE, "kovaplus");
- if (IS_ERR(kovaplus_class))
- return PTR_ERR(kovaplus_class);
- kovaplus_class->dev_attrs = kovaplus_attributes;
- kovaplus_class->dev_bin_attrs = kovaplus_bin_attributes;
-
- retval = hid_register_driver(&kovaplus_driver);
- if (retval)
- class_destroy(kovaplus_class);
- return retval;
-}
-
-static void __exit kovaplus_exit(void)
-{
- hid_unregister_driver(&kovaplus_driver);
- class_destroy(kovaplus_class);
-}
-
-module_init(kovaplus_init);
-module_exit(kovaplus_exit);
-
-MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat Kova[+] driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-kovaplus.h b/ANDROID_3.4.5/drivers/hid/hid-roccat-kovaplus.h
deleted file mode 100644
index fb2aed44..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-kovaplus.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef __HID_ROCCAT_KOVAPLUS_H
-#define __HID_ROCCAT_KOVAPLUS_H
-
-/*
- * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/types.h>
-
-struct kovaplus_control {
- uint8_t command; /* KOVAPLUS_COMMAND_CONTROL */
- uint8_t value;
- uint8_t request;
-} __packed;
-
-enum kovaplus_control_requests {
- /* read after write; value = 1 */
- KOVAPLUS_CONTROL_REQUEST_STATUS = 0x0,
- /* write; value = profile number range 0-4 */
- KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
- /* write; value = profile number range 0-4 */
- KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20,
-};
-
-enum kovaplus_control_values {
- KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, /* supposed */
- KOVAPLUS_CONTROL_REQUEST_STATUS_OK = 1,
- KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, /* supposed */
-};
-
-struct kovaplus_actual_profile {
- uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */
- uint8_t size; /* always 3 */
- uint8_t actual_profile; /* Range 0-4! */
-} __packed;
-
-struct kovaplus_profile_settings {
- uint8_t command; /* KOVAPLUS_COMMAND_PROFILE_SETTINGS */
- uint8_t size; /* 16 */
- uint8_t profile_index; /* range 0-4 */
- uint8_t unknown1;
- uint8_t sensitivity_x; /* range 1-10 */
- uint8_t sensitivity_y; /* range 1-10 */
- uint8_t cpi_levels_enabled;
- uint8_t cpi_startup_level; /* range 1-4 */
- uint8_t data[8];
-} __packed;
-
-struct kovaplus_profile_buttons {
- uint8_t command; /* KOVAPLUS_COMMAND_PROFILE_BUTTONS */
- uint8_t size; /* 23 */
- uint8_t profile_index; /* range 0-4 */
- uint8_t data[20];
-} __packed;
-
-struct kovaplus_info {
- uint8_t command; /* KOVAPLUS_COMMAND_INFO */
- uint8_t size; /* 6 */
- uint8_t firmware_version;
- uint8_t unknown[3];
-} __packed;
-
-/* writes 1 on plugin */
-struct kovaplus_a {
- uint8_t command; /* KOVAPLUS_COMMAND_A */
- uint8_t size; /* 3 */
- uint8_t unknown;
-} __packed;
-
-enum kovaplus_commands {
- KOVAPLUS_COMMAND_CONTROL = 0x4,
- KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
- KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
- KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
- KOVAPLUS_COMMAND_INFO = 0x9,
- KOVAPLUS_COMMAND_A = 0xa,
-};
-
-enum kovaplus_mouse_report_numbers {
- KOVAPLUS_MOUSE_REPORT_NUMBER_MOUSE = 1,
- KOVAPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2,
- KOVAPLUS_MOUSE_REPORT_NUMBER_BUTTON = 3,
- KOVAPLUS_MOUSE_REPORT_NUMBER_KBD = 4,
-};
-
-struct kovaplus_mouse_report_button {
- uint8_t report_number; /* KOVAPLUS_MOUSE_REPORT_NUMBER_BUTTON */
- uint8_t unknown1;
- uint8_t type;
- uint8_t data1;
- uint8_t data2;
-} __packed;
-
-enum kovaplus_mouse_report_button_types {
- /* data1 = profile_number range 1-5; no release event */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_1 = 0x20,
- /* data1 = profile_number range 1-5; no release event */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_2 = 0x30,
- /* data1 = button_number range 1-18; data2 = action */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_MACRO = 0x40,
- /* data1 = button_number range 1-18; data2 = action */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SHORTCUT = 0x50,
- /* data1 = button_number range 1-18; data2 = action */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
- /* data1 = button_number range 1-18; data2 = action */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80,
- /* data1 = 1 = 400, 2 = 800, 4 = 1600, 7 = 3200; no release event */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0,
- /* data1 + data2 = sense range 1-10; no release event */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0,
- /* data1 = type as in profile_buttons; data2 = action */
- KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
-};
-
-enum kovaplus_mouse_report_button_actions {
- KOVAPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS = 0,
- KOVAPLUS_MOUSE_REPORT_BUTTON_ACTION_RELEASE = 1,
-};
-
-struct kovaplus_roccat_report {
- uint8_t type;
- uint8_t profile;
- uint8_t button;
- uint8_t data1;
- uint8_t data2;
-} __packed;
-
-struct kovaplus_device {
- int actual_profile;
- int actual_cpi;
- int actual_x_sensitivity;
- int actual_y_sensitivity;
- int roccat_claimed;
- int chrdev_minor;
- struct mutex kovaplus_lock;
- struct kovaplus_info info;
- struct kovaplus_profile_settings profile_settings[5];
- struct kovaplus_profile_buttons profile_buttons[5];
-};
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-pyra.c b/ANDROID_3.4.5/drivers/hid/hid-roccat-pyra.c
deleted file mode 100644
index df05c1b1..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-pyra.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Roccat Pyra driver for Linux
- *
- * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-/*
- * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless
- * variant. Wireless variant is not tested.
- * Userland tools can be found at http://sourceforge.net/projects/roccat
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/hid-roccat.h>
-#include "hid-ids.h"
-#include "hid-roccat-common.h"
-#include "hid-roccat-pyra.h"
-
-static uint profile_numbers[5] = {0, 1, 2, 3, 4};
-
-/* pyra_class is used for creating sysfs attributes via roccat char device */
-static struct class *pyra_class;
-
-static void profile_activated(struct pyra_device *pyra,
- unsigned int new_profile)
-{
- pyra->actual_profile = new_profile;
- pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
-}
-
-static int pyra_send_control(struct usb_device *usb_dev, int value,
- enum pyra_control_requests request)
-{
- struct pyra_control control;
-
- if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
- request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
- (value < 0 || value > 4))
- return -EINVAL;
-
- control.command = PYRA_COMMAND_CONTROL;
- control.value = value;
- control.request = request;
-
- return roccat_common_send(usb_dev, PYRA_COMMAND_CONTROL,
- &control, sizeof(struct pyra_control));
-}
-
-static int pyra_receive_control_status(struct usb_device *usb_dev)
-{
- int retval;
- struct pyra_control control;
-
- do {
- msleep(10);
- retval = roccat_common_receive(usb_dev, PYRA_COMMAND_CONTROL,
- &control, sizeof(struct pyra_control));
-
- /* requested too early, try again */
- } while (retval == -EPROTO);
-
- if (!retval && control.command == PYRA_COMMAND_CONTROL &&
- control.request == PYRA_CONTROL_REQUEST_STATUS &&
- control.value == 1)
- return 0;
- else {
- hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n",
- control.request, control.value);
- return retval ? retval : -EINVAL;
- }
-}
-
-static int pyra_get_profile_settings(struct usb_device *usb_dev,
- struct pyra_profile_settings *buf, int number)
-{
- int retval;
- retval = pyra_send_control(usb_dev, number,
- PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
- if (retval)
- return retval;
- return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS,
- buf, sizeof(struct pyra_profile_settings));
-}
-
-static int pyra_get_profile_buttons(struct usb_device *usb_dev,
- struct pyra_profile_buttons *buf, int number)
-{
- int retval;
- retval = pyra_send_control(usb_dev, number,
- PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
- if (retval)
- return retval;
- return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS,
- buf, sizeof(struct pyra_profile_buttons));
-}
-
-static int pyra_get_settings(struct usb_device *usb_dev,
- struct pyra_settings *buf)
-{
- return roccat_common_receive(usb_dev, PYRA_COMMAND_SETTINGS,
- buf, sizeof(struct pyra_settings));
-}
-
-static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
-{
- return roccat_common_receive(usb_dev, PYRA_COMMAND_INFO,
- buf, sizeof(struct pyra_info));
-}
-
-static int pyra_send(struct usb_device *usb_dev, uint command,
- void const *buf, uint size)
-{
- int retval;
- retval = roccat_common_send(usb_dev, command, buf, size);
- if (retval)
- return retval;
- return pyra_receive_control_status(usb_dev);
-}
-
-static int pyra_set_profile_settings(struct usb_device *usb_dev,
- struct pyra_profile_settings const *settings)
-{
- return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, settings,
- sizeof(struct pyra_profile_settings));
-}
-
-static int pyra_set_profile_buttons(struct usb_device *usb_dev,
- struct pyra_profile_buttons const *buttons)
-{
- return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buttons,
- sizeof(struct pyra_profile_buttons));
-}
-
-static int pyra_set_settings(struct usb_device *usb_dev,
- struct pyra_settings const *settings)
-{
- return pyra_send(usb_dev, PYRA_COMMAND_SETTINGS, settings,
- sizeof(struct pyra_settings));
-}
-
-static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct pyra_profile_settings))
- return 0;
-
- if (off + count > sizeof(struct pyra_profile_settings))
- count = sizeof(struct pyra_profile_settings) - off;
-
- mutex_lock(&pyra->pyra_lock);
- memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off,
- count);
- mutex_unlock(&pyra->pyra_lock);
-
- return count;
-}
-
-static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct pyra_profile_buttons))
- return 0;
-
- if (off + count > sizeof(struct pyra_profile_buttons))
- count = sizeof(struct pyra_profile_buttons) - off;
-
- mutex_lock(&pyra->pyra_lock);
- memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off,
- count);
- mutex_unlock(&pyra->pyra_lock);
-
- return count;
-}
-
-static ssize_t pyra_sysfs_write_profile_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval = 0;
- int difference;
- int profile_number;
- struct pyra_profile_settings *profile_settings;
-
- if (off != 0 || count != sizeof(struct pyra_profile_settings))
- return -EINVAL;
-
- profile_number = ((struct pyra_profile_settings const *)buf)->number;
- profile_settings = &pyra->profile_settings[profile_number];
-
- mutex_lock(&pyra->pyra_lock);
- difference = memcmp(buf, profile_settings,
- sizeof(struct pyra_profile_settings));
- if (difference) {
- retval = pyra_set_profile_settings(usb_dev,
- (struct pyra_profile_settings const *)buf);
- if (!retval)
- memcpy(profile_settings, buf,
- sizeof(struct pyra_profile_settings));
- }
- mutex_unlock(&pyra->pyra_lock);
-
- if (retval)
- return retval;
-
- return sizeof(struct pyra_profile_settings);
-}
-
-static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval = 0;
- int difference;
- int profile_number;
- struct pyra_profile_buttons *profile_buttons;
-
- if (off != 0 || count != sizeof(struct pyra_profile_buttons))
- return -EINVAL;
-
- profile_number = ((struct pyra_profile_buttons const *)buf)->number;
- profile_buttons = &pyra->profile_buttons[profile_number];
-
- mutex_lock(&pyra->pyra_lock);
- difference = memcmp(buf, profile_buttons,
- sizeof(struct pyra_profile_buttons));
- if (difference) {
- retval = pyra_set_profile_buttons(usb_dev,
- (struct pyra_profile_buttons const *)buf);
- if (!retval)
- memcpy(profile_buttons, buf,
- sizeof(struct pyra_profile_buttons));
- }
- mutex_unlock(&pyra->pyra_lock);
-
- if (retval)
- return retval;
-
- return sizeof(struct pyra_profile_buttons);
-}
-
-static ssize_t pyra_sysfs_read_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
-
- if (off >= sizeof(struct pyra_settings))
- return 0;
-
- if (off + count > sizeof(struct pyra_settings))
- count = sizeof(struct pyra_settings) - off;
-
- mutex_lock(&pyra->pyra_lock);
- memcpy(buf, ((char const *)&pyra->settings) + off, count);
- mutex_unlock(&pyra->pyra_lock);
-
- return count;
-}
-
-static ssize_t pyra_sysfs_write_settings(struct file *fp,
- struct kobject *kobj, struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- struct device *dev =
- container_of(kobj, struct device, kobj)->parent->parent;
- struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
- struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
- int retval = 0;
- int difference;
- struct pyra_roccat_report roccat_report;
-
- if (off != 0 || count != sizeof(struct pyra_settings))
- return -EINVAL;
-
- mutex_lock(&pyra->pyra_lock);
- difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings));
- if (difference) {
- retval = pyra_set_settings(usb_dev,
- (struct pyra_settings const *)buf);
- if (retval) {
- mutex_unlock(&pyra->pyra_lock);
- return retval;
- }
-
- memcpy(&pyra->settings, buf,
- sizeof(struct pyra_settings));
-
- profile_activated(pyra, pyra->settings.startup_profile);
-
- roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2;
- roccat_report.value = pyra->settings.startup_profile + 1;
- roccat_report.key = 0;
- roccat_report_event(pyra->chrdev_minor,
- (uint8_t const *)&roccat_report);
- }
- mutex_unlock(&pyra->pyra_lock);
- return sizeof(struct pyra_settings);
-}
-
-
-static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct pyra_device *pyra =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
-}
-
-static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct pyra_device *pyra =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile);
-}
-
-static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct pyra_device *pyra =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version);
-}
-
-static ssize_t pyra_sysfs_show_startup_profile(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct pyra_device *pyra =
- hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
- return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile);
-}
-
-static struct device_attribute pyra_attributes[] = {
- __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL),
- __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL),
- __ATTR(firmware_version, 0440,
- pyra_sysfs_show_firmware_version, NULL),
- __ATTR(startup_profile, 0440,
- pyra_sysfs_show_startup_profile, NULL),
- __ATTR_NULL
-};
-
-static struct bin_attribute pyra_bin_attributes[] = {
- {
- .attr = { .name = "profile_settings", .mode = 0220 },
- .size = sizeof(struct pyra_profile_settings),
- .write = pyra_sysfs_write_profile_settings
- },
- {
- .attr = { .name = "profile1_settings", .mode = 0440 },
- .size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_settings", .mode = 0440 },
- .size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_settings", .mode = 0440 },
- .size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_settings", .mode = 0440 },
- .size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_settings", .mode = 0440 },
- .size = sizeof(struct pyra_profile_settings),
- .read = pyra_sysfs_read_profilex_settings,
- .private = &profile_numbers[4]
- },
- {
- .attr = { .name = "profile_buttons", .mode = 0220 },
- .size = sizeof(struct pyra_profile_buttons),
- .write = pyra_sysfs_write_profile_buttons
- },
- {
- .attr = { .name = "profile1_buttons", .mode = 0440 },
- .size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[0]
- },
- {
- .attr = { .name = "profile2_buttons", .mode = 0440 },
- .size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[1]
- },
- {
- .attr = { .name = "profile3_buttons", .mode = 0440 },
- .size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[2]
- },
- {
- .attr = { .name = "profile4_buttons", .mode = 0440 },
- .size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[3]
- },
- {
- .attr = { .name = "profile5_buttons", .mode = 0440 },
- .size = sizeof(struct pyra_profile_buttons),
- .read = pyra_sysfs_read_profilex_buttons,
- .private = &profile_numbers[4]
- },
- {
- .attr = { .name = "settings", .mode = 0660 },
- .size = sizeof(struct pyra_settings),
- .read = pyra_sysfs_read_settings,
- .write = pyra_sysfs_write_settings
- },
- __ATTR_NULL
-};
-
-static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
- struct pyra_device *pyra)
-{
- struct pyra_info info;
- int retval, i;
-
- mutex_init(&pyra->pyra_lock);
-
- retval = pyra_get_info(usb_dev, &info);
- if (retval)
- return retval;
-
- pyra->firmware_version = info.firmware_version;
-
- retval = pyra_get_settings(usb_dev, &pyra->settings);
- if (retval)
- return retval;
-
- for (i = 0; i < 5; ++i) {
- retval = pyra_get_profile_settings(usb_dev,
- &pyra->profile_settings[i], i);
- if (retval)
- return retval;
-
- retval = pyra_get_profile_buttons(usb_dev,
- &pyra->profile_buttons[i], i);
- if (retval)
- return retval;
- }
-
- profile_activated(pyra, pyra->settings.startup_profile);
-
- return 0;
-}
-
-static int pyra_init_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct usb_device *usb_dev = interface_to_usbdev(intf);
- struct pyra_device *pyra;
- int retval;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_MOUSE) {
-
- pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
- if (!pyra) {
- hid_err(hdev, "can't alloc device descriptor\n");
- return -ENOMEM;
- }
- hid_set_drvdata(hdev, pyra);
-
- retval = pyra_init_pyra_device_struct(usb_dev, pyra);
- if (retval) {
- hid_err(hdev, "couldn't init struct pyra_device\n");
- goto exit_free;
- }
-
- retval = roccat_connect(pyra_class, hdev,
- sizeof(struct pyra_roccat_report));
- if (retval < 0) {
- hid_err(hdev, "couldn't init char dev\n");
- } else {
- pyra->chrdev_minor = retval;
- pyra->roccat_claimed = 1;
- }
- } else {
- hid_set_drvdata(hdev, NULL);
- }
-
- return 0;
-exit_free:
- kfree(pyra);
- return retval;
-}
-
-static void pyra_remove_specials(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct pyra_device *pyra;
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- == USB_INTERFACE_PROTOCOL_MOUSE) {
- pyra = hid_get_drvdata(hdev);
- if (pyra->roccat_claimed)
- roccat_disconnect(pyra->chrdev_minor);
- kfree(hid_get_drvdata(hdev));
- }
-}
-
-static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int retval;
-
- retval = hid_parse(hdev);
- if (retval) {
- hid_err(hdev, "parse failed\n");
- goto exit;
- }
-
- retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (retval) {
- hid_err(hdev, "hw start failed\n");
- goto exit;
- }
-
- retval = pyra_init_specials(hdev);
- if (retval) {
- hid_err(hdev, "couldn't install mouse\n");
- goto exit_stop;
- }
- return 0;
-
-exit_stop:
- hid_hw_stop(hdev);
-exit:
- return retval;
-}
-
-static void pyra_remove(struct hid_device *hdev)
-{
- pyra_remove_specials(hdev);
- hid_hw_stop(hdev);
-}
-
-static void pyra_keep_values_up_to_date(struct pyra_device *pyra,
- u8 const *data)
-{
- struct pyra_mouse_event_button const *button_event;
-
- switch (data[0]) {
- case PYRA_MOUSE_REPORT_NUMBER_BUTTON:
- button_event = (struct pyra_mouse_event_button const *)data;
- switch (button_event->type) {
- case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
- profile_activated(pyra, button_event->data1 - 1);
- break;
- case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
- pyra->actual_cpi = button_event->data1;
- break;
- }
- break;
- }
-}
-
-static void pyra_report_to_chrdev(struct pyra_device const *pyra,
- u8 const *data)
-{
- struct pyra_roccat_report roccat_report;
- struct pyra_mouse_event_button const *button_event;
-
- if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON)
- return;
-
- button_event = (struct pyra_mouse_event_button const *)data;
-
- switch (button_event->type) {
- case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
- case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
- roccat_report.type = button_event->type;
- roccat_report.value = button_event->data1;
- roccat_report.key = 0;
- roccat_report_event(pyra->chrdev_minor,
- (uint8_t const *)&roccat_report);
- break;
- case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
- case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
- case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH:
- if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) {
- roccat_report.type = button_event->type;
- roccat_report.key = button_event->data1;
- /*
- * pyra reports profile numbers with range 1-5.
- * Keeping this behaviour.
- */
- roccat_report.value = pyra->actual_profile + 1;
- roccat_report_event(pyra->chrdev_minor,
- (uint8_t const *)&roccat_report);
- }
- break;
- }
-}
-
-static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
- u8 *data, int size)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct pyra_device *pyra = hid_get_drvdata(hdev);
-
- if (intf->cur_altsetting->desc.bInterfaceProtocol
- != USB_INTERFACE_PROTOCOL_MOUSE)
- return 0;
-
- if (pyra == NULL)
- return 0;
-
- pyra_keep_values_up_to_date(pyra, data);
-
- if (pyra->roccat_claimed)
- pyra_report_to_chrdev(pyra, data);
-
- return 0;
-}
-
-static const struct hid_device_id pyra_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
- USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
- USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, pyra_devices);
-
-static struct hid_driver pyra_driver = {
- .name = "pyra",
- .id_table = pyra_devices,
- .probe = pyra_probe,
- .remove = pyra_remove,
- .raw_event = pyra_raw_event
-};
-
-static int __init pyra_init(void)
-{
- int retval;
-
- /* class name has to be same as driver name */
- pyra_class = class_create(THIS_MODULE, "pyra");
- if (IS_ERR(pyra_class))
- return PTR_ERR(pyra_class);
- pyra_class->dev_attrs = pyra_attributes;
- pyra_class->dev_bin_attrs = pyra_bin_attributes;
-
- retval = hid_register_driver(&pyra_driver);
- if (retval)
- class_destroy(pyra_class);
- return retval;
-}
-
-static void __exit pyra_exit(void)
-{
- hid_unregister_driver(&pyra_driver);
- class_destroy(pyra_class);
-}
-
-module_init(pyra_init);
-module_exit(pyra_exit);
-
-MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat Pyra driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat-pyra.h b/ANDROID_3.4.5/drivers/hid/hid-roccat-pyra.h
deleted file mode 100644
index 0442d7fa..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat-pyra.h
+++ /dev/null
@@ -1,172 +0,0 @@
-#ifndef __HID_ROCCAT_PYRA_H
-#define __HID_ROCCAT_PYRA_H
-
-/*
- * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/types.h>
-
-struct pyra_b {
- uint8_t command; /* PYRA_COMMAND_B */
- uint8_t size; /* always 3 */
- uint8_t unknown; /* 1 */
-} __attribute__ ((__packed__));
-
-struct pyra_control {
- uint8_t command; /* PYRA_COMMAND_CONTROL */
- /*
- * value is profile number for request_settings and request_buttons
- * 1 if status ok for request_status
- */
- uint8_t value; /* Range 0-4 */
- uint8_t request;
-} __attribute__ ((__packed__));
-
-enum pyra_control_requests {
- PYRA_CONTROL_REQUEST_STATUS = 0x00,
- PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
- PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20
-};
-
-struct pyra_settings {
- uint8_t command; /* PYRA_COMMAND_SETTINGS */
- uint8_t size; /* always 3 */
- uint8_t startup_profile; /* Range 0-4! */
-} __attribute__ ((__packed__));
-
-struct pyra_profile_settings {
- uint8_t command; /* PYRA_COMMAND_PROFILE_SETTINGS */
- uint8_t size; /* always 0xd */
- uint8_t number; /* Range 0-4 */
- uint8_t xysync;
- uint8_t x_sensitivity; /* 0x1-0xa */
- uint8_t y_sensitivity;
- uint8_t x_cpi; /* unused */
- uint8_t y_cpi; /* this value is for x and y */
- uint8_t lightswitch; /* 0 = off, 1 = on */
- uint8_t light_effect;
- uint8_t handedness;
- uint16_t checksum; /* byte sum */
-} __attribute__ ((__packed__));
-
-struct pyra_profile_buttons {
- uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */
- uint8_t size; /* always 0x13 */
- uint8_t number; /* Range 0-4 */
- uint8_t buttons[14];
- uint16_t checksum; /* byte sum */
-} __attribute__ ((__packed__));
-
-struct pyra_info {
- uint8_t command; /* PYRA_COMMAND_INFO */
- uint8_t size; /* always 6 */
- uint8_t firmware_version;
- uint8_t unknown1; /* always 0 */
- uint8_t unknown2; /* always 1 */
- uint8_t unknown3; /* always 0 */
-} __attribute__ ((__packed__));
-
-enum pyra_commands {
- PYRA_COMMAND_CONTROL = 0x4,
- PYRA_COMMAND_SETTINGS = 0x5,
- PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
- PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
- PYRA_COMMAND_INFO = 0x9,
- PYRA_COMMAND_B = 0xb
-};
-
-enum pyra_mouse_report_numbers {
- PYRA_MOUSE_REPORT_NUMBER_HID = 1,
- PYRA_MOUSE_REPORT_NUMBER_AUDIO = 2,
- PYRA_MOUSE_REPORT_NUMBER_BUTTON = 3,
-};
-
-struct pyra_mouse_event_button {
- uint8_t report_number; /* always 3 */
- uint8_t unknown; /* always 0 */
- uint8_t type;
- uint8_t data1;
- uint8_t data2;
-} __attribute__ ((__packed__));
-
-struct pyra_mouse_event_audio {
- uint8_t report_number; /* always 2 */
- uint8_t type;
- uint8_t unused; /* always 0 */
-} __attribute__ ((__packed__));
-
-/* hid audio controls */
-enum pyra_mouse_event_audio_types {
- PYRA_MOUSE_EVENT_AUDIO_TYPE_MUTE = 0xe2,
- PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_UP = 0xe9,
- PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_DOWN = 0xea,
-};
-
-enum pyra_mouse_event_button_types {
- /*
- * Mouse sends tilt events on report_number 1 and 3
- * Tilt events are sent repeatedly with 0.94s between first and second
- * event and 0.22s on subsequent
- */
- PYRA_MOUSE_EVENT_BUTTON_TYPE_TILT = 0x10,
-
- /*
- * These are sent sequentially
- * data1 contains new profile number in range 1-5
- */
- PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_1 = 0x20,
- PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2 = 0x30,
-
- /*
- * data1 = button_number (rmp index)
- * data2 = pressed/released
- */
- PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO = 0x40,
- PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT = 0x50,
-
- /*
- * data1 = button_number (rmp index)
- */
- PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
-
- /* data1 = new cpi */
- PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI = 0xb0,
-
- /* data1 and data2 = new sensitivity */
- PYRA_MOUSE_EVENT_BUTTON_TYPE_SENSITIVITY = 0xc0,
-
- PYRA_MOUSE_EVENT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
-};
-
-enum {
- PYRA_MOUSE_EVENT_BUTTON_PRESS = 0,
- PYRA_MOUSE_EVENT_BUTTON_RELEASE = 1,
-};
-
-struct pyra_roccat_report {
- uint8_t type;
- uint8_t value;
- uint8_t key;
-} __attribute__ ((__packed__));
-
-struct pyra_device {
- int actual_profile;
- int actual_cpi;
- int firmware_version;
- int roccat_claimed;
- int chrdev_minor;
- struct mutex pyra_lock;
- struct pyra_settings settings;
- struct pyra_profile_settings profile_settings[5];
- struct pyra_profile_buttons profile_buttons[5];
-};
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-roccat.c b/ANDROID_3.4.5/drivers/hid/hid-roccat.c
deleted file mode 100644
index b685b04d..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-roccat.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Roccat driver for Linux
- *
- * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-/*
- * Module roccat is a char device used to report special events of roccat
- * hardware to userland. These events include requests for on-screen-display of
- * profile or dpi settings or requests for execution of macro sequences that are
- * not stored in device. The information in these events depends on hid device
- * implementation and contains data that is not available in a single hid event
- * or else hidraw could have been used.
- * It is inspired by hidraw, but uses only one circular buffer for all readers.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/cdev.h>
-#include <linux/poll.h>
-#include <linux/sched.h>
-#include <linux/hid-roccat.h>
-#include <linux/module.h>
-
-#define ROCCAT_FIRST_MINOR 0
-#define ROCCAT_MAX_DEVICES 8
-
-/* should be a power of 2 for performance reason */
-#define ROCCAT_CBUF_SIZE 16
-
-struct roccat_report {
- uint8_t *value;
-};
-
-struct roccat_device {
- unsigned int minor;
- int report_size;
- int open;
- int exist;
- wait_queue_head_t wait;
- struct device *dev;
- struct hid_device *hid;
- struct list_head readers;
- /* protects modifications of readers list */
- struct mutex readers_lock;
-
- /*
- * circular_buffer has one writer and multiple readers with their own
- * read pointers
- */
- struct roccat_report cbuf[ROCCAT_CBUF_SIZE];
- int cbuf_end;
- struct mutex cbuf_lock;
-};
-
-struct roccat_reader {
- struct list_head node;
- struct roccat_device *device;
- int cbuf_start;
-};
-
-static int roccat_major;
-static struct cdev roccat_cdev;
-
-static struct roccat_device *devices[ROCCAT_MAX_DEVICES];
-/* protects modifications of devices array */
-static DEFINE_MUTEX(devices_lock);
-
-static ssize_t roccat_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct roccat_reader *reader = file->private_data;
- struct roccat_device *device = reader->device;
- struct roccat_report *report;
- ssize_t retval = 0, len;
- DECLARE_WAITQUEUE(wait, current);
-
- mutex_lock(&device->cbuf_lock);
-
- /* no data? */
- if (reader->cbuf_start == device->cbuf_end) {
- add_wait_queue(&device->wait, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- /* wait for data */
- while (reader->cbuf_start == device->cbuf_end) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- if (!device->exist) {
- retval = -EIO;
- break;
- }
-
- mutex_unlock(&device->cbuf_lock);
- schedule();
- mutex_lock(&device->cbuf_lock);
- set_current_state(TASK_INTERRUPTIBLE);
- }
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&device->wait, &wait);
- }
-
- /* here we either have data or a reason to return if retval is set */
- if (retval)
- goto exit_unlock;
-
- report = &device->cbuf[reader->cbuf_start];
- /*
- * If report is larger than requested amount of data, rest of report
- * is lost!
- */
- len = device->report_size > count ? count : device->report_size;
-
- if (copy_to_user(buffer, report->value, len)) {
- retval = -EFAULT;
- goto exit_unlock;
- }
- retval += len;
- reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE;
-
-exit_unlock:
- mutex_unlock(&device->cbuf_lock);
- return retval;
-}
-
-static unsigned int roccat_poll(struct file *file, poll_table *wait)
-{
- struct roccat_reader *reader = file->private_data;
- poll_wait(file, &reader->device->wait, wait);
- if (reader->cbuf_start != reader->device->cbuf_end)
- return POLLIN | POLLRDNORM;
- if (!reader->device->exist)
- return POLLERR | POLLHUP;
- return 0;
-}
-
-static int roccat_open(struct inode *inode, struct file *file)
-{
- unsigned int minor = iminor(inode);
- struct roccat_reader *reader;
- struct roccat_device *device;
- int error = 0;
-
- reader = kzalloc(sizeof(struct roccat_reader), GFP_KERNEL);
- if (!reader)
- return -ENOMEM;
-
- mutex_lock(&devices_lock);
-
- device = devices[minor];
-
- if (!device) {
- pr_emerg("roccat device with minor %d doesn't exist\n", minor);
- error = -ENODEV;
- goto exit_err_devices;
- }
-
- mutex_lock(&device->readers_lock);
-
- if (!device->open++) {
- /* power on device on adding first reader */
- error = hid_hw_power(device->hid, PM_HINT_FULLON);
- if (error < 0) {
- --device->open;
- goto exit_err_readers;
- }
-
- error = hid_hw_open(device->hid);
- if (error < 0) {
- hid_hw_power(device->hid, PM_HINT_NORMAL);
- --device->open;
- goto exit_err_readers;
- }
- }
-
- reader->device = device;
- /* new reader doesn't get old events */
- reader->cbuf_start = device->cbuf_end;
-
- list_add_tail(&reader->node, &device->readers);
- file->private_data = reader;
-
-exit_err_readers:
- mutex_unlock(&device->readers_lock);
-exit_err_devices:
- mutex_unlock(&devices_lock);
- if (error)
- kfree(reader);
- return error;
-}
-
-static int roccat_release(struct inode *inode, struct file *file)
-{
- unsigned int minor = iminor(inode);
- struct roccat_reader *reader = file->private_data;
- struct roccat_device *device;
-
- mutex_lock(&devices_lock);
-
- device = devices[minor];
- if (!device) {
- mutex_unlock(&devices_lock);
- pr_emerg("roccat device with minor %d doesn't exist\n", minor);
- return -ENODEV;
- }
-
- mutex_lock(&device->readers_lock);
- list_del(&reader->node);
- mutex_unlock(&device->readers_lock);
- kfree(reader);
-
- if (!--device->open) {
- /* removing last reader */
- if (device->exist) {
- hid_hw_power(device->hid, PM_HINT_NORMAL);
- hid_hw_close(device->hid);
- } else {
- kfree(device);
- }
- }
-
- mutex_unlock(&devices_lock);
-
- return 0;
-}
-
-/*
- * roccat_report_event() - output data to readers
- * @minor: minor device number returned by roccat_connect()
- * @data: pointer to data
- * @len: size of data
- *
- * Return value is zero on success, a negative error code on failure.
- *
- * This is called from interrupt handler.
- */
-int roccat_report_event(int minor, u8 const *data)
-{
- struct roccat_device *device;
- struct roccat_reader *reader;
- struct roccat_report *report;
- uint8_t *new_value;
-
- device = devices[minor];
-
- new_value = kmemdup(data, device->report_size, GFP_ATOMIC);
- if (!new_value)
- return -ENOMEM;
-
- report = &device->cbuf[device->cbuf_end];
-
- /* passing NULL is safe */
- kfree(report->value);
-
- report->value = new_value;
- device->cbuf_end = (device->cbuf_end + 1) % ROCCAT_CBUF_SIZE;
-
- list_for_each_entry(reader, &device->readers, node) {
- /*
- * As we already inserted one element, the buffer can't be
- * empty. If start and end are equal, buffer is full and we
- * increase start, so that slow reader misses one event, but
- * gets the newer ones in the right order.
- */
- if (reader->cbuf_start == device->cbuf_end)
- reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE;
- }
-
- wake_up_interruptible(&device->wait);
- return 0;
-}
-EXPORT_SYMBOL_GPL(roccat_report_event);
-
-/*
- * roccat_connect() - create a char device for special event output
- * @class: the class thats used to create the device. Meant to hold device
- * specific sysfs attributes.
- * @hid: the hid device the char device should be connected to.
- *
- * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on
- * success, a negative error code on failure.
- */
-int roccat_connect(struct class *klass, struct hid_device *hid, int report_size)
-{
- unsigned int minor;
- struct roccat_device *device;
- int temp;
-
- device = kzalloc(sizeof(struct roccat_device), GFP_KERNEL);
- if (!device)
- return -ENOMEM;
-
- mutex_lock(&devices_lock);
-
- for (minor = 0; minor < ROCCAT_MAX_DEVICES; ++minor) {
- if (devices[minor])
- continue;
- break;
- }
-
- if (minor < ROCCAT_MAX_DEVICES) {
- devices[minor] = device;
- } else {
- mutex_unlock(&devices_lock);
- kfree(device);
- return -EINVAL;
- }
-
- device->dev = device_create(klass, &hid->dev,
- MKDEV(roccat_major, minor), NULL,
- "%s%s%d", "roccat", hid->driver->name, minor);
-
- if (IS_ERR(device->dev)) {
- devices[minor] = NULL;
- mutex_unlock(&devices_lock);
- temp = PTR_ERR(device->dev);
- kfree(device);
- return temp;
- }
-
- mutex_unlock(&devices_lock);
-
- init_waitqueue_head(&device->wait);
- INIT_LIST_HEAD(&device->readers);
- mutex_init(&device->readers_lock);
- mutex_init(&device->cbuf_lock);
- device->minor = minor;
- device->hid = hid;
- device->exist = 1;
- device->cbuf_end = 0;
- device->report_size = report_size;
-
- return minor;
-}
-EXPORT_SYMBOL_GPL(roccat_connect);
-
-/* roccat_disconnect() - remove char device from hid device
- * @minor: the minor device number returned by roccat_connect()
- */
-void roccat_disconnect(int minor)
-{
- struct roccat_device *device;
-
- mutex_lock(&devices_lock);
- device = devices[minor];
- mutex_unlock(&devices_lock);
-
- device->exist = 0; /* TODO exist maybe not needed */
-
- device_destroy(device->dev->class, MKDEV(roccat_major, minor));
-
- mutex_lock(&devices_lock);
- devices[minor] = NULL;
- mutex_unlock(&devices_lock);
-
- if (device->open) {
- hid_hw_close(device->hid);
- wake_up_interruptible(&device->wait);
- } else {
- kfree(device);
- }
-}
-EXPORT_SYMBOL_GPL(roccat_disconnect);
-
-static long roccat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct inode *inode = file->f_path.dentry->d_inode;
- struct roccat_device *device;
- unsigned int minor = iminor(inode);
- long retval = 0;
-
- mutex_lock(&devices_lock);
-
- device = devices[minor];
- if (!device) {
- retval = -ENODEV;
- goto out;
- }
-
- switch (cmd) {
- case ROCCATIOCGREPSIZE:
- if (put_user(device->report_size, (int __user *)arg))
- retval = -EFAULT;
- break;
- default:
- retval = -ENOTTY;
- }
-out:
- mutex_unlock(&devices_lock);
- return retval;
-}
-
-static const struct file_operations roccat_ops = {
- .owner = THIS_MODULE,
- .read = roccat_read,
- .poll = roccat_poll,
- .open = roccat_open,
- .release = roccat_release,
- .llseek = noop_llseek,
- .unlocked_ioctl = roccat_ioctl,
-};
-
-static int __init roccat_init(void)
-{
- int retval;
- dev_t dev_id;
-
- retval = alloc_chrdev_region(&dev_id, ROCCAT_FIRST_MINOR,
- ROCCAT_MAX_DEVICES, "roccat");
-
- roccat_major = MAJOR(dev_id);
-
- if (retval < 0) {
- pr_warn("can't get major number\n");
- return retval;
- }
-
- cdev_init(&roccat_cdev, &roccat_ops);
- cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES);
-
- return 0;
-}
-
-static void __exit roccat_exit(void)
-{
- dev_t dev_id = MKDEV(roccat_major, 0);
-
- cdev_del(&roccat_cdev);
- unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES);
-}
-
-module_init(roccat_init);
-module_exit(roccat_exit);
-
-MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat char device");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-saitek.c b/ANDROID_3.4.5/drivers/hid/hid-saitek.c
deleted file mode 100644
index 45aea77b..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-saitek.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * HID driver for Saitek devices, currently only the PS1000 (USB gamepad).
- * Fixes the HID report descriptor by removing a non-existent axis and
- * clearing the constant bit on the input reports for buttons and d-pad.
- * (This module is based on "hid-ortek".)
- *
- * Copyright (c) 2012 Andreas Hübner
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include "hid-ids.h"
-
-static __u8 *saitek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize == 137 && rdesc[20] == 0x09 && rdesc[21] == 0x33
- && rdesc[94] == 0x81 && rdesc[95] == 0x03
- && rdesc[110] == 0x81 && rdesc[111] == 0x03) {
-
- hid_info(hdev, "Fixing up Saitek PS1000 report descriptor\n");
-
- /* convert spurious axis to a "noop" Logical Minimum (0) */
- rdesc[20] = 0x15;
- rdesc[21] = 0x00;
-
- /* clear constant bit on buttons and d-pad */
- rdesc[95] = 0x02;
- rdesc[111] = 0x02;
-
- }
- return rdesc;
-}
-
-static const struct hid_device_id saitek_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000)},
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, saitek_devices);
-
-static struct hid_driver saitek_driver = {
- .name = "saitek",
- .id_table = saitek_devices,
- .report_fixup = saitek_report_fixup
-};
-
-static int __init saitek_init(void)
-{
- return hid_register_driver(&saitek_driver);
-}
-
-static void __exit saitek_exit(void)
-{
- hid_unregister_driver(&saitek_driver);
-}
-
-module_init(saitek_init);
-module_exit(saitek_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-samsung.c b/ANDROID_3.4.5/drivers/hid/hid-samsung.c
deleted file mode 100644
index 3c1fd8af..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-samsung.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * HID driver for some samsung "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- * Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>
- *
- *
- * This driver supports several HID devices:
- *
- * [0419:0001] Samsung IrDA remote controller (reports as Cypress USB Mouse).
- * various hid report fixups for different variants.
- *
- * [0419:0600] Creative Desktop Wireless 6000 keyboard/mouse combo
- * several key mappings used from the consumer usage page
- * deviate from the USB HUT 1.12 standard.
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-/*
- * There are several variants for 0419:0001:
- *
- * 1. 184 byte report descriptor
- * Vendor specific report #4 has a size of 48 bit,
- * and therefore is not accepted when inspecting the descriptors.
- * As a workaround we reinterpret the report as:
- * Variable type, count 6, size 8 bit, log. maximum 255
- * The burden to reconstruct the data is moved into user space.
- *
- * 2. 203 byte report descriptor
- * Report #4 has an array field with logical range 0..18 instead of 1..15.
- *
- * 3. 135 byte report descriptor
- * Report #4 has an array field with logical range 0..17 instead of 1..14.
- *
- * 4. 171 byte report descriptor
- * Report #3 has an array field with logical range 0..1 instead of 1..3.
- */
-static inline void samsung_irda_dev_trace(struct hid_device *hdev,
- unsigned int rsize)
-{
- hid_info(hdev, "fixing up Samsung IrDA %d byte report descriptor\n",
- rsize);
-}
-
-static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
- rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
- rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
- rdesc[182] == 0x40) {
- samsung_irda_dev_trace(hdev, 184);
- rdesc[176] = 0xff;
- rdesc[178] = 0x08;
- rdesc[180] = 0x06;
- rdesc[182] = 0x42;
- } else
- if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
- rdesc[194] == 0x25 && rdesc[195] == 0x12) {
- samsung_irda_dev_trace(hdev, 203);
- rdesc[193] = 0x1;
- rdesc[195] = 0xf;
- } else
- if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
- rdesc[126] == 0x25 && rdesc[127] == 0x11) {
- samsung_irda_dev_trace(hdev, 135);
- rdesc[125] = 0x1;
- rdesc[127] = 0xe;
- } else
- if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
- rdesc[162] == 0x25 && rdesc[163] == 0x01) {
- samsung_irda_dev_trace(hdev, 171);
- rdesc[161] = 0x1;
- rdesc[163] = 0x3;
- }
- return rdesc;
-}
-
-#define samsung_kbd_mouse_map_key_clear(c) \
- hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
-
-static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
- struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
-
- if (1 != ifnum || HID_UP_CONSUMER != (usage->hid & HID_USAGE_PAGE))
- return 0;
-
- dbg_hid("samsung wireless keyboard/mouse input mapping event [0x%x]\n",
- usage->hid & HID_USAGE);
-
- switch (usage->hid & HID_USAGE) {
- /* report 2 */
- case 0x183: samsung_kbd_mouse_map_key_clear(KEY_MEDIA); break;
- case 0x195: samsung_kbd_mouse_map_key_clear(KEY_EMAIL); break;
- case 0x196: samsung_kbd_mouse_map_key_clear(KEY_CALC); break;
- case 0x197: samsung_kbd_mouse_map_key_clear(KEY_COMPUTER); break;
- case 0x22b: samsung_kbd_mouse_map_key_clear(KEY_SEARCH); break;
- case 0x22c: samsung_kbd_mouse_map_key_clear(KEY_WWW); break;
- case 0x22d: samsung_kbd_mouse_map_key_clear(KEY_BACK); break;
- case 0x22e: samsung_kbd_mouse_map_key_clear(KEY_FORWARD); break;
- case 0x22f: samsung_kbd_mouse_map_key_clear(KEY_FAVORITES); break;
- case 0x230: samsung_kbd_mouse_map_key_clear(KEY_REFRESH); break;
- case 0x231: samsung_kbd_mouse_map_key_clear(KEY_STOP); break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
- rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize);
- return rdesc;
-}
-
-static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- int ret = 0;
-
- if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product)
- ret = samsung_kbd_mouse_input_mapping(hdev,
- hi, field, usage, bit, max);
-
- return ret;
-}
-
-static int samsung_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- int ret;
- unsigned int cmask = HID_CONNECT_DEFAULT;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) {
- if (hdev->rsize == 184) {
- /* disable hidinput, force hiddev */
- cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
- HID_CONNECT_HIDDEV_FORCE;
- }
- }
-
- ret = hid_hw_start(hdev, cmask);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- return 0;
-err_free:
- return ret;
-}
-
-static const struct hid_device_id samsung_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, samsung_devices);
-
-static struct hid_driver samsung_driver = {
- .name = "samsung",
- .id_table = samsung_devices,
- .report_fixup = samsung_report_fixup,
- .input_mapping = samsung_input_mapping,
- .probe = samsung_probe,
-};
-
-static int __init samsung_init(void)
-{
- return hid_register_driver(&samsung_driver);
-}
-
-static void __exit samsung_exit(void)
-{
- hid_unregister_driver(&samsung_driver);
-}
-
-module_init(samsung_init);
-module_exit(samsung_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-sjoy.c b/ANDROID_3.4.5/drivers/hid/hid-sjoy.c
deleted file mode 100644
index 42257acf..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-sjoy.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Force feedback support for SmartJoy PLUS PS2->USB adapter
- *
- * Copyright (c) 2009 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
- *
- * Based of hid-pl.c and hid-gaff.c
- * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
- * Copyright (c) 2008 Lukasz Lubojanski <lukasz@lubojanski.info>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* #define DEBUG */
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include "hid-ids.h"
-
-#ifdef CONFIG_SMARTJOYPLUS_FF
-#include "usbhid/usbhid.h"
-
-struct sjoyff_device {
- struct hid_report *report;
-};
-
-static int hid_sjoyff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct sjoyff_device *sjoyff = data;
- u32 left, right;
-
- left = effect->u.rumble.strong_magnitude;
- right = effect->u.rumble.weak_magnitude;
- dev_dbg(&dev->dev, "called with 0x%08x 0x%08x\n", left, right);
-
- left = left * 0xff / 0xffff;
- right = (right != 0); /* on/off only */
-
- sjoyff->report->field[0]->value[1] = right;
- sjoyff->report->field[0]->value[2] = left;
- dev_dbg(&dev->dev, "running with 0x%02x 0x%02x\n", left, right);
- usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int sjoyff_init(struct hid_device *hid)
-{
- struct sjoyff_device *sjoyff;
- struct hid_report *report;
- struct hid_input *hidinput;
- struct list_head *report_list =
- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct list_head *report_ptr = report_list;
- struct input_dev *dev;
- int error;
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output reports found\n");
- return -ENODEV;
- }
-
- list_for_each_entry(hidinput, &hid->inputs, list) {
- report_ptr = report_ptr->next;
-
- if (report_ptr == report_list) {
- hid_err(hid, "required output report is missing\n");
- return -ENODEV;
- }
-
- report = list_entry(report_ptr, struct hid_report, list);
- if (report->maxfield < 1) {
- hid_err(hid, "no fields in the report\n");
- return -ENODEV;
- }
-
- if (report->field[0]->report_count < 3) {
- hid_err(hid, "not enough values in the field\n");
- return -ENODEV;
- }
-
- sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL);
- if (!sjoyff)
- return -ENOMEM;
-
- dev = hidinput->input;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play);
- if (error) {
- kfree(sjoyff);
- return error;
- }
-
- sjoyff->report = report;
- sjoyff->report->field[0]->value[0] = 0x01;
- sjoyff->report->field[0]->value[1] = 0x00;
- sjoyff->report->field[0]->value[2] = 0x00;
- usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);
- }
-
- hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n");
-
- return 0;
-}
-#else
-static inline int sjoyff_init(struct hid_device *hid)
-{
- return 0;
-}
-#endif
-
-static int sjoy_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- hdev->quirks |= id->driver_data;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- sjoyff_init(hdev);
-
- return 0;
-err:
- return ret;
-}
-
-static const struct hid_device_id sjoy_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO),
- .driver_data = HID_QUIRK_NOGET },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO),
- .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
- HID_QUIRK_SKIP_OUTPUT_REPORTS },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO),
- .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
- HID_QUIRK_SKIP_OUTPUT_REPORTS },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD),
- .driver_data = HID_QUIRK_MULTI_INPUT |
- HID_QUIRK_SKIP_OUTPUT_REPORTS },
- { }
-};
-MODULE_DEVICE_TABLE(hid, sjoy_devices);
-
-static struct hid_driver sjoy_driver = {
- .name = "smartjoyplus",
- .id_table = sjoy_devices,
- .probe = sjoy_probe,
-};
-
-static int __init sjoy_init(void)
-{
- return hid_register_driver(&sjoy_driver);
-}
-
-static void __exit sjoy_exit(void)
-{
- hid_unregister_driver(&sjoy_driver);
-}
-
-module_init(sjoy_init);
-module_exit(sjoy_exit);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jussi Kivilinna");
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-sony.c b/ANDROID_3.4.5/drivers/hid/hid-sony.c
deleted file mode 100644
index 5cd25bd9..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-sony.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * HID driver for some sony "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- * Copyright (c) 2006-2008 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "hid-ids.h"
-
-#define VAIO_RDESC_CONSTANT (1 << 0)
-#define SIXAXIS_CONTROLLER_USB (1 << 1)
-#define SIXAXIS_CONTROLLER_BT (1 << 2)
-
-static const u8 sixaxis_rdesc_fixup[] = {
- 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
- 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF,
- 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
-};
-
-struct sony_sc {
- unsigned long quirks;
-};
-
-/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
-static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- struct sony_sc *sc = hid_get_drvdata(hdev);
-
- if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
- *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
- hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n");
- rdesc[55] = 0x06;
- }
-
- /* The HID descriptor exposed over BT has a trailing zero byte */
- if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
- ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
- rdesc[83] == 0x75) {
- hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
- memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
- sizeof(sixaxis_rdesc_fixup));
- }
- return rdesc;
-}
-
-static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
- __u8 *rd, int size)
-{
- struct sony_sc *sc = hid_get_drvdata(hdev);
-
- /* Sixaxis HID report has acclerometers/gyro with MSByte first, this
- * has to be BYTE_SWAPPED before passing up to joystick interface
- */
- if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) &&
- rd[0] == 0x01 && size == 49) {
- swap(rd[41], rd[42]);
- swap(rd[43], rd[44]);
- swap(rd[45], rd[46]);
- swap(rd[47], rd[48]);
- }
-
- return 0;
-}
-
-/*
- * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
- * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
- * so we need to override that forcing HID Output Reports on the Control EP.
- *
- * There is also another issue about HID Output Reports via USB, the Sixaxis
- * does not want the report_id as part of the data packet, so we have to
- * discard buf[0] when sending the actual control message, even for numbered
- * reports, humpf!
- */
-static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
- size_t count, unsigned char report_type)
-{
- struct usb_interface *intf = to_usb_interface(hid->dev.parent);
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface = intf->cur_altsetting;
- int report_id = buf[0];
- int ret;
-
- if (report_type == HID_OUTPUT_REPORT) {
- /* Don't send the Report ID */
- buf++;
- count--;
- }
-
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- HID_REQ_SET_REPORT,
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ((report_type + 1) << 8) | report_id,
- interface->desc.bInterfaceNumber, buf, count,
- USB_CTRL_SET_TIMEOUT);
-
- /* Count also the Report ID, in case of an Output report. */
- if (ret > 0 && report_type == HID_OUTPUT_REPORT)
- ret++;
-
- return ret;
-}
-
-/*
- * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
- * to "operational". Without this, the ps3 controller will not report any
- * events.
- */
-static int sixaxis_set_operational_usb(struct hid_device *hdev)
-{
- struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
- struct usb_device *dev = interface_to_usbdev(intf);
- __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
- int ret;
- char *buf = kmalloc(18, GFP_KERNEL);
-
- if (!buf)
- return -ENOMEM;
-
- ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- HID_REQ_GET_REPORT,
- USB_DIR_IN | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE,
- (3 << 8) | 0xf2, ifnum, buf, 17,
- USB_CTRL_GET_TIMEOUT);
- if (ret < 0)
- hid_err(hdev, "can't set operational mode\n");
-
- kfree(buf);
-
- return ret;
-}
-
-static int sixaxis_set_operational_bt(struct hid_device *hdev)
-{
- unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
- return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
-}
-
-static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
- unsigned long quirks = id->driver_data;
- struct sony_sc *sc;
-
- sc = kzalloc(sizeof(*sc), GFP_KERNEL);
- if (sc == NULL) {
- hid_err(hdev, "can't alloc sony descriptor\n");
- return -ENOMEM;
- }
-
- sc->quirks = quirks;
- hid_set_drvdata(hdev, sc);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
- HID_CONNECT_HIDDEV_FORCE);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
- hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
- ret = sixaxis_set_operational_usb(hdev);
- }
- else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
- ret = sixaxis_set_operational_bt(hdev);
- else
- ret = 0;
-
- if (ret < 0)
- goto err_stop;
-
- return 0;
-err_stop:
- hid_hw_stop(hdev);
-err_free:
- kfree(sc);
- return ret;
-}
-
-static void sony_remove(struct hid_device *hdev)
-{
- hid_hw_stop(hdev);
- kfree(hid_get_drvdata(hdev));
-}
-
-static const struct hid_device_id sony_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
- .driver_data = SIXAXIS_CONTROLLER_USB },
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
- .driver_data = SIXAXIS_CONTROLLER_USB },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
- .driver_data = SIXAXIS_CONTROLLER_BT },
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
- .driver_data = VAIO_RDESC_CONSTANT },
- { }
-};
-MODULE_DEVICE_TABLE(hid, sony_devices);
-
-static struct hid_driver sony_driver = {
- .name = "sony",
- .id_table = sony_devices,
- .probe = sony_probe,
- .remove = sony_remove,
- .report_fixup = sony_report_fixup,
- .raw_event = sony_raw_event
-};
-
-static int __init sony_init(void)
-{
- return hid_register_driver(&sony_driver);
-}
-
-static void __exit sony_exit(void)
-{
- hid_unregister_driver(&sony_driver);
-}
-
-module_init(sony_init);
-module_exit(sony_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-speedlink.c b/ANDROID_3.4.5/drivers/hid/hid-speedlink.c
deleted file mode 100644
index 60201374..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-speedlink.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * HID driver for Speedlink Vicious and Divine Cezanne (USB mouse).
- * Fixes "jumpy" cursor and removes nonexistent keyboard LEDS from
- * the HID descriptor.
- *
- * Copyright (c) 2011 Stefan Kriwanek <mail@stefankriwanek.de>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#include "hid-ids.h"
-#include "usbhid/usbhid.h"
-
-static const struct hid_device_id speedlink_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE)},
- { }
-};
-
-static int speedlink_input_mapping(struct hid_device *hdev,
- struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- /*
- * The Cezanne mouse has a second "keyboard" USB endpoint for it is
- * able to map keyboard events to the button presses.
- * It sends a standard keyboard report descriptor, though, whose
- * LEDs we ignore.
- */
- switch (usage->hid & HID_USAGE_PAGE) {
- case HID_UP_LED:
- return -1;
- }
- return 0;
-}
-
-static int speedlink_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- /* No other conditions due to usage_table. */
- /* Fix "jumpy" cursor (invalid events sent by device). */
- if (value == 256)
- return 1;
- /* Drop useless distance 0 events (on button clicks etc.) as well */
- if (value == 0)
- return 1;
-
- return 0;
-}
-
-MODULE_DEVICE_TABLE(hid, speedlink_devices);
-
-static const struct hid_usage_id speedlink_grabbed_usages[] = {
- { HID_GD_X, EV_REL, 0 },
- { HID_GD_Y, EV_REL, 1 },
- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
-};
-
-static struct hid_driver speedlink_driver = {
- .name = "speedlink",
- .id_table = speedlink_devices,
- .usage_table = speedlink_grabbed_usages,
- .input_mapping = speedlink_input_mapping,
- .event = speedlink_event,
-};
-
-static int __init speedlink_init(void)
-{
- return hid_register_driver(&speedlink_driver);
-}
-
-static void __exit speedlink_exit(void)
-{
- hid_unregister_driver(&speedlink_driver);
-}
-
-module_init(speedlink_init);
-module_exit(speedlink_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-sunplus.c b/ANDROID_3.4.5/drivers/hid/hid-sunplus.c
deleted file mode 100644
index d484a004..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-sunplus.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * HID driver for some sunplus "special" devices
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 &&
- rdesc[106] == 0x03) {
- hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n");
- rdesc[105] = rdesc[110] = 0x03;
- rdesc[106] = rdesc[111] = 0x21;
- }
- return rdesc;
-}
-
-#define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int sp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x2003: sp_map_key_clear(KEY_ZOOMIN); break;
- case 0x2103: sp_map_key_clear(KEY_ZOOMOUT); break;
- default:
- return 0;
- }
- return 1;
-}
-
-static const struct hid_device_id sp_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, sp_devices);
-
-static struct hid_driver sp_driver = {
- .name = "sunplus",
- .id_table = sp_devices,
- .report_fixup = sp_report_fixup,
- .input_mapping = sp_input_mapping,
-};
-
-static int __init sp_init(void)
-{
- return hid_register_driver(&sp_driver);
-}
-
-static void __exit sp_exit(void)
-{
- hid_unregister_driver(&sp_driver);
-}
-
-module_init(sp_init);
-module_exit(sp_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-tivo.c b/ANDROID_3.4.5/drivers/hid/hid-tivo.c
deleted file mode 100644
index 9f85f827..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-tivo.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * HID driver for TiVo Slide Bluetooth remote
- *
- * Copyright (c) 2011 Jarod Wilson <jarod@redhat.com>
- * based on the hid-topseed driver, which is in turn, based on hid-cherry...
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define HID_UP_TIVOVENDOR 0xffff0000
-#define tivo_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-
-static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- switch (usage->hid & HID_USAGE_PAGE) {
- case HID_UP_TIVOVENDOR:
- switch (usage->hid & HID_USAGE) {
- /* TiVo button */
- case 0x3d: tivo_map_key_clear(KEY_MEDIA); break;
- /* Live TV */
- case 0x3e: tivo_map_key_clear(KEY_TV); break;
- /* Red thumbs down */
- case 0x41: tivo_map_key_clear(KEY_KPMINUS); break;
- /* Green thumbs up */
- case 0x42: tivo_map_key_clear(KEY_KPPLUS); break;
- default:
- return 0;
- }
- break;
- case HID_UP_CONSUMER:
- switch (usage->hid & HID_USAGE) {
- /* Enter/Last (default mapping: KEY_LAST) */
- case 0x083: tivo_map_key_clear(KEY_ENTER); break;
- /* Info (default mapping: KEY_PROPS) */
- case 0x209: tivo_map_key_clear(KEY_INFO); break;
- default:
- return 0;
- }
- break;
- default:
- return 0;
- }
-
- /* This means we found a matching mapping here, else, look in the
- * standard hid mappings in hid-input.c */
- return 1;
-}
-
-static const struct hid_device_id tivo_devices[] = {
- /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
- { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, tivo_devices);
-
-static struct hid_driver tivo_driver = {
- .name = "tivo_slide",
- .id_table = tivo_devices,
- .input_mapping = tivo_input_mapping,
-};
-
-static int __init tivo_init(void)
-{
- return hid_register_driver(&tivo_driver);
-}
-
-static void __exit tivo_exit(void)
-{
- hid_unregister_driver(&tivo_driver);
-}
-
-module_init(tivo_init);
-module_exit(tivo_exit);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-tmff.c b/ANDROID_3.4.5/drivers/hid/hid-tmff.c
deleted file mode 100644
index 83a933b9..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-tmff.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Force feedback support for various HID compliant devices by ThrustMaster:
- * ThrustMaster FireStorm Dual Power 2
- * and possibly others whose device ids haven't been added.
- *
- * Modified to support ThrustMaster devices by Zinx Verituse
- * on 2003-01-25 from the Logitech force feedback driver,
- * which is by Johann Deneux.
- *
- * Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org>
- * Copyright (c) 2002 Johann Deneux
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-static const signed short ff_rumble[] = {
- FF_RUMBLE,
- -1
-};
-
-static const signed short ff_joystick[] = {
- FF_CONSTANT,
- -1
-};
-
-#ifdef CONFIG_THRUSTMASTER_FF
-#include "usbhid/usbhid.h"
-
-/* Usages for thrustmaster devices I know about */
-#define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb)
-
-struct tmff_device {
- struct hid_report *report;
- struct hid_field *ff_field;
-};
-
-/* Changes values from 0 to 0xffff into values from minimum to maximum */
-static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum)
-{
- int ret;
-
- ret = (in * (maximum - minimum) / 0xffff) + minimum;
- if (ret < minimum)
- return minimum;
- if (ret > maximum)
- return maximum;
- return ret;
-}
-
-/* Changes values from -0x80 to 0x7f into values from minimum to maximum */
-static inline int tmff_scale_s8(int in, int minimum, int maximum)
-{
- int ret;
-
- ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum;
- if (ret < minimum)
- return minimum;
- if (ret > maximum)
- return maximum;
- return ret;
-}
-
-static int tmff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct tmff_device *tmff = data;
- struct hid_field *ff_field = tmff->ff_field;
- int x, y;
- int left, right; /* Rumbling */
-
- switch (effect->type) {
- case FF_CONSTANT:
- x = tmff_scale_s8(effect->u.ramp.start_level,
- ff_field->logical_minimum,
- ff_field->logical_maximum);
- y = tmff_scale_s8(effect->u.ramp.end_level,
- ff_field->logical_minimum,
- ff_field->logical_maximum);
-
- dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
- ff_field->value[0] = x;
- ff_field->value[1] = y;
- usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
- break;
-
- case FF_RUMBLE:
- left = tmff_scale_u16(effect->u.rumble.weak_magnitude,
- ff_field->logical_minimum,
- ff_field->logical_maximum);
- right = tmff_scale_u16(effect->u.rumble.strong_magnitude,
- ff_field->logical_minimum,
- ff_field->logical_maximum);
-
- dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
- ff_field->value[0] = left;
- ff_field->value[1] = right;
- usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
- break;
- }
- return 0;
-}
-
-static int tmff_init(struct hid_device *hid, const signed short *ff_bits)
-{
- struct tmff_device *tmff;
- struct hid_report *report;
- struct list_head *report_list;
- struct hid_input *hidinput = list_entry(hid->inputs.next,
- struct hid_input, list);
- struct input_dev *input_dev = hidinput->input;
- int error;
- int i;
-
- tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
- if (!tmff)
- return -ENOMEM;
-
- /* Find the report to use */
- report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- list_for_each_entry(report, report_list, list) {
- int fieldnum;
-
- for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) {
- struct hid_field *field = report->field[fieldnum];
-
- if (field->maxusage <= 0)
- continue;
-
- switch (field->usage[0].hid) {
- case THRUSTMASTER_USAGE_FF:
- if (field->report_count < 2) {
- hid_warn(hid, "ignoring FF field with report_count < 2\n");
- continue;
- }
-
- if (field->logical_maximum ==
- field->logical_minimum) {
- hid_warn(hid, "ignoring FF field with logical_maximum == logical_minimum\n");
- continue;
- }
-
- if (tmff->report && tmff->report != report) {
- hid_warn(hid, "ignoring FF field in other report\n");
- continue;
- }
-
- if (tmff->ff_field && tmff->ff_field != field) {
- hid_warn(hid, "ignoring duplicate FF field\n");
- continue;
- }
-
- tmff->report = report;
- tmff->ff_field = field;
-
- for (i = 0; ff_bits[i] >= 0; i++)
- set_bit(ff_bits[i], input_dev->ffbit);
-
- break;
-
- default:
- hid_warn(hid, "ignoring unknown output usage %08x\n",
- field->usage[0].hid);
- continue;
- }
- }
- }
-
- if (!tmff->report) {
- hid_err(hid, "can't find FF field in output reports\n");
- error = -ENODEV;
- goto fail;
- }
-
- error = input_ff_create_memless(input_dev, tmff, tmff_play);
- if (error)
- goto fail;
-
- hid_info(hid, "force feedback for ThrustMaster devices by Zinx Verituse <zinx@epicsol.org>\n");
- return 0;
-
-fail:
- kfree(tmff);
- return error;
-}
-#else
-static inline int tmff_init(struct hid_device *hid, const signed short *ff_bits)
-{
- return 0;
-}
-#endif
-
-static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- tmff_init(hdev, (void *)id->driver_data);
-
- return 0;
-err:
- return ret;
-}
-
-static const struct hid_device_id tm_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300),
- .driver_data = (unsigned long)ff_rumble },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304), /* FireStorm Dual Power 2 (and 3) */
- .driver_data = (unsigned long)ff_rumble },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323), /* Dual Trigger 3-in-1 (PC Mode) */
- .driver_data = (unsigned long)ff_rumble },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324), /* Dual Trigger 3-in-1 (PS3 Mode) */
- .driver_data = (unsigned long)ff_rumble },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */
- .driver_data = (unsigned long)ff_rumble },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653), /* RGT Force Feedback CLUTCH Raging Wheel */
- .driver_data = (unsigned long)ff_joystick },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */
- .driver_data = (unsigned long)ff_joystick },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a), /* F430 Force Feedback Wheel */
- .driver_data = (unsigned long)ff_joystick },
- { }
-};
-MODULE_DEVICE_TABLE(hid, tm_devices);
-
-static struct hid_driver tm_driver = {
- .name = "thrustmaster",
- .id_table = tm_devices,
- .probe = tm_probe,
-};
-
-static int __init tm_init(void)
-{
- return hid_register_driver(&tm_driver);
-}
-
-static void __exit tm_exit(void)
-{
- hid_unregister_driver(&tm_driver);
-}
-
-module_init(tm_init);
-module_exit(tm_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-topseed.c b/ANDROID_3.4.5/drivers/hid/hid-topseed.c
deleted file mode 100644
index 613ff7b1..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-topseed.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * HID driver for TopSeed Cyberlink remote
- *
- * Copyright (c) 2008 Lev Babiev
- * based on hid-cherry driver
- *
- * Modified to also support BTC "Emprex 3009URF III Vista MCE Remote" by
- * Wayne Thomas 2010.
- *
- * Modified to support Conceptronic CLLRCMCE by
- * Kees Bakker 2010.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define ts_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- case 0x00d: ts_map_key_clear(KEY_MEDIA); break;
- case 0x024: ts_map_key_clear(KEY_MENU); break;
- case 0x025: ts_map_key_clear(KEY_TV); break;
- case 0x027: ts_map_key_clear(KEY_MODE); break;
- case 0x031: ts_map_key_clear(KEY_AUDIO); break;
- case 0x032: ts_map_key_clear(KEY_TEXT); break;
- case 0x033: ts_map_key_clear(KEY_CHANNEL); break;
- case 0x047: ts_map_key_clear(KEY_MP3); break;
- case 0x048: ts_map_key_clear(KEY_TV2); break;
- case 0x049: ts_map_key_clear(KEY_CAMERA); break;
- case 0x04a: ts_map_key_clear(KEY_VIDEO); break;
- case 0x04b: ts_map_key_clear(KEY_ANGLE); break;
- case 0x04c: ts_map_key_clear(KEY_LANGUAGE); break;
- case 0x04d: ts_map_key_clear(KEY_SUBTITLE); break;
- case 0x050: ts_map_key_clear(KEY_RADIO); break;
- case 0x05a: ts_map_key_clear(KEY_TEXT); break;
- case 0x05b: ts_map_key_clear(KEY_RED); break;
- case 0x05c: ts_map_key_clear(KEY_GREEN); break;
- case 0x05d: ts_map_key_clear(KEY_YELLOW); break;
- case 0x05e: ts_map_key_clear(KEY_BLUE); break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static const struct hid_device_id ts_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
- { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
- { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, ts_devices);
-
-static struct hid_driver ts_driver = {
- .name = "topseed",
- .id_table = ts_devices,
- .input_mapping = ts_input_mapping,
-};
-
-static int __init ts_init(void)
-{
- return hid_register_driver(&ts_driver);
-}
-
-static void __exit ts_exit(void)
-{
- hid_unregister_driver(&ts_driver);
-}
-
-module_init(ts_init);
-module_exit(ts_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-twinhan.c b/ANDROID_3.4.5/drivers/hid/hid-twinhan.c
deleted file mode 100644
index f23456b1..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-twinhan.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * HID driver for TwinHan IR remote control
- *
- * Based on hid-gyration.c
- *
- * Copyright (c) 2009 Bruno Prémont <bonbons@linux-vserver.org>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License.
- */
-
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-/* Remote control key layout + listing:
- *
- * Full Screen Power
- * KEY_SCREEN KEY_POWER2
- *
- * 1 2 3
- * KEY_NUMERIC_1 KEY_NUMERIC_2 KEY_NUMERIC_3
- *
- * 4 5 6
- * KEY_NUMERIC_4 KEY_NUMERIC_5 KEY_NUMERIC_6
- *
- * 7 8 9
- * KEY_NUMERIC_7 KEY_NUMERIC_8 KEY_NUMERIC_9
- *
- * REC 0 Favorite
- * KEY_RECORD KEY_NUMERIC_0 KEY_FAVORITES
- *
- * Rewind Forward
- * KEY_REWIND CH+ KEY_FORWARD
- * KEY_CHANNELUP
- *
- * VOL- > VOL+
- * KEY_VOLUMEDOWN KEY_PLAY KEY_VOLUMEUP
- *
- * CH-
- * KEY_CHANNELDOWN
- * Recall Stop
- * KEY_RESTART KEY_STOP
- *
- * Timeshift/Pause Mute Cancel
- * KEY_PAUSE KEY_MUTE KEY_CANCEL
- *
- * Capture Preview EPG
- * KEY_PRINT KEY_PROGRAM KEY_EPG
- *
- * Record List Tab Teletext
- * KEY_LIST KEY_TAB KEY_TEXT
- */
-
-#define th_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
- EV_KEY, (c))
-static int twinhan_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_KEYBOARD)
- return 0;
-
- switch (usage->hid & HID_USAGE) {
- /* Map all keys from Twinhan Remote */
- case 0x004: th_map_key_clear(KEY_TEXT); break;
- case 0x006: th_map_key_clear(KEY_RESTART); break;
- case 0x008: th_map_key_clear(KEY_EPG); break;
- case 0x00c: th_map_key_clear(KEY_REWIND); break;
- case 0x00e: th_map_key_clear(KEY_PROGRAM); break;
- case 0x00f: th_map_key_clear(KEY_LIST); break;
- case 0x010: th_map_key_clear(KEY_MUTE); break;
- case 0x011: th_map_key_clear(KEY_FORWARD); break;
- case 0x013: th_map_key_clear(KEY_PRINT); break;
- case 0x017: th_map_key_clear(KEY_PAUSE); break;
- case 0x019: th_map_key_clear(KEY_FAVORITES); break;
- case 0x01d: th_map_key_clear(KEY_SCREEN); break;
- case 0x01e: th_map_key_clear(KEY_NUMERIC_1); break;
- case 0x01f: th_map_key_clear(KEY_NUMERIC_2); break;
- case 0x020: th_map_key_clear(KEY_NUMERIC_3); break;
- case 0x021: th_map_key_clear(KEY_NUMERIC_4); break;
- case 0x022: th_map_key_clear(KEY_NUMERIC_5); break;
- case 0x023: th_map_key_clear(KEY_NUMERIC_6); break;
- case 0x024: th_map_key_clear(KEY_NUMERIC_7); break;
- case 0x025: th_map_key_clear(KEY_NUMERIC_8); break;
- case 0x026: th_map_key_clear(KEY_NUMERIC_9); break;
- case 0x027: th_map_key_clear(KEY_NUMERIC_0); break;
- case 0x028: th_map_key_clear(KEY_PLAY); break;
- case 0x029: th_map_key_clear(KEY_CANCEL); break;
- case 0x02b: th_map_key_clear(KEY_TAB); break;
- /* Power = 0x0e0 + 0x0e1 + 0x0e2 + 0x03f */
- case 0x03f: th_map_key_clear(KEY_POWER2); break;
- case 0x04a: th_map_key_clear(KEY_RECORD); break;
- case 0x04b: th_map_key_clear(KEY_CHANNELUP); break;
- case 0x04d: th_map_key_clear(KEY_STOP); break;
- case 0x04e: th_map_key_clear(KEY_CHANNELDOWN); break;
- /* Volume down = 0x0e1 + 0x051 */
- case 0x051: th_map_key_clear(KEY_VOLUMEDOWN); break;
- /* Volume up = 0x0e1 + 0x052 */
- case 0x052: th_map_key_clear(KEY_VOLUMEUP); break;
- /* Kill the extra keys used for multi-key "power" and "volume" keys
- * as well as continuously to release CTRL,ALT,META,... keys */
- case 0x0e0:
- case 0x0e1:
- case 0x0e2:
- case 0x0e3:
- case 0x0e4:
- case 0x0e5:
- case 0x0e6:
- case 0x0e7:
- default:
- return -1;
- }
- return 1;
-}
-
-static const struct hid_device_id twinhan_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, twinhan_devices);
-
-static struct hid_driver twinhan_driver = {
- .name = "twinhan",
- .id_table = twinhan_devices,
- .input_mapping = twinhan_input_mapping,
-};
-
-static int __init twinhan_init(void)
-{
- return hid_register_driver(&twinhan_driver);
-}
-
-static void __exit twinhan_exit(void)
-{
- hid_unregister_driver(&twinhan_driver);
-}
-
-module_init(twinhan_init);
-module_exit(twinhan_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-uclogic.c b/ANDROID_3.4.5/drivers/hid/hid-uclogic.c
deleted file mode 100644
index 1f112891..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-uclogic.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * HID driver for UC-Logic devices not fully compliant with HID standard
- *
- * Copyright (c) 2010 Nikolai Kondrashov
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-/*
- * See WPXXXXU model descriptions, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP4030U
- * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP5540U
- * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP8060U
- */
-
-/* Size of the original descriptor of WPXXXXU tablets */
-#define WPXXXXU_RDESC_ORIG_SIZE 212
-
-/* Fixed WP4030U report descriptor */
-static __u8 wp4030u_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x09, /* Report ID (9), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x05, /* Report Count (5), */
- 0x81, 0x01, /* Input (Constant), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
- 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */
- 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/* Fixed WP5540U report descriptor */
-static __u8 wp5540u_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x09, /* Report ID (9), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x05, /* Report Count (5), */
- 0x81, 0x01, /* Input (Constant), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
- 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
- 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x09, 0x02, /* Usage (Mouse), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x08, /* Report ID (8), */
- 0x09, 0x01, /* Usage (Pointer), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x01, /* Report Size (1), */
- 0x05, 0x09, /* Usage Page (Button), */
- 0x19, 0x01, /* Usage Minimum (01h), */
- 0x29, 0x03, /* Usage Maximum (03h), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x05, /* Report Count (5), */
- 0x81, 0x01, /* Input (Constant), */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x75, 0x08, /* Report Size (8), */
- 0x09, 0x30, /* Usage (X), */
- 0x09, 0x31, /* Usage (Y), */
- 0x15, 0x81, /* Logical Minimum (-127), */
- 0x25, 0x7F, /* Logical Maximum (127), */
- 0x95, 0x02, /* Report Count (2), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x09, 0x38, /* Usage (Wheel), */
- 0x15, 0xFF, /* Logical Minimum (-1), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x81, 0x01, /* Input (Constant), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/* Fixed WP8060U report descriptor */
-static __u8 wp8060u_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x09, /* Report ID (9), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x05, /* Report Count (5), */
- 0x81, 0x01, /* Input (Constant), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
- 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x70, 0x17, /* Physical Maximum (6000), */
- 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x09, 0x02, /* Usage (Mouse), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x08, /* Report ID (8), */
- 0x09, 0x01, /* Usage (Pointer), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x01, /* Report Size (1), */
- 0x05, 0x09, /* Usage Page (Button), */
- 0x19, 0x01, /* Usage Minimum (01h), */
- 0x29, 0x03, /* Usage Maximum (03h), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x05, /* Report Count (5), */
- 0x81, 0x01, /* Input (Constant), */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x75, 0x08, /* Report Size (8), */
- 0x09, 0x30, /* Usage (X), */
- 0x09, 0x31, /* Usage (Y), */
- 0x15, 0x81, /* Logical Minimum (-127), */
- 0x25, 0x7F, /* Logical Maximum (127), */
- 0x95, 0x02, /* Report Count (2), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x09, 0x38, /* Usage (Wheel), */
- 0x15, 0xFF, /* Logical Minimum (-1), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x81, 0x01, /* Input (Constant), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/*
- * See WP1062 description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP1062
- */
-
-/* Size of the original descriptor of WP1062 tablet */
-#define WP1062_RDESC_ORIG_SIZE 254
-
-/* Fixed WP1062 report descriptor */
-static __u8 wp1062_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x09, /* Report ID (9), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x04, /* Report Count (4), */
- 0x81, 0x01, /* Input (Constant), */
- 0x09, 0x32, /* Usage (In Range), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x10, 0x27, /* Physical Maximum (10000), */
- 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0xB7, 0x19, /* Physical Maximum (6583), */
- 0x26, 0x6E, 0x33, /* Logical Maximum (13166), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/*
- * See PF1209 description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_PF1209
- */
-
-/* Size of the original descriptor of PF1209 tablet */
-#define PF1209_RDESC_ORIG_SIZE 234
-
-/* Fixed PF1209 report descriptor */
-static __u8 pf1209_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x09, /* Report ID (9), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x05, /* Report Count (5), */
- 0x81, 0x01, /* Input (Constant), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */
- 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x28, 0x23, /* Physical Maximum (9000), */
- 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x09, 0x02, /* Usage (Mouse), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x08, /* Report ID (8), */
- 0x09, 0x01, /* Usage (Pointer), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x01, /* Report Size (1), */
- 0x05, 0x09, /* Usage Page (Button), */
- 0x19, 0x01, /* Usage Minimum (01h), */
- 0x29, 0x03, /* Usage Maximum (03h), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x05, /* Report Count (5), */
- 0x81, 0x01, /* Input (Constant), */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x75, 0x08, /* Report Size (8), */
- 0x09, 0x30, /* Usage (X), */
- 0x09, 0x31, /* Usage (Y), */
- 0x15, 0x81, /* Logical Minimum (-127), */
- 0x25, 0x7F, /* Logical Maximum (127), */
- 0x95, 0x02, /* Report Count (2), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x09, 0x38, /* Usage (Wheel), */
- 0x15, 0xFF, /* Logical Minimum (-1), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x81, 0x01, /* Input (Constant), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- switch (hdev->product) {
- case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209:
- if (*rsize == PF1209_RDESC_ORIG_SIZE) {
- rdesc = pf1209_rdesc_fixed;
- *rsize = sizeof(pf1209_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U:
- if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
- rdesc = wp4030u_rdesc_fixed;
- *rsize = sizeof(wp4030u_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U:
- if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
- rdesc = wp5540u_rdesc_fixed;
- *rsize = sizeof(wp5540u_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U:
- if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
- rdesc = wp8060u_rdesc_fixed;
- *rsize = sizeof(wp8060u_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_UCLOGIC_TABLET_WP1062:
- if (*rsize == WP1062_RDESC_ORIG_SIZE) {
- rdesc = wp1062_rdesc_fixed;
- *rsize = sizeof(wp1062_rdesc_fixed);
- }
- break;
- }
-
- return rdesc;
-}
-
-static const struct hid_device_id uclogic_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
- USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
- USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
- USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
- USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
- { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
- USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, uclogic_devices);
-
-static struct hid_driver uclogic_driver = {
- .name = "uclogic",
- .id_table = uclogic_devices,
- .report_fixup = uclogic_report_fixup,
-};
-
-static int __init uclogic_init(void)
-{
- return hid_register_driver(&uclogic_driver);
-}
-
-static void __exit uclogic_exit(void)
-{
- hid_unregister_driver(&uclogic_driver);
-}
-
-module_init(uclogic_init);
-module_exit(uclogic_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-wacom.c b/ANDROID_3.4.5/drivers/hid/hid-wacom.c
deleted file mode 100644
index 067e2963..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-wacom.c
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Bluetooth Wacom Tablet support
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru>
- * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net>
- * Copyright (c) 2011 Przemysław Firszt <przemo@firszt.eu>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
-#include <linux/power_supply.h>
-#endif
-
-#include "hid-ids.h"
-
-#define PAD_DEVICE_ID 0x0F
-
-struct wacom_data {
- __u16 tool;
- __u16 butstate;
- __u8 whlstate;
- __u8 features;
- __u32 id;
- __u32 serial;
- unsigned char high_speed;
-#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
- int battery_capacity;
- struct power_supply battery;
- struct power_supply ac;
-#endif
-};
-
-#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
-/*percent of battery capacity, 0 means AC online*/
-static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 };
-
-static enum power_supply_property wacom_battery_props[] = {
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_SCOPE,
-};
-
-static enum power_supply_property wacom_ac_props[] = {
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_SCOPE,
-};
-
-static int wacom_battery_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct wacom_data *wdata = container_of(psy,
- struct wacom_data, battery);
- int power_state = batcap[wdata->battery_capacity];
- int ret = 0;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_PRESENT:
- val->intval = 1;
- break;
- case POWER_SUPPLY_PROP_SCOPE:
- val->intval = POWER_SUPPLY_SCOPE_DEVICE;
- break;
- case POWER_SUPPLY_PROP_CAPACITY:
- /* show 100% battery capacity when charging */
- if (power_state == 0)
- val->intval = 100;
- else
- val->intval = power_state;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static int wacom_ac_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);
- int power_state = batcap[wdata->battery_capacity];
- int ret = 0;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_PRESENT:
- /* fall through */
- case POWER_SUPPLY_PROP_ONLINE:
- if (power_state == 0)
- val->intval = 1;
- else
- val->intval = 0;
- break;
- case POWER_SUPPLY_PROP_SCOPE:
- val->intval = POWER_SUPPLY_SCOPE_DEVICE;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-#endif
-
-static void wacom_set_features(struct hid_device *hdev)
-{
- int ret;
- __u8 rep_data[2];
-
- /*set high speed, tablet mode*/
- rep_data[0] = 0x03;
- rep_data[1] = 0x20;
- ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
- HID_FEATURE_REPORT);
- return;
-}
-
-static void wacom_poke(struct hid_device *hdev, u8 speed)
-{
- struct wacom_data *wdata = hid_get_drvdata(hdev);
- int limit, ret;
- char rep_data[2];
-
- rep_data[0] = 0x03 ; rep_data[1] = 0x00;
- limit = 3;
- do {
- ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
- HID_FEATURE_REPORT);
- } while (ret < 0 && limit-- > 0);
-
- if (ret >= 0) {
- if (speed == 0)
- rep_data[0] = 0x05;
- else
- rep_data[0] = 0x06;
-
- rep_data[1] = 0x00;
- limit = 3;
- do {
- ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
- HID_FEATURE_REPORT);
- } while (ret < 0 && limit-- > 0);
-
- if (ret >= 0) {
- wdata->high_speed = speed;
- return;
- }
- }
-
- /*
- * Note that if the raw queries fail, it's not a hard failure and it
- * is safe to continue
- */
- hid_warn(hdev, "failed to poke device, command %d, err %d\n",
- rep_data[0], ret);
- return;
-}
-
-static ssize_t wacom_show_speed(struct device *dev,
- struct device_attribute
- *attr, char *buf)
-{
- struct wacom_data *wdata = dev_get_drvdata(dev);
-
- return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed);
-}
-
-static ssize_t wacom_store_speed(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- int new_speed;
-
- if (sscanf(buf, "%1d", &new_speed ) != 1)
- return -EINVAL;
-
- if (new_speed == 0 || new_speed == 1) {
- wacom_poke(hdev, new_speed);
- return strnlen(buf, PAGE_SIZE);
- } else
- return -EINVAL;
-}
-
-static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP,
- wacom_show_speed, wacom_store_speed);
-
-static int wacom_gr_parse_report(struct hid_device *hdev,
- struct wacom_data *wdata,
- struct input_dev *input, unsigned char *data)
-{
- int tool, x, y, rw;
-
- tool = 0;
- /* Get X & Y positions */
- x = le16_to_cpu(*(__le16 *) &data[2]);
- y = le16_to_cpu(*(__le16 *) &data[4]);
-
- /* Get current tool identifier */
- if (data[1] & 0x90) { /* If pen is in the in/active area */
- switch ((data[1] >> 5) & 3) {
- case 0: /* Pen */
- tool = BTN_TOOL_PEN;
- break;
-
- case 1: /* Rubber */
- tool = BTN_TOOL_RUBBER;
- break;
-
- case 2: /* Mouse with wheel */
- case 3: /* Mouse without wheel */
- tool = BTN_TOOL_MOUSE;
- break;
- }
-
- /* Reset tool if out of active tablet area */
- if (!(data[1] & 0x10))
- tool = 0;
- }
-
- /* If tool changed, notify input subsystem */
- if (wdata->tool != tool) {
- if (wdata->tool) {
- /* Completely reset old tool state */
- if (wdata->tool == BTN_TOOL_MOUSE) {
- input_report_key(input, BTN_LEFT, 0);
- input_report_key(input, BTN_RIGHT, 0);
- input_report_key(input, BTN_MIDDLE, 0);
- input_report_abs(input, ABS_DISTANCE,
- input_abs_get_max(input, ABS_DISTANCE));
- } else {
- input_report_key(input, BTN_TOUCH, 0);
- input_report_key(input, BTN_STYLUS, 0);
- input_report_key(input, BTN_STYLUS2, 0);
- input_report_abs(input, ABS_PRESSURE, 0);
- }
- input_report_key(input, wdata->tool, 0);
- input_sync(input);
- }
- wdata->tool = tool;
- if (tool)
- input_report_key(input, tool, 1);
- }
-
- if (tool) {
- input_report_abs(input, ABS_X, x);
- input_report_abs(input, ABS_Y, y);
-
- switch ((data[1] >> 5) & 3) {
- case 2: /* Mouse with wheel */
- input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
- rw = (data[6] & 0x01) ? -1 :
- (data[6] & 0x02) ? 1 : 0;
- input_report_rel(input, REL_WHEEL, rw);
- /* fall through */
-
- case 3: /* Mouse without wheel */
- input_report_key(input, BTN_LEFT, data[1] & 0x01);
- input_report_key(input, BTN_RIGHT, data[1] & 0x02);
- /* Compute distance between mouse and tablet */
- rw = 44 - (data[6] >> 2);
- if (rw < 0)
- rw = 0;
- else if (rw > 31)
- rw = 31;
- input_report_abs(input, ABS_DISTANCE, rw);
- break;
-
- default:
- input_report_abs(input, ABS_PRESSURE,
- data[6] | (((__u16) (data[1] & 0x08)) << 5));
- input_report_key(input, BTN_TOUCH, data[1] & 0x01);
- input_report_key(input, BTN_STYLUS, data[1] & 0x02);
- input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04);
- break;
- }
-
- input_sync(input);
- }
-
- /* Report the state of the two buttons at the top of the tablet
- * as two extra fingerpad keys (buttons 4 & 5). */
- rw = data[7] & 0x03;
- if (rw != wdata->butstate) {
- wdata->butstate = rw;
- input_report_key(input, BTN_0, rw & 0x02);
- input_report_key(input, BTN_1, rw & 0x01);
- input_report_key(input, BTN_TOOL_FINGER, 0xf0);
- input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
- input_sync(input);
- }
-
-#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
- /* Store current battery capacity */
- rw = (data[7] >> 2 & 0x07);
- if (rw != wdata->battery_capacity)
- wdata->battery_capacity = rw;
-#endif
- return 1;
-}
-
-static void wacom_i4_parse_button_report(struct wacom_data *wdata,
- struct input_dev *input, unsigned char *data)
-{
- __u16 new_butstate;
- __u8 new_whlstate;
- __u8 sync = 0;
-
- new_whlstate = data[1];
- if (new_whlstate != wdata->whlstate) {
- wdata->whlstate = new_whlstate;
- if (new_whlstate & 0x80) {
- input_report_key(input, BTN_TOUCH, 1);
- input_report_abs(input, ABS_WHEEL, (new_whlstate & 0x7f));
- input_report_key(input, BTN_TOOL_FINGER, 1);
- } else {
- input_report_key(input, BTN_TOUCH, 0);
- input_report_abs(input, ABS_WHEEL, 0);
- input_report_key(input, BTN_TOOL_FINGER, 0);
- }
- sync = 1;
- }
-
- new_butstate = (data[3] << 1) | (data[2] & 0x01);
- if (new_butstate != wdata->butstate) {
- wdata->butstate = new_butstate;
- input_report_key(input, BTN_0, new_butstate & 0x001);
- input_report_key(input, BTN_1, new_butstate & 0x002);
- input_report_key(input, BTN_2, new_butstate & 0x004);
- input_report_key(input, BTN_3, new_butstate & 0x008);
- input_report_key(input, BTN_4, new_butstate & 0x010);
- input_report_key(input, BTN_5, new_butstate & 0x020);
- input_report_key(input, BTN_6, new_butstate & 0x040);
- input_report_key(input, BTN_7, new_butstate & 0x080);
- input_report_key(input, BTN_8, new_butstate & 0x100);
- input_report_key(input, BTN_TOOL_FINGER, 1);
- sync = 1;
- }
-
- if (sync) {
- input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
- input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
- input_sync(input);
- }
-}
-
-static void wacom_i4_parse_pen_report(struct wacom_data *wdata,
- struct input_dev *input, unsigned char *data)
-{
- __u16 x, y, pressure;
- __u8 distance;
-
- switch (data[1]) {
- case 0x80: /* Out of proximity report */
- input_report_key(input, BTN_TOUCH, 0);
- input_report_abs(input, ABS_PRESSURE, 0);
- input_report_key(input, BTN_STYLUS, 0);
- input_report_key(input, BTN_STYLUS2, 0);
- input_report_key(input, wdata->tool, 0);
- input_report_abs(input, ABS_MISC, 0);
- input_event(input, EV_MSC, MSC_SERIAL, wdata->serial);
- wdata->tool = 0;
- input_sync(input);
- break;
- case 0xC2: /* Tool report */
- wdata->id = ((data[2] << 4) | (data[3] >> 4) |
- ((data[7] & 0x0f) << 20) |
- ((data[8] & 0xf0) << 12));
- wdata->serial = ((data[3] & 0x0f) << 28) +
- (data[4] << 20) + (data[5] << 12) +
- (data[6] << 4) + (data[7] >> 4);
-
- switch (wdata->id) {
- case 0x100802:
- wdata->tool = BTN_TOOL_PEN;
- break;
- case 0x10080A:
- wdata->tool = BTN_TOOL_RUBBER;
- break;
- }
- break;
- default: /* Position/pressure report */
- x = data[2] << 9 | data[3] << 1 | ((data[9] & 0x02) >> 1);
- y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01);
- pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5)
- | (data[1] & 0x01);
- distance = (data[9] >> 2) & 0x3f;
-
- input_report_key(input, BTN_TOUCH, pressure > 1);
-
- input_report_key(input, BTN_STYLUS, data[1] & 0x02);
- input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
- input_report_key(input, wdata->tool, 1);
- input_report_abs(input, ABS_X, x);
- input_report_abs(input, ABS_Y, y);
- input_report_abs(input, ABS_PRESSURE, pressure);
- input_report_abs(input, ABS_DISTANCE, distance);
- input_report_abs(input, ABS_MISC, wdata->id);
- input_event(input, EV_MSC, MSC_SERIAL, wdata->serial);
- input_report_key(input, wdata->tool, 1);
- input_sync(input);
- break;
- }
-
- return;
-}
-
-static void wacom_i4_parse_report(struct hid_device *hdev,
- struct wacom_data *wdata,
- struct input_dev *input, unsigned char *data)
-{
- switch (data[0]) {
- case 0x00: /* Empty report */
- break;
- case 0x02: /* Pen report */
- wacom_i4_parse_pen_report(wdata, input, data);
- break;
- case 0x03: /* Features Report */
- wdata->features = data[2];
- break;
- case 0x0C: /* Button report */
- wacom_i4_parse_button_report(wdata, input, data);
- break;
- default:
- hid_err(hdev, "Unknown report: %d,%d\n", data[0], data[1]);
- break;
- }
-}
-
-static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
- u8 *raw_data, int size)
-{
- struct wacom_data *wdata = hid_get_drvdata(hdev);
- struct hid_input *hidinput;
- struct input_dev *input;
- unsigned char *data = (unsigned char *) raw_data;
- int i;
-
- if (!(hdev->claimed & HID_CLAIMED_INPUT))
- return 0;
-
- hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
- input = hidinput->input;
-
- /* Check if this is a tablet report */
- if (data[0] != 0x03)
- return 0;
-
- switch (hdev->product) {
- case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
- return wacom_gr_parse_report(hdev, wdata, input, data);
- break;
- case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
- i = 1;
-
- switch (data[0]) {
- case 0x04:
- wacom_i4_parse_report(hdev, wdata, input, data + i);
- i += 10;
- /* fall through */
- case 0x03:
- wacom_i4_parse_report(hdev, wdata, input, data + i);
- i += 10;
- wacom_i4_parse_report(hdev, wdata, input, data + i);
- break;
- default:
- hid_err(hdev, "Unknown report: %d,%d size:%d\n",
- data[0], data[1], size);
- return 0;
- }
- }
- return 1;
-}
-
-static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage, unsigned long **bit,
- int *max)
-{
- struct input_dev *input = hi->input;
-
- __set_bit(INPUT_PROP_POINTER, input->propbit);
-
- /* Basics */
- input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
-
- __set_bit(REL_WHEEL, input->relbit);
-
- __set_bit(BTN_TOOL_PEN, input->keybit);
- __set_bit(BTN_TOUCH, input->keybit);
- __set_bit(BTN_STYLUS, input->keybit);
- __set_bit(BTN_STYLUS2, input->keybit);
- __set_bit(BTN_LEFT, input->keybit);
- __set_bit(BTN_RIGHT, input->keybit);
- __set_bit(BTN_MIDDLE, input->keybit);
-
- /* Pad */
- input_set_capability(input, EV_MSC, MSC_SERIAL);
-
- __set_bit(BTN_0, input->keybit);
- __set_bit(BTN_1, input->keybit);
- __set_bit(BTN_TOOL_FINGER, input->keybit);
-
- /* Distance, rubber and mouse */
- __set_bit(BTN_TOOL_RUBBER, input->keybit);
- __set_bit(BTN_TOOL_MOUSE, input->keybit);
-
- switch (hdev->product) {
- case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
- input_set_abs_params(input, ABS_X, 0, 16704, 4, 0);
- input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0);
- input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0);
- input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0);
- break;
- case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
- __set_bit(ABS_WHEEL, input->absbit);
- __set_bit(ABS_MISC, input->absbit);
- __set_bit(BTN_2, input->keybit);
- __set_bit(BTN_3, input->keybit);
- __set_bit(BTN_4, input->keybit);
- __set_bit(BTN_5, input->keybit);
- __set_bit(BTN_6, input->keybit);
- __set_bit(BTN_7, input->keybit);
- __set_bit(BTN_8, input->keybit);
- input_set_abs_params(input, ABS_WHEEL, 0, 71, 0, 0);
- input_set_abs_params(input, ABS_X, 0, 40640, 4, 0);
- input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0);
- input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0);
- input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0);
- break;
- }
-
- return 0;
-}
-
-static int wacom_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- struct wacom_data *wdata;
- int ret;
-
- wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
- if (wdata == NULL) {
- hid_err(hdev, "can't alloc wacom descriptor\n");
- return -ENOMEM;
- }
-
- hid_set_drvdata(hdev, wdata);
-
- /* Parse the HID report now */
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- ret = device_create_file(&hdev->dev, &dev_attr_speed);
- if (ret)
- hid_warn(hdev,
- "can't create sysfs speed attribute err: %d\n", ret);
-
- switch (hdev->product) {
- case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
- /* Set Wacom mode 2 with high reporting speed */
- wacom_poke(hdev, 1);
- break;
- case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
- sprintf(hdev->name, "%s", "Wacom Intuos4 WL");
- wdata->features = 0;
- wacom_set_features(hdev);
- break;
- }
-
-#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
- wdata->battery.properties = wacom_battery_props;
- wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
- wdata->battery.get_property = wacom_battery_get_property;
- wdata->battery.name = "wacom_battery";
- wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
- wdata->battery.use_for_apm = 0;
-
-
- ret = power_supply_register(&hdev->dev, &wdata->battery);
- if (ret) {
- hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
- ret);
- goto err_battery;
- }
-
- power_supply_powers(&wdata->battery, &hdev->dev);
-
- wdata->ac.properties = wacom_ac_props;
- wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
- wdata->ac.get_property = wacom_ac_get_property;
- wdata->ac.name = "wacom_ac";
- wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
- wdata->ac.use_for_apm = 0;
-
- ret = power_supply_register(&hdev->dev, &wdata->ac);
- if (ret) {
- hid_warn(hdev,
- "can't create ac battery attribute, err: %d\n", ret);
- goto err_ac;
- }
-
- power_supply_powers(&wdata->ac, &hdev->dev);
-#endif
- return 0;
-
-#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
-err_ac:
- power_supply_unregister(&wdata->battery);
-err_battery:
- device_remove_file(&hdev->dev, &dev_attr_speed);
- hid_hw_stop(hdev);
-#endif
-err_free:
- kfree(wdata);
- return ret;
-}
-
-static void wacom_remove(struct hid_device *hdev)
-{
-#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
- struct wacom_data *wdata = hid_get_drvdata(hdev);
-#endif
- device_remove_file(&hdev->dev, &dev_attr_speed);
- hid_hw_stop(hdev);
-
-#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
- power_supply_unregister(&wdata->battery);
- power_supply_unregister(&wdata->ac);
-#endif
- kfree(hid_get_drvdata(hdev));
-}
-
-static const struct hid_device_id wacom_devices[] = {
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
-
- { }
-};
-MODULE_DEVICE_TABLE(hid, wacom_devices);
-
-static struct hid_driver wacom_driver = {
- .name = "wacom",
- .id_table = wacom_devices,
- .probe = wacom_probe,
- .remove = wacom_remove,
- .raw_event = wacom_raw_event,
- .input_mapped = wacom_input_mapped,
-};
-
-static int __init wacom_init(void)
-{
- int ret;
-
- ret = hid_register_driver(&wacom_driver);
- if (ret)
- pr_err("can't register wacom driver\n");
- return ret;
-}
-
-static void __exit wacom_exit(void)
-{
- hid_unregister_driver(&wacom_driver);
-}
-
-module_init(wacom_init);
-module_exit(wacom_exit);
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/drivers/hid/hid-waltop.c b/ANDROID_3.4.5/drivers/hid/hid-waltop.c
deleted file mode 100644
index 2cfd95c4..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-waltop.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * HID driver for Waltop devices not fully compliant with HID standard
- *
- * Copyright (c) 2010 Nikolai Kondrashov
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-/*
- * There exists an official driver on the manufacturer's website, which
- * wasn't submitted to the kernel, for some reason. The official driver
- * doesn't seem to support extra features of some tablets, like wheels.
- *
- * It shows that the feature report ID 2 could be used to control any waltop
- * tablet input mode, switching it between "default", "tablet" and "ink".
- *
- * This driver only uses "default" mode for all the supported tablets. This
- * mode tries to be HID-compatible (not very successfully), but cripples the
- * resolution of some tablets.
- *
- * The "tablet" mode uses some proprietary, yet decipherable protocol, which
- * represents the correct resolution, but is possibly HID-incompatible (i.e.
- * indescribable by a report descriptor).
- *
- * The purpose of the "ink" mode is unknown.
- *
- * The feature reports needed for switching to each mode are these:
- *
- * 02 16 00 default
- * 02 16 01 tablet
- * 02 16 02 ink
- */
-
-/*
- * See Slim Tablet 5.8 inch description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=Waltop_Slim_Tablet_5.8%22
- */
-
-/* Size of the original report descriptor of Slim Tablet 5.8 inch */
-#define SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE 222
-
-/* Fixed Slim Tablet 5.8 inch descriptor */
-static __u8 slim_tablet_5_8_inch_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x15, 0x01, /* Logical Minimum (1), */
- 0x25, 0x03, /* Logical Maximum (3), */
- 0x75, 0x04, /* Report Size (4), */
- 0x95, 0x01, /* Report Count (1), */
- 0x80, /* Input, */
- 0x09, 0x32, /* Usage (In Range), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x88, 0x13, /* Physical Maximum (5000), */
- 0x26, 0x10, 0x27, /* Logical Maximum (10000), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */
- 0x26, 0x70, 0x17, /* Logical Maximum (6000), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/*
- * See Slim Tablet 12.1 inch description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=Waltop_Slim_Tablet_12.1%22
- */
-
-/* Size of the original report descriptor of Slim Tablet 12.1 inch */
-#define SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE 269
-
-/* Fixed Slim Tablet 12.1 inch descriptor */
-static __u8 slim_tablet_12_1_inch_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x15, 0x01, /* Logical Minimum (1), */
- 0x25, 0x03, /* Logical Maximum (3), */
- 0x75, 0x04, /* Report Size (4), */
- 0x95, 0x01, /* Report Count (1), */
- 0x80, /* Input, */
- 0x09, 0x32, /* Usage (In Range), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x10, 0x27, /* Physical Maximum (10000), */
- 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */
- 0x26, 0xD4, 0x30, /* Logical Maximum (12500), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/*
- * See Q Pad description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=Waltop_Q_Pad
- */
-
-/* Size of the original report descriptor of Q Pad */
-#define Q_PAD_RDESC_ORIG_SIZE 241
-
-/* Fixed Q Pad descriptor */
-static __u8 q_pad_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x15, 0x01, /* Logical Minimum (1), */
- 0x25, 0x03, /* Logical Maximum (3), */
- 0x75, 0x04, /* Report Size (4), */
- 0x95, 0x01, /* Report Count (1), */
- 0x80, /* Input, */
- 0x09, 0x32, /* Usage (In Range), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x70, 0x17, /* Physical Maximum (6000), */
- 0x26, 0x00, 0x30, /* Logical Maximum (12288), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x94, 0x11, /* Physical Maximum (4500), */
- 0x26, 0x00, 0x24, /* Logical Maximum (9216), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/*
- * See description, device and HID report descriptors of tablet with PID 0038 at
- * http://sf.net/apps/mediawiki/digimend/?title=Waltop_PID_0038
- */
-
-/* Size of the original report descriptor of tablet with PID 0038 */
-#define PID_0038_RDESC_ORIG_SIZE 241
-
-/*
- * Fixed report descriptor for tablet with PID 0038.
- */
-static __u8 pid_0038_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x15, 0x01, /* Logical Minimum (1), */
- 0x25, 0x03, /* Logical Maximum (3), */
- 0x75, 0x04, /* Report Size (4), */
- 0x95, 0x01, /* Report Count (1), */
- 0x80, /* Input, */
- 0x09, 0x32, /* Usage (In Range), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x2E, 0x22, /* Physical Maximum (8750), */
- 0x26, 0x00, 0x46, /* Logical Maximum (17920), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x82, 0x14, /* Physical Maximum (5250), */
- 0x26, 0x00, 0x2A, /* Logical Maximum (10752), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
-};
-
-/*
- * See Media Tablet 10.6 inch description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=Waltop_Media_Tablet_10.6%22
- */
-
-/* Size of the original report descriptor of Media Tablet 10.6 inch */
-#define MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE 300
-
-/* Fixed Media Tablet 10.6 inch descriptor */
-static __u8 media_tablet_10_6_inch_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x15, 0x01, /* Logical Minimum (1), */
- 0x25, 0x03, /* Logical Maximum (3), */
- 0x75, 0x04, /* Report Size (4), */
- 0x95, 0x01, /* Report Count (1), */
- 0x80, /* Input, */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x32, /* Usage (In Range), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x28, 0x23, /* Physical Maximum (9000), */
- 0x26, 0x50, 0x46, /* Logical Maximum (18000), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
- 0x26, 0xF8, 0x2A, /* Logical Maximum (11000), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x09, 0x02, /* Usage (Mouse), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x01, /* Report ID (1), */
- 0x09, 0x01, /* Usage (Pointer), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x08, /* Report Size (8), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x95, 0x02, /* Report Count (2), */
- 0x15, 0xFF, /* Logical Minimum (-1), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x09, 0x38, /* Usage (Wheel), */
- 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */
- 0x0C, 0x00,
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x95, 0x02, /* Report Count (2), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x0C, /* Usage Page (Consumer), */
- 0x09, 0x01, /* Usage (Consumer Control), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x0D, /* Report ID (13), */
- 0x95, 0x01, /* Report Count (1), */
- 0x75, 0x10, /* Report Size (16), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
- 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
- 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
- 0x09, 0xB6, /* Usage (Scan Previous Track), */
- 0x09, 0xB5, /* Usage (Scan Next Track), */
- 0x08, /* Usage (00h), */
- 0x08, /* Usage (00h), */
- 0x08, /* Usage (00h), */
- 0x08, /* Usage (00h), */
- 0x08, /* Usage (00h), */
- 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
- 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
- 0x15, 0x0C, /* Logical Minimum (12), */
- 0x25, 0x17, /* Logical Maximum (23), */
- 0x75, 0x05, /* Report Size (5), */
- 0x80, /* Input, */
- 0x75, 0x03, /* Report Size (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x20, /* Report Size (32), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0xC0, /* End Collection, */
- 0x09, 0x01, /* Usage (Consumer Control), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x0C, /* Report ID (12), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0xE9, /* Usage (Volume Inc), */
- 0x09, 0xEA, /* Usage (Volume Dec), */
- 0x09, 0xE2, /* Usage (Mute), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x95, 0x35, /* Report Count (53), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0xC0 /* End Collection */
-};
-
-/*
- * See Media Tablet 14.1 inch description, device and HID report descriptors at
- * http://sf.net/apps/mediawiki/digimend/?title=Waltop_Media_Tablet_14.1%22
- */
-
-/* Size of the original report descriptor of Media Tablet 14.1 inch */
-#define MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE 309
-
-/* Fixed Media Tablet 14.1 inch descriptor */
-static __u8 media_tablet_14_1_inch_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x10, /* Report ID (16), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x15, 0x01, /* Logical Minimum (1), */
- 0x25, 0x03, /* Logical Maximum (3), */
- 0x75, 0x04, /* Report Size (4), */
- 0x95, 0x01, /* Report Count (1), */
- 0x80, /* Input, */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x32, /* Usage (In Range), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0x14, /* Logical Minimum (0), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */
- 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x52, 0x1C, /* Physical Maximum (7250), */
- 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x09, 0x02, /* Usage (Mouse), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x01, /* Report ID (1), */
- 0x09, 0x01, /* Usage (Pointer), */
- 0xA0, /* Collection (Physical), */
- 0x75, 0x08, /* Report Size (8), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x95, 0x02, /* Report Count (2), */
- 0x15, 0xFF, /* Logical Minimum (-1), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x09, 0x38, /* Usage (Wheel), */
- 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */
- 0x0C, 0x00,
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0xC0, /* End Collection, */
- 0xC0, /* End Collection, */
- 0x05, 0x0C, /* Usage Page (Consumer), */
- 0x09, 0x01, /* Usage (Consumer Control), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x0D, /* Report ID (13), */
- 0x95, 0x01, /* Report Count (1), */
- 0x75, 0x10, /* Report Size (16), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
- 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
- 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
- 0x09, 0xB6, /* Usage (Scan Previous Track), */
- 0x09, 0xB5, /* Usage (Scan Next Track), */
- 0x08, /* Usage (00h), */
- 0x08, /* Usage (00h), */
- 0x08, /* Usage (00h), */
- 0x08, /* Usage (00h), */
- 0x08, /* Usage (00h), */
- 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
- 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
- 0x15, 0x0C, /* Logical Minimum (12), */
- 0x25, 0x17, /* Logical Maximum (23), */
- 0x75, 0x05, /* Report Size (5), */
- 0x80, /* Input, */
- 0x75, 0x03, /* Report Size (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x20, /* Report Size (32), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0xC0, /* End Collection, */
- 0x09, 0x01, /* Usage (Consumer Control), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x0C, /* Report ID (12), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0xE9, /* Usage (Volume Inc), */
- 0x09, 0xEA, /* Usage (Volume Dec), */
- 0x09, 0xE2, /* Usage (Mute), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x06, /* Input (Variable, Relative), */
- 0x75, 0x05, /* Report Size (5), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0xC0 /* End Collection */
-};
-
-struct waltop_state {
- u8 pressure0;
- u8 pressure1;
-};
-
-static int waltop_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- int ret;
- struct waltop_state *s;
-
- s = kzalloc(sizeof(*s), GFP_KERNEL);
- if (s == NULL) {
- hid_err(hdev, "can't allocate device state\n");
- ret = -ENOMEM;
- goto err;
- }
-
- s->pressure0 = 0;
- s->pressure1 = 0;
-
- hid_set_drvdata(hdev, s);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- return 0;
-err:
- kfree(s);
- return ret;
-}
-
-static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- switch (hdev->product) {
- case USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH:
- if (*rsize == SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE) {
- rdesc = slim_tablet_5_8_inch_rdesc_fixed;
- *rsize = sizeof(slim_tablet_5_8_inch_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH:
- if (*rsize == SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE) {
- rdesc = slim_tablet_12_1_inch_rdesc_fixed;
- *rsize = sizeof(slim_tablet_12_1_inch_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_WALTOP_Q_PAD:
- if (*rsize == Q_PAD_RDESC_ORIG_SIZE) {
- rdesc = q_pad_rdesc_fixed;
- *rsize = sizeof(q_pad_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_WALTOP_PID_0038:
- if (*rsize == PID_0038_RDESC_ORIG_SIZE) {
- rdesc = pid_0038_rdesc_fixed;
- *rsize = sizeof(pid_0038_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH:
- if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) {
- rdesc = media_tablet_10_6_inch_rdesc_fixed;
- *rsize = sizeof(media_tablet_10_6_inch_rdesc_fixed);
- }
- break;
- case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH:
- if (*rsize == MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE) {
- rdesc = media_tablet_14_1_inch_rdesc_fixed;
- *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed);
- }
- break;
- }
- return rdesc;
-}
-
-static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report,
- u8 *data, int size)
-{
- /* If this is a pen input report of a tablet with PID 0038 */
- if (hdev->product == USB_DEVICE_ID_WALTOP_PID_0038 &&
- report->type == HID_INPUT_REPORT &&
- report->id == 16 &&
- size == 8) {
- struct waltop_state *s = hid_get_drvdata(hdev);
-
- /*
- * Ignore maximum pressure reported when a barrel button is
- * pressed.
- */
-
- /* If a barrel button is pressed */
- if ((data[1] & 0xF) > 1) {
- /* Use the last known pressure */
- data[6] = s->pressure0;
- data[7] = s->pressure1;
- } else {
- /* Remember reported pressure */
- s->pressure0 = data[6];
- s->pressure1 = data[7];
- }
- }
-
- return 0;
-}
-
-static void waltop_remove(struct hid_device *hdev)
-{
- struct waltop_state *s = hid_get_drvdata(hdev);
-
- hid_hw_stop(hdev);
- kfree(s);
-}
-
-static const struct hid_device_id waltop_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
- USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
- USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
- USB_DEVICE_ID_WALTOP_Q_PAD) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
- USB_DEVICE_ID_WALTOP_PID_0038) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
- USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
- USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, waltop_devices);
-
-static struct hid_driver waltop_driver = {
- .name = "waltop",
- .id_table = waltop_devices,
- .probe = waltop_probe,
- .report_fixup = waltop_report_fixup,
- .raw_event = waltop_raw_event,
- .remove = waltop_remove,
-};
-
-static int __init waltop_init(void)
-{
- return hid_register_driver(&waltop_driver);
-}
-
-static void __exit waltop_exit(void)
-{
- hid_unregister_driver(&waltop_driver);
-}
-
-module_init(waltop_init);
-module_exit(waltop_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-wiimote-core.c b/ANDROID_3.4.5/drivers/hid/hid-wiimote-core.c
deleted file mode 100644
index 84e2fbec..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-wiimote-core.c
+++ /dev/null
@@ -1,1318 +0,0 @@
-/*
- * HID driver for Nintendo Wiimote devices
- * Copyright (c) 2011 David Herrmann
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/completion.h>
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/leds.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/power_supply.h>
-#include <linux/spinlock.h>
-#include "hid-ids.h"
-#include "hid-wiimote.h"
-
-enum wiiproto_keys {
- WIIPROTO_KEY_LEFT,
- WIIPROTO_KEY_RIGHT,
- WIIPROTO_KEY_UP,
- WIIPROTO_KEY_DOWN,
- WIIPROTO_KEY_PLUS,
- WIIPROTO_KEY_MINUS,
- WIIPROTO_KEY_ONE,
- WIIPROTO_KEY_TWO,
- WIIPROTO_KEY_A,
- WIIPROTO_KEY_B,
- WIIPROTO_KEY_HOME,
- WIIPROTO_KEY_COUNT
-};
-
-static __u16 wiiproto_keymap[] = {
- KEY_LEFT, /* WIIPROTO_KEY_LEFT */
- KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */
- KEY_UP, /* WIIPROTO_KEY_UP */
- KEY_DOWN, /* WIIPROTO_KEY_DOWN */
- KEY_NEXT, /* WIIPROTO_KEY_PLUS */
- KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */
- BTN_1, /* WIIPROTO_KEY_ONE */
- BTN_2, /* WIIPROTO_KEY_TWO */
- BTN_A, /* WIIPROTO_KEY_A */
- BTN_B, /* WIIPROTO_KEY_B */
- BTN_MODE, /* WIIPROTO_KEY_HOME */
-};
-
-static enum power_supply_property wiimote_battery_props[] = {
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_SCOPE,
-};
-
-static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
- size_t count)
-{
- __u8 *buf;
- ssize_t ret;
-
- if (!hdev->hid_output_raw_report)
- return -ENODEV;
-
- buf = kmemdup(buffer, count, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- ret = hdev->hid_output_raw_report(hdev, buf, count, HID_OUTPUT_REPORT);
-
- kfree(buf);
- return ret;
-}
-
-static void wiimote_worker(struct work_struct *work)
-{
- struct wiimote_data *wdata = container_of(work, struct wiimote_data,
- worker);
- unsigned long flags;
-
- spin_lock_irqsave(&wdata->qlock, flags);
-
- while (wdata->head != wdata->tail) {
- spin_unlock_irqrestore(&wdata->qlock, flags);
- wiimote_hid_send(wdata->hdev, wdata->outq[wdata->tail].data,
- wdata->outq[wdata->tail].size);
- spin_lock_irqsave(&wdata->qlock, flags);
-
- wdata->tail = (wdata->tail + 1) % WIIMOTE_BUFSIZE;
- }
-
- spin_unlock_irqrestore(&wdata->qlock, flags);
-}
-
-static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer,
- size_t count)
-{
- unsigned long flags;
- __u8 newhead;
-
- if (count > HID_MAX_BUFFER_SIZE) {
- hid_warn(wdata->hdev, "Sending too large output report\n");
- return;
- }
-
- /*
- * Copy new request into our output queue and check whether the
- * queue is full. If it is full, discard this request.
- * If it is empty we need to start a new worker that will
- * send out the buffer to the hid device.
- * If the queue is not empty, then there must be a worker
- * that is currently sending out our buffer and this worker
- * will reschedule itself until the queue is empty.
- */
-
- spin_lock_irqsave(&wdata->qlock, flags);
-
- memcpy(wdata->outq[wdata->head].data, buffer, count);
- wdata->outq[wdata->head].size = count;
- newhead = (wdata->head + 1) % WIIMOTE_BUFSIZE;
-
- if (wdata->head == wdata->tail) {
- wdata->head = newhead;
- schedule_work(&wdata->worker);
- } else if (newhead != wdata->tail) {
- wdata->head = newhead;
- } else {
- hid_warn(wdata->hdev, "Output queue is full");
- }
-
- spin_unlock_irqrestore(&wdata->qlock, flags);
-}
-
-/*
- * This sets the rumble bit on the given output report if rumble is
- * currently enabled.
- * \cmd1 must point to the second byte in the output report => &cmd[1]
- * This must be called on nearly every output report before passing it
- * into the output queue!
- */
-static inline void wiiproto_keep_rumble(struct wiimote_data *wdata, __u8 *cmd1)
-{
- if (wdata->state.flags & WIIPROTO_FLAG_RUMBLE)
- *cmd1 |= 0x01;
-}
-
-static void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble)
-{
- __u8 cmd[2];
-
- rumble = !!rumble;
- if (rumble == !!(wdata->state.flags & WIIPROTO_FLAG_RUMBLE))
- return;
-
- if (rumble)
- wdata->state.flags |= WIIPROTO_FLAG_RUMBLE;
- else
- wdata->state.flags &= ~WIIPROTO_FLAG_RUMBLE;
-
- cmd[0] = WIIPROTO_REQ_RUMBLE;
- cmd[1] = 0;
-
- wiiproto_keep_rumble(wdata, &cmd[1]);
- wiimote_queue(wdata, cmd, sizeof(cmd));
-}
-
-static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
-{
- __u8 cmd[2];
-
- leds &= WIIPROTO_FLAGS_LEDS;
- if ((wdata->state.flags & WIIPROTO_FLAGS_LEDS) == leds)
- return;
- wdata->state.flags = (wdata->state.flags & ~WIIPROTO_FLAGS_LEDS) | leds;
-
- cmd[0] = WIIPROTO_REQ_LED;
- cmd[1] = 0;
-
- if (leds & WIIPROTO_FLAG_LED1)
- cmd[1] |= 0x10;
- if (leds & WIIPROTO_FLAG_LED2)
- cmd[1] |= 0x20;
- if (leds & WIIPROTO_FLAG_LED3)
- cmd[1] |= 0x40;
- if (leds & WIIPROTO_FLAG_LED4)
- cmd[1] |= 0x80;
-
- wiiproto_keep_rumble(wdata, &cmd[1]);
- wiimote_queue(wdata, cmd, sizeof(cmd));
-}
-
-/*
- * Check what peripherals of the wiimote are currently
- * active and select a proper DRM that supports all of
- * the requested data inputs.
- */
-static __u8 select_drm(struct wiimote_data *wdata)
-{
- __u8 ir = wdata->state.flags & WIIPROTO_FLAGS_IR;
- bool ext = wiiext_active(wdata);
-
- if (ir == WIIPROTO_FLAG_IR_BASIC) {
- if (wdata->state.flags & WIIPROTO_FLAG_ACCEL)
- return WIIPROTO_REQ_DRM_KAIE;
- else
- return WIIPROTO_REQ_DRM_KIE;
- } else if (ir == WIIPROTO_FLAG_IR_EXT) {
- return WIIPROTO_REQ_DRM_KAI;
- } else if (ir == WIIPROTO_FLAG_IR_FULL) {
- return WIIPROTO_REQ_DRM_SKAI1;
- } else {
- if (wdata->state.flags & WIIPROTO_FLAG_ACCEL) {
- if (ext)
- return WIIPROTO_REQ_DRM_KAE;
- else
- return WIIPROTO_REQ_DRM_KA;
- } else {
- if (ext)
- return WIIPROTO_REQ_DRM_KE;
- else
- return WIIPROTO_REQ_DRM_K;
- }
- }
-}
-
-void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
-{
- __u8 cmd[3];
-
- if (drm == WIIPROTO_REQ_NULL)
- drm = select_drm(wdata);
-
- cmd[0] = WIIPROTO_REQ_DRM;
- cmd[1] = 0;
- cmd[2] = drm;
-
- wdata->state.drm = drm;
- wiiproto_keep_rumble(wdata, &cmd[1]);
- wiimote_queue(wdata, cmd, sizeof(cmd));
-}
-
-static void wiiproto_req_status(struct wiimote_data *wdata)
-{
- __u8 cmd[2];
-
- cmd[0] = WIIPROTO_REQ_SREQ;
- cmd[1] = 0;
-
- wiiproto_keep_rumble(wdata, &cmd[1]);
- wiimote_queue(wdata, cmd, sizeof(cmd));
-}
-
-static void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel)
-{
- accel = !!accel;
- if (accel == !!(wdata->state.flags & WIIPROTO_FLAG_ACCEL))
- return;
-
- if (accel)
- wdata->state.flags |= WIIPROTO_FLAG_ACCEL;
- else
- wdata->state.flags &= ~WIIPROTO_FLAG_ACCEL;
-
- wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
-}
-
-static void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags)
-{
- __u8 cmd[2];
-
- cmd[0] = WIIPROTO_REQ_IR1;
- cmd[1] = flags;
-
- wiiproto_keep_rumble(wdata, &cmd[1]);
- wiimote_queue(wdata, cmd, sizeof(cmd));
-}
-
-static void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags)
-{
- __u8 cmd[2];
-
- cmd[0] = WIIPROTO_REQ_IR2;
- cmd[1] = flags;
-
- wiiproto_keep_rumble(wdata, &cmd[1]);
- wiimote_queue(wdata, cmd, sizeof(cmd));
-}
-
-#define wiiproto_req_wreg(wdata, os, buf, sz) \
- wiiproto_req_wmem((wdata), false, (os), (buf), (sz))
-
-#define wiiproto_req_weeprom(wdata, os, buf, sz) \
- wiiproto_req_wmem((wdata), true, (os), (buf), (sz))
-
-static void wiiproto_req_wmem(struct wiimote_data *wdata, bool eeprom,
- __u32 offset, const __u8 *buf, __u8 size)
-{
- __u8 cmd[22];
-
- if (size > 16 || size == 0) {
- hid_warn(wdata->hdev, "Invalid length %d wmem request\n", size);
- return;
- }
-
- memset(cmd, 0, sizeof(cmd));
- cmd[0] = WIIPROTO_REQ_WMEM;
- cmd[2] = (offset >> 16) & 0xff;
- cmd[3] = (offset >> 8) & 0xff;
- cmd[4] = offset & 0xff;
- cmd[5] = size;
- memcpy(&cmd[6], buf, size);
-
- if (!eeprom)
- cmd[1] |= 0x04;
-
- wiiproto_keep_rumble(wdata, &cmd[1]);
- wiimote_queue(wdata, cmd, sizeof(cmd));
-}
-
-void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom, __u32 offset,
- __u16 size)
-{
- __u8 cmd[7];
-
- if (size == 0) {
- hid_warn(wdata->hdev, "Invalid length %d rmem request\n", size);
- return;
- }
-
- cmd[0] = WIIPROTO_REQ_RMEM;
- cmd[1] = 0;
- cmd[2] = (offset >> 16) & 0xff;
- cmd[3] = (offset >> 8) & 0xff;
- cmd[4] = offset & 0xff;
- cmd[5] = (size >> 8) & 0xff;
- cmd[6] = size & 0xff;
-
- if (!eeprom)
- cmd[1] |= 0x04;
-
- wiiproto_keep_rumble(wdata, &cmd[1]);
- wiimote_queue(wdata, cmd, sizeof(cmd));
-}
-
-/* requries the cmd-mutex to be held */
-int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
- const __u8 *wmem, __u8 size)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wiimote_cmd_set(wdata, WIIPROTO_REQ_WMEM, 0);
- wiiproto_req_wreg(wdata, offset, wmem, size);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- ret = wiimote_cmd_wait(wdata);
- if (!ret && wdata->state.cmd_err)
- ret = -EIO;
-
- return ret;
-}
-
-/* requries the cmd-mutex to be held */
-ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, __u8 *rmem,
- __u8 size)
-{
- unsigned long flags;
- ssize_t ret;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.cmd_read_size = size;
- wdata->state.cmd_read_buf = rmem;
- wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, offset & 0xffff);
- wiiproto_req_rreg(wdata, offset, size);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- ret = wiimote_cmd_wait(wdata);
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.cmd_read_buf = NULL;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- if (!ret) {
- if (wdata->state.cmd_read_size == 0)
- ret = -EIO;
- else
- ret = wdata->state.cmd_read_size;
- }
-
- return ret;
-}
-
-static int wiimote_battery_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct wiimote_data *wdata = container_of(psy,
- struct wiimote_data, battery);
- int ret = 0, state;
- unsigned long flags;
-
- if (psp == POWER_SUPPLY_PROP_SCOPE) {
- val->intval = POWER_SUPPLY_SCOPE_DEVICE;
- return 0;
- }
-
- ret = wiimote_cmd_acquire(wdata);
- if (ret)
- return ret;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
- wiiproto_req_status(wdata);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- ret = wiimote_cmd_wait(wdata);
- state = wdata->state.cmd_battery;
- wiimote_cmd_release(wdata);
-
- if (ret)
- return ret;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = state * 100 / 255;
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int wiimote_init_ir(struct wiimote_data *wdata, __u16 mode)
-{
- int ret;
- unsigned long flags;
- __u8 format = 0;
- static const __u8 data_enable[] = { 0x01 };
- static const __u8 data_sens1[] = { 0x02, 0x00, 0x00, 0x71, 0x01,
- 0x00, 0xaa, 0x00, 0x64 };
- static const __u8 data_sens2[] = { 0x63, 0x03 };
- static const __u8 data_fin[] = { 0x08 };
-
- spin_lock_irqsave(&wdata->state.lock, flags);
-
- if (mode == (wdata->state.flags & WIIPROTO_FLAGS_IR)) {
- spin_unlock_irqrestore(&wdata->state.lock, flags);
- return 0;
- }
-
- if (mode == 0) {
- wdata->state.flags &= ~WIIPROTO_FLAGS_IR;
- wiiproto_req_ir1(wdata, 0);
- wiiproto_req_ir2(wdata, 0);
- wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
- return 0;
- }
-
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- ret = wiimote_cmd_acquire(wdata);
- if (ret)
- return ret;
-
- /* send PIXEL CLOCK ENABLE cmd first */
- spin_lock_irqsave(&wdata->state.lock, flags);
- wiimote_cmd_set(wdata, WIIPROTO_REQ_IR1, 0);
- wiiproto_req_ir1(wdata, 0x06);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- ret = wiimote_cmd_wait(wdata);
- if (ret)
- goto unlock;
- if (wdata->state.cmd_err) {
- ret = -EIO;
- goto unlock;
- }
-
- /* enable IR LOGIC */
- spin_lock_irqsave(&wdata->state.lock, flags);
- wiimote_cmd_set(wdata, WIIPROTO_REQ_IR2, 0);
- wiiproto_req_ir2(wdata, 0x06);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- ret = wiimote_cmd_wait(wdata);
- if (ret)
- goto unlock;
- if (wdata->state.cmd_err) {
- ret = -EIO;
- goto unlock;
- }
-
- /* enable IR cam but do not make it send data, yet */
- ret = wiimote_cmd_write(wdata, 0xb00030, data_enable,
- sizeof(data_enable));
- if (ret)
- goto unlock;
-
- /* write first sensitivity block */
- ret = wiimote_cmd_write(wdata, 0xb00000, data_sens1,
- sizeof(data_sens1));
- if (ret)
- goto unlock;
-
- /* write second sensitivity block */
- ret = wiimote_cmd_write(wdata, 0xb0001a, data_sens2,
- sizeof(data_sens2));
- if (ret)
- goto unlock;
-
- /* put IR cam into desired state */
- switch (mode) {
- case WIIPROTO_FLAG_IR_FULL:
- format = 5;
- break;
- case WIIPROTO_FLAG_IR_EXT:
- format = 3;
- break;
- case WIIPROTO_FLAG_IR_BASIC:
- format = 1;
- break;
- }
- ret = wiimote_cmd_write(wdata, 0xb00033, &format, sizeof(format));
- if (ret)
- goto unlock;
-
- /* make IR cam send data */
- ret = wiimote_cmd_write(wdata, 0xb00030, data_fin, sizeof(data_fin));
- if (ret)
- goto unlock;
-
- /* request new DRM mode compatible to IR mode */
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.flags &= ~WIIPROTO_FLAGS_IR;
- wdata->state.flags |= mode & WIIPROTO_FLAGS_IR;
- wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
-unlock:
- wiimote_cmd_release(wdata);
- return ret;
-}
-
-static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
-{
- struct wiimote_data *wdata;
- struct device *dev = led_dev->dev->parent;
- int i;
- unsigned long flags;
- bool value = false;
-
- wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
-
- for (i = 0; i < 4; ++i) {
- if (wdata->leds[i] == led_dev) {
- spin_lock_irqsave(&wdata->state.lock, flags);
- value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
- break;
- }
- }
-
- return value ? LED_FULL : LED_OFF;
-}
-
-static void wiimote_leds_set(struct led_classdev *led_dev,
- enum led_brightness value)
-{
- struct wiimote_data *wdata;
- struct device *dev = led_dev->dev->parent;
- int i;
- unsigned long flags;
- __u8 state, flag;
-
- wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
-
- for (i = 0; i < 4; ++i) {
- if (wdata->leds[i] == led_dev) {
- flag = WIIPROTO_FLAG_LED(i + 1);
- spin_lock_irqsave(&wdata->state.lock, flags);
- state = wdata->state.flags;
- if (value == LED_OFF)
- wiiproto_req_leds(wdata, state & ~flag);
- else
- wiiproto_req_leds(wdata, state | flag);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
- break;
- }
- }
-}
-
-static int wiimote_ff_play(struct input_dev *dev, void *data,
- struct ff_effect *eff)
-{
- struct wiimote_data *wdata = input_get_drvdata(dev);
- __u8 value;
- unsigned long flags;
-
- /*
- * The wiimote supports only a single rumble motor so if any magnitude
- * is set to non-zero then we start the rumble motor. If both are set to
- * zero, we stop the rumble motor.
- */
-
- if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude)
- value = 1;
- else
- value = 0;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wiiproto_req_rumble(wdata, value);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- return 0;
-}
-
-static int wiimote_input_open(struct input_dev *dev)
-{
- struct wiimote_data *wdata = input_get_drvdata(dev);
-
- return hid_hw_open(wdata->hdev);
-}
-
-static void wiimote_input_close(struct input_dev *dev)
-{
- struct wiimote_data *wdata = input_get_drvdata(dev);
-
- hid_hw_close(wdata->hdev);
-}
-
-static int wiimote_accel_open(struct input_dev *dev)
-{
- struct wiimote_data *wdata = input_get_drvdata(dev);
- int ret;
- unsigned long flags;
-
- ret = hid_hw_open(wdata->hdev);
- if (ret)
- return ret;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wiiproto_req_accel(wdata, true);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- return 0;
-}
-
-static void wiimote_accel_close(struct input_dev *dev)
-{
- struct wiimote_data *wdata = input_get_drvdata(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wiiproto_req_accel(wdata, false);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- hid_hw_close(wdata->hdev);
-}
-
-static int wiimote_ir_open(struct input_dev *dev)
-{
- struct wiimote_data *wdata = input_get_drvdata(dev);
- int ret;
-
- ret = hid_hw_open(wdata->hdev);
- if (ret)
- return ret;
-
- ret = wiimote_init_ir(wdata, WIIPROTO_FLAG_IR_BASIC);
- if (ret) {
- hid_hw_close(wdata->hdev);
- return ret;
- }
-
- return 0;
-}
-
-static void wiimote_ir_close(struct input_dev *dev)
-{
- struct wiimote_data *wdata = input_get_drvdata(dev);
-
- wiimote_init_ir(wdata, 0);
- hid_hw_close(wdata->hdev);
-}
-
-static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
-{
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_LEFT],
- !!(payload[0] & 0x01));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_RIGHT],
- !!(payload[0] & 0x02));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_DOWN],
- !!(payload[0] & 0x04));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_UP],
- !!(payload[0] & 0x08));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_PLUS],
- !!(payload[0] & 0x10));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_TWO],
- !!(payload[1] & 0x01));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_ONE],
- !!(payload[1] & 0x02));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_B],
- !!(payload[1] & 0x04));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_A],
- !!(payload[1] & 0x08));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_MINUS],
- !!(payload[1] & 0x10));
- input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_HOME],
- !!(payload[1] & 0x80));
- input_sync(wdata->input);
-}
-
-static void handler_accel(struct wiimote_data *wdata, const __u8 *payload)
-{
- __u16 x, y, z;
-
- if (!(wdata->state.flags & WIIPROTO_FLAG_ACCEL))
- return;
-
- /*
- * payload is: BB BB XX YY ZZ
- * Accelerometer data is encoded into 3 10bit values. XX, YY and ZZ
- * contain the upper 8 bits of each value. The lower 2 bits are
- * contained in the buttons data BB BB.
- * Bits 6 and 7 of the first buttons byte BB is the lower 2 bits of the
- * X accel value. Bit 5 of the second buttons byte is the 2nd bit of Y
- * accel value and bit 6 is the second bit of the Z value.
- * The first bit of Y and Z values is not available and always set to 0.
- * 0x200 is returned on no movement.
- */
-
- x = payload[2] << 2;
- y = payload[3] << 2;
- z = payload[4] << 2;
-
- x |= (payload[0] >> 5) & 0x3;
- y |= (payload[1] >> 4) & 0x2;
- z |= (payload[1] >> 5) & 0x2;
-
- input_report_abs(wdata->accel, ABS_RX, x - 0x200);
- input_report_abs(wdata->accel, ABS_RY, y - 0x200);
- input_report_abs(wdata->accel, ABS_RZ, z - 0x200);
- input_sync(wdata->accel);
-}
-
-#define ir_to_input0(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
- ABS_HAT0X, ABS_HAT0Y)
-#define ir_to_input1(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
- ABS_HAT1X, ABS_HAT1Y)
-#define ir_to_input2(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
- ABS_HAT2X, ABS_HAT2Y)
-#define ir_to_input3(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
- ABS_HAT3X, ABS_HAT3Y)
-
-static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir,
- bool packed, __u8 xid, __u8 yid)
-{
- __u16 x, y;
-
- if (!(wdata->state.flags & WIIPROTO_FLAGS_IR))
- return;
-
- /*
- * Basic IR data is encoded into 3 bytes. The first two bytes are the
- * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits
- * of both.
- * If data is packed, then the 3rd byte is put first and slightly
- * reordered. This allows to interleave packed and non-packed data to
- * have two IR sets in 5 bytes instead of 6.
- * The resulting 10bit X/Y values are passed to the ABS_HATXY input dev.
- */
-
- if (packed) {
- x = ir[1] | ((ir[0] & 0x03) << 8);
- y = ir[2] | ((ir[0] & 0x0c) << 6);
- } else {
- x = ir[0] | ((ir[2] & 0x30) << 4);
- y = ir[1] | ((ir[2] & 0xc0) << 2);
- }
-
- input_report_abs(wdata->ir, xid, x);
- input_report_abs(wdata->ir, yid, y);
-}
-
-static void handler_status(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
-
- /* on status reports the drm is reset so we need to resend the drm */
- wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
-
- wiiext_event(wdata, payload[2] & 0x02);
-
- if (wiimote_cmd_pending(wdata, WIIPROTO_REQ_SREQ, 0)) {
- wdata->state.cmd_battery = payload[5];
- wiimote_cmd_complete(wdata);
- }
-}
-
-static void handler_data(struct wiimote_data *wdata, const __u8 *payload)
-{
- __u16 offset = payload[3] << 8 | payload[4];
- __u8 size = (payload[2] >> 4) + 1;
- __u8 err = payload[2] & 0x0f;
-
- handler_keys(wdata, payload);
-
- if (wiimote_cmd_pending(wdata, WIIPROTO_REQ_RMEM, offset)) {
- if (err)
- size = 0;
- else if (size > wdata->state.cmd_read_size)
- size = wdata->state.cmd_read_size;
-
- wdata->state.cmd_read_size = size;
- if (wdata->state.cmd_read_buf)
- memcpy(wdata->state.cmd_read_buf, &payload[5], size);
- wiimote_cmd_complete(wdata);
- }
-}
-
-static void handler_return(struct wiimote_data *wdata, const __u8 *payload)
-{
- __u8 err = payload[3];
- __u8 cmd = payload[2];
-
- handler_keys(wdata, payload);
-
- if (wiimote_cmd_pending(wdata, cmd, 0)) {
- wdata->state.cmd_err = err;
- wiimote_cmd_complete(wdata);
- } else if (err) {
- hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err,
- cmd);
- }
-}
-
-static void handler_drm_KA(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
- handler_accel(wdata, payload);
-}
-
-static void handler_drm_KE(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
- wiiext_handle(wdata, &payload[2]);
-}
-
-static void handler_drm_KAI(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
- handler_accel(wdata, payload);
- ir_to_input0(wdata, &payload[5], false);
- ir_to_input1(wdata, &payload[8], false);
- ir_to_input2(wdata, &payload[11], false);
- ir_to_input3(wdata, &payload[14], false);
- input_sync(wdata->ir);
-}
-
-static void handler_drm_KEE(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
- wiiext_handle(wdata, &payload[2]);
-}
-
-static void handler_drm_KIE(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
- ir_to_input0(wdata, &payload[2], false);
- ir_to_input1(wdata, &payload[4], true);
- ir_to_input2(wdata, &payload[7], false);
- ir_to_input3(wdata, &payload[9], true);
- input_sync(wdata->ir);
- wiiext_handle(wdata, &payload[12]);
-}
-
-static void handler_drm_KAE(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
- handler_accel(wdata, payload);
- wiiext_handle(wdata, &payload[5]);
-}
-
-static void handler_drm_KAIE(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
- handler_accel(wdata, payload);
- ir_to_input0(wdata, &payload[5], false);
- ir_to_input1(wdata, &payload[7], true);
- ir_to_input2(wdata, &payload[10], false);
- ir_to_input3(wdata, &payload[12], true);
- input_sync(wdata->ir);
- wiiext_handle(wdata, &payload[15]);
-}
-
-static void handler_drm_E(struct wiimote_data *wdata, const __u8 *payload)
-{
- wiiext_handle(wdata, payload);
-}
-
-static void handler_drm_SKAI1(struct wiimote_data *wdata, const __u8 *payload)
-{
- handler_keys(wdata, payload);
-
- wdata->state.accel_split[0] = payload[2];
- wdata->state.accel_split[1] = (payload[0] >> 1) & (0x10 | 0x20);
- wdata->state.accel_split[1] |= (payload[1] << 1) & (0x40 | 0x80);
-
- ir_to_input0(wdata, &payload[3], false);
- ir_to_input1(wdata, &payload[12], false);
- input_sync(wdata->ir);
-}
-
-static void handler_drm_SKAI2(struct wiimote_data *wdata, const __u8 *payload)
-{
- __u8 buf[5];
-
- handler_keys(wdata, payload);
-
- wdata->state.accel_split[1] |= (payload[0] >> 5) & (0x01 | 0x02);
- wdata->state.accel_split[1] |= (payload[1] >> 3) & (0x04 | 0x08);
-
- buf[0] = 0;
- buf[1] = 0;
- buf[2] = wdata->state.accel_split[0];
- buf[3] = payload[2];
- buf[4] = wdata->state.accel_split[1];
- handler_accel(wdata, buf);
-
- ir_to_input2(wdata, &payload[3], false);
- ir_to_input3(wdata, &payload[12], false);
- input_sync(wdata->ir);
-}
-
-struct wiiproto_handler {
- __u8 id;
- size_t size;
- void (*func)(struct wiimote_data *wdata, const __u8 *payload);
-};
-
-static struct wiiproto_handler handlers[] = {
- { .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status },
- { .id = WIIPROTO_REQ_DATA, .size = 21, .func = handler_data },
- { .id = WIIPROTO_REQ_RETURN, .size = 4, .func = handler_return },
- { .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys },
- { .id = WIIPROTO_REQ_DRM_KA, .size = 5, .func = handler_drm_KA },
- { .id = WIIPROTO_REQ_DRM_KE, .size = 10, .func = handler_drm_KE },
- { .id = WIIPROTO_REQ_DRM_KAI, .size = 17, .func = handler_drm_KAI },
- { .id = WIIPROTO_REQ_DRM_KEE, .size = 21, .func = handler_drm_KEE },
- { .id = WIIPROTO_REQ_DRM_KAE, .size = 21, .func = handler_drm_KAE },
- { .id = WIIPROTO_REQ_DRM_KIE, .size = 21, .func = handler_drm_KIE },
- { .id = WIIPROTO_REQ_DRM_KAIE, .size = 21, .func = handler_drm_KAIE },
- { .id = WIIPROTO_REQ_DRM_E, .size = 21, .func = handler_drm_E },
- { .id = WIIPROTO_REQ_DRM_SKAI1, .size = 21, .func = handler_drm_SKAI1 },
- { .id = WIIPROTO_REQ_DRM_SKAI2, .size = 21, .func = handler_drm_SKAI2 },
- { .id = 0 }
-};
-
-static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
- u8 *raw_data, int size)
-{
- struct wiimote_data *wdata = hid_get_drvdata(hdev);
- struct wiiproto_handler *h;
- int i;
- unsigned long flags;
- bool handled = false;
-
- if (size < 1)
- return -EINVAL;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
-
- for (i = 0; handlers[i].id; ++i) {
- h = &handlers[i];
- if (h->id == raw_data[0] && h->size < size) {
- h->func(wdata, &raw_data[1]);
- handled = true;
- }
- }
-
- if (!handled)
- hid_warn(hdev, "Unhandled report %hhu size %d\n", raw_data[0],
- size);
-
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- return 0;
-}
-
-static void wiimote_leds_destroy(struct wiimote_data *wdata)
-{
- int i;
- struct led_classdev *led;
-
- for (i = 0; i < 4; ++i) {
- if (wdata->leds[i]) {
- led = wdata->leds[i];
- wdata->leds[i] = NULL;
- led_classdev_unregister(led);
- kfree(led);
- }
- }
-}
-
-static int wiimote_leds_create(struct wiimote_data *wdata)
-{
- int i, ret;
- struct device *dev = &wdata->hdev->dev;
- size_t namesz = strlen(dev_name(dev)) + 9;
- struct led_classdev *led;
- char *name;
-
- for (i = 0; i < 4; ++i) {
- led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
- if (!led) {
- ret = -ENOMEM;
- goto err;
- }
- name = (void*)&led[1];
- snprintf(name, namesz, "%s:blue:p%d", dev_name(dev), i);
- led->name = name;
- led->brightness = 0;
- led->max_brightness = 1;
- led->brightness_get = wiimote_leds_get;
- led->brightness_set = wiimote_leds_set;
-
- ret = led_classdev_register(dev, led);
- if (ret) {
- kfree(led);
- goto err;
- }
- wdata->leds[i] = led;
- }
-
- return 0;
-
-err:
- wiimote_leds_destroy(wdata);
- return ret;
-}
-
-static struct wiimote_data *wiimote_create(struct hid_device *hdev)
-{
- struct wiimote_data *wdata;
- int i;
-
- wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
- if (!wdata)
- return NULL;
-
- wdata->input = input_allocate_device();
- if (!wdata->input)
- goto err;
-
- wdata->hdev = hdev;
- hid_set_drvdata(hdev, wdata);
-
- input_set_drvdata(wdata->input, wdata);
- wdata->input->open = wiimote_input_open;
- wdata->input->close = wiimote_input_close;
- wdata->input->dev.parent = &wdata->hdev->dev;
- wdata->input->id.bustype = wdata->hdev->bus;
- wdata->input->id.vendor = wdata->hdev->vendor;
- wdata->input->id.product = wdata->hdev->product;
- wdata->input->id.version = wdata->hdev->version;
- wdata->input->name = WIIMOTE_NAME;
-
- set_bit(EV_KEY, wdata->input->evbit);
- for (i = 0; i < WIIPROTO_KEY_COUNT; ++i)
- set_bit(wiiproto_keymap[i], wdata->input->keybit);
-
- set_bit(FF_RUMBLE, wdata->input->ffbit);
- if (input_ff_create_memless(wdata->input, NULL, wiimote_ff_play))
- goto err_input;
-
- wdata->accel = input_allocate_device();
- if (!wdata->accel)
- goto err_input;
-
- input_set_drvdata(wdata->accel, wdata);
- wdata->accel->open = wiimote_accel_open;
- wdata->accel->close = wiimote_accel_close;
- wdata->accel->dev.parent = &wdata->hdev->dev;
- wdata->accel->id.bustype = wdata->hdev->bus;
- wdata->accel->id.vendor = wdata->hdev->vendor;
- wdata->accel->id.product = wdata->hdev->product;
- wdata->accel->id.version = wdata->hdev->version;
- wdata->accel->name = WIIMOTE_NAME " Accelerometer";
-
- set_bit(EV_ABS, wdata->accel->evbit);
- set_bit(ABS_RX, wdata->accel->absbit);
- set_bit(ABS_RY, wdata->accel->absbit);
- set_bit(ABS_RZ, wdata->accel->absbit);
- input_set_abs_params(wdata->accel, ABS_RX, -500, 500, 2, 4);
- input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4);
- input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4);
-
- wdata->ir = input_allocate_device();
- if (!wdata->ir)
- goto err_ir;
-
- input_set_drvdata(wdata->ir, wdata);
- wdata->ir->open = wiimote_ir_open;
- wdata->ir->close = wiimote_ir_close;
- wdata->ir->dev.parent = &wdata->hdev->dev;
- wdata->ir->id.bustype = wdata->hdev->bus;
- wdata->ir->id.vendor = wdata->hdev->vendor;
- wdata->ir->id.product = wdata->hdev->product;
- wdata->ir->id.version = wdata->hdev->version;
- wdata->ir->name = WIIMOTE_NAME " IR";
-
- set_bit(EV_ABS, wdata->ir->evbit);
- set_bit(ABS_HAT0X, wdata->ir->absbit);
- set_bit(ABS_HAT0Y, wdata->ir->absbit);
- set_bit(ABS_HAT1X, wdata->ir->absbit);
- set_bit(ABS_HAT1Y, wdata->ir->absbit);
- set_bit(ABS_HAT2X, wdata->ir->absbit);
- set_bit(ABS_HAT2Y, wdata->ir->absbit);
- set_bit(ABS_HAT3X, wdata->ir->absbit);
- set_bit(ABS_HAT3Y, wdata->ir->absbit);
- input_set_abs_params(wdata->ir, ABS_HAT0X, 0, 1023, 2, 4);
- input_set_abs_params(wdata->ir, ABS_HAT0Y, 0, 767, 2, 4);
- input_set_abs_params(wdata->ir, ABS_HAT1X, 0, 1023, 2, 4);
- input_set_abs_params(wdata->ir, ABS_HAT1Y, 0, 767, 2, 4);
- input_set_abs_params(wdata->ir, ABS_HAT2X, 0, 1023, 2, 4);
- input_set_abs_params(wdata->ir, ABS_HAT2Y, 0, 767, 2, 4);
- input_set_abs_params(wdata->ir, ABS_HAT3X, 0, 1023, 2, 4);
- input_set_abs_params(wdata->ir, ABS_HAT3Y, 0, 767, 2, 4);
-
- spin_lock_init(&wdata->qlock);
- INIT_WORK(&wdata->worker, wiimote_worker);
-
- spin_lock_init(&wdata->state.lock);
- init_completion(&wdata->state.ready);
- mutex_init(&wdata->state.sync);
- wdata->state.drm = WIIPROTO_REQ_DRM_K;
-
- return wdata;
-
-err_ir:
- input_free_device(wdata->accel);
-err_input:
- input_free_device(wdata->input);
-err:
- kfree(wdata);
- return NULL;
-}
-
-static void wiimote_destroy(struct wiimote_data *wdata)
-{
- wiidebug_deinit(wdata);
- wiiext_deinit(wdata);
- wiimote_leds_destroy(wdata);
-
- power_supply_unregister(&wdata->battery);
- input_unregister_device(wdata->accel);
- input_unregister_device(wdata->ir);
- input_unregister_device(wdata->input);
- cancel_work_sync(&wdata->worker);
- hid_hw_stop(wdata->hdev);
-
- kfree(wdata);
-}
-
-static int wiimote_hid_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- struct wiimote_data *wdata;
- int ret;
-
- hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
-
- wdata = wiimote_create(hdev);
- if (!wdata) {
- hid_err(hdev, "Can't alloc device\n");
- return -ENOMEM;
- }
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "HID parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
- if (ret) {
- hid_err(hdev, "HW start failed\n");
- goto err;
- }
-
- ret = input_register_device(wdata->accel);
- if (ret) {
- hid_err(hdev, "Cannot register input device\n");
- goto err_stop;
- }
-
- ret = input_register_device(wdata->ir);
- if (ret) {
- hid_err(hdev, "Cannot register input device\n");
- goto err_ir;
- }
-
- ret = input_register_device(wdata->input);
- if (ret) {
- hid_err(hdev, "Cannot register input device\n");
- goto err_input;
- }
-
- wdata->battery.properties = wiimote_battery_props;
- wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props);
- wdata->battery.get_property = wiimote_battery_get_property;
- wdata->battery.name = "wiimote_battery";
- wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
- wdata->battery.use_for_apm = 0;
-
- ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
- if (ret) {
- hid_err(hdev, "Cannot register battery device\n");
- goto err_battery;
- }
-
- power_supply_powers(&wdata->battery, &hdev->dev);
-
- ret = wiimote_leds_create(wdata);
- if (ret)
- goto err_free;
-
- ret = wiiext_init(wdata);
- if (ret)
- goto err_free;
-
- ret = wiidebug_init(wdata);
- if (ret)
- goto err_free;
-
- hid_info(hdev, "New device registered\n");
-
- /* by default set led1 after device initialization */
- spin_lock_irq(&wdata->state.lock);
- wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1);
- spin_unlock_irq(&wdata->state.lock);
-
- return 0;
-
-err_free:
- wiimote_destroy(wdata);
- return ret;
-
-err_battery:
- input_unregister_device(wdata->input);
- wdata->input = NULL;
-err_input:
- input_unregister_device(wdata->ir);
- wdata->ir = NULL;
-err_ir:
- input_unregister_device(wdata->accel);
- wdata->accel = NULL;
-err_stop:
- hid_hw_stop(hdev);
-err:
- input_free_device(wdata->ir);
- input_free_device(wdata->accel);
- input_free_device(wdata->input);
- kfree(wdata);
- return ret;
-}
-
-static void wiimote_hid_remove(struct hid_device *hdev)
-{
- struct wiimote_data *wdata = hid_get_drvdata(hdev);
-
- hid_info(hdev, "Device removed\n");
- wiimote_destroy(wdata);
-}
-
-static const struct hid_device_id wiimote_hid_devices[] = {
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
- USB_DEVICE_ID_NINTENDO_WIIMOTE) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, wiimote_hid_devices);
-
-static struct hid_driver wiimote_hid_driver = {
- .name = "wiimote",
- .id_table = wiimote_hid_devices,
- .probe = wiimote_hid_probe,
- .remove = wiimote_hid_remove,
- .raw_event = wiimote_hid_event,
-};
-
-static int __init wiimote_init(void)
-{
- int ret;
-
- ret = hid_register_driver(&wiimote_hid_driver);
- if (ret)
- pr_err("Can't register wiimote hid driver\n");
-
- return ret;
-}
-
-static void __exit wiimote_exit(void)
-{
- hid_unregister_driver(&wiimote_hid_driver);
-}
-
-module_init(wiimote_init);
-module_exit(wiimote_exit);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
-MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-wiimote-debug.c b/ANDROID_3.4.5/drivers/hid/hid-wiimote-debug.c
deleted file mode 100644
index eec32919..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-wiimote-debug.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Debug support for HID Nintendo Wiimote devices
- * Copyright (c) 2011 David Herrmann
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/debugfs.h>
-#include <linux/module.h>
-#include <linux/seq_file.h>
-#include <linux/spinlock.h>
-#include <linux/uaccess.h>
-#include "hid-wiimote.h"
-
-struct wiimote_debug {
- struct wiimote_data *wdata;
- struct dentry *eeprom;
- struct dentry *drm;
-};
-
-static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s,
- loff_t *off)
-{
- struct wiimote_debug *dbg = f->private_data;
- struct wiimote_data *wdata = dbg->wdata;
- unsigned long flags;
- ssize_t ret;
- char buf[16];
- __u16 size;
-
- if (s == 0)
- return -EINVAL;
- if (*off > 0xffffff)
- return 0;
- if (s > 16)
- s = 16;
-
- ret = wiimote_cmd_acquire(wdata);
- if (ret)
- return ret;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.cmd_read_size = s;
- wdata->state.cmd_read_buf = buf;
- wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, *off & 0xffff);
- wiiproto_req_reeprom(wdata, *off, s);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- ret = wiimote_cmd_wait(wdata);
- if (!ret)
- size = wdata->state.cmd_read_size;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.cmd_read_buf = NULL;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- wiimote_cmd_release(wdata);
-
- if (ret)
- return ret;
- else if (size == 0)
- return -EIO;
-
- if (copy_to_user(u, buf, size))
- return -EFAULT;
-
- *off += size;
- ret = size;
-
- return ret;
-}
-
-static const struct file_operations wiidebug_eeprom_fops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = wiidebug_eeprom_read,
- .llseek = generic_file_llseek,
-};
-
-static const char *wiidebug_drmmap[] = {
- [WIIPROTO_REQ_NULL] = "NULL",
- [WIIPROTO_REQ_DRM_K] = "K",
- [WIIPROTO_REQ_DRM_KA] = "KA",
- [WIIPROTO_REQ_DRM_KE] = "KE",
- [WIIPROTO_REQ_DRM_KAI] = "KAI",
- [WIIPROTO_REQ_DRM_KEE] = "KEE",
- [WIIPROTO_REQ_DRM_KAE] = "KAE",
- [WIIPROTO_REQ_DRM_KIE] = "KIE",
- [WIIPROTO_REQ_DRM_KAIE] = "KAIE",
- [WIIPROTO_REQ_DRM_E] = "E",
- [WIIPROTO_REQ_DRM_SKAI1] = "SKAI1",
- [WIIPROTO_REQ_DRM_SKAI2] = "SKAI2",
- [WIIPROTO_REQ_MAX] = NULL
-};
-
-static int wiidebug_drm_show(struct seq_file *f, void *p)
-{
- struct wiimote_debug *dbg = f->private;
- const char *str = NULL;
- unsigned long flags;
- __u8 drm;
-
- spin_lock_irqsave(&dbg->wdata->state.lock, flags);
- drm = dbg->wdata->state.drm;
- spin_unlock_irqrestore(&dbg->wdata->state.lock, flags);
-
- if (drm < WIIPROTO_REQ_MAX)
- str = wiidebug_drmmap[drm];
- if (!str)
- str = "unknown";
-
- seq_printf(f, "%s\n", str);
-
- return 0;
-}
-
-static int wiidebug_drm_open(struct inode *i, struct file *f)
-{
- return single_open(f, wiidebug_drm_show, i->i_private);
-}
-
-static ssize_t wiidebug_drm_write(struct file *f, const char __user *u,
- size_t s, loff_t *off)
-{
- struct wiimote_debug *dbg = f->private_data;
- unsigned long flags;
- char buf[16];
- ssize_t len;
- int i;
-
- if (s == 0)
- return -EINVAL;
-
- len = min((size_t) 15, s);
- if (copy_from_user(buf, u, len))
- return -EFAULT;
-
- buf[15] = 0;
-
- for (i = 0; i < WIIPROTO_REQ_MAX; ++i) {
- if (!wiidebug_drmmap[i])
- continue;
- if (!strcasecmp(buf, wiidebug_drmmap[i]))
- break;
- }
-
- if (i == WIIPROTO_REQ_MAX)
- i = simple_strtoul(buf, NULL, 10);
-
- spin_lock_irqsave(&dbg->wdata->state.lock, flags);
- wiiproto_req_drm(dbg->wdata, (__u8) i);
- spin_unlock_irqrestore(&dbg->wdata->state.lock, flags);
-
- return len;
-}
-
-static const struct file_operations wiidebug_drm_fops = {
- .owner = THIS_MODULE,
- .open = wiidebug_drm_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = wiidebug_drm_write,
- .release = single_release,
-};
-
-int wiidebug_init(struct wiimote_data *wdata)
-{
- struct wiimote_debug *dbg;
- unsigned long flags;
- int ret = -ENOMEM;
-
- dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
- if (!dbg)
- return -ENOMEM;
-
- dbg->wdata = wdata;
-
- dbg->eeprom = debugfs_create_file("eeprom", S_IRUSR,
- dbg->wdata->hdev->debug_dir, dbg, &wiidebug_eeprom_fops);
- if (!dbg->eeprom)
- goto err;
-
- dbg->drm = debugfs_create_file("drm", S_IRUSR,
- dbg->wdata->hdev->debug_dir, dbg, &wiidebug_drm_fops);
- if (!dbg->drm)
- goto err_drm;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->debug = dbg;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- return 0;
-
-err_drm:
- debugfs_remove(dbg->eeprom);
-err:
- kfree(dbg);
- return ret;
-}
-
-void wiidebug_deinit(struct wiimote_data *wdata)
-{
- struct wiimote_debug *dbg = wdata->debug;
- unsigned long flags;
-
- if (!dbg)
- return;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->debug = NULL;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- debugfs_remove(dbg->drm);
- debugfs_remove(dbg->eeprom);
- kfree(dbg);
-}
diff --git a/ANDROID_3.4.5/drivers/hid/hid-wiimote-ext.c b/ANDROID_3.4.5/drivers/hid/hid-wiimote-ext.c
deleted file mode 100644
index aa958706..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-wiimote-ext.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * HID driver for Nintendo Wiimote extension devices
- * Copyright (c) 2011 David Herrmann
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/atomic.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include "hid-wiimote.h"
-
-struct wiimote_ext {
- struct wiimote_data *wdata;
- struct work_struct worker;
- struct input_dev *input;
- struct input_dev *mp_input;
-
- atomic_t opened;
- atomic_t mp_opened;
- bool plugged;
- bool mp_plugged;
- bool motionp;
- __u8 ext_type;
-};
-
-enum wiiext_type {
- WIIEXT_NONE, /* placeholder */
- WIIEXT_CLASSIC, /* Nintendo classic controller */
- WIIEXT_NUNCHUCK, /* Nintendo nunchuck controller */
-};
-
-enum wiiext_keys {
- WIIEXT_KEY_C,
- WIIEXT_KEY_Z,
- WIIEXT_KEY_A,
- WIIEXT_KEY_B,
- WIIEXT_KEY_X,
- WIIEXT_KEY_Y,
- WIIEXT_KEY_ZL,
- WIIEXT_KEY_ZR,
- WIIEXT_KEY_PLUS,
- WIIEXT_KEY_MINUS,
- WIIEXT_KEY_HOME,
- WIIEXT_KEY_LEFT,
- WIIEXT_KEY_RIGHT,
- WIIEXT_KEY_UP,
- WIIEXT_KEY_DOWN,
- WIIEXT_KEY_LT,
- WIIEXT_KEY_RT,
- WIIEXT_KEY_COUNT
-};
-
-static __u16 wiiext_keymap[] = {
- BTN_C, /* WIIEXT_KEY_C */
- BTN_Z, /* WIIEXT_KEY_Z */
- BTN_A, /* WIIEXT_KEY_A */
- BTN_B, /* WIIEXT_KEY_B */
- BTN_X, /* WIIEXT_KEY_X */
- BTN_Y, /* WIIEXT_KEY_Y */
- BTN_TL2, /* WIIEXT_KEY_ZL */
- BTN_TR2, /* WIIEXT_KEY_ZR */
- KEY_NEXT, /* WIIEXT_KEY_PLUS */
- KEY_PREVIOUS, /* WIIEXT_KEY_MINUS */
- BTN_MODE, /* WIIEXT_KEY_HOME */
- KEY_LEFT, /* WIIEXT_KEY_LEFT */
- KEY_RIGHT, /* WIIEXT_KEY_RIGHT */
- KEY_UP, /* WIIEXT_KEY_UP */
- KEY_DOWN, /* WIIEXT_KEY_DOWN */
- BTN_TL, /* WIIEXT_KEY_LT */
- BTN_TR, /* WIIEXT_KEY_RT */
-};
-
-/* diable all extensions */
-static void ext_disable(struct wiimote_ext *ext)
-{
- unsigned long flags;
- __u8 wmem = 0x55;
-
- if (!wiimote_cmd_acquire(ext->wdata)) {
- wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
- wiimote_cmd_release(ext->wdata);
- }
-
- spin_lock_irqsave(&ext->wdata->state.lock, flags);
- ext->motionp = false;
- ext->ext_type = WIIEXT_NONE;
- wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL);
- spin_unlock_irqrestore(&ext->wdata->state.lock, flags);
-}
-
-static bool motionp_read(struct wiimote_ext *ext)
-{
- __u8 rmem[2], wmem;
- ssize_t ret;
- bool avail = false;
-
- if (!atomic_read(&ext->mp_opened))
- return false;
-
- if (wiimote_cmd_acquire(ext->wdata))
- return false;
-
- /* initialize motion plus */
- wmem = 0x55;
- ret = wiimote_cmd_write(ext->wdata, 0xa600f0, &wmem, sizeof(wmem));
- if (ret)
- goto error;
-
- /* read motion plus ID */
- ret = wiimote_cmd_read(ext->wdata, 0xa600fe, rmem, 2);
- if (ret == 2 || rmem[1] == 0x5)
- avail = true;
-
-error:
- wiimote_cmd_release(ext->wdata);
- return avail;
-}
-
-static __u8 ext_read(struct wiimote_ext *ext)
-{
- ssize_t ret;
- __u8 rmem[2], wmem;
- __u8 type = WIIEXT_NONE;
-
- if (!ext->plugged || !atomic_read(&ext->opened))
- return WIIEXT_NONE;
-
- if (wiimote_cmd_acquire(ext->wdata))
- return WIIEXT_NONE;
-
- /* initialize extension */
- wmem = 0x55;
- ret = wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
- if (!ret) {
- /* disable encryption */
- wmem = 0x0;
- wiimote_cmd_write(ext->wdata, 0xa400fb, &wmem, sizeof(wmem));
- }
-
- /* read extension ID */
- ret = wiimote_cmd_read(ext->wdata, 0xa400fe, rmem, 2);
- if (ret == 2) {
- if (rmem[0] == 0 && rmem[1] == 0)
- type = WIIEXT_NUNCHUCK;
- else if (rmem[0] == 0x01 && rmem[1] == 0x01)
- type = WIIEXT_CLASSIC;
- }
-
- wiimote_cmd_release(ext->wdata);
-
- return type;
-}
-
-static void ext_enable(struct wiimote_ext *ext, bool motionp, __u8 ext_type)
-{
- unsigned long flags;
- __u8 wmem;
- int ret;
-
- if (motionp) {
- if (wiimote_cmd_acquire(ext->wdata))
- return;
-
- if (ext_type == WIIEXT_CLASSIC)
- wmem = 0x07;
- else if (ext_type == WIIEXT_NUNCHUCK)
- wmem = 0x05;
- else
- wmem = 0x04;
-
- ret = wiimote_cmd_write(ext->wdata, 0xa600fe, &wmem, sizeof(wmem));
- wiimote_cmd_release(ext->wdata);
- if (ret)
- return;
- }
-
- spin_lock_irqsave(&ext->wdata->state.lock, flags);
- ext->motionp = motionp;
- ext->ext_type = ext_type;
- wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL);
- spin_unlock_irqrestore(&ext->wdata->state.lock, flags);
-}
-
-static void wiiext_worker(struct work_struct *work)
-{
- struct wiimote_ext *ext = container_of(work, struct wiimote_ext,
- worker);
- bool motionp;
- __u8 ext_type;
-
- ext_disable(ext);
- motionp = motionp_read(ext);
- ext_type = ext_read(ext);
- ext_enable(ext, motionp, ext_type);
-}
-
-/* schedule work only once, otherwise mark for reschedule */
-static void wiiext_schedule(struct wiimote_ext *ext)
-{
- queue_work(system_nrt_wq, &ext->worker);
-}
-
-/*
- * Reacts on extension port events
- * Whenever the driver gets an event from the wiimote that an extension has been
- * plugged or unplugged, this funtion shall be called. It checks what extensions
- * are connected and initializes and activates them.
- * This can be called in atomic context. The initialization is done in a
- * separate worker thread. The state.lock spinlock must be held by the caller.
- */
-void wiiext_event(struct wiimote_data *wdata, bool plugged)
-{
- if (!wdata->ext)
- return;
-
- if (wdata->ext->plugged == plugged)
- return;
-
- wdata->ext->plugged = plugged;
-
- if (!plugged)
- wdata->ext->mp_plugged = false;
-
- /*
- * We need to call wiiext_schedule(wdata->ext) here, however, the
- * extension initialization logic is not fully understood and so
- * automatic initialization is not supported, yet.
- */
-}
-
-/*
- * Returns true if the current DRM mode should contain extension data and false
- * if there is no interest in extension data.
- * All supported extensions send 6 byte extension data so any DRM that contains
- * extension bytes is fine.
- * The caller must hold the state.lock spinlock.
- */
-bool wiiext_active(struct wiimote_data *wdata)
-{
- if (!wdata->ext)
- return false;
-
- return wdata->ext->motionp || wdata->ext->ext_type;
-}
-
-static void handler_motionp(struct wiimote_ext *ext, const __u8 *payload)
-{
- __s32 x, y, z;
- bool plugged;
-
- /* | 8 7 6 5 4 3 | 2 | 1 |
- * -----+------------------------------+-----+-----+
- * 1 | Yaw Speed <7:0> |
- * 2 | Roll Speed <7:0> |
- * 3 | Pitch Speed <7:0> |
- * -----+------------------------------+-----+-----+
- * 4 | Yaw Speed <13:8> | Yaw |Pitch|
- * -----+------------------------------+-----+-----+
- * 5 | Roll Speed <13:8> |Roll | Ext |
- * -----+------------------------------+-----+-----+
- * 6 | Pitch Speed <13:8> | 1 | 0 |
- * -----+------------------------------+-----+-----+
- * The single bits Yaw, Roll, Pitch in the lower right corner specify
- * whether the wiimote is rotating fast (0) or slow (1). Speed for slow
- * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a
- * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast
- * and 9 for slow.
- * If the wiimote is not rotating the sensor reports 2^13 = 8192.
- * Ext specifies whether an extension is connected to the motionp.
- */
-
- x = payload[0];
- y = payload[1];
- z = payload[2];
-
- x |= (((__u16)payload[3]) << 6) & 0xff00;
- y |= (((__u16)payload[4]) << 6) & 0xff00;
- z |= (((__u16)payload[5]) << 6) & 0xff00;
-
- x -= 8192;
- y -= 8192;
- z -= 8192;
-
- if (!(payload[3] & 0x02))
- x *= 18;
- else
- x *= 9;
- if (!(payload[4] & 0x02))
- y *= 18;
- else
- y *= 9;
- if (!(payload[3] & 0x01))
- z *= 18;
- else
- z *= 9;
-
- input_report_abs(ext->mp_input, ABS_RX, x);
- input_report_abs(ext->mp_input, ABS_RY, y);
- input_report_abs(ext->mp_input, ABS_RZ, z);
- input_sync(ext->mp_input);
-
- plugged = payload[5] & 0x01;
- if (plugged != ext->mp_plugged)
- ext->mp_plugged = plugged;
-}
-
-static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload)
-{
- __s16 x, y, z, bx, by;
-
- /* Byte | 8 7 | 6 5 | 4 3 | 2 | 1 |
- * -----+----------+---------+---------+----+-----+
- * 1 | Button X <7:0> |
- * 2 | Button Y <7:0> |
- * -----+----------+---------+---------+----+-----+
- * 3 | Speed X <9:2> |
- * 4 | Speed Y <9:2> |
- * 5 | Speed Z <9:2> |
- * -----+----------+---------+---------+----+-----+
- * 6 | Z <1:0> | Y <1:0> | X <1:0> | BC | BZ |
- * -----+----------+---------+---------+----+-----+
- * Button X/Y is the analog stick. Speed X, Y and Z are the
- * accelerometer data in the same format as the wiimote's accelerometer.
- * The 6th byte contains the LSBs of the accelerometer data.
- * BC and BZ are the C and Z buttons: 0 means pressed
- *
- * If reported interleaved with motionp, then the layout changes. The
- * 5th and 6th byte changes to:
- * -----+-----------------------------------+-----+
- * 5 | Speed Z <9:3> | EXT |
- * -----+--------+-----+-----+----+----+----+-----+
- * 6 |Z <2:1> |Y <1>|X <1>| BC | BZ | 0 | 0 |
- * -----+--------+-----+-----+----+----+----+-----+
- * All three accelerometer values lose their LSB. The other data is
- * still available but slightly moved.
- *
- * Center data for button values is 128. Center value for accelerometer
- * values it 512 / 0x200
- */
-
- bx = payload[0];
- by = payload[1];
- bx -= 128;
- by -= 128;
-
- x = payload[2] << 2;
- y = payload[3] << 2;
- z = payload[4] << 2;
-
- if (ext->motionp) {
- x |= (payload[5] >> 3) & 0x02;
- y |= (payload[5] >> 4) & 0x02;
- z &= ~0x4;
- z |= (payload[5] >> 5) & 0x06;
- } else {
- x |= (payload[5] >> 2) & 0x03;
- y |= (payload[5] >> 4) & 0x03;
- z |= (payload[5] >> 6) & 0x03;
- }
-
- x -= 0x200;
- y -= 0x200;
- z -= 0x200;
-
- input_report_abs(ext->input, ABS_HAT0X, bx);
- input_report_abs(ext->input, ABS_HAT0Y, by);
-
- input_report_abs(ext->input, ABS_RX, x);
- input_report_abs(ext->input, ABS_RY, y);
- input_report_abs(ext->input, ABS_RZ, z);
-
- if (ext->motionp) {
- input_report_key(ext->input,
- wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x04));
- input_report_key(ext->input,
- wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x08));
- } else {
- input_report_key(ext->input,
- wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x01));
- input_report_key(ext->input,
- wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x02));
- }
-
- input_sync(ext->input);
-}
-
-static void handler_classic(struct wiimote_ext *ext, const __u8 *payload)
-{
- __s8 rx, ry, lx, ly, lt, rt;
-
- /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
- * -----+-----+-----+-----+-----+-----+-----+-----+-----+
- * 1 | RX <5:4> | LX <5:0> |
- * 2 | RX <3:2> | LY <5:0> |
- * -----+-----+-----+-----+-----------------------------+
- * 3 |RX<1>| LT <5:4> | RY <5:1> |
- * -----+-----+-----------+-----------------------------+
- * 4 | LT <3:1> | RT <5:1> |
- * -----+-----+-----+-----+-----+-----+-----+-----+-----+
- * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 |
- * -----+-----+-----+-----+-----+-----+-----+-----+-----+
- * 6 | BZL | BB | BY | BA | BX | BZR | BDL | BDU |
- * -----+-----+-----+-----+-----+-----+-----+-----+-----+
- * All buttons are 0 if pressed
- * RX and RY are right analog stick
- * LX and LY are left analog stick
- * LT is left trigger, RT is right trigger
- * BLT is 0 if left trigger is fully pressed
- * BRT is 0 if right trigger is fully pressed
- * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons
- * BZL is left Z button and BZR is right Z button
- * B-, BH, B+ are +, HOME and - buttons
- * BB, BY, BA, BX are A, B, X, Y buttons
- * LSB of RX, RY, LT, and RT are not transmitted and always 0.
- *
- * With motionp enabled it changes slightly to this:
- * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
- * -----+-----+-----+-----+-----+-----+-----+-----+-----+
- * 1 | RX <4:3> | LX <5:1> | BDU |
- * 2 | RX <2:1> | LY <5:1> | BDL |
- * -----+-----+-----+-----+-----------------------+-----+
- * 3 |RX<0>| LT <4:3> | RY <4:0> |
- * -----+-----+-----------+-----------------------------+
- * 4 | LT <2:0> | RT <4:0> |
- * -----+-----+-----+-----+-----+-----+-----+-----+-----+
- * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | EXT |
- * -----+-----+-----+-----+-----+-----+-----+-----+-----+
- * 6 | BZL | BB | BY | BA | BX | BZR | 0 | 0 |
- * -----+-----+-----+-----+-----+-----+-----+-----+-----+
- * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest
- * is the same as before.
- */
-
- if (ext->motionp) {
- lx = payload[0] & 0x3e;
- ly = payload[0] & 0x3e;
- } else {
- lx = payload[0] & 0x3f;
- ly = payload[0] & 0x3f;
- }
-
- rx = (payload[0] >> 3) & 0x14;
- rx |= (payload[1] >> 5) & 0x06;
- rx |= (payload[2] >> 7) & 0x01;
- ry = payload[2] & 0x1f;
-
- rt = payload[3] & 0x1f;
- lt = (payload[2] >> 2) & 0x18;
- lt |= (payload[3] >> 5) & 0x07;
-
- rx <<= 1;
- ry <<= 1;
- rt <<= 1;
- lt <<= 1;
-
- input_report_abs(ext->input, ABS_HAT1X, lx - 0x20);
- input_report_abs(ext->input, ABS_HAT1Y, ly - 0x20);
- input_report_abs(ext->input, ABS_HAT2X, rx - 0x20);
- input_report_abs(ext->input, ABS_HAT2Y, ry - 0x20);
- input_report_abs(ext->input, ABS_HAT3X, rt - 0x20);
- input_report_abs(ext->input, ABS_HAT3Y, lt - 0x20);
-
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_RIGHT],
- !!(payload[4] & 0x80));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_DOWN],
- !!(payload[4] & 0x40));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LT],
- !!(payload[4] & 0x20));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_MINUS],
- !!(payload[4] & 0x10));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_HOME],
- !!(payload[4] & 0x08));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_PLUS],
- !!(payload[4] & 0x04));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_RT],
- !!(payload[4] & 0x02));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_ZL],
- !!(payload[5] & 0x80));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_B],
- !!(payload[5] & 0x40));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_Y],
- !!(payload[5] & 0x20));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_A],
- !!(payload[5] & 0x10));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_X],
- !!(payload[5] & 0x08));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_ZR],
- !!(payload[5] & 0x04));
-
- if (ext->motionp) {
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_UP],
- !!(payload[0] & 0x01));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LEFT],
- !!(payload[1] & 0x01));
- } else {
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_UP],
- !!(payload[5] & 0x01));
- input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LEFT],
- !!(payload[5] & 0x02));
- }
-
- input_sync(ext->input);
-}
-
-/* call this with state.lock spinlock held */
-void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload)
-{
- struct wiimote_ext *ext = wdata->ext;
-
- if (!ext)
- return;
-
- if (ext->motionp && (payload[5] & 0x02)) {
- handler_motionp(ext, payload);
- } else if (ext->ext_type == WIIEXT_NUNCHUCK) {
- handler_nunchuck(ext, payload);
- } else if (ext->ext_type == WIIEXT_CLASSIC) {
- handler_classic(ext, payload);
- }
-}
-
-static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct wiimote_data *wdata = dev_to_wii(dev);
- __u8 type = WIIEXT_NONE;
- bool motionp = false;
- unsigned long flags;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- if (wdata->ext) {
- motionp = wdata->ext->motionp;
- type = wdata->ext->ext_type;
- }
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- if (type == WIIEXT_NUNCHUCK) {
- if (motionp)
- return sprintf(buf, "motionp+nunchuck\n");
- else
- return sprintf(buf, "nunchuck\n");
- } else if (type == WIIEXT_CLASSIC) {
- if (motionp)
- return sprintf(buf, "motionp+classic\n");
- else
- return sprintf(buf, "classic\n");
- } else {
- if (motionp)
- return sprintf(buf, "motionp\n");
- else
- return sprintf(buf, "none\n");
- }
-}
-
-static DEVICE_ATTR(extension, S_IRUGO, wiiext_show, NULL);
-
-static int wiiext_input_open(struct input_dev *dev)
-{
- struct wiimote_ext *ext = input_get_drvdata(dev);
- int ret;
-
- ret = hid_hw_open(ext->wdata->hdev);
- if (ret)
- return ret;
-
- atomic_inc(&ext->opened);
- wiiext_schedule(ext);
-
- return 0;
-}
-
-static void wiiext_input_close(struct input_dev *dev)
-{
- struct wiimote_ext *ext = input_get_drvdata(dev);
-
- atomic_dec(&ext->opened);
- wiiext_schedule(ext);
- hid_hw_close(ext->wdata->hdev);
-}
-
-static int wiiext_mp_open(struct input_dev *dev)
-{
- struct wiimote_ext *ext = input_get_drvdata(dev);
- int ret;
-
- ret = hid_hw_open(ext->wdata->hdev);
- if (ret)
- return ret;
-
- atomic_inc(&ext->mp_opened);
- wiiext_schedule(ext);
-
- return 0;
-}
-
-static void wiiext_mp_close(struct input_dev *dev)
-{
- struct wiimote_ext *ext = input_get_drvdata(dev);
-
- atomic_dec(&ext->mp_opened);
- wiiext_schedule(ext);
- hid_hw_close(ext->wdata->hdev);
-}
-
-/* Initializes the extension driver of a wiimote */
-int wiiext_init(struct wiimote_data *wdata)
-{
- struct wiimote_ext *ext;
- unsigned long flags;
- int ret, i;
-
- ext = kzalloc(sizeof(*ext), GFP_KERNEL);
- if (!ext)
- return -ENOMEM;
-
- ext->wdata = wdata;
- INIT_WORK(&ext->worker, wiiext_worker);
-
- ext->input = input_allocate_device();
- if (!ext->input) {
- ret = -ENOMEM;
- goto err_input;
- }
-
- input_set_drvdata(ext->input, ext);
- ext->input->open = wiiext_input_open;
- ext->input->close = wiiext_input_close;
- ext->input->dev.parent = &wdata->hdev->dev;
- ext->input->id.bustype = wdata->hdev->bus;
- ext->input->id.vendor = wdata->hdev->vendor;
- ext->input->id.product = wdata->hdev->product;
- ext->input->id.version = wdata->hdev->version;
- ext->input->name = WIIMOTE_NAME " Extension";
-
- set_bit(EV_KEY, ext->input->evbit);
- for (i = 0; i < WIIEXT_KEY_COUNT; ++i)
- set_bit(wiiext_keymap[i], ext->input->keybit);
-
- set_bit(EV_ABS, ext->input->evbit);
- set_bit(ABS_HAT0X, ext->input->absbit);
- set_bit(ABS_HAT0Y, ext->input->absbit);
- set_bit(ABS_HAT1X, ext->input->absbit);
- set_bit(ABS_HAT1Y, ext->input->absbit);
- set_bit(ABS_HAT2X, ext->input->absbit);
- set_bit(ABS_HAT2Y, ext->input->absbit);
- set_bit(ABS_HAT3X, ext->input->absbit);
- set_bit(ABS_HAT3Y, ext->input->absbit);
- input_set_abs_params(ext->input, ABS_HAT0X, -120, 120, 2, 4);
- input_set_abs_params(ext->input, ABS_HAT0Y, -120, 120, 2, 4);
- input_set_abs_params(ext->input, ABS_HAT1X, -30, 30, 1, 1);
- input_set_abs_params(ext->input, ABS_HAT1Y, -30, 30, 1, 1);
- input_set_abs_params(ext->input, ABS_HAT2X, -30, 30, 1, 1);
- input_set_abs_params(ext->input, ABS_HAT2Y, -30, 30, 1, 1);
- input_set_abs_params(ext->input, ABS_HAT3X, -30, 30, 1, 1);
- input_set_abs_params(ext->input, ABS_HAT3Y, -30, 30, 1, 1);
- set_bit(ABS_RX, ext->input->absbit);
- set_bit(ABS_RY, ext->input->absbit);
- set_bit(ABS_RZ, ext->input->absbit);
- input_set_abs_params(ext->input, ABS_RX, -500, 500, 2, 4);
- input_set_abs_params(ext->input, ABS_RY, -500, 500, 2, 4);
- input_set_abs_params(ext->input, ABS_RZ, -500, 500, 2, 4);
-
- ret = input_register_device(ext->input);
- if (ret) {
- input_free_device(ext->input);
- goto err_input;
- }
-
- ext->mp_input = input_allocate_device();
- if (!ext->mp_input) {
- ret = -ENOMEM;
- goto err_mp;
- }
-
- input_set_drvdata(ext->mp_input, ext);
- ext->mp_input->open = wiiext_mp_open;
- ext->mp_input->close = wiiext_mp_close;
- ext->mp_input->dev.parent = &wdata->hdev->dev;
- ext->mp_input->id.bustype = wdata->hdev->bus;
- ext->mp_input->id.vendor = wdata->hdev->vendor;
- ext->mp_input->id.product = wdata->hdev->product;
- ext->mp_input->id.version = wdata->hdev->version;
- ext->mp_input->name = WIIMOTE_NAME " Motion+";
-
- set_bit(EV_ABS, ext->mp_input->evbit);
- set_bit(ABS_RX, ext->mp_input->absbit);
- set_bit(ABS_RY, ext->mp_input->absbit);
- set_bit(ABS_RZ, ext->mp_input->absbit);
- input_set_abs_params(ext->mp_input, ABS_RX, -160000, 160000, 4, 8);
- input_set_abs_params(ext->mp_input, ABS_RY, -160000, 160000, 4, 8);
- input_set_abs_params(ext->mp_input, ABS_RZ, -160000, 160000, 4, 8);
-
- ret = input_register_device(ext->mp_input);
- if (ret) {
- input_free_device(ext->mp_input);
- goto err_mp;
- }
-
- ret = device_create_file(&wdata->hdev->dev, &dev_attr_extension);
- if (ret)
- goto err_dev;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->ext = ext;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- return 0;
-
-err_dev:
- input_unregister_device(ext->mp_input);
-err_mp:
- input_unregister_device(ext->input);
-err_input:
- kfree(ext);
- return ret;
-}
-
-/* Deinitializes the extension driver of a wiimote */
-void wiiext_deinit(struct wiimote_data *wdata)
-{
- struct wiimote_ext *ext = wdata->ext;
- unsigned long flags;
-
- if (!ext)
- return;
-
- /*
- * We first unset wdata->ext to avoid further input from the wiimote
- * core. The worker thread does not access this pointer so it is not
- * affected by this.
- * We kill the worker after this so it does not get respawned during
- * deinitialization.
- */
-
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->ext = NULL;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
-
- device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
- input_unregister_device(ext->mp_input);
- input_unregister_device(ext->input);
-
- cancel_work_sync(&ext->worker);
- kfree(ext);
-}
diff --git a/ANDROID_3.4.5/drivers/hid/hid-wiimote.h b/ANDROID_3.4.5/drivers/hid/hid-wiimote.h
deleted file mode 100644
index c81dbeb0..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-wiimote.h
+++ /dev/null
@@ -1,208 +0,0 @@
-#ifndef __HID_WIIMOTE_H
-#define __HID_WIIMOTE_H
-
-/*
- * HID driver for Nintendo Wiimote devices
- * Copyright (c) 2011 David Herrmann
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/completion.h>
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/leds.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/power_supply.h>
-#include <linux/spinlock.h>
-
-#define WIIMOTE_NAME "Nintendo Wii Remote"
-#define WIIMOTE_BUFSIZE 32
-
-#define WIIPROTO_FLAG_LED1 0x01
-#define WIIPROTO_FLAG_LED2 0x02
-#define WIIPROTO_FLAG_LED3 0x04
-#define WIIPROTO_FLAG_LED4 0x08
-#define WIIPROTO_FLAG_RUMBLE 0x10
-#define WIIPROTO_FLAG_ACCEL 0x20
-#define WIIPROTO_FLAG_IR_BASIC 0x40
-#define WIIPROTO_FLAG_IR_EXT 0x80
-#define WIIPROTO_FLAG_IR_FULL 0xc0 /* IR_BASIC | IR_EXT */
-#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
- WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
-#define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \
- WIIPROTO_FLAG_IR_FULL)
-
-/* return flag for led \num */
-#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
-
-struct wiimote_buf {
- __u8 data[HID_MAX_BUFFER_SIZE];
- size_t size;
-};
-
-struct wiimote_state {
- spinlock_t lock;
- __u8 flags;
- __u8 accel_split[2];
- __u8 drm;
-
- /* synchronous cmd requests */
- struct mutex sync;
- struct completion ready;
- int cmd;
- __u32 opt;
-
- /* results of synchronous requests */
- __u8 cmd_battery;
- __u8 cmd_err;
- __u8 *cmd_read_buf;
- __u8 cmd_read_size;
-};
-
-struct wiimote_data {
- struct hid_device *hdev;
- struct input_dev *input;
- struct led_classdev *leds[4];
- struct input_dev *accel;
- struct input_dev *ir;
- struct power_supply battery;
- struct wiimote_ext *ext;
- struct wiimote_debug *debug;
-
- spinlock_t qlock;
- __u8 head;
- __u8 tail;
- struct wiimote_buf outq[WIIMOTE_BUFSIZE];
- struct work_struct worker;
-
- struct wiimote_state state;
-};
-
-enum wiiproto_reqs {
- WIIPROTO_REQ_NULL = 0x0,
- WIIPROTO_REQ_RUMBLE = 0x10,
- WIIPROTO_REQ_LED = 0x11,
- WIIPROTO_REQ_DRM = 0x12,
- WIIPROTO_REQ_IR1 = 0x13,
- WIIPROTO_REQ_SREQ = 0x15,
- WIIPROTO_REQ_WMEM = 0x16,
- WIIPROTO_REQ_RMEM = 0x17,
- WIIPROTO_REQ_IR2 = 0x1a,
- WIIPROTO_REQ_STATUS = 0x20,
- WIIPROTO_REQ_DATA = 0x21,
- WIIPROTO_REQ_RETURN = 0x22,
- WIIPROTO_REQ_DRM_K = 0x30,
- WIIPROTO_REQ_DRM_KA = 0x31,
- WIIPROTO_REQ_DRM_KE = 0x32,
- WIIPROTO_REQ_DRM_KAI = 0x33,
- WIIPROTO_REQ_DRM_KEE = 0x34,
- WIIPROTO_REQ_DRM_KAE = 0x35,
- WIIPROTO_REQ_DRM_KIE = 0x36,
- WIIPROTO_REQ_DRM_KAIE = 0x37,
- WIIPROTO_REQ_DRM_E = 0x3d,
- WIIPROTO_REQ_DRM_SKAI1 = 0x3e,
- WIIPROTO_REQ_DRM_SKAI2 = 0x3f,
- WIIPROTO_REQ_MAX
-};
-
-#define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \
- dev))
-
-extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm);
-extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
- const __u8 *wmem, __u8 size);
-extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset,
- __u8 *rmem, __u8 size);
-
-#define wiiproto_req_rreg(wdata, os, sz) \
- wiiproto_req_rmem((wdata), false, (os), (sz))
-#define wiiproto_req_reeprom(wdata, os, sz) \
- wiiproto_req_rmem((wdata), true, (os), (sz))
-extern void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom,
- __u32 offset, __u16 size);
-
-#ifdef CONFIG_HID_WIIMOTE_EXT
-
-extern int wiiext_init(struct wiimote_data *wdata);
-extern void wiiext_deinit(struct wiimote_data *wdata);
-extern void wiiext_event(struct wiimote_data *wdata, bool plugged);
-extern bool wiiext_active(struct wiimote_data *wdata);
-extern void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload);
-
-#else
-
-static inline int wiiext_init(void *u) { return 0; }
-static inline void wiiext_deinit(void *u) { }
-static inline void wiiext_event(void *u, bool p) { }
-static inline bool wiiext_active(void *u) { return false; }
-static inline void wiiext_handle(void *u, const __u8 *p) { }
-
-#endif
-
-#ifdef CONFIG_DEBUG_FS
-
-extern int wiidebug_init(struct wiimote_data *wdata);
-extern void wiidebug_deinit(struct wiimote_data *wdata);
-
-#else
-
-static inline int wiidebug_init(void *u) { return 0; }
-static inline void wiidebug_deinit(void *u) { }
-
-#endif
-
-/* requires the state.lock spinlock to be held */
-static inline bool wiimote_cmd_pending(struct wiimote_data *wdata, int cmd,
- __u32 opt)
-{
- return wdata->state.cmd == cmd && wdata->state.opt == opt;
-}
-
-/* requires the state.lock spinlock to be held */
-static inline void wiimote_cmd_complete(struct wiimote_data *wdata)
-{
- wdata->state.cmd = WIIPROTO_REQ_NULL;
- complete(&wdata->state.ready);
-}
-
-static inline int wiimote_cmd_acquire(struct wiimote_data *wdata)
-{
- return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0;
-}
-
-/* requires the state.lock spinlock to be held */
-static inline void wiimote_cmd_set(struct wiimote_data *wdata, int cmd,
- __u32 opt)
-{
- INIT_COMPLETION(wdata->state.ready);
- wdata->state.cmd = cmd;
- wdata->state.opt = opt;
-}
-
-static inline void wiimote_cmd_release(struct wiimote_data *wdata)
-{
- mutex_unlock(&wdata->state.sync);
-}
-
-static inline int wiimote_cmd_wait(struct wiimote_data *wdata)
-{
- int ret;
-
- ret = wait_for_completion_interruptible_timeout(&wdata->state.ready, HZ);
- if (ret < 0)
- return -ERESTARTSYS;
- else if (ret == 0)
- return -EIO;
- else
- return 0;
-}
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/hid/hid-zpff.c b/ANDROID_3.4.5/drivers/hid/hid-zpff.c
deleted file mode 100644
index f6ba81df..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-zpff.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Force feedback support for Zeroplus based devices
- *
- * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#ifdef CONFIG_ZEROPLUS_FF
-#include "usbhid/usbhid.h"
-
-struct zpff_device {
- struct hid_report *report;
-};
-
-static int zpff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct zpff_device *zpff = data;
- int left, right;
-
- /*
- * The following is specified the other way around in the Zeroplus
- * datasheet but the order below is correct for the XFX Executioner;
- * however it is possible that the XFX Executioner is an exception
- */
-
- left = effect->u.rumble.strong_magnitude;
- right = effect->u.rumble.weak_magnitude;
- dbg_hid("called with 0x%04x 0x%04x\n", left, right);
-
- left = left * 0x7f / 0xffff;
- right = right * 0x7f / 0xffff;
-
- zpff->report->field[2]->value[0] = left;
- zpff->report->field[3]->value[0] = right;
- dbg_hid("running with 0x%02x 0x%02x\n", left, right);
- usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int zpff_init(struct hid_device *hid)
-{
- struct zpff_device *zpff;
- struct hid_report *report;
- struct hid_input *hidinput = list_entry(hid->inputs.next,
- struct hid_input, list);
- struct list_head *report_list =
- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- int error;
-
- if (list_empty(report_list)) {
- hid_err(hid, "no output report found\n");
- return -ENODEV;
- }
-
- report = list_entry(report_list->next, struct hid_report, list);
-
- if (report->maxfield < 4) {
- hid_err(hid, "not enough fields in report\n");
- return -ENODEV;
- }
-
- zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
- if (!zpff)
- return -ENOMEM;
-
- set_bit(FF_RUMBLE, dev->ffbit);
-
- error = input_ff_create_memless(dev, zpff, zpff_play);
- if (error) {
- kfree(zpff);
- return error;
- }
-
- zpff->report = report;
- zpff->report->field[0]->value[0] = 0x00;
- zpff->report->field[1]->value[0] = 0x02;
- zpff->report->field[2]->value[0] = 0x00;
- zpff->report->field[3]->value[0] = 0x00;
- usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
-
- hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
-
- return 0;
-}
-#else
-static inline int zpff_init(struct hid_device *hid)
-{
- return 0;
-}
-#endif
-
-static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- zpff_init(hdev);
-
- return 0;
-err:
- return ret;
-}
-
-static const struct hid_device_id zp_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, zp_devices);
-
-static struct hid_driver zp_driver = {
- .name = "zeroplus",
- .id_table = zp_devices,
- .probe = zp_probe,
-};
-
-static int __init zp_init(void)
-{
- return hid_register_driver(&zp_driver);
-}
-
-static void __exit zp_exit(void)
-{
- hid_unregister_driver(&zp_driver);
-}
-
-module_init(zp_init);
-module_exit(zp_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hid-zydacron.c b/ANDROID_3.4.5/drivers/hid/hid-zydacron.c
deleted file mode 100644
index 1ad85f22..00000000
--- a/ANDROID_3.4.5/drivers/hid/hid-zydacron.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-* HID driver for zydacron remote control
-*
-* Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>
-*/
-
-/*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the Free
-* Software Foundation; either version 2 of the License, or (at your option)
-* any later version.
-*/
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-struct zc_device {
- struct input_dev *input_ep81;
- unsigned short last_key[4];
-};
-
-
-/*
-* Zydacron remote control has an invalid HID report descriptor,
-* that needs fixing before we can parse it.
-*/
-static __u8 *zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize >= 253 &&
- rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff &&
- rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff &&
- rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) {
- hid_info(hdev,
- "fixing up zydacron remote control report descriptor\n");
- rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c;
- rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00;
- }
- return rdesc;
-}
-
-#define zc_map_key_clear(c) \
- hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
-
-static int zc_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- int i;
- struct zc_device *zc = hid_get_drvdata(hdev);
- zc->input_ep81 = hi->input;
-
- if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
- return 0;
-
- dbg_hid("zynacron input mapping event [0x%x]\n",
- usage->hid & HID_USAGE);
-
- switch (usage->hid & HID_USAGE) {
- /* report 2 */
- case 0x10:
- zc_map_key_clear(KEY_MODE);
- break;
- case 0x30:
- zc_map_key_clear(KEY_SCREEN);
- break;
- case 0x70:
- zc_map_key_clear(KEY_INFO);
- break;
- /* report 3 */
- case 0x04:
- zc_map_key_clear(KEY_RADIO);
- break;
- /* report 4 */
- case 0x0d:
- zc_map_key_clear(KEY_PVR);
- break;
- case 0x25:
- zc_map_key_clear(KEY_TV);
- break;
- case 0x47:
- zc_map_key_clear(KEY_AUDIO);
- break;
- case 0x49:
- zc_map_key_clear(KEY_AUX);
- break;
- case 0x4a:
- zc_map_key_clear(KEY_VIDEO);
- break;
- case 0x48:
- zc_map_key_clear(KEY_DVD);
- break;
- case 0x24:
- zc_map_key_clear(KEY_MENU);
- break;
- case 0x32:
- zc_map_key_clear(KEY_TEXT);
- break;
- default:
- return 0;
- }
-
- for (i = 0; i < 4; i++)
- zc->last_key[i] = 0;
-
- return 1;
-}
-
-static int zc_raw_event(struct hid_device *hdev, struct hid_report *report,
- u8 *data, int size)
-{
- struct zc_device *zc = hid_get_drvdata(hdev);
- int ret = 0;
- unsigned key;
- unsigned short index;
-
- if (report->id == data[0]) {
-
- /* break keys */
- for (index = 0; index < 4; index++) {
- key = zc->last_key[index];
- if (key) {
- input_event(zc->input_ep81, EV_KEY, key, 0);
- zc->last_key[index] = 0;
- }
- }
-
- key = 0;
- switch (report->id) {
- case 0x02:
- case 0x03:
- switch (data[1]) {
- case 0x10:
- key = KEY_MODE;
- index = 0;
- break;
- case 0x30:
- key = KEY_SCREEN;
- index = 1;
- break;
- case 0x70:
- key = KEY_INFO;
- index = 2;
- break;
- case 0x04:
- key = KEY_RADIO;
- index = 3;
- break;
- }
-
- if (key) {
- input_event(zc->input_ep81, EV_KEY, key, 1);
- zc->last_key[index] = key;
- }
-
- ret = 1;
- break;
- }
- }
-
- return ret;
-}
-
-static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
- struct zc_device *zc;
-
- zc = kzalloc(sizeof(*zc), GFP_KERNEL);
- if (zc == NULL) {
- hid_err(hdev, "can't alloc descriptor\n");
- return -ENOMEM;
- }
-
- hid_set_drvdata(hdev, zc);
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "parse failed\n");
- goto err_free;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hw start failed\n");
- goto err_free;
- }
-
- return 0;
-err_free:
- kfree(zc);
-
- return ret;
-}
-
-static void zc_remove(struct hid_device *hdev)
-{
- struct zc_device *zc = hid_get_drvdata(hdev);
-
- hid_hw_stop(hdev);
- kfree(zc);
-}
-
-static const struct hid_device_id zc_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, zc_devices);
-
-static struct hid_driver zc_driver = {
- .name = "zydacron",
- .id_table = zc_devices,
- .report_fixup = zc_report_fixup,
- .input_mapping = zc_input_mapping,
- .raw_event = zc_raw_event,
- .probe = zc_probe,
- .remove = zc_remove,
-};
-
-static int __init zc_init(void)
-{
- return hid_register_driver(&zc_driver);
-}
-
-static void __exit zc_exit(void)
-{
- hid_unregister_driver(&zc_driver);
-}
-
-module_init(zc_init);
-module_exit(zc_exit);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/hid/hidraw.c b/ANDROID_3.4.5/drivers/hid/hidraw.c
deleted file mode 100644
index cf7d6d58..00000000
--- a/ANDROID_3.4.5/drivers/hid/hidraw.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * HID raw devices, giving access to raw HID events.
- *
- * In comparison to hiddev, this device does not process the
- * hid events at all (no parsing, no lookups). This lets applications
- * to work on raw hid events as they want to, and avoids a need to
- * use a transport-specific userspace libhid/libusb libraries.
- *
- * Copyright (c) 2007 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/fs.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/cdev.h>
-#include <linux/poll.h>
-#include <linux/device.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/hid.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-
-#include <linux/hidraw.h>
-
-static int hidraw_major;
-static struct cdev hidraw_cdev;
-static struct class *hidraw_class;
-static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
-static DEFINE_MUTEX(minors_lock);
-
-static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
- struct hidraw_list *list = file->private_data;
- int ret = 0, len;
- DECLARE_WAITQUEUE(wait, current);
-
- mutex_lock(&list->read_mutex);
-
- while (ret == 0) {
- if (list->head == list->tail) {
- add_wait_queue(&list->hidraw->wait, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- while (list->head == list->tail) {
- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- if (!list->hidraw->exist) {
- ret = -EIO;
- break;
- }
-
- /* allow O_NONBLOCK to work well from other threads */
- mutex_unlock(&list->read_mutex);
- schedule();
- mutex_lock(&list->read_mutex);
- set_current_state(TASK_INTERRUPTIBLE);
- }
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&list->hidraw->wait, &wait);
- }
-
- if (ret)
- goto out;
-
- len = list->buffer[list->tail].len > count ?
- count : list->buffer[list->tail].len;
-
- if (copy_to_user(buffer, list->buffer[list->tail].value, len)) {
- ret = -EFAULT;
- goto out;
- }
- ret = len;
-
- kfree(list->buffer[list->tail].value);
- list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
- }
-out:
- mutex_unlock(&list->read_mutex);
- return ret;
-}
-
-/* The first byte is expected to be a report number.
- * This function is to be called with the minors_lock mutex held */
-static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type)
-{
- unsigned int minor = iminor(file->f_path.dentry->d_inode);
- struct hid_device *dev;
- __u8 *buf;
- int ret = 0;
-
- if (!hidraw_table[minor]) {
- ret = -ENODEV;
- goto out;
- }
-
- dev = hidraw_table[minor]->hid;
-
- if (!dev->hid_output_raw_report) {
- ret = -ENODEV;
- goto out;
- }
-
- if (count > HID_MAX_BUFFER_SIZE) {
- hid_warn(dev, "pid %d passed too large report\n",
- task_pid_nr(current));
- ret = -EINVAL;
- goto out;
- }
-
- if (count < 2) {
- hid_warn(dev, "pid %d passed too short report\n",
- task_pid_nr(current));
- ret = -EINVAL;
- goto out;
- }
-
- buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
- if (!buf) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (copy_from_user(buf, buffer, count)) {
- ret = -EFAULT;
- goto out_free;
- }
-
- ret = dev->hid_output_raw_report(dev, buf, count, report_type);
-out_free:
- kfree(buf);
-out:
- return ret;
-}
-
-/* the first byte is expected to be a report number */
-static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
- ssize_t ret;
- mutex_lock(&minors_lock);
- ret = hidraw_send_report(file, buffer, count, HID_OUTPUT_REPORT);
- mutex_unlock(&minors_lock);
- return ret;
-}
-
-
-/* This function performs a Get_Report transfer over the control endpoint
- * per section 7.2.1 of the HID specification, version 1.1. The first byte
- * of buffer is the report number to request, or 0x0 if the defice does not
- * use numbered reports. The report_type parameter can be HID_FEATURE_REPORT
- * or HID_INPUT_REPORT. This function is to be called with the minors_lock
- * mutex held. */
-static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type)
-{
- unsigned int minor = iminor(file->f_path.dentry->d_inode);
- struct hid_device *dev;
- __u8 *buf;
- int ret = 0, len;
- unsigned char report_number;
-
- dev = hidraw_table[minor]->hid;
-
- if (!dev->hid_get_raw_report) {
- ret = -ENODEV;
- goto out;
- }
-
- if (count > HID_MAX_BUFFER_SIZE) {
- printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
- task_pid_nr(current));
- ret = -EINVAL;
- goto out;
- }
-
- if (count < 2) {
- printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
- task_pid_nr(current));
- ret = -EINVAL;
- goto out;
- }
-
- buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
- if (!buf) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* Read the first byte from the user. This is the report number,
- * which is passed to dev->hid_get_raw_report(). */
- if (copy_from_user(&report_number, buffer, 1)) {
- ret = -EFAULT;
- goto out_free;
- }
-
- ret = dev->hid_get_raw_report(dev, report_number, buf, count, report_type);
-
- if (ret < 0)
- goto out_free;
-
- len = (ret < count) ? ret : count;
-
- if (copy_to_user(buffer, buf, len)) {
- ret = -EFAULT;
- goto out_free;
- }
-
- ret = len;
-
-out_free:
- kfree(buf);
-out:
- return ret;
-}
-
-static unsigned int hidraw_poll(struct file *file, poll_table *wait)
-{
- struct hidraw_list *list = file->private_data;
-
- poll_wait(file, &list->hidraw->wait, wait);
- if (list->head != list->tail)
- return POLLIN | POLLRDNORM;
- if (!list->hidraw->exist)
- return POLLERR | POLLHUP;
- return 0;
-}
-
-static int hidraw_open(struct inode *inode, struct file *file)
-{
- unsigned int minor = iminor(inode);
- struct hidraw *dev;
- struct hidraw_list *list;
- int err = 0;
-
- if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) {
- err = -ENOMEM;
- goto out;
- }
-
- mutex_lock(&minors_lock);
- if (!hidraw_table[minor]) {
- err = -ENODEV;
- goto out_unlock;
- }
-
- list->hidraw = hidraw_table[minor];
- mutex_init(&list->read_mutex);
- list_add_tail(&list->node, &hidraw_table[minor]->list);
- file->private_data = list;
-
- dev = hidraw_table[minor];
- if (!dev->open++) {
- err = hid_hw_power(dev->hid, PM_HINT_FULLON);
- if (err < 0) {
- dev->open--;
- goto out_unlock;
- }
-
- err = hid_hw_open(dev->hid);
- if (err < 0) {
- hid_hw_power(dev->hid, PM_HINT_NORMAL);
- dev->open--;
- }
- }
-
-out_unlock:
- mutex_unlock(&minors_lock);
-out:
- if (err < 0)
- kfree(list);
- return err;
-
-}
-
-static int hidraw_release(struct inode * inode, struct file * file)
-{
- unsigned int minor = iminor(inode);
- struct hidraw *dev;
- struct hidraw_list *list = file->private_data;
- int ret;
-
- mutex_lock(&minors_lock);
- if (!hidraw_table[minor]) {
- ret = -ENODEV;
- goto unlock;
- }
-
- list_del(&list->node);
- dev = hidraw_table[minor];
- if (!--dev->open) {
- if (list->hidraw->exist) {
- hid_hw_power(dev->hid, PM_HINT_NORMAL);
- hid_hw_close(dev->hid);
- } else {
- kfree(list->hidraw);
- }
- }
- kfree(list);
- ret = 0;
-unlock:
- mutex_unlock(&minors_lock);
-
- return ret;
-}
-
-static long hidraw_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct inode *inode = file->f_path.dentry->d_inode;
- unsigned int minor = iminor(inode);
- long ret = 0;
- struct hidraw *dev;
- void __user *user_arg = (void __user*) arg;
-
- mutex_lock(&minors_lock);
- dev = hidraw_table[minor];
- if (!dev) {
- ret = -ENODEV;
- goto out;
- }
-
- switch (cmd) {
- case HIDIOCGRDESCSIZE:
- if (put_user(dev->hid->rsize, (int __user *)arg))
- ret = -EFAULT;
- break;
-
- case HIDIOCGRDESC:
- {
- __u32 len;
-
- if (get_user(len, (int __user *)arg))
- ret = -EFAULT;
- else if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
- ret = -EINVAL;
- else if (copy_to_user(user_arg + offsetof(
- struct hidraw_report_descriptor,
- value[0]),
- dev->hid->rdesc,
- min(dev->hid->rsize, len)))
- ret = -EFAULT;
- break;
- }
- case HIDIOCGRAWINFO:
- {
- struct hidraw_devinfo dinfo;
-
- dinfo.bustype = dev->hid->bus;
- dinfo.vendor = dev->hid->vendor;
- dinfo.product = dev->hid->product;
- if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
- ret = -EFAULT;
- break;
- }
- default:
- {
- struct hid_device *hid = dev->hid;
- if (_IOC_TYPE(cmd) != 'H') {
- ret = -EINVAL;
- break;
- }
-
- if (_IOC_NR(cmd) == _IOC_NR(HIDIOCSFEATURE(0))) {
- int len = _IOC_SIZE(cmd);
- ret = hidraw_send_report(file, user_arg, len, HID_FEATURE_REPORT);
- break;
- }
- if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGFEATURE(0))) {
- int len = _IOC_SIZE(cmd);
- ret = hidraw_get_report(file, user_arg, len, HID_FEATURE_REPORT);
- break;
- }
-
- /* Begin Read-only ioctls. */
- if (_IOC_DIR(cmd) != _IOC_READ) {
- ret = -EINVAL;
- break;
- }
-
- if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
- int len = strlen(hid->name) + 1;
- if (len > _IOC_SIZE(cmd))
- len = _IOC_SIZE(cmd);
- ret = copy_to_user(user_arg, hid->name, len) ?
- -EFAULT : len;
- break;
- }
-
- if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
- int len = strlen(hid->phys) + 1;
- if (len > _IOC_SIZE(cmd))
- len = _IOC_SIZE(cmd);
- ret = copy_to_user(user_arg, hid->phys, len) ?
- -EFAULT : len;
- break;
- }
- }
-
- ret = -ENOTTY;
- }
-out:
- mutex_unlock(&minors_lock);
- return ret;
-}
-
-static const struct file_operations hidraw_ops = {
- .owner = THIS_MODULE,
- .read = hidraw_read,
- .write = hidraw_write,
- .poll = hidraw_poll,
- .open = hidraw_open,
- .release = hidraw_release,
- .unlocked_ioctl = hidraw_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = hidraw_ioctl,
-#endif
- .llseek = noop_llseek,
-};
-
-void hidraw_report_event(struct hid_device *hid, u8 *data, int len)
-{
- struct hidraw *dev = hid->hidraw;
- struct hidraw_list *list;
-
- list_for_each_entry(list, &dev->list, node) {
- list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC);
- list->buffer[list->head].len = len;
- list->head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);
- kill_fasync(&list->fasync, SIGIO, POLL_IN);
- }
-
- wake_up_interruptible(&dev->wait);
-}
-EXPORT_SYMBOL_GPL(hidraw_report_event);
-
-int hidraw_connect(struct hid_device *hid)
-{
- int minor, result;
- struct hidraw *dev;
-
- /* we accept any HID device, no matter the applications */
-
- dev = kzalloc(sizeof(struct hidraw), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- result = -EINVAL;
-
- mutex_lock(&minors_lock);
-
- for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) {
- if (hidraw_table[minor])
- continue;
- hidraw_table[minor] = dev;
- result = 0;
- break;
- }
-
- if (result) {
- mutex_unlock(&minors_lock);
- kfree(dev);
- goto out;
- }
-
- dev->dev = device_create(hidraw_class, &hid->dev, MKDEV(hidraw_major, minor),
- NULL, "%s%d", "hidraw", minor);
-
- if (IS_ERR(dev->dev)) {
- hidraw_table[minor] = NULL;
- mutex_unlock(&minors_lock);
- result = PTR_ERR(dev->dev);
- kfree(dev);
- goto out;
- }
-
- mutex_unlock(&minors_lock);
- init_waitqueue_head(&dev->wait);
- INIT_LIST_HEAD(&dev->list);
-
- dev->hid = hid;
- dev->minor = minor;
-
- dev->exist = 1;
- hid->hidraw = dev;
-
-out:
- return result;
-
-}
-EXPORT_SYMBOL_GPL(hidraw_connect);
-
-void hidraw_disconnect(struct hid_device *hid)
-{
- struct hidraw *hidraw = hid->hidraw;
-
- mutex_lock(&minors_lock);
- hidraw->exist = 0;
-
- device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
-
- hidraw_table[hidraw->minor] = NULL;
-
- if (hidraw->open) {
- hid_hw_close(hid);
- wake_up_interruptible(&hidraw->wait);
- } else {
- kfree(hidraw);
- }
- mutex_unlock(&minors_lock);
-}
-EXPORT_SYMBOL_GPL(hidraw_disconnect);
-
-int __init hidraw_init(void)
-{
- int result;
- dev_t dev_id;
-
- result = alloc_chrdev_region(&dev_id, HIDRAW_FIRST_MINOR,
- HIDRAW_MAX_DEVICES, "hidraw");
-
- hidraw_major = MAJOR(dev_id);
-
- if (result < 0) {
- pr_warn("can't get major number\n");
- result = 0;
- goto out;
- }
-
- hidraw_class = class_create(THIS_MODULE, "hidraw");
- if (IS_ERR(hidraw_class)) {
- result = PTR_ERR(hidraw_class);
- unregister_chrdev(hidraw_major, "hidraw");
- goto out;
- }
-
- cdev_init(&hidraw_cdev, &hidraw_ops);
- cdev_add(&hidraw_cdev, dev_id, HIDRAW_MAX_DEVICES);
-out:
- return result;
-}
-
-void hidraw_exit(void)
-{
- dev_t dev_id = MKDEV(hidraw_major, 0);
-
- cdev_del(&hidraw_cdev);
- class_destroy(hidraw_class);
- unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
-
-}
diff --git a/ANDROID_3.4.5/drivers/hid/uhid.c b/ANDROID_3.4.5/drivers/hid/uhid.c
deleted file mode 100644
index 714cd8cc..00000000
--- a/ANDROID_3.4.5/drivers/hid/uhid.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * User-space I/O driver support for HID subsystem
- * Copyright (c) 2012 David Herrmann
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/atomic.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/poll.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/uhid.h>
-#include <linux/wait.h>
-
-#define UHID_NAME "uhid"
-#define UHID_BUFSIZE 32
-
-struct uhid_device {
- struct mutex devlock;
- bool running;
-
- __u8 *rd_data;
- uint rd_size;
-
- struct hid_device *hid;
- struct uhid_event input_buf;
-
- wait_queue_head_t waitq;
- spinlock_t qlock;
- __u8 head;
- __u8 tail;
- struct uhid_event *outq[UHID_BUFSIZE];
-
- struct mutex report_lock;
- wait_queue_head_t report_wait;
- atomic_t report_done;
- atomic_t report_id;
- struct uhid_event report_buf;
-};
-
-static struct miscdevice uhid_misc;
-
-static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev)
-{
- __u8 newhead;
-
- newhead = (uhid->head + 1) % UHID_BUFSIZE;
-
- if (newhead != uhid->tail) {
- uhid->outq[uhid->head] = ev;
- uhid->head = newhead;
- wake_up_interruptible(&uhid->waitq);
- } else {
- hid_warn(uhid->hid, "Output queue is full\n");
- kfree(ev);
- }
-}
-
-static int uhid_queue_event(struct uhid_device *uhid, __u32 event)
-{
- unsigned long flags;
- struct uhid_event *ev;
-
- ev = kzalloc(sizeof(*ev), GFP_KERNEL);
- if (!ev)
- return -ENOMEM;
-
- ev->type = event;
-
- spin_lock_irqsave(&uhid->qlock, flags);
- uhid_queue(uhid, ev);
- spin_unlock_irqrestore(&uhid->qlock, flags);
-
- return 0;
-}
-
-static int uhid_hid_start(struct hid_device *hid)
-{
- struct uhid_device *uhid = hid->driver_data;
-
- return uhid_queue_event(uhid, UHID_START);
-}
-
-static void uhid_hid_stop(struct hid_device *hid)
-{
- struct uhid_device *uhid = hid->driver_data;
-
- hid->claimed = 0;
- uhid_queue_event(uhid, UHID_STOP);
-}
-
-static int uhid_hid_open(struct hid_device *hid)
-{
- struct uhid_device *uhid = hid->driver_data;
-
- return uhid_queue_event(uhid, UHID_OPEN);
-}
-
-static void uhid_hid_close(struct hid_device *hid)
-{
- struct uhid_device *uhid = hid->driver_data;
-
- uhid_queue_event(uhid, UHID_CLOSE);
-}
-
-static int uhid_hid_input(struct input_dev *input, unsigned int type,
- unsigned int code, int value)
-{
- struct hid_device *hid = input_get_drvdata(input);
- struct uhid_device *uhid = hid->driver_data;
- unsigned long flags;
- struct uhid_event *ev;
-
- ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
- if (!ev)
- return -ENOMEM;
-
- ev->type = UHID_OUTPUT_EV;
- ev->u.output_ev.type = type;
- ev->u.output_ev.code = code;
- ev->u.output_ev.value = value;
-
- spin_lock_irqsave(&uhid->qlock, flags);
- uhid_queue(uhid, ev);
- spin_unlock_irqrestore(&uhid->qlock, flags);
-
- return 0;
-}
-
-static int uhid_hid_parse(struct hid_device *hid)
-{
- struct uhid_device *uhid = hid->driver_data;
-
- return hid_parse_report(hid, uhid->rd_data, uhid->rd_size);
-}
-
-static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum,
- __u8 *buf, size_t count, unsigned char rtype)
-{
- struct uhid_device *uhid = hid->driver_data;
- __u8 report_type;
- struct uhid_event *ev;
- unsigned long flags;
- int ret;
- size_t uninitialized_var(len);
- struct uhid_feature_answer_req *req;
-
- if (!uhid->running)
- return -EIO;
-
- switch (rtype) {
- case HID_FEATURE_REPORT:
- report_type = UHID_FEATURE_REPORT;
- break;
- case HID_OUTPUT_REPORT:
- report_type = UHID_OUTPUT_REPORT;
- break;
- case HID_INPUT_REPORT:
- report_type = UHID_INPUT_REPORT;
- break;
- default:
- return -EINVAL;
- }
-
- ret = mutex_lock_interruptible(&uhid->report_lock);
- if (ret)
- return ret;
-
- ev = kzalloc(sizeof(*ev), GFP_KERNEL);
- if (!ev) {
- ret = -ENOMEM;
- goto unlock;
- }
-
- spin_lock_irqsave(&uhid->qlock, flags);
- ev->type = UHID_FEATURE;
- ev->u.feature.id = atomic_inc_return(&uhid->report_id);
- ev->u.feature.rnum = rnum;
- ev->u.feature.rtype = report_type;
-
- atomic_set(&uhid->report_done, 0);
- uhid_queue(uhid, ev);
- spin_unlock_irqrestore(&uhid->qlock, flags);
-
- ret = wait_event_interruptible_timeout(uhid->report_wait,
- atomic_read(&uhid->report_done), 5 * HZ);
-
- /*
- * Make sure "uhid->running" is cleared on shutdown before
- * "uhid->report_done" is set.
- */
- smp_rmb();
- if (!ret || !uhid->running) {
- ret = -EIO;
- } else if (ret < 0) {
- ret = -ERESTARTSYS;
- } else {
- spin_lock_irqsave(&uhid->qlock, flags);
- req = &uhid->report_buf.u.feature_answer;
-
- if (req->err) {
- ret = -EIO;
- } else {
- ret = 0;
- len = min(count,
- min_t(size_t, req->size, UHID_DATA_MAX));
- memcpy(buf, req->data, len);
- }
-
- spin_unlock_irqrestore(&uhid->qlock, flags);
- }
-
- atomic_set(&uhid->report_done, 1);
-
-unlock:
- mutex_unlock(&uhid->report_lock);
- return ret ? ret : len;
-}
-
-static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count,
- unsigned char report_type)
-{
- struct uhid_device *uhid = hid->driver_data;
- __u8 rtype;
- unsigned long flags;
- struct uhid_event *ev;
-
- switch (report_type) {
- case HID_FEATURE_REPORT:
- rtype = UHID_FEATURE_REPORT;
- break;
- case HID_OUTPUT_REPORT:
- rtype = UHID_OUTPUT_REPORT;
- break;
- default:
- return -EINVAL;
- }
-
- if (count < 1 || count > UHID_DATA_MAX)
- return -EINVAL;
-
- ev = kzalloc(sizeof(*ev), GFP_KERNEL);
- if (!ev)
- return -ENOMEM;
-
- ev->type = UHID_OUTPUT;
- ev->u.output.size = count;
- ev->u.output.rtype = rtype;
- memcpy(ev->u.output.data, buf, count);
-
- spin_lock_irqsave(&uhid->qlock, flags);
- uhid_queue(uhid, ev);
- spin_unlock_irqrestore(&uhid->qlock, flags);
-
- return count;
-}
-
-static struct hid_ll_driver uhid_hid_driver = {
- .start = uhid_hid_start,
- .stop = uhid_hid_stop,
- .open = uhid_hid_open,
- .close = uhid_hid_close,
- .hidinput_input_event = uhid_hid_input,
- .parse = uhid_hid_parse,
-};
-
-static int uhid_dev_create(struct uhid_device *uhid,
- const struct uhid_event *ev)
-{
- struct hid_device *hid;
- int ret;
-
- if (uhid->running)
- return -EALREADY;
-
- uhid->rd_size = ev->u.create.rd_size;
- if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE)
- return -EINVAL;
-
- uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL);
- if (!uhid->rd_data)
- return -ENOMEM;
-
- if (copy_from_user(uhid->rd_data, ev->u.create.rd_data,
- uhid->rd_size)) {
- ret = -EFAULT;
- goto err_free;
- }
-
- hid = hid_allocate_device();
- if (IS_ERR(hid)) {
- ret = PTR_ERR(hid);
- goto err_free;
- }
-
- strncpy(hid->name, ev->u.create.name, 127);
- hid->name[127] = 0;
- strncpy(hid->phys, ev->u.create.phys, 63);
- hid->phys[63] = 0;
- strncpy(hid->uniq, ev->u.create.uniq, 63);
- hid->uniq[63] = 0;
-
- hid->ll_driver = &uhid_hid_driver;
- hid->hid_get_raw_report = uhid_hid_get_raw;
- hid->hid_output_raw_report = uhid_hid_output_raw;
- hid->bus = ev->u.create.bus;
- hid->vendor = ev->u.create.vendor;
- hid->product = ev->u.create.product;
- hid->version = ev->u.create.version;
- hid->country = ev->u.create.country;
- hid->driver_data = uhid;
- hid->dev.parent = uhid_misc.this_device;
-
- uhid->hid = hid;
- uhid->running = true;
-
- ret = hid_add_device(hid);
- if (ret) {
- hid_err(hid, "Cannot register HID device\n");
- goto err_hid;
- }
-
- return 0;
-
-err_hid:
- hid_destroy_device(hid);
- uhid->hid = NULL;
- uhid->running = false;
-err_free:
- kfree(uhid->rd_data);
- return ret;
-}
-
-static int uhid_dev_destroy(struct uhid_device *uhid)
-{
- if (!uhid->running)
- return -EINVAL;
-
- /* clear "running" before setting "report_done" */
- uhid->running = false;
- smp_wmb();
- atomic_set(&uhid->report_done, 1);
- wake_up_interruptible(&uhid->report_wait);
-
- hid_destroy_device(uhid->hid);
- kfree(uhid->rd_data);
-
- return 0;
-}
-
-static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev)
-{
- if (!uhid->running)
- return -EINVAL;
-
- hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data,
- min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0);
-
- return 0;
-}
-
-static int uhid_dev_feature_answer(struct uhid_device *uhid,
- struct uhid_event *ev)
-{
- unsigned long flags;
-
- if (!uhid->running)
- return -EINVAL;
-
- spin_lock_irqsave(&uhid->qlock, flags);
-
- /* id for old report; drop it silently */
- if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id)
- goto unlock;
- if (atomic_read(&uhid->report_done))
- goto unlock;
-
- memcpy(&uhid->report_buf, ev, sizeof(*ev));
- atomic_set(&uhid->report_done, 1);
- wake_up_interruptible(&uhid->report_wait);
-
-unlock:
- spin_unlock_irqrestore(&uhid->qlock, flags);
- return 0;
-}
-
-static int uhid_char_open(struct inode *inode, struct file *file)
-{
- struct uhid_device *uhid;
-
- uhid = kzalloc(sizeof(*uhid), GFP_KERNEL);
- if (!uhid)
- return -ENOMEM;
-
- mutex_init(&uhid->devlock);
- mutex_init(&uhid->report_lock);
- spin_lock_init(&uhid->qlock);
- init_waitqueue_head(&uhid->waitq);
- init_waitqueue_head(&uhid->report_wait);
- uhid->running = false;
- atomic_set(&uhid->report_done, 1);
-
- file->private_data = uhid;
- nonseekable_open(inode, file);
-
- return 0;
-}
-
-static int uhid_char_release(struct inode *inode, struct file *file)
-{
- struct uhid_device *uhid = file->private_data;
- unsigned int i;
-
- uhid_dev_destroy(uhid);
-
- for (i = 0; i < UHID_BUFSIZE; ++i)
- kfree(uhid->outq[i]);
-
- kfree(uhid);
-
- return 0;
-}
-
-static ssize_t uhid_char_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct uhid_device *uhid = file->private_data;
- int ret;
- unsigned long flags;
- size_t len;
-
- /* they need at least the "type" member of uhid_event */
- if (count < sizeof(__u32))
- return -EINVAL;
-
-try_again:
- if (file->f_flags & O_NONBLOCK) {
- if (uhid->head == uhid->tail)
- return -EAGAIN;
- } else {
- ret = wait_event_interruptible(uhid->waitq,
- uhid->head != uhid->tail);
- if (ret)
- return ret;
- }
-
- ret = mutex_lock_interruptible(&uhid->devlock);
- if (ret)
- return ret;
-
- if (uhid->head == uhid->tail) {
- mutex_unlock(&uhid->devlock);
- goto try_again;
- } else {
- len = min(count, sizeof(**uhid->outq));
- if (copy_to_user(buffer, uhid->outq[uhid->tail], len)) {
- ret = -EFAULT;
- } else {
- kfree(uhid->outq[uhid->tail]);
- uhid->outq[uhid->tail] = NULL;
-
- spin_lock_irqsave(&uhid->qlock, flags);
- uhid->tail = (uhid->tail + 1) % UHID_BUFSIZE;
- spin_unlock_irqrestore(&uhid->qlock, flags);
- }
- }
-
- mutex_unlock(&uhid->devlock);
- return ret ? ret : len;
-}
-
-static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct uhid_device *uhid = file->private_data;
- int ret;
- size_t len;
-
- /* we need at least the "type" member of uhid_event */
- if (count < sizeof(__u32))
- return -EINVAL;
-
- ret = mutex_lock_interruptible(&uhid->devlock);
- if (ret)
- return ret;
-
- memset(&uhid->input_buf, 0, sizeof(uhid->input_buf));
- len = min(count, sizeof(uhid->input_buf));
- if (copy_from_user(&uhid->input_buf, buffer, len)) {
- ret = -EFAULT;
- goto unlock;
- }
-
- switch (uhid->input_buf.type) {
- case UHID_CREATE:
- ret = uhid_dev_create(uhid, &uhid->input_buf);
- break;
- case UHID_DESTROY:
- ret = uhid_dev_destroy(uhid);
- break;
- case UHID_INPUT:
- ret = uhid_dev_input(uhid, &uhid->input_buf);
- break;
- case UHID_FEATURE_ANSWER:
- ret = uhid_dev_feature_answer(uhid, &uhid->input_buf);
- break;
- default:
- ret = -EOPNOTSUPP;
- }
-
-unlock:
- mutex_unlock(&uhid->devlock);
-
- /* return "count" not "len" to not confuse the caller */
- return ret ? ret : count;
-}
-
-static unsigned int uhid_char_poll(struct file *file, poll_table *wait)
-{
- struct uhid_device *uhid = file->private_data;
-
- poll_wait(file, &uhid->waitq, wait);
-
- if (uhid->head != uhid->tail)
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-static const struct file_operations uhid_fops = {
- .owner = THIS_MODULE,
- .open = uhid_char_open,
- .release = uhid_char_release,
- .read = uhid_char_read,
- .write = uhid_char_write,
- .poll = uhid_char_poll,
- .llseek = no_llseek,
-};
-
-static struct miscdevice uhid_misc = {
- .fops = &uhid_fops,
- .minor = MISC_DYNAMIC_MINOR,
- .name = UHID_NAME,
-};
-
-static int __init uhid_init(void)
-{
- return misc_register(&uhid_misc);
-}
-
-static void __exit uhid_exit(void)
-{
- misc_deregister(&uhid_misc);
-}
-
-module_init(uhid_init);
-module_exit(uhid_exit);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
-MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/Kconfig b/ANDROID_3.4.5/drivers/hid/usbhid/Kconfig
deleted file mode 100644
index 0f20fd17..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/Kconfig
+++ /dev/null
@@ -1,84 +0,0 @@
-comment "USB Input Devices"
- depends on USB
-
-config USB_HID
- tristate "USB Human Interface Device (full HID) support"
- default y
- depends on USB && INPUT
- select HID
- ---help---
- Say Y here if you want full HID support to connect USB keyboards,
- mice, joysticks, graphic tablets, or any other HID based devices
- to your computer via USB, as well as Uninterruptible Power Supply
- (UPS) and monitor control devices.
-
- You can't use this driver and the HIDBP (Boot Protocol) keyboard
- and mouse drivers at the same time. More information is available:
- <file:Documentation/input/input.txt>.
-
- If unsure, say Y.
-
- To compile this driver as a module, choose M here: the
- module will be called usbhid.
-
-comment "Input core support is needed for USB HID input layer or HIDBP support"
- depends on USB_HID && INPUT=n
-
-config HID_PID
- bool "PID device support"
- help
- Say Y here if you have a PID-compliant device and wish to enable force
- feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
- devices.
-
-config USB_HIDDEV
- bool "/dev/hiddev raw HID device support"
- depends on USB_HID
- help
- Say Y here if you want to support HID devices (from the USB
- specification standpoint) that aren't strictly user interface
- devices, like monitor controls and Uninterruptable Power Supplies.
-
- This module supports these devices separately using a separate
- event interface on /dev/usb/hiddevX (char 180:96 to 180:111).
-
- If unsure, say Y.
-
-menu "USB HID Boot Protocol drivers"
- depends on USB!=n && USB_HID!=y && EXPERT
-
-config USB_KBD
- tristate "USB HIDBP Keyboard (simple Boot) support"
- depends on USB && INPUT
- ---help---
- Say Y here only if you are absolutely sure that you don't want
- to use the generic HID driver for your USB keyboard and prefer
- to use the keyboard in its limited Boot Protocol mode instead.
-
- This is almost certainly not what you want. This is mostly
- useful for embedded applications or simple keyboards.
-
- To compile this driver as a module, choose M here: the
- module will be called usbkbd.
-
- If even remotely unsure, say N.
-
-config USB_MOUSE
- tristate "USB HIDBP Mouse (simple Boot) support"
- depends on USB && INPUT
- ---help---
- Say Y here only if you are absolutely sure that you don't want
- to use the generic HID driver for your USB mouse and prefer
- to use the mouse in its limited Boot Protocol mode instead.
-
- This is almost certainly not what you want. This is mostly
- useful for embedded applications or simple mice.
-
- To compile this driver as a module, choose M here: the
- module will be called usbmouse.
-
- If even remotely unsure, say N.
-
-endmenu
-
-
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/Makefile b/ANDROID_3.4.5/drivers/hid/usbhid/Makefile
deleted file mode 100644
index db3cf31c..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Makefile for the USB input drivers
-#
-
-# Multipart objects.
-usbhid-y := hid-core.o hid-quirks.o
-
-# Optional parts of multipart objects.
-
-ifeq ($(CONFIG_USB_HIDDEV),y)
- usbhid-y += hiddev.o
-endif
-ifeq ($(CONFIG_HID_PID),y)
- usbhid-y += hid-pidff.o
-endif
-
-obj-$(CONFIG_USB_HID) += usbhid.o
-obj-$(CONFIG_USB_KBD) += usbkbd.o
-obj-$(CONFIG_USB_MOUSE) += usbmouse.o
-
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/hid-core.c b/ANDROID_3.4.5/drivers/hid/usbhid/hid-core.c
deleted file mode 100644
index 4bbb883a..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/hid-core.c
+++ /dev/null
@@ -1,1609 +0,0 @@
-/*
- * USB HID support for Linux
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2007-2008 Oliver Neukum
- * Copyright (c) 2006-2010 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
-#include <asm/unaligned.h>
-#include <asm/byteorder.h>
-#include <linux/input.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-
-#include <linux/usb.h>
-
-#include <linux/hid.h>
-#include <linux/hiddev.h>
-#include <linux/hid-debug.h>
-#include <linux/hidraw.h>
-#include "usbhid.h"
-
-/*
- * Version Information
- */
-
-#define DRIVER_DESC "USB HID core driver"
-#define DRIVER_LICENSE "GPL"
-
-/*
- * Module parameters.
- */
-
-static unsigned int hid_mousepoll_interval;
-module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
-MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
-
-static unsigned int ignoreled;
-module_param_named(ignoreled, ignoreled, uint, 0644);
-MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
-
-/* Quirks specified at module load time */
-static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
-module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
-MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
- " quirks=vendorID:productID:quirks"
- " where vendorID, productID, and quirks are all in"
- " 0x-prefixed hex");
-/*
- * Input submission and I/O error handler.
- */
-static DEFINE_MUTEX(hid_open_mut);
-
-static void hid_io_error(struct hid_device *hid);
-static int hid_submit_out(struct hid_device *hid);
-static int hid_submit_ctrl(struct hid_device *hid);
-static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid);
-
-/* Start up the input URB */
-static int hid_start_in(struct hid_device *hid)
-{
- unsigned long flags;
- int rc = 0;
- struct usbhid_device *usbhid = hid->driver_data;
-
- spin_lock_irqsave(&usbhid->lock, flags);
- if (hid->open > 0 &&
- !test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
- !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) &&
- !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
- rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
- if (rc != 0)
- clear_bit(HID_IN_RUNNING, &usbhid->iofl);
- }
- spin_unlock_irqrestore(&usbhid->lock, flags);
- return rc;
-}
-
-/* I/O retry timer routine */
-static void hid_retry_timeout(unsigned long _hid)
-{
- struct hid_device *hid = (struct hid_device *) _hid;
- struct usbhid_device *usbhid = hid->driver_data;
-
- dev_dbg(&usbhid->intf->dev, "retrying intr urb\n");
- if (hid_start_in(hid))
- hid_io_error(hid);
-}
-
-/* Workqueue routine to reset the device or clear a halt */
-static void hid_reset(struct work_struct *work)
-{
- struct usbhid_device *usbhid =
- container_of(work, struct usbhid_device, reset_work);
- struct hid_device *hid = usbhid->hid;
- int rc = 0;
-
- if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) {
- dev_dbg(&usbhid->intf->dev, "clear halt\n");
- rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe);
- clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
- hid_start_in(hid);
- }
-
- else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {
- dev_dbg(&usbhid->intf->dev, "resetting device\n");
- rc = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf);
- if (rc == 0) {
- rc = usb_reset_device(hid_to_usb_dev(hid));
- usb_unlock_device(hid_to_usb_dev(hid));
- }
- clear_bit(HID_RESET_PENDING, &usbhid->iofl);
- }
-
- switch (rc) {
- case 0:
- if (!test_bit(HID_IN_RUNNING, &usbhid->iofl))
- hid_io_error(hid);
- break;
- default:
- hid_err(hid, "can't reset device, %s-%s/input%d, status %d\n",
- hid_to_usb_dev(hid)->bus->bus_name,
- hid_to_usb_dev(hid)->devpath,
- usbhid->ifnum, rc);
- /* FALLTHROUGH */
- case -EHOSTUNREACH:
- case -ENODEV:
- case -EINTR:
- break;
- }
-}
-
-/* Main I/O error handler */
-static void hid_io_error(struct hid_device *hid)
-{
- unsigned long flags;
- struct usbhid_device *usbhid = hid->driver_data;
-
- spin_lock_irqsave(&usbhid->lock, flags);
-
- /* Stop when disconnected */
- if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
- goto done;
-
- /* If it has been a while since the last error, we'll assume
- * this a brand new error and reset the retry timeout. */
- if (time_after(jiffies, usbhid->stop_retry + HZ/2))
- usbhid->retry_delay = 0;
-
- /* When an error occurs, retry at increasing intervals */
- if (usbhid->retry_delay == 0) {
- usbhid->retry_delay = 13; /* Then 26, 52, 104, 104, ... */
- usbhid->stop_retry = jiffies + msecs_to_jiffies(1000);
- } else if (usbhid->retry_delay < 100)
- usbhid->retry_delay *= 2;
-
- if (time_after(jiffies, usbhid->stop_retry)) {
-
- /* Retries failed, so do a port reset */
- if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) {
- schedule_work(&usbhid->reset_work);
- goto done;
- }
- }
-
- mod_timer(&usbhid->io_retry,
- jiffies + msecs_to_jiffies(usbhid->retry_delay));
-done:
- spin_unlock_irqrestore(&usbhid->lock, flags);
-}
-
-static void usbhid_mark_busy(struct usbhid_device *usbhid)
-{
- struct usb_interface *intf = usbhid->intf;
-
- usb_mark_last_busy(interface_to_usbdev(intf));
-}
-
-static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
-{
- struct hid_device *hid = usb_get_intfdata(usbhid->intf);
- int kicked;
- int r;
-
- if (!hid)
- return 0;
-
- if ((kicked = (usbhid->outhead != usbhid->outtail))) {
- dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
-
- r = usb_autopm_get_interface_async(usbhid->intf);
- if (r < 0)
- return r;
- /* Asynchronously flush queue. */
- set_bit(HID_OUT_RUNNING, &usbhid->iofl);
- if (hid_submit_out(hid)) {
- clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
- usb_autopm_put_interface_async(usbhid->intf);
- }
- wake_up(&usbhid->wait);
- }
- return kicked;
-}
-
-static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
-{
- struct hid_device *hid = usb_get_intfdata(usbhid->intf);
- int kicked;
- int r;
-
- WARN_ON(hid == NULL);
- if (!hid)
- return 0;
-
- if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
- dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
-
- r = usb_autopm_get_interface_async(usbhid->intf);
- if (r < 0)
- return r;
- /* Asynchronously flush queue. */
- set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- if (hid_submit_ctrl(hid)) {
- clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- usb_autopm_put_interface_async(usbhid->intf);
- }
- wake_up(&usbhid->wait);
- }
- return kicked;
-}
-
-/*
- * Input interrupt completion handler.
- */
-
-static void hid_irq_in(struct urb *urb)
-{
- struct hid_device *hid = urb->context;
- struct usbhid_device *usbhid = hid->driver_data;
- int status;
-
- switch (urb->status) {
- case 0: /* success */
- usbhid_mark_busy(usbhid);
- usbhid->retry_delay = 0;
- hid_input_report(urb->context, HID_INPUT_REPORT,
- urb->transfer_buffer,
- urb->actual_length, 1);
- /*
- * autosuspend refused while keys are pressed
- * because most keyboards don't wake up when
- * a key is released
- */
- if (hid_check_keys_pressed(hid))
- set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
- else
- clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
- break;
- case -EPIPE: /* stall */
- usbhid_mark_busy(usbhid);
- clear_bit(HID_IN_RUNNING, &usbhid->iofl);
- set_bit(HID_CLEAR_HALT, &usbhid->iofl);
- schedule_work(&usbhid->reset_work);
- return;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN: /* unplug */
- clear_bit(HID_IN_RUNNING, &usbhid->iofl);
- return;
- case -EILSEQ: /* protocol error or unplug */
- case -EPROTO: /* protocol error or unplug */
- case -ETIME: /* protocol error or unplug */
- case -ETIMEDOUT: /* Should never happen, but... */
- usbhid_mark_busy(usbhid);
- clear_bit(HID_IN_RUNNING, &usbhid->iofl);
- hid_io_error(hid);
- return;
- default: /* error */
- hid_warn(urb->dev, "input irq status %d received\n",
- urb->status);
- }
-
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status) {
- clear_bit(HID_IN_RUNNING, &usbhid->iofl);
- if (status != -EPERM) {
- hid_err(hid, "can't resubmit intr, %s-%s/input%d, status %d\n",
- hid_to_usb_dev(hid)->bus->bus_name,
- hid_to_usb_dev(hid)->devpath,
- usbhid->ifnum, status);
- hid_io_error(hid);
- }
- }
-}
-
-static int hid_submit_out(struct hid_device *hid)
-{
- struct hid_report *report;
- char *raw_report;
- struct usbhid_device *usbhid = hid->driver_data;
- int r;
-
- report = usbhid->out[usbhid->outtail].report;
- raw_report = usbhid->out[usbhid->outtail].raw_report;
-
- usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) +
- 1 + (report->id > 0);
- usbhid->urbout->dev = hid_to_usb_dev(hid);
- memcpy(usbhid->outbuf, raw_report,
- usbhid->urbout->transfer_buffer_length);
- kfree(raw_report);
-
- dbg_hid("submitting out urb\n");
-
- r = usb_submit_urb(usbhid->urbout, GFP_ATOMIC);
- if (r < 0) {
- hid_err(hid, "usb_submit_urb(out) failed: %d\n", r);
- return r;
- }
- usbhid->last_out = jiffies;
- return 0;
-}
-
-static int hid_submit_ctrl(struct hid_device *hid)
-{
- struct hid_report *report;
- unsigned char dir;
- char *raw_report;
- int len, r;
- struct usbhid_device *usbhid = hid->driver_data;
-
- report = usbhid->ctrl[usbhid->ctrltail].report;
- raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
- dir = usbhid->ctrl[usbhid->ctrltail].dir;
-
- len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- if (dir == USB_DIR_OUT) {
- usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
- usbhid->urbctrl->transfer_buffer_length = len;
- memcpy(usbhid->ctrlbuf, raw_report, len);
- kfree(raw_report);
- } else {
- int maxpacket, padlen;
-
- usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
- maxpacket = usb_maxpacket(hid_to_usb_dev(hid),
- usbhid->urbctrl->pipe, 0);
- if (maxpacket > 0) {
- padlen = DIV_ROUND_UP(len, maxpacket);
- padlen *= maxpacket;
- if (padlen > usbhid->bufsize)
- padlen = usbhid->bufsize;
- } else
- padlen = 0;
- usbhid->urbctrl->transfer_buffer_length = padlen;
- }
- usbhid->urbctrl->dev = hid_to_usb_dev(hid);
-
- usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
- usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT :
- HID_REQ_GET_REPORT;
- usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) |
- report->id);
- usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
- usbhid->cr->wLength = cpu_to_le16(len);
-
- dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
- usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" :
- "Get_Report",
- usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
-
- r = usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC);
- if (r < 0) {
- hid_err(hid, "usb_submit_urb(ctrl) failed: %d\n", r);
- return r;
- }
- usbhid->last_ctrl = jiffies;
- return 0;
-}
-
-/*
- * Output interrupt completion handler.
- */
-
-static int irq_out_pump_restart(struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- if (usbhid->outhead != usbhid->outtail)
- return hid_submit_out(hid);
- else
- return -1;
-}
-
-static void hid_irq_out(struct urb *urb)
-{
- struct hid_device *hid = urb->context;
- struct usbhid_device *usbhid = hid->driver_data;
- unsigned long flags;
- int unplug = 0;
-
- switch (urb->status) {
- case 0: /* success */
- break;
- case -ESHUTDOWN: /* unplug */
- unplug = 1;
- case -EILSEQ: /* protocol error or unplug */
- case -EPROTO: /* protocol error or unplug */
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- break;
- default: /* error */
- hid_warn(urb->dev, "output irq status %d received\n",
- urb->status);
- }
-
- spin_lock_irqsave(&usbhid->lock, flags);
-
- if (unplug)
- usbhid->outtail = usbhid->outhead;
- else
- usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
-
- if (!irq_out_pump_restart(hid)) {
- /* Successfully submitted next urb in queue */
- spin_unlock_irqrestore(&usbhid->lock, flags);
- return;
- }
-
- clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->lock, flags);
- usb_autopm_put_interface_async(usbhid->intf);
- wake_up(&usbhid->wait);
-}
-
-/*
- * Control pipe completion handler.
- */
-static int ctrl_pump_restart(struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- if (usbhid->ctrlhead != usbhid->ctrltail)
- return hid_submit_ctrl(hid);
- else
- return -1;
-}
-
-static void hid_ctrl(struct urb *urb)
-{
- struct hid_device *hid = urb->context;
- struct usbhid_device *usbhid = hid->driver_data;
- int unplug = 0, status = urb->status;
-
- spin_lock(&usbhid->lock);
-
- switch (status) {
- case 0: /* success */
- if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
- hid_input_report(urb->context,
- usbhid->ctrl[usbhid->ctrltail].report->type,
- urb->transfer_buffer, urb->actual_length, 0);
- break;
- case -ESHUTDOWN: /* unplug */
- unplug = 1;
- case -EILSEQ: /* protocol error or unplug */
- case -EPROTO: /* protocol error or unplug */
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -EPIPE: /* report not available */
- break;
- default: /* error */
- hid_warn(urb->dev, "ctrl urb status %d received\n", status);
- }
-
- if (unplug)
- usbhid->ctrltail = usbhid->ctrlhead;
- else
- usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
-
- if (!ctrl_pump_restart(hid)) {
- /* Successfully submitted next urb in queue */
- spin_unlock(&usbhid->lock);
- return;
- }
-
- clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- spin_unlock(&usbhid->lock);
- usb_autopm_put_interface_async(usbhid->intf);
- wake_up(&usbhid->wait);
-}
-
-static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report,
- unsigned char dir)
-{
- int head;
- struct usbhid_device *usbhid = hid->driver_data;
- int len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
-
- if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
- return;
-
- if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
- if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
- hid_warn(hid, "output queue full\n");
- return;
- }
-
- usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
- if (!usbhid->out[usbhid->outhead].raw_report) {
- hid_warn(hid, "output queueing failed\n");
- return;
- }
- hid_output_report(report, usbhid->out[usbhid->outhead].raw_report);
- usbhid->out[usbhid->outhead].report = report;
- usbhid->outhead = head;
-
- /* Try to awake from autosuspend... */
- if (usb_autopm_get_interface_async(usbhid->intf) < 0)
- return;
-
- /*
- * But if still suspended, leave urb enqueued, don't submit.
- * Submission will occur if/when resume() drains the queue.
- */
- if (test_bit(HID_REPORTED_IDLE, &usbhid->iofl))
- return;
-
- if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) {
- if (hid_submit_out(hid)) {
- clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
- usb_autopm_put_interface_async(usbhid->intf);
- }
- wake_up(&usbhid->wait);
- } else {
- /*
- * the queue is known to run
- * but an earlier request may be stuck
- * we may need to time out
- * no race because the URB is blocked under
- * spinlock
- */
- if (time_after(jiffies, usbhid->last_out + HZ * 5)) {
- usb_block_urb(usbhid->urbout);
- /* drop lock to not deadlock if the callback is called */
- spin_unlock(&usbhid->lock);
- usb_unlink_urb(usbhid->urbout);
- spin_lock(&usbhid->lock);
- usb_unblock_urb(usbhid->urbout);
- /*
- * if the unlinking has already completed
- * the pump will have been stopped
- * it must be restarted now
- */
- if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl))
- if (!irq_out_pump_restart(hid))
- set_bit(HID_OUT_RUNNING, &usbhid->iofl);
-
-
- }
- }
- return;
- }
-
- if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
- hid_warn(hid, "control queue full\n");
- return;
- }
-
- if (dir == USB_DIR_OUT) {
- usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
- if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
- hid_warn(hid, "control queueing failed\n");
- return;
- }
- hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report);
- }
- usbhid->ctrl[usbhid->ctrlhead].report = report;
- usbhid->ctrl[usbhid->ctrlhead].dir = dir;
- usbhid->ctrlhead = head;
-
- /* Try to awake from autosuspend... */
- if (usb_autopm_get_interface_async(usbhid->intf) < 0)
- return;
-
- /*
- * If already suspended, leave urb enqueued, but don't submit.
- * Submission will occur if/when resume() drains the queue.
- */
- if (test_bit(HID_REPORTED_IDLE, &usbhid->iofl))
- return;
-
- if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) {
- if (hid_submit_ctrl(hid)) {
- clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- usb_autopm_put_interface_async(usbhid->intf);
- }
- wake_up(&usbhid->wait);
- } else {
- /*
- * the queue is known to run
- * but an earlier request may be stuck
- * we may need to time out
- * no race because the URB is blocked under
- * spinlock
- */
- if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) {
- usb_block_urb(usbhid->urbctrl);
- /* drop lock to not deadlock if the callback is called */
- spin_unlock(&usbhid->lock);
- usb_unlink_urb(usbhid->urbctrl);
- spin_lock(&usbhid->lock);
- usb_unblock_urb(usbhid->urbctrl);
- /*
- * if the unlinking has already completed
- * the pump will have been stopped
- * it must be restarted now
- */
- if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
- if (!ctrl_pump_restart(hid))
- set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- }
- }
-}
-
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
-{
- struct usbhid_device *usbhid = hid->driver_data;
- unsigned long flags;
-
- spin_lock_irqsave(&usbhid->lock, flags);
- __usbhid_submit_report(hid, report, dir);
- spin_unlock_irqrestore(&usbhid->lock, flags);
-}
-EXPORT_SYMBOL_GPL(usbhid_submit_report);
-
-/* Workqueue routine to send requests to change LEDs */
-static void hid_led(struct work_struct *work)
-{
- struct usbhid_device *usbhid =
- container_of(work, struct usbhid_device, led_work);
- struct hid_device *hid = usbhid->hid;
- struct hid_field *field;
- unsigned long flags;
-
- field = hidinput_get_led_field(hid);
- if (!field) {
- hid_warn(hid, "LED event field not found\n");
- return;
- }
-
- spin_lock_irqsave(&usbhid->lock, flags);
- if (!test_bit(HID_DISCONNECTED, &usbhid->iofl)) {
- usbhid->ledcount = hidinput_count_leds(hid);
- hid_dbg(usbhid->hid, "New ledcount = %u\n", usbhid->ledcount);
- __usbhid_submit_report(hid, field->report, USB_DIR_OUT);
- }
- spin_unlock_irqrestore(&usbhid->lock, flags);
-}
-
-static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct usbhid_device *usbhid = hid->driver_data;
- struct hid_field *field;
- unsigned long flags;
- int offset;
-
- if (type == EV_FF)
- return input_ff_event(dev, type, code, value);
-
- if (type != EV_LED)
- return -1;
-
- if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
- hid_warn(dev, "event field not found\n");
- return -1;
- }
-
- spin_lock_irqsave(&usbhid->lock, flags);
- hid_set_field(field, offset, value);
- spin_unlock_irqrestore(&usbhid->lock, flags);
-
- /*
- * Defer performing requested LED action.
- * This is more likely gather all LED changes into a single URB.
- */
- schedule_work(&usbhid->led_work);
-
- return 0;
-}
-
-int usbhid_wait_io(struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- if (!wait_event_timeout(usbhid->wait,
- (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
- !test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
- 10*HZ)) {
- dbg_hid("timeout waiting for ctrl or out queue to clear\n");
- return -1;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(usbhid_wait_io);
-
-static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle)
-{
- return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report,
- ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
-}
-
-static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
- unsigned char type, void *buf, int size)
-{
- int result, retries = 4;
-
- memset(buf, 0, size);
-
- do {
- result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
- (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT);
- retries--;
- } while (result < size && retries);
- return result;
-}
-
-int usbhid_open(struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
- int res;
-
- mutex_lock(&hid_open_mut);
- if (!hid->open++) {
- res = usb_autopm_get_interface(usbhid->intf);
- /* the device must be awake to reliably request remote wakeup */
- if (res < 0) {
- hid->open--;
- mutex_unlock(&hid_open_mut);
- return -EIO;
- }
- usbhid->intf->needs_remote_wakeup = 1;
- if (hid_start_in(hid))
- hid_io_error(hid);
-
- usb_autopm_put_interface(usbhid->intf);
- }
- mutex_unlock(&hid_open_mut);
- return 0;
-}
-
-void usbhid_close(struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- mutex_lock(&hid_open_mut);
-
- /* protecting hid->open to make sure we don't restart
- * data acquistion due to a resumption we no longer
- * care about
- */
- spin_lock_irq(&usbhid->lock);
- if (!--hid->open) {
- spin_unlock_irq(&usbhid->lock);
- hid_cancel_delayed_stuff(usbhid);
- usb_kill_urb(usbhid->urbin);
- usbhid->intf->needs_remote_wakeup = 0;
- } else {
- spin_unlock_irq(&usbhid->lock);
- }
- mutex_unlock(&hid_open_mut);
-}
-
-/*
- * Initialize all reports
- */
-
-void usbhid_init_reports(struct hid_device *hid)
-{
- struct hid_report *report;
- struct usbhid_device *usbhid = hid->driver_data;
- int err, ret;
-
- list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
- usbhid_submit_report(hid, report, USB_DIR_IN);
-
- list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
- usbhid_submit_report(hid, report, USB_DIR_IN);
-
- err = 0;
- ret = usbhid_wait_io(hid);
- while (ret) {
- err |= ret;
- if (test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
- usb_kill_urb(usbhid->urbctrl);
- if (test_bit(HID_OUT_RUNNING, &usbhid->iofl))
- usb_kill_urb(usbhid->urbout);
- ret = usbhid_wait_io(hid);
- }
-
- if (err)
- hid_warn(hid, "timeout initializing reports\n");
-}
-
-/*
- * Reset LEDs which BIOS might have left on. For now, just NumLock (0x01).
- */
-static int hid_find_field_early(struct hid_device *hid, unsigned int page,
- unsigned int hid_code, struct hid_field **pfield)
-{
- struct hid_report *report;
- struct hid_field *field;
- struct hid_usage *usage;
- int i, j;
-
- list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
- for (i = 0; i < report->maxfield; i++) {
- field = report->field[i];
- for (j = 0; j < field->maxusage; j++) {
- usage = &field->usage[j];
- if ((usage->hid & HID_USAGE_PAGE) == page &&
- (usage->hid & 0xFFFF) == hid_code) {
- *pfield = field;
- return j;
- }
- }
- }
- }
- return -1;
-}
-
-void usbhid_set_leds(struct hid_device *hid)
-{
- struct hid_field *field;
- int offset;
-
- if ((offset = hid_find_field_early(hid, HID_UP_LED, 0x01, &field)) != -1) {
- hid_set_field(field, offset, 0);
- usbhid_submit_report(hid, field->report, USB_DIR_OUT);
- }
-}
-EXPORT_SYMBOL_GPL(usbhid_set_leds);
-
-/*
- * Traverse the supplied list of reports and find the longest
- */
-static void hid_find_max_report(struct hid_device *hid, unsigned int type,
- unsigned int *max)
-{
- struct hid_report *report;
- unsigned int size;
-
- list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
- size = ((report->size - 1) >> 3) + 1 + hid->report_enum[type].numbered;
- if (*max < size)
- *max = size;
- }
-}
-
-static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- usbhid->inbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
- &usbhid->inbuf_dma);
- usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
- &usbhid->outbuf_dma);
- usbhid->cr = kmalloc(sizeof(*usbhid->cr), GFP_KERNEL);
- usbhid->ctrlbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
- &usbhid->ctrlbuf_dma);
- if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr ||
- !usbhid->ctrlbuf)
- return -1;
-
- return 0;
-}
-
-static int usbhid_get_raw_report(struct hid_device *hid,
- unsigned char report_number, __u8 *buf, size_t count,
- unsigned char report_type)
-{
- struct usbhid_device *usbhid = hid->driver_data;
- struct usb_device *dev = hid_to_usb_dev(hid);
- struct usb_interface *intf = usbhid->intf;
- struct usb_host_interface *interface = intf->cur_altsetting;
- int skipped_report_id = 0;
- int ret;
-
- /* Byte 0 is the report number. Report data starts at byte 1.*/
- buf[0] = report_number;
- if (report_number == 0x0) {
- /* Offset the return buffer by 1, so that the report ID
- will remain in byte 0. */
- buf++;
- count--;
- skipped_report_id = 1;
- }
- ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- HID_REQ_GET_REPORT,
- USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ((report_type + 1) << 8) | report_number,
- interface->desc.bInterfaceNumber, buf, count,
- USB_CTRL_SET_TIMEOUT);
-
- /* count also the report id */
- if (ret > 0 && skipped_report_id)
- ret++;
-
- return ret;
-}
-
-static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
- unsigned char report_type)
-{
- struct usbhid_device *usbhid = hid->driver_data;
- struct usb_device *dev = hid_to_usb_dev(hid);
- struct usb_interface *intf = usbhid->intf;
- struct usb_host_interface *interface = intf->cur_altsetting;
- int ret;
-
- if (usbhid->urbout && report_type != HID_FEATURE_REPORT) {
- int actual_length;
- int skipped_report_id = 0;
-
- if (buf[0] == 0x0) {
- /* Don't send the Report ID */
- buf++;
- count--;
- skipped_report_id = 1;
- }
- ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,
- buf, count, &actual_length,
- USB_CTRL_SET_TIMEOUT);
- /* return the number of bytes transferred */
- if (ret == 0) {
- ret = actual_length;
- /* count also the report id */
- if (skipped_report_id)
- ret++;
- }
- } else {
- int skipped_report_id = 0;
- int report_id = buf[0];
- if (buf[0] == 0x0) {
- /* Don't send the Report ID */
- buf++;
- count--;
- skipped_report_id = 1;
- }
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- HID_REQ_SET_REPORT,
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ((report_type + 1) << 8) | report_id,
- interface->desc.bInterfaceNumber, buf, count,
- USB_CTRL_SET_TIMEOUT);
- /* count also the report id, if this was a numbered report. */
- if (ret > 0 && skipped_report_id)
- ret++;
- }
-
- return ret;
-}
-
-static void usbhid_restart_queues(struct usbhid_device *usbhid)
-{
- if (usbhid->urbout)
- usbhid_restart_out_queue(usbhid);
- usbhid_restart_ctrl_queue(usbhid);
-}
-
-static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- usb_free_coherent(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
- usb_free_coherent(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
- kfree(usbhid->cr);
- usb_free_coherent(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
-}
-
-static int usbhid_parse(struct hid_device *hid)
-{
- struct usb_interface *intf = to_usb_interface(hid->dev.parent);
- struct usb_host_interface *interface = intf->cur_altsetting;
- struct usb_device *dev = interface_to_usbdev (intf);
- struct hid_descriptor *hdesc;
- u32 quirks = 0;
- unsigned int rsize = 0;
- char *rdesc;
- int ret, n;
-
- quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- if (quirks & HID_QUIRK_IGNORE)
- return -ENODEV;
-
- /* Many keyboards and mice don't like to be polled for reports,
- * so we will always set the HID_QUIRK_NOGET flag for them. */
- if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
- if (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD ||
- interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)
- quirks |= HID_QUIRK_NOGET;
- }
-
- if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
- (!interface->desc.bNumEndpoints ||
- usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
- dbg_hid("class descriptor not present\n");
- return -ENODEV;
- }
-
- hid->version = le16_to_cpu(hdesc->bcdHID);
- hid->country = hdesc->bCountryCode;
-
- for (n = 0; n < hdesc->bNumDescriptors; n++)
- if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
- rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
-
- if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
- dbg_hid("weird size of report descriptor (%u)\n", rsize);
- return -EINVAL;
- }
-
- if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
- dbg_hid("couldn't allocate rdesc memory\n");
- return -ENOMEM;
- }
-
- hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
-
- ret = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber,
- HID_DT_REPORT, rdesc, rsize);
- if (ret < 0) {
- dbg_hid("reading report descriptor failed\n");
- kfree(rdesc);
- goto err;
- }
-
- ret = hid_parse_report(hid, rdesc, rsize);
- kfree(rdesc);
- if (ret) {
- dbg_hid("parsing report descriptor failed\n");
- goto err;
- }
-
- hid->quirks |= quirks;
-
- return 0;
-err:
- return ret;
-}
-
-static int usbhid_start(struct hid_device *hid)
-{
- struct usb_interface *intf = to_usb_interface(hid->dev.parent);
- struct usb_host_interface *interface = intf->cur_altsetting;
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usbhid_device *usbhid = hid->driver_data;
- unsigned int n, insize = 0;
- int ret;
-
- clear_bit(HID_DISCONNECTED, &usbhid->iofl);
-
- usbhid->bufsize = HID_MIN_BUFFER_SIZE;
- hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize);
- hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize);
- hid_find_max_report(hid, HID_FEATURE_REPORT, &usbhid->bufsize);
-
- if (usbhid->bufsize > HID_MAX_BUFFER_SIZE)
- usbhid->bufsize = HID_MAX_BUFFER_SIZE;
-
- hid_find_max_report(hid, HID_INPUT_REPORT, &insize);
-
- if (insize > HID_MAX_BUFFER_SIZE)
- insize = HID_MAX_BUFFER_SIZE;
-
- if (hid_alloc_buffers(dev, hid)) {
- ret = -ENOMEM;
- goto fail;
- }
-
- for (n = 0; n < interface->desc.bNumEndpoints; n++) {
- struct usb_endpoint_descriptor *endpoint;
- int pipe;
- int interval;
-
- endpoint = &interface->endpoint[n].desc;
- if (!usb_endpoint_xfer_int(endpoint))
- continue;
-
- interval = endpoint->bInterval;
-
- /* Some vendors give fullspeed interval on highspeed devides */
- if (hid->quirks & HID_QUIRK_FULLSPEED_INTERVAL &&
- dev->speed == USB_SPEED_HIGH) {
- interval = fls(endpoint->bInterval*8);
- printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n",
- hid->name, endpoint->bInterval, interval);
- }
-
- /* Change the polling interval of mice. */
- if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
- interval = hid_mousepoll_interval;
-
- ret = -ENOMEM;
- if (usb_endpoint_dir_in(endpoint)) {
- if (usbhid->urbin)
- continue;
- if (!(usbhid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
- goto fail;
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- usb_fill_int_urb(usbhid->urbin, dev, pipe, usbhid->inbuf, insize,
- hid_irq_in, hid, interval);
- usbhid->urbin->transfer_dma = usbhid->inbuf_dma;
- usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- } else {
- if (usbhid->urbout)
- continue;
- if (!(usbhid->urbout = usb_alloc_urb(0, GFP_KERNEL)))
- goto fail;
- pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress);
- usb_fill_int_urb(usbhid->urbout, dev, pipe, usbhid->outbuf, 0,
- hid_irq_out, hid, interval);
- usbhid->urbout->transfer_dma = usbhid->outbuf_dma;
- usbhid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- }
- }
-
- usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
- if (!usbhid->urbctrl) {
- ret = -ENOMEM;
- goto fail;
- }
-
- usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr,
- usbhid->ctrlbuf, 1, hid_ctrl, hid);
- usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
- usbhid->urbctrl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
- usbhid_init_reports(hid);
-
- set_bit(HID_STARTED, &usbhid->iofl);
-
- /* Some keyboards don't work until their LEDs have been set.
- * Since BIOSes do set the LEDs, it must be safe for any device
- * that supports the keyboard boot protocol.
- * In addition, enable remote wakeup by default for all keyboard
- * devices supporting the boot protocol.
- */
- if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT &&
- interface->desc.bInterfaceProtocol ==
- USB_INTERFACE_PROTOCOL_KEYBOARD) {
- usbhid_set_leds(hid);
- device_set_wakeup_enable(&dev->dev, 1);
- }
- return 0;
-
-fail:
- usb_free_urb(usbhid->urbin);
- usb_free_urb(usbhid->urbout);
- usb_free_urb(usbhid->urbctrl);
- usbhid->urbin = NULL;
- usbhid->urbout = NULL;
- usbhid->urbctrl = NULL;
- hid_free_buffers(dev, hid);
- return ret;
-}
-
-static void usbhid_stop(struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- if (WARN_ON(!usbhid))
- return;
-
- clear_bit(HID_STARTED, &usbhid->iofl);
- spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
- set_bit(HID_DISCONNECTED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->lock);
- usb_kill_urb(usbhid->urbin);
- usb_kill_urb(usbhid->urbout);
- usb_kill_urb(usbhid->urbctrl);
-
- hid_cancel_delayed_stuff(usbhid);
-
- hid->claimed = 0;
-
- usb_free_urb(usbhid->urbin);
- usb_free_urb(usbhid->urbctrl);
- usb_free_urb(usbhid->urbout);
- usbhid->urbin = NULL; /* don't mess up next start */
- usbhid->urbctrl = NULL;
- usbhid->urbout = NULL;
-
- hid_free_buffers(hid_to_usb_dev(hid), hid);
-}
-
-static int usbhid_power(struct hid_device *hid, int lvl)
-{
- int r = 0;
-
- switch (lvl) {
- case PM_HINT_FULLON:
- r = usbhid_get_power(hid);
- break;
- case PM_HINT_NORMAL:
- usbhid_put_power(hid);
- break;
- }
- return r;
-}
-
-static struct hid_ll_driver usb_hid_driver = {
- .parse = usbhid_parse,
- .start = usbhid_start,
- .stop = usbhid_stop,
- .open = usbhid_open,
- .close = usbhid_close,
- .power = usbhid_power,
- .hidinput_input_event = usb_hidinput_input_event,
-};
-
-static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_host_interface *interface = intf->cur_altsetting;
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usbhid_device *usbhid;
- struct hid_device *hid;
- unsigned int n, has_in = 0;
- size_t len;
- int ret;
-
- dbg_hid("HID probe called for ifnum %d\n",
- intf->altsetting->desc.bInterfaceNumber);
-
- for (n = 0; n < interface->desc.bNumEndpoints; n++)
- if (usb_endpoint_is_int_in(&interface->endpoint[n].desc))
- has_in++;
- if (!has_in) {
- hid_err(intf, "couldn't find an input interrupt endpoint\n");
- return -ENODEV;
- }
-
- hid = hid_allocate_device();
- if (IS_ERR(hid))
- return PTR_ERR(hid);
-
- usb_set_intfdata(intf, hid);
- hid->ll_driver = &usb_hid_driver;
- hid->hid_get_raw_report = usbhid_get_raw_report;
- hid->hid_output_raw_report = usbhid_output_raw_report;
- hid->ff_init = hid_pidff_init;
-#ifdef CONFIG_USB_HIDDEV
- hid->hiddev_connect = hiddev_connect;
- hid->hiddev_disconnect = hiddev_disconnect;
- hid->hiddev_hid_event = hiddev_hid_event;
- hid->hiddev_report_event = hiddev_report_event;
-#endif
- hid->dev.parent = &intf->dev;
- hid->bus = BUS_USB;
- hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
- hid->product = le16_to_cpu(dev->descriptor.idProduct);
- hid->name[0] = 0;
- hid->quirks = usbhid_lookup_quirk(hid->vendor, hid->product);
- if (intf->cur_altsetting->desc.bInterfaceProtocol ==
- USB_INTERFACE_PROTOCOL_MOUSE)
- hid->type = HID_TYPE_USBMOUSE;
- else if (intf->cur_altsetting->desc.bInterfaceProtocol == 0)
- hid->type = HID_TYPE_USBNONE;
-
- if (dev->manufacturer)
- strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
-
- if (dev->product) {
- if (dev->manufacturer)
- strlcat(hid->name, " ", sizeof(hid->name));
- strlcat(hid->name, dev->product, sizeof(hid->name));
- }
-
- if (!strlen(hid->name))
- snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- usb_make_path(dev, hid->phys, sizeof(hid->phys));
- strlcat(hid->phys, "/input", sizeof(hid->phys));
- len = strlen(hid->phys);
- if (len < sizeof(hid->phys) - 1)
- snprintf(hid->phys + len, sizeof(hid->phys) - len,
- "%d", intf->altsetting[0].desc.bInterfaceNumber);
-
- if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
- hid->uniq[0] = 0;
-
- usbhid = kzalloc(sizeof(*usbhid), GFP_KERNEL);
- if (usbhid == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- hid->driver_data = usbhid;
- usbhid->hid = hid;
- usbhid->intf = intf;
- usbhid->ifnum = interface->desc.bInterfaceNumber;
-
- init_waitqueue_head(&usbhid->wait);
- INIT_WORK(&usbhid->reset_work, hid_reset);
- setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
- spin_lock_init(&usbhid->lock);
-
- INIT_WORK(&usbhid->led_work, hid_led);
-
- ret = hid_add_device(hid);
- if (ret) {
- if (ret != -ENODEV)
- hid_err(intf, "can't add hid device: %d\n", ret);
- goto err_free;
- }
-
- return 0;
-err_free:
- kfree(usbhid);
-err:
- hid_destroy_device(hid);
- return ret;
-}
-
-static void usbhid_disconnect(struct usb_interface *intf)
-{
- struct hid_device *hid = usb_get_intfdata(intf);
- struct usbhid_device *usbhid;
-
- if (WARN_ON(!hid))
- return;
-
- usbhid = hid->driver_data;
- hid_destroy_device(hid);
- kfree(usbhid);
-}
-
-static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
-{
- del_timer_sync(&usbhid->io_retry);
- cancel_work_sync(&usbhid->reset_work);
- cancel_work_sync(&usbhid->led_work);
-}
-
-static void hid_cease_io(struct usbhid_device *usbhid)
-{
- del_timer_sync(&usbhid->io_retry);
- usb_kill_urb(usbhid->urbin);
- usb_kill_urb(usbhid->urbctrl);
- usb_kill_urb(usbhid->urbout);
-}
-
-/* Treat USB reset pretty much the same as suspend/resume */
-static int hid_pre_reset(struct usb_interface *intf)
-{
- struct hid_device *hid = usb_get_intfdata(intf);
- struct usbhid_device *usbhid = hid->driver_data;
-
- spin_lock_irq(&usbhid->lock);
- set_bit(HID_RESET_PENDING, &usbhid->iofl);
- spin_unlock_irq(&usbhid->lock);
- hid_cease_io(usbhid);
-
- return 0;
-}
-
-/* Same routine used for post_reset and reset_resume */
-static int hid_post_reset(struct usb_interface *intf)
-{
- struct usb_device *dev = interface_to_usbdev (intf);
- struct hid_device *hid = usb_get_intfdata(intf);
- struct usbhid_device *usbhid = hid->driver_data;
- int status;
-
- spin_lock_irq(&usbhid->lock);
- clear_bit(HID_RESET_PENDING, &usbhid->iofl);
- spin_unlock_irq(&usbhid->lock);
- hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
- status = hid_start_in(hid);
- if (status < 0)
- hid_io_error(hid);
- usbhid_restart_queues(usbhid);
-
- return 0;
-}
-
-int usbhid_get_power(struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- return usb_autopm_get_interface(usbhid->intf);
-}
-
-void usbhid_put_power(struct hid_device *hid)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- usb_autopm_put_interface(usbhid->intf);
-}
-
-
-#ifdef CONFIG_PM
-static int hid_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct hid_device *hid = usb_get_intfdata(intf);
- struct usbhid_device *usbhid = hid->driver_data;
- int status;
-
- if (PMSG_IS_AUTO(message)) {
- spin_lock_irq(&usbhid->lock); /* Sync with error handler */
- if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
- && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
- && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
- && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
- && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
- && (!usbhid->ledcount || ignoreled))
- {
- set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
- spin_unlock_irq(&usbhid->lock);
- if (hid->driver && hid->driver->suspend) {
- status = hid->driver->suspend(hid, message);
- if (status < 0)
- return status;
- }
- } else {
- usbhid_mark_busy(usbhid);
- spin_unlock_irq(&usbhid->lock);
- return -EBUSY;
- }
-
- } else {
- if (hid->driver && hid->driver->suspend) {
- status = hid->driver->suspend(hid, message);
- if (status < 0)
- return status;
- }
- spin_lock_irq(&usbhid->lock);
- set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
- spin_unlock_irq(&usbhid->lock);
- if (usbhid_wait_io(hid) < 0)
- return -EIO;
- }
-
- hid_cancel_delayed_stuff(usbhid);
- hid_cease_io(usbhid);
-
- if (PMSG_IS_AUTO(message) && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
- /* lost race against keypresses */
- status = hid_start_in(hid);
- if (status < 0)
- hid_io_error(hid);
- usbhid_mark_busy(usbhid);
- return -EBUSY;
- }
- dev_dbg(&intf->dev, "suspend\n");
- return 0;
-}
-
-static int hid_resume(struct usb_interface *intf)
-{
- struct hid_device *hid = usb_get_intfdata (intf);
- struct usbhid_device *usbhid = hid->driver_data;
- int status;
-
- if (!test_bit(HID_STARTED, &usbhid->iofl))
- return 0;
-
- clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
- usbhid_mark_busy(usbhid);
-
- if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
- test_bit(HID_RESET_PENDING, &usbhid->iofl))
- schedule_work(&usbhid->reset_work);
- usbhid->retry_delay = 0;
- status = hid_start_in(hid);
- if (status < 0)
- hid_io_error(hid);
- usbhid_restart_queues(usbhid);
-
- if (status >= 0 && hid->driver && hid->driver->resume) {
- int ret = hid->driver->resume(hid);
- if (ret < 0)
- status = ret;
- }
- dev_dbg(&intf->dev, "resume status %d\n", status);
- return 0;
-}
-
-static int hid_reset_resume(struct usb_interface *intf)
-{
- struct hid_device *hid = usb_get_intfdata(intf);
- struct usbhid_device *usbhid = hid->driver_data;
- int status;
-
- clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
- status = hid_post_reset(intf);
- if (status >= 0 && hid->driver && hid->driver->reset_resume) {
- int ret = hid->driver->reset_resume(hid);
- if (ret < 0)
- status = ret;
- }
- return status;
-}
-
-#endif /* CONFIG_PM */
-
-static const struct usb_device_id hid_usb_ids[] = {
- { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
- .bInterfaceClass = USB_INTERFACE_CLASS_HID },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, hid_usb_ids);
-
-static struct usb_driver hid_driver = {
- .name = "usbhid",
- .probe = usbhid_probe,
- .disconnect = usbhid_disconnect,
-#ifdef CONFIG_PM
- .suspend = hid_suspend,
- .resume = hid_resume,
- .reset_resume = hid_reset_resume,
-#endif
- .pre_reset = hid_pre_reset,
- .post_reset = hid_post_reset,
- .id_table = hid_usb_ids,
- .supports_autosuspend = 1,
-};
-
-static const struct hid_device_id hid_usb_table[] = {
- { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) },
- { }
-};
-
-struct usb_interface *usbhid_find_interface(int minor)
-{
- return usb_find_interface(&hid_driver, minor);
-}
-
-static struct hid_driver hid_usb_driver = {
- .name = "generic-usb",
- .id_table = hid_usb_table,
-};
-
-static int __init hid_init(void)
-{
- int retval = -ENOMEM;
-
- retval = hid_register_driver(&hid_usb_driver);
- if (retval)
- goto hid_register_fail;
- retval = usbhid_quirks_init(quirks_param);
- if (retval)
- goto usbhid_quirks_init_fail;
- retval = usb_register(&hid_driver);
- if (retval)
- goto usb_register_fail;
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
-
- return 0;
-usb_register_fail:
- usbhid_quirks_exit();
-usbhid_quirks_init_fail:
- hid_unregister_driver(&hid_usb_driver);
-hid_register_fail:
- return retval;
-}
-
-static void __exit hid_exit(void)
-{
- usb_deregister(&hid_driver);
- usbhid_quirks_exit();
- hid_unregister_driver(&hid_usb_driver);
-}
-
-module_init(hid_init);
-module_exit(hid_exit);
-
-MODULE_AUTHOR("Andreas Gal");
-MODULE_AUTHOR("Vojtech Pavlik");
-MODULE_AUTHOR("Jiri Kosina");
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/hid-pidff.c b/ANDROID_3.4.5/drivers/hid/usbhid/hid-pidff.c
deleted file mode 100644
index f91c1368..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/hid-pidff.c
+++ /dev/null
@@ -1,1323 +0,0 @@
-/*
- * Force feedback driver for USB HID PID compliant devices
- *
- * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com>
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* #define DEBUG */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include <linux/hid.h>
-
-#include "usbhid.h"
-
-#define PID_EFFECTS_MAX 64
-
-/* Report usage table used to put reports into an array */
-
-#define PID_SET_EFFECT 0
-#define PID_EFFECT_OPERATION 1
-#define PID_DEVICE_GAIN 2
-#define PID_POOL 3
-#define PID_BLOCK_LOAD 4
-#define PID_BLOCK_FREE 5
-#define PID_DEVICE_CONTROL 6
-#define PID_CREATE_NEW_EFFECT 7
-
-#define PID_REQUIRED_REPORTS 7
-
-#define PID_SET_ENVELOPE 8
-#define PID_SET_CONDITION 9
-#define PID_SET_PERIODIC 10
-#define PID_SET_CONSTANT 11
-#define PID_SET_RAMP 12
-static const u8 pidff_reports[] = {
- 0x21, 0x77, 0x7d, 0x7f, 0x89, 0x90, 0x96, 0xab,
- 0x5a, 0x5f, 0x6e, 0x73, 0x74
-};
-
-/* device_control is really 0x95, but 0x96 specified as it is the usage of
-the only field in that report */
-
-/* Value usage tables used to put fields and values into arrays */
-
-#define PID_EFFECT_BLOCK_INDEX 0
-
-#define PID_DURATION 1
-#define PID_GAIN 2
-#define PID_TRIGGER_BUTTON 3
-#define PID_TRIGGER_REPEAT_INT 4
-#define PID_DIRECTION_ENABLE 5
-#define PID_START_DELAY 6
-static const u8 pidff_set_effect[] = {
- 0x22, 0x50, 0x52, 0x53, 0x54, 0x56, 0xa7
-};
-
-#define PID_ATTACK_LEVEL 1
-#define PID_ATTACK_TIME 2
-#define PID_FADE_LEVEL 3
-#define PID_FADE_TIME 4
-static const u8 pidff_set_envelope[] = { 0x22, 0x5b, 0x5c, 0x5d, 0x5e };
-
-#define PID_PARAM_BLOCK_OFFSET 1
-#define PID_CP_OFFSET 2
-#define PID_POS_COEFFICIENT 3
-#define PID_NEG_COEFFICIENT 4
-#define PID_POS_SATURATION 5
-#define PID_NEG_SATURATION 6
-#define PID_DEAD_BAND 7
-static const u8 pidff_set_condition[] = {
- 0x22, 0x23, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65
-};
-
-#define PID_MAGNITUDE 1
-#define PID_OFFSET 2
-#define PID_PHASE 3
-#define PID_PERIOD 4
-static const u8 pidff_set_periodic[] = { 0x22, 0x70, 0x6f, 0x71, 0x72 };
-static const u8 pidff_set_constant[] = { 0x22, 0x70 };
-
-#define PID_RAMP_START 1
-#define PID_RAMP_END 2
-static const u8 pidff_set_ramp[] = { 0x22, 0x75, 0x76 };
-
-#define PID_RAM_POOL_AVAILABLE 1
-static const u8 pidff_block_load[] = { 0x22, 0xac };
-
-#define PID_LOOP_COUNT 1
-static const u8 pidff_effect_operation[] = { 0x22, 0x7c };
-
-static const u8 pidff_block_free[] = { 0x22 };
-
-#define PID_DEVICE_GAIN_FIELD 0
-static const u8 pidff_device_gain[] = { 0x7e };
-
-#define PID_RAM_POOL_SIZE 0
-#define PID_SIMULTANEOUS_MAX 1
-#define PID_DEVICE_MANAGED_POOL 2
-static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
-
-/* Special field key tables used to put special field keys into arrays */
-
-#define PID_ENABLE_ACTUATORS 0
-#define PID_RESET 1
-static const u8 pidff_device_control[] = { 0x97, 0x9a };
-
-#define PID_CONSTANT 0
-#define PID_RAMP 1
-#define PID_SQUARE 2
-#define PID_SINE 3
-#define PID_TRIANGLE 4
-#define PID_SAW_UP 5
-#define PID_SAW_DOWN 6
-#define PID_SPRING 7
-#define PID_DAMPER 8
-#define PID_INERTIA 9
-#define PID_FRICTION 10
-static const u8 pidff_effect_types[] = {
- 0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34,
- 0x40, 0x41, 0x42, 0x43
-};
-
-#define PID_BLOCK_LOAD_SUCCESS 0
-#define PID_BLOCK_LOAD_FULL 1
-static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
-
-#define PID_EFFECT_START 0
-#define PID_EFFECT_STOP 1
-static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
-
-struct pidff_usage {
- struct hid_field *field;
- s32 *value;
-};
-
-struct pidff_device {
- struct hid_device *hid;
-
- struct hid_report *reports[sizeof(pidff_reports)];
-
- struct pidff_usage set_effect[sizeof(pidff_set_effect)];
- struct pidff_usage set_envelope[sizeof(pidff_set_envelope)];
- struct pidff_usage set_condition[sizeof(pidff_set_condition)];
- struct pidff_usage set_periodic[sizeof(pidff_set_periodic)];
- struct pidff_usage set_constant[sizeof(pidff_set_constant)];
- struct pidff_usage set_ramp[sizeof(pidff_set_ramp)];
-
- struct pidff_usage device_gain[sizeof(pidff_device_gain)];
- struct pidff_usage block_load[sizeof(pidff_block_load)];
- struct pidff_usage pool[sizeof(pidff_pool)];
- struct pidff_usage effect_operation[sizeof(pidff_effect_operation)];
- struct pidff_usage block_free[sizeof(pidff_block_free)];
-
- /* Special field is a field that is not composed of
- usage<->value pairs that pidff_usage values are */
-
- /* Special field in create_new_effect */
- struct hid_field *create_new_effect_type;
-
- /* Special fields in set_effect */
- struct hid_field *set_effect_type;
- struct hid_field *effect_direction;
-
- /* Special field in device_control */
- struct hid_field *device_control;
-
- /* Special field in block_load */
- struct hid_field *block_load_status;
-
- /* Special field in effect_operation */
- struct hid_field *effect_operation_status;
-
- int control_id[sizeof(pidff_device_control)];
- int type_id[sizeof(pidff_effect_types)];
- int status_id[sizeof(pidff_block_load_status)];
- int operation_id[sizeof(pidff_effect_operation_status)];
-
- int pid_id[PID_EFFECTS_MAX];
-};
-
-/*
- * Scale an unsigned value with range 0..max for the given field
- */
-static int pidff_rescale(int i, int max, struct hid_field *field)
-{
- return i * (field->logical_maximum - field->logical_minimum) / max +
- field->logical_minimum;
-}
-
-/*
- * Scale a signed value in range -0x8000..0x7fff for the given field
- */
-static int pidff_rescale_signed(int i, struct hid_field *field)
-{
- return i == 0 ? 0 : i >
- 0 ? i * field->logical_maximum / 0x7fff : i *
- field->logical_minimum / -0x8000;
-}
-
-static void pidff_set(struct pidff_usage *usage, u16 value)
-{
- usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
- pr_debug("calculated from %d to %d\n", value, usage->value[0]);
-}
-
-static void pidff_set_signed(struct pidff_usage *usage, s16 value)
-{
- if (usage->field->logical_minimum < 0)
- usage->value[0] = pidff_rescale_signed(value, usage->field);
- else {
- if (value < 0)
- usage->value[0] =
- pidff_rescale(-value, 0x8000, usage->field);
- else
- usage->value[0] =
- pidff_rescale(value, 0x7fff, usage->field);
- }
- pr_debug("calculated from %d to %d\n", value, usage->value[0]);
-}
-
-/*
- * Send envelope report to the device
- */
-static void pidff_set_envelope_report(struct pidff_device *pidff,
- struct ff_envelope *envelope)
-{
- pidff->set_envelope[PID_EFFECT_BLOCK_INDEX].value[0] =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
-
- pidff->set_envelope[PID_ATTACK_LEVEL].value[0] =
- pidff_rescale(envelope->attack_level >
- 0x7fff ? 0x7fff : envelope->attack_level, 0x7fff,
- pidff->set_envelope[PID_ATTACK_LEVEL].field);
- pidff->set_envelope[PID_FADE_LEVEL].value[0] =
- pidff_rescale(envelope->fade_level >
- 0x7fff ? 0x7fff : envelope->fade_level, 0x7fff,
- pidff->set_envelope[PID_FADE_LEVEL].field);
-
- pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length;
- pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length;
-
- hid_dbg(pidff->hid, "attack %u => %d\n",
- envelope->attack_level,
- pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
-
- usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
- USB_DIR_OUT);
-}
-
-/*
- * Test if the new envelope differs from old one
- */
-static int pidff_needs_set_envelope(struct ff_envelope *envelope,
- struct ff_envelope *old)
-{
- return envelope->attack_level != old->attack_level ||
- envelope->fade_level != old->fade_level ||
- envelope->attack_length != old->attack_length ||
- envelope->fade_length != old->fade_length;
-}
-
-/*
- * Send constant force report to the device
- */
-static void pidff_set_constant_force_report(struct pidff_device *pidff,
- struct ff_effect *effect)
-{
- pidff->set_constant[PID_EFFECT_BLOCK_INDEX].value[0] =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
- pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
- effect->u.constant.level);
-
- usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT],
- USB_DIR_OUT);
-}
-
-/*
- * Test if the constant parameters have changed between effects
- */
-static int pidff_needs_set_constant(struct ff_effect *effect,
- struct ff_effect *old)
-{
- return effect->u.constant.level != old->u.constant.level;
-}
-
-/*
- * Send set effect report to the device
- */
-static void pidff_set_effect_report(struct pidff_device *pidff,
- struct ff_effect *effect)
-{
- pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
- pidff->set_effect_type->value[0] =
- pidff->create_new_effect_type->value[0];
- pidff->set_effect[PID_DURATION].value[0] = effect->replay.length;
- pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button;
- pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] =
- effect->trigger.interval;
- pidff->set_effect[PID_GAIN].value[0] =
- pidff->set_effect[PID_GAIN].field->logical_maximum;
- pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
- pidff->effect_direction->value[0] =
- pidff_rescale(effect->direction, 0xffff,
- pidff->effect_direction);
- pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
-
- usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
- USB_DIR_OUT);
-}
-
-/*
- * Test if the values used in set_effect have changed
- */
-static int pidff_needs_set_effect(struct ff_effect *effect,
- struct ff_effect *old)
-{
- return effect->replay.length != old->replay.length ||
- effect->trigger.interval != old->trigger.interval ||
- effect->trigger.button != old->trigger.button ||
- effect->direction != old->direction ||
- effect->replay.delay != old->replay.delay;
-}
-
-/*
- * Send periodic effect report to the device
- */
-static void pidff_set_periodic_report(struct pidff_device *pidff,
- struct ff_effect *effect)
-{
- pidff->set_periodic[PID_EFFECT_BLOCK_INDEX].value[0] =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
- pidff_set_signed(&pidff->set_periodic[PID_MAGNITUDE],
- effect->u.periodic.magnitude);
- pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
- effect->u.periodic.offset);
- pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
- pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
-
- usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC],
- USB_DIR_OUT);
-
-}
-
-/*
- * Test if periodic effect parameters have changed
- */
-static int pidff_needs_set_periodic(struct ff_effect *effect,
- struct ff_effect *old)
-{
- return effect->u.periodic.magnitude != old->u.periodic.magnitude ||
- effect->u.periodic.offset != old->u.periodic.offset ||
- effect->u.periodic.phase != old->u.periodic.phase ||
- effect->u.periodic.period != old->u.periodic.period;
-}
-
-/*
- * Send condition effect reports to the device
- */
-static void pidff_set_condition_report(struct pidff_device *pidff,
- struct ff_effect *effect)
-{
- int i;
-
- pidff->set_condition[PID_EFFECT_BLOCK_INDEX].value[0] =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
-
- for (i = 0; i < 2; i++) {
- pidff->set_condition[PID_PARAM_BLOCK_OFFSET].value[0] = i;
- pidff_set_signed(&pidff->set_condition[PID_CP_OFFSET],
- effect->u.condition[i].center);
- pidff_set_signed(&pidff->set_condition[PID_POS_COEFFICIENT],
- effect->u.condition[i].right_coeff);
- pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT],
- effect->u.condition[i].left_coeff);
- pidff_set(&pidff->set_condition[PID_POS_SATURATION],
- effect->u.condition[i].right_saturation);
- pidff_set(&pidff->set_condition[PID_NEG_SATURATION],
- effect->u.condition[i].left_saturation);
- pidff_set(&pidff->set_condition[PID_DEAD_BAND],
- effect->u.condition[i].deadband);
- usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION],
- USB_DIR_OUT);
- }
-}
-
-/*
- * Test if condition effect parameters have changed
- */
-static int pidff_needs_set_condition(struct ff_effect *effect,
- struct ff_effect *old)
-{
- int i;
- int ret = 0;
-
- for (i = 0; i < 2; i++) {
- struct ff_condition_effect *cond = &effect->u.condition[i];
- struct ff_condition_effect *old_cond = &old->u.condition[i];
-
- ret |= cond->center != old_cond->center ||
- cond->right_coeff != old_cond->right_coeff ||
- cond->left_coeff != old_cond->left_coeff ||
- cond->right_saturation != old_cond->right_saturation ||
- cond->left_saturation != old_cond->left_saturation ||
- cond->deadband != old_cond->deadband;
- }
-
- return ret;
-}
-
-/*
- * Send ramp force report to the device
- */
-static void pidff_set_ramp_force_report(struct pidff_device *pidff,
- struct ff_effect *effect)
-{
- pidff->set_ramp[PID_EFFECT_BLOCK_INDEX].value[0] =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
- pidff_set_signed(&pidff->set_ramp[PID_RAMP_START],
- effect->u.ramp.start_level);
- pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
- effect->u.ramp.end_level);
- usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP],
- USB_DIR_OUT);
-}
-
-/*
- * Test if ramp force parameters have changed
- */
-static int pidff_needs_set_ramp(struct ff_effect *effect, struct ff_effect *old)
-{
- return effect->u.ramp.start_level != old->u.ramp.start_level ||
- effect->u.ramp.end_level != old->u.ramp.end_level;
-}
-
-/*
- * Send a request for effect upload to the device
- *
- * Returns 0 if device reported success, -ENOSPC if the device reported memory
- * is full. Upon unknown response the function will retry for 60 times, if
- * still unsuccessful -EIO is returned.
- */
-static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
-{
- int j;
-
- pidff->create_new_effect_type->value[0] = efnum;
- usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
- USB_DIR_OUT);
- hid_dbg(pidff->hid, "create_new_effect sent, type: %d\n", efnum);
-
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
- pidff->block_load_status->value[0] = 0;
- usbhid_wait_io(pidff->hid);
-
- for (j = 0; j < 60; j++) {
- hid_dbg(pidff->hid, "pid_block_load requested\n");
- usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
- USB_DIR_IN);
- usbhid_wait_io(pidff->hid);
- if (pidff->block_load_status->value[0] ==
- pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
- hid_dbg(pidff->hid, "device reported free memory: %d bytes\n",
- pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
- pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
- return 0;
- }
- if (pidff->block_load_status->value[0] ==
- pidff->status_id[PID_BLOCK_LOAD_FULL]) {
- hid_dbg(pidff->hid, "not enough memory free: %d bytes\n",
- pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
- pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
- return -ENOSPC;
- }
- }
- hid_err(pidff->hid, "pid_block_load failed 60 times\n");
- return -EIO;
-}
-
-/*
- * Play the effect with PID id n times
- */
-static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
-{
- pidff->effect_operation[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
-
- if (n == 0) {
- pidff->effect_operation_status->value[0] =
- pidff->operation_id[PID_EFFECT_STOP];
- } else {
- pidff->effect_operation_status->value[0] =
- pidff->operation_id[PID_EFFECT_START];
- pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
- }
-
- usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
- USB_DIR_OUT);
-}
-
-/**
- * Play the effect with effect id @effect_id for @value times
- */
-static int pidff_playback(struct input_dev *dev, int effect_id, int value)
-{
- struct pidff_device *pidff = dev->ff->private;
-
- pidff_playback_pid(pidff, pidff->pid_id[effect_id], value);
-
- return 0;
-}
-
-/*
- * Erase effect with PID id
- */
-static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
-{
- pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
- usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE],
- USB_DIR_OUT);
-}
-
-/*
- * Stop and erase effect with effect_id
- */
-static int pidff_erase_effect(struct input_dev *dev, int effect_id)
-{
- struct pidff_device *pidff = dev->ff->private;
- int pid_id = pidff->pid_id[effect_id];
-
- hid_dbg(pidff->hid, "starting to erase %d/%d\n",
- effect_id, pidff->pid_id[effect_id]);
- /* Wait for the queue to clear. We do not want a full fifo to
- prevent the effect removal. */
- usbhid_wait_io(pidff->hid);
- pidff_playback_pid(pidff, pid_id, 0);
- pidff_erase_pid(pidff, pid_id);
-
- return 0;
-}
-
-/*
- * Effect upload handler
- */
-static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
- struct ff_effect *old)
-{
- struct pidff_device *pidff = dev->ff->private;
- int type_id;
- int error;
-
- switch (effect->type) {
- case FF_CONSTANT:
- if (!old) {
- error = pidff_request_effect_upload(pidff,
- pidff->type_id[PID_CONSTANT]);
- if (error)
- return error;
- }
- if (!old || pidff_needs_set_effect(effect, old))
- pidff_set_effect_report(pidff, effect);
- if (!old || pidff_needs_set_constant(effect, old))
- pidff_set_constant_force_report(pidff, effect);
- if (!old ||
- pidff_needs_set_envelope(&effect->u.constant.envelope,
- &old->u.constant.envelope))
- pidff_set_envelope_report(pidff,
- &effect->u.constant.envelope);
- break;
-
- case FF_PERIODIC:
- if (!old) {
- switch (effect->u.periodic.waveform) {
- case FF_SQUARE:
- type_id = PID_SQUARE;
- break;
- case FF_TRIANGLE:
- type_id = PID_TRIANGLE;
- break;
- case FF_SINE:
- type_id = PID_SINE;
- break;
- case FF_SAW_UP:
- type_id = PID_SAW_UP;
- break;
- case FF_SAW_DOWN:
- type_id = PID_SAW_DOWN;
- break;
- default:
- hid_err(pidff->hid, "invalid waveform\n");
- return -EINVAL;
- }
-
- error = pidff_request_effect_upload(pidff,
- pidff->type_id[type_id]);
- if (error)
- return error;
- }
- if (!old || pidff_needs_set_effect(effect, old))
- pidff_set_effect_report(pidff, effect);
- if (!old || pidff_needs_set_periodic(effect, old))
- pidff_set_periodic_report(pidff, effect);
- if (!old ||
- pidff_needs_set_envelope(&effect->u.periodic.envelope,
- &old->u.periodic.envelope))
- pidff_set_envelope_report(pidff,
- &effect->u.periodic.envelope);
- break;
-
- case FF_RAMP:
- if (!old) {
- error = pidff_request_effect_upload(pidff,
- pidff->type_id[PID_RAMP]);
- if (error)
- return error;
- }
- if (!old || pidff_needs_set_effect(effect, old))
- pidff_set_effect_report(pidff, effect);
- if (!old || pidff_needs_set_ramp(effect, old))
- pidff_set_ramp_force_report(pidff, effect);
- if (!old ||
- pidff_needs_set_envelope(&effect->u.ramp.envelope,
- &old->u.ramp.envelope))
- pidff_set_envelope_report(pidff,
- &effect->u.ramp.envelope);
- break;
-
- case FF_SPRING:
- if (!old) {
- error = pidff_request_effect_upload(pidff,
- pidff->type_id[PID_SPRING]);
- if (error)
- return error;
- }
- if (!old || pidff_needs_set_effect(effect, old))
- pidff_set_effect_report(pidff, effect);
- if (!old || pidff_needs_set_condition(effect, old))
- pidff_set_condition_report(pidff, effect);
- break;
-
- case FF_FRICTION:
- if (!old) {
- error = pidff_request_effect_upload(pidff,
- pidff->type_id[PID_FRICTION]);
- if (error)
- return error;
- }
- if (!old || pidff_needs_set_effect(effect, old))
- pidff_set_effect_report(pidff, effect);
- if (!old || pidff_needs_set_condition(effect, old))
- pidff_set_condition_report(pidff, effect);
- break;
-
- case FF_DAMPER:
- if (!old) {
- error = pidff_request_effect_upload(pidff,
- pidff->type_id[PID_DAMPER]);
- if (error)
- return error;
- }
- if (!old || pidff_needs_set_effect(effect, old))
- pidff_set_effect_report(pidff, effect);
- if (!old || pidff_needs_set_condition(effect, old))
- pidff_set_condition_report(pidff, effect);
- break;
-
- case FF_INERTIA:
- if (!old) {
- error = pidff_request_effect_upload(pidff,
- pidff->type_id[PID_INERTIA]);
- if (error)
- return error;
- }
- if (!old || pidff_needs_set_effect(effect, old))
- pidff_set_effect_report(pidff, effect);
- if (!old || pidff_needs_set_condition(effect, old))
- pidff_set_condition_report(pidff, effect);
- break;
-
- default:
- hid_err(pidff->hid, "invalid type\n");
- return -EINVAL;
- }
-
- if (!old)
- pidff->pid_id[effect->id] =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
-
- hid_dbg(pidff->hid, "uploaded\n");
-
- return 0;
-}
-
-/*
- * set_gain() handler
- */
-static void pidff_set_gain(struct input_dev *dev, u16 gain)
-{
- struct pidff_device *pidff = dev->ff->private;
-
- pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
- usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
- USB_DIR_OUT);
-}
-
-static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
-{
- struct hid_field *field =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].field;
-
- if (!magnitude) {
- pidff_playback_pid(pidff, field->logical_minimum, 0);
- return;
- }
-
- pidff_playback_pid(pidff, field->logical_minimum, 1);
-
- pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum;
- pidff->set_effect_type->value[0] = pidff->type_id[PID_SPRING];
- pidff->set_effect[PID_DURATION].value[0] = 0;
- pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
- pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
- pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
- pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
- pidff->set_effect[PID_START_DELAY].value[0] = 0;
-
- usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
- USB_DIR_OUT);
-}
-
-/*
- * pidff_set_autocenter() handler
- */
-static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude)
-{
- struct pidff_device *pidff = dev->ff->private;
-
- pidff_autocenter(pidff, magnitude);
-}
-
-/*
- * Find fields from a report and fill a pidff_usage
- */
-static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
- struct hid_report *report, int count, int strict)
-{
- int i, j, k, found;
-
- for (k = 0; k < count; k++) {
- found = 0;
- for (i = 0; i < report->maxfield; i++) {
- if (report->field[i]->maxusage !=
- report->field[i]->report_count) {
- pr_debug("maxusage and report_count do not match, skipping\n");
- continue;
- }
- for (j = 0; j < report->field[i]->maxusage; j++) {
- if (report->field[i]->usage[j].hid ==
- (HID_UP_PID | table[k])) {
- pr_debug("found %d at %d->%d\n",
- k, i, j);
- usage[k].field = report->field[i];
- usage[k].value =
- &report->field[i]->value[j];
- found = 1;
- break;
- }
- }
- if (found)
- break;
- }
- if (!found && strict) {
- pr_debug("failed to locate %d\n", k);
- return -1;
- }
- }
- return 0;
-}
-
-/*
- * Return index into pidff_reports for the given usage
- */
-static int pidff_check_usage(int usage)
-{
- int i;
-
- for (i = 0; i < sizeof(pidff_reports); i++)
- if (usage == (HID_UP_PID | pidff_reports[i]))
- return i;
-
- return -1;
-}
-
-/*
- * Find the reports and fill pidff->reports[]
- * report_type specifies either OUTPUT or FEATURE reports
- */
-static void pidff_find_reports(struct hid_device *hid, int report_type,
- struct pidff_device *pidff)
-{
- struct hid_report *report;
- int i, ret;
-
- list_for_each_entry(report,
- &hid->report_enum[report_type].report_list, list) {
- if (report->maxfield < 1)
- continue;
- ret = pidff_check_usage(report->field[0]->logical);
- if (ret != -1) {
- hid_dbg(hid, "found usage 0x%02x from field->logical\n",
- pidff_reports[ret]);
- pidff->reports[ret] = report;
- continue;
- }
-
- /*
- * Sometimes logical collections are stacked to indicate
- * different usages for the report and the field, in which
- * case we want the usage of the parent. However, Linux HID
- * implementation hides this fact, so we have to dig it up
- * ourselves
- */
- i = report->field[0]->usage[0].collection_index;
- if (i <= 0 ||
- hid->collection[i - 1].type != HID_COLLECTION_LOGICAL)
- continue;
- ret = pidff_check_usage(hid->collection[i - 1].usage);
- if (ret != -1 && !pidff->reports[ret]) {
- hid_dbg(hid,
- "found usage 0x%02x from collection array\n",
- pidff_reports[ret]);
- pidff->reports[ret] = report;
- }
- }
-}
-
-/*
- * Test if the required reports have been found
- */
-static int pidff_reports_ok(struct pidff_device *pidff)
-{
- int i;
-
- for (i = 0; i <= PID_REQUIRED_REPORTS; i++) {
- if (!pidff->reports[i]) {
- hid_dbg(pidff->hid, "%d missing\n", i);
- return 0;
- }
- }
-
- return 1;
-}
-
-/*
- * Find a field with a specific usage within a report
- */
-static struct hid_field *pidff_find_special_field(struct hid_report *report,
- int usage, int enforce_min)
-{
- int i;
-
- for (i = 0; i < report->maxfield; i++) {
- if (report->field[i]->logical == (HID_UP_PID | usage) &&
- report->field[i]->report_count > 0) {
- if (!enforce_min ||
- report->field[i]->logical_minimum == 1)
- return report->field[i];
- else {
- pr_err("logical_minimum is not 1 as it should be\n");
- return NULL;
- }
- }
- }
- return NULL;
-}
-
-/*
- * Fill a pidff->*_id struct table
- */
-static int pidff_find_special_keys(int *keys, struct hid_field *fld,
- const u8 *usagetable, int count)
-{
-
- int i, j;
- int found = 0;
-
- for (i = 0; i < count; i++) {
- for (j = 0; j < fld->maxusage; j++) {
- if (fld->usage[j].hid == (HID_UP_PID | usagetable[i])) {
- keys[i] = j + 1;
- found++;
- break;
- }
- }
- }
- return found;
-}
-
-#define PIDFF_FIND_SPECIAL_KEYS(keys, field, name) \
- pidff_find_special_keys(pidff->keys, pidff->field, pidff_ ## name, \
- sizeof(pidff_ ## name))
-
-/*
- * Find and check the special fields
- */
-static int pidff_find_special_fields(struct pidff_device *pidff)
-{
- hid_dbg(pidff->hid, "finding special fields\n");
-
- pidff->create_new_effect_type =
- pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT],
- 0x25, 1);
- pidff->set_effect_type =
- pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
- 0x25, 1);
- pidff->effect_direction =
- pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
- 0x57, 0);
- pidff->device_control =
- pidff_find_special_field(pidff->reports[PID_DEVICE_CONTROL],
- 0x96, 1);
- pidff->block_load_status =
- pidff_find_special_field(pidff->reports[PID_BLOCK_LOAD],
- 0x8b, 1);
- pidff->effect_operation_status =
- pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION],
- 0x78, 1);
-
- hid_dbg(pidff->hid, "search done\n");
-
- if (!pidff->create_new_effect_type || !pidff->set_effect_type) {
- hid_err(pidff->hid, "effect lists not found\n");
- return -1;
- }
-
- if (!pidff->effect_direction) {
- hid_err(pidff->hid, "direction field not found\n");
- return -1;
- }
-
- if (!pidff->device_control) {
- hid_err(pidff->hid, "device control field not found\n");
- return -1;
- }
-
- if (!pidff->block_load_status) {
- hid_err(pidff->hid, "block load status field not found\n");
- return -1;
- }
-
- if (!pidff->effect_operation_status) {
- hid_err(pidff->hid, "effect operation field not found\n");
- return -1;
- }
-
- pidff_find_special_keys(pidff->control_id, pidff->device_control,
- pidff_device_control,
- sizeof(pidff_device_control));
-
- PIDFF_FIND_SPECIAL_KEYS(control_id, device_control, device_control);
-
- if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type,
- effect_types)) {
- hid_err(pidff->hid, "no effect types found\n");
- return -1;
- }
-
- if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status,
- block_load_status) !=
- sizeof(pidff_block_load_status)) {
- hid_err(pidff->hid,
- "block load status identifiers not found\n");
- return -1;
- }
-
- if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status,
- effect_operation_status) !=
- sizeof(pidff_effect_operation_status)) {
- hid_err(pidff->hid, "effect operation identifiers not found\n");
- return -1;
- }
-
- return 0;
-}
-
-/**
- * Find the implemented effect types
- */
-static int pidff_find_effects(struct pidff_device *pidff,
- struct input_dev *dev)
-{
- int i;
-
- for (i = 0; i < sizeof(pidff_effect_types); i++) {
- int pidff_type = pidff->type_id[i];
- if (pidff->set_effect_type->usage[pidff_type].hid !=
- pidff->create_new_effect_type->usage[pidff_type].hid) {
- hid_err(pidff->hid,
- "effect type number %d is invalid\n", i);
- return -1;
- }
- }
-
- if (pidff->type_id[PID_CONSTANT])
- set_bit(FF_CONSTANT, dev->ffbit);
- if (pidff->type_id[PID_RAMP])
- set_bit(FF_RAMP, dev->ffbit);
- if (pidff->type_id[PID_SQUARE]) {
- set_bit(FF_SQUARE, dev->ffbit);
- set_bit(FF_PERIODIC, dev->ffbit);
- }
- if (pidff->type_id[PID_SINE]) {
- set_bit(FF_SINE, dev->ffbit);
- set_bit(FF_PERIODIC, dev->ffbit);
- }
- if (pidff->type_id[PID_TRIANGLE]) {
- set_bit(FF_TRIANGLE, dev->ffbit);
- set_bit(FF_PERIODIC, dev->ffbit);
- }
- if (pidff->type_id[PID_SAW_UP]) {
- set_bit(FF_SAW_UP, dev->ffbit);
- set_bit(FF_PERIODIC, dev->ffbit);
- }
- if (pidff->type_id[PID_SAW_DOWN]) {
- set_bit(FF_SAW_DOWN, dev->ffbit);
- set_bit(FF_PERIODIC, dev->ffbit);
- }
- if (pidff->type_id[PID_SPRING])
- set_bit(FF_SPRING, dev->ffbit);
- if (pidff->type_id[PID_DAMPER])
- set_bit(FF_DAMPER, dev->ffbit);
- if (pidff->type_id[PID_INERTIA])
- set_bit(FF_INERTIA, dev->ffbit);
- if (pidff->type_id[PID_FRICTION])
- set_bit(FF_FRICTION, dev->ffbit);
-
- return 0;
-
-}
-
-#define PIDFF_FIND_FIELDS(name, report, strict) \
- pidff_find_fields(pidff->name, pidff_ ## name, \
- pidff->reports[report], \
- sizeof(pidff_ ## name), strict)
-
-/*
- * Fill and check the pidff_usages
- */
-static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
-{
- int envelope_ok = 0;
-
- if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) {
- hid_err(pidff->hid, "unknown set_effect report layout\n");
- return -ENODEV;
- }
-
- PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0);
- if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) {
- hid_err(pidff->hid, "unknown pid_block_load report layout\n");
- return -ENODEV;
- }
-
- if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) {
- hid_err(pidff->hid, "unknown effect_operation report layout\n");
- return -ENODEV;
- }
-
- if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) {
- hid_err(pidff->hid, "unknown pid_block_free report layout\n");
- return -ENODEV;
- }
-
- if (!PIDFF_FIND_FIELDS(set_envelope, PID_SET_ENVELOPE, 1))
- envelope_ok = 1;
-
- if (pidff_find_special_fields(pidff) || pidff_find_effects(pidff, dev))
- return -ENODEV;
-
- if (!envelope_ok) {
- if (test_and_clear_bit(FF_CONSTANT, dev->ffbit))
- hid_warn(pidff->hid,
- "has constant effect but no envelope\n");
- if (test_and_clear_bit(FF_RAMP, dev->ffbit))
- hid_warn(pidff->hid,
- "has ramp effect but no envelope\n");
-
- if (test_and_clear_bit(FF_PERIODIC, dev->ffbit))
- hid_warn(pidff->hid,
- "has periodic effect but no envelope\n");
- }
-
- if (test_bit(FF_CONSTANT, dev->ffbit) &&
- PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) {
- hid_warn(pidff->hid, "unknown constant effect layout\n");
- clear_bit(FF_CONSTANT, dev->ffbit);
- }
-
- if (test_bit(FF_RAMP, dev->ffbit) &&
- PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) {
- hid_warn(pidff->hid, "unknown ramp effect layout\n");
- clear_bit(FF_RAMP, dev->ffbit);
- }
-
- if ((test_bit(FF_SPRING, dev->ffbit) ||
- test_bit(FF_DAMPER, dev->ffbit) ||
- test_bit(FF_FRICTION, dev->ffbit) ||
- test_bit(FF_INERTIA, dev->ffbit)) &&
- PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) {
- hid_warn(pidff->hid, "unknown condition effect layout\n");
- clear_bit(FF_SPRING, dev->ffbit);
- clear_bit(FF_DAMPER, dev->ffbit);
- clear_bit(FF_FRICTION, dev->ffbit);
- clear_bit(FF_INERTIA, dev->ffbit);
- }
-
- if (test_bit(FF_PERIODIC, dev->ffbit) &&
- PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) {
- hid_warn(pidff->hid, "unknown periodic effect layout\n");
- clear_bit(FF_PERIODIC, dev->ffbit);
- }
-
- PIDFF_FIND_FIELDS(pool, PID_POOL, 0);
-
- if (!PIDFF_FIND_FIELDS(device_gain, PID_DEVICE_GAIN, 1))
- set_bit(FF_GAIN, dev->ffbit);
-
- return 0;
-}
-
-/*
- * Reset the device
- */
-static void pidff_reset(struct pidff_device *pidff)
-{
- struct hid_device *hid = pidff->hid;
- int i = 0;
-
- pidff->device_control->value[0] = pidff->control_id[PID_RESET];
- /* We reset twice as sometimes hid_wait_io isn't waiting long enough */
- usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
- usbhid_wait_io(hid);
- usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
- usbhid_wait_io(hid);
-
- pidff->device_control->value[0] =
- pidff->control_id[PID_ENABLE_ACTUATORS];
- usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
- usbhid_wait_io(hid);
-
- /* pool report is sometimes messed up, refetch it */
- usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN);
- usbhid_wait_io(hid);
-
- if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
- while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
- if (i++ > 20) {
- hid_warn(pidff->hid,
- "device reports %d simultaneous effects\n",
- pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
- break;
- }
- hid_dbg(pidff->hid, "pid_pool requested again\n");
- usbhid_submit_report(hid, pidff->reports[PID_POOL],
- USB_DIR_IN);
- usbhid_wait_io(hid);
- }
- }
-}
-
-/*
- * Test if autocenter modification is using the supported method
- */
-static int pidff_check_autocenter(struct pidff_device *pidff,
- struct input_dev *dev)
-{
- int error;
-
- /*
- * Let's find out if autocenter modification is supported
- * Specification doesn't specify anything, so we request an
- * effect upload and cancel it immediately. If the approved
- * effect id was one above the minimum, then we assume the first
- * effect id is a built-in spring type effect used for autocenter
- */
-
- error = pidff_request_effect_upload(pidff, 1);
- if (error) {
- hid_err(pidff->hid, "upload request failed\n");
- return error;
- }
-
- if (pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] ==
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1) {
- pidff_autocenter(pidff, 0xffff);
- set_bit(FF_AUTOCENTER, dev->ffbit);
- } else {
- hid_notice(pidff->hid,
- "device has unknown autocenter control method\n");
- }
-
- pidff_erase_pid(pidff,
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]);
-
- return 0;
-
-}
-
-/*
- * Check if the device is PID and initialize it
- */
-int hid_pidff_init(struct hid_device *hid)
-{
- struct pidff_device *pidff;
- struct hid_input *hidinput = list_entry(hid->inputs.next,
- struct hid_input, list);
- struct input_dev *dev = hidinput->input;
- struct ff_device *ff;
- int max_effects;
- int error;
-
- hid_dbg(hid, "starting pid init\n");
-
- if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
- hid_dbg(hid, "not a PID device, no output report\n");
- return -ENODEV;
- }
-
- pidff = kzalloc(sizeof(*pidff), GFP_KERNEL);
- if (!pidff)
- return -ENOMEM;
-
- pidff->hid = hid;
-
- pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff);
- pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
-
- if (!pidff_reports_ok(pidff)) {
- hid_dbg(hid, "reports not ok, aborting\n");
- error = -ENODEV;
- goto fail;
- }
-
- error = pidff_init_fields(pidff, dev);
- if (error)
- goto fail;
-
- pidff_reset(pidff);
-
- if (test_bit(FF_GAIN, dev->ffbit)) {
- pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
- usbhid_submit_report(hid, pidff->reports[PID_DEVICE_GAIN],
- USB_DIR_OUT);
- }
-
- error = pidff_check_autocenter(pidff, dev);
- if (error)
- goto fail;
-
- max_effects =
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum -
- pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum +
- 1;
- hid_dbg(hid, "max effects is %d\n", max_effects);
-
- if (max_effects > PID_EFFECTS_MAX)
- max_effects = PID_EFFECTS_MAX;
-
- if (pidff->pool[PID_SIMULTANEOUS_MAX].value)
- hid_dbg(hid, "max simultaneous effects is %d\n",
- pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
-
- if (pidff->pool[PID_RAM_POOL_SIZE].value)
- hid_dbg(hid, "device memory size is %d bytes\n",
- pidff->pool[PID_RAM_POOL_SIZE].value[0]);
-
- if (pidff->pool[PID_DEVICE_MANAGED_POOL].value &&
- pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) {
- hid_notice(hid,
- "device does not support device managed pool\n");
- goto fail;
- }
-
- error = input_ff_create(dev, max_effects);
- if (error)
- goto fail;
-
- ff = dev->ff;
- ff->private = pidff;
- ff->upload = pidff_upload_effect;
- ff->erase = pidff_erase_effect;
- ff->set_gain = pidff_set_gain;
- ff->set_autocenter = pidff_set_autocenter;
- ff->playback = pidff_playback;
-
- hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
-
- return 0;
-
- fail:
- kfree(pidff);
- return error;
-}
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/hid-quirks.c b/ANDROID_3.4.5/drivers/hid/usbhid/hid-quirks.c
deleted file mode 100644
index 782c6395..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/hid-quirks.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * USB HID quirks support for Linux
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- * Copyright (c) 2006-2007 Jiri Kosina
- * Copyright (c) 2007 Paul Walmsley
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/hid.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-
-#include "../hid-ids.h"
-
-/*
- * Alphabetically sorted blacklist by quirk type.
- */
-
-static const struct hid_blacklist {
- __u16 idVendor;
- __u16 idProduct;
- __u32 quirks;
-} hid_blacklist[] = {
- { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
- { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT},
- { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
-
- { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
-
- { USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
- { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
-
- { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
- { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
- { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
- { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
-
- { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
-
- { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
-
- { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
- { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
- { 0, 0 }
-};
-
-/* Dynamic HID quirks list - specified at runtime */
-struct quirks_list_struct {
- struct hid_blacklist hid_bl_item;
- struct list_head node;
-};
-
-static LIST_HEAD(dquirks_list);
-static DECLARE_RWSEM(dquirks_rwsem);
-
-/* Runtime ("dynamic") quirks manipulation functions */
-
-/**
- * usbhid_exists_dquirk: find any dynamic quirks for a USB HID device
- * @idVendor: the 16-bit USB vendor ID, in native byteorder
- * @idProduct: the 16-bit USB product ID, in native byteorder
- *
- * Description:
- * Scans dquirks_list for a matching dynamic quirk and returns
- * the pointer to the relevant struct hid_blacklist if found.
- * Must be called with a read lock held on dquirks_rwsem.
- *
- * Returns: NULL if no quirk found, struct hid_blacklist * if found.
- */
-static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor,
- const u16 idProduct)
-{
- struct quirks_list_struct *q;
- struct hid_blacklist *bl_entry = NULL;
-
- list_for_each_entry(q, &dquirks_list, node) {
- if (q->hid_bl_item.idVendor == idVendor &&
- q->hid_bl_item.idProduct == idProduct) {
- bl_entry = &q->hid_bl_item;
- break;
- }
- }
-
- if (bl_entry != NULL)
- dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
- bl_entry->quirks, bl_entry->idVendor,
- bl_entry->idProduct);
-
- return bl_entry;
-}
-
-
-/**
- * usbhid_modify_dquirk: add/replace a HID quirk
- * @idVendor: the 16-bit USB vendor ID, in native byteorder
- * @idProduct: the 16-bit USB product ID, in native byteorder
- * @quirks: the u32 quirks value to add/replace
- *
- * Description:
- * If an dynamic quirk exists in memory for this (idVendor,
- * idProduct) pair, replace its quirks value with what was
- * provided. Otherwise, add the quirk to the dynamic quirks list.
- *
- * Returns: 0 OK, -error on failure.
- */
-static int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
- const u32 quirks)
-{
- struct quirks_list_struct *q_new, *q;
- int list_edited = 0;
-
- if (!idVendor) {
- dbg_hid("Cannot add a quirk with idVendor = 0\n");
- return -EINVAL;
- }
-
- q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL);
- if (!q_new) {
- dbg_hid("Could not allocate quirks_list_struct\n");
- return -ENOMEM;
- }
-
- q_new->hid_bl_item.idVendor = idVendor;
- q_new->hid_bl_item.idProduct = idProduct;
- q_new->hid_bl_item.quirks = quirks;
-
- down_write(&dquirks_rwsem);
-
- list_for_each_entry(q, &dquirks_list, node) {
-
- if (q->hid_bl_item.idVendor == idVendor &&
- q->hid_bl_item.idProduct == idProduct) {
-
- list_replace(&q->node, &q_new->node);
- kfree(q);
- list_edited = 1;
- break;
-
- }
-
- }
-
- if (!list_edited)
- list_add_tail(&q_new->node, &dquirks_list);
-
- up_write(&dquirks_rwsem);
-
- return 0;
-}
-
-/**
- * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory
- *
- * Description:
- * Free all memory associated with dynamic quirks - called before
- * module unload.
- *
- */
-static void usbhid_remove_all_dquirks(void)
-{
- struct quirks_list_struct *q, *temp;
-
- down_write(&dquirks_rwsem);
- list_for_each_entry_safe(q, temp, &dquirks_list, node) {
- list_del(&q->node);
- kfree(q);
- }
- up_write(&dquirks_rwsem);
-
-}
-
-/**
- * usbhid_quirks_init: apply USB HID quirks specified at module load time
- */
-int usbhid_quirks_init(char **quirks_param)
-{
- u16 idVendor, idProduct;
- u32 quirks;
- int n = 0, m;
-
- for (; n < MAX_USBHID_BOOT_QUIRKS && quirks_param[n]; n++) {
-
- m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
- &idVendor, &idProduct, &quirks);
-
- if (m != 3 ||
- usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) {
- printk(KERN_WARNING
- "Could not parse HID quirk module param %s\n",
- quirks_param[n]);
- }
- }
-
- return 0;
-}
-
-/**
- * usbhid_quirks_exit: release memory associated with dynamic_quirks
- *
- * Description:
- * Release all memory associated with dynamic quirks. Called upon
- * module unload.
- *
- * Returns: nothing
- */
-void usbhid_quirks_exit(void)
-{
- usbhid_remove_all_dquirks();
-}
-
-/**
- * usbhid_exists_squirk: return any static quirks for a USB HID device
- * @idVendor: the 16-bit USB vendor ID, in native byteorder
- * @idProduct: the 16-bit USB product ID, in native byteorder
- *
- * Description:
- * Given a USB vendor ID and product ID, return a pointer to
- * the hid_blacklist entry associated with that device.
- *
- * Returns: pointer if quirk found, or NULL if no quirks found.
- */
-static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
- const u16 idProduct)
-{
- const struct hid_blacklist *bl_entry = NULL;
- int n = 0;
-
- for (; hid_blacklist[n].idVendor; n++)
- if (hid_blacklist[n].idVendor == idVendor &&
- hid_blacklist[n].idProduct == idProduct)
- bl_entry = &hid_blacklist[n];
-
- if (bl_entry != NULL)
- dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
- bl_entry->quirks, bl_entry->idVendor,
- bl_entry->idProduct);
- return bl_entry;
-}
-
-/**
- * usbhid_lookup_quirk: return any quirks associated with a USB HID device
- * @idVendor: the 16-bit USB vendor ID, in native byteorder
- * @idProduct: the 16-bit USB product ID, in native byteorder
- *
- * Description:
- * Given a USB vendor ID and product ID, return any quirks associated
- * with that device.
- *
- * Returns: a u32 quirks value.
- */
-u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
-{
- u32 quirks = 0;
- const struct hid_blacklist *bl_entry = NULL;
-
- /* NCR devices must not be queried for reports */
- if (idVendor == USB_VENDOR_ID_NCR &&
- idProduct >= USB_DEVICE_ID_NCR_FIRST &&
- idProduct <= USB_DEVICE_ID_NCR_LAST)
- return HID_QUIRK_NO_INIT_REPORTS;
-
- down_read(&dquirks_rwsem);
- bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
- if (!bl_entry)
- bl_entry = usbhid_exists_squirk(idVendor, idProduct);
- if (bl_entry)
- quirks = bl_entry->quirks;
- up_read(&dquirks_rwsem);
-
- return quirks;
-}
-
-EXPORT_SYMBOL_GPL(usbhid_lookup_quirk);
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/hiddev.c b/ANDROID_3.4.5/drivers/hid/usbhid/hiddev.c
deleted file mode 100644
index b1ec0e2a..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/hiddev.c
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * Copyright (c) 2001 Paul Stewart
- * Copyright (c) 2001 Vojtech Pavlik
- *
- * HID char devices, giving access to raw HID device events.
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to Paul Stewart <stewart@wetlogic.net>
- */
-
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include <linux/hiddev.h>
-#include <linux/compat.h>
-#include "usbhid.h"
-
-#ifdef CONFIG_USB_DYNAMIC_MINORS
-#define HIDDEV_MINOR_BASE 0
-#define HIDDEV_MINORS 256
-#else
-#define HIDDEV_MINOR_BASE 96
-#define HIDDEV_MINORS 16
-#endif
-#define HIDDEV_BUFFER_SIZE 2048
-
-struct hiddev {
- int exist;
- int open;
- struct mutex existancelock;
- wait_queue_head_t wait;
- struct hid_device *hid;
- struct list_head list;
- spinlock_t list_lock;
-};
-
-struct hiddev_list {
- struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE];
- int head;
- int tail;
- unsigned flags;
- struct fasync_struct *fasync;
- struct hiddev *hiddev;
- struct list_head node;
- struct mutex thread_lock;
-};
-
-/*
- * Find a report, given the report's type and ID. The ID can be specified
- * indirectly by REPORT_ID_FIRST (which returns the first report of the given
- * type) or by (REPORT_ID_NEXT | old_id), which returns the next report of the
- * given type which follows old_id.
- */
-static struct hid_report *
-hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
-{
- unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
- unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK;
- struct hid_report_enum *report_enum;
- struct hid_report *report;
- struct list_head *list;
-
- if (rinfo->report_type < HID_REPORT_TYPE_MIN ||
- rinfo->report_type > HID_REPORT_TYPE_MAX)
- return NULL;
-
- report_enum = hid->report_enum +
- (rinfo->report_type - HID_REPORT_TYPE_MIN);
-
- switch (flags) {
- case 0: /* Nothing to do -- report_id is already set correctly */
- break;
-
- case HID_REPORT_ID_FIRST:
- if (list_empty(&report_enum->report_list))
- return NULL;
-
- list = report_enum->report_list.next;
- report = list_entry(list, struct hid_report, list);
- rinfo->report_id = report->id;
- break;
-
- case HID_REPORT_ID_NEXT:
- report = report_enum->report_id_hash[rid];
- if (!report)
- return NULL;
-
- list = report->list.next;
- if (list == &report_enum->report_list)
- return NULL;
-
- report = list_entry(list, struct hid_report, list);
- rinfo->report_id = report->id;
- break;
-
- default:
- return NULL;
- }
-
- return report_enum->report_id_hash[rinfo->report_id];
-}
-
-/*
- * Perform an exhaustive search of the report table for a usage, given its
- * type and usage id.
- */
-static struct hid_field *
-hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
-{
- int i, j;
- struct hid_report *report;
- struct hid_report_enum *report_enum;
- struct hid_field *field;
-
- if (uref->report_type < HID_REPORT_TYPE_MIN ||
- uref->report_type > HID_REPORT_TYPE_MAX)
- return NULL;
-
- report_enum = hid->report_enum +
- (uref->report_type - HID_REPORT_TYPE_MIN);
-
- list_for_each_entry(report, &report_enum->report_list, list) {
- for (i = 0; i < report->maxfield; i++) {
- field = report->field[i];
- for (j = 0; j < field->maxusage; j++) {
- if (field->usage[j].hid == uref->usage_code) {
- uref->report_id = report->id;
- uref->field_index = i;
- uref->usage_index = j;
- return field;
- }
- }
- }
- }
-
- return NULL;
-}
-
-static void hiddev_send_event(struct hid_device *hid,
- struct hiddev_usage_ref *uref)
-{
- struct hiddev *hiddev = hid->hiddev;
- struct hiddev_list *list;
- unsigned long flags;
-
- spin_lock_irqsave(&hiddev->list_lock, flags);
- list_for_each_entry(list, &hiddev->list, node) {
- if (uref->field_index != HID_FIELD_INDEX_NONE ||
- (list->flags & HIDDEV_FLAG_REPORT) != 0) {
- list->buffer[list->head] = *uref;
- list->head = (list->head + 1) &
- (HIDDEV_BUFFER_SIZE - 1);
- kill_fasync(&list->fasync, SIGIO, POLL_IN);
- }
- }
- spin_unlock_irqrestore(&hiddev->list_lock, flags);
-
- wake_up_interruptible(&hiddev->wait);
-}
-
-/*
- * This is where hid.c calls into hiddev to pass an event that occurred over
- * the interrupt pipe
- */
-void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- unsigned type = field->report_type;
- struct hiddev_usage_ref uref;
-
- uref.report_type =
- (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
- ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
- ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
- uref.report_id = field->report->id;
- uref.field_index = field->index;
- uref.usage_index = (usage - field->usage);
- uref.usage_code = usage->hid;
- uref.value = value;
-
- hiddev_send_event(hid, &uref);
-}
-EXPORT_SYMBOL_GPL(hiddev_hid_event);
-
-void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
-{
- unsigned type = report->type;
- struct hiddev_usage_ref uref;
-
- memset(&uref, 0, sizeof(uref));
- uref.report_type =
- (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
- ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
- ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
- uref.report_id = report->id;
- uref.field_index = HID_FIELD_INDEX_NONE;
-
- hiddev_send_event(hid, &uref);
-}
-
-/*
- * fasync file op
- */
-static int hiddev_fasync(int fd, struct file *file, int on)
-{
- struct hiddev_list *list = file->private_data;
-
- return fasync_helper(fd, file, on, &list->fasync);
-}
-
-
-/*
- * release file op
- */
-static int hiddev_release(struct inode * inode, struct file * file)
-{
- struct hiddev_list *list = file->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&list->hiddev->list_lock, flags);
- list_del(&list->node);
- spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
-
- mutex_lock(&list->hiddev->existancelock);
- if (!--list->hiddev->open) {
- if (list->hiddev->exist) {
- usbhid_close(list->hiddev->hid);
- usbhid_put_power(list->hiddev->hid);
- } else {
- mutex_unlock(&list->hiddev->existancelock);
- kfree(list->hiddev);
- kfree(list);
- return 0;
- }
- }
-
- mutex_unlock(&list->hiddev->existancelock);
- kfree(list);
-
- return 0;
-}
-
-/*
- * open file op
- */
-static int hiddev_open(struct inode *inode, struct file *file)
-{
- struct hiddev_list *list;
- struct usb_interface *intf;
- struct hid_device *hid;
- struct hiddev *hiddev;
- int res;
-
- intf = usbhid_find_interface(iminor(inode));
- if (!intf)
- return -ENODEV;
- hid = usb_get_intfdata(intf);
- hiddev = hid->hiddev;
-
- if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
- return -ENOMEM;
- mutex_init(&list->thread_lock);
- list->hiddev = hiddev;
- file->private_data = list;
-
- /*
- * no need for locking because the USB major number
- * is shared which usbcore guards against disconnect
- */
- if (list->hiddev->exist) {
- if (!list->hiddev->open++) {
- res = usbhid_open(hiddev->hid);
- if (res < 0) {
- res = -EIO;
- goto bail;
- }
- }
- } else {
- res = -ENODEV;
- goto bail;
- }
-
- spin_lock_irq(&list->hiddev->list_lock);
- list_add_tail(&list->node, &hiddev->list);
- spin_unlock_irq(&list->hiddev->list_lock);
-
- mutex_lock(&hiddev->existancelock);
- if (!list->hiddev->open++)
- if (list->hiddev->exist) {
- struct hid_device *hid = hiddev->hid;
- res = usbhid_get_power(hid);
- if (res < 0) {
- res = -EIO;
- goto bail_unlock;
- }
- usbhid_open(hid);
- }
- mutex_unlock(&hiddev->existancelock);
- return 0;
-bail_unlock:
- mutex_unlock(&hiddev->existancelock);
-bail:
- file->private_data = NULL;
- kfree(list);
- return res;
-}
-
-/*
- * "write" file op
- */
-static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
-{
- return -EINVAL;
-}
-
-/*
- * "read" file op
- */
-static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
-{
- DEFINE_WAIT(wait);
- struct hiddev_list *list = file->private_data;
- int event_size;
- int retval;
-
- event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
- sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
-
- if (count < event_size)
- return 0;
-
- /* lock against other threads */
- retval = mutex_lock_interruptible(&list->thread_lock);
- if (retval)
- return -ERESTARTSYS;
-
- while (retval == 0) {
- if (list->head == list->tail) {
- prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE);
-
- while (list->head == list->tail) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- if (!list->hiddev->exist) {
- retval = -EIO;
- break;
- }
-
- /* let O_NONBLOCK tasks run */
- mutex_unlock(&list->thread_lock);
- schedule();
- if (mutex_lock_interruptible(&list->thread_lock)) {
- finish_wait(&list->hiddev->wait, &wait);
- return -EINTR;
- }
- set_current_state(TASK_INTERRUPTIBLE);
- }
- finish_wait(&list->hiddev->wait, &wait);
-
- }
-
- if (retval) {
- mutex_unlock(&list->thread_lock);
- return retval;
- }
-
-
- while (list->head != list->tail &&
- retval + event_size <= count) {
- if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
- if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE) {
- struct hiddev_event event;
-
- event.hid = list->buffer[list->tail].usage_code;
- event.value = list->buffer[list->tail].value;
- if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event))) {
- mutex_unlock(&list->thread_lock);
- return -EFAULT;
- }
- retval += sizeof(struct hiddev_event);
- }
- } else {
- if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
- (list->flags & HIDDEV_FLAG_REPORT) != 0) {
-
- if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref))) {
- mutex_unlock(&list->thread_lock);
- return -EFAULT;
- }
- retval += sizeof(struct hiddev_usage_ref);
- }
- }
- list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
- }
-
- }
- mutex_unlock(&list->thread_lock);
-
- return retval;
-}
-
-/*
- * "poll" file op
- * No kernel lock - fine
- */
-static unsigned int hiddev_poll(struct file *file, poll_table *wait)
-{
- struct hiddev_list *list = file->private_data;
-
- poll_wait(file, &list->hiddev->wait, wait);
- if (list->head != list->tail)
- return POLLIN | POLLRDNORM;
- if (!list->hiddev->exist)
- return POLLERR | POLLHUP;
- return 0;
-}
-
-/*
- * "ioctl" file op
- */
-static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
-{
- struct hid_device *hid = hiddev->hid;
- struct hiddev_report_info rinfo;
- struct hiddev_usage_ref_multi *uref_multi = NULL;
- struct hiddev_usage_ref *uref;
- struct hid_report *report;
- struct hid_field *field;
- int i;
-
- uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
- if (!uref_multi)
- return -ENOMEM;
- uref = &uref_multi->uref;
- if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
- if (copy_from_user(uref_multi, user_arg,
- sizeof(*uref_multi)))
- goto fault;
- } else {
- if (copy_from_user(uref, user_arg, sizeof(*uref)))
- goto fault;
- }
-
- switch (cmd) {
- case HIDIOCGUCODE:
- rinfo.report_type = uref->report_type;
- rinfo.report_id = uref->report_id;
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- goto inval;
-
- if (uref->field_index >= report->maxfield)
- goto inval;
-
- field = report->field[uref->field_index];
- if (uref->usage_index >= field->maxusage)
- goto inval;
-
- uref->usage_code = field->usage[uref->usage_index].hid;
-
- if (copy_to_user(user_arg, uref, sizeof(*uref)))
- goto fault;
-
- goto goodreturn;
-
- default:
- if (cmd != HIDIOCGUSAGE &&
- cmd != HIDIOCGUSAGES &&
- uref->report_type == HID_REPORT_TYPE_INPUT)
- goto inval;
-
- if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
- field = hiddev_lookup_usage(hid, uref);
- if (field == NULL)
- goto inval;
- } else {
- rinfo.report_type = uref->report_type;
- rinfo.report_id = uref->report_id;
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- goto inval;
-
- if (uref->field_index >= report->maxfield)
- goto inval;
-
- field = report->field[uref->field_index];
-
- if (cmd == HIDIOCGCOLLECTIONINDEX) {
- if (uref->usage_index >= field->maxusage)
- goto inval;
- } else if (uref->usage_index >= field->report_count)
- goto inval;
-
- else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
- (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
- uref->usage_index + uref_multi->num_values > field->report_count))
- goto inval;
- }
-
- switch (cmd) {
- case HIDIOCGUSAGE:
- uref->value = field->value[uref->usage_index];
- if (copy_to_user(user_arg, uref, sizeof(*uref)))
- goto fault;
- goto goodreturn;
-
- case HIDIOCSUSAGE:
- field->value[uref->usage_index] = uref->value;
- goto goodreturn;
-
- case HIDIOCGCOLLECTIONINDEX:
- i = field->usage[uref->usage_index].collection_index;
- kfree(uref_multi);
- return i;
- case HIDIOCGUSAGES:
- for (i = 0; i < uref_multi->num_values; i++)
- uref_multi->values[i] =
- field->value[uref->usage_index + i];
- if (copy_to_user(user_arg, uref_multi,
- sizeof(*uref_multi)))
- goto fault;
- goto goodreturn;
- case HIDIOCSUSAGES:
- for (i = 0; i < uref_multi->num_values; i++)
- field->value[uref->usage_index + i] =
- uref_multi->values[i];
- goto goodreturn;
- }
-
-goodreturn:
- kfree(uref_multi);
- return 0;
-fault:
- kfree(uref_multi);
- return -EFAULT;
-inval:
- kfree(uref_multi);
- return -EINVAL;
- }
-}
-
-static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
-{
- struct hid_device *hid = hiddev->hid;
- struct usb_device *dev = hid_to_usb_dev(hid);
- int idx, len;
- char *buf;
-
- if (get_user(idx, (int __user *)user_arg))
- return -EFAULT;
-
- if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
- return -ENOMEM;
-
- if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
- kfree(buf);
- return -EINVAL;
- }
-
- if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
- kfree(buf);
- return -EFAULT;
- }
-
- kfree(buf);
-
- return len;
-}
-
-static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct hiddev_list *list = file->private_data;
- struct hiddev *hiddev = list->hiddev;
- struct hid_device *hid;
- struct hiddev_collection_info cinfo;
- struct hiddev_report_info rinfo;
- struct hiddev_field_info finfo;
- struct hiddev_devinfo dinfo;
- struct hid_report *report;
- struct hid_field *field;
- void __user *user_arg = (void __user *)arg;
- int i, r = -EINVAL;
-
- /* Called without BKL by compat methods so no BKL taken */
-
- mutex_lock(&hiddev->existancelock);
- if (!hiddev->exist) {
- r = -ENODEV;
- goto ret_unlock;
- }
-
- hid = hiddev->hid;
-
- switch (cmd) {
-
- case HIDIOCGVERSION:
- r = put_user(HID_VERSION, (int __user *)arg) ?
- -EFAULT : 0;
- break;
-
- case HIDIOCAPPLICATION:
- if (arg < 0 || arg >= hid->maxapplication)
- break;
-
- for (i = 0; i < hid->maxcollection; i++)
- if (hid->collection[i].type ==
- HID_COLLECTION_APPLICATION && arg-- == 0)
- break;
-
- if (i < hid->maxcollection)
- r = hid->collection[i].usage;
- break;
-
- case HIDIOCGDEVINFO:
- {
- struct usb_device *dev = hid_to_usb_dev(hid);
- struct usbhid_device *usbhid = hid->driver_data;
-
- memset(&dinfo, 0, sizeof(dinfo));
-
- dinfo.bustype = BUS_USB;
- dinfo.busnum = dev->bus->busnum;
- dinfo.devnum = dev->devnum;
- dinfo.ifnum = usbhid->ifnum;
- dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
- dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
- dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
- dinfo.num_applications = hid->maxapplication;
-
- r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ?
- -EFAULT : 0;
- break;
- }
-
- case HIDIOCGFLAG:
- r = put_user(list->flags, (int __user *)arg) ?
- -EFAULT : 0;
- break;
-
- case HIDIOCSFLAG:
- {
- int newflags;
-
- if (get_user(newflags, (int __user *)arg)) {
- r = -EFAULT;
- break;
- }
-
- if ((newflags & ~HIDDEV_FLAGS) != 0 ||
- ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
- (newflags & HIDDEV_FLAG_UREF) == 0))
- break;
-
- list->flags = newflags;
-
- r = 0;
- break;
- }
-
- case HIDIOCGSTRING:
- r = hiddev_ioctl_string(hiddev, cmd, user_arg);
- break;
-
- case HIDIOCINITREPORT:
- usbhid_init_reports(hid);
- r = 0;
- break;
-
- case HIDIOCGREPORT:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
- r = -EFAULT;
- break;
- }
-
- if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
- break;
-
- report = hiddev_lookup_report(hid, &rinfo);
- if (report == NULL)
- break;
-
- usbhid_submit_report(hid, report, USB_DIR_IN);
- usbhid_wait_io(hid);
-
- r = 0;
- break;
-
- case HIDIOCSREPORT:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
- r = -EFAULT;
- break;
- }
-
- if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
- break;
-
- report = hiddev_lookup_report(hid, &rinfo);
- if (report == NULL)
- break;
-
- usbhid_submit_report(hid, report, USB_DIR_OUT);
- usbhid_wait_io(hid);
-
- r = 0;
- break;
-
- case HIDIOCGREPORTINFO:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
- r = -EFAULT;
- break;
- }
-
- report = hiddev_lookup_report(hid, &rinfo);
- if (report == NULL)
- break;
-
- rinfo.num_fields = report->maxfield;
-
- r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ?
- -EFAULT : 0;
- break;
-
- case HIDIOCGFIELDINFO:
- if (copy_from_user(&finfo, user_arg, sizeof(finfo))) {
- r = -EFAULT;
- break;
- }
-
- rinfo.report_type = finfo.report_type;
- rinfo.report_id = finfo.report_id;
-
- report = hiddev_lookup_report(hid, &rinfo);
- if (report == NULL)
- break;
-
- if (finfo.field_index >= report->maxfield)
- break;
-
- field = report->field[finfo.field_index];
- memset(&finfo, 0, sizeof(finfo));
- finfo.report_type = rinfo.report_type;
- finfo.report_id = rinfo.report_id;
- finfo.field_index = field->report_count - 1;
- finfo.maxusage = field->maxusage;
- finfo.flags = field->flags;
- finfo.physical = field->physical;
- finfo.logical = field->logical;
- finfo.application = field->application;
- finfo.logical_minimum = field->logical_minimum;
- finfo.logical_maximum = field->logical_maximum;
- finfo.physical_minimum = field->physical_minimum;
- finfo.physical_maximum = field->physical_maximum;
- finfo.unit_exponent = field->unit_exponent;
- finfo.unit = field->unit;
-
- r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ?
- -EFAULT : 0;
- break;
-
- case HIDIOCGUCODE:
- /* fall through */
- case HIDIOCGUSAGE:
- case HIDIOCSUSAGE:
- case HIDIOCGUSAGES:
- case HIDIOCSUSAGES:
- case HIDIOCGCOLLECTIONINDEX:
- r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
- break;
-
- case HIDIOCGCOLLECTIONINFO:
- if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) {
- r = -EFAULT;
- break;
- }
-
- if (cinfo.index >= hid->maxcollection)
- break;
-
- cinfo.type = hid->collection[cinfo.index].type;
- cinfo.usage = hid->collection[cinfo.index].usage;
- cinfo.level = hid->collection[cinfo.index].level;
-
- r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ?
- -EFAULT : 0;
- break;
-
- default:
- if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
- break;
-
- if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
- int len = strlen(hid->name) + 1;
- if (len > _IOC_SIZE(cmd))
- len = _IOC_SIZE(cmd);
- r = copy_to_user(user_arg, hid->name, len) ?
- -EFAULT : len;
- break;
- }
-
- if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
- int len = strlen(hid->phys) + 1;
- if (len > _IOC_SIZE(cmd))
- len = _IOC_SIZE(cmd);
- r = copy_to_user(user_arg, hid->phys, len) ?
- -EFAULT : len;
- break;
- }
- }
-
-ret_unlock:
- mutex_unlock(&hiddev->existancelock);
- return r;
-}
-
-#ifdef CONFIG_COMPAT
-static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- return hiddev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
-}
-#endif
-
-static const struct file_operations hiddev_fops = {
- .owner = THIS_MODULE,
- .read = hiddev_read,
- .write = hiddev_write,
- .poll = hiddev_poll,
- .open = hiddev_open,
- .release = hiddev_release,
- .unlocked_ioctl = hiddev_ioctl,
- .fasync = hiddev_fasync,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = hiddev_compat_ioctl,
-#endif
- .llseek = noop_llseek,
-};
-
-static char *hiddev_devnode(struct device *dev, umode_t *mode)
-{
- return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
-}
-
-static struct usb_class_driver hiddev_class = {
- .name = "hiddev%d",
- .devnode = hiddev_devnode,
- .fops = &hiddev_fops,
- .minor_base = HIDDEV_MINOR_BASE,
-};
-
-/*
- * This is where hid.c calls us to connect a hid device to the hiddev driver
- */
-int hiddev_connect(struct hid_device *hid, unsigned int force)
-{
- struct hiddev *hiddev;
- struct usbhid_device *usbhid = hid->driver_data;
- int retval;
-
- if (!force) {
- unsigned int i;
- for (i = 0; i < hid->maxcollection; i++)
- if (hid->collection[i].type ==
- HID_COLLECTION_APPLICATION &&
- !IS_INPUT_APPLICATION(hid->collection[i].usage))
- break;
-
- if (i == hid->maxcollection)
- return -1;
- }
-
- if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
- return -1;
-
- init_waitqueue_head(&hiddev->wait);
- INIT_LIST_HEAD(&hiddev->list);
- spin_lock_init(&hiddev->list_lock);
- mutex_init(&hiddev->existancelock);
- hid->hiddev = hiddev;
- hiddev->hid = hid;
- hiddev->exist = 1;
- retval = usb_register_dev(usbhid->intf, &hiddev_class);
- if (retval) {
- hid_err(hid, "Not able to get a minor for this device\n");
- hid->hiddev = NULL;
- kfree(hiddev);
- return -1;
- }
- return 0;
-}
-
-/*
- * This is where hid.c calls us to disconnect a hiddev device from the
- * corresponding hid device (usually because the usb device has disconnected)
- */
-static struct usb_class_driver hiddev_class;
-void hiddev_disconnect(struct hid_device *hid)
-{
- struct hiddev *hiddev = hid->hiddev;
- struct usbhid_device *usbhid = hid->driver_data;
-
- usb_deregister_dev(usbhid->intf, &hiddev_class);
-
- mutex_lock(&hiddev->existancelock);
- hiddev->exist = 0;
-
- if (hiddev->open) {
- mutex_unlock(&hiddev->existancelock);
- usbhid_close(hiddev->hid);
- wake_up_interruptible(&hiddev->wait);
- } else {
- mutex_unlock(&hiddev->existancelock);
- kfree(hiddev);
- }
-}
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/usbhid.h b/ANDROID_3.4.5/drivers/hid/usbhid/usbhid.h
deleted file mode 100644
index cb8f703e..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/usbhid.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef __USBHID_H
-#define __USBHID_H
-
-/*
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2001 Vojtech Pavlik
- * Copyright (c) 2006 Jiri Kosina
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/timer.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/input.h>
-
-/* API provided by hid-core.c for USB HID drivers */
-int usbhid_wait_io(struct hid_device* hid);
-void usbhid_close(struct hid_device *hid);
-int usbhid_open(struct hid_device *hid);
-void usbhid_init_reports(struct hid_device *hid);
-void usbhid_submit_report
-(struct hid_device *hid, struct hid_report *report, unsigned char dir);
-int usbhid_get_power(struct hid_device *hid);
-void usbhid_put_power(struct hid_device *hid);
-struct usb_interface *usbhid_find_interface(int minor);
-
-/* iofl flags */
-#define HID_CTRL_RUNNING 1
-#define HID_OUT_RUNNING 2
-#define HID_IN_RUNNING 3
-#define HID_RESET_PENDING 4
-#define HID_SUSPENDED 5
-#define HID_CLEAR_HALT 6
-#define HID_DISCONNECTED 7
-#define HID_STARTED 8
-#define HID_REPORTED_IDLE 9
-#define HID_KEYS_PRESSED 10
-
-/*
- * USB-specific HID struct, to be pointed to
- * from struct hid_device->driver_data
- */
-
-struct usbhid_device {
- struct hid_device *hid; /* pointer to corresponding HID dev */
-
- struct usb_interface *intf; /* USB interface */
- int ifnum; /* USB interface number */
-
- unsigned int bufsize; /* URB buffer size */
-
- struct urb *urbin; /* Input URB */
- char *inbuf; /* Input buffer */
- dma_addr_t inbuf_dma; /* Input buffer dma */
-
- struct urb *urbctrl; /* Control URB */
- struct usb_ctrlrequest *cr; /* Control request struct */
- struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */
- unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
- char *ctrlbuf; /* Control buffer */
- dma_addr_t ctrlbuf_dma; /* Control buffer dma */
- unsigned long last_ctrl; /* record of last output for timeouts */
-
- struct urb *urbout; /* Output URB */
- struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
- unsigned char outhead, outtail; /* Output pipe fifo head & tail */
- char *outbuf; /* Output buffer */
- dma_addr_t outbuf_dma; /* Output buffer dma */
- unsigned long last_out; /* record of last output for timeouts */
-
- spinlock_t lock; /* fifo spinlock */
- unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
- struct timer_list io_retry; /* Retry timer */
- unsigned long stop_retry; /* Time to give up, in jiffies */
- unsigned int retry_delay; /* Delay length in ms */
- struct work_struct reset_work; /* Task context for resets */
- wait_queue_head_t wait; /* For sleeping */
- int ledcount; /* counting the number of active leds */
-
- struct work_struct led_work; /* Task context for setting LEDs */
-};
-
-#define hid_to_usb_dev(hid_dev) \
- container_of(hid_dev->dev.parent->parent, struct usb_device, dev)
-
-#endif
-
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/usbkbd.c b/ANDROID_3.4.5/drivers/hid/usbhid/usbkbd.c
deleted file mode 100644
index 79608698..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/usbkbd.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Copyright (c) 1999-2001 Vojtech Pavlik
- *
- * USB HIDBP Keyboard support
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb/input.h>
-#include <linux/hid.h>
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION ""
-#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB HID Boot Protocol keyboard driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-static const unsigned char usb_kbd_keycode[256] = {
- 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
- 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
- 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
- 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
- 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
- 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
- 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
- 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
- 150,158,159,128,136,177,178,176,142,152,173,140
-};
-
-
-/**
- * struct usb_kbd - state of each attached keyboard
- * @dev: input device associated with this keyboard
- * @usbdev: usb device associated with this keyboard
- * @old: data received in the past from the @irq URB representing which
- * keys were pressed. By comparing with the current list of keys
- * that are pressed, we are able to see key releases.
- * @irq: URB for receiving a list of keys that are pressed when a
- * new key is pressed or a key that was pressed is released.
- * @led: URB for sending LEDs (e.g. numlock, ...)
- * @newleds: data that will be sent with the @led URB representing which LEDs
- should be on
- * @name: Name of the keyboard. @dev's name field points to this buffer
- * @phys: Physical path of the keyboard. @dev's phys field points to this
- * buffer
- * @new: Buffer for the @irq URB
- * @cr: Control request for @led URB
- * @leds: Buffer for the @led URB
- * @new_dma: DMA address for @irq URB
- * @leds_dma: DMA address for @led URB
- * @leds_lock: spinlock that protects @leds, @newleds, and @led_urb_submitted
- * @led_urb_submitted: indicates whether @led is in progress, i.e. it has been
- * submitted and its completion handler has not returned yet
- * without resubmitting @led
- */
-struct usb_kbd {
- struct input_dev *dev;
- struct usb_device *usbdev;
- unsigned char old[8];
- struct urb *irq, *led;
- unsigned char newleds;
- char name[128];
- char phys[64];
-
- unsigned char *new;
- struct usb_ctrlrequest *cr;
- unsigned char *leds;
- dma_addr_t new_dma;
- dma_addr_t leds_dma;
-
- spinlock_t leds_lock;
- bool led_urb_submitted;
-
-};
-
-static void usb_kbd_irq(struct urb *urb)
-{
- struct usb_kbd *kbd = urb->context;
- int i;
-
- switch (urb->status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default: /* error */
- goto resubmit;
- }
-
- for (i = 0; i < 8; i++)
- input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
-
- for (i = 2; i < 8; i++) {
-
- if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
- if (usb_kbd_keycode[kbd->old[i]])
- input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
- else
- hid_info(urb->dev,
- "Unknown key (scancode %#x) released.\n",
- kbd->old[i]);
- }
-
- if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
- if (usb_kbd_keycode[kbd->new[i]])
- input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
- else
- hid_info(urb->dev,
- "Unknown key (scancode %#x) released.\n",
- kbd->new[i]);
- }
- }
-
- input_sync(kbd->dev);
-
- memcpy(kbd->old, kbd->new, 8);
-
-resubmit:
- i = usb_submit_urb (urb, GFP_ATOMIC);
- if (i)
- hid_err(urb->dev, "can't resubmit intr, %s-%s/input0, status %d",
- kbd->usbdev->bus->bus_name,
- kbd->usbdev->devpath, i);
-}
-
-static int usb_kbd_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int value)
-{
- unsigned long flags;
- struct usb_kbd *kbd = input_get_drvdata(dev);
-
- if (type != EV_LED)
- return -1;
-
- spin_lock_irqsave(&kbd->leds_lock, flags);
- kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) |
- (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) |
- (!!test_bit(LED_NUML, dev->led));
-
- if (kbd->led_urb_submitted){
- spin_unlock_irqrestore(&kbd->leds_lock, flags);
- return 0;
- }
-
- if (*(kbd->leds) == kbd->newleds){
- spin_unlock_irqrestore(&kbd->leds_lock, flags);
- return 0;
- }
-
- *(kbd->leds) = kbd->newleds;
-
- kbd->led->dev = kbd->usbdev;
- if (usb_submit_urb(kbd->led, GFP_ATOMIC))
- pr_err("usb_submit_urb(leds) failed\n");
- else
- kbd->led_urb_submitted = true;
-
- spin_unlock_irqrestore(&kbd->leds_lock, flags);
-
- return 0;
-}
-
-static void usb_kbd_led(struct urb *urb)
-{
- unsigned long flags;
- struct usb_kbd *kbd = urb->context;
-
- if (urb->status)
- hid_warn(urb->dev, "led urb status %d received\n",
- urb->status);
-
- spin_lock_irqsave(&kbd->leds_lock, flags);
-
- if (*(kbd->leds) == kbd->newleds){
- kbd->led_urb_submitted = false;
- spin_unlock_irqrestore(&kbd->leds_lock, flags);
- return;
- }
-
- *(kbd->leds) = kbd->newleds;
-
- kbd->led->dev = kbd->usbdev;
- if (usb_submit_urb(kbd->led, GFP_ATOMIC)){
- hid_err(urb->dev, "usb_submit_urb(leds) failed\n");
- kbd->led_urb_submitted = false;
- }
- spin_unlock_irqrestore(&kbd->leds_lock, flags);
-
-}
-
-static int usb_kbd_open(struct input_dev *dev)
-{
- struct usb_kbd *kbd = input_get_drvdata(dev);
-
- kbd->irq->dev = kbd->usbdev;
- if (usb_submit_urb(kbd->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void usb_kbd_close(struct input_dev *dev)
-{
- struct usb_kbd *kbd = input_get_drvdata(dev);
-
- usb_kill_urb(kbd->irq);
-}
-
-static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
-{
- if (!(kbd->irq = usb_alloc_urb(0, GFP_KERNEL)))
- return -1;
- if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
- return -1;
- if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
- return -1;
- if (!(kbd->cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL)))
- return -1;
- if (!(kbd->leds = usb_alloc_coherent(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
- return -1;
-
- return 0;
-}
-
-static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
-{
- usb_free_urb(kbd->irq);
- usb_free_urb(kbd->led);
- usb_free_coherent(dev, 8, kbd->new, kbd->new_dma);
- kfree(kbd->cr);
- usb_free_coherent(dev, 1, kbd->leds, kbd->leds_dma);
-}
-
-static int usb_kbd_probe(struct usb_interface *iface,
- const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(iface);
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_kbd *kbd;
- struct input_dev *input_dev;
- int i, pipe, maxp;
- int error = -ENOMEM;
-
- interface = iface->cur_altsetting;
-
- if (interface->desc.bNumEndpoints != 1)
- return -ENODEV;
-
- endpoint = &interface->endpoint[0].desc;
- if (!usb_endpoint_is_int_in(endpoint))
- return -ENODEV;
-
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!kbd || !input_dev)
- goto fail1;
-
- if (usb_kbd_alloc_mem(dev, kbd))
- goto fail2;
-
- kbd->usbdev = dev;
- kbd->dev = input_dev;
- spin_lock_init(&kbd->leds_lock);
-
- if (dev->manufacturer)
- strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
-
- if (dev->product) {
- if (dev->manufacturer)
- strlcat(kbd->name, " ", sizeof(kbd->name));
- strlcat(kbd->name, dev->product, sizeof(kbd->name));
- }
-
- if (!strlen(kbd->name))
- snprintf(kbd->name, sizeof(kbd->name),
- "USB HIDBP Keyboard %04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
- strlcat(kbd->phys, "/input0", sizeof(kbd->phys));
-
- input_dev->name = kbd->name;
- input_dev->phys = kbd->phys;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->dev.parent = &iface->dev;
-
- input_set_drvdata(input_dev, kbd);
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
- BIT_MASK(EV_REP);
- input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
- BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_COMPOSE) |
- BIT_MASK(LED_KANA);
-
- for (i = 0; i < 255; i++)
- set_bit(usb_kbd_keycode[i], input_dev->keybit);
- clear_bit(0, input_dev->keybit);
-
- input_dev->event = usb_kbd_event;
- input_dev->open = usb_kbd_open;
- input_dev->close = usb_kbd_close;
-
- usb_fill_int_urb(kbd->irq, dev, pipe,
- kbd->new, (maxp > 8 ? 8 : maxp),
- usb_kbd_irq, kbd, endpoint->bInterval);
- kbd->irq->transfer_dma = kbd->new_dma;
- kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- kbd->cr->bRequest = 0x09;
- kbd->cr->wValue = cpu_to_le16(0x200);
- kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
- kbd->cr->wLength = cpu_to_le16(1);
-
- usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
- (void *) kbd->cr, kbd->leds, 1,
- usb_kbd_led, kbd);
- kbd->led->transfer_dma = kbd->leds_dma;
- kbd->led->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- error = input_register_device(kbd->dev);
- if (error)
- goto fail2;
-
- usb_set_intfdata(iface, kbd);
- device_set_wakeup_enable(&dev->dev, 1);
- return 0;
-
-fail2:
- usb_kbd_free_mem(dev, kbd);
-fail1:
- input_free_device(input_dev);
- kfree(kbd);
- return error;
-}
-
-static void usb_kbd_disconnect(struct usb_interface *intf)
-{
- struct usb_kbd *kbd = usb_get_intfdata (intf);
-
- usb_set_intfdata(intf, NULL);
- if (kbd) {
- usb_kill_urb(kbd->irq);
- input_unregister_device(kbd->dev);
- usb_kill_urb(kbd->led);
- usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
- kfree(kbd);
- }
-}
-
-static struct usb_device_id usb_kbd_id_table [] = {
- { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
- USB_INTERFACE_PROTOCOL_KEYBOARD) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
-
-static struct usb_driver usb_kbd_driver = {
- .name = "usbkbd",
- .probe = usb_kbd_probe,
- .disconnect = usb_kbd_disconnect,
- .id_table = usb_kbd_id_table,
-};
-
-module_usb_driver(usb_kbd_driver);
diff --git a/ANDROID_3.4.5/drivers/hid/usbhid/usbmouse.c b/ANDROID_3.4.5/drivers/hid/usbhid/usbmouse.c
deleted file mode 100644
index 0f6be45d..00000000
--- a/ANDROID_3.4.5/drivers/hid/usbhid/usbmouse.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 1999-2001 Vojtech Pavlik
- *
- * USB HIDBP Mouse support
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb/input.h>
-#include <linux/hid.h>
-
-/* for apple IDs */
-#ifdef CONFIG_USB_HID_MODULE
-#include "../hid-ids.h"
-#endif
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.6"
-#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB HID Boot Protocol mouse driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-struct usb_mouse {
- char name[128];
- char phys[64];
- struct usb_device *usbdev;
- struct input_dev *dev;
- struct urb *irq;
-
- signed char *data;
- dma_addr_t data_dma;
-};
-
-static void usb_mouse_irq(struct urb *urb)
-{
- struct usb_mouse *mouse = urb->context;
- signed char *data = mouse->data;
- struct input_dev *dev = mouse->dev;
- int status;
-
- switch (urb->status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default: /* error */
- goto resubmit;
- }
-
- input_report_key(dev, BTN_LEFT, data[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
- input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
- input_report_key(dev, BTN_SIDE, data[0] & 0x08);
- input_report_key(dev, BTN_EXTRA, data[0] & 0x10);
-
- input_report_rel(dev, REL_X, data[1]);
- input_report_rel(dev, REL_Y, data[2]);
- input_report_rel(dev, REL_WHEEL, data[3]);
-
- input_sync(dev);
-resubmit:
- status = usb_submit_urb (urb, GFP_ATOMIC);
- if (status)
- err ("can't resubmit intr, %s-%s/input0, status %d",
- mouse->usbdev->bus->bus_name,
- mouse->usbdev->devpath, status);
-}
-
-static int usb_mouse_open(struct input_dev *dev)
-{
- struct usb_mouse *mouse = input_get_drvdata(dev);
-
- mouse->irq->dev = mouse->usbdev;
- if (usb_submit_urb(mouse->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void usb_mouse_close(struct input_dev *dev)
-{
- struct usb_mouse *mouse = input_get_drvdata(dev);
-
- usb_kill_urb(mouse->irq);
-}
-
-static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_mouse *mouse;
- struct input_dev *input_dev;
- int pipe, maxp;
- int error = -ENOMEM;
-
- interface = intf->cur_altsetting;
-
- if (interface->desc.bNumEndpoints != 1)
- return -ENODEV;
-
- endpoint = &interface->endpoint[0].desc;
- if (!usb_endpoint_is_int_in(endpoint))
- return -ENODEV;
-
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!mouse || !input_dev)
- goto fail1;
-
- mouse->data = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &mouse->data_dma);
- if (!mouse->data)
- goto fail1;
-
- mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!mouse->irq)
- goto fail2;
-
- mouse->usbdev = dev;
- mouse->dev = input_dev;
-
- if (dev->manufacturer)
- strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
-
- if (dev->product) {
- if (dev->manufacturer)
- strlcat(mouse->name, " ", sizeof(mouse->name));
- strlcat(mouse->name, dev->product, sizeof(mouse->name));
- }
-
- if (!strlen(mouse->name))
- snprintf(mouse->name, sizeof(mouse->name),
- "USB HIDBP Mouse %04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
- strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
-
- input_dev->name = mouse->name;
- input_dev->phys = mouse->phys;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->dev.parent = &intf->dev;
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
- input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
- BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
- input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
- input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
- BIT_MASK(BTN_EXTRA);
- input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
-
- input_set_drvdata(input_dev, mouse);
-
- input_dev->open = usb_mouse_open;
- input_dev->close = usb_mouse_close;
-
- usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
- (maxp > 8 ? 8 : maxp),
- usb_mouse_irq, mouse, endpoint->bInterval);
- mouse->irq->transfer_dma = mouse->data_dma;
- mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- error = input_register_device(mouse->dev);
- if (error)
- goto fail3;
-
- usb_set_intfdata(intf, mouse);
- return 0;
-
-fail3:
- usb_free_urb(mouse->irq);
-fail2:
- usb_free_coherent(dev, 8, mouse->data, mouse->data_dma);
-fail1:
- input_free_device(input_dev);
- kfree(mouse);
- return error;
-}
-
-static void usb_mouse_disconnect(struct usb_interface *intf)
-{
- struct usb_mouse *mouse = usb_get_intfdata (intf);
-
- usb_set_intfdata(intf, NULL);
- if (mouse) {
- usb_kill_urb(mouse->irq);
- input_unregister_device(mouse->dev);
- usb_free_urb(mouse->irq);
- usb_free_coherent(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
- kfree(mouse);
- }
-}
-
-static struct usb_device_id usb_mouse_id_table [] = {
- { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
- USB_INTERFACE_PROTOCOL_MOUSE) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
-
-static struct usb_driver usb_mouse_driver = {
- .name = "usbmouse",
- .probe = usb_mouse_probe,
- .disconnect = usb_mouse_disconnect,
- .id_table = usb_mouse_id_table,
-};
-
-module_usb_driver(usb_mouse_driver);