diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/hid/Kconfig | 63 | ||||
| -rw-r--r-- | drivers/hid/Makefile | 9 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 12 | ||||
| -rw-r--r-- | drivers/hid/hid-elo.c | 273 | ||||
| -rw-r--r-- | drivers/hid/hid-holtek-mouse.c | 77 | ||||
| -rw-r--r-- | drivers/hid/hid-huion.c | 177 | ||||
| -rw-r--r-- | drivers/hid/hid-hyperv.c | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 22 | ||||
| -rw-r--r-- | drivers/hid/hid-input.c | 11 | ||||
| -rw-r--r-- | drivers/hid/hid-kye.c | 21 | ||||
| -rw-r--r-- | drivers/hid/hid-multitouch.c | 34 | ||||
| -rw-r--r-- | drivers/hid/hid-ps3remote.c | 204 | ||||
| -rw-r--r-- | drivers/hid/hid-roccat.c | 16 | ||||
| -rw-r--r-- | drivers/hid/hid-sony.c | 473 | ||||
| -rw-r--r-- | drivers/hid/hid-wacom.c | 14 | ||||
| -rw-r--r-- | drivers/hid/hid-wiimote-core.c | 1658 | ||||
| -rw-r--r-- | drivers/hid/hid-wiimote-debug.c | 14 | ||||
| -rw-r--r-- | drivers/hid/hid-wiimote-ext.c | 849 | ||||
| -rw-r--r-- | drivers/hid/hid-wiimote-modules.c | 2086 | ||||
| -rw-r--r-- | drivers/hid/hid-wiimote.h | 217 | ||||
| -rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 20 |
21 files changed, 4540 insertions, 1714 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index fb52f3f6de80..14ef6ab69790 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -217,6 +217,13 @@ config HID_ELECOM | |||
| 217 | ---help--- | 217 | ---help--- |
| 218 | Support for the ELECOM BM084 (bluetooth mouse). | 218 | Support for the ELECOM BM084 (bluetooth mouse). |
| 219 | 219 | ||
| 220 | config HID_ELO | ||
| 221 | tristate "ELO USB 4000/4500 touchscreen" | ||
| 222 | depends on USB_HID | ||
| 223 | ---help--- | ||
| 224 | Support for the ELO USB 4000/4500 touchscreens. Note that this is for | ||
| 225 | different devices than those handled by CONFIG_TOUCHSCREEN_USB_ELO. | ||
| 226 | |||
| 220 | config HID_EZKEY | 227 | config HID_EZKEY |
| 221 | tristate "Ezkey BTC 8193 keyboard" if EXPERT | 228 | tristate "Ezkey BTC 8193 keyboard" if EXPERT |
| 222 | depends on HID | 229 | depends on HID |
| @@ -231,6 +238,9 @@ config HID_HOLTEK | |||
| 231 | Support for Holtek based devices: | 238 | Support for Holtek based devices: |
| 232 | - Holtek On Line Grip based game controller | 239 | - Holtek On Line Grip based game controller |
| 233 | - Trust GXT 18 Gaming Keyboard | 240 | - Trust GXT 18 Gaming Keyboard |
| 241 | - Sharkoon Drakonia / Perixx MX-2000 gaming mice | ||
| 242 | - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 / | ||
| 243 | Zalman ZM-GM1 | ||
| 234 | 244 | ||
| 235 | config HOLTEK_FF | 245 | config HOLTEK_FF |
| 236 | bool "Holtek On Line Grip force feedback support" | 246 | bool "Holtek On Line Grip force feedback support" |
| @@ -240,6 +250,12 @@ config HOLTEK_FF | |||
| 240 | Say Y here if you have a Holtek On Line Grip based game controller | 250 | Say Y here if you have a Holtek On Line Grip based game controller |
| 241 | and want to have force feedback support for it. | 251 | and want to have force feedback support for it. |
| 242 | 252 | ||
| 253 | config HID_HUION | ||
| 254 | tristate "Huion tablets" | ||
| 255 | depends on USB_HID | ||
| 256 | ---help--- | ||
| 257 | Support for Huion 580 tablet. | ||
| 258 | |||
| 243 | config HID_KEYTOUCH | 259 | config HID_KEYTOUCH |
| 244 | tristate "Keytouch HID devices" | 260 | tristate "Keytouch HID devices" |
| 245 | depends on HID | 261 | depends on HID |
| @@ -561,15 +577,6 @@ config HID_PRIMAX | |||
| 561 | Support for Primax devices that are not fully compliant with the | 577 | Support for Primax devices that are not fully compliant with the |
| 562 | HID standard. | 578 | HID standard. |
| 563 | 579 | ||
| 564 | config HID_PS3REMOTE | ||
| 565 | tristate "Sony PS3 BD Remote Control" | ||
| 566 | depends on HID | ||
| 567 | ---help--- | ||
| 568 | Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech | ||
| 569 | Harmony Adapter for PS3, which connect over Bluetooth. | ||
| 570 | |||
| 571 | Support for the 6-axis controllers is provided by HID_SONY. | ||
| 572 | |||
| 573 | config HID_ROCCAT | 580 | config HID_ROCCAT |
| 574 | tristate "Roccat device support" | 581 | tristate "Roccat device support" |
| 575 | depends on USB_HID | 582 | depends on USB_HID |
| @@ -594,12 +601,17 @@ config HID_SAMSUNG | |||
| 594 | Support for Samsung InfraRed remote control or keyboards. | 601 | Support for Samsung InfraRed remote control or keyboards. |
| 595 | 602 | ||
| 596 | config HID_SONY | 603 | config HID_SONY |
| 597 | tristate "Sony PS3 controller" | 604 | tristate "Sony PS2/3 accessories" |
| 598 | depends on USB_HID | 605 | depends on USB_HID |
| 606 | depends on NEW_LEDS | ||
| 607 | depends on LEDS_CLASS | ||
| 599 | ---help--- | 608 | ---help--- |
| 600 | Support for Sony PS3 6-axis controllers. | 609 | Support for |
| 601 | 610 | ||
| 602 | Support for the Sony PS3 BD Remote is provided by HID_PS3REMOTE. | 611 | * Sony PS3 6-axis controllers |
| 612 | * Buzz controllers | ||
| 613 | * Sony PS3 Blue-ray Disk Remote Control (Bluetooth) | ||
| 614 | * Logitech Harmony adapter for Sony Playstation 3 (Bluetooth) | ||
| 603 | 615 | ||
| 604 | config HID_SPEEDLINK | 616 | config HID_SPEEDLINK |
| 605 | tristate "Speedlink VAD Cezanne mouse support" | 617 | tristate "Speedlink VAD Cezanne mouse support" |
| @@ -707,22 +719,29 @@ config HID_WACOM | |||
| 707 | Support for Wacom Graphire Bluetooth and Intuos4 WL tablets. | 719 | Support for Wacom Graphire Bluetooth and Intuos4 WL tablets. |
| 708 | 720 | ||
| 709 | config HID_WIIMOTE | 721 | config HID_WIIMOTE |
| 710 | tristate "Nintendo Wii Remote support" | 722 | tristate "Nintendo Wii / Wii U peripherals" |
| 711 | depends on HID | 723 | depends on HID |
| 712 | depends on LEDS_CLASS | 724 | depends on LEDS_CLASS |
| 713 | select POWER_SUPPLY | 725 | select POWER_SUPPLY |
| 714 | select INPUT_FF_MEMLESS | 726 | select INPUT_FF_MEMLESS |
| 715 | ---help--- | 727 | ---help--- |
| 716 | Support for the Nintendo Wii Remote bluetooth device. | 728 | Support for Nintendo Wii and Wii U Bluetooth peripherals. Supported |
| 729 | devices are the Wii Remote and its extension devices, but also devices | ||
| 730 | based on the Wii Remote like the Wii U Pro Controller or the | ||
| 731 | Wii Balance Board. | ||
| 717 | 732 | ||
| 718 | config HID_WIIMOTE_EXT | 733 | Support for all official Nintendo extensions is available, however, 3rd |
| 719 | bool "Nintendo Wii Remote Extension support" | 734 | party extensions might not be supported. Please report these devices to: |
| 720 | depends on HID_WIIMOTE | 735 | http://github.com/dvdhrm/xwiimote/issues |
| 721 | default HID_WIIMOTE | 736 | |
| 722 | ---help--- | 737 | Other Nintendo Wii U peripherals that are IEEE 802.11 based (including |
| 723 | Support for extension controllers of the Nintendo Wii Remote. Say yes | 738 | the Wii U Gamepad) might be supported in the future. But currently |
| 724 | here if you want to use the Nintendo Motion+, Nunchuck or Classic | 739 | support is limited to Bluetooth based devices. |
| 725 | extension controllers with your Wii Remote. | 740 | |
| 741 | If unsure, say N. | ||
| 742 | |||
| 743 | To compile this driver as a module, choose M here: the | ||
| 744 | module will be called hid-wiimote. | ||
| 726 | 745 | ||
| 727 | config HID_ZEROPLUS | 746 | config HID_ZEROPLUS |
| 728 | tristate "Zeroplus based game controller support" | 747 | tristate "Zeroplus based game controller support" |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 2065694f57ab..6f687287e212 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
| @@ -28,10 +28,7 @@ ifdef CONFIG_LOGIWHEELS_FF | |||
| 28 | hid-logitech-y += hid-lg4ff.o | 28 | hid-logitech-y += hid-lg4ff.o |
| 29 | endif | 29 | endif |
| 30 | 30 | ||
| 31 | hid-wiimote-y := hid-wiimote-core.o | 31 | hid-wiimote-y := hid-wiimote-core.o hid-wiimote-modules.o |
| 32 | ifdef CONFIG_HID_WIIMOTE_EXT | ||
| 33 | hid-wiimote-y += hid-wiimote-ext.o | ||
| 34 | endif | ||
| 35 | ifdef CONFIG_DEBUG_FS | 32 | ifdef CONFIG_DEBUG_FS |
| 36 | hid-wiimote-y += hid-wiimote-debug.o | 33 | hid-wiimote-y += hid-wiimote-debug.o |
| 37 | endif | 34 | endif |
| @@ -48,10 +45,13 @@ obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o | |||
| 48 | obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o | 45 | obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o |
| 49 | obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o | 46 | obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o |
| 50 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o | 47 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o |
| 48 | obj-$(CONFIG_HID_ELO) += hid-elo.o | ||
| 51 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o | 49 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o |
| 52 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o | 50 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o |
| 53 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o | 51 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o |
| 52 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o | ||
| 54 | obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o | 53 | obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o |
| 54 | obj-$(CONFIG_HID_HUION) += hid-huion.o | ||
| 55 | obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o | 55 | obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o |
| 56 | obj-$(CONFIG_HID_ICADE) += hid-icade.o | 56 | obj-$(CONFIG_HID_ICADE) += hid-icade.o |
| 57 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o | 57 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o |
| @@ -92,7 +92,6 @@ hid-picolcd-y += hid-picolcd_debugfs.o | |||
| 92 | endif | 92 | endif |
| 93 | 93 | ||
| 94 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o | 94 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o |
| 95 | obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o | ||
| 96 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ | 95 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ |
| 97 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ | 96 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ |
| 98 | hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ | 97 | hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 264f55099940..e39dac68063c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1293,7 +1293,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i | |||
| 1293 | 1293 | ||
| 1294 | if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { | 1294 | if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { |
| 1295 | ret = hdrv->raw_event(hid, report, data, size); | 1295 | ret = hdrv->raw_event(hid, report, data, size); |
| 1296 | if (ret != 0) { | 1296 | if (ret < 0) { |
| 1297 | ret = ret < 0 ? ret : 0; | 1297 | ret = ret < 0 ? ret : 0; |
| 1298 | goto unlock; | 1298 | goto unlock; |
| 1299 | } | 1299 | } |
| @@ -1573,6 +1573,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1573 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1573 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
| 1574 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, | 1574 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, |
| 1575 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | 1575 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
| 1576 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, | ||
| 1577 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) }, | ||
| 1576 | { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, | 1578 | { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, |
| 1577 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1579 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
| 1578 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1580 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
| @@ -1584,10 +1586,14 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1584 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, | 1586 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, |
| 1585 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, | 1587 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, |
| 1586 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, | 1588 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, |
| 1589 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, | ||
| 1590 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, | ||
| 1591 | { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) }, | ||
| 1587 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, | 1592 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, |
| 1588 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, | 1593 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, |
| 1589 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1594 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
| 1590 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, | 1595 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, |
| 1596 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) }, | ||
| 1591 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 1597 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
| 1592 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) }, | 1598 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) }, |
| 1593 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, | 1599 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, |
| @@ -1680,6 +1686,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1680 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, | 1686 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, |
| 1681 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, | 1687 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, |
| 1682 | { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, | 1688 | { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, |
| 1689 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, | ||
| 1690 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, | ||
| 1683 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, | 1691 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, |
| 1684 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1692 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
| 1685 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, | 1693 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, |
| @@ -2042,6 +2050,8 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
| 2042 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, | 2050 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, |
| 2043 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, | 2051 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, |
| 2044 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, | 2052 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, |
| 2053 | { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) }, | ||
| 2054 | { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) }, | ||
| 2045 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, | 2055 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, |
| 2046 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, | 2056 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, |
| 2047 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, | 2057 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, |
diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c new file mode 100644 index 000000000000..f042a6cf8b18 --- /dev/null +++ b/drivers/hid/hid-elo.c | |||
| @@ -0,0 +1,273 @@ | |||
| 1 | /* | ||
| 2 | * HID driver for ELO usb touchscreen 4000/4500 | ||
| 3 | * | ||
| 4 | * Copyright (c) 2013 Jiri Slaby | ||
| 5 | * | ||
| 6 | * Data parsing taken from elousb driver by Vojtech Pavlik. | ||
| 7 | * | ||
| 8 | * This driver is licensed under the terms of GPLv2. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/hid.h> | ||
| 12 | #include <linux/input.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/usb.h> | ||
| 15 | #include <linux/workqueue.h> | ||
| 16 | |||
| 17 | #include "hid-ids.h" | ||
| 18 | |||
| 19 | #define ELO_PERIODIC_READ_INTERVAL HZ | ||
| 20 | #define ELO_SMARTSET_CMD_TIMEOUT 2000 /* msec */ | ||
| 21 | |||
| 22 | /* Elo SmartSet commands */ | ||
| 23 | #define ELO_FLUSH_SMARTSET_RESPONSES 0x02 /* Flush all pending smartset responses */ | ||
| 24 | #define ELO_SEND_SMARTSET_COMMAND 0x05 /* Send a smartset command */ | ||
| 25 | #define ELO_GET_SMARTSET_RESPONSE 0x06 /* Get a smartset response */ | ||
| 26 | #define ELO_DIAG 0x64 /* Diagnostics command */ | ||
| 27 | #define ELO_SMARTSET_PACKET_SIZE 8 | ||
| 28 | |||
| 29 | struct elo_priv { | ||
| 30 | struct usb_device *usbdev; | ||
| 31 | struct delayed_work work; | ||
| 32 | unsigned char buffer[ELO_SMARTSET_PACKET_SIZE]; | ||
| 33 | }; | ||
| 34 | |||
| 35 | static struct workqueue_struct *wq; | ||
| 36 | static bool use_fw_quirk = true; | ||
| 37 | module_param(use_fw_quirk, bool, S_IRUGO); | ||
| 38 | MODULE_PARM_DESC(use_fw_quirk, "Do periodic pokes for broken M firmwares (default = true)"); | ||
| 39 | |||
| 40 | static void elo_input_configured(struct hid_device *hdev, | ||
| 41 | struct hid_input *hidinput) | ||
| 42 | { | ||
| 43 | struct input_dev *input = hidinput->input; | ||
| 44 | |||
| 45 | set_bit(BTN_TOUCH, input->keybit); | ||
| 46 | set_bit(ABS_PRESSURE, input->absbit); | ||
| 47 | input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0); | ||
| 48 | } | ||
| 49 | |||
| 50 | static void elo_process_data(struct input_dev *input, const u8 *data, int size) | ||
| 51 | { | ||
| 52 | int press; | ||
| 53 | |||
| 54 | input_report_abs(input, ABS_X, (data[3] << 8) | data[2]); | ||
| 55 | input_report_abs(input, ABS_Y, (data[5] << 8) | data[4]); | ||
| 56 | |||
| 57 | press = 0; | ||
| 58 | if (data[1] & 0x80) | ||
| 59 | press = (data[7] << 8) | data[6]; | ||
| 60 | input_report_abs(input, ABS_PRESSURE, press); | ||
| 61 | |||
| 62 | if (data[1] & 0x03) { | ||
| 63 | input_report_key(input, BTN_TOUCH, 1); | ||
| 64 | input_sync(input); | ||
| 65 | } | ||
| 66 | |||
| 67 | if (data[1] & 0x04) | ||
| 68 | input_report_key(input, BTN_TOUCH, 0); | ||
| 69 | |||
| 70 | input_sync(input); | ||
| 71 | } | ||
| 72 | |||
| 73 | static int elo_raw_event(struct hid_device *hdev, struct hid_report *report, | ||
| 74 | u8 *data, int size) | ||
| 75 | { | ||
| 76 | struct hid_input *hidinput; | ||
| 77 | |||
| 78 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || list_empty(&hdev->inputs)) | ||
| 79 | return 0; | ||
| 80 | |||
| 81 | hidinput = list_first_entry(&hdev->inputs, struct hid_input, list); | ||
| 82 | |||
| 83 | switch (report->id) { | ||
| 84 | case 0: | ||
| 85 | if (data[0] == 'T') { /* Mandatory ELO packet marker */ | ||
| 86 | elo_process_data(hidinput->input, data, size); | ||
| 87 | return 1; | ||
| 88 | } | ||
| 89 | break; | ||
| 90 | default: /* unknown report */ | ||
| 91 | /* Unknown report type; pass upstream */ | ||
| 92 | hid_info(hdev, "unknown report type %d\n", report->id); | ||
| 93 | break; | ||
| 94 | } | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int elo_smartset_send_get(struct usb_device *dev, u8 command, | ||
| 100 | void *data) | ||
| 101 | { | ||
| 102 | unsigned int pipe; | ||
| 103 | u8 dir; | ||
| 104 | |||
| 105 | if (command == ELO_SEND_SMARTSET_COMMAND) { | ||
| 106 | pipe = usb_sndctrlpipe(dev, 0); | ||
| 107 | dir = USB_DIR_OUT; | ||
| 108 | } else if (command == ELO_GET_SMARTSET_RESPONSE) { | ||
| 109 | pipe = usb_rcvctrlpipe(dev, 0); | ||
| 110 | dir = USB_DIR_IN; | ||
| 111 | } else | ||
| 112 | return -EINVAL; | ||
| 113 | |||
| 114 | return usb_control_msg(dev, pipe, command, | ||
| 115 | dir | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 116 | 0, 0, data, ELO_SMARTSET_PACKET_SIZE, | ||
| 117 | ELO_SMARTSET_CMD_TIMEOUT); | ||
| 118 | } | ||
| 119 | |||
| 120 | static int elo_flush_smartset_responses(struct usb_device *dev) | ||
| 121 | { | ||
| 122 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
| 123 | ELO_FLUSH_SMARTSET_RESPONSES, | ||
| 124 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 125 | 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
| 126 | } | ||
| 127 | |||
| 128 | static void elo_work(struct work_struct *work) | ||
| 129 | { | ||
| 130 | struct elo_priv *priv = container_of(work, struct elo_priv, work.work); | ||
| 131 | struct usb_device *dev = priv->usbdev; | ||
| 132 | unsigned char *buffer = priv->buffer; | ||
| 133 | int ret; | ||
| 134 | |||
| 135 | ret = elo_flush_smartset_responses(dev); | ||
| 136 | if (ret < 0) { | ||
| 137 | dev_err(&dev->dev, "initial FLUSH_SMARTSET_RESPONSES failed, error %d\n", | ||
| 138 | ret); | ||
| 139 | goto fail; | ||
| 140 | } | ||
| 141 | |||
| 142 | /* send Diagnostics command */ | ||
| 143 | *buffer = ELO_DIAG; | ||
| 144 | ret = elo_smartset_send_get(dev, ELO_SEND_SMARTSET_COMMAND, buffer); | ||
| 145 | if (ret < 0) { | ||
| 146 | dev_err(&dev->dev, "send Diagnostics Command failed, error %d\n", | ||
| 147 | ret); | ||
| 148 | goto fail; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* get the result */ | ||
| 152 | ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE, buffer); | ||
| 153 | if (ret < 0) { | ||
| 154 | dev_err(&dev->dev, "get Diagnostics Command response failed, error %d\n", | ||
| 155 | ret); | ||
| 156 | goto fail; | ||
| 157 | } | ||
| 158 | |||
| 159 | /* read the ack */ | ||
| 160 | if (*buffer != 'A') { | ||
| 161 | ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE, | ||
| 162 | buffer); | ||
| 163 | if (ret < 0) { | ||
| 164 | dev_err(&dev->dev, "get acknowledge response failed, error %d\n", | ||
| 165 | ret); | ||
| 166 | goto fail; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | fail: | ||
| 171 | ret = elo_flush_smartset_responses(dev); | ||
| 172 | if (ret < 0) | ||
| 173 | dev_err(&dev->dev, "final FLUSH_SMARTSET_RESPONSES failed, error %d\n", | ||
| 174 | ret); | ||
| 175 | queue_delayed_work(wq, &priv->work, ELO_PERIODIC_READ_INTERVAL); | ||
| 176 | } | ||
| 177 | |||
| 178 | /* | ||
| 179 | * Not all Elo devices need the periodic HID descriptor reads. | ||
| 180 | * Only firmware version M needs this. | ||
| 181 | */ | ||
| 182 | static bool elo_broken_firmware(struct usb_device *dev) | ||
| 183 | { | ||
| 184 | return use_fw_quirk && le16_to_cpu(dev->descriptor.bcdDevice) == 0x10d; | ||
| 185 | } | ||
| 186 | |||
| 187 | static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
| 188 | { | ||
| 189 | struct elo_priv *priv; | ||
| 190 | int ret; | ||
| 191 | |||
| 192 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 193 | if (!priv) | ||
| 194 | return -ENOMEM; | ||
| 195 | |||
| 196 | INIT_DELAYED_WORK(&priv->work, elo_work); | ||
| 197 | priv->usbdev = interface_to_usbdev(to_usb_interface(hdev->dev.parent)); | ||
| 198 | |||
| 199 | hid_set_drvdata(hdev, priv); | ||
| 200 | |||
| 201 | ret = hid_parse(hdev); | ||
| 202 | if (ret) { | ||
| 203 | hid_err(hdev, "parse failed\n"); | ||
| 204 | goto err_free; | ||
| 205 | } | ||
| 206 | |||
| 207 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
| 208 | if (ret) { | ||
| 209 | hid_err(hdev, "hw start failed\n"); | ||
| 210 | goto err_free; | ||
| 211 | } | ||
| 212 | |||
| 213 | if (elo_broken_firmware(priv->usbdev)) { | ||
| 214 | hid_info(hdev, "broken firmware found, installing workaround\n"); | ||
| 215 | queue_delayed_work(wq, &priv->work, ELO_PERIODIC_READ_INTERVAL); | ||
| 216 | } | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | err_free: | ||
| 220 | kfree(priv); | ||
| 221 | return ret; | ||
| 222 | } | ||
| 223 | |||
| 224 | static void elo_remove(struct hid_device *hdev) | ||
| 225 | { | ||
| 226 | struct elo_priv *priv = hid_get_drvdata(hdev); | ||
| 227 | |||
| 228 | hid_hw_stop(hdev); | ||
| 229 | flush_workqueue(wq); | ||
| 230 | kfree(priv); | ||
| 231 | } | ||
| 232 | |||
| 233 | static const struct hid_device_id elo_devices[] = { | ||
| 234 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009), }, | ||
| 235 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030), }, | ||
| 236 | { } | ||
| 237 | }; | ||
| 238 | MODULE_DEVICE_TABLE(hid, elo_devices); | ||
| 239 | |||
| 240 | static struct hid_driver elo_driver = { | ||
| 241 | .name = "elo", | ||
| 242 | .id_table = elo_devices, | ||
| 243 | .probe = elo_probe, | ||
| 244 | .remove = elo_remove, | ||
| 245 | .raw_event = elo_raw_event, | ||
| 246 | .input_configured = elo_input_configured, | ||
| 247 | }; | ||
| 248 | |||
| 249 | static int __init elo_driver_init(void) | ||
| 250 | { | ||
| 251 | int ret; | ||
| 252 | |||
| 253 | wq = create_singlethread_workqueue("elousb"); | ||
| 254 | if (!wq) | ||
| 255 | return -ENOMEM; | ||
| 256 | |||
| 257 | ret = hid_register_driver(&elo_driver); | ||
| 258 | if (ret) | ||
| 259 | destroy_workqueue(wq); | ||
| 260 | |||
| 261 | return ret; | ||
| 262 | } | ||
| 263 | module_init(elo_driver_init); | ||
| 264 | |||
| 265 | static void __exit elo_driver_exit(void) | ||
| 266 | { | ||
| 267 | hid_unregister_driver(&elo_driver); | ||
| 268 | destroy_workqueue(wq); | ||
| 269 | } | ||
| 270 | module_exit(elo_driver_exit); | ||
| 271 | |||
| 272 | MODULE_AUTHOR("Jiri Slaby <jslaby@suse.cz>"); | ||
| 273 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c new file mode 100644 index 000000000000..7e6db3cf46f9 --- /dev/null +++ b/drivers/hid/hid-holtek-mouse.c | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | /* | ||
| 2 | * HID driver for Holtek gaming mice | ||
| 3 | * Copyright (c) 2013 Christian Ohm | ||
| 4 | * Heavily inspired by various other HID drivers that adjust the report | ||
| 5 | * descriptor. | ||
| 6 | */ | ||
| 7 | |||
| 8 | /* | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the Free | ||
| 11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 12 | * any later version. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/hid.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/usb.h> | ||
| 18 | |||
| 19 | #include "hid-ids.h" | ||
| 20 | |||
| 21 | /* | ||
| 22 | * The report descriptor of some Holtek based gaming mice specifies an | ||
| 23 | * excessively large number of consumer usages (2^15), which is more than | ||
| 24 | * HID_MAX_USAGES. This prevents proper parsing of the report descriptor. | ||
| 25 | * | ||
| 26 | * This driver fixes the report descriptor for: | ||
| 27 | * - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000 | ||
| 28 | * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200 | ||
| 29 | * and Zalman ZM-GM1 | ||
| 30 | */ | ||
| 31 | |||
| 32 | static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
| 33 | unsigned int *rsize) | ||
| 34 | { | ||
| 35 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
| 36 | |||
| 37 | if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { | ||
| 38 | /* Change usage maximum and logical maximum from 0x7fff to | ||
| 39 | * 0x2fff, so they don't exceed HID_MAX_USAGES */ | ||
| 40 | switch (hdev->product) { | ||
| 41 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067: | ||
| 42 | if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f | ||
| 43 | && rdesc[120] == 0xff && rdesc[121] == 0x7f) { | ||
| 44 | hid_info(hdev, "Fixing up report descriptor\n"); | ||
| 45 | rdesc[116] = rdesc[121] = 0x2f; | ||
| 46 | } | ||
| 47 | break; | ||
| 48 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A: | ||
| 49 | if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f | ||
| 50 | && rdesc[111] == 0xff && rdesc[112] == 0x7f) { | ||
| 51 | hid_info(hdev, "Fixing up report descriptor\n"); | ||
| 52 | rdesc[107] = rdesc[112] = 0x2f; | ||
| 53 | } | ||
| 54 | break; | ||
| 55 | } | ||
| 56 | |||
| 57 | } | ||
| 58 | return rdesc; | ||
| 59 | } | ||
| 60 | |||
| 61 | static const struct hid_device_id holtek_mouse_devices[] = { | ||
| 62 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, | ||
| 63 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, | ||
| 64 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, | ||
| 65 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, | ||
| 66 | { } | ||
| 67 | }; | ||
| 68 | MODULE_DEVICE_TABLE(hid, holtek_mouse_devices); | ||
| 69 | |||
| 70 | static struct hid_driver holtek_mouse_driver = { | ||
| 71 | .name = "holtek_mouse", | ||
| 72 | .id_table = holtek_mouse_devices, | ||
| 73 | .report_fixup = holtek_mouse_report_fixup, | ||
| 74 | }; | ||
| 75 | |||
| 76 | module_hid_driver(holtek_mouse_driver); | ||
| 77 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c new file mode 100644 index 000000000000..cbf4da4689ba --- /dev/null +++ b/drivers/hid/hid-huion.c | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | /* | ||
| 2 | * HID driver for Huion devices not fully compliant with HID standard | ||
| 3 | * | ||
| 4 | * Copyright (c) 2013 Martin Rusko | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the Free | ||
| 10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/hid.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/usb.h> | ||
| 18 | #include "usbhid/usbhid.h" | ||
| 19 | |||
| 20 | #include "hid-ids.h" | ||
| 21 | |||
| 22 | /* Original Huion 580 report descriptor size */ | ||
| 23 | #define HUION_580_RDESC_ORIG_SIZE 177 | ||
| 24 | |||
| 25 | /* Fixed Huion 580 report descriptor */ | ||
| 26 | static __u8 huion_580_rdesc_fixed[] = { | ||
| 27 | 0x05, 0x0D, /* Usage Page (Digitizer), */ | ||
| 28 | 0x09, 0x02, /* Usage (Pen), */ | ||
| 29 | 0xA1, 0x01, /* Collection (Application), */ | ||
| 30 | 0x85, 0x07, /* Report ID (7), */ | ||
| 31 | 0x09, 0x20, /* Usage (Stylus), */ | ||
| 32 | 0xA0, /* Collection (Physical), */ | ||
| 33 | 0x14, /* Logical Minimum (0), */ | ||
| 34 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
| 35 | 0x75, 0x01, /* Report Size (1), */ | ||
| 36 | 0x09, 0x42, /* Usage (Tip Switch), */ | ||
| 37 | 0x09, 0x44, /* Usage (Barrel Switch), */ | ||
| 38 | 0x09, 0x46, /* Usage (Tablet Pick), */ | ||
| 39 | 0x95, 0x03, /* Report Count (3), */ | ||
| 40 | 0x81, 0x02, /* Input (Variable), */ | ||
| 41 | 0x95, 0x03, /* Report Count (3), */ | ||
| 42 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
| 43 | 0x09, 0x32, /* Usage (In Range), */ | ||
| 44 | 0x95, 0x01, /* Report Count (1), */ | ||
| 45 | 0x81, 0x02, /* Input (Variable), */ | ||
| 46 | 0x95, 0x01, /* Report Count (1), */ | ||
| 47 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
| 48 | 0x75, 0x10, /* Report Size (16), */ | ||
| 49 | 0x95, 0x01, /* Report Count (1), */ | ||
| 50 | 0xA4, /* Push, */ | ||
| 51 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
| 52 | 0x65, 0x13, /* Unit (Inch), */ | ||
| 53 | 0x55, 0xFD, /* Unit Exponent (-3), */ | ||
| 54 | 0x34, /* Physical Minimum (0), */ | ||
| 55 | 0x09, 0x30, /* Usage (X), */ | ||
| 56 | 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ | ||
| 57 | 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */ | ||
| 58 | 0x81, 0x02, /* Input (Variable), */ | ||
| 59 | 0x09, 0x31, /* Usage (Y), */ | ||
| 60 | 0x46, 0x88, 0x13, /* Physical Maximum (5000), */ | ||
| 61 | 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ | ||
| 62 | 0x81, 0x02, /* Input (Variable), */ | ||
| 63 | 0xB4, /* Pop, */ | ||
| 64 | 0x09, 0x30, /* Usage (Tip Pressure), */ | ||
| 65 | 0x26, 0xFF, 0x07, /* Logical Maximum (2047), */ | ||
| 66 | 0x81, 0x02, /* Input (Variable), */ | ||
| 67 | 0xC0, /* End Collection, */ | ||
| 68 | 0xC0 /* End Collection */ | ||
| 69 | }; | ||
| 70 | |||
| 71 | static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
| 72 | unsigned int *rsize) | ||
| 73 | { | ||
| 74 | switch (hdev->product) { | ||
| 75 | case USB_DEVICE_ID_HUION_580: | ||
| 76 | if (*rsize == HUION_580_RDESC_ORIG_SIZE) { | ||
| 77 | rdesc = huion_580_rdesc_fixed; | ||
| 78 | *rsize = sizeof(huion_580_rdesc_fixed); | ||
| 79 | } | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | return rdesc; | ||
| 83 | } | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Enable fully-functional tablet mode by reading special string | ||
| 87 | * descriptor. | ||
| 88 | * | ||
| 89 | * @hdev: HID device | ||
| 90 | * | ||
| 91 | * The specific string descriptor and data were discovered by sniffing | ||
| 92 | * the Windows driver traffic. | ||
| 93 | */ | ||
| 94 | static int huion_tablet_enable(struct hid_device *hdev) | ||
| 95 | { | ||
| 96 | int rc; | ||
| 97 | char buf[22]; | ||
| 98 | |||
| 99 | rc = usb_string(hid_to_usb_dev(hdev), 0x64, buf, sizeof(buf)); | ||
| 100 | if (rc < 0) | ||
| 101 | return rc; | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
| 107 | { | ||
| 108 | int ret; | ||
| 109 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
| 110 | |||
| 111 | /* Ignore interfaces 1 (mouse) and 2 (keyboard) for Huion 580 tablet, | ||
| 112 | * as they are not used | ||
| 113 | */ | ||
| 114 | switch (id->product) { | ||
| 115 | case USB_DEVICE_ID_HUION_580: | ||
| 116 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0x00) | ||
| 117 | return -ENODEV; | ||
| 118 | break; | ||
| 119 | } | ||
| 120 | |||
| 121 | ret = hid_parse(hdev); | ||
| 122 | if (ret) { | ||
| 123 | hid_err(hdev, "parse failed\n"); | ||
| 124 | goto err; | ||
| 125 | } | ||
| 126 | |||
| 127 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
| 128 | if (ret) { | ||
| 129 | hid_err(hdev, "hw start failed\n"); | ||
| 130 | goto err; | ||
| 131 | } | ||
| 132 | |||
| 133 | switch (id->product) { | ||
| 134 | case USB_DEVICE_ID_HUION_580: | ||
| 135 | ret = huion_tablet_enable(hdev); | ||
| 136 | if (ret) { | ||
| 137 | hid_err(hdev, "tablet enabling failed\n"); | ||
| 138 | goto enabling_err; | ||
| 139 | } | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | |||
| 143 | return 0; | ||
| 144 | enabling_err: | ||
| 145 | hid_hw_stop(hdev); | ||
| 146 | err: | ||
| 147 | return ret; | ||
| 148 | } | ||
| 149 | |||
| 150 | static int huion_raw_event(struct hid_device *hdev, struct hid_report *report, | ||
| 151 | u8 *data, int size) | ||
| 152 | { | ||
| 153 | /* If this is a pen input report then invert the in-range bit */ | ||
| 154 | if (report->type == HID_INPUT_REPORT && report->id == 0x07 && size >= 2) | ||
| 155 | data[1] ^= 0x40; | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | static const struct hid_device_id huion_devices[] = { | ||
| 161 | { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) }, | ||
| 162 | { } | ||
| 163 | }; | ||
| 164 | MODULE_DEVICE_TABLE(hid, huion_devices); | ||
| 165 | |||
| 166 | static struct hid_driver huion_driver = { | ||
| 167 | .name = "huion", | ||
| 168 | .id_table = huion_devices, | ||
| 169 | .probe = huion_probe, | ||
| 170 | .report_fixup = huion_report_fixup, | ||
| 171 | .raw_event = huion_raw_event, | ||
| 172 | }; | ||
| 173 | module_hid_driver(huion_driver); | ||
| 174 | |||
| 175 | MODULE_AUTHOR("Martin Rusko"); | ||
| 176 | MODULE_DESCRIPTION("Huion HID driver"); | ||
| 177 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index aa3fec0d9dc6..713217380b44 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c | |||
| @@ -199,13 +199,11 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, | |||
| 199 | if (desc->bLength == 0) | 199 | if (desc->bLength == 0) |
| 200 | goto cleanup; | 200 | goto cleanup; |
| 201 | 201 | ||
| 202 | input_device->hid_desc = kzalloc(desc->bLength, GFP_ATOMIC); | 202 | input_device->hid_desc = kmemdup(desc, desc->bLength, GFP_ATOMIC); |
| 203 | 203 | ||
| 204 | if (!input_device->hid_desc) | 204 | if (!input_device->hid_desc) |
| 205 | goto cleanup; | 205 | goto cleanup; |
| 206 | 206 | ||
| 207 | memcpy(input_device->hid_desc, desc, desc->bLength); | ||
| 208 | |||
| 209 | input_device->report_desc_size = desc->desc[0].wDescriptorLength; | 207 | input_device->report_desc_size = desc->desc[0].wDescriptorLength; |
| 210 | if (input_device->report_desc_size == 0) { | 208 | if (input_device->report_desc_size == 0) { |
| 211 | input_device->dev_info_status = -EINVAL; | 209 | input_device->dev_info_status = -EINVAL; |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 38535c9243d5..c5aea29f164f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -248,6 +248,9 @@ | |||
| 248 | #define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81 | 248 | #define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81 |
| 249 | #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 | 249 | #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 |
| 250 | 250 | ||
| 251 | #define USB_VENDOR_ID_DATA_MODUL 0x7374 | ||
| 252 | #define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201 | ||
| 253 | |||
| 251 | #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 | 254 | #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 |
| 252 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a | 255 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a |
| 253 | 256 | ||
| @@ -272,16 +275,15 @@ | |||
| 272 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e | 275 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e |
| 273 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262 | 276 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262 |
| 274 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b | 277 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b |
| 275 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa | ||
| 276 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1 | 278 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1 |
| 279 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa | ||
| 280 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4 0x72c4 | ||
| 281 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0 0x72d0 | ||
| 277 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa | 282 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa |
| 278 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302 | 283 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302 |
| 279 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349 | 284 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349 |
| 280 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7 | 285 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7 |
| 281 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 | 286 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 |
| 282 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224 | ||
| 283 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0 0x72d0 | ||
| 284 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4 0x72c4 | ||
| 285 | 287 | ||
| 286 | #define USB_VENDOR_ID_ELECOM 0x056e | 288 | #define USB_VENDOR_ID_ELECOM 0x056e |
| 287 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 | 289 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 |
| @@ -425,6 +427,9 @@ | |||
| 425 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 | 427 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 |
| 426 | #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 | 428 | #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 |
| 427 | 429 | ||
| 430 | #define USB_VENDOR_ID_HUION 0x256c | ||
| 431 | #define USB_DEVICE_ID_HUION_580 0x006e | ||
| 432 | |||
| 428 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 | 433 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 |
| 429 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 | 434 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 |
| 430 | #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 | 435 | #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 |
| @@ -440,6 +445,8 @@ | |||
| 440 | 445 | ||
| 441 | #define USB_VENDOR_ID_HOLTEK_ALT 0x04d9 | 446 | #define USB_VENDOR_ID_HOLTEK_ALT 0x04d9 |
| 442 | #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055 | 447 | #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055 |
| 448 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067 | ||
| 449 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a | ||
| 443 | 450 | ||
| 444 | #define USB_VENDOR_ID_IMATION 0x0718 | 451 | #define USB_VENDOR_ID_IMATION 0x0718 |
| 445 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 | 452 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 |
| @@ -447,6 +454,10 @@ | |||
| 447 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 | 454 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 |
| 448 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 | 455 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 |
| 449 | 456 | ||
| 457 | #define USB_VENDOR_ID_JABRA 0x0b0e | ||
| 458 | #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 | ||
| 459 | #define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420 | ||
| 460 | |||
| 450 | #define USB_VENDOR_ID_JESS 0x0c45 | 461 | #define USB_VENDOR_ID_JESS 0x0c45 |
| 451 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 | 462 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 |
| 452 | 463 | ||
| @@ -467,6 +478,7 @@ | |||
| 467 | 478 | ||
| 468 | #define USB_VENDOR_ID_KYE 0x0458 | 479 | #define USB_VENDOR_ID_KYE 0x0458 |
| 469 | #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 | 480 | #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 |
| 481 | #define USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE 0x0138 | ||
| 470 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 | 482 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 |
| 471 | #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 | 483 | #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 |
| 472 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 | 484 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 |
| @@ -734,6 +746,8 @@ | |||
| 734 | #define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 | 746 | #define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 |
| 735 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | 747 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 |
| 736 | #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f | 748 | #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f |
| 749 | #define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002 | ||
| 750 | #define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000 | ||
| 737 | 751 | ||
| 738 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 | 752 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 |
| 739 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 | 753 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 945b8158ec4c..7480799e535c 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -354,10 +354,10 @@ static int hidinput_get_battery_property(struct power_supply *psy, | |||
| 354 | dev->battery_report_type); | 354 | dev->battery_report_type); |
| 355 | 355 | ||
| 356 | if (ret != 2) { | 356 | if (ret != 2) { |
| 357 | if (ret >= 0) | 357 | ret = -ENODATA; |
| 358 | ret = -EINVAL; | ||
| 359 | break; | 358 | break; |
| 360 | } | 359 | } |
| 360 | ret = 0; | ||
| 361 | 361 | ||
| 362 | if (dev->battery_min < dev->battery_max && | 362 | if (dev->battery_min < dev->battery_max && |
| 363 | buf[1] >= dev->battery_min && | 363 | buf[1] >= dev->battery_min && |
| @@ -1042,9 +1042,14 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
| 1042 | 1042 | ||
| 1043 | /* | 1043 | /* |
| 1044 | * Ignore out-of-range values as per HID specification, | 1044 | * Ignore out-of-range values as per HID specification, |
| 1045 | * section 5.10 and 6.2.25 | 1045 | * section 5.10 and 6.2.25. |
| 1046 | * | ||
| 1047 | * The logical_minimum < logical_maximum check is done so that we | ||
| 1048 | * don't unintentionally discard values sent by devices which | ||
| 1049 | * don't specify logical min and max. | ||
| 1046 | */ | 1050 | */ |
| 1047 | if ((field->flags & HID_MAIN_ITEM_VARIABLE) && | 1051 | if ((field->flags & HID_MAIN_ITEM_VARIABLE) && |
| 1052 | (field->logical_minimum < field->logical_maximum) && | ||
| 1048 | (value < field->logical_minimum || | 1053 | (value < field->logical_minimum || |
| 1049 | value > field->logical_maximum)) { | 1054 | value > field->logical_maximum)) { |
| 1050 | dbg_hid("Ignoring out-of-range value %x\n", value); | 1055 | dbg_hid("Ignoring out-of-range value %x\n", value); |
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index 6af90dbdc3d4..1e2ee2aa84a0 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c | |||
| @@ -314,6 +314,25 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 314 | *rsize = sizeof(easypen_m610x_rdesc_fixed); | 314 | *rsize = sizeof(easypen_m610x_rdesc_fixed); |
| 315 | } | 315 | } |
| 316 | break; | 316 | break; |
| 317 | case USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE: | ||
| 318 | /* | ||
| 319 | * the fixup that need to be done: | ||
| 320 | * - change Usage Maximum in the Comsumer Control | ||
| 321 | * (report ID 3) to a reasonable value | ||
| 322 | */ | ||
| 323 | if (*rsize >= 135 && | ||
| 324 | /* Usage Page (Consumer Devices) */ | ||
| 325 | rdesc[104] == 0x05 && rdesc[105] == 0x0c && | ||
| 326 | /* Usage (Consumer Control) */ | ||
| 327 | rdesc[106] == 0x09 && rdesc[107] == 0x01 && | ||
| 328 | /* Usage Maximum > 12287 */ | ||
| 329 | rdesc[114] == 0x2a && rdesc[116] > 0x2f) { | ||
| 330 | hid_info(hdev, | ||
| 331 | "fixing up Genius Gila Gaming Mouse " | ||
| 332 | "report descriptor\n"); | ||
| 333 | rdesc[116] = 0x2f; | ||
| 334 | } | ||
| 335 | break; | ||
| 317 | } | 336 | } |
| 318 | return rdesc; | 337 | return rdesc; |
| 319 | } | 338 | } |
| @@ -407,6 +426,8 @@ static const struct hid_device_id kye_devices[] = { | |||
| 407 | USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, | 426 | USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, |
| 408 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | 427 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, |
| 409 | USB_DEVICE_ID_KYE_EASYPEN_M610X) }, | 428 | USB_DEVICE_ID_KYE_EASYPEN_M610X) }, |
| 429 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | ||
| 430 | USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) }, | ||
| 410 | { } | 431 | { } |
| 411 | }; | 432 | }; |
| 412 | MODULE_DEVICE_TABLE(hid, kye_devices); | 433 | MODULE_DEVICE_TABLE(hid, kye_devices); |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index d39a5cede0b0..cb0e361d7a4b 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
| @@ -1111,6 +1111,11 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1111 | HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, | 1111 | HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, |
| 1112 | USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, | 1112 | USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, |
| 1113 | 1113 | ||
| 1114 | /* Data Modul easyMaxTouch */ | ||
| 1115 | { .driver_data = MT_CLS_DEFAULT, | ||
| 1116 | MT_USB_DEVICE(USB_VENDOR_ID_DATA_MODUL, | ||
| 1117 | USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH) }, | ||
| 1118 | |||
| 1114 | /* eGalax devices (resistive) */ | 1119 | /* eGalax devices (resistive) */ |
| 1115 | { .driver_data = MT_CLS_EGALAX, | 1120 | { .driver_data = MT_CLS_EGALAX, |
| 1116 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1121 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| @@ -1120,34 +1125,40 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1120 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, | 1125 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, |
| 1121 | 1126 | ||
| 1122 | /* eGalax devices (capacitive) */ | 1127 | /* eGalax devices (capacitive) */ |
| 1123 | { .driver_data = MT_CLS_EGALAX, | ||
| 1124 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
| 1125 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, | ||
| 1126 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 1128 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
| 1127 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1129 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1128 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) }, | 1130 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) }, |
| 1129 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 1131 | { .driver_data = MT_CLS_EGALAX, |
| 1130 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1132 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1131 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, | 1133 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, |
| 1132 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 1134 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
| 1133 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1135 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1134 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, | 1136 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, |
| 1135 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 1137 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
| 1136 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1138 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1137 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) }, | 1139 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) }, |
| 1138 | { .driver_data = MT_CLS_EGALAX, | 1140 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
| 1139 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1141 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1140 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, | 1142 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, |
| 1141 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 1143 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
| 1142 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1144 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1143 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) }, | 1145 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) }, |
| 1144 | { .driver_data = MT_CLS_EGALAX, | 1146 | { .driver_data = MT_CLS_EGALAX, |
| 1145 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1147 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1148 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, | ||
| 1149 | { .driver_data = MT_CLS_EGALAX, | ||
| 1150 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
| 1146 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, | 1151 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, |
| 1147 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 1152 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
| 1148 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1153 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1149 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) }, | 1154 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) }, |
| 1150 | { .driver_data = MT_CLS_EGALAX, | 1155 | { .driver_data = MT_CLS_EGALAX, |
| 1156 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
| 1157 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4) }, | ||
| 1158 | { .driver_data = MT_CLS_EGALAX, | ||
| 1159 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
| 1160 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0) }, | ||
| 1161 | { .driver_data = MT_CLS_EGALAX, | ||
| 1151 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1162 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1152 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, | 1163 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, |
| 1153 | { .driver_data = MT_CLS_EGALAX, | 1164 | { .driver_data = MT_CLS_EGALAX, |
| @@ -1162,15 +1173,6 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1162 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 1173 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
| 1163 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1174 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1164 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, | 1175 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, |
| 1165 | { .driver_data = MT_CLS_EGALAX, | ||
| 1166 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
| 1167 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, | ||
| 1168 | { .driver_data = MT_CLS_EGALAX, | ||
| 1169 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
| 1170 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0) }, | ||
| 1171 | { .driver_data = MT_CLS_EGALAX, | ||
| 1172 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
| 1173 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4) }, | ||
| 1174 | 1176 | ||
| 1175 | /* Elo TouchSystems IntelliTouch Plus panel */ | 1177 | /* Elo TouchSystems IntelliTouch Plus panel */ |
| 1176 | { .driver_data = MT_CLS_DUAL_CONTACT_ID, | 1178 | { .driver_data = MT_CLS_DUAL_CONTACT_ID, |
diff --git a/drivers/hid/hid-ps3remote.c b/drivers/hid/hid-ps3remote.c deleted file mode 100644 index f1239d3c5b14..000000000000 --- a/drivers/hid/hid-ps3remote.c +++ /dev/null | |||
| @@ -1,204 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * HID driver for Sony PS3 BD Remote Control | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 David Dillow <dave@thedillows.org> | ||
| 5 | * Based on a blend of the bluez fakehid user-space code by Marcel Holtmann | ||
| 6 | * and other kernel HID drivers. | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the Free | ||
| 12 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 13 | * any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | /* NOTE: in order for the Sony PS3 BD Remote Control to be found by | ||
| 17 | * a Bluetooth host, the key combination Start+Enter has to be kept pressed | ||
| 18 | * for about 7 seconds with the Bluetooth Host Controller in discovering mode. | ||
| 19 | * | ||
| 20 | * There will be no PIN request from the device. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/device.h> | ||
| 24 | #include <linux/hid.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | |||
| 27 | #include "hid-ids.h" | ||
| 28 | |||
| 29 | static __u8 ps3remote_rdesc[] = { | ||
| 30 | 0x05, 0x01, /* GUsagePage Generic Desktop */ | ||
| 31 | 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ | ||
| 32 | 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ | ||
| 33 | |||
| 34 | /* Use collection 1 for joypad buttons */ | ||
| 35 | 0xA1, 0x02, /* MCollection Logical (interrelated data) */ | ||
| 36 | |||
| 37 | /* Ignore the 1st byte, maybe it is used for a controller | ||
| 38 | * number but it's not needed for correct operation */ | ||
| 39 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | ||
| 40 | 0x95, 0x01, /* GReportCount 0x01 [1] */ | ||
| 41 | 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ | ||
| 42 | |||
| 43 | /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these | ||
| 44 | * buttons multiple keypresses are allowed */ | ||
| 45 | 0x05, 0x09, /* GUsagePage Button */ | ||
| 46 | 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ | ||
| 47 | 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ | ||
| 48 | 0x14, /* GLogicalMinimum [0] */ | ||
| 49 | 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ | ||
| 50 | 0x75, 0x01, /* GReportSize 0x01 [1] */ | ||
| 51 | 0x95, 0x18, /* GReportCount 0x18 [24] */ | ||
| 52 | 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ | ||
| 53 | |||
| 54 | 0xC0, /* MEndCollection */ | ||
| 55 | |||
| 56 | /* Use collection 2 for remote control buttons */ | ||
| 57 | 0xA1, 0x02, /* MCollection Logical (interrelated data) */ | ||
| 58 | |||
| 59 | /* 5th byte is used for remote control buttons */ | ||
| 60 | 0x05, 0x09, /* GUsagePage Button */ | ||
| 61 | 0x18, /* LUsageMinimum [No button pressed] */ | ||
| 62 | 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ | ||
| 63 | 0x14, /* GLogicalMinimum [0] */ | ||
| 64 | 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ | ||
| 65 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | ||
| 66 | 0x95, 0x01, /* GReportCount 0x01 [1] */ | ||
| 67 | 0x80, /* MInput */ | ||
| 68 | |||
| 69 | /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at | ||
| 70 | * 0xff and 11th is for press indication */ | ||
| 71 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | ||
| 72 | 0x95, 0x06, /* GReportCount 0x06 [6] */ | ||
| 73 | 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ | ||
| 74 | |||
| 75 | /* 12th byte is for battery strength */ | ||
| 76 | 0x05, 0x06, /* GUsagePage Generic Device Controls */ | ||
| 77 | 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ | ||
| 78 | 0x14, /* GLogicalMinimum [0] */ | ||
| 79 | 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ | ||
| 80 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | ||
| 81 | 0x95, 0x01, /* GReportCount 0x01 [1] */ | ||
| 82 | 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ | ||
| 83 | |||
| 84 | 0xC0, /* MEndCollection */ | ||
| 85 | |||
| 86 | 0xC0 /* MEndCollection [Game Pad] */ | ||
| 87 | }; | ||
| 88 | |||
| 89 | static const unsigned int ps3remote_keymap_joypad_buttons[] = { | ||
| 90 | [0x01] = KEY_SELECT, | ||
| 91 | [0x02] = BTN_THUMBL, /* L3 */ | ||
| 92 | [0x03] = BTN_THUMBR, /* R3 */ | ||
| 93 | [0x04] = BTN_START, | ||
| 94 | [0x05] = KEY_UP, | ||
| 95 | [0x06] = KEY_RIGHT, | ||
| 96 | [0x07] = KEY_DOWN, | ||
| 97 | [0x08] = KEY_LEFT, | ||
| 98 | [0x09] = BTN_TL2, /* L2 */ | ||
| 99 | [0x0a] = BTN_TR2, /* R2 */ | ||
| 100 | [0x0b] = BTN_TL, /* L1 */ | ||
| 101 | [0x0c] = BTN_TR, /* R1 */ | ||
| 102 | [0x0d] = KEY_OPTION, /* options/triangle */ | ||
| 103 | [0x0e] = KEY_BACK, /* back/circle */ | ||
| 104 | [0x0f] = BTN_0, /* cross */ | ||
| 105 | [0x10] = KEY_SCREEN, /* view/square */ | ||
| 106 | [0x11] = KEY_HOMEPAGE, /* PS button */ | ||
| 107 | [0x14] = KEY_ENTER, | ||
| 108 | }; | ||
| 109 | static const unsigned int ps3remote_keymap_remote_buttons[] = { | ||
| 110 | [0x00] = KEY_1, | ||
| 111 | [0x01] = KEY_2, | ||
| 112 | [0x02] = KEY_3, | ||
| 113 | [0x03] = KEY_4, | ||
| 114 | [0x04] = KEY_5, | ||
| 115 | [0x05] = KEY_6, | ||
| 116 | [0x06] = KEY_7, | ||
| 117 | [0x07] = KEY_8, | ||
| 118 | [0x08] = KEY_9, | ||
| 119 | [0x09] = KEY_0, | ||
| 120 | [0x0e] = KEY_ESC, /* return */ | ||
| 121 | [0x0f] = KEY_CLEAR, | ||
| 122 | [0x16] = KEY_EJECTCD, | ||
| 123 | [0x1a] = KEY_MENU, /* top menu */ | ||
| 124 | [0x28] = KEY_TIME, | ||
| 125 | [0x30] = KEY_PREVIOUS, | ||
| 126 | [0x31] = KEY_NEXT, | ||
| 127 | [0x32] = KEY_PLAY, | ||
| 128 | [0x33] = KEY_REWIND, /* scan back */ | ||
| 129 | [0x34] = KEY_FORWARD, /* scan forward */ | ||
| 130 | [0x38] = KEY_STOP, | ||
| 131 | [0x39] = KEY_PAUSE, | ||
| 132 | [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ | ||
| 133 | [0x60] = KEY_FRAMEBACK, /* slow/step back */ | ||
| 134 | [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ | ||
| 135 | [0x63] = KEY_SUBTITLE, | ||
| 136 | [0x64] = KEY_AUDIO, | ||
| 137 | [0x65] = KEY_ANGLE, | ||
| 138 | [0x70] = KEY_INFO, /* display */ | ||
| 139 | [0x80] = KEY_BLUE, | ||
| 140 | [0x81] = KEY_RED, | ||
| 141 | [0x82] = KEY_GREEN, | ||
| 142 | [0x83] = KEY_YELLOW, | ||
| 143 | }; | ||
| 144 | |||
| 145 | static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
| 146 | unsigned int *rsize) | ||
| 147 | { | ||
| 148 | *rsize = sizeof(ps3remote_rdesc); | ||
| 149 | return ps3remote_rdesc; | ||
| 150 | } | ||
| 151 | |||
| 152 | static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
| 153 | struct hid_field *field, struct hid_usage *usage, | ||
| 154 | unsigned long **bit, int *max) | ||
| 155 | { | ||
| 156 | unsigned int key = usage->hid & HID_USAGE; | ||
| 157 | |||
| 158 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) | ||
| 159 | return -1; | ||
| 160 | |||
| 161 | switch (usage->collection_index) { | ||
| 162 | case 1: | ||
| 163 | if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) | ||
| 164 | return -1; | ||
| 165 | |||
| 166 | key = ps3remote_keymap_joypad_buttons[key]; | ||
| 167 | if (!key) | ||
| 168 | return -1; | ||
| 169 | break; | ||
| 170 | case 2: | ||
| 171 | if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) | ||
| 172 | return -1; | ||
| 173 | |||
| 174 | key = ps3remote_keymap_remote_buttons[key]; | ||
| 175 | if (!key) | ||
| 176 | return -1; | ||
| 177 | break; | ||
| 178 | default: | ||
| 179 | return -1; | ||
| 180 | } | ||
| 181 | |||
| 182 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); | ||
| 183 | return 1; | ||
| 184 | } | ||
| 185 | |||
| 186 | static const struct hid_device_id ps3remote_devices[] = { | ||
| 187 | /* PS3 BD Remote Control */ | ||
| 188 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, | ||
| 189 | /* Logitech Harmony Adapter for PS3 */ | ||
| 190 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, | ||
| 191 | { } | ||
| 192 | }; | ||
| 193 | MODULE_DEVICE_TABLE(hid, ps3remote_devices); | ||
| 194 | |||
| 195 | static struct hid_driver ps3remote_driver = { | ||
| 196 | .name = "ps3_remote", | ||
| 197 | .id_table = ps3remote_devices, | ||
| 198 | .report_fixup = ps3remote_fixup, | ||
| 199 | .input_mapping = ps3remote_mapping, | ||
| 200 | }; | ||
| 201 | module_hid_driver(ps3remote_driver); | ||
| 202 | |||
| 203 | MODULE_LICENSE("GPL"); | ||
| 204 | MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>"); | ||
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index b59b3df9ca95..65c4ccfcbd29 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c | |||
| @@ -366,7 +366,7 @@ void roccat_disconnect(int minor) | |||
| 366 | mutex_lock(&devices_lock); | 366 | mutex_lock(&devices_lock); |
| 367 | devices[minor] = NULL; | 367 | devices[minor] = NULL; |
| 368 | mutex_unlock(&devices_lock); | 368 | mutex_unlock(&devices_lock); |
| 369 | 369 | ||
| 370 | if (device->open) { | 370 | if (device->open) { |
| 371 | hid_hw_close(device->hid); | 371 | hid_hw_close(device->hid); |
| 372 | wake_up_interruptible(&device->wait); | 372 | wake_up_interruptible(&device->wait); |
| @@ -426,13 +426,23 @@ static int __init roccat_init(void) | |||
| 426 | 426 | ||
| 427 | if (retval < 0) { | 427 | if (retval < 0) { |
| 428 | pr_warn("can't get major number\n"); | 428 | pr_warn("can't get major number\n"); |
| 429 | return retval; | 429 | goto error; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | cdev_init(&roccat_cdev, &roccat_ops); | 432 | cdev_init(&roccat_cdev, &roccat_ops); |
| 433 | cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES); | 433 | retval = cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES); |
| 434 | 434 | ||
| 435 | if (retval < 0) { | ||
| 436 | pr_warn("cannot add cdev\n"); | ||
| 437 | goto cleanup_alloc_chrdev_region; | ||
| 438 | } | ||
| 435 | return 0; | 439 | return 0; |
| 440 | |||
| 441 | |||
| 442 | cleanup_alloc_chrdev_region: | ||
| 443 | unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES); | ||
| 444 | error: | ||
| 445 | return retval; | ||
| 436 | } | 446 | } |
| 437 | 447 | ||
| 438 | static void __exit roccat_exit(void) | 448 | static void __exit roccat_exit(void) |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 312098e4af4f..ecbc74923d06 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
| @@ -1,11 +1,13 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * HID driver for some sony "special" devices | 2 | * HID driver for Sony / PS2 / PS3 BD devices. |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
| 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
| 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
| 7 | * Copyright (c) 2008 Jiri Slaby | 7 | * Copyright (c) 2008 Jiri Slaby |
| 8 | * Copyright (c) 2006-2008 Jiri Kosina | 8 | * Copyright (c) 2012 David Dillow <dave@thedillows.org> |
| 9 | * Copyright (c) 2006-2013 Jiri Kosina | ||
| 10 | * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> | ||
| 9 | */ | 11 | */ |
| 10 | 12 | ||
| 11 | /* | 13 | /* |
| @@ -15,17 +17,27 @@ | |||
| 15 | * any later version. | 17 | * any later version. |
| 16 | */ | 18 | */ |
| 17 | 19 | ||
| 20 | /* NOTE: in order for the Sony PS3 BD Remote Control to be found by | ||
| 21 | * a Bluetooth host, the key combination Start+Enter has to be kept pressed | ||
| 22 | * for about 7 seconds with the Bluetooth Host Controller in discovering mode. | ||
| 23 | * | ||
| 24 | * There will be no PIN request from the device. | ||
| 25 | */ | ||
| 26 | |||
| 18 | #include <linux/device.h> | 27 | #include <linux/device.h> |
| 19 | #include <linux/hid.h> | 28 | #include <linux/hid.h> |
| 20 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 21 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 22 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
| 32 | #include <linux/leds.h> | ||
| 23 | 33 | ||
| 24 | #include "hid-ids.h" | 34 | #include "hid-ids.h" |
| 25 | 35 | ||
| 26 | #define VAIO_RDESC_CONSTANT (1 << 0) | 36 | #define VAIO_RDESC_CONSTANT (1 << 0) |
| 27 | #define SIXAXIS_CONTROLLER_USB (1 << 1) | 37 | #define SIXAXIS_CONTROLLER_USB (1 << 1) |
| 28 | #define SIXAXIS_CONTROLLER_BT (1 << 2) | 38 | #define SIXAXIS_CONTROLLER_BT (1 << 2) |
| 39 | #define BUZZ_CONTROLLER (1 << 3) | ||
| 40 | #define PS3REMOTE (1 << 4) | ||
| 29 | 41 | ||
| 30 | static const u8 sixaxis_rdesc_fixup[] = { | 42 | static const u8 sixaxis_rdesc_fixup[] = { |
| 31 | 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, | 43 | 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, |
| @@ -55,10 +67,214 @@ static const u8 sixaxis_rdesc_fixup2[] = { | |||
| 55 | 0xb1, 0x02, 0xc0, 0xc0, | 67 | 0xb1, 0x02, 0xc0, 0xc0, |
| 56 | }; | 68 | }; |
| 57 | 69 | ||
| 70 | static __u8 ps3remote_rdesc[] = { | ||
| 71 | 0x05, 0x01, /* GUsagePage Generic Desktop */ | ||
| 72 | 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ | ||
| 73 | 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ | ||
| 74 | |||
| 75 | /* Use collection 1 for joypad buttons */ | ||
| 76 | 0xA1, 0x02, /* MCollection Logical (interrelated data) */ | ||
| 77 | |||
| 78 | /* Ignore the 1st byte, maybe it is used for a controller | ||
| 79 | * number but it's not needed for correct operation */ | ||
| 80 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | ||
| 81 | 0x95, 0x01, /* GReportCount 0x01 [1] */ | ||
| 82 | 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ | ||
| 83 | |||
| 84 | /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these | ||
| 85 | * buttons multiple keypresses are allowed */ | ||
| 86 | 0x05, 0x09, /* GUsagePage Button */ | ||
| 87 | 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ | ||
| 88 | 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ | ||
| 89 | 0x14, /* GLogicalMinimum [0] */ | ||
| 90 | 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ | ||
| 91 | 0x75, 0x01, /* GReportSize 0x01 [1] */ | ||
| 92 | 0x95, 0x18, /* GReportCount 0x18 [24] */ | ||
| 93 | 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ | ||
| 94 | |||
| 95 | 0xC0, /* MEndCollection */ | ||
| 96 | |||
| 97 | /* Use collection 2 for remote control buttons */ | ||
| 98 | 0xA1, 0x02, /* MCollection Logical (interrelated data) */ | ||
| 99 | |||
| 100 | /* 5th byte is used for remote control buttons */ | ||
| 101 | 0x05, 0x09, /* GUsagePage Button */ | ||
| 102 | 0x18, /* LUsageMinimum [No button pressed] */ | ||
| 103 | 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ | ||
| 104 | 0x14, /* GLogicalMinimum [0] */ | ||
| 105 | 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ | ||
| 106 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | ||
| 107 | 0x95, 0x01, /* GReportCount 0x01 [1] */ | ||
| 108 | 0x80, /* MInput */ | ||
| 109 | |||
| 110 | /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at | ||
| 111 | * 0xff and 11th is for press indication */ | ||
| 112 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | ||
| 113 | 0x95, 0x06, /* GReportCount 0x06 [6] */ | ||
| 114 | 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ | ||
| 115 | |||
| 116 | /* 12th byte is for battery strength */ | ||
| 117 | 0x05, 0x06, /* GUsagePage Generic Device Controls */ | ||
| 118 | 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ | ||
| 119 | 0x14, /* GLogicalMinimum [0] */ | ||
| 120 | 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ | ||
| 121 | 0x75, 0x08, /* GReportSize 0x08 [8] */ | ||
| 122 | 0x95, 0x01, /* GReportCount 0x01 [1] */ | ||
| 123 | 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ | ||
| 124 | |||
| 125 | 0xC0, /* MEndCollection */ | ||
| 126 | |||
| 127 | 0xC0 /* MEndCollection [Game Pad] */ | ||
| 128 | }; | ||
| 129 | |||
| 130 | static const unsigned int ps3remote_keymap_joypad_buttons[] = { | ||
| 131 | [0x01] = KEY_SELECT, | ||
| 132 | [0x02] = BTN_THUMBL, /* L3 */ | ||
| 133 | [0x03] = BTN_THUMBR, /* R3 */ | ||
| 134 | [0x04] = BTN_START, | ||
| 135 | [0x05] = KEY_UP, | ||
| 136 | [0x06] = KEY_RIGHT, | ||
| 137 | [0x07] = KEY_DOWN, | ||
| 138 | [0x08] = KEY_LEFT, | ||
| 139 | [0x09] = BTN_TL2, /* L2 */ | ||
| 140 | [0x0a] = BTN_TR2, /* R2 */ | ||
| 141 | [0x0b] = BTN_TL, /* L1 */ | ||
| 142 | [0x0c] = BTN_TR, /* R1 */ | ||
| 143 | [0x0d] = KEY_OPTION, /* options/triangle */ | ||
| 144 | [0x0e] = KEY_BACK, /* back/circle */ | ||
| 145 | [0x0f] = BTN_0, /* cross */ | ||
| 146 | [0x10] = KEY_SCREEN, /* view/square */ | ||
| 147 | [0x11] = KEY_HOMEPAGE, /* PS button */ | ||
| 148 | [0x14] = KEY_ENTER, | ||
| 149 | }; | ||
| 150 | static const unsigned int ps3remote_keymap_remote_buttons[] = { | ||
| 151 | [0x00] = KEY_1, | ||
| 152 | [0x01] = KEY_2, | ||
| 153 | [0x02] = KEY_3, | ||
| 154 | [0x03] = KEY_4, | ||
| 155 | [0x04] = KEY_5, | ||
| 156 | [0x05] = KEY_6, | ||
| 157 | [0x06] = KEY_7, | ||
| 158 | [0x07] = KEY_8, | ||
| 159 | [0x08] = KEY_9, | ||
| 160 | [0x09] = KEY_0, | ||
| 161 | [0x0e] = KEY_ESC, /* return */ | ||
| 162 | [0x0f] = KEY_CLEAR, | ||
| 163 | [0x16] = KEY_EJECTCD, | ||
| 164 | [0x1a] = KEY_MENU, /* top menu */ | ||
| 165 | [0x28] = KEY_TIME, | ||
| 166 | [0x30] = KEY_PREVIOUS, | ||
| 167 | [0x31] = KEY_NEXT, | ||
| 168 | [0x32] = KEY_PLAY, | ||
| 169 | [0x33] = KEY_REWIND, /* scan back */ | ||
| 170 | [0x34] = KEY_FORWARD, /* scan forward */ | ||
| 171 | [0x38] = KEY_STOP, | ||
| 172 | [0x39] = KEY_PAUSE, | ||
| 173 | [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ | ||
| 174 | [0x60] = KEY_FRAMEBACK, /* slow/step back */ | ||
| 175 | [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ | ||
| 176 | [0x63] = KEY_SUBTITLE, | ||
| 177 | [0x64] = KEY_AUDIO, | ||
| 178 | [0x65] = KEY_ANGLE, | ||
| 179 | [0x70] = KEY_INFO, /* display */ | ||
| 180 | [0x80] = KEY_BLUE, | ||
| 181 | [0x81] = KEY_RED, | ||
| 182 | [0x82] = KEY_GREEN, | ||
| 183 | [0x83] = KEY_YELLOW, | ||
| 184 | }; | ||
| 185 | |||
| 186 | static const unsigned int buzz_keymap[] = { | ||
| 187 | /* The controller has 4 remote buzzers, each with one LED and 5 | ||
| 188 | * buttons. | ||
| 189 | * | ||
| 190 | * We use the mapping chosen by the controller, which is: | ||
| 191 | * | ||
| 192 | * Key Offset | ||
| 193 | * ------------------- | ||
| 194 | * Buzz 1 | ||
| 195 | * Blue 5 | ||
| 196 | * Orange 4 | ||
| 197 | * Green 3 | ||
| 198 | * Yellow 2 | ||
| 199 | * | ||
| 200 | * So, for example, the orange button on the third buzzer is mapped to | ||
| 201 | * BTN_TRIGGER_HAPPY14 | ||
| 202 | */ | ||
| 203 | [ 1] = BTN_TRIGGER_HAPPY1, | ||
| 204 | [ 2] = BTN_TRIGGER_HAPPY2, | ||
| 205 | [ 3] = BTN_TRIGGER_HAPPY3, | ||
| 206 | [ 4] = BTN_TRIGGER_HAPPY4, | ||
| 207 | [ 5] = BTN_TRIGGER_HAPPY5, | ||
| 208 | [ 6] = BTN_TRIGGER_HAPPY6, | ||
| 209 | [ 7] = BTN_TRIGGER_HAPPY7, | ||
| 210 | [ 8] = BTN_TRIGGER_HAPPY8, | ||
| 211 | [ 9] = BTN_TRIGGER_HAPPY9, | ||
| 212 | [10] = BTN_TRIGGER_HAPPY10, | ||
| 213 | [11] = BTN_TRIGGER_HAPPY11, | ||
| 214 | [12] = BTN_TRIGGER_HAPPY12, | ||
| 215 | [13] = BTN_TRIGGER_HAPPY13, | ||
| 216 | [14] = BTN_TRIGGER_HAPPY14, | ||
| 217 | [15] = BTN_TRIGGER_HAPPY15, | ||
| 218 | [16] = BTN_TRIGGER_HAPPY16, | ||
| 219 | [17] = BTN_TRIGGER_HAPPY17, | ||
| 220 | [18] = BTN_TRIGGER_HAPPY18, | ||
| 221 | [19] = BTN_TRIGGER_HAPPY19, | ||
| 222 | [20] = BTN_TRIGGER_HAPPY20, | ||
| 223 | }; | ||
| 224 | |||
| 58 | struct sony_sc { | 225 | struct sony_sc { |
| 59 | unsigned long quirks; | 226 | unsigned long quirks; |
| 227 | |||
| 228 | void *extra; | ||
| 60 | }; | 229 | }; |
| 61 | 230 | ||
| 231 | struct buzz_extra { | ||
| 232 | int led_state; | ||
| 233 | struct led_classdev *leds[4]; | ||
| 234 | }; | ||
| 235 | |||
| 236 | static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
| 237 | unsigned int *rsize) | ||
| 238 | { | ||
| 239 | *rsize = sizeof(ps3remote_rdesc); | ||
| 240 | return ps3remote_rdesc; | ||
| 241 | } | ||
| 242 | |||
| 243 | static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
| 244 | struct hid_field *field, struct hid_usage *usage, | ||
| 245 | unsigned long **bit, int *max) | ||
| 246 | { | ||
| 247 | unsigned int key = usage->hid & HID_USAGE; | ||
| 248 | |||
| 249 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) | ||
| 250 | return -1; | ||
| 251 | |||
| 252 | switch (usage->collection_index) { | ||
| 253 | case 1: | ||
| 254 | if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) | ||
| 255 | return -1; | ||
| 256 | |||
| 257 | key = ps3remote_keymap_joypad_buttons[key]; | ||
| 258 | if (!key) | ||
| 259 | return -1; | ||
| 260 | break; | ||
| 261 | case 2: | ||
| 262 | if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) | ||
| 263 | return -1; | ||
| 264 | |||
| 265 | key = ps3remote_keymap_remote_buttons[key]; | ||
| 266 | if (!key) | ||
| 267 | return -1; | ||
| 268 | break; | ||
| 269 | default: | ||
| 270 | return -1; | ||
| 271 | } | ||
| 272 | |||
| 273 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); | ||
| 274 | return 1; | ||
| 275 | } | ||
| 276 | |||
| 277 | |||
| 62 | /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ | 278 | /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ |
| 63 | static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 279 | static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 64 | unsigned int *rsize) | 280 | unsigned int *rsize) |
| @@ -95,6 +311,10 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 95 | *rsize = sizeof(sixaxis_rdesc_fixup2); | 311 | *rsize = sizeof(sixaxis_rdesc_fixup2); |
| 96 | memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); | 312 | memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); |
| 97 | } | 313 | } |
| 314 | |||
| 315 | if (sc->quirks & PS3REMOTE) | ||
| 316 | return ps3remote_fixup(hdev, rdesc, rsize); | ||
| 317 | |||
| 98 | return rdesc; | 318 | return rdesc; |
| 99 | } | 319 | } |
| 100 | 320 | ||
| @@ -117,6 +337,41 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
| 117 | return 0; | 337 | return 0; |
| 118 | } | 338 | } |
| 119 | 339 | ||
| 340 | static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
| 341 | struct hid_field *field, struct hid_usage *usage, | ||
| 342 | unsigned long **bit, int *max) | ||
| 343 | { | ||
| 344 | struct sony_sc *sc = hid_get_drvdata(hdev); | ||
| 345 | |||
| 346 | if (sc->quirks & BUZZ_CONTROLLER) { | ||
| 347 | unsigned int key = usage->hid & HID_USAGE; | ||
| 348 | |||
| 349 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) | ||
| 350 | return -1; | ||
| 351 | |||
| 352 | switch (usage->collection_index) { | ||
| 353 | case 1: | ||
| 354 | if (key >= ARRAY_SIZE(buzz_keymap)) | ||
| 355 | return -1; | ||
| 356 | |||
| 357 | key = buzz_keymap[key]; | ||
| 358 | if (!key) | ||
| 359 | return -1; | ||
| 360 | break; | ||
| 361 | default: | ||
| 362 | return -1; | ||
| 363 | } | ||
| 364 | |||
| 365 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); | ||
| 366 | return 1; | ||
| 367 | } | ||
| 368 | |||
| 369 | if (sc->quirks & PS3REMOTE) | ||
| 370 | return ps3remote_mapping(hdev, hi, field, usage, bit, max); | ||
| 371 | |||
| 372 | return -1; | ||
| 373 | } | ||
| 374 | |||
| 120 | /* | 375 | /* |
| 121 | * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP | 376 | * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP |
| 122 | * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() | 377 | * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() |
| @@ -192,11 +447,181 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev) | |||
| 192 | return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | 447 | return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); |
| 193 | } | 448 | } |
| 194 | 449 | ||
| 450 | static void buzz_set_leds(struct hid_device *hdev, int leds) | ||
| 451 | { | ||
| 452 | struct list_head *report_list = | ||
| 453 | &hdev->report_enum[HID_OUTPUT_REPORT].report_list; | ||
| 454 | struct hid_report *report = list_entry(report_list->next, | ||
| 455 | struct hid_report, list); | ||
| 456 | __s32 *value = report->field[0]->value; | ||
| 457 | |||
| 458 | value[0] = 0x00; | ||
| 459 | value[1] = (leds & 1) ? 0xff : 0x00; | ||
| 460 | value[2] = (leds & 2) ? 0xff : 0x00; | ||
| 461 | value[3] = (leds & 4) ? 0xff : 0x00; | ||
| 462 | value[4] = (leds & 8) ? 0xff : 0x00; | ||
| 463 | value[5] = 0x00; | ||
| 464 | value[6] = 0x00; | ||
| 465 | hid_hw_request(hdev, report, HID_REQ_SET_REPORT); | ||
| 466 | } | ||
| 467 | |||
| 468 | static void buzz_led_set_brightness(struct led_classdev *led, | ||
| 469 | enum led_brightness value) | ||
| 470 | { | ||
| 471 | struct device *dev = led->dev->parent; | ||
| 472 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 473 | struct sony_sc *drv_data; | ||
| 474 | struct buzz_extra *buzz; | ||
| 475 | |||
| 476 | int n; | ||
| 477 | |||
| 478 | drv_data = hid_get_drvdata(hdev); | ||
| 479 | if (!drv_data || !drv_data->extra) { | ||
| 480 | hid_err(hdev, "No device data\n"); | ||
| 481 | return; | ||
| 482 | } | ||
| 483 | buzz = drv_data->extra; | ||
| 484 | |||
| 485 | for (n = 0; n < 4; n++) { | ||
| 486 | if (led == buzz->leds[n]) { | ||
| 487 | int on = !! (buzz->led_state & (1 << n)); | ||
| 488 | if (value == LED_OFF && on) { | ||
| 489 | buzz->led_state &= ~(1 << n); | ||
| 490 | buzz_set_leds(hdev, buzz->led_state); | ||
| 491 | } else if (value != LED_OFF && !on) { | ||
| 492 | buzz->led_state |= (1 << n); | ||
| 493 | buzz_set_leds(hdev, buzz->led_state); | ||
| 494 | } | ||
| 495 | break; | ||
| 496 | } | ||
| 497 | } | ||
| 498 | } | ||
| 499 | |||
| 500 | static enum led_brightness buzz_led_get_brightness(struct led_classdev *led) | ||
| 501 | { | ||
| 502 | struct device *dev = led->dev->parent; | ||
| 503 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 504 | struct sony_sc *drv_data; | ||
| 505 | struct buzz_extra *buzz; | ||
| 506 | |||
| 507 | int n; | ||
| 508 | int on = 0; | ||
| 509 | |||
| 510 | drv_data = hid_get_drvdata(hdev); | ||
| 511 | if (!drv_data || !drv_data->extra) { | ||
| 512 | hid_err(hdev, "No device data\n"); | ||
| 513 | return LED_OFF; | ||
| 514 | } | ||
| 515 | buzz = drv_data->extra; | ||
| 516 | |||
| 517 | for (n = 0; n < 4; n++) { | ||
| 518 | if (led == buzz->leds[n]) { | ||
| 519 | on = !! (buzz->led_state & (1 << n)); | ||
| 520 | break; | ||
| 521 | } | ||
| 522 | } | ||
| 523 | |||
| 524 | return on ? LED_FULL : LED_OFF; | ||
| 525 | } | ||
| 526 | |||
| 527 | static int buzz_init(struct hid_device *hdev) | ||
| 528 | { | ||
| 529 | struct sony_sc *drv_data; | ||
| 530 | struct buzz_extra *buzz; | ||
| 531 | int n, ret = 0; | ||
| 532 | struct led_classdev *led; | ||
| 533 | size_t name_sz; | ||
| 534 | char *name; | ||
| 535 | |||
| 536 | drv_data = hid_get_drvdata(hdev); | ||
| 537 | BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); | ||
| 538 | |||
| 539 | buzz = kzalloc(sizeof(*buzz), GFP_KERNEL); | ||
| 540 | if (!buzz) { | ||
| 541 | hid_err(hdev, "Insufficient memory, cannot allocate driver data\n"); | ||
| 542 | return -ENOMEM; | ||
| 543 | } | ||
| 544 | drv_data->extra = buzz; | ||
| 545 | |||
| 546 | /* Clear LEDs as we have no way of reading their initial state. This is | ||
| 547 | * only relevant if the driver is loaded after somebody actively set the | ||
| 548 | * LEDs to on */ | ||
| 549 | buzz_set_leds(hdev, 0x00); | ||
| 550 | |||
| 551 | name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1; | ||
| 552 | |||
| 553 | for (n = 0; n < 4; n++) { | ||
| 554 | led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); | ||
| 555 | if (!led) { | ||
| 556 | hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); | ||
| 557 | goto error_leds; | ||
| 558 | } | ||
| 559 | |||
| 560 | name = (void *)(&led[1]); | ||
| 561 | snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1); | ||
| 562 | led->name = name; | ||
| 563 | led->brightness = 0; | ||
| 564 | led->max_brightness = 1; | ||
| 565 | led->brightness_get = buzz_led_get_brightness; | ||
| 566 | led->brightness_set = buzz_led_set_brightness; | ||
| 567 | |||
| 568 | if (led_classdev_register(&hdev->dev, led)) { | ||
| 569 | hid_err(hdev, "Failed to register LED %d\n", n); | ||
| 570 | kfree(led); | ||
| 571 | goto error_leds; | ||
| 572 | } | ||
| 573 | |||
| 574 | buzz->leds[n] = led; | ||
| 575 | } | ||
| 576 | |||
| 577 | return ret; | ||
| 578 | |||
| 579 | error_leds: | ||
| 580 | for (n = 0; n < 4; n++) { | ||
| 581 | led = buzz->leds[n]; | ||
| 582 | buzz->leds[n] = NULL; | ||
| 583 | if (!led) | ||
| 584 | continue; | ||
| 585 | led_classdev_unregister(led); | ||
| 586 | kfree(led); | ||
| 587 | } | ||
| 588 | |||
| 589 | kfree(drv_data->extra); | ||
| 590 | drv_data->extra = NULL; | ||
| 591 | return ret; | ||
| 592 | } | ||
| 593 | |||
| 594 | static void buzz_remove(struct hid_device *hdev) | ||
| 595 | { | ||
| 596 | struct sony_sc *drv_data; | ||
| 597 | struct buzz_extra *buzz; | ||
| 598 | struct led_classdev *led; | ||
| 599 | int n; | ||
| 600 | |||
| 601 | drv_data = hid_get_drvdata(hdev); | ||
| 602 | BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); | ||
| 603 | |||
| 604 | buzz = drv_data->extra; | ||
| 605 | |||
| 606 | for (n = 0; n < 4; n++) { | ||
| 607 | led = buzz->leds[n]; | ||
| 608 | buzz->leds[n] = NULL; | ||
| 609 | if (!led) | ||
| 610 | continue; | ||
| 611 | led_classdev_unregister(led); | ||
| 612 | kfree(led); | ||
| 613 | } | ||
| 614 | |||
| 615 | kfree(drv_data->extra); | ||
| 616 | drv_data->extra = NULL; | ||
| 617 | } | ||
| 618 | |||
| 195 | static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | 619 | static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| 196 | { | 620 | { |
| 197 | int ret; | 621 | int ret; |
| 198 | unsigned long quirks = id->driver_data; | 622 | unsigned long quirks = id->driver_data; |
| 199 | struct sony_sc *sc; | 623 | struct sony_sc *sc; |
| 624 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | ||
| 200 | 625 | ||
| 201 | sc = kzalloc(sizeof(*sc), GFP_KERNEL); | 626 | sc = kzalloc(sizeof(*sc), GFP_KERNEL); |
| 202 | if (sc == NULL) { | 627 | if (sc == NULL) { |
| @@ -213,8 +638,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 213 | goto err_free; | 638 | goto err_free; |
| 214 | } | 639 | } |
| 215 | 640 | ||
| 216 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | | 641 | if (sc->quirks & VAIO_RDESC_CONSTANT) |
| 217 | HID_CONNECT_HIDDEV_FORCE); | 642 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; |
| 643 | else if (sc->quirks & SIXAXIS_CONTROLLER_USB) | ||
| 644 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; | ||
| 645 | else if (sc->quirks & SIXAXIS_CONTROLLER_BT) | ||
| 646 | connect_mask |= HID_CONNECT_HIDDEV_FORCE; | ||
| 647 | |||
| 648 | ret = hid_hw_start(hdev, connect_mask); | ||
| 218 | if (ret) { | 649 | if (ret) { |
| 219 | hid_err(hdev, "hw start failed\n"); | 650 | hid_err(hdev, "hw start failed\n"); |
| 220 | goto err_free; | 651 | goto err_free; |
| @@ -226,6 +657,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 226 | } | 657 | } |
| 227 | else if (sc->quirks & SIXAXIS_CONTROLLER_BT) | 658 | else if (sc->quirks & SIXAXIS_CONTROLLER_BT) |
| 228 | ret = sixaxis_set_operational_bt(hdev); | 659 | ret = sixaxis_set_operational_bt(hdev); |
| 660 | else if (sc->quirks & BUZZ_CONTROLLER) | ||
| 661 | ret = buzz_init(hdev); | ||
| 229 | else | 662 | else |
| 230 | ret = 0; | 663 | ret = 0; |
| 231 | 664 | ||
| @@ -242,8 +675,13 @@ err_free: | |||
| 242 | 675 | ||
| 243 | static void sony_remove(struct hid_device *hdev) | 676 | static void sony_remove(struct hid_device *hdev) |
| 244 | { | 677 | { |
| 678 | struct sony_sc *sc = hid_get_drvdata(hdev); | ||
| 679 | |||
| 680 | if (sc->quirks & BUZZ_CONTROLLER) | ||
| 681 | buzz_remove(hdev); | ||
| 682 | |||
| 245 | hid_hw_stop(hdev); | 683 | hid_hw_stop(hdev); |
| 246 | kfree(hid_get_drvdata(hdev)); | 684 | kfree(sc); |
| 247 | } | 685 | } |
| 248 | 686 | ||
| 249 | static const struct hid_device_id sony_devices[] = { | 687 | static const struct hid_device_id sony_devices[] = { |
| @@ -257,17 +695,30 @@ static const struct hid_device_id sony_devices[] = { | |||
| 257 | .driver_data = VAIO_RDESC_CONSTANT }, | 695 | .driver_data = VAIO_RDESC_CONSTANT }, |
| 258 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), | 696 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), |
| 259 | .driver_data = VAIO_RDESC_CONSTANT }, | 697 | .driver_data = VAIO_RDESC_CONSTANT }, |
| 698 | /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as | ||
| 699 | * Logitech joystick from the device descriptor. */ | ||
| 700 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), | ||
| 701 | .driver_data = BUZZ_CONTROLLER }, | ||
| 702 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), | ||
| 703 | .driver_data = BUZZ_CONTROLLER }, | ||
| 704 | /* PS3 BD Remote Control */ | ||
| 705 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), | ||
| 706 | .driver_data = PS3REMOTE }, | ||
| 707 | /* Logitech Harmony Adapter for PS3 */ | ||
| 708 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), | ||
| 709 | .driver_data = PS3REMOTE }, | ||
| 260 | { } | 710 | { } |
| 261 | }; | 711 | }; |
| 262 | MODULE_DEVICE_TABLE(hid, sony_devices); | 712 | MODULE_DEVICE_TABLE(hid, sony_devices); |
| 263 | 713 | ||
| 264 | static struct hid_driver sony_driver = { | 714 | static struct hid_driver sony_driver = { |
| 265 | .name = "sony", | 715 | .name = "sony", |
| 266 | .id_table = sony_devices, | 716 | .id_table = sony_devices, |
| 267 | .probe = sony_probe, | 717 | .input_mapping = sony_mapping, |
| 268 | .remove = sony_remove, | 718 | .probe = sony_probe, |
| 269 | .report_fixup = sony_report_fixup, | 719 | .remove = sony_remove, |
| 270 | .raw_event = sony_raw_event | 720 | .report_fixup = sony_report_fixup, |
| 721 | .raw_event = sony_raw_event | ||
| 271 | }; | 722 | }; |
| 272 | module_hid_driver(sony_driver); | 723 | module_hid_driver(sony_driver); |
| 273 | 724 | ||
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index a4a8bb0da688..60c75dcbbdb8 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
| @@ -46,6 +46,7 @@ struct wacom_data { | |||
| 46 | __u8 battery_capacity; | 46 | __u8 battery_capacity; |
| 47 | __u8 power_raw; | 47 | __u8 power_raw; |
| 48 | __u8 ps_connected; | 48 | __u8 ps_connected; |
| 49 | __u8 bat_charging; | ||
| 49 | struct power_supply battery; | 50 | struct power_supply battery; |
| 50 | struct power_supply ac; | 51 | struct power_supply ac; |
| 51 | __u8 led_selector; | 52 | __u8 led_selector; |
| @@ -62,6 +63,7 @@ static enum power_supply_property wacom_battery_props[] = { | |||
| 62 | POWER_SUPPLY_PROP_PRESENT, | 63 | POWER_SUPPLY_PROP_PRESENT, |
| 63 | POWER_SUPPLY_PROP_CAPACITY, | 64 | POWER_SUPPLY_PROP_CAPACITY, |
| 64 | POWER_SUPPLY_PROP_SCOPE, | 65 | POWER_SUPPLY_PROP_SCOPE, |
| 66 | POWER_SUPPLY_PROP_STATUS, | ||
| 65 | }; | 67 | }; |
| 66 | 68 | ||
| 67 | static enum power_supply_property wacom_ac_props[] = { | 69 | static enum power_supply_property wacom_ac_props[] = { |
| @@ -287,6 +289,15 @@ static int wacom_battery_get_property(struct power_supply *psy, | |||
| 287 | case POWER_SUPPLY_PROP_CAPACITY: | 289 | case POWER_SUPPLY_PROP_CAPACITY: |
| 288 | val->intval = wdata->battery_capacity; | 290 | val->intval = wdata->battery_capacity; |
| 289 | break; | 291 | break; |
| 292 | case POWER_SUPPLY_PROP_STATUS: | ||
| 293 | if (wdata->bat_charging) | ||
| 294 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | ||
| 295 | else | ||
| 296 | if (wdata->battery_capacity == 100 && wdata->ps_connected) | ||
| 297 | val->intval = POWER_SUPPLY_STATUS_FULL; | ||
| 298 | else | ||
| 299 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | ||
| 300 | break; | ||
| 290 | default: | 301 | default: |
| 291 | ret = -EINVAL; | 302 | ret = -EINVAL; |
| 292 | break; | 303 | break; |
| @@ -727,7 +738,8 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
| 727 | if (power_raw != wdata->power_raw) { | 738 | if (power_raw != wdata->power_raw) { |
| 728 | wdata->power_raw = power_raw; | 739 | wdata->power_raw = power_raw; |
| 729 | wdata->battery_capacity = batcap_i4[power_raw & 0x07]; | 740 | wdata->battery_capacity = batcap_i4[power_raw & 0x07]; |
| 730 | wdata->ps_connected = power_raw & 0x08; | 741 | wdata->bat_charging = (power_raw & 0x08) ? 1 : 0; |
| 742 | wdata->ps_connected = (power_raw & 0x10) ? 1 : 0; | ||
| 731 | } | 743 | } |
| 732 | 744 | ||
| 733 | break; | 745 | break; |
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index e5ee1f20bbd9..0c06054cab8f 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * HID driver for Nintendo Wiimote devices | 2 | * HID driver for Nintendo Wii / Wii U peripherals |
| 3 | * Copyright (c) 2011 David Herrmann | 3 | * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com> |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | /* | 6 | /* |
| @@ -14,53 +14,19 @@ | |||
| 14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
| 15 | #include <linux/hid.h> | 15 | #include <linux/hid.h> |
| 16 | #include <linux/input.h> | 16 | #include <linux/input.h> |
| 17 | #include <linux/leds.h> | ||
| 18 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 19 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
| 20 | #include <linux/power_supply.h> | ||
| 21 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
| 22 | #include "hid-ids.h" | 20 | #include "hid-ids.h" |
| 23 | #include "hid-wiimote.h" | 21 | #include "hid-wiimote.h" |
| 24 | 22 | ||
| 25 | enum wiiproto_keys { | 23 | /* output queue handling */ |
| 26 | WIIPROTO_KEY_LEFT, | ||
| 27 | WIIPROTO_KEY_RIGHT, | ||
| 28 | WIIPROTO_KEY_UP, | ||
| 29 | WIIPROTO_KEY_DOWN, | ||
| 30 | WIIPROTO_KEY_PLUS, | ||
| 31 | WIIPROTO_KEY_MINUS, | ||
| 32 | WIIPROTO_KEY_ONE, | ||
| 33 | WIIPROTO_KEY_TWO, | ||
| 34 | WIIPROTO_KEY_A, | ||
| 35 | WIIPROTO_KEY_B, | ||
| 36 | WIIPROTO_KEY_HOME, | ||
| 37 | WIIPROTO_KEY_COUNT | ||
| 38 | }; | ||
| 39 | |||
| 40 | static __u16 wiiproto_keymap[] = { | ||
| 41 | KEY_LEFT, /* WIIPROTO_KEY_LEFT */ | ||
| 42 | KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */ | ||
| 43 | KEY_UP, /* WIIPROTO_KEY_UP */ | ||
| 44 | KEY_DOWN, /* WIIPROTO_KEY_DOWN */ | ||
| 45 | KEY_NEXT, /* WIIPROTO_KEY_PLUS */ | ||
| 46 | KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */ | ||
| 47 | BTN_1, /* WIIPROTO_KEY_ONE */ | ||
| 48 | BTN_2, /* WIIPROTO_KEY_TWO */ | ||
| 49 | BTN_A, /* WIIPROTO_KEY_A */ | ||
| 50 | BTN_B, /* WIIPROTO_KEY_B */ | ||
| 51 | BTN_MODE, /* WIIPROTO_KEY_HOME */ | ||
| 52 | }; | ||
| 53 | 24 | ||
| 54 | static enum power_supply_property wiimote_battery_props[] = { | 25 | static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, |
| 55 | POWER_SUPPLY_PROP_CAPACITY, | 26 | size_t count) |
| 56 | POWER_SUPPLY_PROP_SCOPE, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, | ||
| 60 | size_t count) | ||
| 61 | { | 27 | { |
| 62 | __u8 *buf; | 28 | __u8 *buf; |
| 63 | ssize_t ret; | 29 | int ret; |
| 64 | 30 | ||
| 65 | if (!hdev->hid_output_raw_report) | 31 | if (!hdev->hid_output_raw_report) |
| 66 | return -ENODEV; | 32 | return -ENODEV; |
| @@ -75,24 +41,33 @@ static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, | |||
| 75 | return ret; | 41 | return ret; |
| 76 | } | 42 | } |
| 77 | 43 | ||
| 78 | static void wiimote_worker(struct work_struct *work) | 44 | static void wiimote_queue_worker(struct work_struct *work) |
| 79 | { | 45 | { |
| 80 | struct wiimote_data *wdata = container_of(work, struct wiimote_data, | 46 | struct wiimote_queue *queue = container_of(work, struct wiimote_queue, |
| 81 | worker); | 47 | worker); |
| 48 | struct wiimote_data *wdata = container_of(queue, struct wiimote_data, | ||
| 49 | queue); | ||
| 82 | unsigned long flags; | 50 | unsigned long flags; |
| 51 | int ret; | ||
| 83 | 52 | ||
| 84 | spin_lock_irqsave(&wdata->qlock, flags); | 53 | spin_lock_irqsave(&wdata->queue.lock, flags); |
| 85 | 54 | ||
| 86 | while (wdata->head != wdata->tail) { | 55 | while (wdata->queue.head != wdata->queue.tail) { |
| 87 | spin_unlock_irqrestore(&wdata->qlock, flags); | 56 | spin_unlock_irqrestore(&wdata->queue.lock, flags); |
| 88 | wiimote_hid_send(wdata->hdev, wdata->outq[wdata->tail].data, | 57 | ret = wiimote_hid_send(wdata->hdev, |
| 89 | wdata->outq[wdata->tail].size); | 58 | wdata->queue.outq[wdata->queue.tail].data, |
| 90 | spin_lock_irqsave(&wdata->qlock, flags); | 59 | wdata->queue.outq[wdata->queue.tail].size); |
| 60 | if (ret < 0) { | ||
| 61 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 62 | wiimote_cmd_abort(wdata); | ||
| 63 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 64 | } | ||
| 65 | spin_lock_irqsave(&wdata->queue.lock, flags); | ||
| 91 | 66 | ||
| 92 | wdata->tail = (wdata->tail + 1) % WIIMOTE_BUFSIZE; | 67 | wdata->queue.tail = (wdata->queue.tail + 1) % WIIMOTE_BUFSIZE; |
| 93 | } | 68 | } |
| 94 | 69 | ||
| 95 | spin_unlock_irqrestore(&wdata->qlock, flags); | 70 | spin_unlock_irqrestore(&wdata->queue.lock, flags); |
| 96 | } | 71 | } |
| 97 | 72 | ||
| 98 | static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer, | 73 | static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer, |
| @@ -103,7 +78,9 @@ static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer, | |||
| 103 | 78 | ||
| 104 | if (count > HID_MAX_BUFFER_SIZE) { | 79 | if (count > HID_MAX_BUFFER_SIZE) { |
| 105 | hid_warn(wdata->hdev, "Sending too large output report\n"); | 80 | hid_warn(wdata->hdev, "Sending too large output report\n"); |
| 106 | return; | 81 | |
| 82 | spin_lock_irqsave(&wdata->queue.lock, flags); | ||
| 83 | goto out_error; | ||
| 107 | } | 84 | } |
| 108 | 85 | ||
| 109 | /* | 86 | /* |
| @@ -116,22 +93,28 @@ static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer, | |||
| 116 | * will reschedule itself until the queue is empty. | 93 | * will reschedule itself until the queue is empty. |
| 117 | */ | 94 | */ |
| 118 | 95 | ||
| 119 | spin_lock_irqsave(&wdata->qlock, flags); | 96 | spin_lock_irqsave(&wdata->queue.lock, flags); |
| 120 | 97 | ||
| 121 | memcpy(wdata->outq[wdata->head].data, buffer, count); | 98 | memcpy(wdata->queue.outq[wdata->queue.head].data, buffer, count); |
| 122 | wdata->outq[wdata->head].size = count; | 99 | wdata->queue.outq[wdata->queue.head].size = count; |
| 123 | newhead = (wdata->head + 1) % WIIMOTE_BUFSIZE; | 100 | newhead = (wdata->queue.head + 1) % WIIMOTE_BUFSIZE; |
| 124 | 101 | ||
| 125 | if (wdata->head == wdata->tail) { | 102 | if (wdata->queue.head == wdata->queue.tail) { |
| 126 | wdata->head = newhead; | 103 | wdata->queue.head = newhead; |
| 127 | schedule_work(&wdata->worker); | 104 | schedule_work(&wdata->queue.worker); |
| 128 | } else if (newhead != wdata->tail) { | 105 | } else if (newhead != wdata->queue.tail) { |
| 129 | wdata->head = newhead; | 106 | wdata->queue.head = newhead; |
| 130 | } else { | 107 | } else { |
| 131 | hid_warn(wdata->hdev, "Output queue is full"); | 108 | hid_warn(wdata->hdev, "Output queue is full"); |
| 109 | goto out_error; | ||
| 132 | } | 110 | } |
| 133 | 111 | ||
| 134 | spin_unlock_irqrestore(&wdata->qlock, flags); | 112 | goto out_unlock; |
| 113 | |||
| 114 | out_error: | ||
| 115 | wiimote_cmd_abort(wdata); | ||
| 116 | out_unlock: | ||
| 117 | spin_unlock_irqrestore(&wdata->queue.lock, flags); | ||
| 135 | } | 118 | } |
| 136 | 119 | ||
| 137 | /* | 120 | /* |
| @@ -147,7 +130,7 @@ static inline void wiiproto_keep_rumble(struct wiimote_data *wdata, __u8 *cmd1) | |||
| 147 | *cmd1 |= 0x01; | 130 | *cmd1 |= 0x01; |
| 148 | } | 131 | } |
| 149 | 132 | ||
| 150 | static void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble) | 133 | void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble) |
| 151 | { | 134 | { |
| 152 | __u8 cmd[2]; | 135 | __u8 cmd[2]; |
| 153 | 136 | ||
| @@ -167,7 +150,7 @@ static void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble) | |||
| 167 | wiimote_queue(wdata, cmd, sizeof(cmd)); | 150 | wiimote_queue(wdata, cmd, sizeof(cmd)); |
| 168 | } | 151 | } |
| 169 | 152 | ||
| 170 | static void wiiproto_req_leds(struct wiimote_data *wdata, int leds) | 153 | void wiiproto_req_leds(struct wiimote_data *wdata, int leds) |
| 171 | { | 154 | { |
| 172 | __u8 cmd[2]; | 155 | __u8 cmd[2]; |
| 173 | 156 | ||
| @@ -196,17 +179,46 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds) | |||
| 196 | * Check what peripherals of the wiimote are currently | 179 | * Check what peripherals of the wiimote are currently |
| 197 | * active and select a proper DRM that supports all of | 180 | * active and select a proper DRM that supports all of |
| 198 | * the requested data inputs. | 181 | * the requested data inputs. |
| 182 | * | ||
| 183 | * Not all combinations are actually supported. The following | ||
| 184 | * combinations work only with limitations: | ||
| 185 | * - IR cam in extended or full mode disables any data transmission | ||
| 186 | * of extension controllers. There is no DRM mode that supports | ||
| 187 | * extension bytes plus extended/full IR. | ||
| 188 | * - IR cam with accelerometer and extension *_EXT8 is not supported. | ||
| 189 | * However, all extensions that need *_EXT8 are devices that don't | ||
| 190 | * support IR cameras. Hence, this shouldn't happen under normal | ||
| 191 | * operation. | ||
| 192 | * - *_EXT16 is only supported in combination with buttons and | ||
| 193 | * accelerometer. No IR or similar can be active simultaneously. As | ||
| 194 | * above, all modules that require it are mutually exclusive with | ||
| 195 | * IR/etc. so this doesn't matter. | ||
| 199 | */ | 196 | */ |
| 200 | static __u8 select_drm(struct wiimote_data *wdata) | 197 | static __u8 select_drm(struct wiimote_data *wdata) |
| 201 | { | 198 | { |
| 202 | __u8 ir = wdata->state.flags & WIIPROTO_FLAGS_IR; | 199 | __u8 ir = wdata->state.flags & WIIPROTO_FLAGS_IR; |
| 203 | bool ext = wiiext_active(wdata); | 200 | bool ext; |
| 204 | 201 | ||
| 205 | if (ir == WIIPROTO_FLAG_IR_BASIC) { | 202 | ext = (wdata->state.flags & WIIPROTO_FLAG_EXT_USED) || |
| 206 | if (wdata->state.flags & WIIPROTO_FLAG_ACCEL) | 203 | (wdata->state.flags & WIIPROTO_FLAG_MP_USED); |
| 207 | return WIIPROTO_REQ_DRM_KAIE; | 204 | |
| 205 | /* some 3rd-party balance-boards are hard-coded to KEE, *sigh* */ | ||
| 206 | if (wdata->state.devtype == WIIMOTE_DEV_BALANCE_BOARD) { | ||
| 207 | if (ext) | ||
| 208 | return WIIPROTO_REQ_DRM_KEE; | ||
| 208 | else | 209 | else |
| 210 | return WIIPROTO_REQ_DRM_K; | ||
| 211 | } | ||
| 212 | |||
| 213 | if (ir == WIIPROTO_FLAG_IR_BASIC) { | ||
| 214 | if (wdata->state.flags & WIIPROTO_FLAG_ACCEL) { | ||
| 215 | if (ext) | ||
| 216 | return WIIPROTO_REQ_DRM_KAIE; | ||
| 217 | else | ||
| 218 | return WIIPROTO_REQ_DRM_KAI; | ||
| 219 | } else { | ||
| 209 | return WIIPROTO_REQ_DRM_KIE; | 220 | return WIIPROTO_REQ_DRM_KIE; |
| 221 | } | ||
| 210 | } else if (ir == WIIPROTO_FLAG_IR_EXT) { | 222 | } else if (ir == WIIPROTO_FLAG_IR_EXT) { |
| 211 | return WIIPROTO_REQ_DRM_KAI; | 223 | return WIIPROTO_REQ_DRM_KAI; |
| 212 | } else if (ir == WIIPROTO_FLAG_IR_FULL) { | 224 | } else if (ir == WIIPROTO_FLAG_IR_FULL) { |
| @@ -219,7 +231,7 @@ static __u8 select_drm(struct wiimote_data *wdata) | |||
| 219 | return WIIPROTO_REQ_DRM_KA; | 231 | return WIIPROTO_REQ_DRM_KA; |
| 220 | } else { | 232 | } else { |
| 221 | if (ext) | 233 | if (ext) |
| 222 | return WIIPROTO_REQ_DRM_KE; | 234 | return WIIPROTO_REQ_DRM_KEE; |
| 223 | else | 235 | else |
| 224 | return WIIPROTO_REQ_DRM_K; | 236 | return WIIPROTO_REQ_DRM_K; |
| 225 | } | 237 | } |
| @@ -230,7 +242,9 @@ void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm) | |||
| 230 | { | 242 | { |
| 231 | __u8 cmd[3]; | 243 | __u8 cmd[3]; |
| 232 | 244 | ||
| 233 | if (drm == WIIPROTO_REQ_NULL) | 245 | if (wdata->state.flags & WIIPROTO_FLAG_DRM_LOCKED) |
| 246 | drm = wdata->state.drm; | ||
| 247 | else if (drm == WIIPROTO_REQ_NULL) | ||
| 234 | drm = select_drm(wdata); | 248 | drm = select_drm(wdata); |
| 235 | 249 | ||
| 236 | cmd[0] = WIIPROTO_REQ_DRM; | 250 | cmd[0] = WIIPROTO_REQ_DRM; |
| @@ -242,7 +256,7 @@ void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm) | |||
| 242 | wiimote_queue(wdata, cmd, sizeof(cmd)); | 256 | wiimote_queue(wdata, cmd, sizeof(cmd)); |
| 243 | } | 257 | } |
| 244 | 258 | ||
| 245 | static void wiiproto_req_status(struct wiimote_data *wdata) | 259 | void wiiproto_req_status(struct wiimote_data *wdata) |
| 246 | { | 260 | { |
| 247 | __u8 cmd[2]; | 261 | __u8 cmd[2]; |
| 248 | 262 | ||
| @@ -253,7 +267,7 @@ static void wiiproto_req_status(struct wiimote_data *wdata) | |||
| 253 | wiimote_queue(wdata, cmd, sizeof(cmd)); | 267 | wiimote_queue(wdata, cmd, sizeof(cmd)); |
| 254 | } | 268 | } |
| 255 | 269 | ||
| 256 | static void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel) | 270 | void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel) |
| 257 | { | 271 | { |
| 258 | accel = !!accel; | 272 | accel = !!accel; |
| 259 | if (accel == !!(wdata->state.flags & WIIPROTO_FLAG_ACCEL)) | 273 | if (accel == !!(wdata->state.flags & WIIPROTO_FLAG_ACCEL)) |
| @@ -267,7 +281,7 @@ static void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel) | |||
| 267 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | 281 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); |
| 268 | } | 282 | } |
| 269 | 283 | ||
| 270 | static void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags) | 284 | void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags) |
| 271 | { | 285 | { |
| 272 | __u8 cmd[2]; | 286 | __u8 cmd[2]; |
| 273 | 287 | ||
| @@ -278,7 +292,7 @@ static void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags) | |||
| 278 | wiimote_queue(wdata, cmd, sizeof(cmd)); | 292 | wiimote_queue(wdata, cmd, sizeof(cmd)); |
| 279 | } | 293 | } |
| 280 | 294 | ||
| 281 | static void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags) | 295 | void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags) |
| 282 | { | 296 | { |
| 283 | __u8 cmd[2]; | 297 | __u8 cmd[2]; |
| 284 | 298 | ||
| @@ -394,399 +408,998 @@ ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, __u8 *rmem, | |||
| 394 | return ret; | 408 | return ret; |
| 395 | } | 409 | } |
| 396 | 410 | ||
| 397 | static int wiimote_battery_get_property(struct power_supply *psy, | 411 | /* requires the cmd-mutex to be held */ |
| 398 | enum power_supply_property psp, | 412 | static int wiimote_cmd_init_ext(struct wiimote_data *wdata) |
| 399 | union power_supply_propval *val) | ||
| 400 | { | 413 | { |
| 401 | struct wiimote_data *wdata = container_of(psy, | 414 | __u8 wmem; |
| 402 | struct wiimote_data, battery); | 415 | int ret; |
| 403 | int ret = 0, state; | ||
| 404 | unsigned long flags; | ||
| 405 | 416 | ||
| 406 | if (psp == POWER_SUPPLY_PROP_SCOPE) { | 417 | /* initialize extension */ |
| 407 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | 418 | wmem = 0x55; |
| 408 | return 0; | 419 | ret = wiimote_cmd_write(wdata, 0xa400f0, &wmem, sizeof(wmem)); |
| 409 | } | 420 | if (ret) |
| 421 | return ret; | ||
| 410 | 422 | ||
| 411 | ret = wiimote_cmd_acquire(wdata); | 423 | /* disable default encryption */ |
| 424 | wmem = 0x0; | ||
| 425 | ret = wiimote_cmd_write(wdata, 0xa400fb, &wmem, sizeof(wmem)); | ||
| 412 | if (ret) | 426 | if (ret) |
| 413 | return ret; | 427 | return ret; |
| 414 | 428 | ||
| 415 | spin_lock_irqsave(&wdata->state.lock, flags); | 429 | return 0; |
| 416 | wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0); | 430 | } |
| 417 | wiiproto_req_status(wdata); | ||
| 418 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 419 | 431 | ||
| 420 | ret = wiimote_cmd_wait(wdata); | 432 | /* requires the cmd-mutex to be held */ |
| 421 | state = wdata->state.cmd_battery; | 433 | static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem) |
| 422 | wiimote_cmd_release(wdata); | 434 | { |
| 435 | int ret; | ||
| 436 | |||
| 437 | /* read extension ID */ | ||
| 438 | ret = wiimote_cmd_read(wdata, 0xa400fa, rmem, 6); | ||
| 439 | if (ret != 6) | ||
| 440 | return WIIMOTE_EXT_NONE; | ||
| 441 | |||
| 442 | hid_dbg(wdata->hdev, "extension ID: %02x:%02x %02x:%02x %02x:%02x\n", | ||
| 443 | rmem[0], rmem[1], rmem[2], rmem[3], rmem[4], rmem[5]); | ||
| 423 | 444 | ||
| 445 | if (rmem[0] == 0xff && rmem[1] == 0xff && rmem[2] == 0xff && | ||
| 446 | rmem[3] == 0xff && rmem[4] == 0xff && rmem[5] == 0xff) | ||
| 447 | return WIIMOTE_EXT_NONE; | ||
| 448 | |||
| 449 | if (rmem[4] == 0x00 && rmem[5] == 0x00) | ||
| 450 | return WIIMOTE_EXT_NUNCHUK; | ||
| 451 | if (rmem[4] == 0x01 && rmem[5] == 0x01) | ||
| 452 | return WIIMOTE_EXT_CLASSIC_CONTROLLER; | ||
| 453 | if (rmem[4] == 0x04 && rmem[5] == 0x02) | ||
| 454 | return WIIMOTE_EXT_BALANCE_BOARD; | ||
| 455 | if (rmem[4] == 0x01 && rmem[5] == 0x20) | ||
| 456 | return WIIMOTE_EXT_PRO_CONTROLLER; | ||
| 457 | |||
| 458 | return WIIMOTE_EXT_UNKNOWN; | ||
| 459 | } | ||
| 460 | |||
| 461 | /* requires the cmd-mutex to be held */ | ||
| 462 | static int wiimote_cmd_init_mp(struct wiimote_data *wdata) | ||
| 463 | { | ||
| 464 | __u8 wmem; | ||
| 465 | int ret; | ||
| 466 | |||
| 467 | /* initialize MP */ | ||
| 468 | wmem = 0x55; | ||
| 469 | ret = wiimote_cmd_write(wdata, 0xa600f0, &wmem, sizeof(wmem)); | ||
| 424 | if (ret) | 470 | if (ret) |
| 425 | return ret; | 471 | return ret; |
| 426 | 472 | ||
| 427 | switch (psp) { | 473 | /* disable default encryption */ |
| 428 | case POWER_SUPPLY_PROP_CAPACITY: | 474 | wmem = 0x0; |
| 429 | val->intval = state * 100 / 255; | 475 | ret = wiimote_cmd_write(wdata, 0xa600fb, &wmem, sizeof(wmem)); |
| 430 | break; | 476 | if (ret) |
| 431 | default: | 477 | return ret; |
| 432 | ret = -EINVAL; | 478 | |
| 433 | break; | 479 | return 0; |
| 480 | } | ||
| 481 | |||
| 482 | /* requires the cmd-mutex to be held */ | ||
| 483 | static bool wiimote_cmd_map_mp(struct wiimote_data *wdata, __u8 exttype) | ||
| 484 | { | ||
| 485 | __u8 wmem; | ||
| 486 | |||
| 487 | /* map MP with correct pass-through mode */ | ||
| 488 | switch (exttype) { | ||
| 489 | case WIIMOTE_EXT_CLASSIC_CONTROLLER: | ||
| 490 | wmem = 0x07; | ||
| 491 | break; | ||
| 492 | case WIIMOTE_EXT_NUNCHUK: | ||
| 493 | wmem = 0x05; | ||
| 494 | break; | ||
| 495 | default: | ||
| 496 | wmem = 0x04; | ||
| 497 | break; | ||
| 434 | } | 498 | } |
| 435 | 499 | ||
| 436 | return ret; | 500 | return wiimote_cmd_write(wdata, 0xa600fe, &wmem, sizeof(wmem)); |
| 437 | } | 501 | } |
| 438 | 502 | ||
| 439 | static int wiimote_init_ir(struct wiimote_data *wdata, __u16 mode) | 503 | /* requires the cmd-mutex to be held */ |
| 504 | static bool wiimote_cmd_read_mp(struct wiimote_data *wdata, __u8 *rmem) | ||
| 440 | { | 505 | { |
| 441 | int ret; | 506 | int ret; |
| 442 | unsigned long flags; | ||
| 443 | __u8 format = 0; | ||
| 444 | static const __u8 data_enable[] = { 0x01 }; | ||
| 445 | static const __u8 data_sens1[] = { 0x02, 0x00, 0x00, 0x71, 0x01, | ||
| 446 | 0x00, 0xaa, 0x00, 0x64 }; | ||
| 447 | static const __u8 data_sens2[] = { 0x63, 0x03 }; | ||
| 448 | static const __u8 data_fin[] = { 0x08 }; | ||
| 449 | 507 | ||
| 450 | spin_lock_irqsave(&wdata->state.lock, flags); | 508 | /* read motion plus ID */ |
| 509 | ret = wiimote_cmd_read(wdata, 0xa600fa, rmem, 6); | ||
| 510 | if (ret != 6) | ||
| 511 | return false; | ||
| 451 | 512 | ||
| 452 | if (mode == (wdata->state.flags & WIIPROTO_FLAGS_IR)) { | 513 | hid_dbg(wdata->hdev, "motion plus ID: %02x:%02x %02x:%02x %02x:%02x\n", |
| 453 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 514 | rmem[0], rmem[1], rmem[2], rmem[3], rmem[4], rmem[5]); |
| 454 | return 0; | ||
| 455 | } | ||
| 456 | 515 | ||
| 457 | if (mode == 0) { | 516 | if (rmem[5] == 0x05) |
| 458 | wdata->state.flags &= ~WIIPROTO_FLAGS_IR; | 517 | return true; |
| 459 | wiiproto_req_ir1(wdata, 0); | ||
| 460 | wiiproto_req_ir2(wdata, 0); | ||
| 461 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 462 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 463 | return 0; | ||
| 464 | } | ||
| 465 | 518 | ||
| 466 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 519 | hid_info(wdata->hdev, "unknown motion plus ID: %02x:%02x %02x:%02x %02x:%02x\n", |
| 520 | rmem[0], rmem[1], rmem[2], rmem[3], rmem[4], rmem[5]); | ||
| 467 | 521 | ||
| 468 | ret = wiimote_cmd_acquire(wdata); | 522 | return false; |
| 469 | if (ret) | 523 | } |
| 470 | return ret; | ||
| 471 | 524 | ||
| 472 | /* send PIXEL CLOCK ENABLE cmd first */ | 525 | /* requires the cmd-mutex to be held */ |
| 473 | spin_lock_irqsave(&wdata->state.lock, flags); | 526 | static __u8 wiimote_cmd_read_mp_mapped(struct wiimote_data *wdata) |
| 474 | wiimote_cmd_set(wdata, WIIPROTO_REQ_IR1, 0); | 527 | { |
| 475 | wiiproto_req_ir1(wdata, 0x06); | 528 | int ret; |
| 476 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 529 | __u8 rmem[6]; |
| 477 | 530 | ||
| 478 | ret = wiimote_cmd_wait(wdata); | 531 | /* read motion plus ID */ |
| 479 | if (ret) | 532 | ret = wiimote_cmd_read(wdata, 0xa400fa, rmem, 6); |
| 480 | goto unlock; | 533 | if (ret != 6) |
| 481 | if (wdata->state.cmd_err) { | 534 | return WIIMOTE_MP_NONE; |
| 482 | ret = -EIO; | 535 | |
| 483 | goto unlock; | 536 | hid_dbg(wdata->hdev, "mapped motion plus ID: %02x:%02x %02x:%02x %02x:%02x\n", |
| 537 | rmem[0], rmem[1], rmem[2], rmem[3], rmem[4], rmem[5]); | ||
| 538 | |||
| 539 | if (rmem[0] == 0xff && rmem[1] == 0xff && rmem[2] == 0xff && | ||
| 540 | rmem[3] == 0xff && rmem[4] == 0xff && rmem[5] == 0xff) | ||
| 541 | return WIIMOTE_MP_NONE; | ||
| 542 | |||
| 543 | if (rmem[4] == 0x04 && rmem[5] == 0x05) | ||
| 544 | return WIIMOTE_MP_SINGLE; | ||
| 545 | else if (rmem[4] == 0x05 && rmem[5] == 0x05) | ||
| 546 | return WIIMOTE_MP_PASSTHROUGH_NUNCHUK; | ||
| 547 | else if (rmem[4] == 0x07 && rmem[5] == 0x05) | ||
| 548 | return WIIMOTE_MP_PASSTHROUGH_CLASSIC; | ||
| 549 | |||
| 550 | return WIIMOTE_MP_UNKNOWN; | ||
| 551 | } | ||
| 552 | |||
| 553 | /* device module handling */ | ||
| 554 | |||
| 555 | static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = { | ||
| 556 | [WIIMOTE_DEV_PENDING] = (const __u8[]){ | ||
| 557 | WIIMOD_NULL, | ||
| 558 | }, | ||
| 559 | [WIIMOTE_DEV_UNKNOWN] = (const __u8[]){ | ||
| 560 | WIIMOD_NO_MP, | ||
| 561 | WIIMOD_NULL, | ||
| 562 | }, | ||
| 563 | [WIIMOTE_DEV_GENERIC] = (const __u8[]){ | ||
| 564 | WIIMOD_KEYS, | ||
| 565 | WIIMOD_RUMBLE, | ||
| 566 | WIIMOD_BATTERY, | ||
| 567 | WIIMOD_LED1, | ||
| 568 | WIIMOD_LED2, | ||
| 569 | WIIMOD_LED3, | ||
| 570 | WIIMOD_LED4, | ||
| 571 | WIIMOD_ACCEL, | ||
| 572 | WIIMOD_IR, | ||
| 573 | WIIMOD_NULL, | ||
| 574 | }, | ||
| 575 | [WIIMOTE_DEV_GEN10] = (const __u8[]){ | ||
| 576 | WIIMOD_KEYS, | ||
| 577 | WIIMOD_RUMBLE, | ||
| 578 | WIIMOD_BATTERY, | ||
| 579 | WIIMOD_LED1, | ||
| 580 | WIIMOD_LED2, | ||
| 581 | WIIMOD_LED3, | ||
| 582 | WIIMOD_LED4, | ||
| 583 | WIIMOD_ACCEL, | ||
| 584 | WIIMOD_IR, | ||
| 585 | WIIMOD_NULL, | ||
| 586 | }, | ||
| 587 | [WIIMOTE_DEV_GEN20] = (const __u8[]){ | ||
| 588 | WIIMOD_KEYS, | ||
| 589 | WIIMOD_RUMBLE, | ||
| 590 | WIIMOD_BATTERY, | ||
| 591 | WIIMOD_LED1, | ||
| 592 | WIIMOD_LED2, | ||
| 593 | WIIMOD_LED3, | ||
| 594 | WIIMOD_LED4, | ||
| 595 | WIIMOD_ACCEL, | ||
| 596 | WIIMOD_IR, | ||
| 597 | WIIMOD_BUILTIN_MP, | ||
| 598 | WIIMOD_NULL, | ||
| 599 | }, | ||
| 600 | [WIIMOTE_DEV_BALANCE_BOARD] = (const __u8[]) { | ||
| 601 | WIIMOD_BATTERY, | ||
| 602 | WIIMOD_LED1, | ||
| 603 | WIIMOD_NO_MP, | ||
| 604 | WIIMOD_NULL, | ||
| 605 | }, | ||
| 606 | [WIIMOTE_DEV_PRO_CONTROLLER] = (const __u8[]) { | ||
| 607 | WIIMOD_BATTERY, | ||
| 608 | WIIMOD_LED1, | ||
| 609 | WIIMOD_LED2, | ||
| 610 | WIIMOD_LED3, | ||
| 611 | WIIMOD_LED4, | ||
| 612 | WIIMOD_NO_MP, | ||
| 613 | WIIMOD_NULL, | ||
| 614 | }, | ||
| 615 | }; | ||
| 616 | |||
| 617 | static void wiimote_modules_load(struct wiimote_data *wdata, | ||
| 618 | unsigned int devtype) | ||
| 619 | { | ||
| 620 | bool need_input = false; | ||
| 621 | const __u8 *mods, *iter; | ||
| 622 | const struct wiimod_ops *ops; | ||
| 623 | int ret; | ||
| 624 | |||
| 625 | mods = wiimote_devtype_mods[devtype]; | ||
| 626 | |||
| 627 | for (iter = mods; *iter != WIIMOD_NULL; ++iter) { | ||
| 628 | if (wiimod_table[*iter]->flags & WIIMOD_FLAG_INPUT) { | ||
| 629 | need_input = true; | ||
| 630 | break; | ||
| 631 | } | ||
| 484 | } | 632 | } |
| 485 | 633 | ||
| 486 | /* enable IR LOGIC */ | 634 | if (need_input) { |
| 487 | spin_lock_irqsave(&wdata->state.lock, flags); | 635 | wdata->input = input_allocate_device(); |
| 488 | wiimote_cmd_set(wdata, WIIPROTO_REQ_IR2, 0); | 636 | if (!wdata->input) |
| 489 | wiiproto_req_ir2(wdata, 0x06); | 637 | return; |
| 490 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 638 | |
| 639 | input_set_drvdata(wdata->input, wdata); | ||
| 640 | wdata->input->dev.parent = &wdata->hdev->dev; | ||
| 641 | wdata->input->id.bustype = wdata->hdev->bus; | ||
| 642 | wdata->input->id.vendor = wdata->hdev->vendor; | ||
| 643 | wdata->input->id.product = wdata->hdev->product; | ||
| 644 | wdata->input->id.version = wdata->hdev->version; | ||
| 645 | wdata->input->name = WIIMOTE_NAME; | ||
| 646 | } | ||
| 491 | 647 | ||
| 492 | ret = wiimote_cmd_wait(wdata); | 648 | for (iter = mods; *iter != WIIMOD_NULL; ++iter) { |
| 493 | if (ret) | 649 | ops = wiimod_table[*iter]; |
| 494 | goto unlock; | 650 | if (!ops->probe) |
| 495 | if (wdata->state.cmd_err) { | 651 | continue; |
| 496 | ret = -EIO; | 652 | |
| 497 | goto unlock; | 653 | ret = ops->probe(ops, wdata); |
| 654 | if (ret) | ||
| 655 | goto error; | ||
| 498 | } | 656 | } |
| 499 | 657 | ||
| 500 | /* enable IR cam but do not make it send data, yet */ | 658 | if (wdata->input) { |
| 501 | ret = wiimote_cmd_write(wdata, 0xb00030, data_enable, | 659 | ret = input_register_device(wdata->input); |
| 502 | sizeof(data_enable)); | 660 | if (ret) |
| 503 | if (ret) | 661 | goto error; |
| 504 | goto unlock; | 662 | } |
| 505 | 663 | ||
| 506 | /* write first sensitivity block */ | 664 | spin_lock_irq(&wdata->state.lock); |
| 507 | ret = wiimote_cmd_write(wdata, 0xb00000, data_sens1, | 665 | wdata->state.devtype = devtype; |
| 508 | sizeof(data_sens1)); | 666 | spin_unlock_irq(&wdata->state.lock); |
| 509 | if (ret) | 667 | return; |
| 510 | goto unlock; | ||
| 511 | 668 | ||
| 512 | /* write second sensitivity block */ | 669 | error: |
| 513 | ret = wiimote_cmd_write(wdata, 0xb0001a, data_sens2, | 670 | for ( ; iter-- != mods; ) { |
| 514 | sizeof(data_sens2)); | 671 | ops = wiimod_table[*iter]; |
| 515 | if (ret) | 672 | if (ops->remove) |
| 516 | goto unlock; | 673 | ops->remove(ops, wdata); |
| 674 | } | ||
| 517 | 675 | ||
| 518 | /* put IR cam into desired state */ | 676 | if (wdata->input) { |
| 519 | switch (mode) { | 677 | input_free_device(wdata->input); |
| 520 | case WIIPROTO_FLAG_IR_FULL: | 678 | wdata->input = NULL; |
| 521 | format = 5; | ||
| 522 | break; | ||
| 523 | case WIIPROTO_FLAG_IR_EXT: | ||
| 524 | format = 3; | ||
| 525 | break; | ||
| 526 | case WIIPROTO_FLAG_IR_BASIC: | ||
| 527 | format = 1; | ||
| 528 | break; | ||
| 529 | } | 679 | } |
| 530 | ret = wiimote_cmd_write(wdata, 0xb00033, &format, sizeof(format)); | 680 | } |
| 531 | if (ret) | ||
| 532 | goto unlock; | ||
| 533 | 681 | ||
| 534 | /* make IR cam send data */ | 682 | static void wiimote_modules_unload(struct wiimote_data *wdata) |
| 535 | ret = wiimote_cmd_write(wdata, 0xb00030, data_fin, sizeof(data_fin)); | 683 | { |
| 536 | if (ret) | 684 | const __u8 *mods, *iter; |
| 537 | goto unlock; | 685 | const struct wiimod_ops *ops; |
| 686 | unsigned long flags; | ||
| 687 | |||
| 688 | mods = wiimote_devtype_mods[wdata->state.devtype]; | ||
| 538 | 689 | ||
| 539 | /* request new DRM mode compatible to IR mode */ | ||
| 540 | spin_lock_irqsave(&wdata->state.lock, flags); | 690 | spin_lock_irqsave(&wdata->state.lock, flags); |
| 541 | wdata->state.flags &= ~WIIPROTO_FLAGS_IR; | 691 | wdata->state.devtype = WIIMOTE_DEV_UNKNOWN; |
| 542 | wdata->state.flags |= mode & WIIPROTO_FLAGS_IR; | ||
| 543 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 544 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 692 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
| 545 | 693 | ||
| 546 | unlock: | 694 | /* find end of list */ |
| 547 | wiimote_cmd_release(wdata); | 695 | for (iter = mods; *iter != WIIMOD_NULL; ++iter) |
| 548 | return ret; | 696 | /* empty */ ; |
| 697 | |||
| 698 | if (wdata->input) { | ||
| 699 | input_get_device(wdata->input); | ||
| 700 | input_unregister_device(wdata->input); | ||
| 701 | } | ||
| 702 | |||
| 703 | for ( ; iter-- != mods; ) { | ||
| 704 | ops = wiimod_table[*iter]; | ||
| 705 | if (ops->remove) | ||
| 706 | ops->remove(ops, wdata); | ||
| 707 | } | ||
| 708 | |||
| 709 | if (wdata->input) { | ||
| 710 | input_put_device(wdata->input); | ||
| 711 | wdata->input = NULL; | ||
| 712 | } | ||
| 549 | } | 713 | } |
| 550 | 714 | ||
| 551 | static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev) | 715 | /* device extension handling */ |
| 716 | |||
| 717 | static void wiimote_ext_load(struct wiimote_data *wdata, unsigned int ext) | ||
| 552 | { | 718 | { |
| 553 | struct wiimote_data *wdata; | ||
| 554 | struct device *dev = led_dev->dev->parent; | ||
| 555 | int i; | ||
| 556 | unsigned long flags; | 719 | unsigned long flags; |
| 557 | bool value = false; | 720 | const struct wiimod_ops *ops; |
| 721 | int ret; | ||
| 558 | 722 | ||
| 559 | wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); | 723 | ops = wiimod_ext_table[ext]; |
| 560 | 724 | ||
| 561 | for (i = 0; i < 4; ++i) { | 725 | if (ops->probe) { |
| 562 | if (wdata->leds[i] == led_dev) { | 726 | ret = ops->probe(ops, wdata); |
| 563 | spin_lock_irqsave(&wdata->state.lock, flags); | 727 | if (ret) |
| 564 | value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1); | 728 | ext = WIIMOTE_EXT_UNKNOWN; |
| 565 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 566 | break; | ||
| 567 | } | ||
| 568 | } | 729 | } |
| 569 | 730 | ||
| 570 | return value ? LED_FULL : LED_OFF; | 731 | spin_lock_irqsave(&wdata->state.lock, flags); |
| 732 | wdata->state.exttype = ext; | ||
| 733 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 571 | } | 734 | } |
| 572 | 735 | ||
| 573 | static void wiimote_leds_set(struct led_classdev *led_dev, | 736 | static void wiimote_ext_unload(struct wiimote_data *wdata) |
| 574 | enum led_brightness value) | ||
| 575 | { | 737 | { |
| 576 | struct wiimote_data *wdata; | ||
| 577 | struct device *dev = led_dev->dev->parent; | ||
| 578 | int i; | ||
| 579 | unsigned long flags; | 738 | unsigned long flags; |
| 580 | __u8 state, flag; | 739 | const struct wiimod_ops *ops; |
| 581 | 740 | ||
| 582 | wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); | 741 | ops = wiimod_ext_table[wdata->state.exttype]; |
| 583 | 742 | ||
| 584 | for (i = 0; i < 4; ++i) { | 743 | spin_lock_irqsave(&wdata->state.lock, flags); |
| 585 | if (wdata->leds[i] == led_dev) { | 744 | wdata->state.exttype = WIIMOTE_EXT_UNKNOWN; |
| 586 | flag = WIIPROTO_FLAG_LED(i + 1); | 745 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; |
| 587 | spin_lock_irqsave(&wdata->state.lock, flags); | 746 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
| 588 | state = wdata->state.flags; | 747 | |
| 589 | if (value == LED_OFF) | 748 | if (ops->remove) |
| 590 | wiiproto_req_leds(wdata, state & ~flag); | 749 | ops->remove(ops, wdata); |
| 591 | else | 750 | } |
| 592 | wiiproto_req_leds(wdata, state | flag); | 751 | |
| 593 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 752 | static void wiimote_mp_load(struct wiimote_data *wdata) |
| 594 | break; | 753 | { |
| 595 | } | 754 | unsigned long flags; |
| 755 | const struct wiimod_ops *ops; | ||
| 756 | int ret; | ||
| 757 | __u8 mode = 2; | ||
| 758 | |||
| 759 | ops = &wiimod_mp; | ||
| 760 | if (ops->probe) { | ||
| 761 | ret = ops->probe(ops, wdata); | ||
| 762 | if (ret) | ||
| 763 | mode = 1; | ||
| 596 | } | 764 | } |
| 765 | |||
| 766 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 767 | wdata->state.mp = mode; | ||
| 768 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 597 | } | 769 | } |
| 598 | 770 | ||
| 599 | static int wiimote_ff_play(struct input_dev *dev, void *data, | 771 | static void wiimote_mp_unload(struct wiimote_data *wdata) |
| 600 | struct ff_effect *eff) | ||
| 601 | { | 772 | { |
| 602 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 603 | __u8 value; | ||
| 604 | unsigned long flags; | 773 | unsigned long flags; |
| 774 | const struct wiimod_ops *ops; | ||
| 605 | 775 | ||
| 606 | /* | 776 | if (wdata->state.mp < 2) |
| 607 | * The wiimote supports only a single rumble motor so if any magnitude | 777 | return; |
| 608 | * is set to non-zero then we start the rumble motor. If both are set to | ||
| 609 | * zero, we stop the rumble motor. | ||
| 610 | */ | ||
| 611 | 778 | ||
| 612 | if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude) | 779 | ops = &wiimod_mp; |
| 613 | value = 1; | ||
| 614 | else | ||
| 615 | value = 0; | ||
| 616 | 780 | ||
| 617 | spin_lock_irqsave(&wdata->state.lock, flags); | 781 | spin_lock_irqsave(&wdata->state.lock, flags); |
| 618 | wiiproto_req_rumble(wdata, value); | 782 | wdata->state.mp = 0; |
| 783 | wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED; | ||
| 619 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 784 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
| 620 | 785 | ||
| 621 | return 0; | 786 | if (ops->remove) |
| 787 | ops->remove(ops, wdata); | ||
| 622 | } | 788 | } |
| 623 | 789 | ||
| 624 | static int wiimote_input_open(struct input_dev *dev) | 790 | /* device (re-)initialization and detection */ |
| 625 | { | ||
| 626 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 627 | 791 | ||
| 628 | return hid_hw_open(wdata->hdev); | 792 | static const char *wiimote_devtype_names[WIIMOTE_DEV_NUM] = { |
| 629 | } | 793 | [WIIMOTE_DEV_PENDING] = "Pending", |
| 794 | [WIIMOTE_DEV_UNKNOWN] = "Unknown", | ||
| 795 | [WIIMOTE_DEV_GENERIC] = "Generic", | ||
| 796 | [WIIMOTE_DEV_GEN10] = "Nintendo Wii Remote (Gen 1)", | ||
| 797 | [WIIMOTE_DEV_GEN20] = "Nintendo Wii Remote Plus (Gen 2)", | ||
| 798 | [WIIMOTE_DEV_BALANCE_BOARD] = "Nintendo Wii Balance Board", | ||
| 799 | [WIIMOTE_DEV_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller", | ||
| 800 | }; | ||
| 630 | 801 | ||
| 631 | static void wiimote_input_close(struct input_dev *dev) | 802 | /* Try to guess the device type based on all collected information. We |
| 803 | * first try to detect by static extension types, then VID/PID and the | ||
| 804 | * device name. If we cannot detect the device, we use | ||
| 805 | * WIIMOTE_DEV_GENERIC so all modules will get probed on the device. */ | ||
| 806 | static void wiimote_init_set_type(struct wiimote_data *wdata, | ||
| 807 | __u8 exttype) | ||
| 632 | { | 808 | { |
| 633 | struct wiimote_data *wdata = input_get_drvdata(dev); | 809 | __u8 devtype = WIIMOTE_DEV_GENERIC; |
| 810 | __u16 vendor, product; | ||
| 811 | const char *name; | ||
| 812 | |||
| 813 | vendor = wdata->hdev->vendor; | ||
| 814 | product = wdata->hdev->product; | ||
| 815 | name = wdata->hdev->name; | ||
| 816 | |||
| 817 | if (exttype == WIIMOTE_EXT_BALANCE_BOARD) { | ||
| 818 | devtype = WIIMOTE_DEV_BALANCE_BOARD; | ||
| 819 | goto done; | ||
| 820 | } else if (exttype == WIIMOTE_EXT_PRO_CONTROLLER) { | ||
| 821 | devtype = WIIMOTE_DEV_PRO_CONTROLLER; | ||
| 822 | goto done; | ||
| 823 | } | ||
| 634 | 824 | ||
| 635 | hid_hw_close(wdata->hdev); | 825 | if (!strcmp(name, "Nintendo RVL-CNT-01")) { |
| 826 | devtype = WIIMOTE_DEV_GEN10; | ||
| 827 | goto done; | ||
| 828 | } else if (!strcmp(name, "Nintendo RVL-CNT-01-TR")) { | ||
| 829 | devtype = WIIMOTE_DEV_GEN20; | ||
| 830 | goto done; | ||
| 831 | } else if (!strcmp(name, "Nintendo RVL-WBC-01")) { | ||
| 832 | devtype = WIIMOTE_DEV_BALANCE_BOARD; | ||
| 833 | goto done; | ||
| 834 | } else if (!strcmp(name, "Nintendo RVL-CNT-01-UC")) { | ||
| 835 | devtype = WIIMOTE_DEV_PRO_CONTROLLER; | ||
| 836 | goto done; | ||
| 837 | } | ||
| 838 | |||
| 839 | if (vendor == USB_VENDOR_ID_NINTENDO) { | ||
| 840 | if (product == USB_DEVICE_ID_NINTENDO_WIIMOTE) { | ||
| 841 | devtype = WIIMOTE_DEV_GEN10; | ||
| 842 | goto done; | ||
| 843 | } else if (product == USB_DEVICE_ID_NINTENDO_WIIMOTE2) { | ||
| 844 | devtype = WIIMOTE_DEV_GEN20; | ||
| 845 | goto done; | ||
| 846 | } | ||
| 847 | } | ||
| 848 | |||
| 849 | done: | ||
| 850 | if (devtype == WIIMOTE_DEV_GENERIC) | ||
| 851 | hid_info(wdata->hdev, "cannot detect device; NAME: %s VID: %04x PID: %04x EXT: %04x\n", | ||
| 852 | name, vendor, product, exttype); | ||
| 853 | else | ||
| 854 | hid_info(wdata->hdev, "detected device: %s\n", | ||
| 855 | wiimote_devtype_names[devtype]); | ||
| 856 | |||
| 857 | wiimote_modules_load(wdata, devtype); | ||
| 636 | } | 858 | } |
| 637 | 859 | ||
| 638 | static int wiimote_accel_open(struct input_dev *dev) | 860 | static void wiimote_init_detect(struct wiimote_data *wdata) |
| 639 | { | 861 | { |
| 640 | struct wiimote_data *wdata = input_get_drvdata(dev); | 862 | __u8 exttype = WIIMOTE_EXT_NONE, extdata[6]; |
| 863 | bool ext; | ||
| 641 | int ret; | 864 | int ret; |
| 642 | unsigned long flags; | ||
| 643 | 865 | ||
| 644 | ret = hid_hw_open(wdata->hdev); | 866 | wiimote_cmd_acquire_noint(wdata); |
| 867 | |||
| 868 | spin_lock_irq(&wdata->state.lock); | ||
| 869 | wdata->state.devtype = WIIMOTE_DEV_UNKNOWN; | ||
| 870 | wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0); | ||
| 871 | wiiproto_req_status(wdata); | ||
| 872 | spin_unlock_irq(&wdata->state.lock); | ||
| 873 | |||
| 874 | ret = wiimote_cmd_wait_noint(wdata); | ||
| 645 | if (ret) | 875 | if (ret) |
| 646 | return ret; | 876 | goto out_release; |
| 647 | 877 | ||
| 648 | spin_lock_irqsave(&wdata->state.lock, flags); | 878 | spin_lock_irq(&wdata->state.lock); |
| 649 | wiiproto_req_accel(wdata, true); | 879 | ext = wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED; |
| 650 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 880 | spin_unlock_irq(&wdata->state.lock); |
| 651 | 881 | ||
| 652 | return 0; | 882 | if (!ext) |
| 883 | goto out_release; | ||
| 884 | |||
| 885 | wiimote_cmd_init_ext(wdata); | ||
| 886 | exttype = wiimote_cmd_read_ext(wdata, extdata); | ||
| 887 | |||
| 888 | out_release: | ||
| 889 | wiimote_cmd_release(wdata); | ||
| 890 | wiimote_init_set_type(wdata, exttype); | ||
| 891 | |||
| 892 | /* schedule MP timer */ | ||
| 893 | spin_lock_irq(&wdata->state.lock); | ||
| 894 | if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) && | ||
| 895 | !(wdata->state.flags & WIIPROTO_FLAG_NO_MP)) | ||
| 896 | mod_timer(&wdata->timer, jiffies + HZ * 4); | ||
| 897 | spin_unlock_irq(&wdata->state.lock); | ||
| 653 | } | 898 | } |
| 654 | 899 | ||
| 655 | static void wiimote_accel_close(struct input_dev *dev) | 900 | /* |
| 901 | * MP hotplug events are not generated by the wiimote. Therefore, we need | ||
| 902 | * polling to detect it. We use a 4s interval for polling MP registers. This | ||
| 903 | * seems reasonable considering applications can trigger it manually via | ||
| 904 | * sysfs requests. | ||
| 905 | */ | ||
| 906 | static void wiimote_init_poll_mp(struct wiimote_data *wdata) | ||
| 656 | { | 907 | { |
| 657 | struct wiimote_data *wdata = input_get_drvdata(dev); | 908 | bool mp; |
| 658 | unsigned long flags; | 909 | __u8 mpdata[6]; |
| 659 | 910 | ||
| 660 | spin_lock_irqsave(&wdata->state.lock, flags); | 911 | wiimote_cmd_acquire_noint(wdata); |
| 661 | wiiproto_req_accel(wdata, false); | 912 | wiimote_cmd_init_mp(wdata); |
| 662 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 913 | mp = wiimote_cmd_read_mp(wdata, mpdata); |
| 914 | wiimote_cmd_release(wdata); | ||
| 663 | 915 | ||
| 664 | hid_hw_close(wdata->hdev); | 916 | /* load/unload MP module if it changed */ |
| 917 | if (mp) { | ||
| 918 | if (!wdata->state.mp) { | ||
| 919 | hid_info(wdata->hdev, "detected extension: Nintendo Wii Motion Plus\n"); | ||
| 920 | wiimote_mp_load(wdata); | ||
| 921 | } | ||
| 922 | } else if (wdata->state.mp) { | ||
| 923 | wiimote_mp_unload(wdata); | ||
| 924 | } | ||
| 925 | |||
| 926 | mod_timer(&wdata->timer, jiffies + HZ * 4); | ||
| 665 | } | 927 | } |
| 666 | 928 | ||
| 667 | static int wiimote_ir_open(struct input_dev *dev) | 929 | /* |
| 930 | * Check whether the wiimote is in the expected state. The extension registers | ||
| 931 | * may change during hotplug and initialization so we might get hotplug events | ||
| 932 | * that we caused by remapping some memory. | ||
| 933 | * We use some heuristics here to check known states. If the wiimote is in the | ||
| 934 | * expected state, we can ignore the hotplug event. | ||
| 935 | * | ||
| 936 | * Returns "true" if the device is in expected state, "false" if we should | ||
| 937 | * redo hotplug handling and extension initialization. | ||
| 938 | */ | ||
| 939 | static bool wiimote_init_check(struct wiimote_data *wdata) | ||
| 668 | { | 940 | { |
| 669 | struct wiimote_data *wdata = input_get_drvdata(dev); | 941 | __u32 flags; |
| 670 | int ret; | 942 | __u8 type, data[6]; |
| 943 | bool ret, poll_mp; | ||
| 671 | 944 | ||
| 672 | ret = hid_hw_open(wdata->hdev); | 945 | spin_lock_irq(&wdata->state.lock); |
| 673 | if (ret) | 946 | flags = wdata->state.flags; |
| 674 | return ret; | 947 | spin_unlock_irq(&wdata->state.lock); |
| 675 | 948 | ||
| 676 | ret = wiimote_init_ir(wdata, WIIPROTO_FLAG_IR_BASIC); | 949 | wiimote_cmd_acquire_noint(wdata); |
| 677 | if (ret) { | 950 | |
| 678 | hid_hw_close(wdata->hdev); | 951 | /* If MP is used and active, but the extension is not, we expect: |
| 679 | return ret; | 952 | * read_mp_mapped() == WIIMOTE_MP_SINGLE |
| 953 | * state.flags == !EXT_ACTIVE && !MP_PLUGGED && MP_ACTIVE | ||
| 954 | * We do not check EXT_PLUGGED because it might change during | ||
| 955 | * initialization of MP without extensions. | ||
| 956 | * - If MP is unplugged/replugged, read_mp_mapped() fails | ||
| 957 | * - If EXT is plugged, MP_PLUGGED will get set */ | ||
| 958 | if (wdata->state.exttype == WIIMOTE_EXT_NONE && | ||
| 959 | wdata->state.mp > 0 && (flags & WIIPROTO_FLAG_MP_USED)) { | ||
| 960 | type = wiimote_cmd_read_mp_mapped(wdata); | ||
| 961 | ret = type == WIIMOTE_MP_SINGLE; | ||
| 962 | |||
| 963 | spin_lock_irq(&wdata->state.lock); | ||
| 964 | ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); | ||
| 965 | ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED); | ||
| 966 | ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); | ||
| 967 | spin_unlock_irq(&wdata->state.lock); | ||
| 968 | |||
| 969 | if (!ret) | ||
| 970 | hid_dbg(wdata->hdev, "state left: !EXT && MP\n"); | ||
| 971 | |||
| 972 | /* while MP is mapped, we get EXT_PLUGGED events */ | ||
| 973 | poll_mp = false; | ||
| 974 | |||
| 975 | goto out_release; | ||
| 680 | } | 976 | } |
| 681 | 977 | ||
| 682 | return 0; | 978 | /* If MP is unused, but the extension port is used, we expect: |
| 979 | * read_ext == state.exttype | ||
| 980 | * state.flags == !MP_ACTIVE && EXT_ACTIVE | ||
| 981 | * - If MP is plugged/unplugged, our timer detects it | ||
| 982 | * - If EXT is unplugged/replugged, EXT_ACTIVE will become unset */ | ||
| 983 | if (!(flags & WIIPROTO_FLAG_MP_USED) && | ||
| 984 | wdata->state.exttype != WIIMOTE_EXT_NONE) { | ||
| 985 | type = wiimote_cmd_read_ext(wdata, data); | ||
| 986 | ret = type == wdata->state.exttype; | ||
| 987 | |||
| 988 | spin_lock_irq(&wdata->state.lock); | ||
| 989 | ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); | ||
| 990 | ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); | ||
| 991 | spin_unlock_irq(&wdata->state.lock); | ||
| 992 | |||
| 993 | if (!ret) | ||
| 994 | hid_dbg(wdata->hdev, "state left: EXT && !MP\n"); | ||
| 995 | |||
| 996 | /* poll MP for hotplug events */ | ||
| 997 | poll_mp = true; | ||
| 998 | |||
| 999 | goto out_release; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | /* If neither MP nor an extension are used, we expect: | ||
| 1003 | * read_ext() == WIIMOTE_EXT_NONE | ||
| 1004 | * state.flags == !MP_ACTIVE && !EXT_ACTIVE && !EXT_PLUGGED | ||
| 1005 | * No need to perform any action in this case as everything is | ||
| 1006 | * disabled already. | ||
| 1007 | * - If MP is plugged/unplugged, our timer detects it | ||
| 1008 | * - If EXT is plugged, EXT_PLUGGED will be set */ | ||
| 1009 | if (!(flags & WIIPROTO_FLAG_MP_USED) && | ||
| 1010 | wdata->state.exttype == WIIMOTE_EXT_NONE) { | ||
| 1011 | type = wiimote_cmd_read_ext(wdata, data); | ||
| 1012 | ret = type == wdata->state.exttype; | ||
| 1013 | |||
| 1014 | spin_lock_irq(&wdata->state.lock); | ||
| 1015 | ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); | ||
| 1016 | ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); | ||
| 1017 | ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED); | ||
| 1018 | spin_unlock_irq(&wdata->state.lock); | ||
| 1019 | |||
| 1020 | if (!ret) | ||
| 1021 | hid_dbg(wdata->hdev, "state left: !EXT && !MP\n"); | ||
| 1022 | |||
| 1023 | /* poll MP for hotplug events */ | ||
| 1024 | poll_mp = true; | ||
| 1025 | |||
| 1026 | goto out_release; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | /* The trickiest part is if both EXT and MP are active. We cannot read | ||
| 1030 | * the EXT ID, anymore, because MP is mapped over it. However, we use | ||
| 1031 | * a handy trick here: | ||
| 1032 | * - EXT_ACTIVE is unset whenever !MP_PLUGGED is sent | ||
| 1033 | * MP_PLUGGED might be re-sent again before we are scheduled, but | ||
| 1034 | * EXT_ACTIVE will stay unset. | ||
| 1035 | * So it is enough to check for mp_mapped() and MP_ACTIVE and | ||
| 1036 | * EXT_ACTIVE. EXT_PLUGGED is a sanity check. */ | ||
| 1037 | if (wdata->state.exttype != WIIMOTE_EXT_NONE && | ||
| 1038 | wdata->state.mp > 0 && (flags & WIIPROTO_FLAG_MP_USED)) { | ||
| 1039 | type = wiimote_cmd_read_mp_mapped(wdata); | ||
| 1040 | ret = type != WIIMOTE_MP_NONE; | ||
| 1041 | ret = ret && type != WIIMOTE_MP_UNKNOWN; | ||
| 1042 | ret = ret && type != WIIMOTE_MP_SINGLE; | ||
| 1043 | |||
| 1044 | spin_lock_irq(&wdata->state.lock); | ||
| 1045 | ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED); | ||
| 1046 | ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); | ||
| 1047 | ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); | ||
| 1048 | spin_unlock_irq(&wdata->state.lock); | ||
| 1049 | |||
| 1050 | if (!ret) | ||
| 1051 | hid_dbg(wdata->hdev, "state left: EXT && MP\n"); | ||
| 1052 | |||
| 1053 | /* while MP is mapped, we get EXT_PLUGGED events */ | ||
| 1054 | poll_mp = false; | ||
| 1055 | |||
| 1056 | goto out_release; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | /* unknown state */ | ||
| 1060 | ret = false; | ||
| 1061 | |||
| 1062 | out_release: | ||
| 1063 | wiimote_cmd_release(wdata); | ||
| 1064 | |||
| 1065 | /* only poll for MP if requested and if state didn't change */ | ||
| 1066 | if (ret && poll_mp && !(flags & WIIPROTO_FLAG_BUILTIN_MP) && | ||
| 1067 | !(flags & WIIPROTO_FLAG_NO_MP)) | ||
| 1068 | wiimote_init_poll_mp(wdata); | ||
| 1069 | |||
| 1070 | return ret; | ||
| 683 | } | 1071 | } |
| 684 | 1072 | ||
| 685 | static void wiimote_ir_close(struct input_dev *dev) | 1073 | static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = { |
| 1074 | [WIIMOTE_EXT_NONE] = "None", | ||
| 1075 | [WIIMOTE_EXT_UNKNOWN] = "Unknown", | ||
| 1076 | [WIIMOTE_EXT_NUNCHUK] = "Nintendo Wii Nunchuk", | ||
| 1077 | [WIIMOTE_EXT_CLASSIC_CONTROLLER] = "Nintendo Wii Classic Controller", | ||
| 1078 | [WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board", | ||
| 1079 | [WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller", | ||
| 1080 | }; | ||
| 1081 | |||
| 1082 | /* | ||
| 1083 | * Handle hotplug events | ||
| 1084 | * If we receive an hotplug event and the device-check failed, we deinitialize | ||
| 1085 | * the extension ports, re-read all extension IDs and set the device into | ||
| 1086 | * the desired state. This involves mapping MP into the main extension | ||
| 1087 | * registers, setting up extension passthrough modes and initializing the | ||
| 1088 | * requested extensions. | ||
| 1089 | */ | ||
| 1090 | static void wiimote_init_hotplug(struct wiimote_data *wdata) | ||
| 686 | { | 1091 | { |
| 687 | struct wiimote_data *wdata = input_get_drvdata(dev); | 1092 | __u8 exttype, extdata[6], mpdata[6]; |
| 1093 | __u32 flags; | ||
| 1094 | bool mp; | ||
| 688 | 1095 | ||
| 689 | wiimote_init_ir(wdata, 0); | 1096 | hid_dbg(wdata->hdev, "detect extensions..\n"); |
| 690 | hid_hw_close(wdata->hdev); | 1097 | |
| 1098 | wiimote_cmd_acquire_noint(wdata); | ||
| 1099 | |||
| 1100 | spin_lock_irq(&wdata->state.lock); | ||
| 1101 | |||
| 1102 | /* get state snapshot that we will then work on */ | ||
| 1103 | flags = wdata->state.flags; | ||
| 1104 | |||
| 1105 | /* disable event forwarding temporarily */ | ||
| 1106 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE; | ||
| 1107 | wdata->state.flags &= ~WIIPROTO_FLAG_MP_ACTIVE; | ||
| 1108 | |||
| 1109 | spin_unlock_irq(&wdata->state.lock); | ||
| 1110 | |||
| 1111 | /* init extension and MP (deactivates current extension or MP) */ | ||
| 1112 | wiimote_cmd_init_ext(wdata); | ||
| 1113 | if (flags & WIIPROTO_FLAG_NO_MP) { | ||
| 1114 | mp = false; | ||
| 1115 | } else { | ||
| 1116 | wiimote_cmd_init_mp(wdata); | ||
| 1117 | mp = wiimote_cmd_read_mp(wdata, mpdata); | ||
| 1118 | } | ||
| 1119 | exttype = wiimote_cmd_read_ext(wdata, extdata); | ||
| 1120 | |||
| 1121 | wiimote_cmd_release(wdata); | ||
| 1122 | |||
| 1123 | /* load/unload extension module if it changed */ | ||
| 1124 | if (exttype != wdata->state.exttype) { | ||
| 1125 | /* unload previous extension */ | ||
| 1126 | wiimote_ext_unload(wdata); | ||
| 1127 | |||
| 1128 | if (exttype == WIIMOTE_EXT_UNKNOWN) { | ||
| 1129 | hid_info(wdata->hdev, "cannot detect extension; %02x:%02x %02x:%02x %02x:%02x\n", | ||
| 1130 | extdata[0], extdata[1], extdata[2], | ||
| 1131 | extdata[3], extdata[4], extdata[5]); | ||
| 1132 | } else if (exttype == WIIMOTE_EXT_NONE) { | ||
| 1133 | spin_lock_irq(&wdata->state.lock); | ||
| 1134 | wdata->state.exttype = WIIMOTE_EXT_NONE; | ||
| 1135 | spin_unlock_irq(&wdata->state.lock); | ||
| 1136 | } else { | ||
| 1137 | hid_info(wdata->hdev, "detected extension: %s\n", | ||
| 1138 | wiimote_exttype_names[exttype]); | ||
| 1139 | /* try loading new extension */ | ||
| 1140 | wiimote_ext_load(wdata, exttype); | ||
| 1141 | } | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | /* load/unload MP module if it changed */ | ||
| 1145 | if (mp) { | ||
| 1146 | if (!wdata->state.mp) { | ||
| 1147 | hid_info(wdata->hdev, "detected extension: Nintendo Wii Motion Plus\n"); | ||
| 1148 | wiimote_mp_load(wdata); | ||
| 1149 | } | ||
| 1150 | } else if (wdata->state.mp) { | ||
| 1151 | wiimote_mp_unload(wdata); | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | /* if MP is not used, do not map or activate it */ | ||
| 1155 | if (!(flags & WIIPROTO_FLAG_MP_USED)) | ||
| 1156 | mp = false; | ||
| 1157 | |||
| 1158 | /* map MP into main extension registers if used */ | ||
| 1159 | if (mp) { | ||
| 1160 | wiimote_cmd_acquire_noint(wdata); | ||
| 1161 | wiimote_cmd_map_mp(wdata, exttype); | ||
| 1162 | wiimote_cmd_release(wdata); | ||
| 1163 | |||
| 1164 | /* delete MP hotplug timer */ | ||
| 1165 | del_timer_sync(&wdata->timer); | ||
| 1166 | } else { | ||
| 1167 | /* reschedule MP hotplug timer */ | ||
| 1168 | if (!(flags & WIIPROTO_FLAG_BUILTIN_MP) && | ||
| 1169 | !(flags & WIIPROTO_FLAG_NO_MP)) | ||
| 1170 | mod_timer(&wdata->timer, jiffies + HZ * 4); | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | spin_lock_irq(&wdata->state.lock); | ||
| 1174 | |||
| 1175 | /* enable data forwarding again and set expected hotplug state */ | ||
| 1176 | if (mp) { | ||
| 1177 | wdata->state.flags |= WIIPROTO_FLAG_MP_ACTIVE; | ||
| 1178 | if (wdata->state.exttype == WIIMOTE_EXT_NONE) { | ||
| 1179 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED; | ||
| 1180 | wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED; | ||
| 1181 | } else { | ||
| 1182 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED; | ||
| 1183 | wdata->state.flags |= WIIPROTO_FLAG_MP_PLUGGED; | ||
| 1184 | wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE; | ||
| 1185 | } | ||
| 1186 | } else if (wdata->state.exttype != WIIMOTE_EXT_NONE) { | ||
| 1187 | wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | /* request status report for hotplug state updates */ | ||
| 1191 | wiiproto_req_status(wdata); | ||
| 1192 | |||
| 1193 | spin_unlock_irq(&wdata->state.lock); | ||
| 1194 | |||
| 1195 | hid_dbg(wdata->hdev, "detected extensions: MP: %d EXT: %d\n", | ||
| 1196 | wdata->state.mp, wdata->state.exttype); | ||
| 691 | } | 1197 | } |
| 692 | 1198 | ||
| 693 | static void handler_keys(struct wiimote_data *wdata, const __u8 *payload) | 1199 | static void wiimote_init_worker(struct work_struct *work) |
| 1200 | { | ||
| 1201 | struct wiimote_data *wdata = container_of(work, struct wiimote_data, | ||
| 1202 | init_worker); | ||
| 1203 | bool changed = false; | ||
| 1204 | |||
| 1205 | if (wdata->state.devtype == WIIMOTE_DEV_PENDING) { | ||
| 1206 | wiimote_init_detect(wdata); | ||
| 1207 | changed = true; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | if (changed || !wiimote_init_check(wdata)) | ||
| 1211 | wiimote_init_hotplug(wdata); | ||
| 1212 | |||
| 1213 | if (changed) | ||
| 1214 | kobject_uevent(&wdata->hdev->dev.kobj, KOBJ_CHANGE); | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | void __wiimote_schedule(struct wiimote_data *wdata) | ||
| 694 | { | 1218 | { |
| 695 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_LEFT], | 1219 | if (!(wdata->state.flags & WIIPROTO_FLAG_EXITING)) |
| 696 | !!(payload[0] & 0x01)); | 1220 | schedule_work(&wdata->init_worker); |
| 697 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_RIGHT], | ||
| 698 | !!(payload[0] & 0x02)); | ||
| 699 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_DOWN], | ||
| 700 | !!(payload[0] & 0x04)); | ||
| 701 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_UP], | ||
| 702 | !!(payload[0] & 0x08)); | ||
| 703 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_PLUS], | ||
| 704 | !!(payload[0] & 0x10)); | ||
| 705 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_TWO], | ||
| 706 | !!(payload[1] & 0x01)); | ||
| 707 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_ONE], | ||
| 708 | !!(payload[1] & 0x02)); | ||
| 709 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_B], | ||
| 710 | !!(payload[1] & 0x04)); | ||
| 711 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_A], | ||
| 712 | !!(payload[1] & 0x08)); | ||
| 713 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_MINUS], | ||
| 714 | !!(payload[1] & 0x10)); | ||
| 715 | input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_HOME], | ||
| 716 | !!(payload[1] & 0x80)); | ||
| 717 | input_sync(wdata->input); | ||
| 718 | } | 1221 | } |
| 719 | 1222 | ||
| 720 | static void handler_accel(struct wiimote_data *wdata, const __u8 *payload) | 1223 | static void wiimote_schedule(struct wiimote_data *wdata) |
| 721 | { | 1224 | { |
| 722 | __u16 x, y, z; | 1225 | unsigned long flags; |
| 723 | 1226 | ||
| 724 | if (!(wdata->state.flags & WIIPROTO_FLAG_ACCEL)) | 1227 | spin_lock_irqsave(&wdata->state.lock, flags); |
| 725 | return; | 1228 | __wiimote_schedule(wdata); |
| 1229 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1230 | } | ||
| 726 | 1231 | ||
| 727 | /* | 1232 | static void wiimote_init_timeout(unsigned long arg) |
| 728 | * payload is: BB BB XX YY ZZ | 1233 | { |
| 729 | * Accelerometer data is encoded into 3 10bit values. XX, YY and ZZ | 1234 | struct wiimote_data *wdata = (void*)arg; |
| 730 | * contain the upper 8 bits of each value. The lower 2 bits are | ||
| 731 | * contained in the buttons data BB BB. | ||
| 732 | * Bits 6 and 7 of the first buttons byte BB is the lower 2 bits of the | ||
| 733 | * X accel value. Bit 5 of the second buttons byte is the 2nd bit of Y | ||
| 734 | * accel value and bit 6 is the second bit of the Z value. | ||
| 735 | * The first bit of Y and Z values is not available and always set to 0. | ||
| 736 | * 0x200 is returned on no movement. | ||
| 737 | */ | ||
| 738 | 1235 | ||
| 739 | x = payload[2] << 2; | 1236 | wiimote_schedule(wdata); |
| 740 | y = payload[3] << 2; | 1237 | } |
| 741 | z = payload[4] << 2; | 1238 | |
| 1239 | /* protocol handlers */ | ||
| 1240 | |||
| 1241 | static void handler_keys(struct wiimote_data *wdata, const __u8 *payload) | ||
| 1242 | { | ||
| 1243 | const __u8 *iter, *mods; | ||
| 1244 | const struct wiimod_ops *ops; | ||
| 742 | 1245 | ||
| 743 | x |= (payload[0] >> 5) & 0x3; | 1246 | ops = wiimod_ext_table[wdata->state.exttype]; |
| 744 | y |= (payload[1] >> 4) & 0x2; | 1247 | if (ops->in_keys) { |
| 745 | z |= (payload[1] >> 5) & 0x2; | 1248 | ops->in_keys(wdata, payload); |
| 1249 | return; | ||
| 1250 | } | ||
| 746 | 1251 | ||
| 747 | input_report_abs(wdata->accel, ABS_RX, x - 0x200); | 1252 | mods = wiimote_devtype_mods[wdata->state.devtype]; |
| 748 | input_report_abs(wdata->accel, ABS_RY, y - 0x200); | 1253 | for (iter = mods; *iter != WIIMOD_NULL; ++iter) { |
| 749 | input_report_abs(wdata->accel, ABS_RZ, z - 0x200); | 1254 | ops = wiimod_table[*iter]; |
| 750 | input_sync(wdata->accel); | 1255 | if (ops->in_keys) { |
| 1256 | ops->in_keys(wdata, payload); | ||
| 1257 | break; | ||
| 1258 | } | ||
| 1259 | } | ||
| 751 | } | 1260 | } |
| 752 | 1261 | ||
| 753 | #define ir_to_input0(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \ | 1262 | static void handler_accel(struct wiimote_data *wdata, const __u8 *payload) |
| 754 | ABS_HAT0X, ABS_HAT0Y) | 1263 | { |
| 755 | #define ir_to_input1(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \ | 1264 | const __u8 *iter, *mods; |
| 756 | ABS_HAT1X, ABS_HAT1Y) | 1265 | const struct wiimod_ops *ops; |
| 757 | #define ir_to_input2(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \ | 1266 | |
| 758 | ABS_HAT2X, ABS_HAT2Y) | 1267 | ops = wiimod_ext_table[wdata->state.exttype]; |
| 759 | #define ir_to_input3(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \ | 1268 | if (ops->in_accel) { |
| 760 | ABS_HAT3X, ABS_HAT3Y) | 1269 | ops->in_accel(wdata, payload); |
| 1270 | return; | ||
| 1271 | } | ||
| 761 | 1272 | ||
| 762 | static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir, | 1273 | mods = wiimote_devtype_mods[wdata->state.devtype]; |
| 763 | bool packed, __u8 xid, __u8 yid) | 1274 | for (iter = mods; *iter != WIIMOD_NULL; ++iter) { |
| 1275 | ops = wiimod_table[*iter]; | ||
| 1276 | if (ops->in_accel) { | ||
| 1277 | ops->in_accel(wdata, payload); | ||
| 1278 | break; | ||
| 1279 | } | ||
| 1280 | } | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | static bool valid_ext_handler(const struct wiimod_ops *ops, size_t len) | ||
| 764 | { | 1284 | { |
| 765 | __u16 x, y; | 1285 | if (!ops->in_ext) |
| 1286 | return false; | ||
| 1287 | if ((ops->flags & WIIMOD_FLAG_EXT8) && len < 8) | ||
| 1288 | return false; | ||
| 1289 | if ((ops->flags & WIIMOD_FLAG_EXT16) && len < 16) | ||
| 1290 | return false; | ||
| 1291 | |||
| 1292 | return true; | ||
| 1293 | } | ||
| 766 | 1294 | ||
| 767 | if (!(wdata->state.flags & WIIPROTO_FLAGS_IR)) | 1295 | static void handler_ext(struct wiimote_data *wdata, const __u8 *payload, |
| 1296 | size_t len) | ||
| 1297 | { | ||
| 1298 | static const __u8 invalid[21] = { 0xff, 0xff, 0xff, 0xff, | ||
| 1299 | 0xff, 0xff, 0xff, 0xff, | ||
| 1300 | 0xff, 0xff, 0xff, 0xff, | ||
| 1301 | 0xff, 0xff, 0xff, 0xff, | ||
| 1302 | 0xff, 0xff, 0xff, 0xff, | ||
| 1303 | 0xff }; | ||
| 1304 | const __u8 *iter, *mods; | ||
| 1305 | const struct wiimod_ops *ops; | ||
| 1306 | bool is_mp; | ||
| 1307 | |||
| 1308 | if (len > 21) | ||
| 1309 | len = 21; | ||
| 1310 | if (len < 6 || !memcmp(payload, invalid, len)) | ||
| 768 | return; | 1311 | return; |
| 769 | 1312 | ||
| 770 | /* | 1313 | /* if MP is active, track MP slot hotplugging */ |
| 771 | * Basic IR data is encoded into 3 bytes. The first two bytes are the | 1314 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { |
| 772 | * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits | 1315 | /* this bit is set for invalid events (eg. during hotplug) */ |
| 773 | * of both. | 1316 | if (payload[5] & 0x01) |
| 774 | * If data is packed, then the 3rd byte is put first and slightly | 1317 | return; |
| 775 | * reordered. This allows to interleave packed and non-packed data to | 1318 | |
| 776 | * have two IR sets in 5 bytes instead of 6. | 1319 | if (payload[4] & 0x01) { |
| 777 | * The resulting 10bit X/Y values are passed to the ABS_HATXY input dev. | 1320 | if (!(wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED)) { |
| 778 | */ | 1321 | hid_dbg(wdata->hdev, "MP hotplug: 1\n"); |
| 1322 | wdata->state.flags |= WIIPROTO_FLAG_MP_PLUGGED; | ||
| 1323 | __wiimote_schedule(wdata); | ||
| 1324 | } | ||
| 1325 | } else { | ||
| 1326 | if (wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED) { | ||
| 1327 | hid_dbg(wdata->hdev, "MP hotplug: 0\n"); | ||
| 1328 | wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED; | ||
| 1329 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE; | ||
| 1330 | __wiimote_schedule(wdata); | ||
| 1331 | } | ||
| 1332 | } | ||
| 779 | 1333 | ||
| 780 | if (packed) { | 1334 | /* detect MP data that is sent interleaved with EXT data */ |
| 781 | x = ir[1] | ((ir[0] & 0x03) << 8); | 1335 | is_mp = payload[5] & 0x02; |
| 782 | y = ir[2] | ((ir[0] & 0x0c) << 6); | ||
| 783 | } else { | 1336 | } else { |
| 784 | x = ir[0] | ((ir[2] & 0x30) << 4); | 1337 | is_mp = false; |
| 785 | y = ir[1] | ((ir[2] & 0xc0) << 2); | 1338 | } |
| 1339 | |||
| 1340 | /* ignore EXT events if no extension is active */ | ||
| 1341 | if (!(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE) && !is_mp) | ||
| 1342 | return; | ||
| 1343 | |||
| 1344 | /* try forwarding to extension handler, first */ | ||
| 1345 | ops = wiimod_ext_table[wdata->state.exttype]; | ||
| 1346 | if (is_mp && ops->in_mp) { | ||
| 1347 | ops->in_mp(wdata, payload); | ||
| 1348 | return; | ||
| 1349 | } else if (!is_mp && valid_ext_handler(ops, len)) { | ||
| 1350 | ops->in_ext(wdata, payload); | ||
| 1351 | return; | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | /* try forwarding to MP handler */ | ||
| 1355 | ops = &wiimod_mp; | ||
| 1356 | if (is_mp && ops->in_mp) { | ||
| 1357 | ops->in_mp(wdata, payload); | ||
| 1358 | return; | ||
| 1359 | } else if (!is_mp && valid_ext_handler(ops, len)) { | ||
| 1360 | ops->in_ext(wdata, payload); | ||
| 1361 | return; | ||
| 786 | } | 1362 | } |
| 787 | 1363 | ||
| 788 | input_report_abs(wdata->ir, xid, x); | 1364 | /* try forwarding to loaded modules */ |
| 789 | input_report_abs(wdata->ir, yid, y); | 1365 | mods = wiimote_devtype_mods[wdata->state.devtype]; |
| 1366 | for (iter = mods; *iter != WIIMOD_NULL; ++iter) { | ||
| 1367 | ops = wiimod_table[*iter]; | ||
| 1368 | if (is_mp && ops->in_mp) { | ||
| 1369 | ops->in_mp(wdata, payload); | ||
| 1370 | return; | ||
| 1371 | } else if (!is_mp && valid_ext_handler(ops, len)) { | ||
| 1372 | ops->in_ext(wdata, payload); | ||
| 1373 | return; | ||
| 1374 | } | ||
| 1375 | } | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | #define ir_to_input0(wdata, ir, packed) handler_ir((wdata), (ir), (packed), 0) | ||
| 1379 | #define ir_to_input1(wdata, ir, packed) handler_ir((wdata), (ir), (packed), 1) | ||
| 1380 | #define ir_to_input2(wdata, ir, packed) handler_ir((wdata), (ir), (packed), 2) | ||
| 1381 | #define ir_to_input3(wdata, ir, packed) handler_ir((wdata), (ir), (packed), 3) | ||
| 1382 | |||
| 1383 | static void handler_ir(struct wiimote_data *wdata, const __u8 *payload, | ||
| 1384 | bool packed, unsigned int id) | ||
| 1385 | { | ||
| 1386 | const __u8 *iter, *mods; | ||
| 1387 | const struct wiimod_ops *ops; | ||
| 1388 | |||
| 1389 | ops = wiimod_ext_table[wdata->state.exttype]; | ||
| 1390 | if (ops->in_ir) { | ||
| 1391 | ops->in_ir(wdata, payload, packed, id); | ||
| 1392 | return; | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | mods = wiimote_devtype_mods[wdata->state.devtype]; | ||
| 1396 | for (iter = mods; *iter != WIIMOD_NULL; ++iter) { | ||
| 1397 | ops = wiimod_table[*iter]; | ||
| 1398 | if (ops->in_ir) { | ||
| 1399 | ops->in_ir(wdata, payload, packed, id); | ||
| 1400 | break; | ||
| 1401 | } | ||
| 1402 | } | ||
| 790 | } | 1403 | } |
| 791 | 1404 | ||
| 792 | /* reduced status report with "BB BB" key data only */ | 1405 | /* reduced status report with "BB BB" key data only */ |
| @@ -804,12 +1417,27 @@ static void handler_status(struct wiimote_data *wdata, const __u8 *payload) | |||
| 804 | { | 1417 | { |
| 805 | handler_status_K(wdata, payload); | 1418 | handler_status_K(wdata, payload); |
| 806 | 1419 | ||
| 807 | wiiext_event(wdata, payload[2] & 0x02); | 1420 | /* update extension status */ |
| 1421 | if (payload[2] & 0x02) { | ||
| 1422 | if (!(wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED)) { | ||
| 1423 | hid_dbg(wdata->hdev, "EXT hotplug: 1\n"); | ||
| 1424 | wdata->state.flags |= WIIPROTO_FLAG_EXT_PLUGGED; | ||
| 1425 | __wiimote_schedule(wdata); | ||
| 1426 | } | ||
| 1427 | } else { | ||
| 1428 | if (wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED) { | ||
| 1429 | hid_dbg(wdata->hdev, "EXT hotplug: 0\n"); | ||
| 1430 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED; | ||
| 1431 | wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED; | ||
| 1432 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE; | ||
| 1433 | wdata->state.flags &= ~WIIPROTO_FLAG_MP_ACTIVE; | ||
| 1434 | __wiimote_schedule(wdata); | ||
| 1435 | } | ||
| 1436 | } | ||
| 808 | 1437 | ||
| 809 | if (wiimote_cmd_pending(wdata, WIIPROTO_REQ_SREQ, 0)) { | 1438 | wdata->state.cmd_battery = payload[5]; |
| 810 | wdata->state.cmd_battery = payload[5]; | 1439 | if (wiimote_cmd_pending(wdata, WIIPROTO_REQ_SREQ, 0)) |
| 811 | wiimote_cmd_complete(wdata); | 1440 | wiimote_cmd_complete(wdata); |
| 812 | } | ||
| 813 | } | 1441 | } |
| 814 | 1442 | ||
| 815 | /* reduced generic report with "BB BB" key data only */ | 1443 | /* reduced generic report with "BB BB" key data only */ |
| @@ -864,7 +1492,7 @@ static void handler_drm_KA(struct wiimote_data *wdata, const __u8 *payload) | |||
| 864 | static void handler_drm_KE(struct wiimote_data *wdata, const __u8 *payload) | 1492 | static void handler_drm_KE(struct wiimote_data *wdata, const __u8 *payload) |
| 865 | { | 1493 | { |
| 866 | handler_keys(wdata, payload); | 1494 | handler_keys(wdata, payload); |
| 867 | wiiext_handle(wdata, &payload[2]); | 1495 | handler_ext(wdata, &payload[2], 8); |
| 868 | } | 1496 | } |
| 869 | 1497 | ||
| 870 | static void handler_drm_KAI(struct wiimote_data *wdata, const __u8 *payload) | 1498 | static void handler_drm_KAI(struct wiimote_data *wdata, const __u8 *payload) |
| @@ -875,13 +1503,12 @@ static void handler_drm_KAI(struct wiimote_data *wdata, const __u8 *payload) | |||
| 875 | ir_to_input1(wdata, &payload[8], false); | 1503 | ir_to_input1(wdata, &payload[8], false); |
| 876 | ir_to_input2(wdata, &payload[11], false); | 1504 | ir_to_input2(wdata, &payload[11], false); |
| 877 | ir_to_input3(wdata, &payload[14], false); | 1505 | ir_to_input3(wdata, &payload[14], false); |
| 878 | input_sync(wdata->ir); | ||
| 879 | } | 1506 | } |
| 880 | 1507 | ||
| 881 | static void handler_drm_KEE(struct wiimote_data *wdata, const __u8 *payload) | 1508 | static void handler_drm_KEE(struct wiimote_data *wdata, const __u8 *payload) |
| 882 | { | 1509 | { |
| 883 | handler_keys(wdata, payload); | 1510 | handler_keys(wdata, payload); |
| 884 | wiiext_handle(wdata, &payload[2]); | 1511 | handler_ext(wdata, &payload[2], 19); |
| 885 | } | 1512 | } |
| 886 | 1513 | ||
| 887 | static void handler_drm_KIE(struct wiimote_data *wdata, const __u8 *payload) | 1514 | static void handler_drm_KIE(struct wiimote_data *wdata, const __u8 *payload) |
| @@ -891,15 +1518,14 @@ static void handler_drm_KIE(struct wiimote_data *wdata, const __u8 *payload) | |||
| 891 | ir_to_input1(wdata, &payload[4], true); | 1518 | ir_to_input1(wdata, &payload[4], true); |
| 892 | ir_to_input2(wdata, &payload[7], false); | 1519 | ir_to_input2(wdata, &payload[7], false); |
| 893 | ir_to_input3(wdata, &payload[9], true); | 1520 | ir_to_input3(wdata, &payload[9], true); |
| 894 | input_sync(wdata->ir); | 1521 | handler_ext(wdata, &payload[12], 9); |
| 895 | wiiext_handle(wdata, &payload[12]); | ||
| 896 | } | 1522 | } |
| 897 | 1523 | ||
| 898 | static void handler_drm_KAE(struct wiimote_data *wdata, const __u8 *payload) | 1524 | static void handler_drm_KAE(struct wiimote_data *wdata, const __u8 *payload) |
| 899 | { | 1525 | { |
| 900 | handler_keys(wdata, payload); | 1526 | handler_keys(wdata, payload); |
| 901 | handler_accel(wdata, payload); | 1527 | handler_accel(wdata, payload); |
| 902 | wiiext_handle(wdata, &payload[5]); | 1528 | handler_ext(wdata, &payload[5], 16); |
| 903 | } | 1529 | } |
| 904 | 1530 | ||
| 905 | static void handler_drm_KAIE(struct wiimote_data *wdata, const __u8 *payload) | 1531 | static void handler_drm_KAIE(struct wiimote_data *wdata, const __u8 *payload) |
| @@ -910,13 +1536,12 @@ static void handler_drm_KAIE(struct wiimote_data *wdata, const __u8 *payload) | |||
| 910 | ir_to_input1(wdata, &payload[7], true); | 1536 | ir_to_input1(wdata, &payload[7], true); |
| 911 | ir_to_input2(wdata, &payload[10], false); | 1537 | ir_to_input2(wdata, &payload[10], false); |
| 912 | ir_to_input3(wdata, &payload[12], true); | 1538 | ir_to_input3(wdata, &payload[12], true); |
| 913 | input_sync(wdata->ir); | 1539 | handler_ext(wdata, &payload[15], 6); |
| 914 | wiiext_handle(wdata, &payload[15]); | ||
| 915 | } | 1540 | } |
| 916 | 1541 | ||
| 917 | static void handler_drm_E(struct wiimote_data *wdata, const __u8 *payload) | 1542 | static void handler_drm_E(struct wiimote_data *wdata, const __u8 *payload) |
| 918 | { | 1543 | { |
| 919 | wiiext_handle(wdata, payload); | 1544 | handler_ext(wdata, payload, 21); |
| 920 | } | 1545 | } |
| 921 | 1546 | ||
| 922 | static void handler_drm_SKAI1(struct wiimote_data *wdata, const __u8 *payload) | 1547 | static void handler_drm_SKAI1(struct wiimote_data *wdata, const __u8 *payload) |
| @@ -929,7 +1554,6 @@ static void handler_drm_SKAI1(struct wiimote_data *wdata, const __u8 *payload) | |||
| 929 | 1554 | ||
| 930 | ir_to_input0(wdata, &payload[3], false); | 1555 | ir_to_input0(wdata, &payload[3], false); |
| 931 | ir_to_input1(wdata, &payload[12], false); | 1556 | ir_to_input1(wdata, &payload[12], false); |
| 932 | input_sync(wdata->ir); | ||
| 933 | } | 1557 | } |
| 934 | 1558 | ||
| 935 | static void handler_drm_SKAI2(struct wiimote_data *wdata, const __u8 *payload) | 1559 | static void handler_drm_SKAI2(struct wiimote_data *wdata, const __u8 *payload) |
| @@ -950,7 +1574,6 @@ static void handler_drm_SKAI2(struct wiimote_data *wdata, const __u8 *payload) | |||
| 950 | 1574 | ||
| 951 | ir_to_input2(wdata, &payload[3], false); | 1575 | ir_to_input2(wdata, &payload[3], false); |
| 952 | ir_to_input3(wdata, &payload[12], false); | 1576 | ir_to_input3(wdata, &payload[12], false); |
| 953 | input_sync(wdata->ir); | ||
| 954 | } | 1577 | } |
| 955 | 1578 | ||
| 956 | struct wiiproto_handler { | 1579 | struct wiiproto_handler { |
| @@ -1017,177 +1640,136 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, | |||
| 1017 | return 0; | 1640 | return 0; |
| 1018 | } | 1641 | } |
| 1019 | 1642 | ||
| 1020 | static void wiimote_leds_destroy(struct wiimote_data *wdata) | 1643 | static ssize_t wiimote_ext_show(struct device *dev, |
| 1644 | struct device_attribute *attr, | ||
| 1645 | char *buf) | ||
| 1021 | { | 1646 | { |
| 1022 | int i; | 1647 | struct wiimote_data *wdata = dev_to_wii(dev); |
| 1023 | struct led_classdev *led; | 1648 | __u8 type; |
| 1024 | 1649 | unsigned long flags; | |
| 1025 | for (i = 0; i < 4; ++i) { | 1650 | |
| 1026 | if (wdata->leds[i]) { | 1651 | spin_lock_irqsave(&wdata->state.lock, flags); |
| 1027 | led = wdata->leds[i]; | 1652 | type = wdata->state.exttype; |
| 1028 | wdata->leds[i] = NULL; | 1653 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
| 1029 | led_classdev_unregister(led); | 1654 | |
| 1030 | kfree(led); | 1655 | switch (type) { |
| 1031 | } | 1656 | case WIIMOTE_EXT_NONE: |
| 1657 | return sprintf(buf, "none\n"); | ||
| 1658 | case WIIMOTE_EXT_NUNCHUK: | ||
| 1659 | return sprintf(buf, "nunchuk\n"); | ||
| 1660 | case WIIMOTE_EXT_CLASSIC_CONTROLLER: | ||
| 1661 | return sprintf(buf, "classic\n"); | ||
| 1662 | case WIIMOTE_EXT_BALANCE_BOARD: | ||
| 1663 | return sprintf(buf, "balanceboard\n"); | ||
| 1664 | case WIIMOTE_EXT_PRO_CONTROLLER: | ||
| 1665 | return sprintf(buf, "procontroller\n"); | ||
| 1666 | case WIIMOTE_EXT_UNKNOWN: | ||
| 1667 | /* fallthrough */ | ||
| 1668 | default: | ||
| 1669 | return sprintf(buf, "unknown\n"); | ||
| 1032 | } | 1670 | } |
| 1033 | } | 1671 | } |
| 1034 | 1672 | ||
| 1035 | static int wiimote_leds_create(struct wiimote_data *wdata) | 1673 | static ssize_t wiimote_ext_store(struct device *dev, |
| 1674 | struct device_attribute *attr, | ||
| 1675 | const char *buf, size_t count) | ||
| 1036 | { | 1676 | { |
| 1037 | int i, ret; | 1677 | struct wiimote_data *wdata = dev_to_wii(dev); |
| 1038 | struct device *dev = &wdata->hdev->dev; | ||
| 1039 | size_t namesz = strlen(dev_name(dev)) + 9; | ||
| 1040 | struct led_classdev *led; | ||
| 1041 | char *name; | ||
| 1042 | 1678 | ||
| 1043 | for (i = 0; i < 4; ++i) { | 1679 | if (!strcmp(buf, "scan")) { |
| 1044 | led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL); | 1680 | wiimote_schedule(wdata); |
| 1045 | if (!led) { | 1681 | } else { |
| 1046 | ret = -ENOMEM; | 1682 | return -EINVAL; |
| 1047 | goto err; | ||
| 1048 | } | ||
| 1049 | name = (void*)&led[1]; | ||
| 1050 | snprintf(name, namesz, "%s:blue:p%d", dev_name(dev), i); | ||
| 1051 | led->name = name; | ||
| 1052 | led->brightness = 0; | ||
| 1053 | led->max_brightness = 1; | ||
| 1054 | led->brightness_get = wiimote_leds_get; | ||
| 1055 | led->brightness_set = wiimote_leds_set; | ||
| 1056 | |||
| 1057 | ret = led_classdev_register(dev, led); | ||
| 1058 | if (ret) { | ||
| 1059 | kfree(led); | ||
| 1060 | goto err; | ||
| 1061 | } | ||
| 1062 | wdata->leds[i] = led; | ||
| 1063 | } | 1683 | } |
| 1064 | 1684 | ||
| 1065 | return 0; | 1685 | return strnlen(buf, PAGE_SIZE); |
| 1686 | } | ||
| 1066 | 1687 | ||
| 1067 | err: | 1688 | static DEVICE_ATTR(extension, S_IRUGO | S_IWUSR | S_IWGRP, wiimote_ext_show, |
| 1068 | wiimote_leds_destroy(wdata); | 1689 | wiimote_ext_store); |
| 1069 | return ret; | 1690 | |
| 1691 | static ssize_t wiimote_dev_show(struct device *dev, | ||
| 1692 | struct device_attribute *attr, | ||
| 1693 | char *buf) | ||
| 1694 | { | ||
| 1695 | struct wiimote_data *wdata = dev_to_wii(dev); | ||
| 1696 | __u8 type; | ||
| 1697 | unsigned long flags; | ||
| 1698 | |||
| 1699 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1700 | type = wdata->state.devtype; | ||
| 1701 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1702 | |||
| 1703 | switch (type) { | ||
| 1704 | case WIIMOTE_DEV_GENERIC: | ||
| 1705 | return sprintf(buf, "generic\n"); | ||
| 1706 | case WIIMOTE_DEV_GEN10: | ||
| 1707 | return sprintf(buf, "gen10\n"); | ||
| 1708 | case WIIMOTE_DEV_GEN20: | ||
| 1709 | return sprintf(buf, "gen20\n"); | ||
| 1710 | case WIIMOTE_DEV_BALANCE_BOARD: | ||
| 1711 | return sprintf(buf, "balanceboard\n"); | ||
| 1712 | case WIIMOTE_DEV_PRO_CONTROLLER: | ||
| 1713 | return sprintf(buf, "procontroller\n"); | ||
| 1714 | case WIIMOTE_DEV_PENDING: | ||
| 1715 | return sprintf(buf, "pending\n"); | ||
| 1716 | case WIIMOTE_DEV_UNKNOWN: | ||
| 1717 | /* fallthrough */ | ||
| 1718 | default: | ||
| 1719 | return sprintf(buf, "unknown\n"); | ||
| 1720 | } | ||
| 1070 | } | 1721 | } |
| 1071 | 1722 | ||
| 1723 | static DEVICE_ATTR(devtype, S_IRUGO, wiimote_dev_show, NULL); | ||
| 1724 | |||
| 1072 | static struct wiimote_data *wiimote_create(struct hid_device *hdev) | 1725 | static struct wiimote_data *wiimote_create(struct hid_device *hdev) |
| 1073 | { | 1726 | { |
| 1074 | struct wiimote_data *wdata; | 1727 | struct wiimote_data *wdata; |
| 1075 | int i; | ||
| 1076 | 1728 | ||
| 1077 | wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); | 1729 | wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); |
| 1078 | if (!wdata) | 1730 | if (!wdata) |
| 1079 | return NULL; | 1731 | return NULL; |
| 1080 | 1732 | ||
| 1081 | wdata->input = input_allocate_device(); | ||
| 1082 | if (!wdata->input) | ||
| 1083 | goto err; | ||
| 1084 | |||
| 1085 | wdata->hdev = hdev; | 1733 | wdata->hdev = hdev; |
| 1086 | hid_set_drvdata(hdev, wdata); | 1734 | hid_set_drvdata(hdev, wdata); |
| 1087 | 1735 | ||
| 1088 | input_set_drvdata(wdata->input, wdata); | 1736 | spin_lock_init(&wdata->queue.lock); |
| 1089 | wdata->input->open = wiimote_input_open; | 1737 | INIT_WORK(&wdata->queue.worker, wiimote_queue_worker); |
| 1090 | wdata->input->close = wiimote_input_close; | ||
| 1091 | wdata->input->dev.parent = &wdata->hdev->dev; | ||
| 1092 | wdata->input->id.bustype = wdata->hdev->bus; | ||
| 1093 | wdata->input->id.vendor = wdata->hdev->vendor; | ||
| 1094 | wdata->input->id.product = wdata->hdev->product; | ||
| 1095 | wdata->input->id.version = wdata->hdev->version; | ||
| 1096 | wdata->input->name = WIIMOTE_NAME; | ||
| 1097 | |||
| 1098 | set_bit(EV_KEY, wdata->input->evbit); | ||
| 1099 | for (i = 0; i < WIIPROTO_KEY_COUNT; ++i) | ||
| 1100 | set_bit(wiiproto_keymap[i], wdata->input->keybit); | ||
| 1101 | |||
| 1102 | set_bit(FF_RUMBLE, wdata->input->ffbit); | ||
| 1103 | if (input_ff_create_memless(wdata->input, NULL, wiimote_ff_play)) | ||
| 1104 | goto err_input; | ||
| 1105 | |||
| 1106 | wdata->accel = input_allocate_device(); | ||
| 1107 | if (!wdata->accel) | ||
| 1108 | goto err_input; | ||
| 1109 | |||
| 1110 | input_set_drvdata(wdata->accel, wdata); | ||
| 1111 | wdata->accel->open = wiimote_accel_open; | ||
| 1112 | wdata->accel->close = wiimote_accel_close; | ||
| 1113 | wdata->accel->dev.parent = &wdata->hdev->dev; | ||
| 1114 | wdata->accel->id.bustype = wdata->hdev->bus; | ||
| 1115 | wdata->accel->id.vendor = wdata->hdev->vendor; | ||
| 1116 | wdata->accel->id.product = wdata->hdev->product; | ||
| 1117 | wdata->accel->id.version = wdata->hdev->version; | ||
| 1118 | wdata->accel->name = WIIMOTE_NAME " Accelerometer"; | ||
| 1119 | |||
| 1120 | set_bit(EV_ABS, wdata->accel->evbit); | ||
| 1121 | set_bit(ABS_RX, wdata->accel->absbit); | ||
| 1122 | set_bit(ABS_RY, wdata->accel->absbit); | ||
| 1123 | set_bit(ABS_RZ, wdata->accel->absbit); | ||
| 1124 | input_set_abs_params(wdata->accel, ABS_RX, -500, 500, 2, 4); | ||
| 1125 | input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4); | ||
| 1126 | input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4); | ||
| 1127 | |||
| 1128 | wdata->ir = input_allocate_device(); | ||
| 1129 | if (!wdata->ir) | ||
| 1130 | goto err_ir; | ||
| 1131 | |||
| 1132 | input_set_drvdata(wdata->ir, wdata); | ||
| 1133 | wdata->ir->open = wiimote_ir_open; | ||
| 1134 | wdata->ir->close = wiimote_ir_close; | ||
| 1135 | wdata->ir->dev.parent = &wdata->hdev->dev; | ||
| 1136 | wdata->ir->id.bustype = wdata->hdev->bus; | ||
| 1137 | wdata->ir->id.vendor = wdata->hdev->vendor; | ||
| 1138 | wdata->ir->id.product = wdata->hdev->product; | ||
| 1139 | wdata->ir->id.version = wdata->hdev->version; | ||
| 1140 | wdata->ir->name = WIIMOTE_NAME " IR"; | ||
| 1141 | |||
| 1142 | set_bit(EV_ABS, wdata->ir->evbit); | ||
| 1143 | set_bit(ABS_HAT0X, wdata->ir->absbit); | ||
| 1144 | set_bit(ABS_HAT0Y, wdata->ir->absbit); | ||
| 1145 | set_bit(ABS_HAT1X, wdata->ir->absbit); | ||
| 1146 | set_bit(ABS_HAT1Y, wdata->ir->absbit); | ||
| 1147 | set_bit(ABS_HAT2X, wdata->ir->absbit); | ||
| 1148 | set_bit(ABS_HAT2Y, wdata->ir->absbit); | ||
| 1149 | set_bit(ABS_HAT3X, wdata->ir->absbit); | ||
| 1150 | set_bit(ABS_HAT3Y, wdata->ir->absbit); | ||
| 1151 | input_set_abs_params(wdata->ir, ABS_HAT0X, 0, 1023, 2, 4); | ||
| 1152 | input_set_abs_params(wdata->ir, ABS_HAT0Y, 0, 767, 2, 4); | ||
| 1153 | input_set_abs_params(wdata->ir, ABS_HAT1X, 0, 1023, 2, 4); | ||
| 1154 | input_set_abs_params(wdata->ir, ABS_HAT1Y, 0, 767, 2, 4); | ||
| 1155 | input_set_abs_params(wdata->ir, ABS_HAT2X, 0, 1023, 2, 4); | ||
| 1156 | input_set_abs_params(wdata->ir, ABS_HAT2Y, 0, 767, 2, 4); | ||
| 1157 | input_set_abs_params(wdata->ir, ABS_HAT3X, 0, 1023, 2, 4); | ||
| 1158 | input_set_abs_params(wdata->ir, ABS_HAT3Y, 0, 767, 2, 4); | ||
| 1159 | |||
| 1160 | spin_lock_init(&wdata->qlock); | ||
| 1161 | INIT_WORK(&wdata->worker, wiimote_worker); | ||
| 1162 | 1738 | ||
| 1163 | spin_lock_init(&wdata->state.lock); | 1739 | spin_lock_init(&wdata->state.lock); |
| 1164 | init_completion(&wdata->state.ready); | 1740 | init_completion(&wdata->state.ready); |
| 1165 | mutex_init(&wdata->state.sync); | 1741 | mutex_init(&wdata->state.sync); |
| 1166 | wdata->state.drm = WIIPROTO_REQ_DRM_K; | 1742 | wdata->state.drm = WIIPROTO_REQ_DRM_K; |
| 1743 | wdata->state.cmd_battery = 0xff; | ||
| 1167 | 1744 | ||
| 1168 | return wdata; | 1745 | INIT_WORK(&wdata->init_worker, wiimote_init_worker); |
| 1746 | setup_timer(&wdata->timer, wiimote_init_timeout, (long)wdata); | ||
| 1169 | 1747 | ||
| 1170 | err_ir: | 1748 | return wdata; |
| 1171 | input_free_device(wdata->accel); | ||
| 1172 | err_input: | ||
| 1173 | input_free_device(wdata->input); | ||
| 1174 | err: | ||
| 1175 | kfree(wdata); | ||
| 1176 | return NULL; | ||
| 1177 | } | 1749 | } |
| 1178 | 1750 | ||
| 1179 | static void wiimote_destroy(struct wiimote_data *wdata) | 1751 | static void wiimote_destroy(struct wiimote_data *wdata) |
| 1180 | { | 1752 | { |
| 1753 | unsigned long flags; | ||
| 1754 | |||
| 1181 | wiidebug_deinit(wdata); | 1755 | wiidebug_deinit(wdata); |
| 1182 | wiiext_deinit(wdata); | 1756 | |
| 1183 | wiimote_leds_destroy(wdata); | 1757 | /* prevent init_worker from being scheduled again */ |
| 1184 | 1758 | spin_lock_irqsave(&wdata->state.lock, flags); | |
| 1185 | power_supply_unregister(&wdata->battery); | 1759 | wdata->state.flags |= WIIPROTO_FLAG_EXITING; |
| 1186 | kfree(wdata->battery.name); | 1760 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
| 1187 | input_unregister_device(wdata->accel); | 1761 | |
| 1188 | input_unregister_device(wdata->ir); | 1762 | cancel_work_sync(&wdata->init_worker); |
| 1189 | input_unregister_device(wdata->input); | 1763 | del_timer_sync(&wdata->timer); |
| 1190 | cancel_work_sync(&wdata->worker); | 1764 | |
| 1765 | device_remove_file(&wdata->hdev->dev, &dev_attr_devtype); | ||
| 1766 | device_remove_file(&wdata->hdev->dev, &dev_attr_extension); | ||
| 1767 | |||
| 1768 | wiimote_mp_unload(wdata); | ||
| 1769 | wiimote_ext_unload(wdata); | ||
| 1770 | wiimote_modules_unload(wdata); | ||
| 1771 | cancel_work_sync(&wdata->queue.worker); | ||
| 1772 | hid_hw_close(wdata->hdev); | ||
| 1191 | hid_hw_stop(wdata->hdev); | 1773 | hid_hw_stop(wdata->hdev); |
| 1192 | 1774 | ||
| 1193 | kfree(wdata); | 1775 | kfree(wdata); |
| @@ -1219,62 +1801,32 @@ static int wiimote_hid_probe(struct hid_device *hdev, | |||
| 1219 | goto err; | 1801 | goto err; |
| 1220 | } | 1802 | } |
| 1221 | 1803 | ||
| 1222 | ret = input_register_device(wdata->accel); | 1804 | ret = hid_hw_open(hdev); |
| 1223 | if (ret) { | 1805 | if (ret) { |
| 1224 | hid_err(hdev, "Cannot register input device\n"); | 1806 | hid_err(hdev, "cannot start hardware I/O\n"); |
| 1225 | goto err_stop; | 1807 | goto err_stop; |
| 1226 | } | 1808 | } |
| 1227 | 1809 | ||
| 1228 | ret = input_register_device(wdata->ir); | 1810 | ret = device_create_file(&hdev->dev, &dev_attr_extension); |
| 1229 | if (ret) { | ||
| 1230 | hid_err(hdev, "Cannot register input device\n"); | ||
| 1231 | goto err_ir; | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | ret = input_register_device(wdata->input); | ||
| 1235 | if (ret) { | 1811 | if (ret) { |
| 1236 | hid_err(hdev, "Cannot register input device\n"); | 1812 | hid_err(hdev, "cannot create sysfs attribute\n"); |
| 1237 | goto err_input; | 1813 | goto err_close; |
| 1238 | } | ||
| 1239 | |||
| 1240 | wdata->battery.properties = wiimote_battery_props; | ||
| 1241 | wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props); | ||
| 1242 | wdata->battery.get_property = wiimote_battery_get_property; | ||
| 1243 | wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 1244 | wdata->battery.use_for_apm = 0; | ||
| 1245 | wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s", | ||
| 1246 | wdata->hdev->uniq); | ||
| 1247 | if (!wdata->battery.name) { | ||
| 1248 | ret = -ENOMEM; | ||
| 1249 | goto err_battery_name; | ||
| 1250 | } | 1814 | } |
| 1251 | 1815 | ||
| 1252 | ret = power_supply_register(&wdata->hdev->dev, &wdata->battery); | 1816 | ret = device_create_file(&hdev->dev, &dev_attr_devtype); |
| 1253 | if (ret) { | 1817 | if (ret) { |
| 1254 | hid_err(hdev, "Cannot register battery device\n"); | 1818 | hid_err(hdev, "cannot create sysfs attribute\n"); |
| 1255 | goto err_battery; | 1819 | goto err_ext; |
| 1256 | } | 1820 | } |
| 1257 | 1821 | ||
| 1258 | power_supply_powers(&wdata->battery, &hdev->dev); | ||
| 1259 | |||
| 1260 | ret = wiimote_leds_create(wdata); | ||
| 1261 | if (ret) | ||
| 1262 | goto err_free; | ||
| 1263 | |||
| 1264 | ret = wiiext_init(wdata); | ||
| 1265 | if (ret) | ||
| 1266 | goto err_free; | ||
| 1267 | |||
| 1268 | ret = wiidebug_init(wdata); | 1822 | ret = wiidebug_init(wdata); |
| 1269 | if (ret) | 1823 | if (ret) |
| 1270 | goto err_free; | 1824 | goto err_free; |
| 1271 | 1825 | ||
| 1272 | hid_info(hdev, "New device registered\n"); | 1826 | hid_info(hdev, "New device registered\n"); |
| 1273 | 1827 | ||
| 1274 | /* by default set led1 after device initialization */ | 1828 | /* schedule device detection */ |
| 1275 | spin_lock_irq(&wdata->state.lock); | 1829 | wiimote_schedule(wdata); |
| 1276 | wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1); | ||
| 1277 | spin_unlock_irq(&wdata->state.lock); | ||
| 1278 | 1830 | ||
| 1279 | return 0; | 1831 | return 0; |
| 1280 | 1832 | ||
| @@ -1282,23 +1834,15 @@ err_free: | |||
| 1282 | wiimote_destroy(wdata); | 1834 | wiimote_destroy(wdata); |
| 1283 | return ret; | 1835 | return ret; |
| 1284 | 1836 | ||
| 1285 | err_battery: | 1837 | err_ext: |
| 1286 | kfree(wdata->battery.name); | 1838 | device_remove_file(&wdata->hdev->dev, &dev_attr_extension); |
| 1287 | err_battery_name: | 1839 | err_close: |
| 1288 | input_unregister_device(wdata->input); | 1840 | hid_hw_close(hdev); |
| 1289 | wdata->input = NULL; | ||
| 1290 | err_input: | ||
| 1291 | input_unregister_device(wdata->ir); | ||
| 1292 | wdata->ir = NULL; | ||
| 1293 | err_ir: | ||
| 1294 | input_unregister_device(wdata->accel); | ||
| 1295 | wdata->accel = NULL; | ||
| 1296 | err_stop: | 1841 | err_stop: |
| 1297 | hid_hw_stop(hdev); | 1842 | hid_hw_stop(hdev); |
| 1298 | err: | 1843 | err: |
| 1299 | input_free_device(wdata->ir); | 1844 | input_free_device(wdata->ir); |
| 1300 | input_free_device(wdata->accel); | 1845 | input_free_device(wdata->accel); |
| 1301 | input_free_device(wdata->input); | ||
| 1302 | kfree(wdata); | 1846 | kfree(wdata); |
| 1303 | return ret; | 1847 | return ret; |
| 1304 | } | 1848 | } |
| @@ -1331,4 +1875,4 @@ module_hid_driver(wiimote_hid_driver); | |||
| 1331 | 1875 | ||
| 1332 | MODULE_LICENSE("GPL"); | 1876 | MODULE_LICENSE("GPL"); |
| 1333 | MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); | 1877 | MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); |
| 1334 | MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver"); | 1878 | MODULE_DESCRIPTION("Driver for Nintendo Wii / Wii U peripherals"); |
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c index 90124ffaa2a5..c13fb5bd79e8 100644 --- a/drivers/hid/hid-wiimote-debug.c +++ b/drivers/hid/hid-wiimote-debug.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Debug support for HID Nintendo Wiimote devices | 2 | * Debug support for HID Nintendo Wii / Wii U peripherals |
| 3 | * Copyright (c) 2011 David Herrmann | 3 | * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com> |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | /* | 6 | /* |
| @@ -127,7 +127,8 @@ static int wiidebug_drm_open(struct inode *i, struct file *f) | |||
| 127 | static ssize_t wiidebug_drm_write(struct file *f, const char __user *u, | 127 | static ssize_t wiidebug_drm_write(struct file *f, const char __user *u, |
| 128 | size_t s, loff_t *off) | 128 | size_t s, loff_t *off) |
| 129 | { | 129 | { |
| 130 | struct wiimote_debug *dbg = f->private_data; | 130 | struct seq_file *sf = f->private_data; |
| 131 | struct wiimote_debug *dbg = sf->private; | ||
| 131 | unsigned long flags; | 132 | unsigned long flags; |
| 132 | char buf[16]; | 133 | char buf[16]; |
| 133 | ssize_t len; | 134 | ssize_t len; |
| @@ -140,7 +141,7 @@ static ssize_t wiidebug_drm_write(struct file *f, const char __user *u, | |||
| 140 | if (copy_from_user(buf, u, len)) | 141 | if (copy_from_user(buf, u, len)) |
| 141 | return -EFAULT; | 142 | return -EFAULT; |
| 142 | 143 | ||
| 143 | buf[15] = 0; | 144 | buf[len] = 0; |
| 144 | 145 | ||
| 145 | for (i = 0; i < WIIPROTO_REQ_MAX; ++i) { | 146 | for (i = 0; i < WIIPROTO_REQ_MAX; ++i) { |
| 146 | if (!wiidebug_drmmap[i]) | 147 | if (!wiidebug_drmmap[i]) |
| @@ -150,10 +151,13 @@ static ssize_t wiidebug_drm_write(struct file *f, const char __user *u, | |||
| 150 | } | 151 | } |
| 151 | 152 | ||
| 152 | if (i == WIIPROTO_REQ_MAX) | 153 | if (i == WIIPROTO_REQ_MAX) |
| 153 | i = simple_strtoul(buf, NULL, 10); | 154 | i = simple_strtoul(buf, NULL, 16); |
| 154 | 155 | ||
| 155 | spin_lock_irqsave(&dbg->wdata->state.lock, flags); | 156 | spin_lock_irqsave(&dbg->wdata->state.lock, flags); |
| 157 | dbg->wdata->state.flags &= ~WIIPROTO_FLAG_DRM_LOCKED; | ||
| 156 | wiiproto_req_drm(dbg->wdata, (__u8) i); | 158 | wiiproto_req_drm(dbg->wdata, (__u8) i); |
| 159 | if (i != WIIPROTO_REQ_NULL) | ||
| 160 | dbg->wdata->state.flags |= WIIPROTO_FLAG_DRM_LOCKED; | ||
| 157 | spin_unlock_irqrestore(&dbg->wdata->state.lock, flags); | 161 | spin_unlock_irqrestore(&dbg->wdata->state.lock, flags); |
| 158 | 162 | ||
| 159 | return len; | 163 | return len; |
diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c deleted file mode 100644 index 0472191d4a72..000000000000 --- a/drivers/hid/hid-wiimote-ext.c +++ /dev/null | |||
| @@ -1,849 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * HID driver for Nintendo Wiimote extension devices | ||
| 3 | * Copyright (c) 2011 David Herrmann | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the Free | ||
| 9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 10 | * any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/atomic.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/spinlock.h> | ||
| 16 | #include <linux/workqueue.h> | ||
| 17 | #include "hid-wiimote.h" | ||
| 18 | |||
| 19 | struct wiimote_ext { | ||
| 20 | struct wiimote_data *wdata; | ||
| 21 | struct work_struct worker; | ||
| 22 | struct input_dev *input; | ||
| 23 | struct input_dev *mp_input; | ||
| 24 | |||
| 25 | atomic_t opened; | ||
| 26 | atomic_t mp_opened; | ||
| 27 | bool plugged; | ||
| 28 | bool mp_plugged; | ||
| 29 | bool motionp; | ||
| 30 | __u8 ext_type; | ||
| 31 | __u16 calib[4][3]; | ||
| 32 | }; | ||
| 33 | |||
| 34 | enum wiiext_type { | ||
| 35 | WIIEXT_NONE, /* placeholder */ | ||
| 36 | WIIEXT_CLASSIC, /* Nintendo classic controller */ | ||
| 37 | WIIEXT_NUNCHUCK, /* Nintendo nunchuck controller */ | ||
| 38 | WIIEXT_BALANCE_BOARD, /* Nintendo balance board controller */ | ||
| 39 | }; | ||
| 40 | |||
| 41 | enum wiiext_keys { | ||
| 42 | WIIEXT_KEY_C, | ||
| 43 | WIIEXT_KEY_Z, | ||
| 44 | WIIEXT_KEY_A, | ||
| 45 | WIIEXT_KEY_B, | ||
| 46 | WIIEXT_KEY_X, | ||
| 47 | WIIEXT_KEY_Y, | ||
| 48 | WIIEXT_KEY_ZL, | ||
| 49 | WIIEXT_KEY_ZR, | ||
| 50 | WIIEXT_KEY_PLUS, | ||
| 51 | WIIEXT_KEY_MINUS, | ||
| 52 | WIIEXT_KEY_HOME, | ||
| 53 | WIIEXT_KEY_LEFT, | ||
| 54 | WIIEXT_KEY_RIGHT, | ||
| 55 | WIIEXT_KEY_UP, | ||
| 56 | WIIEXT_KEY_DOWN, | ||
| 57 | WIIEXT_KEY_LT, | ||
| 58 | WIIEXT_KEY_RT, | ||
| 59 | WIIEXT_KEY_COUNT | ||
| 60 | }; | ||
| 61 | |||
| 62 | static __u16 wiiext_keymap[] = { | ||
| 63 | BTN_C, /* WIIEXT_KEY_C */ | ||
| 64 | BTN_Z, /* WIIEXT_KEY_Z */ | ||
| 65 | BTN_A, /* WIIEXT_KEY_A */ | ||
| 66 | BTN_B, /* WIIEXT_KEY_B */ | ||
| 67 | BTN_X, /* WIIEXT_KEY_X */ | ||
| 68 | BTN_Y, /* WIIEXT_KEY_Y */ | ||
| 69 | BTN_TL2, /* WIIEXT_KEY_ZL */ | ||
| 70 | BTN_TR2, /* WIIEXT_KEY_ZR */ | ||
| 71 | KEY_NEXT, /* WIIEXT_KEY_PLUS */ | ||
| 72 | KEY_PREVIOUS, /* WIIEXT_KEY_MINUS */ | ||
| 73 | BTN_MODE, /* WIIEXT_KEY_HOME */ | ||
| 74 | KEY_LEFT, /* WIIEXT_KEY_LEFT */ | ||
| 75 | KEY_RIGHT, /* WIIEXT_KEY_RIGHT */ | ||
| 76 | KEY_UP, /* WIIEXT_KEY_UP */ | ||
| 77 | KEY_DOWN, /* WIIEXT_KEY_DOWN */ | ||
| 78 | BTN_TL, /* WIIEXT_KEY_LT */ | ||
| 79 | BTN_TR, /* WIIEXT_KEY_RT */ | ||
| 80 | }; | ||
| 81 | |||
| 82 | /* disable all extensions */ | ||
| 83 | static void ext_disable(struct wiimote_ext *ext) | ||
| 84 | { | ||
| 85 | unsigned long flags; | ||
| 86 | __u8 wmem = 0x55; | ||
| 87 | |||
| 88 | if (!wiimote_cmd_acquire(ext->wdata)) { | ||
| 89 | wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem)); | ||
| 90 | wiimote_cmd_release(ext->wdata); | ||
| 91 | } | ||
| 92 | |||
| 93 | spin_lock_irqsave(&ext->wdata->state.lock, flags); | ||
| 94 | ext->motionp = false; | ||
| 95 | ext->ext_type = WIIEXT_NONE; | ||
| 96 | wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL); | ||
| 97 | spin_unlock_irqrestore(&ext->wdata->state.lock, flags); | ||
| 98 | } | ||
| 99 | |||
| 100 | static bool motionp_read(struct wiimote_ext *ext) | ||
| 101 | { | ||
| 102 | __u8 rmem[2], wmem; | ||
| 103 | ssize_t ret; | ||
| 104 | bool avail = false; | ||
| 105 | |||
| 106 | if (!atomic_read(&ext->mp_opened)) | ||
| 107 | return false; | ||
| 108 | |||
| 109 | if (wiimote_cmd_acquire(ext->wdata)) | ||
| 110 | return false; | ||
| 111 | |||
| 112 | /* initialize motion plus */ | ||
| 113 | wmem = 0x55; | ||
| 114 | ret = wiimote_cmd_write(ext->wdata, 0xa600f0, &wmem, sizeof(wmem)); | ||
| 115 | if (ret) | ||
| 116 | goto error; | ||
| 117 | |||
| 118 | /* read motion plus ID */ | ||
| 119 | ret = wiimote_cmd_read(ext->wdata, 0xa600fe, rmem, 2); | ||
| 120 | if (ret == 2 || rmem[1] == 0x5) | ||
| 121 | avail = true; | ||
| 122 | |||
| 123 | error: | ||
| 124 | wiimote_cmd_release(ext->wdata); | ||
| 125 | return avail; | ||
| 126 | } | ||
| 127 | |||
| 128 | static __u8 ext_read(struct wiimote_ext *ext) | ||
| 129 | { | ||
| 130 | ssize_t ret; | ||
| 131 | __u8 buf[24], i, j, offs = 0; | ||
| 132 | __u8 rmem[2], wmem; | ||
| 133 | __u8 type = WIIEXT_NONE; | ||
| 134 | |||
| 135 | if (!ext->plugged || !atomic_read(&ext->opened)) | ||
| 136 | return WIIEXT_NONE; | ||
| 137 | |||
| 138 | if (wiimote_cmd_acquire(ext->wdata)) | ||
| 139 | return WIIEXT_NONE; | ||
| 140 | |||
| 141 | /* initialize extension */ | ||
| 142 | wmem = 0x55; | ||
| 143 | ret = wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem)); | ||
| 144 | if (!ret) { | ||
| 145 | /* disable encryption */ | ||
| 146 | wmem = 0x0; | ||
| 147 | wiimote_cmd_write(ext->wdata, 0xa400fb, &wmem, sizeof(wmem)); | ||
| 148 | } | ||
| 149 | |||
| 150 | /* read extension ID */ | ||
| 151 | ret = wiimote_cmd_read(ext->wdata, 0xa400fe, rmem, 2); | ||
| 152 | if (ret == 2) { | ||
| 153 | if (rmem[0] == 0 && rmem[1] == 0) | ||
| 154 | type = WIIEXT_NUNCHUCK; | ||
| 155 | else if (rmem[0] == 0x01 && rmem[1] == 0x01) | ||
| 156 | type = WIIEXT_CLASSIC; | ||
| 157 | else if (rmem[0] == 0x04 && rmem[1] == 0x02) | ||
| 158 | type = WIIEXT_BALANCE_BOARD; | ||
| 159 | } | ||
| 160 | |||
| 161 | /* get balance board calibration data */ | ||
| 162 | if (type == WIIEXT_BALANCE_BOARD) { | ||
| 163 | ret = wiimote_cmd_read(ext->wdata, 0xa40024, buf, 12); | ||
| 164 | ret += wiimote_cmd_read(ext->wdata, 0xa40024 + 12, | ||
| 165 | buf + 12, 12); | ||
| 166 | |||
| 167 | if (ret != 24) { | ||
| 168 | type = WIIEXT_NONE; | ||
| 169 | } else { | ||
| 170 | for (i = 0; i < 3; i++) { | ||
| 171 | for (j = 0; j < 4; j++) { | ||
| 172 | ext->calib[j][i] = buf[offs]; | ||
| 173 | ext->calib[j][i] <<= 8; | ||
| 174 | ext->calib[j][i] |= buf[offs + 1]; | ||
| 175 | offs += 2; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 181 | wiimote_cmd_release(ext->wdata); | ||
| 182 | |||
| 183 | return type; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void ext_enable(struct wiimote_ext *ext, bool motionp, __u8 ext_type) | ||
| 187 | { | ||
| 188 | unsigned long flags; | ||
| 189 | __u8 wmem; | ||
| 190 | int ret; | ||
| 191 | |||
| 192 | if (motionp) { | ||
| 193 | if (wiimote_cmd_acquire(ext->wdata)) | ||
| 194 | return; | ||
| 195 | |||
| 196 | if (ext_type == WIIEXT_CLASSIC) | ||
| 197 | wmem = 0x07; | ||
| 198 | else if (ext_type == WIIEXT_NUNCHUCK) | ||
| 199 | wmem = 0x05; | ||
| 200 | else | ||
| 201 | wmem = 0x04; | ||
| 202 | |||
| 203 | ret = wiimote_cmd_write(ext->wdata, 0xa600fe, &wmem, sizeof(wmem)); | ||
| 204 | wiimote_cmd_release(ext->wdata); | ||
| 205 | if (ret) | ||
| 206 | return; | ||
| 207 | } | ||
| 208 | |||
| 209 | spin_lock_irqsave(&ext->wdata->state.lock, flags); | ||
| 210 | ext->motionp = motionp; | ||
| 211 | ext->ext_type = ext_type; | ||
| 212 | wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL); | ||
| 213 | spin_unlock_irqrestore(&ext->wdata->state.lock, flags); | ||
| 214 | } | ||
| 215 | |||
| 216 | static void wiiext_worker(struct work_struct *work) | ||
| 217 | { | ||
| 218 | struct wiimote_ext *ext = container_of(work, struct wiimote_ext, | ||
| 219 | worker); | ||
| 220 | bool motionp; | ||
| 221 | __u8 ext_type; | ||
| 222 | |||
| 223 | ext_disable(ext); | ||
| 224 | motionp = motionp_read(ext); | ||
| 225 | ext_type = ext_read(ext); | ||
| 226 | ext_enable(ext, motionp, ext_type); | ||
| 227 | } | ||
| 228 | |||
| 229 | /* schedule work only once, otherwise mark for reschedule */ | ||
| 230 | static void wiiext_schedule(struct wiimote_ext *ext) | ||
| 231 | { | ||
| 232 | schedule_work(&ext->worker); | ||
| 233 | } | ||
| 234 | |||
| 235 | /* | ||
| 236 | * Reacts on extension port events | ||
| 237 | * Whenever the driver gets an event from the wiimote that an extension has been | ||
| 238 | * plugged or unplugged, this funtion shall be called. It checks what extensions | ||
| 239 | * are connected and initializes and activates them. | ||
| 240 | * This can be called in atomic context. The initialization is done in a | ||
| 241 | * separate worker thread. The state.lock spinlock must be held by the caller. | ||
| 242 | */ | ||
| 243 | void wiiext_event(struct wiimote_data *wdata, bool plugged) | ||
| 244 | { | ||
| 245 | if (!wdata->ext) | ||
| 246 | return; | ||
| 247 | |||
| 248 | if (wdata->ext->plugged == plugged) | ||
| 249 | return; | ||
| 250 | |||
| 251 | wdata->ext->plugged = plugged; | ||
| 252 | |||
| 253 | if (!plugged) | ||
| 254 | wdata->ext->mp_plugged = false; | ||
| 255 | |||
| 256 | /* | ||
| 257 | * We need to call wiiext_schedule(wdata->ext) here, however, the | ||
| 258 | * extension initialization logic is not fully understood and so | ||
| 259 | * automatic initialization is not supported, yet. | ||
| 260 | */ | ||
| 261 | } | ||
| 262 | |||
| 263 | /* | ||
| 264 | * Returns true if the current DRM mode should contain extension data and false | ||
| 265 | * if there is no interest in extension data. | ||
| 266 | * All supported extensions send 6 byte extension data so any DRM that contains | ||
| 267 | * extension bytes is fine. | ||
| 268 | * The caller must hold the state.lock spinlock. | ||
| 269 | */ | ||
| 270 | bool wiiext_active(struct wiimote_data *wdata) | ||
| 271 | { | ||
| 272 | if (!wdata->ext) | ||
| 273 | return false; | ||
| 274 | |||
| 275 | return wdata->ext->motionp || wdata->ext->ext_type; | ||
| 276 | } | ||
| 277 | |||
| 278 | static void handler_motionp(struct wiimote_ext *ext, const __u8 *payload) | ||
| 279 | { | ||
| 280 | __s32 x, y, z; | ||
| 281 | bool plugged; | ||
| 282 | |||
| 283 | /* | 8 7 6 5 4 3 | 2 | 1 | | ||
| 284 | * -----+------------------------------+-----+-----+ | ||
| 285 | * 1 | Yaw Speed <7:0> | | ||
| 286 | * 2 | Roll Speed <7:0> | | ||
| 287 | * 3 | Pitch Speed <7:0> | | ||
| 288 | * -----+------------------------------+-----+-----+ | ||
| 289 | * 4 | Yaw Speed <13:8> | Yaw |Pitch| | ||
| 290 | * -----+------------------------------+-----+-----+ | ||
| 291 | * 5 | Roll Speed <13:8> |Roll | Ext | | ||
| 292 | * -----+------------------------------+-----+-----+ | ||
| 293 | * 6 | Pitch Speed <13:8> | 1 | 0 | | ||
| 294 | * -----+------------------------------+-----+-----+ | ||
| 295 | * The single bits Yaw, Roll, Pitch in the lower right corner specify | ||
| 296 | * whether the wiimote is rotating fast (0) or slow (1). Speed for slow | ||
| 297 | * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a | ||
| 298 | * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast | ||
| 299 | * and 9 for slow. | ||
| 300 | * If the wiimote is not rotating the sensor reports 2^13 = 8192. | ||
| 301 | * Ext specifies whether an extension is connected to the motionp. | ||
| 302 | */ | ||
| 303 | |||
| 304 | x = payload[0]; | ||
| 305 | y = payload[1]; | ||
| 306 | z = payload[2]; | ||
| 307 | |||
| 308 | x |= (((__u16)payload[3]) << 6) & 0xff00; | ||
| 309 | y |= (((__u16)payload[4]) << 6) & 0xff00; | ||
| 310 | z |= (((__u16)payload[5]) << 6) & 0xff00; | ||
| 311 | |||
| 312 | x -= 8192; | ||
| 313 | y -= 8192; | ||
| 314 | z -= 8192; | ||
| 315 | |||
| 316 | if (!(payload[3] & 0x02)) | ||
| 317 | x *= 18; | ||
| 318 | else | ||
| 319 | x *= 9; | ||
| 320 | if (!(payload[4] & 0x02)) | ||
| 321 | y *= 18; | ||
| 322 | else | ||
| 323 | y *= 9; | ||
| 324 | if (!(payload[3] & 0x01)) | ||
| 325 | z *= 18; | ||
| 326 | else | ||
| 327 | z *= 9; | ||
| 328 | |||
| 329 | input_report_abs(ext->mp_input, ABS_RX, x); | ||
| 330 | input_report_abs(ext->mp_input, ABS_RY, y); | ||
| 331 | input_report_abs(ext->mp_input, ABS_RZ, z); | ||
| 332 | input_sync(ext->mp_input); | ||
| 333 | |||
| 334 | plugged = payload[5] & 0x01; | ||
| 335 | if (plugged != ext->mp_plugged) | ||
| 336 | ext->mp_plugged = plugged; | ||
| 337 | } | ||
| 338 | |||
| 339 | static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload) | ||
| 340 | { | ||
| 341 | __s16 x, y, z, bx, by; | ||
| 342 | |||
| 343 | /* Byte | 8 7 | 6 5 | 4 3 | 2 | 1 | | ||
| 344 | * -----+----------+---------+---------+----+-----+ | ||
| 345 | * 1 | Button X <7:0> | | ||
| 346 | * 2 | Button Y <7:0> | | ||
| 347 | * -----+----------+---------+---------+----+-----+ | ||
| 348 | * 3 | Speed X <9:2> | | ||
| 349 | * 4 | Speed Y <9:2> | | ||
| 350 | * 5 | Speed Z <9:2> | | ||
| 351 | * -----+----------+---------+---------+----+-----+ | ||
| 352 | * 6 | Z <1:0> | Y <1:0> | X <1:0> | BC | BZ | | ||
| 353 | * -----+----------+---------+---------+----+-----+ | ||
| 354 | * Button X/Y is the analog stick. Speed X, Y and Z are the | ||
| 355 | * accelerometer data in the same format as the wiimote's accelerometer. | ||
| 356 | * The 6th byte contains the LSBs of the accelerometer data. | ||
| 357 | * BC and BZ are the C and Z buttons: 0 means pressed | ||
| 358 | * | ||
| 359 | * If reported interleaved with motionp, then the layout changes. The | ||
| 360 | * 5th and 6th byte changes to: | ||
| 361 | * -----+-----------------------------------+-----+ | ||
| 362 | * 5 | Speed Z <9:3> | EXT | | ||
| 363 | * -----+--------+-----+-----+----+----+----+-----+ | ||
| 364 | * 6 |Z <2:1> |Y <1>|X <1>| BC | BZ | 0 | 0 | | ||
| 365 | * -----+--------+-----+-----+----+----+----+-----+ | ||
| 366 | * All three accelerometer values lose their LSB. The other data is | ||
| 367 | * still available but slightly moved. | ||
| 368 | * | ||
| 369 | * Center data for button values is 128. Center value for accelerometer | ||
| 370 | * values it 512 / 0x200 | ||
| 371 | */ | ||
| 372 | |||
| 373 | bx = payload[0]; | ||
| 374 | by = payload[1]; | ||
| 375 | bx -= 128; | ||
| 376 | by -= 128; | ||
| 377 | |||
| 378 | x = payload[2] << 2; | ||
| 379 | y = payload[3] << 2; | ||
| 380 | z = payload[4] << 2; | ||
| 381 | |||
| 382 | if (ext->motionp) { | ||
| 383 | x |= (payload[5] >> 3) & 0x02; | ||
| 384 | y |= (payload[5] >> 4) & 0x02; | ||
| 385 | z &= ~0x4; | ||
| 386 | z |= (payload[5] >> 5) & 0x06; | ||
| 387 | } else { | ||
| 388 | x |= (payload[5] >> 2) & 0x03; | ||
| 389 | y |= (payload[5] >> 4) & 0x03; | ||
| 390 | z |= (payload[5] >> 6) & 0x03; | ||
| 391 | } | ||
| 392 | |||
| 393 | x -= 0x200; | ||
| 394 | y -= 0x200; | ||
| 395 | z -= 0x200; | ||
| 396 | |||
| 397 | input_report_abs(ext->input, ABS_HAT0X, bx); | ||
| 398 | input_report_abs(ext->input, ABS_HAT0Y, by); | ||
| 399 | |||
| 400 | input_report_abs(ext->input, ABS_RX, x); | ||
| 401 | input_report_abs(ext->input, ABS_RY, y); | ||
| 402 | input_report_abs(ext->input, ABS_RZ, z); | ||
| 403 | |||
| 404 | if (ext->motionp) { | ||
| 405 | input_report_key(ext->input, | ||
| 406 | wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x04)); | ||
| 407 | input_report_key(ext->input, | ||
| 408 | wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x08)); | ||
| 409 | } else { | ||
| 410 | input_report_key(ext->input, | ||
| 411 | wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x01)); | ||
| 412 | input_report_key(ext->input, | ||
| 413 | wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x02)); | ||
| 414 | } | ||
| 415 | |||
| 416 | input_sync(ext->input); | ||
| 417 | } | ||
| 418 | |||
| 419 | static void handler_classic(struct wiimote_ext *ext, const __u8 *payload) | ||
| 420 | { | ||
| 421 | __s8 rx, ry, lx, ly, lt, rt; | ||
| 422 | |||
| 423 | /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ||
| 424 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 425 | * 1 | RX <5:4> | LX <5:0> | | ||
| 426 | * 2 | RX <3:2> | LY <5:0> | | ||
| 427 | * -----+-----+-----+-----+-----------------------------+ | ||
| 428 | * 3 |RX<1>| LT <5:4> | RY <5:1> | | ||
| 429 | * -----+-----+-----------+-----------------------------+ | ||
| 430 | * 4 | LT <3:1> | RT <5:1> | | ||
| 431 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 432 | * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 | | ||
| 433 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 434 | * 6 | BZL | BB | BY | BA | BX | BZR | BDL | BDU | | ||
| 435 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 436 | * All buttons are 0 if pressed | ||
| 437 | * RX and RY are right analog stick | ||
| 438 | * LX and LY are left analog stick | ||
| 439 | * LT is left trigger, RT is right trigger | ||
| 440 | * BLT is 0 if left trigger is fully pressed | ||
| 441 | * BRT is 0 if right trigger is fully pressed | ||
| 442 | * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons | ||
| 443 | * BZL is left Z button and BZR is right Z button | ||
| 444 | * B-, BH, B+ are +, HOME and - buttons | ||
| 445 | * BB, BY, BA, BX are A, B, X, Y buttons | ||
| 446 | * LSB of RX, RY, LT, and RT are not transmitted and always 0. | ||
| 447 | * | ||
| 448 | * With motionp enabled it changes slightly to this: | ||
| 449 | * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ||
| 450 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 451 | * 1 | RX <4:3> | LX <5:1> | BDU | | ||
| 452 | * 2 | RX <2:1> | LY <5:1> | BDL | | ||
| 453 | * -----+-----+-----+-----+-----------------------+-----+ | ||
| 454 | * 3 |RX<0>| LT <4:3> | RY <4:0> | | ||
| 455 | * -----+-----+-----------+-----------------------------+ | ||
| 456 | * 4 | LT <2:0> | RT <4:0> | | ||
| 457 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 458 | * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | EXT | | ||
| 459 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 460 | * 6 | BZL | BB | BY | BA | BX | BZR | 0 | 0 | | ||
| 461 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 462 | * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest | ||
| 463 | * is the same as before. | ||
| 464 | */ | ||
| 465 | |||
| 466 | if (ext->motionp) { | ||
| 467 | lx = payload[0] & 0x3e; | ||
| 468 | ly = payload[0] & 0x3e; | ||
| 469 | } else { | ||
| 470 | lx = payload[0] & 0x3f; | ||
| 471 | ly = payload[0] & 0x3f; | ||
| 472 | } | ||
| 473 | |||
| 474 | rx = (payload[0] >> 3) & 0x14; | ||
| 475 | rx |= (payload[1] >> 5) & 0x06; | ||
| 476 | rx |= (payload[2] >> 7) & 0x01; | ||
| 477 | ry = payload[2] & 0x1f; | ||
| 478 | |||
| 479 | rt = payload[3] & 0x1f; | ||
| 480 | lt = (payload[2] >> 2) & 0x18; | ||
| 481 | lt |= (payload[3] >> 5) & 0x07; | ||
| 482 | |||
| 483 | rx <<= 1; | ||
| 484 | ry <<= 1; | ||
| 485 | rt <<= 1; | ||
| 486 | lt <<= 1; | ||
| 487 | |||
| 488 | input_report_abs(ext->input, ABS_HAT1X, lx - 0x20); | ||
| 489 | input_report_abs(ext->input, ABS_HAT1Y, ly - 0x20); | ||
| 490 | input_report_abs(ext->input, ABS_HAT2X, rx - 0x20); | ||
| 491 | input_report_abs(ext->input, ABS_HAT2Y, ry - 0x20); | ||
| 492 | input_report_abs(ext->input, ABS_HAT3X, rt - 0x20); | ||
| 493 | input_report_abs(ext->input, ABS_HAT3Y, lt - 0x20); | ||
| 494 | |||
| 495 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_RIGHT], | ||
| 496 | !!(payload[4] & 0x80)); | ||
| 497 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_DOWN], | ||
| 498 | !!(payload[4] & 0x40)); | ||
| 499 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LT], | ||
| 500 | !!(payload[4] & 0x20)); | ||
| 501 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_MINUS], | ||
| 502 | !!(payload[4] & 0x10)); | ||
| 503 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_HOME], | ||
| 504 | !!(payload[4] & 0x08)); | ||
| 505 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_PLUS], | ||
| 506 | !!(payload[4] & 0x04)); | ||
| 507 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_RT], | ||
| 508 | !!(payload[4] & 0x02)); | ||
| 509 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_ZL], | ||
| 510 | !!(payload[5] & 0x80)); | ||
| 511 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_B], | ||
| 512 | !!(payload[5] & 0x40)); | ||
| 513 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_Y], | ||
| 514 | !!(payload[5] & 0x20)); | ||
| 515 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_A], | ||
| 516 | !!(payload[5] & 0x10)); | ||
| 517 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_X], | ||
| 518 | !!(payload[5] & 0x08)); | ||
| 519 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_ZR], | ||
| 520 | !!(payload[5] & 0x04)); | ||
| 521 | |||
| 522 | if (ext->motionp) { | ||
| 523 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_UP], | ||
| 524 | !!(payload[0] & 0x01)); | ||
| 525 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LEFT], | ||
| 526 | !!(payload[1] & 0x01)); | ||
| 527 | } else { | ||
| 528 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_UP], | ||
| 529 | !!(payload[5] & 0x01)); | ||
| 530 | input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LEFT], | ||
| 531 | !!(payload[5] & 0x02)); | ||
| 532 | } | ||
| 533 | |||
| 534 | input_sync(ext->input); | ||
| 535 | } | ||
| 536 | |||
| 537 | static void handler_balance_board(struct wiimote_ext *ext, const __u8 *payload) | ||
| 538 | { | ||
| 539 | __s32 val[4], tmp; | ||
| 540 | unsigned int i; | ||
| 541 | |||
| 542 | /* Byte | 8 7 6 5 4 3 2 1 | | ||
| 543 | * -----+--------------------------+ | ||
| 544 | * 1 | Top Right <15:8> | | ||
| 545 | * 2 | Top Right <7:0> | | ||
| 546 | * -----+--------------------------+ | ||
| 547 | * 3 | Bottom Right <15:8> | | ||
| 548 | * 4 | Bottom Right <7:0> | | ||
| 549 | * -----+--------------------------+ | ||
| 550 | * 5 | Top Left <15:8> | | ||
| 551 | * 6 | Top Left <7:0> | | ||
| 552 | * -----+--------------------------+ | ||
| 553 | * 7 | Bottom Left <15:8> | | ||
| 554 | * 8 | Bottom Left <7:0> | | ||
| 555 | * -----+--------------------------+ | ||
| 556 | * | ||
| 557 | * These values represent the weight-measurements of the Wii-balance | ||
| 558 | * board with 16bit precision. | ||
| 559 | * | ||
| 560 | * The balance-board is never reported interleaved with motionp. | ||
| 561 | */ | ||
| 562 | |||
| 563 | val[0] = payload[0]; | ||
| 564 | val[0] <<= 8; | ||
| 565 | val[0] |= payload[1]; | ||
| 566 | |||
| 567 | val[1] = payload[2]; | ||
| 568 | val[1] <<= 8; | ||
| 569 | val[1] |= payload[3]; | ||
| 570 | |||
| 571 | val[2] = payload[4]; | ||
| 572 | val[2] <<= 8; | ||
| 573 | val[2] |= payload[5]; | ||
| 574 | |||
| 575 | val[3] = payload[6]; | ||
| 576 | val[3] <<= 8; | ||
| 577 | val[3] |= payload[7]; | ||
| 578 | |||
| 579 | /* apply calibration data */ | ||
| 580 | for (i = 0; i < 4; i++) { | ||
| 581 | if (val[i] < ext->calib[i][1]) { | ||
| 582 | tmp = val[i] - ext->calib[i][0]; | ||
| 583 | tmp *= 1700; | ||
| 584 | tmp /= ext->calib[i][1] - ext->calib[i][0]; | ||
| 585 | } else { | ||
| 586 | tmp = val[i] - ext->calib[i][1]; | ||
| 587 | tmp *= 1700; | ||
| 588 | tmp /= ext->calib[i][2] - ext->calib[i][1]; | ||
| 589 | tmp += 1700; | ||
| 590 | } | ||
| 591 | val[i] = tmp; | ||
| 592 | } | ||
| 593 | |||
| 594 | input_report_abs(ext->input, ABS_HAT0X, val[0]); | ||
| 595 | input_report_abs(ext->input, ABS_HAT0Y, val[1]); | ||
| 596 | input_report_abs(ext->input, ABS_HAT1X, val[2]); | ||
| 597 | input_report_abs(ext->input, ABS_HAT1Y, val[3]); | ||
| 598 | |||
| 599 | input_sync(ext->input); | ||
| 600 | } | ||
| 601 | |||
| 602 | /* call this with state.lock spinlock held */ | ||
| 603 | void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload) | ||
| 604 | { | ||
| 605 | struct wiimote_ext *ext = wdata->ext; | ||
| 606 | |||
| 607 | if (!ext) | ||
| 608 | return; | ||
| 609 | |||
| 610 | if (ext->motionp && (payload[5] & 0x02)) { | ||
| 611 | handler_motionp(ext, payload); | ||
| 612 | } else if (ext->ext_type == WIIEXT_NUNCHUCK) { | ||
| 613 | handler_nunchuck(ext, payload); | ||
| 614 | } else if (ext->ext_type == WIIEXT_CLASSIC) { | ||
| 615 | handler_classic(ext, payload); | ||
| 616 | } else if (ext->ext_type == WIIEXT_BALANCE_BOARD) { | ||
| 617 | handler_balance_board(ext, payload); | ||
| 618 | } | ||
| 619 | } | ||
| 620 | |||
| 621 | static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr, | ||
| 622 | char *buf) | ||
| 623 | { | ||
| 624 | struct wiimote_data *wdata = dev_to_wii(dev); | ||
| 625 | __u8 type = WIIEXT_NONE; | ||
| 626 | bool motionp = false; | ||
| 627 | unsigned long flags; | ||
| 628 | |||
| 629 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 630 | if (wdata->ext) { | ||
| 631 | motionp = wdata->ext->motionp; | ||
| 632 | type = wdata->ext->ext_type; | ||
| 633 | } | ||
| 634 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 635 | |||
| 636 | if (type == WIIEXT_NUNCHUCK) { | ||
| 637 | if (motionp) | ||
| 638 | return sprintf(buf, "motionp+nunchuck\n"); | ||
| 639 | else | ||
| 640 | return sprintf(buf, "nunchuck\n"); | ||
| 641 | } else if (type == WIIEXT_CLASSIC) { | ||
| 642 | if (motionp) | ||
| 643 | return sprintf(buf, "motionp+classic\n"); | ||
| 644 | else | ||
| 645 | return sprintf(buf, "classic\n"); | ||
| 646 | } else if (type == WIIEXT_BALANCE_BOARD) { | ||
| 647 | if (motionp) | ||
| 648 | return sprintf(buf, "motionp+balanceboard\n"); | ||
| 649 | else | ||
| 650 | return sprintf(buf, "balanceboard\n"); | ||
| 651 | } else { | ||
| 652 | if (motionp) | ||
| 653 | return sprintf(buf, "motionp\n"); | ||
| 654 | else | ||
| 655 | return sprintf(buf, "none\n"); | ||
| 656 | } | ||
| 657 | } | ||
| 658 | |||
| 659 | static DEVICE_ATTR(extension, S_IRUGO, wiiext_show, NULL); | ||
| 660 | |||
| 661 | static int wiiext_input_open(struct input_dev *dev) | ||
| 662 | { | ||
| 663 | struct wiimote_ext *ext = input_get_drvdata(dev); | ||
| 664 | int ret; | ||
| 665 | |||
| 666 | ret = hid_hw_open(ext->wdata->hdev); | ||
| 667 | if (ret) | ||
| 668 | return ret; | ||
| 669 | |||
| 670 | atomic_inc(&ext->opened); | ||
| 671 | wiiext_schedule(ext); | ||
| 672 | |||
| 673 | return 0; | ||
| 674 | } | ||
| 675 | |||
| 676 | static void wiiext_input_close(struct input_dev *dev) | ||
| 677 | { | ||
| 678 | struct wiimote_ext *ext = input_get_drvdata(dev); | ||
| 679 | |||
| 680 | atomic_dec(&ext->opened); | ||
| 681 | wiiext_schedule(ext); | ||
| 682 | hid_hw_close(ext->wdata->hdev); | ||
| 683 | } | ||
| 684 | |||
| 685 | static int wiiext_mp_open(struct input_dev *dev) | ||
| 686 | { | ||
| 687 | struct wiimote_ext *ext = input_get_drvdata(dev); | ||
| 688 | int ret; | ||
| 689 | |||
| 690 | ret = hid_hw_open(ext->wdata->hdev); | ||
| 691 | if (ret) | ||
| 692 | return ret; | ||
| 693 | |||
| 694 | atomic_inc(&ext->mp_opened); | ||
| 695 | wiiext_schedule(ext); | ||
| 696 | |||
| 697 | return 0; | ||
| 698 | } | ||
| 699 | |||
| 700 | static void wiiext_mp_close(struct input_dev *dev) | ||
| 701 | { | ||
| 702 | struct wiimote_ext *ext = input_get_drvdata(dev); | ||
| 703 | |||
| 704 | atomic_dec(&ext->mp_opened); | ||
| 705 | wiiext_schedule(ext); | ||
| 706 | hid_hw_close(ext->wdata->hdev); | ||
| 707 | } | ||
| 708 | |||
| 709 | /* Initializes the extension driver of a wiimote */ | ||
| 710 | int wiiext_init(struct wiimote_data *wdata) | ||
| 711 | { | ||
| 712 | struct wiimote_ext *ext; | ||
| 713 | unsigned long flags; | ||
| 714 | int ret, i; | ||
| 715 | |||
| 716 | ext = kzalloc(sizeof(*ext), GFP_KERNEL); | ||
| 717 | if (!ext) | ||
| 718 | return -ENOMEM; | ||
| 719 | |||
| 720 | ext->wdata = wdata; | ||
| 721 | INIT_WORK(&ext->worker, wiiext_worker); | ||
| 722 | |||
| 723 | ext->input = input_allocate_device(); | ||
| 724 | if (!ext->input) { | ||
| 725 | ret = -ENOMEM; | ||
| 726 | goto err_input; | ||
| 727 | } | ||
| 728 | |||
| 729 | input_set_drvdata(ext->input, ext); | ||
| 730 | ext->input->open = wiiext_input_open; | ||
| 731 | ext->input->close = wiiext_input_close; | ||
| 732 | ext->input->dev.parent = &wdata->hdev->dev; | ||
| 733 | ext->input->id.bustype = wdata->hdev->bus; | ||
| 734 | ext->input->id.vendor = wdata->hdev->vendor; | ||
| 735 | ext->input->id.product = wdata->hdev->product; | ||
| 736 | ext->input->id.version = wdata->hdev->version; | ||
| 737 | ext->input->name = WIIMOTE_NAME " Extension"; | ||
| 738 | |||
| 739 | set_bit(EV_KEY, ext->input->evbit); | ||
| 740 | for (i = 0; i < WIIEXT_KEY_COUNT; ++i) | ||
| 741 | set_bit(wiiext_keymap[i], ext->input->keybit); | ||
| 742 | |||
| 743 | set_bit(EV_ABS, ext->input->evbit); | ||
| 744 | set_bit(ABS_HAT0X, ext->input->absbit); | ||
| 745 | set_bit(ABS_HAT0Y, ext->input->absbit); | ||
| 746 | set_bit(ABS_HAT1X, ext->input->absbit); | ||
| 747 | set_bit(ABS_HAT1Y, ext->input->absbit); | ||
| 748 | set_bit(ABS_HAT2X, ext->input->absbit); | ||
| 749 | set_bit(ABS_HAT2Y, ext->input->absbit); | ||
| 750 | set_bit(ABS_HAT3X, ext->input->absbit); | ||
| 751 | set_bit(ABS_HAT3Y, ext->input->absbit); | ||
| 752 | input_set_abs_params(ext->input, ABS_HAT0X, -120, 120, 2, 4); | ||
| 753 | input_set_abs_params(ext->input, ABS_HAT0Y, -120, 120, 2, 4); | ||
| 754 | input_set_abs_params(ext->input, ABS_HAT1X, -30, 30, 1, 1); | ||
| 755 | input_set_abs_params(ext->input, ABS_HAT1Y, -30, 30, 1, 1); | ||
| 756 | input_set_abs_params(ext->input, ABS_HAT2X, -30, 30, 1, 1); | ||
| 757 | input_set_abs_params(ext->input, ABS_HAT2Y, -30, 30, 1, 1); | ||
| 758 | input_set_abs_params(ext->input, ABS_HAT3X, -30, 30, 1, 1); | ||
| 759 | input_set_abs_params(ext->input, ABS_HAT3Y, -30, 30, 1, 1); | ||
| 760 | set_bit(ABS_RX, ext->input->absbit); | ||
| 761 | set_bit(ABS_RY, ext->input->absbit); | ||
| 762 | set_bit(ABS_RZ, ext->input->absbit); | ||
| 763 | input_set_abs_params(ext->input, ABS_RX, -500, 500, 2, 4); | ||
| 764 | input_set_abs_params(ext->input, ABS_RY, -500, 500, 2, 4); | ||
| 765 | input_set_abs_params(ext->input, ABS_RZ, -500, 500, 2, 4); | ||
| 766 | |||
| 767 | ret = input_register_device(ext->input); | ||
| 768 | if (ret) { | ||
| 769 | input_free_device(ext->input); | ||
| 770 | goto err_input; | ||
| 771 | } | ||
| 772 | |||
| 773 | ext->mp_input = input_allocate_device(); | ||
| 774 | if (!ext->mp_input) { | ||
| 775 | ret = -ENOMEM; | ||
| 776 | goto err_mp; | ||
| 777 | } | ||
| 778 | |||
| 779 | input_set_drvdata(ext->mp_input, ext); | ||
| 780 | ext->mp_input->open = wiiext_mp_open; | ||
| 781 | ext->mp_input->close = wiiext_mp_close; | ||
| 782 | ext->mp_input->dev.parent = &wdata->hdev->dev; | ||
| 783 | ext->mp_input->id.bustype = wdata->hdev->bus; | ||
| 784 | ext->mp_input->id.vendor = wdata->hdev->vendor; | ||
| 785 | ext->mp_input->id.product = wdata->hdev->product; | ||
| 786 | ext->mp_input->id.version = wdata->hdev->version; | ||
| 787 | ext->mp_input->name = WIIMOTE_NAME " Motion+"; | ||
| 788 | |||
| 789 | set_bit(EV_ABS, ext->mp_input->evbit); | ||
| 790 | set_bit(ABS_RX, ext->mp_input->absbit); | ||
| 791 | set_bit(ABS_RY, ext->mp_input->absbit); | ||
| 792 | set_bit(ABS_RZ, ext->mp_input->absbit); | ||
| 793 | input_set_abs_params(ext->mp_input, ABS_RX, -160000, 160000, 4, 8); | ||
| 794 | input_set_abs_params(ext->mp_input, ABS_RY, -160000, 160000, 4, 8); | ||
| 795 | input_set_abs_params(ext->mp_input, ABS_RZ, -160000, 160000, 4, 8); | ||
| 796 | |||
| 797 | ret = input_register_device(ext->mp_input); | ||
| 798 | if (ret) { | ||
| 799 | input_free_device(ext->mp_input); | ||
| 800 | goto err_mp; | ||
| 801 | } | ||
| 802 | |||
| 803 | ret = device_create_file(&wdata->hdev->dev, &dev_attr_extension); | ||
| 804 | if (ret) | ||
| 805 | goto err_dev; | ||
| 806 | |||
| 807 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 808 | wdata->ext = ext; | ||
| 809 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 810 | |||
| 811 | return 0; | ||
| 812 | |||
| 813 | err_dev: | ||
| 814 | input_unregister_device(ext->mp_input); | ||
| 815 | err_mp: | ||
| 816 | input_unregister_device(ext->input); | ||
| 817 | err_input: | ||
| 818 | kfree(ext); | ||
| 819 | return ret; | ||
| 820 | } | ||
| 821 | |||
| 822 | /* Deinitializes the extension driver of a wiimote */ | ||
| 823 | void wiiext_deinit(struct wiimote_data *wdata) | ||
| 824 | { | ||
| 825 | struct wiimote_ext *ext = wdata->ext; | ||
| 826 | unsigned long flags; | ||
| 827 | |||
| 828 | if (!ext) | ||
| 829 | return; | ||
| 830 | |||
| 831 | /* | ||
| 832 | * We first unset wdata->ext to avoid further input from the wiimote | ||
| 833 | * core. The worker thread does not access this pointer so it is not | ||
| 834 | * affected by this. | ||
| 835 | * We kill the worker after this so it does not get respawned during | ||
| 836 | * deinitialization. | ||
| 837 | */ | ||
| 838 | |||
| 839 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 840 | wdata->ext = NULL; | ||
| 841 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 842 | |||
| 843 | device_remove_file(&wdata->hdev->dev, &dev_attr_extension); | ||
| 844 | input_unregister_device(ext->mp_input); | ||
| 845 | input_unregister_device(ext->input); | ||
| 846 | |||
| 847 | cancel_work_sync(&ext->worker); | ||
| 848 | kfree(ext); | ||
| 849 | } | ||
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c new file mode 100644 index 000000000000..2e7d644dba18 --- /dev/null +++ b/drivers/hid/hid-wiimote-modules.c | |||
| @@ -0,0 +1,2086 @@ | |||
| 1 | /* | ||
| 2 | * Device Modules for Nintendo Wii / Wii U HID Driver | ||
| 3 | * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com> | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the Free | ||
| 9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 10 | * any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Wiimote Modules | ||
| 15 | * Nintendo devices provide different peripherals and many new devices lack | ||
| 16 | * initial features like the IR camera. Therefore, each peripheral device is | ||
| 17 | * implemented as an independent module and we probe on each device only the | ||
| 18 | * modules for the hardware that really is available. | ||
| 19 | * | ||
| 20 | * Module registration is sequential. Unregistration is done in reverse order. | ||
| 21 | * After device detection, the needed modules are loaded. Users can trigger | ||
| 22 | * re-detection which causes all modules to be unloaded and then reload the | ||
| 23 | * modules for the new detected device. | ||
| 24 | * | ||
| 25 | * wdata->input is a shared input device. It is always initialized prior to | ||
| 26 | * module registration. If at least one registered module is marked as | ||
| 27 | * WIIMOD_FLAG_INPUT, then the input device will get registered after all | ||
| 28 | * modules were registered. | ||
| 29 | * Please note that it is unregistered _before_ the "remove" callbacks are | ||
| 30 | * called. This guarantees that no input interaction is done, anymore. However, | ||
| 31 | * the wiimote core keeps a reference to the input device so it is freed only | ||
| 32 | * after all modules were removed. It is safe to send events to unregistered | ||
| 33 | * input devices. | ||
| 34 | */ | ||
| 35 | |||
| 36 | #include <linux/device.h> | ||
| 37 | #include <linux/hid.h> | ||
| 38 | #include <linux/input.h> | ||
| 39 | #include <linux/spinlock.h> | ||
| 40 | #include "hid-wiimote.h" | ||
| 41 | |||
| 42 | /* | ||
| 43 | * Keys | ||
| 44 | * The initial Wii Remote provided a bunch of buttons that are reported as | ||
| 45 | * part of the core protocol. Many later devices dropped these and report | ||
| 46 | * invalid data in the core button reports. Load this only on devices which | ||
| 47 | * correctly send button reports. | ||
| 48 | * It uses the shared input device. | ||
| 49 | */ | ||
| 50 | |||
| 51 | static const __u16 wiimod_keys_map[] = { | ||
| 52 | KEY_LEFT, /* WIIPROTO_KEY_LEFT */ | ||
| 53 | KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */ | ||
| 54 | KEY_UP, /* WIIPROTO_KEY_UP */ | ||
| 55 | KEY_DOWN, /* WIIPROTO_KEY_DOWN */ | ||
| 56 | KEY_NEXT, /* WIIPROTO_KEY_PLUS */ | ||
| 57 | KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */ | ||
| 58 | BTN_1, /* WIIPROTO_KEY_ONE */ | ||
| 59 | BTN_2, /* WIIPROTO_KEY_TWO */ | ||
| 60 | BTN_A, /* WIIPROTO_KEY_A */ | ||
| 61 | BTN_B, /* WIIPROTO_KEY_B */ | ||
| 62 | BTN_MODE, /* WIIPROTO_KEY_HOME */ | ||
| 63 | }; | ||
| 64 | |||
| 65 | static void wiimod_keys_in_keys(struct wiimote_data *wdata, const __u8 *keys) | ||
| 66 | { | ||
| 67 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_LEFT], | ||
| 68 | !!(keys[0] & 0x01)); | ||
| 69 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_RIGHT], | ||
| 70 | !!(keys[0] & 0x02)); | ||
| 71 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_DOWN], | ||
| 72 | !!(keys[0] & 0x04)); | ||
| 73 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_UP], | ||
| 74 | !!(keys[0] & 0x08)); | ||
| 75 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_PLUS], | ||
| 76 | !!(keys[0] & 0x10)); | ||
| 77 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_TWO], | ||
| 78 | !!(keys[1] & 0x01)); | ||
| 79 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_ONE], | ||
| 80 | !!(keys[1] & 0x02)); | ||
| 81 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_B], | ||
| 82 | !!(keys[1] & 0x04)); | ||
| 83 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_A], | ||
| 84 | !!(keys[1] & 0x08)); | ||
| 85 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_MINUS], | ||
| 86 | !!(keys[1] & 0x10)); | ||
| 87 | input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_HOME], | ||
| 88 | !!(keys[1] & 0x80)); | ||
| 89 | input_sync(wdata->input); | ||
| 90 | } | ||
| 91 | |||
| 92 | static int wiimod_keys_probe(const struct wiimod_ops *ops, | ||
| 93 | struct wiimote_data *wdata) | ||
| 94 | { | ||
| 95 | unsigned int i; | ||
| 96 | |||
| 97 | set_bit(EV_KEY, wdata->input->evbit); | ||
| 98 | for (i = 0; i < WIIPROTO_KEY_COUNT; ++i) | ||
| 99 | set_bit(wiimod_keys_map[i], wdata->input->keybit); | ||
| 100 | |||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | static const struct wiimod_ops wiimod_keys = { | ||
| 105 | .flags = WIIMOD_FLAG_INPUT, | ||
| 106 | .arg = 0, | ||
| 107 | .probe = wiimod_keys_probe, | ||
| 108 | .remove = NULL, | ||
| 109 | .in_keys = wiimod_keys_in_keys, | ||
| 110 | }; | ||
| 111 | |||
| 112 | /* | ||
| 113 | * Rumble | ||
| 114 | * Nearly all devices provide a rumble feature. A small motor for | ||
| 115 | * force-feedback effects. We provide an FF_RUMBLE memless ff device on the | ||
| 116 | * shared input device if this module is loaded. | ||
| 117 | * The rumble motor is controlled via a flag on almost every output report so | ||
| 118 | * the wiimote core handles the rumble flag. But if a device doesn't provide | ||
| 119 | * the rumble motor, this flag shouldn't be set. | ||
| 120 | */ | ||
| 121 | |||
| 122 | static int wiimod_rumble_play(struct input_dev *dev, void *data, | ||
| 123 | struct ff_effect *eff) | ||
| 124 | { | ||
| 125 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 126 | __u8 value; | ||
| 127 | unsigned long flags; | ||
| 128 | |||
| 129 | /* | ||
| 130 | * The wiimote supports only a single rumble motor so if any magnitude | ||
| 131 | * is set to non-zero then we start the rumble motor. If both are set to | ||
| 132 | * zero, we stop the rumble motor. | ||
| 133 | */ | ||
| 134 | |||
| 135 | if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude) | ||
| 136 | value = 1; | ||
| 137 | else | ||
| 138 | value = 0; | ||
| 139 | |||
| 140 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 141 | wiiproto_req_rumble(wdata, value); | ||
| 142 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static int wiimod_rumble_probe(const struct wiimod_ops *ops, | ||
| 148 | struct wiimote_data *wdata) | ||
| 149 | { | ||
| 150 | set_bit(FF_RUMBLE, wdata->input->ffbit); | ||
| 151 | if (input_ff_create_memless(wdata->input, NULL, wiimod_rumble_play)) | ||
| 152 | return -ENOMEM; | ||
| 153 | |||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | |||
| 157 | static void wiimod_rumble_remove(const struct wiimod_ops *ops, | ||
| 158 | struct wiimote_data *wdata) | ||
| 159 | { | ||
| 160 | unsigned long flags; | ||
| 161 | |||
| 162 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 163 | wiiproto_req_rumble(wdata, 0); | ||
| 164 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 165 | } | ||
| 166 | |||
| 167 | static const struct wiimod_ops wiimod_rumble = { | ||
| 168 | .flags = WIIMOD_FLAG_INPUT, | ||
| 169 | .arg = 0, | ||
| 170 | .probe = wiimod_rumble_probe, | ||
| 171 | .remove = wiimod_rumble_remove, | ||
| 172 | }; | ||
| 173 | |||
| 174 | /* | ||
| 175 | * Battery | ||
| 176 | * 1 byte of battery capacity information is sent along every protocol status | ||
| 177 | * report. The wiimote core caches it but we try to update it on every | ||
| 178 | * user-space request. | ||
| 179 | * This is supported by nearly every device so it's almost always enabled. | ||
| 180 | */ | ||
| 181 | |||
| 182 | static enum power_supply_property wiimod_battery_props[] = { | ||
| 183 | POWER_SUPPLY_PROP_CAPACITY, | ||
| 184 | POWER_SUPPLY_PROP_SCOPE, | ||
| 185 | }; | ||
| 186 | |||
| 187 | static int wiimod_battery_get_property(struct power_supply *psy, | ||
| 188 | enum power_supply_property psp, | ||
| 189 | union power_supply_propval *val) | ||
| 190 | { | ||
| 191 | struct wiimote_data *wdata = container_of(psy, struct wiimote_data, | ||
| 192 | battery); | ||
| 193 | int ret = 0, state; | ||
| 194 | unsigned long flags; | ||
| 195 | |||
| 196 | if (psp == POWER_SUPPLY_PROP_SCOPE) { | ||
| 197 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | ||
| 198 | return 0; | ||
| 199 | } else if (psp != POWER_SUPPLY_PROP_CAPACITY) { | ||
| 200 | return -EINVAL; | ||
| 201 | } | ||
| 202 | |||
| 203 | ret = wiimote_cmd_acquire(wdata); | ||
| 204 | if (ret) | ||
| 205 | return ret; | ||
| 206 | |||
| 207 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 208 | wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0); | ||
| 209 | wiiproto_req_status(wdata); | ||
| 210 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 211 | |||
| 212 | wiimote_cmd_wait(wdata); | ||
| 213 | wiimote_cmd_release(wdata); | ||
| 214 | |||
| 215 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 216 | state = wdata->state.cmd_battery; | ||
| 217 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 218 | |||
| 219 | val->intval = state * 100 / 255; | ||
| 220 | return ret; | ||
| 221 | } | ||
| 222 | |||
| 223 | static int wiimod_battery_probe(const struct wiimod_ops *ops, | ||
| 224 | struct wiimote_data *wdata) | ||
| 225 | { | ||
| 226 | int ret; | ||
| 227 | |||
| 228 | wdata->battery.properties = wiimod_battery_props; | ||
| 229 | wdata->battery.num_properties = ARRAY_SIZE(wiimod_battery_props); | ||
| 230 | wdata->battery.get_property = wiimod_battery_get_property; | ||
| 231 | wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 232 | wdata->battery.use_for_apm = 0; | ||
| 233 | wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s", | ||
| 234 | wdata->hdev->uniq); | ||
| 235 | if (!wdata->battery.name) | ||
| 236 | return -ENOMEM; | ||
| 237 | |||
| 238 | ret = power_supply_register(&wdata->hdev->dev, &wdata->battery); | ||
| 239 | if (ret) { | ||
| 240 | hid_err(wdata->hdev, "cannot register battery device\n"); | ||
| 241 | goto err_free; | ||
| 242 | } | ||
| 243 | |||
| 244 | power_supply_powers(&wdata->battery, &wdata->hdev->dev); | ||
| 245 | return 0; | ||
| 246 | |||
| 247 | err_free: | ||
| 248 | kfree(wdata->battery.name); | ||
| 249 | wdata->battery.name = NULL; | ||
| 250 | return ret; | ||
| 251 | } | ||
| 252 | |||
| 253 | static void wiimod_battery_remove(const struct wiimod_ops *ops, | ||
| 254 | struct wiimote_data *wdata) | ||
| 255 | { | ||
| 256 | if (!wdata->battery.name) | ||
| 257 | return; | ||
| 258 | |||
| 259 | power_supply_unregister(&wdata->battery); | ||
| 260 | kfree(wdata->battery.name); | ||
| 261 | wdata->battery.name = NULL; | ||
| 262 | } | ||
| 263 | |||
| 264 | static const struct wiimod_ops wiimod_battery = { | ||
| 265 | .flags = 0, | ||
| 266 | .arg = 0, | ||
| 267 | .probe = wiimod_battery_probe, | ||
| 268 | .remove = wiimod_battery_remove, | ||
| 269 | }; | ||
| 270 | |||
| 271 | /* | ||
| 272 | * LED | ||
| 273 | * 0 to 4 player LEDs are supported by devices. The "arg" field of the | ||
| 274 | * wiimod_ops structure specifies which LED this module controls. This allows | ||
| 275 | * to register a limited number of LEDs. | ||
| 276 | * State is managed by wiimote core. | ||
| 277 | */ | ||
| 278 | |||
| 279 | static enum led_brightness wiimod_led_get(struct led_classdev *led_dev) | ||
| 280 | { | ||
| 281 | struct wiimote_data *wdata; | ||
| 282 | struct device *dev = led_dev->dev->parent; | ||
| 283 | int i; | ||
| 284 | unsigned long flags; | ||
| 285 | bool value = false; | ||
| 286 | |||
| 287 | wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); | ||
| 288 | |||
| 289 | for (i = 0; i < 4; ++i) { | ||
| 290 | if (wdata->leds[i] == led_dev) { | ||
| 291 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 292 | value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1); | ||
| 293 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 294 | break; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | return value ? LED_FULL : LED_OFF; | ||
| 299 | } | ||
| 300 | |||
| 301 | static void wiimod_led_set(struct led_classdev *led_dev, | ||
| 302 | enum led_brightness value) | ||
| 303 | { | ||
| 304 | struct wiimote_data *wdata; | ||
| 305 | struct device *dev = led_dev->dev->parent; | ||
| 306 | int i; | ||
| 307 | unsigned long flags; | ||
| 308 | __u8 state, flag; | ||
| 309 | |||
| 310 | wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); | ||
| 311 | |||
| 312 | for (i = 0; i < 4; ++i) { | ||
| 313 | if (wdata->leds[i] == led_dev) { | ||
| 314 | flag = WIIPROTO_FLAG_LED(i + 1); | ||
| 315 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 316 | state = wdata->state.flags; | ||
| 317 | if (value == LED_OFF) | ||
| 318 | wiiproto_req_leds(wdata, state & ~flag); | ||
| 319 | else | ||
| 320 | wiiproto_req_leds(wdata, state | flag); | ||
| 321 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 322 | break; | ||
| 323 | } | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | static int wiimod_led_probe(const struct wiimod_ops *ops, | ||
| 328 | struct wiimote_data *wdata) | ||
| 329 | { | ||
| 330 | struct device *dev = &wdata->hdev->dev; | ||
| 331 | size_t namesz = strlen(dev_name(dev)) + 9; | ||
| 332 | struct led_classdev *led; | ||
| 333 | unsigned long flags; | ||
| 334 | char *name; | ||
| 335 | int ret; | ||
| 336 | |||
| 337 | led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL); | ||
| 338 | if (!led) | ||
| 339 | return -ENOMEM; | ||
| 340 | |||
| 341 | name = (void*)&led[1]; | ||
| 342 | snprintf(name, namesz, "%s:blue:p%lu", dev_name(dev), ops->arg); | ||
| 343 | led->name = name; | ||
| 344 | led->brightness = 0; | ||
| 345 | led->max_brightness = 1; | ||
| 346 | led->brightness_get = wiimod_led_get; | ||
| 347 | led->brightness_set = wiimod_led_set; | ||
| 348 | |||
| 349 | wdata->leds[ops->arg] = led; | ||
| 350 | ret = led_classdev_register(dev, led); | ||
| 351 | if (ret) | ||
| 352 | goto err_free; | ||
| 353 | |||
| 354 | /* enable LED1 to stop initial LED-blinking */ | ||
| 355 | if (ops->arg == 0) { | ||
| 356 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 357 | wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1); | ||
| 358 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 359 | } | ||
| 360 | |||
| 361 | return 0; | ||
| 362 | |||
| 363 | err_free: | ||
| 364 | wdata->leds[ops->arg] = NULL; | ||
| 365 | kfree(led); | ||
| 366 | return ret; | ||
| 367 | } | ||
| 368 | |||
| 369 | static void wiimod_led_remove(const struct wiimod_ops *ops, | ||
| 370 | struct wiimote_data *wdata) | ||
| 371 | { | ||
| 372 | if (!wdata->leds[ops->arg]) | ||
| 373 | return; | ||
| 374 | |||
| 375 | led_classdev_unregister(wdata->leds[ops->arg]); | ||
| 376 | kfree(wdata->leds[ops->arg]); | ||
| 377 | wdata->leds[ops->arg] = NULL; | ||
| 378 | } | ||
| 379 | |||
| 380 | static const struct wiimod_ops wiimod_leds[4] = { | ||
| 381 | { | ||
| 382 | .flags = 0, | ||
| 383 | .arg = 0, | ||
| 384 | .probe = wiimod_led_probe, | ||
| 385 | .remove = wiimod_led_remove, | ||
| 386 | }, | ||
| 387 | { | ||
| 388 | .flags = 0, | ||
| 389 | .arg = 1, | ||
| 390 | .probe = wiimod_led_probe, | ||
| 391 | .remove = wiimod_led_remove, | ||
| 392 | }, | ||
| 393 | { | ||
| 394 | .flags = 0, | ||
| 395 | .arg = 2, | ||
| 396 | .probe = wiimod_led_probe, | ||
| 397 | .remove = wiimod_led_remove, | ||
| 398 | }, | ||
| 399 | { | ||
| 400 | .flags = 0, | ||
| 401 | .arg = 3, | ||
| 402 | .probe = wiimod_led_probe, | ||
| 403 | .remove = wiimod_led_remove, | ||
| 404 | }, | ||
| 405 | }; | ||
| 406 | |||
| 407 | /* | ||
| 408 | * Accelerometer | ||
| 409 | * 3 axis accelerometer data is part of nearly all DRMs. If not supported by a | ||
| 410 | * device, it's mostly cleared to 0. This module parses this data and provides | ||
| 411 | * it via a separate input device. | ||
| 412 | */ | ||
| 413 | |||
| 414 | static void wiimod_accel_in_accel(struct wiimote_data *wdata, | ||
| 415 | const __u8 *accel) | ||
| 416 | { | ||
| 417 | __u16 x, y, z; | ||
| 418 | |||
| 419 | if (!(wdata->state.flags & WIIPROTO_FLAG_ACCEL)) | ||
| 420 | return; | ||
| 421 | |||
| 422 | /* | ||
| 423 | * payload is: BB BB XX YY ZZ | ||
| 424 | * Accelerometer data is encoded into 3 10bit values. XX, YY and ZZ | ||
| 425 | * contain the upper 8 bits of each value. The lower 2 bits are | ||
| 426 | * contained in the buttons data BB BB. | ||
| 427 | * Bits 6 and 7 of the first buttons byte BB is the lower 2 bits of the | ||
| 428 | * X accel value. Bit 5 of the second buttons byte is the 2nd bit of Y | ||
| 429 | * accel value and bit 6 is the second bit of the Z value. | ||
| 430 | * The first bit of Y and Z values is not available and always set to 0. | ||
| 431 | * 0x200 is returned on no movement. | ||
| 432 | */ | ||
| 433 | |||
| 434 | x = accel[2] << 2; | ||
| 435 | y = accel[3] << 2; | ||
| 436 | z = accel[4] << 2; | ||
| 437 | |||
| 438 | x |= (accel[0] >> 5) & 0x3; | ||
| 439 | y |= (accel[1] >> 4) & 0x2; | ||
| 440 | z |= (accel[1] >> 5) & 0x2; | ||
| 441 | |||
| 442 | input_report_abs(wdata->accel, ABS_RX, x - 0x200); | ||
| 443 | input_report_abs(wdata->accel, ABS_RY, y - 0x200); | ||
| 444 | input_report_abs(wdata->accel, ABS_RZ, z - 0x200); | ||
| 445 | input_sync(wdata->accel); | ||
| 446 | } | ||
| 447 | |||
| 448 | static int wiimod_accel_open(struct input_dev *dev) | ||
| 449 | { | ||
| 450 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 451 | unsigned long flags; | ||
| 452 | |||
| 453 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 454 | wiiproto_req_accel(wdata, true); | ||
| 455 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 456 | |||
| 457 | return 0; | ||
| 458 | } | ||
| 459 | |||
| 460 | static void wiimod_accel_close(struct input_dev *dev) | ||
| 461 | { | ||
| 462 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 463 | unsigned long flags; | ||
| 464 | |||
| 465 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 466 | wiiproto_req_accel(wdata, false); | ||
| 467 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 468 | } | ||
| 469 | |||
| 470 | static int wiimod_accel_probe(const struct wiimod_ops *ops, | ||
| 471 | struct wiimote_data *wdata) | ||
| 472 | { | ||
| 473 | int ret; | ||
| 474 | |||
| 475 | wdata->accel = input_allocate_device(); | ||
| 476 | if (!wdata->accel) | ||
| 477 | return -ENOMEM; | ||
| 478 | |||
| 479 | input_set_drvdata(wdata->accel, wdata); | ||
| 480 | wdata->accel->open = wiimod_accel_open; | ||
| 481 | wdata->accel->close = wiimod_accel_close; | ||
| 482 | wdata->accel->dev.parent = &wdata->hdev->dev; | ||
| 483 | wdata->accel->id.bustype = wdata->hdev->bus; | ||
| 484 | wdata->accel->id.vendor = wdata->hdev->vendor; | ||
| 485 | wdata->accel->id.product = wdata->hdev->product; | ||
| 486 | wdata->accel->id.version = wdata->hdev->version; | ||
| 487 | wdata->accel->name = WIIMOTE_NAME " Accelerometer"; | ||
| 488 | |||
| 489 | set_bit(EV_ABS, wdata->accel->evbit); | ||
| 490 | set_bit(ABS_RX, wdata->accel->absbit); | ||
| 491 | set_bit(ABS_RY, wdata->accel->absbit); | ||
| 492 | set_bit(ABS_RZ, wdata->accel->absbit); | ||
| 493 | input_set_abs_params(wdata->accel, ABS_RX, -500, 500, 2, 4); | ||
| 494 | input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4); | ||
| 495 | input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4); | ||
| 496 | |||
| 497 | ret = input_register_device(wdata->accel); | ||
| 498 | if (ret) { | ||
| 499 | hid_err(wdata->hdev, "cannot register input device\n"); | ||
| 500 | goto err_free; | ||
| 501 | } | ||
| 502 | |||
| 503 | return 0; | ||
| 504 | |||
| 505 | err_free: | ||
| 506 | input_free_device(wdata->accel); | ||
| 507 | wdata->accel = NULL; | ||
| 508 | return ret; | ||
| 509 | } | ||
| 510 | |||
| 511 | static void wiimod_accel_remove(const struct wiimod_ops *ops, | ||
| 512 | struct wiimote_data *wdata) | ||
| 513 | { | ||
| 514 | if (!wdata->accel) | ||
| 515 | return; | ||
| 516 | |||
| 517 | input_unregister_device(wdata->accel); | ||
| 518 | wdata->accel = NULL; | ||
| 519 | } | ||
| 520 | |||
| 521 | static const struct wiimod_ops wiimod_accel = { | ||
| 522 | .flags = 0, | ||
| 523 | .arg = 0, | ||
| 524 | .probe = wiimod_accel_probe, | ||
| 525 | .remove = wiimod_accel_remove, | ||
| 526 | .in_accel = wiimod_accel_in_accel, | ||
| 527 | }; | ||
| 528 | |||
| 529 | /* | ||
| 530 | * IR Cam | ||
| 531 | * Up to 4 IR sources can be tracked by a normal Wii Remote. The IR cam needs | ||
| 532 | * to be initialized with a fairly complex procedure and consumes a lot of | ||
| 533 | * power. Therefore, as long as no application uses the IR input device, it is | ||
| 534 | * kept offline. | ||
| 535 | * Nearly no other device than the normal Wii Remotes supports the IR cam so | ||
| 536 | * you can disable this module for these devices. | ||
| 537 | */ | ||
| 538 | |||
| 539 | static void wiimod_ir_in_ir(struct wiimote_data *wdata, const __u8 *ir, | ||
| 540 | bool packed, unsigned int id) | ||
| 541 | { | ||
| 542 | __u16 x, y; | ||
| 543 | __u8 xid, yid; | ||
| 544 | bool sync = false; | ||
| 545 | |||
| 546 | if (!(wdata->state.flags & WIIPROTO_FLAGS_IR)) | ||
| 547 | return; | ||
| 548 | |||
| 549 | switch (id) { | ||
| 550 | case 0: | ||
| 551 | xid = ABS_HAT0X; | ||
| 552 | yid = ABS_HAT0Y; | ||
| 553 | break; | ||
| 554 | case 1: | ||
| 555 | xid = ABS_HAT1X; | ||
| 556 | yid = ABS_HAT1Y; | ||
| 557 | break; | ||
| 558 | case 2: | ||
| 559 | xid = ABS_HAT2X; | ||
| 560 | yid = ABS_HAT2Y; | ||
| 561 | break; | ||
| 562 | case 3: | ||
| 563 | xid = ABS_HAT3X; | ||
| 564 | yid = ABS_HAT3Y; | ||
| 565 | sync = true; | ||
| 566 | break; | ||
| 567 | default: | ||
| 568 | return; | ||
| 569 | } | ||
| 570 | |||
| 571 | /* | ||
| 572 | * Basic IR data is encoded into 3 bytes. The first two bytes are the | ||
| 573 | * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits | ||
| 574 | * of both. | ||
| 575 | * If data is packed, then the 3rd byte is put first and slightly | ||
| 576 | * reordered. This allows to interleave packed and non-packed data to | ||
| 577 | * have two IR sets in 5 bytes instead of 6. | ||
| 578 | * The resulting 10bit X/Y values are passed to the ABS_HAT? input dev. | ||
| 579 | */ | ||
| 580 | |||
| 581 | if (packed) { | ||
| 582 | x = ir[1] | ((ir[0] & 0x03) << 8); | ||
| 583 | y = ir[2] | ((ir[0] & 0x0c) << 6); | ||
| 584 | } else { | ||
| 585 | x = ir[0] | ((ir[2] & 0x30) << 4); | ||
| 586 | y = ir[1] | ((ir[2] & 0xc0) << 2); | ||
| 587 | } | ||
| 588 | |||
| 589 | input_report_abs(wdata->ir, xid, x); | ||
| 590 | input_report_abs(wdata->ir, yid, y); | ||
| 591 | |||
| 592 | if (sync) | ||
| 593 | input_sync(wdata->ir); | ||
| 594 | } | ||
| 595 | |||
| 596 | static int wiimod_ir_change(struct wiimote_data *wdata, __u16 mode) | ||
| 597 | { | ||
| 598 | int ret; | ||
| 599 | unsigned long flags; | ||
| 600 | __u8 format = 0; | ||
| 601 | static const __u8 data_enable[] = { 0x01 }; | ||
| 602 | static const __u8 data_sens1[] = { 0x02, 0x00, 0x00, 0x71, 0x01, | ||
| 603 | 0x00, 0xaa, 0x00, 0x64 }; | ||
| 604 | static const __u8 data_sens2[] = { 0x63, 0x03 }; | ||
| 605 | static const __u8 data_fin[] = { 0x08 }; | ||
| 606 | |||
| 607 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 608 | |||
| 609 | if (mode == (wdata->state.flags & WIIPROTO_FLAGS_IR)) { | ||
| 610 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 611 | return 0; | ||
| 612 | } | ||
| 613 | |||
| 614 | if (mode == 0) { | ||
| 615 | wdata->state.flags &= ~WIIPROTO_FLAGS_IR; | ||
| 616 | wiiproto_req_ir1(wdata, 0); | ||
| 617 | wiiproto_req_ir2(wdata, 0); | ||
| 618 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 619 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 620 | return 0; | ||
| 621 | } | ||
| 622 | |||
| 623 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 624 | |||
| 625 | ret = wiimote_cmd_acquire(wdata); | ||
| 626 | if (ret) | ||
| 627 | return ret; | ||
| 628 | |||
| 629 | /* send PIXEL CLOCK ENABLE cmd first */ | ||
| 630 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 631 | wiimote_cmd_set(wdata, WIIPROTO_REQ_IR1, 0); | ||
| 632 | wiiproto_req_ir1(wdata, 0x06); | ||
| 633 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 634 | |||
| 635 | ret = wiimote_cmd_wait(wdata); | ||
| 636 | if (ret) | ||
| 637 | goto unlock; | ||
| 638 | if (wdata->state.cmd_err) { | ||
| 639 | ret = -EIO; | ||
| 640 | goto unlock; | ||
| 641 | } | ||
| 642 | |||
| 643 | /* enable IR LOGIC */ | ||
| 644 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 645 | wiimote_cmd_set(wdata, WIIPROTO_REQ_IR2, 0); | ||
| 646 | wiiproto_req_ir2(wdata, 0x06); | ||
| 647 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 648 | |||
| 649 | ret = wiimote_cmd_wait(wdata); | ||
| 650 | if (ret) | ||
| 651 | goto unlock; | ||
| 652 | if (wdata->state.cmd_err) { | ||
| 653 | ret = -EIO; | ||
| 654 | goto unlock; | ||
| 655 | } | ||
| 656 | |||
| 657 | /* enable IR cam but do not make it send data, yet */ | ||
| 658 | ret = wiimote_cmd_write(wdata, 0xb00030, data_enable, | ||
| 659 | sizeof(data_enable)); | ||
| 660 | if (ret) | ||
| 661 | goto unlock; | ||
| 662 | |||
| 663 | /* write first sensitivity block */ | ||
| 664 | ret = wiimote_cmd_write(wdata, 0xb00000, data_sens1, | ||
| 665 | sizeof(data_sens1)); | ||
| 666 | if (ret) | ||
| 667 | goto unlock; | ||
| 668 | |||
| 669 | /* write second sensitivity block */ | ||
| 670 | ret = wiimote_cmd_write(wdata, 0xb0001a, data_sens2, | ||
| 671 | sizeof(data_sens2)); | ||
| 672 | if (ret) | ||
| 673 | goto unlock; | ||
| 674 | |||
| 675 | /* put IR cam into desired state */ | ||
| 676 | switch (mode) { | ||
| 677 | case WIIPROTO_FLAG_IR_FULL: | ||
| 678 | format = 5; | ||
| 679 | break; | ||
| 680 | case WIIPROTO_FLAG_IR_EXT: | ||
| 681 | format = 3; | ||
| 682 | break; | ||
| 683 | case WIIPROTO_FLAG_IR_BASIC: | ||
| 684 | format = 1; | ||
| 685 | break; | ||
| 686 | } | ||
| 687 | ret = wiimote_cmd_write(wdata, 0xb00033, &format, sizeof(format)); | ||
| 688 | if (ret) | ||
| 689 | goto unlock; | ||
| 690 | |||
| 691 | /* make IR cam send data */ | ||
| 692 | ret = wiimote_cmd_write(wdata, 0xb00030, data_fin, sizeof(data_fin)); | ||
| 693 | if (ret) | ||
| 694 | goto unlock; | ||
| 695 | |||
| 696 | /* request new DRM mode compatible to IR mode */ | ||
| 697 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 698 | wdata->state.flags &= ~WIIPROTO_FLAGS_IR; | ||
| 699 | wdata->state.flags |= mode & WIIPROTO_FLAGS_IR; | ||
| 700 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 701 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 702 | |||
| 703 | unlock: | ||
| 704 | wiimote_cmd_release(wdata); | ||
| 705 | return ret; | ||
| 706 | } | ||
| 707 | |||
| 708 | static int wiimod_ir_open(struct input_dev *dev) | ||
| 709 | { | ||
| 710 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 711 | |||
| 712 | return wiimod_ir_change(wdata, WIIPROTO_FLAG_IR_BASIC); | ||
| 713 | } | ||
| 714 | |||
| 715 | static void wiimod_ir_close(struct input_dev *dev) | ||
| 716 | { | ||
| 717 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 718 | |||
| 719 | wiimod_ir_change(wdata, 0); | ||
| 720 | } | ||
| 721 | |||
| 722 | static int wiimod_ir_probe(const struct wiimod_ops *ops, | ||
| 723 | struct wiimote_data *wdata) | ||
| 724 | { | ||
| 725 | int ret; | ||
| 726 | |||
| 727 | wdata->ir = input_allocate_device(); | ||
| 728 | if (!wdata->ir) | ||
| 729 | return -ENOMEM; | ||
| 730 | |||
| 731 | input_set_drvdata(wdata->ir, wdata); | ||
| 732 | wdata->ir->open = wiimod_ir_open; | ||
| 733 | wdata->ir->close = wiimod_ir_close; | ||
| 734 | wdata->ir->dev.parent = &wdata->hdev->dev; | ||
| 735 | wdata->ir->id.bustype = wdata->hdev->bus; | ||
| 736 | wdata->ir->id.vendor = wdata->hdev->vendor; | ||
| 737 | wdata->ir->id.product = wdata->hdev->product; | ||
| 738 | wdata->ir->id.version = wdata->hdev->version; | ||
| 739 | wdata->ir->name = WIIMOTE_NAME " IR"; | ||
| 740 | |||
| 741 | set_bit(EV_ABS, wdata->ir->evbit); | ||
| 742 | set_bit(ABS_HAT0X, wdata->ir->absbit); | ||
| 743 | set_bit(ABS_HAT0Y, wdata->ir->absbit); | ||
| 744 | set_bit(ABS_HAT1X, wdata->ir->absbit); | ||
| 745 | set_bit(ABS_HAT1Y, wdata->ir->absbit); | ||
| 746 | set_bit(ABS_HAT2X, wdata->ir->absbit); | ||
| 747 | set_bit(ABS_HAT2Y, wdata->ir->absbit); | ||
| 748 | set_bit(ABS_HAT3X, wdata->ir->absbit); | ||
| 749 | set_bit(ABS_HAT3Y, wdata->ir->absbit); | ||
| 750 | input_set_abs_params(wdata->ir, ABS_HAT0X, 0, 1023, 2, 4); | ||
| 751 | input_set_abs_params(wdata->ir, ABS_HAT0Y, 0, 767, 2, 4); | ||
| 752 | input_set_abs_params(wdata->ir, ABS_HAT1X, 0, 1023, 2, 4); | ||
| 753 | input_set_abs_params(wdata->ir, ABS_HAT1Y, 0, 767, 2, 4); | ||
| 754 | input_set_abs_params(wdata->ir, ABS_HAT2X, 0, 1023, 2, 4); | ||
| 755 | input_set_abs_params(wdata->ir, ABS_HAT2Y, 0, 767, 2, 4); | ||
| 756 | input_set_abs_params(wdata->ir, ABS_HAT3X, 0, 1023, 2, 4); | ||
| 757 | input_set_abs_params(wdata->ir, ABS_HAT3Y, 0, 767, 2, 4); | ||
| 758 | |||
| 759 | ret = input_register_device(wdata->ir); | ||
| 760 | if (ret) { | ||
| 761 | hid_err(wdata->hdev, "cannot register input device\n"); | ||
| 762 | goto err_free; | ||
| 763 | } | ||
| 764 | |||
| 765 | return 0; | ||
| 766 | |||
| 767 | err_free: | ||
| 768 | input_free_device(wdata->ir); | ||
| 769 | wdata->ir = NULL; | ||
| 770 | return ret; | ||
| 771 | } | ||
| 772 | |||
| 773 | static void wiimod_ir_remove(const struct wiimod_ops *ops, | ||
| 774 | struct wiimote_data *wdata) | ||
| 775 | { | ||
| 776 | if (!wdata->ir) | ||
| 777 | return; | ||
| 778 | |||
| 779 | input_unregister_device(wdata->ir); | ||
| 780 | wdata->ir = NULL; | ||
| 781 | } | ||
| 782 | |||
| 783 | static const struct wiimod_ops wiimod_ir = { | ||
| 784 | .flags = 0, | ||
| 785 | .arg = 0, | ||
| 786 | .probe = wiimod_ir_probe, | ||
| 787 | .remove = wiimod_ir_remove, | ||
| 788 | .in_ir = wiimod_ir_in_ir, | ||
| 789 | }; | ||
| 790 | |||
| 791 | /* | ||
| 792 | * Nunchuk Extension | ||
| 793 | * The Nintendo Wii Nunchuk was the first official extension published by | ||
| 794 | * Nintendo. It provides two additional keys and a separate accelerometer. It | ||
| 795 | * can be hotplugged to standard Wii Remotes. | ||
| 796 | */ | ||
| 797 | |||
| 798 | enum wiimod_nunchuk_keys { | ||
| 799 | WIIMOD_NUNCHUK_KEY_C, | ||
| 800 | WIIMOD_NUNCHUK_KEY_Z, | ||
| 801 | WIIMOD_NUNCHUK_KEY_NUM, | ||
| 802 | }; | ||
| 803 | |||
| 804 | static const __u16 wiimod_nunchuk_map[] = { | ||
| 805 | BTN_C, /* WIIMOD_NUNCHUK_KEY_C */ | ||
| 806 | BTN_Z, /* WIIMOD_NUNCHUK_KEY_Z */ | ||
| 807 | }; | ||
| 808 | |||
| 809 | static void wiimod_nunchuk_in_ext(struct wiimote_data *wdata, const __u8 *ext) | ||
| 810 | { | ||
| 811 | __s16 x, y, z, bx, by; | ||
| 812 | |||
| 813 | /* Byte | 8 7 | 6 5 | 4 3 | 2 | 1 | | ||
| 814 | * -----+----------+---------+---------+----+-----+ | ||
| 815 | * 1 | Button X <7:0> | | ||
| 816 | * 2 | Button Y <7:0> | | ||
| 817 | * -----+----------+---------+---------+----+-----+ | ||
| 818 | * 3 | Speed X <9:2> | | ||
| 819 | * 4 | Speed Y <9:2> | | ||
| 820 | * 5 | Speed Z <9:2> | | ||
| 821 | * -----+----------+---------+---------+----+-----+ | ||
| 822 | * 6 | Z <1:0> | Y <1:0> | X <1:0> | BC | BZ | | ||
| 823 | * -----+----------+---------+---------+----+-----+ | ||
| 824 | * Button X/Y is the analog stick. Speed X, Y and Z are the | ||
| 825 | * accelerometer data in the same format as the wiimote's accelerometer. | ||
| 826 | * The 6th byte contains the LSBs of the accelerometer data. | ||
| 827 | * BC and BZ are the C and Z buttons: 0 means pressed | ||
| 828 | * | ||
| 829 | * If reported interleaved with motionp, then the layout changes. The | ||
| 830 | * 5th and 6th byte changes to: | ||
| 831 | * -----+-----------------------------------+-----+ | ||
| 832 | * 5 | Speed Z <9:3> | EXT | | ||
| 833 | * -----+--------+-----+-----+----+----+----+-----+ | ||
| 834 | * 6 |Z <2:1> |Y <1>|X <1>| BC | BZ | 0 | 0 | | ||
| 835 | * -----+--------+-----+-----+----+----+----+-----+ | ||
| 836 | * All three accelerometer values lose their LSB. The other data is | ||
| 837 | * still available but slightly moved. | ||
| 838 | * | ||
| 839 | * Center data for button values is 128. Center value for accelerometer | ||
| 840 | * values it 512 / 0x200 | ||
| 841 | */ | ||
| 842 | |||
| 843 | bx = ext[0]; | ||
| 844 | by = ext[1]; | ||
| 845 | bx -= 128; | ||
| 846 | by -= 128; | ||
| 847 | |||
| 848 | x = ext[2] << 2; | ||
| 849 | y = ext[3] << 2; | ||
| 850 | z = ext[4] << 2; | ||
| 851 | |||
| 852 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { | ||
| 853 | x |= (ext[5] >> 3) & 0x02; | ||
| 854 | y |= (ext[5] >> 4) & 0x02; | ||
| 855 | z &= ~0x4; | ||
| 856 | z |= (ext[5] >> 5) & 0x06; | ||
| 857 | } else { | ||
| 858 | x |= (ext[5] >> 2) & 0x03; | ||
| 859 | y |= (ext[5] >> 4) & 0x03; | ||
| 860 | z |= (ext[5] >> 6) & 0x03; | ||
| 861 | } | ||
| 862 | |||
| 863 | x -= 0x200; | ||
| 864 | y -= 0x200; | ||
| 865 | z -= 0x200; | ||
| 866 | |||
| 867 | input_report_abs(wdata->extension.input, ABS_HAT0X, bx); | ||
| 868 | input_report_abs(wdata->extension.input, ABS_HAT0Y, by); | ||
| 869 | |||
| 870 | input_report_abs(wdata->extension.input, ABS_RX, x); | ||
| 871 | input_report_abs(wdata->extension.input, ABS_RY, y); | ||
| 872 | input_report_abs(wdata->extension.input, ABS_RZ, z); | ||
| 873 | |||
| 874 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { | ||
| 875 | input_report_key(wdata->extension.input, | ||
| 876 | wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z], | ||
| 877 | !(ext[5] & 0x04)); | ||
| 878 | input_report_key(wdata->extension.input, | ||
| 879 | wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C], | ||
| 880 | !(ext[5] & 0x08)); | ||
| 881 | } else { | ||
| 882 | input_report_key(wdata->extension.input, | ||
| 883 | wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z], | ||
| 884 | !(ext[5] & 0x01)); | ||
| 885 | input_report_key(wdata->extension.input, | ||
| 886 | wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C], | ||
| 887 | !(ext[5] & 0x02)); | ||
| 888 | } | ||
| 889 | |||
| 890 | input_sync(wdata->extension.input); | ||
| 891 | } | ||
| 892 | |||
| 893 | static int wiimod_nunchuk_open(struct input_dev *dev) | ||
| 894 | { | ||
| 895 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 896 | unsigned long flags; | ||
| 897 | |||
| 898 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 899 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; | ||
| 900 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 901 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 902 | |||
| 903 | return 0; | ||
| 904 | } | ||
| 905 | |||
| 906 | static void wiimod_nunchuk_close(struct input_dev *dev) | ||
| 907 | { | ||
| 908 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 909 | unsigned long flags; | ||
| 910 | |||
| 911 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 912 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; | ||
| 913 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 914 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 915 | } | ||
| 916 | |||
| 917 | static int wiimod_nunchuk_probe(const struct wiimod_ops *ops, | ||
| 918 | struct wiimote_data *wdata) | ||
| 919 | { | ||
| 920 | int ret, i; | ||
| 921 | |||
| 922 | wdata->extension.input = input_allocate_device(); | ||
| 923 | if (!wdata->extension.input) | ||
| 924 | return -ENOMEM; | ||
| 925 | |||
| 926 | input_set_drvdata(wdata->extension.input, wdata); | ||
| 927 | wdata->extension.input->open = wiimod_nunchuk_open; | ||
| 928 | wdata->extension.input->close = wiimod_nunchuk_close; | ||
| 929 | wdata->extension.input->dev.parent = &wdata->hdev->dev; | ||
| 930 | wdata->extension.input->id.bustype = wdata->hdev->bus; | ||
| 931 | wdata->extension.input->id.vendor = wdata->hdev->vendor; | ||
| 932 | wdata->extension.input->id.product = wdata->hdev->product; | ||
| 933 | wdata->extension.input->id.version = wdata->hdev->version; | ||
| 934 | wdata->extension.input->name = WIIMOTE_NAME " Nunchuk"; | ||
| 935 | |||
| 936 | set_bit(EV_KEY, wdata->extension.input->evbit); | ||
| 937 | for (i = 0; i < WIIMOD_NUNCHUK_KEY_NUM; ++i) | ||
| 938 | set_bit(wiimod_nunchuk_map[i], | ||
| 939 | wdata->extension.input->keybit); | ||
| 940 | |||
| 941 | set_bit(EV_ABS, wdata->extension.input->evbit); | ||
| 942 | set_bit(ABS_HAT0X, wdata->extension.input->absbit); | ||
| 943 | set_bit(ABS_HAT0Y, wdata->extension.input->absbit); | ||
| 944 | input_set_abs_params(wdata->extension.input, | ||
| 945 | ABS_HAT0X, -120, 120, 2, 4); | ||
| 946 | input_set_abs_params(wdata->extension.input, | ||
| 947 | ABS_HAT0Y, -120, 120, 2, 4); | ||
| 948 | set_bit(ABS_RX, wdata->extension.input->absbit); | ||
| 949 | set_bit(ABS_RY, wdata->extension.input->absbit); | ||
| 950 | set_bit(ABS_RZ, wdata->extension.input->absbit); | ||
| 951 | input_set_abs_params(wdata->extension.input, | ||
| 952 | ABS_RX, -500, 500, 2, 4); | ||
| 953 | input_set_abs_params(wdata->extension.input, | ||
| 954 | ABS_RY, -500, 500, 2, 4); | ||
| 955 | input_set_abs_params(wdata->extension.input, | ||
| 956 | ABS_RZ, -500, 500, 2, 4); | ||
| 957 | |||
| 958 | ret = input_register_device(wdata->extension.input); | ||
| 959 | if (ret) | ||
| 960 | goto err_free; | ||
| 961 | |||
| 962 | return 0; | ||
| 963 | |||
| 964 | err_free: | ||
| 965 | input_free_device(wdata->extension.input); | ||
| 966 | wdata->extension.input = NULL; | ||
| 967 | return ret; | ||
| 968 | } | ||
| 969 | |||
| 970 | static void wiimod_nunchuk_remove(const struct wiimod_ops *ops, | ||
| 971 | struct wiimote_data *wdata) | ||
| 972 | { | ||
| 973 | if (!wdata->extension.input) | ||
| 974 | return; | ||
| 975 | |||
| 976 | input_unregister_device(wdata->extension.input); | ||
| 977 | wdata->extension.input = NULL; | ||
| 978 | } | ||
| 979 | |||
| 980 | static const struct wiimod_ops wiimod_nunchuk = { | ||
| 981 | .flags = 0, | ||
| 982 | .arg = 0, | ||
| 983 | .probe = wiimod_nunchuk_probe, | ||
| 984 | .remove = wiimod_nunchuk_remove, | ||
| 985 | .in_ext = wiimod_nunchuk_in_ext, | ||
| 986 | }; | ||
| 987 | |||
| 988 | /* | ||
| 989 | * Classic Controller | ||
| 990 | * Another official extension from Nintendo. It provides a classic | ||
| 991 | * gamecube-like controller that can be hotplugged on the Wii Remote. | ||
| 992 | * It has several hardware buttons and switches that are all reported via | ||
| 993 | * a normal extension device. | ||
| 994 | */ | ||
| 995 | |||
| 996 | enum wiimod_classic_keys { | ||
| 997 | WIIMOD_CLASSIC_KEY_A, | ||
| 998 | WIIMOD_CLASSIC_KEY_B, | ||
| 999 | WIIMOD_CLASSIC_KEY_X, | ||
| 1000 | WIIMOD_CLASSIC_KEY_Y, | ||
| 1001 | WIIMOD_CLASSIC_KEY_ZL, | ||
| 1002 | WIIMOD_CLASSIC_KEY_ZR, | ||
| 1003 | WIIMOD_CLASSIC_KEY_PLUS, | ||
| 1004 | WIIMOD_CLASSIC_KEY_MINUS, | ||
| 1005 | WIIMOD_CLASSIC_KEY_HOME, | ||
| 1006 | WIIMOD_CLASSIC_KEY_LEFT, | ||
| 1007 | WIIMOD_CLASSIC_KEY_RIGHT, | ||
| 1008 | WIIMOD_CLASSIC_KEY_UP, | ||
| 1009 | WIIMOD_CLASSIC_KEY_DOWN, | ||
| 1010 | WIIMOD_CLASSIC_KEY_LT, | ||
| 1011 | WIIMOD_CLASSIC_KEY_RT, | ||
| 1012 | WIIMOD_CLASSIC_KEY_NUM, | ||
| 1013 | }; | ||
| 1014 | |||
| 1015 | static const __u16 wiimod_classic_map[] = { | ||
| 1016 | BTN_A, /* WIIMOD_CLASSIC_KEY_A */ | ||
| 1017 | BTN_B, /* WIIMOD_CLASSIC_KEY_B */ | ||
| 1018 | BTN_X, /* WIIMOD_CLASSIC_KEY_X */ | ||
| 1019 | BTN_Y, /* WIIMOD_CLASSIC_KEY_Y */ | ||
| 1020 | BTN_TL2, /* WIIMOD_CLASSIC_KEY_ZL */ | ||
| 1021 | BTN_TR2, /* WIIMOD_CLASSIC_KEY_ZR */ | ||
| 1022 | KEY_NEXT, /* WIIMOD_CLASSIC_KEY_PLUS */ | ||
| 1023 | KEY_PREVIOUS, /* WIIMOD_CLASSIC_KEY_MINUS */ | ||
| 1024 | BTN_MODE, /* WIIMOD_CLASSIC_KEY_HOME */ | ||
| 1025 | KEY_LEFT, /* WIIMOD_CLASSIC_KEY_LEFT */ | ||
| 1026 | KEY_RIGHT, /* WIIMOD_CLASSIC_KEY_RIGHT */ | ||
| 1027 | KEY_UP, /* WIIMOD_CLASSIC_KEY_UP */ | ||
| 1028 | KEY_DOWN, /* WIIMOD_CLASSIC_KEY_DOWN */ | ||
| 1029 | BTN_TL, /* WIIMOD_CLASSIC_KEY_LT */ | ||
| 1030 | BTN_TR, /* WIIMOD_CLASSIC_KEY_RT */ | ||
| 1031 | }; | ||
| 1032 | |||
| 1033 | static void wiimod_classic_in_ext(struct wiimote_data *wdata, const __u8 *ext) | ||
| 1034 | { | ||
| 1035 | __s8 rx, ry, lx, ly, lt, rt; | ||
| 1036 | |||
| 1037 | /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ||
| 1038 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1039 | * 1 | RX <5:4> | LX <5:0> | | ||
| 1040 | * 2 | RX <3:2> | LY <5:0> | | ||
| 1041 | * -----+-----+-----+-----+-----------------------------+ | ||
| 1042 | * 3 |RX<1>| LT <5:4> | RY <5:1> | | ||
| 1043 | * -----+-----+-----------+-----------------------------+ | ||
| 1044 | * 4 | LT <3:1> | RT <5:1> | | ||
| 1045 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1046 | * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 | | ||
| 1047 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1048 | * 6 | BZL | BB | BY | BA | BX | BZR | BDL | BDU | | ||
| 1049 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1050 | * All buttons are 0 if pressed | ||
| 1051 | * RX and RY are right analog stick | ||
| 1052 | * LX and LY are left analog stick | ||
| 1053 | * LT is left trigger, RT is right trigger | ||
| 1054 | * BLT is 0 if left trigger is fully pressed | ||
| 1055 | * BRT is 0 if right trigger is fully pressed | ||
| 1056 | * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons | ||
| 1057 | * BZL is left Z button and BZR is right Z button | ||
| 1058 | * B-, BH, B+ are +, HOME and - buttons | ||
| 1059 | * BB, BY, BA, BX are A, B, X, Y buttons | ||
| 1060 | * LSB of RX, RY, LT, and RT are not transmitted and always 0. | ||
| 1061 | * | ||
| 1062 | * With motionp enabled it changes slightly to this: | ||
| 1063 | * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ||
| 1064 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1065 | * 1 | RX <5:4> | LX <5:1> | BDU | | ||
| 1066 | * 2 | RX <3:2> | LY <5:1> | BDL | | ||
| 1067 | * -----+-----+-----+-----+-----------------------+-----+ | ||
| 1068 | * 3 |RX<1>| LT <5:4> | RY <5:1> | | ||
| 1069 | * -----+-----+-----------+-----------------------------+ | ||
| 1070 | * 4 | LT <3:1> | RT <5:1> | | ||
| 1071 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1072 | * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | EXT | | ||
| 1073 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1074 | * 6 | BZL | BB | BY | BA | BX | BZR | 0 | 0 | | ||
| 1075 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1076 | * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest | ||
| 1077 | * is the same as before. | ||
| 1078 | */ | ||
| 1079 | |||
| 1080 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { | ||
| 1081 | lx = ext[0] & 0x3e; | ||
| 1082 | ly = ext[1] & 0x3e; | ||
| 1083 | } else { | ||
| 1084 | lx = ext[0] & 0x3f; | ||
| 1085 | ly = ext[1] & 0x3f; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | rx = (ext[0] >> 3) & 0x18; | ||
| 1089 | rx |= (ext[1] >> 5) & 0x06; | ||
| 1090 | rx |= (ext[2] >> 7) & 0x01; | ||
| 1091 | ry = ext[2] & 0x1f; | ||
| 1092 | |||
| 1093 | rt = ext[3] & 0x1f; | ||
| 1094 | lt = (ext[2] >> 2) & 0x18; | ||
| 1095 | lt |= (ext[3] >> 5) & 0x07; | ||
| 1096 | |||
| 1097 | rx <<= 1; | ||
| 1098 | ry <<= 1; | ||
| 1099 | rt <<= 1; | ||
| 1100 | lt <<= 1; | ||
| 1101 | |||
| 1102 | input_report_abs(wdata->extension.input, ABS_HAT1X, lx - 0x20); | ||
| 1103 | input_report_abs(wdata->extension.input, ABS_HAT1Y, ly - 0x20); | ||
| 1104 | input_report_abs(wdata->extension.input, ABS_HAT2X, rx - 0x20); | ||
| 1105 | input_report_abs(wdata->extension.input, ABS_HAT2Y, ry - 0x20); | ||
| 1106 | input_report_abs(wdata->extension.input, ABS_HAT3X, rt); | ||
| 1107 | input_report_abs(wdata->extension.input, ABS_HAT3Y, lt); | ||
| 1108 | |||
| 1109 | input_report_key(wdata->extension.input, | ||
| 1110 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_RIGHT], | ||
| 1111 | !(ext[4] & 0x80)); | ||
| 1112 | input_report_key(wdata->extension.input, | ||
| 1113 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_DOWN], | ||
| 1114 | !(ext[4] & 0x40)); | ||
| 1115 | input_report_key(wdata->extension.input, | ||
| 1116 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_LT], | ||
| 1117 | !(ext[4] & 0x20)); | ||
| 1118 | input_report_key(wdata->extension.input, | ||
| 1119 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_MINUS], | ||
| 1120 | !(ext[4] & 0x10)); | ||
| 1121 | input_report_key(wdata->extension.input, | ||
| 1122 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_HOME], | ||
| 1123 | !(ext[4] & 0x08)); | ||
| 1124 | input_report_key(wdata->extension.input, | ||
| 1125 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_PLUS], | ||
| 1126 | !(ext[4] & 0x04)); | ||
| 1127 | input_report_key(wdata->extension.input, | ||
| 1128 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_RT], | ||
| 1129 | !(ext[4] & 0x02)); | ||
| 1130 | input_report_key(wdata->extension.input, | ||
| 1131 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZL], | ||
| 1132 | !(ext[5] & 0x80)); | ||
| 1133 | input_report_key(wdata->extension.input, | ||
| 1134 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_B], | ||
| 1135 | !(ext[5] & 0x40)); | ||
| 1136 | input_report_key(wdata->extension.input, | ||
| 1137 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_Y], | ||
| 1138 | !(ext[5] & 0x20)); | ||
| 1139 | input_report_key(wdata->extension.input, | ||
| 1140 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_A], | ||
| 1141 | !(ext[5] & 0x10)); | ||
| 1142 | input_report_key(wdata->extension.input, | ||
| 1143 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_X], | ||
| 1144 | !(ext[5] & 0x08)); | ||
| 1145 | input_report_key(wdata->extension.input, | ||
| 1146 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZR], | ||
| 1147 | !(ext[5] & 0x04)); | ||
| 1148 | |||
| 1149 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { | ||
| 1150 | input_report_key(wdata->extension.input, | ||
| 1151 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT], | ||
| 1152 | !(ext[1] & 0x01)); | ||
| 1153 | input_report_key(wdata->extension.input, | ||
| 1154 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP], | ||
| 1155 | !(ext[0] & 0x01)); | ||
| 1156 | } else { | ||
| 1157 | input_report_key(wdata->extension.input, | ||
| 1158 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT], | ||
| 1159 | !(ext[5] & 0x02)); | ||
| 1160 | input_report_key(wdata->extension.input, | ||
| 1161 | wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP], | ||
| 1162 | !(ext[5] & 0x01)); | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | input_sync(wdata->extension.input); | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | static int wiimod_classic_open(struct input_dev *dev) | ||
| 1169 | { | ||
| 1170 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1171 | unsigned long flags; | ||
| 1172 | |||
| 1173 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1174 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; | ||
| 1175 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 1176 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1177 | |||
| 1178 | return 0; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | static void wiimod_classic_close(struct input_dev *dev) | ||
| 1182 | { | ||
| 1183 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1184 | unsigned long flags; | ||
| 1185 | |||
| 1186 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1187 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; | ||
| 1188 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 1189 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | static int wiimod_classic_probe(const struct wiimod_ops *ops, | ||
| 1193 | struct wiimote_data *wdata) | ||
| 1194 | { | ||
| 1195 | int ret, i; | ||
| 1196 | |||
| 1197 | wdata->extension.input = input_allocate_device(); | ||
| 1198 | if (!wdata->extension.input) | ||
| 1199 | return -ENOMEM; | ||
| 1200 | |||
| 1201 | input_set_drvdata(wdata->extension.input, wdata); | ||
| 1202 | wdata->extension.input->open = wiimod_classic_open; | ||
| 1203 | wdata->extension.input->close = wiimod_classic_close; | ||
| 1204 | wdata->extension.input->dev.parent = &wdata->hdev->dev; | ||
| 1205 | wdata->extension.input->id.bustype = wdata->hdev->bus; | ||
| 1206 | wdata->extension.input->id.vendor = wdata->hdev->vendor; | ||
| 1207 | wdata->extension.input->id.product = wdata->hdev->product; | ||
| 1208 | wdata->extension.input->id.version = wdata->hdev->version; | ||
| 1209 | wdata->extension.input->name = WIIMOTE_NAME " Classic Controller"; | ||
| 1210 | |||
| 1211 | set_bit(EV_KEY, wdata->extension.input->evbit); | ||
| 1212 | for (i = 0; i < WIIMOD_CLASSIC_KEY_NUM; ++i) | ||
| 1213 | set_bit(wiimod_classic_map[i], | ||
| 1214 | wdata->extension.input->keybit); | ||
| 1215 | |||
| 1216 | set_bit(EV_ABS, wdata->extension.input->evbit); | ||
| 1217 | set_bit(ABS_HAT1X, wdata->extension.input->absbit); | ||
| 1218 | set_bit(ABS_HAT1Y, wdata->extension.input->absbit); | ||
| 1219 | set_bit(ABS_HAT2X, wdata->extension.input->absbit); | ||
| 1220 | set_bit(ABS_HAT2Y, wdata->extension.input->absbit); | ||
| 1221 | set_bit(ABS_HAT3X, wdata->extension.input->absbit); | ||
| 1222 | set_bit(ABS_HAT3Y, wdata->extension.input->absbit); | ||
| 1223 | input_set_abs_params(wdata->extension.input, | ||
| 1224 | ABS_HAT1X, -30, 30, 1, 1); | ||
| 1225 | input_set_abs_params(wdata->extension.input, | ||
| 1226 | ABS_HAT1Y, -30, 30, 1, 1); | ||
| 1227 | input_set_abs_params(wdata->extension.input, | ||
| 1228 | ABS_HAT2X, -30, 30, 1, 1); | ||
| 1229 | input_set_abs_params(wdata->extension.input, | ||
| 1230 | ABS_HAT2Y, -30, 30, 1, 1); | ||
| 1231 | input_set_abs_params(wdata->extension.input, | ||
| 1232 | ABS_HAT3X, -30, 30, 1, 1); | ||
| 1233 | input_set_abs_params(wdata->extension.input, | ||
| 1234 | ABS_HAT3Y, -30, 30, 1, 1); | ||
| 1235 | |||
| 1236 | ret = input_register_device(wdata->extension.input); | ||
| 1237 | if (ret) | ||
| 1238 | goto err_free; | ||
| 1239 | |||
| 1240 | return 0; | ||
| 1241 | |||
| 1242 | err_free: | ||
| 1243 | input_free_device(wdata->extension.input); | ||
| 1244 | wdata->extension.input = NULL; | ||
| 1245 | return ret; | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | static void wiimod_classic_remove(const struct wiimod_ops *ops, | ||
| 1249 | struct wiimote_data *wdata) | ||
| 1250 | { | ||
| 1251 | if (!wdata->extension.input) | ||
| 1252 | return; | ||
| 1253 | |||
| 1254 | input_unregister_device(wdata->extension.input); | ||
| 1255 | wdata->extension.input = NULL; | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | static const struct wiimod_ops wiimod_classic = { | ||
| 1259 | .flags = 0, | ||
| 1260 | .arg = 0, | ||
| 1261 | .probe = wiimod_classic_probe, | ||
| 1262 | .remove = wiimod_classic_remove, | ||
| 1263 | .in_ext = wiimod_classic_in_ext, | ||
| 1264 | }; | ||
| 1265 | |||
| 1266 | /* | ||
| 1267 | * Balance Board Extension | ||
| 1268 | * The Nintendo Wii Balance Board provides four hardware weight sensor plus a | ||
| 1269 | * single push button. No other peripherals are available. However, the | ||
| 1270 | * balance-board data is sent via a standard Wii Remote extension. All other | ||
| 1271 | * data for non-present hardware is zeroed out. | ||
| 1272 | * Some 3rd party devices react allergic if we try to access normal Wii Remote | ||
| 1273 | * hardware, so this extension module should be the only module that is loaded | ||
| 1274 | * on balance boards. | ||
| 1275 | * The balance board needs 8 bytes extension data instead of basic 6 bytes so | ||
| 1276 | * it needs the WIIMOD_FLAG_EXT8 flag. | ||
| 1277 | */ | ||
| 1278 | |||
| 1279 | static void wiimod_bboard_in_keys(struct wiimote_data *wdata, const __u8 *keys) | ||
| 1280 | { | ||
| 1281 | input_report_key(wdata->extension.input, BTN_A, | ||
| 1282 | !!(keys[1] & 0x08)); | ||
| 1283 | input_sync(wdata->extension.input); | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | static void wiimod_bboard_in_ext(struct wiimote_data *wdata, | ||
| 1287 | const __u8 *ext) | ||
| 1288 | { | ||
| 1289 | __s32 val[4], tmp, div; | ||
| 1290 | unsigned int i; | ||
| 1291 | struct wiimote_state *s = &wdata->state; | ||
| 1292 | |||
| 1293 | /* | ||
| 1294 | * Balance board data layout: | ||
| 1295 | * | ||
| 1296 | * Byte | 8 7 6 5 4 3 2 1 | | ||
| 1297 | * -----+--------------------------+ | ||
| 1298 | * 1 | Top Right <15:8> | | ||
| 1299 | * 2 | Top Right <7:0> | | ||
| 1300 | * -----+--------------------------+ | ||
| 1301 | * 3 | Bottom Right <15:8> | | ||
| 1302 | * 4 | Bottom Right <7:0> | | ||
| 1303 | * -----+--------------------------+ | ||
| 1304 | * 5 | Top Left <15:8> | | ||
| 1305 | * 6 | Top Left <7:0> | | ||
| 1306 | * -----+--------------------------+ | ||
| 1307 | * 7 | Bottom Left <15:8> | | ||
| 1308 | * 8 | Bottom Left <7:0> | | ||
| 1309 | * -----+--------------------------+ | ||
| 1310 | * | ||
| 1311 | * These values represent the weight-measurements of the Wii-balance | ||
| 1312 | * board with 16bit precision. | ||
| 1313 | * | ||
| 1314 | * The balance-board is never reported interleaved with motionp. | ||
| 1315 | */ | ||
| 1316 | |||
| 1317 | val[0] = ext[0]; | ||
| 1318 | val[0] <<= 8; | ||
| 1319 | val[0] |= ext[1]; | ||
| 1320 | |||
| 1321 | val[1] = ext[2]; | ||
| 1322 | val[1] <<= 8; | ||
| 1323 | val[1] |= ext[3]; | ||
| 1324 | |||
| 1325 | val[2] = ext[4]; | ||
| 1326 | val[2] <<= 8; | ||
| 1327 | val[2] |= ext[5]; | ||
| 1328 | |||
| 1329 | val[3] = ext[6]; | ||
| 1330 | val[3] <<= 8; | ||
| 1331 | val[3] |= ext[7]; | ||
| 1332 | |||
| 1333 | /* apply calibration data */ | ||
| 1334 | for (i = 0; i < 4; i++) { | ||
| 1335 | if (val[i] <= s->calib_bboard[i][0]) { | ||
| 1336 | tmp = 0; | ||
| 1337 | } else if (val[i] < s->calib_bboard[i][1]) { | ||
| 1338 | tmp = val[i] - s->calib_bboard[i][0]; | ||
| 1339 | tmp *= 1700; | ||
| 1340 | div = s->calib_bboard[i][1] - s->calib_bboard[i][0]; | ||
| 1341 | tmp /= div ? div : 1; | ||
| 1342 | } else { | ||
| 1343 | tmp = val[i] - s->calib_bboard[i][1]; | ||
| 1344 | tmp *= 1700; | ||
| 1345 | div = s->calib_bboard[i][2] - s->calib_bboard[i][1]; | ||
| 1346 | tmp /= div ? div : 1; | ||
| 1347 | tmp += 1700; | ||
| 1348 | } | ||
| 1349 | val[i] = tmp; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | input_report_abs(wdata->extension.input, ABS_HAT0X, val[0]); | ||
| 1353 | input_report_abs(wdata->extension.input, ABS_HAT0Y, val[1]); | ||
| 1354 | input_report_abs(wdata->extension.input, ABS_HAT1X, val[2]); | ||
| 1355 | input_report_abs(wdata->extension.input, ABS_HAT1Y, val[3]); | ||
| 1356 | input_sync(wdata->extension.input); | ||
| 1357 | } | ||
| 1358 | |||
| 1359 | static int wiimod_bboard_open(struct input_dev *dev) | ||
| 1360 | { | ||
| 1361 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1362 | unsigned long flags; | ||
| 1363 | |||
| 1364 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1365 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; | ||
| 1366 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 1367 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1368 | |||
| 1369 | return 0; | ||
| 1370 | } | ||
| 1371 | |||
| 1372 | static void wiimod_bboard_close(struct input_dev *dev) | ||
| 1373 | { | ||
| 1374 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1375 | unsigned long flags; | ||
| 1376 | |||
| 1377 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1378 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; | ||
| 1379 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 1380 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | static ssize_t wiimod_bboard_calib_show(struct device *dev, | ||
| 1384 | struct device_attribute *attr, | ||
| 1385 | char *out) | ||
| 1386 | { | ||
| 1387 | struct wiimote_data *wdata = dev_to_wii(dev); | ||
| 1388 | int i, j, ret; | ||
| 1389 | __u16 val; | ||
| 1390 | __u8 buf[24], offs; | ||
| 1391 | |||
| 1392 | ret = wiimote_cmd_acquire(wdata); | ||
| 1393 | if (ret) | ||
| 1394 | return ret; | ||
| 1395 | |||
| 1396 | ret = wiimote_cmd_read(wdata, 0xa40024, buf, 12); | ||
| 1397 | if (ret != 12) { | ||
| 1398 | wiimote_cmd_release(wdata); | ||
| 1399 | return ret < 0 ? ret : -EIO; | ||
| 1400 | } | ||
| 1401 | ret = wiimote_cmd_read(wdata, 0xa40024 + 12, buf + 12, 12); | ||
| 1402 | if (ret != 12) { | ||
| 1403 | wiimote_cmd_release(wdata); | ||
| 1404 | return ret < 0 ? ret : -EIO; | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | wiimote_cmd_release(wdata); | ||
| 1408 | |||
| 1409 | spin_lock_irq(&wdata->state.lock); | ||
| 1410 | offs = 0; | ||
| 1411 | for (i = 0; i < 3; ++i) { | ||
| 1412 | for (j = 0; j < 4; ++j) { | ||
| 1413 | wdata->state.calib_bboard[j][i] = buf[offs]; | ||
| 1414 | wdata->state.calib_bboard[j][i] <<= 8; | ||
| 1415 | wdata->state.calib_bboard[j][i] |= buf[offs + 1]; | ||
| 1416 | offs += 2; | ||
| 1417 | } | ||
| 1418 | } | ||
| 1419 | spin_unlock_irq(&wdata->state.lock); | ||
| 1420 | |||
| 1421 | ret = 0; | ||
| 1422 | for (i = 0; i < 3; ++i) { | ||
| 1423 | for (j = 0; j < 4; ++j) { | ||
| 1424 | val = wdata->state.calib_bboard[j][i]; | ||
| 1425 | if (i == 2 && j == 3) | ||
| 1426 | ret += sprintf(&out[ret], "%04x\n", val); | ||
| 1427 | else | ||
| 1428 | ret += sprintf(&out[ret], "%04x:", val); | ||
| 1429 | } | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | return ret; | ||
| 1433 | } | ||
| 1434 | |||
| 1435 | static DEVICE_ATTR(bboard_calib, S_IRUGO, wiimod_bboard_calib_show, NULL); | ||
| 1436 | |||
| 1437 | static int wiimod_bboard_probe(const struct wiimod_ops *ops, | ||
| 1438 | struct wiimote_data *wdata) | ||
| 1439 | { | ||
| 1440 | int ret, i, j; | ||
| 1441 | __u8 buf[24], offs; | ||
| 1442 | |||
| 1443 | wiimote_cmd_acquire_noint(wdata); | ||
| 1444 | |||
| 1445 | ret = wiimote_cmd_read(wdata, 0xa40024, buf, 12); | ||
| 1446 | if (ret != 12) { | ||
| 1447 | wiimote_cmd_release(wdata); | ||
| 1448 | return ret < 0 ? ret : -EIO; | ||
| 1449 | } | ||
| 1450 | ret = wiimote_cmd_read(wdata, 0xa40024 + 12, buf + 12, 12); | ||
| 1451 | if (ret != 12) { | ||
| 1452 | wiimote_cmd_release(wdata); | ||
| 1453 | return ret < 0 ? ret : -EIO; | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | wiimote_cmd_release(wdata); | ||
| 1457 | |||
| 1458 | offs = 0; | ||
| 1459 | for (i = 0; i < 3; ++i) { | ||
| 1460 | for (j = 0; j < 4; ++j) { | ||
| 1461 | wdata->state.calib_bboard[j][i] = buf[offs]; | ||
| 1462 | wdata->state.calib_bboard[j][i] <<= 8; | ||
| 1463 | wdata->state.calib_bboard[j][i] |= buf[offs + 1]; | ||
| 1464 | offs += 2; | ||
| 1465 | } | ||
| 1466 | } | ||
| 1467 | |||
| 1468 | wdata->extension.input = input_allocate_device(); | ||
| 1469 | if (!wdata->extension.input) | ||
| 1470 | return -ENOMEM; | ||
| 1471 | |||
| 1472 | ret = device_create_file(&wdata->hdev->dev, | ||
| 1473 | &dev_attr_bboard_calib); | ||
| 1474 | if (ret) { | ||
| 1475 | hid_err(wdata->hdev, "cannot create sysfs attribute\n"); | ||
| 1476 | goto err_free; | ||
| 1477 | } | ||
| 1478 | |||
| 1479 | input_set_drvdata(wdata->extension.input, wdata); | ||
| 1480 | wdata->extension.input->open = wiimod_bboard_open; | ||
| 1481 | wdata->extension.input->close = wiimod_bboard_close; | ||
| 1482 | wdata->extension.input->dev.parent = &wdata->hdev->dev; | ||
| 1483 | wdata->extension.input->id.bustype = wdata->hdev->bus; | ||
| 1484 | wdata->extension.input->id.vendor = wdata->hdev->vendor; | ||
| 1485 | wdata->extension.input->id.product = wdata->hdev->product; | ||
| 1486 | wdata->extension.input->id.version = wdata->hdev->version; | ||
| 1487 | wdata->extension.input->name = WIIMOTE_NAME " Balance Board"; | ||
| 1488 | |||
| 1489 | set_bit(EV_KEY, wdata->extension.input->evbit); | ||
| 1490 | set_bit(BTN_A, wdata->extension.input->keybit); | ||
| 1491 | |||
| 1492 | set_bit(EV_ABS, wdata->extension.input->evbit); | ||
| 1493 | set_bit(ABS_HAT0X, wdata->extension.input->absbit); | ||
| 1494 | set_bit(ABS_HAT0Y, wdata->extension.input->absbit); | ||
| 1495 | set_bit(ABS_HAT1X, wdata->extension.input->absbit); | ||
| 1496 | set_bit(ABS_HAT1Y, wdata->extension.input->absbit); | ||
| 1497 | input_set_abs_params(wdata->extension.input, | ||
| 1498 | ABS_HAT0X, 0, 65535, 2, 4); | ||
| 1499 | input_set_abs_params(wdata->extension.input, | ||
| 1500 | ABS_HAT0Y, 0, 65535, 2, 4); | ||
| 1501 | input_set_abs_params(wdata->extension.input, | ||
| 1502 | ABS_HAT1X, 0, 65535, 2, 4); | ||
| 1503 | input_set_abs_params(wdata->extension.input, | ||
| 1504 | ABS_HAT1Y, 0, 65535, 2, 4); | ||
| 1505 | |||
| 1506 | ret = input_register_device(wdata->extension.input); | ||
| 1507 | if (ret) | ||
| 1508 | goto err_file; | ||
| 1509 | |||
| 1510 | return 0; | ||
| 1511 | |||
| 1512 | err_file: | ||
| 1513 | device_remove_file(&wdata->hdev->dev, | ||
| 1514 | &dev_attr_bboard_calib); | ||
| 1515 | err_free: | ||
| 1516 | input_free_device(wdata->extension.input); | ||
| 1517 | wdata->extension.input = NULL; | ||
| 1518 | return ret; | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | static void wiimod_bboard_remove(const struct wiimod_ops *ops, | ||
| 1522 | struct wiimote_data *wdata) | ||
| 1523 | { | ||
| 1524 | if (!wdata->extension.input) | ||
| 1525 | return; | ||
| 1526 | |||
| 1527 | input_unregister_device(wdata->extension.input); | ||
| 1528 | wdata->extension.input = NULL; | ||
| 1529 | device_remove_file(&wdata->hdev->dev, | ||
| 1530 | &dev_attr_bboard_calib); | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | static const struct wiimod_ops wiimod_bboard = { | ||
| 1534 | .flags = WIIMOD_FLAG_EXT8, | ||
| 1535 | .arg = 0, | ||
| 1536 | .probe = wiimod_bboard_probe, | ||
| 1537 | .remove = wiimod_bboard_remove, | ||
| 1538 | .in_keys = wiimod_bboard_in_keys, | ||
| 1539 | .in_ext = wiimod_bboard_in_ext, | ||
| 1540 | }; | ||
| 1541 | |||
| 1542 | /* | ||
| 1543 | * Pro Controller | ||
| 1544 | * Released with the Wii U was the Nintendo Wii U Pro Controller. It does not | ||
| 1545 | * work together with the classic Wii, but only with the new Wii U. However, it | ||
| 1546 | * uses the same protocol and provides a builtin "classic controller pro" | ||
| 1547 | * extension, few standard buttons, a rumble motor, 4 LEDs and a battery. | ||
| 1548 | * We provide all these via a standard extension device as the device doesn't | ||
| 1549 | * feature an extension port. | ||
| 1550 | */ | ||
| 1551 | |||
| 1552 | enum wiimod_pro_keys { | ||
| 1553 | WIIMOD_PRO_KEY_A, | ||
| 1554 | WIIMOD_PRO_KEY_B, | ||
| 1555 | WIIMOD_PRO_KEY_X, | ||
| 1556 | WIIMOD_PRO_KEY_Y, | ||
| 1557 | WIIMOD_PRO_KEY_PLUS, | ||
| 1558 | WIIMOD_PRO_KEY_MINUS, | ||
| 1559 | WIIMOD_PRO_KEY_HOME, | ||
| 1560 | WIIMOD_PRO_KEY_LEFT, | ||
| 1561 | WIIMOD_PRO_KEY_RIGHT, | ||
| 1562 | WIIMOD_PRO_KEY_UP, | ||
| 1563 | WIIMOD_PRO_KEY_DOWN, | ||
| 1564 | WIIMOD_PRO_KEY_TL, | ||
| 1565 | WIIMOD_PRO_KEY_TR, | ||
| 1566 | WIIMOD_PRO_KEY_ZL, | ||
| 1567 | WIIMOD_PRO_KEY_ZR, | ||
| 1568 | WIIMOD_PRO_KEY_THUMBL, | ||
| 1569 | WIIMOD_PRO_KEY_THUMBR, | ||
| 1570 | WIIMOD_PRO_KEY_NUM, | ||
| 1571 | }; | ||
| 1572 | |||
| 1573 | static const __u16 wiimod_pro_map[] = { | ||
| 1574 | BTN_EAST, /* WIIMOD_PRO_KEY_A */ | ||
| 1575 | BTN_SOUTH, /* WIIMOD_PRO_KEY_B */ | ||
| 1576 | BTN_NORTH, /* WIIMOD_PRO_KEY_X */ | ||
| 1577 | BTN_WEST, /* WIIMOD_PRO_KEY_Y */ | ||
| 1578 | BTN_START, /* WIIMOD_PRO_KEY_PLUS */ | ||
| 1579 | BTN_SELECT, /* WIIMOD_PRO_KEY_MINUS */ | ||
| 1580 | BTN_MODE, /* WIIMOD_PRO_KEY_HOME */ | ||
| 1581 | BTN_DPAD_LEFT, /* WIIMOD_PRO_KEY_LEFT */ | ||
| 1582 | BTN_DPAD_RIGHT, /* WIIMOD_PRO_KEY_RIGHT */ | ||
| 1583 | BTN_DPAD_UP, /* WIIMOD_PRO_KEY_UP */ | ||
| 1584 | BTN_DPAD_DOWN, /* WIIMOD_PRO_KEY_DOWN */ | ||
| 1585 | BTN_TL, /* WIIMOD_PRO_KEY_TL */ | ||
| 1586 | BTN_TR, /* WIIMOD_PRO_KEY_TR */ | ||
| 1587 | BTN_TL2, /* WIIMOD_PRO_KEY_ZL */ | ||
| 1588 | BTN_TR2, /* WIIMOD_PRO_KEY_ZR */ | ||
| 1589 | BTN_THUMBL, /* WIIMOD_PRO_KEY_THUMBL */ | ||
| 1590 | BTN_THUMBR, /* WIIMOD_PRO_KEY_THUMBR */ | ||
| 1591 | }; | ||
| 1592 | |||
| 1593 | static void wiimod_pro_in_ext(struct wiimote_data *wdata, const __u8 *ext) | ||
| 1594 | { | ||
| 1595 | __s16 rx, ry, lx, ly; | ||
| 1596 | |||
| 1597 | /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | ||
| 1598 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1599 | * 1 | LX <7:0> | | ||
| 1600 | * -----+-----------------------+-----------------------+ | ||
| 1601 | * 2 | 0 0 0 0 | LX <11:8> | | ||
| 1602 | * -----+-----------------------+-----------------------+ | ||
| 1603 | * 3 | RX <7:0> | | ||
| 1604 | * -----+-----------------------+-----------------------+ | ||
| 1605 | * 4 | 0 0 0 0 | RX <11:8> | | ||
| 1606 | * -----+-----------------------+-----------------------+ | ||
| 1607 | * 5 | LY <7:0> | | ||
| 1608 | * -----+-----------------------+-----------------------+ | ||
| 1609 | * 6 | 0 0 0 0 | LY <11:8> | | ||
| 1610 | * -----+-----------------------+-----------------------+ | ||
| 1611 | * 7 | RY <7:0> | | ||
| 1612 | * -----+-----------------------+-----------------------+ | ||
| 1613 | * 8 | 0 0 0 0 | RY <11:8> | | ||
| 1614 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1615 | * 9 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 | | ||
| 1616 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1617 | * 10 | BZL | BB | BY | BA | BX | BZR | BDL | BDU | | ||
| 1618 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ | ||
| 1619 | * 11 | 1 | BATTERY | USB |CHARG|LTHUM|RTHUM| | ||
| 1620 | * -----+-----+-----------------+-----------+-----+-----+ | ||
| 1621 | * All buttons are low-active (0 if pressed) | ||
| 1622 | * RX and RY are right analog stick | ||
| 1623 | * LX and LY are left analog stick | ||
| 1624 | * BLT is left trigger, BRT is right trigger. | ||
| 1625 | * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons | ||
| 1626 | * BZL is left Z button and BZR is right Z button | ||
| 1627 | * B-, BH, B+ are +, HOME and - buttons | ||
| 1628 | * BB, BY, BA, BX are A, B, X, Y buttons | ||
| 1629 | * | ||
| 1630 | * Bits marked as 0/1 are unknown and never changed during tests. | ||
| 1631 | * | ||
| 1632 | * Not entirely verified: | ||
| 1633 | * CHARG: 1 if uncharging, 0 if charging | ||
| 1634 | * USB: 1 if not connected, 0 if connected | ||
| 1635 | * BATTERY: battery capacity from 000 (empty) to 100 (full) | ||
| 1636 | */ | ||
| 1637 | |||
| 1638 | lx = (ext[0] & 0xff) | ((ext[1] & 0x0f) << 8); | ||
| 1639 | rx = (ext[2] & 0xff) | ((ext[3] & 0x0f) << 8); | ||
| 1640 | ly = (ext[4] & 0xff) | ((ext[5] & 0x0f) << 8); | ||
| 1641 | ry = (ext[6] & 0xff) | ((ext[7] & 0x0f) << 8); | ||
| 1642 | |||
| 1643 | input_report_abs(wdata->extension.input, ABS_X, lx - 0x800); | ||
| 1644 | input_report_abs(wdata->extension.input, ABS_Y, ly - 0x800); | ||
| 1645 | input_report_abs(wdata->extension.input, ABS_RX, rx - 0x800); | ||
| 1646 | input_report_abs(wdata->extension.input, ABS_RY, ry - 0x800); | ||
| 1647 | |||
| 1648 | input_report_key(wdata->extension.input, | ||
| 1649 | wiimod_pro_map[WIIMOD_PRO_KEY_RIGHT], | ||
| 1650 | !(ext[8] & 0x80)); | ||
| 1651 | input_report_key(wdata->extension.input, | ||
| 1652 | wiimod_pro_map[WIIMOD_PRO_KEY_DOWN], | ||
| 1653 | !(ext[8] & 0x40)); | ||
| 1654 | input_report_key(wdata->extension.input, | ||
| 1655 | wiimod_pro_map[WIIMOD_PRO_KEY_TL], | ||
| 1656 | !(ext[8] & 0x20)); | ||
| 1657 | input_report_key(wdata->extension.input, | ||
| 1658 | wiimod_pro_map[WIIMOD_PRO_KEY_MINUS], | ||
| 1659 | !(ext[8] & 0x10)); | ||
| 1660 | input_report_key(wdata->extension.input, | ||
| 1661 | wiimod_pro_map[WIIMOD_PRO_KEY_HOME], | ||
| 1662 | !(ext[8] & 0x08)); | ||
| 1663 | input_report_key(wdata->extension.input, | ||
| 1664 | wiimod_pro_map[WIIMOD_PRO_KEY_PLUS], | ||
| 1665 | !(ext[8] & 0x04)); | ||
| 1666 | input_report_key(wdata->extension.input, | ||
| 1667 | wiimod_pro_map[WIIMOD_PRO_KEY_TR], | ||
| 1668 | !(ext[8] & 0x02)); | ||
| 1669 | |||
| 1670 | input_report_key(wdata->extension.input, | ||
| 1671 | wiimod_pro_map[WIIMOD_PRO_KEY_ZL], | ||
| 1672 | !(ext[9] & 0x80)); | ||
| 1673 | input_report_key(wdata->extension.input, | ||
| 1674 | wiimod_pro_map[WIIMOD_PRO_KEY_B], | ||
| 1675 | !(ext[9] & 0x40)); | ||
| 1676 | input_report_key(wdata->extension.input, | ||
| 1677 | wiimod_pro_map[WIIMOD_PRO_KEY_Y], | ||
| 1678 | !(ext[9] & 0x20)); | ||
| 1679 | input_report_key(wdata->extension.input, | ||
| 1680 | wiimod_pro_map[WIIMOD_PRO_KEY_A], | ||
| 1681 | !(ext[9] & 0x10)); | ||
| 1682 | input_report_key(wdata->extension.input, | ||
| 1683 | wiimod_pro_map[WIIMOD_PRO_KEY_X], | ||
| 1684 | !(ext[9] & 0x08)); | ||
| 1685 | input_report_key(wdata->extension.input, | ||
| 1686 | wiimod_pro_map[WIIMOD_PRO_KEY_ZR], | ||
| 1687 | !(ext[9] & 0x04)); | ||
| 1688 | input_report_key(wdata->extension.input, | ||
| 1689 | wiimod_pro_map[WIIMOD_PRO_KEY_LEFT], | ||
| 1690 | !(ext[9] & 0x02)); | ||
| 1691 | input_report_key(wdata->extension.input, | ||
| 1692 | wiimod_pro_map[WIIMOD_PRO_KEY_UP], | ||
| 1693 | !(ext[9] & 0x01)); | ||
| 1694 | |||
| 1695 | input_report_key(wdata->extension.input, | ||
| 1696 | wiimod_pro_map[WIIMOD_PRO_KEY_THUMBL], | ||
| 1697 | !(ext[10] & 0x02)); | ||
| 1698 | input_report_key(wdata->extension.input, | ||
| 1699 | wiimod_pro_map[WIIMOD_PRO_KEY_THUMBR], | ||
| 1700 | !(ext[10] & 0x01)); | ||
| 1701 | |||
| 1702 | input_sync(wdata->extension.input); | ||
| 1703 | } | ||
| 1704 | |||
| 1705 | static int wiimod_pro_open(struct input_dev *dev) | ||
| 1706 | { | ||
| 1707 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1708 | unsigned long flags; | ||
| 1709 | |||
| 1710 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1711 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; | ||
| 1712 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 1713 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1714 | |||
| 1715 | return 0; | ||
| 1716 | } | ||
| 1717 | |||
| 1718 | static void wiimod_pro_close(struct input_dev *dev) | ||
| 1719 | { | ||
| 1720 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1721 | unsigned long flags; | ||
| 1722 | |||
| 1723 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1724 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; | ||
| 1725 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 1726 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | static int wiimod_pro_play(struct input_dev *dev, void *data, | ||
| 1730 | struct ff_effect *eff) | ||
| 1731 | { | ||
| 1732 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1733 | __u8 value; | ||
| 1734 | unsigned long flags; | ||
| 1735 | |||
| 1736 | /* | ||
| 1737 | * The wiimote supports only a single rumble motor so if any magnitude | ||
| 1738 | * is set to non-zero then we start the rumble motor. If both are set to | ||
| 1739 | * zero, we stop the rumble motor. | ||
| 1740 | */ | ||
| 1741 | |||
| 1742 | if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude) | ||
| 1743 | value = 1; | ||
| 1744 | else | ||
| 1745 | value = 0; | ||
| 1746 | |||
| 1747 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1748 | wiiproto_req_rumble(wdata, value); | ||
| 1749 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1750 | |||
| 1751 | return 0; | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | static int wiimod_pro_probe(const struct wiimod_ops *ops, | ||
| 1755 | struct wiimote_data *wdata) | ||
| 1756 | { | ||
| 1757 | int ret, i; | ||
| 1758 | |||
| 1759 | wdata->extension.input = input_allocate_device(); | ||
| 1760 | if (!wdata->extension.input) | ||
| 1761 | return -ENOMEM; | ||
| 1762 | |||
| 1763 | set_bit(FF_RUMBLE, wdata->extension.input->ffbit); | ||
| 1764 | input_set_drvdata(wdata->extension.input, wdata); | ||
| 1765 | |||
| 1766 | if (input_ff_create_memless(wdata->extension.input, NULL, | ||
| 1767 | wiimod_pro_play)) { | ||
| 1768 | ret = -ENOMEM; | ||
| 1769 | goto err_free; | ||
| 1770 | } | ||
| 1771 | |||
| 1772 | wdata->extension.input->open = wiimod_pro_open; | ||
| 1773 | wdata->extension.input->close = wiimod_pro_close; | ||
| 1774 | wdata->extension.input->dev.parent = &wdata->hdev->dev; | ||
| 1775 | wdata->extension.input->id.bustype = wdata->hdev->bus; | ||
| 1776 | wdata->extension.input->id.vendor = wdata->hdev->vendor; | ||
| 1777 | wdata->extension.input->id.product = wdata->hdev->product; | ||
| 1778 | wdata->extension.input->id.version = wdata->hdev->version; | ||
| 1779 | wdata->extension.input->name = WIIMOTE_NAME " Pro Controller"; | ||
| 1780 | |||
| 1781 | set_bit(EV_KEY, wdata->extension.input->evbit); | ||
| 1782 | for (i = 0; i < WIIMOD_PRO_KEY_NUM; ++i) | ||
| 1783 | set_bit(wiimod_pro_map[i], | ||
| 1784 | wdata->extension.input->keybit); | ||
| 1785 | |||
| 1786 | set_bit(EV_ABS, wdata->extension.input->evbit); | ||
| 1787 | set_bit(ABS_X, wdata->extension.input->absbit); | ||
| 1788 | set_bit(ABS_Y, wdata->extension.input->absbit); | ||
| 1789 | set_bit(ABS_RX, wdata->extension.input->absbit); | ||
| 1790 | set_bit(ABS_RY, wdata->extension.input->absbit); | ||
| 1791 | input_set_abs_params(wdata->extension.input, | ||
| 1792 | ABS_X, -0x800, 0x800, 2, 4); | ||
| 1793 | input_set_abs_params(wdata->extension.input, | ||
| 1794 | ABS_Y, -0x800, 0x800, 2, 4); | ||
| 1795 | input_set_abs_params(wdata->extension.input, | ||
| 1796 | ABS_RX, -0x800, 0x800, 2, 4); | ||
| 1797 | input_set_abs_params(wdata->extension.input, | ||
| 1798 | ABS_RY, -0x800, 0x800, 2, 4); | ||
| 1799 | |||
| 1800 | ret = input_register_device(wdata->extension.input); | ||
| 1801 | if (ret) | ||
| 1802 | goto err_free; | ||
| 1803 | |||
| 1804 | return 0; | ||
| 1805 | |||
| 1806 | err_free: | ||
| 1807 | input_free_device(wdata->extension.input); | ||
| 1808 | wdata->extension.input = NULL; | ||
| 1809 | return ret; | ||
| 1810 | } | ||
| 1811 | |||
| 1812 | static void wiimod_pro_remove(const struct wiimod_ops *ops, | ||
| 1813 | struct wiimote_data *wdata) | ||
| 1814 | { | ||
| 1815 | unsigned long flags; | ||
| 1816 | |||
| 1817 | if (!wdata->extension.input) | ||
| 1818 | return; | ||
| 1819 | |||
| 1820 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1821 | wiiproto_req_rumble(wdata, 0); | ||
| 1822 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1823 | |||
| 1824 | input_unregister_device(wdata->extension.input); | ||
| 1825 | wdata->extension.input = NULL; | ||
| 1826 | } | ||
| 1827 | |||
| 1828 | static const struct wiimod_ops wiimod_pro = { | ||
| 1829 | .flags = WIIMOD_FLAG_EXT16, | ||
| 1830 | .arg = 0, | ||
| 1831 | .probe = wiimod_pro_probe, | ||
| 1832 | .remove = wiimod_pro_remove, | ||
| 1833 | .in_ext = wiimod_pro_in_ext, | ||
| 1834 | }; | ||
| 1835 | |||
| 1836 | /* | ||
| 1837 | * Builtin Motion Plus | ||
| 1838 | * This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which | ||
| 1839 | * disables polling for Motion-Plus. This should be set only for devices which | ||
| 1840 | * don't allow MP hotplugging. | ||
| 1841 | */ | ||
| 1842 | |||
| 1843 | static int wiimod_builtin_mp_probe(const struct wiimod_ops *ops, | ||
| 1844 | struct wiimote_data *wdata) | ||
| 1845 | { | ||
| 1846 | unsigned long flags; | ||
| 1847 | |||
| 1848 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1849 | wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP; | ||
| 1850 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1851 | |||
| 1852 | return 0; | ||
| 1853 | } | ||
| 1854 | |||
| 1855 | static void wiimod_builtin_mp_remove(const struct wiimod_ops *ops, | ||
| 1856 | struct wiimote_data *wdata) | ||
| 1857 | { | ||
| 1858 | unsigned long flags; | ||
| 1859 | |||
| 1860 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1861 | wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP; | ||
| 1862 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1863 | } | ||
| 1864 | |||
| 1865 | static const struct wiimod_ops wiimod_builtin_mp = { | ||
| 1866 | .flags = 0, | ||
| 1867 | .arg = 0, | ||
| 1868 | .probe = wiimod_builtin_mp_probe, | ||
| 1869 | .remove = wiimod_builtin_mp_remove, | ||
| 1870 | }; | ||
| 1871 | |||
| 1872 | /* | ||
| 1873 | * No Motion Plus | ||
| 1874 | * This module simply sets the WIIPROTO_FLAG_NO_MP protocol flag which | ||
| 1875 | * disables motion-plus. This is needed for devices that advertise this but we | ||
| 1876 | * don't know how to use it (or whether it is actually present). | ||
| 1877 | */ | ||
| 1878 | |||
| 1879 | static int wiimod_no_mp_probe(const struct wiimod_ops *ops, | ||
| 1880 | struct wiimote_data *wdata) | ||
| 1881 | { | ||
| 1882 | unsigned long flags; | ||
| 1883 | |||
| 1884 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1885 | wdata->state.flags |= WIIPROTO_FLAG_NO_MP; | ||
| 1886 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1887 | |||
| 1888 | return 0; | ||
| 1889 | } | ||
| 1890 | |||
| 1891 | static void wiimod_no_mp_remove(const struct wiimod_ops *ops, | ||
| 1892 | struct wiimote_data *wdata) | ||
| 1893 | { | ||
| 1894 | unsigned long flags; | ||
| 1895 | |||
| 1896 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1897 | wdata->state.flags |= WIIPROTO_FLAG_NO_MP; | ||
| 1898 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | static const struct wiimod_ops wiimod_no_mp = { | ||
| 1902 | .flags = 0, | ||
| 1903 | .arg = 0, | ||
| 1904 | .probe = wiimod_no_mp_probe, | ||
| 1905 | .remove = wiimod_no_mp_remove, | ||
| 1906 | }; | ||
| 1907 | |||
| 1908 | /* | ||
| 1909 | * Motion Plus | ||
| 1910 | * The Motion Plus extension provides rotation sensors (gyro) as a small | ||
| 1911 | * extension device for Wii Remotes. Many devices have them built-in so | ||
| 1912 | * you cannot see them from the outside. | ||
| 1913 | * Motion Plus extensions are special because they are on a separate extension | ||
| 1914 | * port and allow other extensions to be used simultaneously. This is all | ||
| 1915 | * handled by the Wiimote Core so we don't have to deal with it. | ||
| 1916 | */ | ||
| 1917 | |||
| 1918 | static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext) | ||
| 1919 | { | ||
| 1920 | __s32 x, y, z; | ||
| 1921 | |||
| 1922 | /* | 8 7 6 5 4 3 | 2 | 1 | | ||
| 1923 | * -----+------------------------------+-----+-----+ | ||
| 1924 | * 1 | Yaw Speed <7:0> | | ||
| 1925 | * 2 | Roll Speed <7:0> | | ||
| 1926 | * 3 | Pitch Speed <7:0> | | ||
| 1927 | * -----+------------------------------+-----+-----+ | ||
| 1928 | * 4 | Yaw Speed <13:8> | Yaw |Pitch| | ||
| 1929 | * -----+------------------------------+-----+-----+ | ||
| 1930 | * 5 | Roll Speed <13:8> |Roll | Ext | | ||
| 1931 | * -----+------------------------------+-----+-----+ | ||
| 1932 | * 6 | Pitch Speed <13:8> | 1 | 0 | | ||
| 1933 | * -----+------------------------------+-----+-----+ | ||
| 1934 | * The single bits Yaw, Roll, Pitch in the lower right corner specify | ||
| 1935 | * whether the wiimote is rotating fast (0) or slow (1). Speed for slow | ||
| 1936 | * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a | ||
| 1937 | * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast | ||
| 1938 | * and 9 for slow. | ||
| 1939 | * If the wiimote is not rotating the sensor reports 2^13 = 8192. | ||
| 1940 | * Ext specifies whether an extension is connected to the motionp. | ||
| 1941 | * which is parsed by wiimote-core. | ||
| 1942 | */ | ||
| 1943 | |||
| 1944 | x = ext[0]; | ||
| 1945 | y = ext[1]; | ||
| 1946 | z = ext[2]; | ||
| 1947 | |||
| 1948 | x |= (((__u16)ext[3]) << 6) & 0xff00; | ||
| 1949 | y |= (((__u16)ext[4]) << 6) & 0xff00; | ||
| 1950 | z |= (((__u16)ext[5]) << 6) & 0xff00; | ||
| 1951 | |||
| 1952 | x -= 8192; | ||
| 1953 | y -= 8192; | ||
| 1954 | z -= 8192; | ||
| 1955 | |||
| 1956 | if (!(ext[3] & 0x02)) | ||
| 1957 | x *= 18; | ||
| 1958 | else | ||
| 1959 | x *= 9; | ||
| 1960 | if (!(ext[4] & 0x02)) | ||
| 1961 | y *= 18; | ||
| 1962 | else | ||
| 1963 | y *= 9; | ||
| 1964 | if (!(ext[3] & 0x01)) | ||
| 1965 | z *= 18; | ||
| 1966 | else | ||
| 1967 | z *= 9; | ||
| 1968 | |||
| 1969 | input_report_abs(wdata->mp, ABS_RX, x); | ||
| 1970 | input_report_abs(wdata->mp, ABS_RY, y); | ||
| 1971 | input_report_abs(wdata->mp, ABS_RZ, z); | ||
| 1972 | input_sync(wdata->mp); | ||
| 1973 | } | ||
| 1974 | |||
| 1975 | static int wiimod_mp_open(struct input_dev *dev) | ||
| 1976 | { | ||
| 1977 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1978 | unsigned long flags; | ||
| 1979 | |||
| 1980 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1981 | wdata->state.flags |= WIIPROTO_FLAG_MP_USED; | ||
| 1982 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 1983 | __wiimote_schedule(wdata); | ||
| 1984 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1985 | |||
| 1986 | return 0; | ||
| 1987 | } | ||
| 1988 | |||
| 1989 | static void wiimod_mp_close(struct input_dev *dev) | ||
| 1990 | { | ||
| 1991 | struct wiimote_data *wdata = input_get_drvdata(dev); | ||
| 1992 | unsigned long flags; | ||
| 1993 | |||
| 1994 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1995 | wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED; | ||
| 1996 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | ||
| 1997 | __wiimote_schedule(wdata); | ||
| 1998 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1999 | } | ||
| 2000 | |||
| 2001 | static int wiimod_mp_probe(const struct wiimod_ops *ops, | ||
| 2002 | struct wiimote_data *wdata) | ||
| 2003 | { | ||
| 2004 | int ret; | ||
| 2005 | |||
| 2006 | wdata->mp = input_allocate_device(); | ||
| 2007 | if (!wdata->mp) | ||
| 2008 | return -ENOMEM; | ||
| 2009 | |||
| 2010 | input_set_drvdata(wdata->mp, wdata); | ||
| 2011 | wdata->mp->open = wiimod_mp_open; | ||
| 2012 | wdata->mp->close = wiimod_mp_close; | ||
| 2013 | wdata->mp->dev.parent = &wdata->hdev->dev; | ||
| 2014 | wdata->mp->id.bustype = wdata->hdev->bus; | ||
| 2015 | wdata->mp->id.vendor = wdata->hdev->vendor; | ||
| 2016 | wdata->mp->id.product = wdata->hdev->product; | ||
| 2017 | wdata->mp->id.version = wdata->hdev->version; | ||
| 2018 | wdata->mp->name = WIIMOTE_NAME " Motion Plus"; | ||
| 2019 | |||
| 2020 | set_bit(EV_ABS, wdata->mp->evbit); | ||
| 2021 | set_bit(ABS_RX, wdata->mp->absbit); | ||
| 2022 | set_bit(ABS_RY, wdata->mp->absbit); | ||
| 2023 | set_bit(ABS_RZ, wdata->mp->absbit); | ||
| 2024 | input_set_abs_params(wdata->mp, | ||
| 2025 | ABS_RX, -16000, 16000, 4, 8); | ||
| 2026 | input_set_abs_params(wdata->mp, | ||
| 2027 | ABS_RY, -16000, 16000, 4, 8); | ||
| 2028 | input_set_abs_params(wdata->mp, | ||
| 2029 | ABS_RZ, -16000, 16000, 4, 8); | ||
| 2030 | |||
| 2031 | ret = input_register_device(wdata->mp); | ||
| 2032 | if (ret) | ||
| 2033 | goto err_free; | ||
| 2034 | |||
| 2035 | return 0; | ||
| 2036 | |||
| 2037 | err_free: | ||
| 2038 | input_free_device(wdata->mp); | ||
| 2039 | wdata->mp = NULL; | ||
| 2040 | return ret; | ||
| 2041 | } | ||
| 2042 | |||
| 2043 | static void wiimod_mp_remove(const struct wiimod_ops *ops, | ||
| 2044 | struct wiimote_data *wdata) | ||
| 2045 | { | ||
| 2046 | if (!wdata->mp) | ||
| 2047 | return; | ||
| 2048 | |||
| 2049 | input_unregister_device(wdata->mp); | ||
| 2050 | wdata->mp = NULL; | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | const struct wiimod_ops wiimod_mp = { | ||
| 2054 | .flags = 0, | ||
| 2055 | .arg = 0, | ||
| 2056 | .probe = wiimod_mp_probe, | ||
| 2057 | .remove = wiimod_mp_remove, | ||
| 2058 | .in_mp = wiimod_mp_in_mp, | ||
| 2059 | }; | ||
| 2060 | |||
| 2061 | /* module table */ | ||
| 2062 | |||
| 2063 | static const struct wiimod_ops wiimod_dummy; | ||
| 2064 | |||
| 2065 | const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { | ||
| 2066 | [WIIMOD_KEYS] = &wiimod_keys, | ||
| 2067 | [WIIMOD_RUMBLE] = &wiimod_rumble, | ||
| 2068 | [WIIMOD_BATTERY] = &wiimod_battery, | ||
| 2069 | [WIIMOD_LED1] = &wiimod_leds[0], | ||
| 2070 | [WIIMOD_LED2] = &wiimod_leds[1], | ||
| 2071 | [WIIMOD_LED3] = &wiimod_leds[2], | ||
| 2072 | [WIIMOD_LED4] = &wiimod_leds[3], | ||
| 2073 | [WIIMOD_ACCEL] = &wiimod_accel, | ||
| 2074 | [WIIMOD_IR] = &wiimod_ir, | ||
| 2075 | [WIIMOD_BUILTIN_MP] = &wiimod_builtin_mp, | ||
| 2076 | [WIIMOD_NO_MP] = &wiimod_no_mp, | ||
| 2077 | }; | ||
| 2078 | |||
| 2079 | const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = { | ||
| 2080 | [WIIMOTE_EXT_NONE] = &wiimod_dummy, | ||
| 2081 | [WIIMOTE_EXT_UNKNOWN] = &wiimod_dummy, | ||
| 2082 | [WIIMOTE_EXT_NUNCHUK] = &wiimod_nunchuk, | ||
| 2083 | [WIIMOTE_EXT_CLASSIC_CONTROLLER] = &wiimod_classic, | ||
| 2084 | [WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard, | ||
| 2085 | [WIIMOTE_EXT_PRO_CONTROLLER] = &wiimod_pro, | ||
| 2086 | }; | ||
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index c81dbeb086c5..f1474f372c0b 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | #define __HID_WIIMOTE_H | 2 | #define __HID_WIIMOTE_H |
| 3 | 3 | ||
| 4 | /* | 4 | /* |
| 5 | * HID driver for Nintendo Wiimote devices | 5 | * HID driver for Nintendo Wii / Wii U peripherals |
| 6 | * Copyright (c) 2011 David Herrmann | 6 | * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com> |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | /* | 9 | /* |
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
| 23 | #include <linux/power_supply.h> | 23 | #include <linux/power_supply.h> |
| 24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
| 25 | #include <linux/timer.h> | ||
| 25 | 26 | ||
| 26 | #define WIIMOTE_NAME "Nintendo Wii Remote" | 27 | #define WIIMOTE_NAME "Nintendo Wii Remote" |
| 27 | #define WIIMOTE_BUFSIZE 32 | 28 | #define WIIMOTE_BUFSIZE 32 |
| @@ -35,6 +36,17 @@ | |||
| 35 | #define WIIPROTO_FLAG_IR_BASIC 0x40 | 36 | #define WIIPROTO_FLAG_IR_BASIC 0x40 |
| 36 | #define WIIPROTO_FLAG_IR_EXT 0x80 | 37 | #define WIIPROTO_FLAG_IR_EXT 0x80 |
| 37 | #define WIIPROTO_FLAG_IR_FULL 0xc0 /* IR_BASIC | IR_EXT */ | 38 | #define WIIPROTO_FLAG_IR_FULL 0xc0 /* IR_BASIC | IR_EXT */ |
| 39 | #define WIIPROTO_FLAG_EXT_PLUGGED 0x0100 | ||
| 40 | #define WIIPROTO_FLAG_EXT_USED 0x0200 | ||
| 41 | #define WIIPROTO_FLAG_EXT_ACTIVE 0x0400 | ||
| 42 | #define WIIPROTO_FLAG_MP_PLUGGED 0x0800 | ||
| 43 | #define WIIPROTO_FLAG_MP_USED 0x1000 | ||
| 44 | #define WIIPROTO_FLAG_MP_ACTIVE 0x2000 | ||
| 45 | #define WIIPROTO_FLAG_EXITING 0x4000 | ||
| 46 | #define WIIPROTO_FLAG_DRM_LOCKED 0x8000 | ||
| 47 | #define WIIPROTO_FLAG_BUILTIN_MP 0x010000 | ||
| 48 | #define WIIPROTO_FLAG_NO_MP 0x020000 | ||
| 49 | |||
| 38 | #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ | 50 | #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ |
| 39 | WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) | 51 | WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) |
| 40 | #define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \ | 52 | #define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \ |
| @@ -43,16 +55,71 @@ | |||
| 43 | /* return flag for led \num */ | 55 | /* return flag for led \num */ |
| 44 | #define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1)) | 56 | #define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1)) |
| 45 | 57 | ||
| 58 | enum wiiproto_keys { | ||
| 59 | WIIPROTO_KEY_LEFT, | ||
| 60 | WIIPROTO_KEY_RIGHT, | ||
| 61 | WIIPROTO_KEY_UP, | ||
| 62 | WIIPROTO_KEY_DOWN, | ||
| 63 | WIIPROTO_KEY_PLUS, | ||
| 64 | WIIPROTO_KEY_MINUS, | ||
| 65 | WIIPROTO_KEY_ONE, | ||
| 66 | WIIPROTO_KEY_TWO, | ||
| 67 | WIIPROTO_KEY_A, | ||
| 68 | WIIPROTO_KEY_B, | ||
| 69 | WIIPROTO_KEY_HOME, | ||
| 70 | WIIPROTO_KEY_COUNT | ||
| 71 | }; | ||
| 72 | |||
| 73 | enum wiimote_devtype { | ||
| 74 | WIIMOTE_DEV_PENDING, | ||
| 75 | WIIMOTE_DEV_UNKNOWN, | ||
| 76 | WIIMOTE_DEV_GENERIC, | ||
| 77 | WIIMOTE_DEV_GEN10, | ||
| 78 | WIIMOTE_DEV_GEN20, | ||
| 79 | WIIMOTE_DEV_BALANCE_BOARD, | ||
| 80 | WIIMOTE_DEV_PRO_CONTROLLER, | ||
| 81 | WIIMOTE_DEV_NUM, | ||
| 82 | }; | ||
| 83 | |||
| 84 | enum wiimote_exttype { | ||
| 85 | WIIMOTE_EXT_NONE, | ||
| 86 | WIIMOTE_EXT_UNKNOWN, | ||
| 87 | WIIMOTE_EXT_NUNCHUK, | ||
| 88 | WIIMOTE_EXT_CLASSIC_CONTROLLER, | ||
| 89 | WIIMOTE_EXT_BALANCE_BOARD, | ||
| 90 | WIIMOTE_EXT_PRO_CONTROLLER, | ||
| 91 | WIIMOTE_EXT_NUM, | ||
| 92 | }; | ||
| 93 | |||
| 94 | enum wiimote_mptype { | ||
| 95 | WIIMOTE_MP_NONE, | ||
| 96 | WIIMOTE_MP_UNKNOWN, | ||
| 97 | WIIMOTE_MP_SINGLE, | ||
| 98 | WIIMOTE_MP_PASSTHROUGH_NUNCHUK, | ||
| 99 | WIIMOTE_MP_PASSTHROUGH_CLASSIC, | ||
| 100 | }; | ||
| 101 | |||
| 46 | struct wiimote_buf { | 102 | struct wiimote_buf { |
| 47 | __u8 data[HID_MAX_BUFFER_SIZE]; | 103 | __u8 data[HID_MAX_BUFFER_SIZE]; |
| 48 | size_t size; | 104 | size_t size; |
| 49 | }; | 105 | }; |
| 50 | 106 | ||
| 107 | struct wiimote_queue { | ||
| 108 | spinlock_t lock; | ||
| 109 | struct work_struct worker; | ||
| 110 | __u8 head; | ||
| 111 | __u8 tail; | ||
| 112 | struct wiimote_buf outq[WIIMOTE_BUFSIZE]; | ||
| 113 | }; | ||
| 114 | |||
| 51 | struct wiimote_state { | 115 | struct wiimote_state { |
| 52 | spinlock_t lock; | 116 | spinlock_t lock; |
| 53 | __u8 flags; | 117 | __u32 flags; |
| 54 | __u8 accel_split[2]; | 118 | __u8 accel_split[2]; |
| 55 | __u8 drm; | 119 | __u8 drm; |
| 120 | __u8 devtype; | ||
| 121 | __u8 exttype; | ||
| 122 | __u8 mp; | ||
| 56 | 123 | ||
| 57 | /* synchronous cmd requests */ | 124 | /* synchronous cmd requests */ |
| 58 | struct mutex sync; | 125 | struct mutex sync; |
| @@ -65,6 +132,9 @@ struct wiimote_state { | |||
| 65 | __u8 cmd_err; | 132 | __u8 cmd_err; |
| 66 | __u8 *cmd_read_buf; | 133 | __u8 *cmd_read_buf; |
| 67 | __u8 cmd_read_size; | 134 | __u8 cmd_read_size; |
| 135 | |||
| 136 | /* calibration data */ | ||
| 137 | __u16 calib_bboard[4][3]; | ||
| 68 | }; | 138 | }; |
| 69 | 139 | ||
| 70 | struct wiimote_data { | 140 | struct wiimote_data { |
| @@ -74,18 +144,63 @@ struct wiimote_data { | |||
| 74 | struct input_dev *accel; | 144 | struct input_dev *accel; |
| 75 | struct input_dev *ir; | 145 | struct input_dev *ir; |
| 76 | struct power_supply battery; | 146 | struct power_supply battery; |
| 77 | struct wiimote_ext *ext; | 147 | struct input_dev *mp; |
| 148 | struct timer_list timer; | ||
| 78 | struct wiimote_debug *debug; | 149 | struct wiimote_debug *debug; |
| 79 | 150 | ||
| 80 | spinlock_t qlock; | 151 | union { |
| 81 | __u8 head; | 152 | struct input_dev *input; |
| 82 | __u8 tail; | 153 | } extension; |
| 83 | struct wiimote_buf outq[WIIMOTE_BUFSIZE]; | ||
| 84 | struct work_struct worker; | ||
| 85 | 154 | ||
| 155 | struct wiimote_queue queue; | ||
| 86 | struct wiimote_state state; | 156 | struct wiimote_state state; |
| 157 | struct work_struct init_worker; | ||
| 158 | }; | ||
| 159 | |||
| 160 | /* wiimote modules */ | ||
| 161 | |||
| 162 | enum wiimod_module { | ||
| 163 | WIIMOD_KEYS, | ||
| 164 | WIIMOD_RUMBLE, | ||
| 165 | WIIMOD_BATTERY, | ||
| 166 | WIIMOD_LED1, | ||
| 167 | WIIMOD_LED2, | ||
| 168 | WIIMOD_LED3, | ||
| 169 | WIIMOD_LED4, | ||
| 170 | WIIMOD_ACCEL, | ||
| 171 | WIIMOD_IR, | ||
| 172 | WIIMOD_BUILTIN_MP, | ||
| 173 | WIIMOD_NO_MP, | ||
| 174 | WIIMOD_NUM, | ||
| 175 | WIIMOD_NULL = WIIMOD_NUM, | ||
| 176 | }; | ||
| 177 | |||
| 178 | #define WIIMOD_FLAG_INPUT 0x0001 | ||
| 179 | #define WIIMOD_FLAG_EXT8 0x0002 | ||
| 180 | #define WIIMOD_FLAG_EXT16 0x0004 | ||
| 181 | |||
| 182 | struct wiimod_ops { | ||
| 183 | __u16 flags; | ||
| 184 | unsigned long arg; | ||
| 185 | int (*probe) (const struct wiimod_ops *ops, | ||
| 186 | struct wiimote_data *wdata); | ||
| 187 | void (*remove) (const struct wiimod_ops *ops, | ||
| 188 | struct wiimote_data *wdata); | ||
| 189 | |||
| 190 | void (*in_keys) (struct wiimote_data *wdata, const __u8 *keys); | ||
| 191 | void (*in_accel) (struct wiimote_data *wdata, const __u8 *accel); | ||
| 192 | void (*in_ir) (struct wiimote_data *wdata, const __u8 *ir, bool packed, | ||
| 193 | unsigned int id); | ||
| 194 | void (*in_mp) (struct wiimote_data *wdata, const __u8 *mp); | ||
| 195 | void (*in_ext) (struct wiimote_data *wdata, const __u8 *ext); | ||
| 87 | }; | 196 | }; |
| 88 | 197 | ||
| 198 | extern const struct wiimod_ops *wiimod_table[WIIMOD_NUM]; | ||
| 199 | extern const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM]; | ||
| 200 | extern const struct wiimod_ops wiimod_mp; | ||
| 201 | |||
| 202 | /* wiimote requests */ | ||
| 203 | |||
| 89 | enum wiiproto_reqs { | 204 | enum wiiproto_reqs { |
| 90 | WIIPROTO_REQ_NULL = 0x0, | 205 | WIIPROTO_REQ_NULL = 0x0, |
| 91 | WIIPROTO_REQ_RUMBLE = 0x10, | 206 | WIIPROTO_REQ_RUMBLE = 0x10, |
| @@ -99,24 +214,55 @@ enum wiiproto_reqs { | |||
| 99 | WIIPROTO_REQ_STATUS = 0x20, | 214 | WIIPROTO_REQ_STATUS = 0x20, |
| 100 | WIIPROTO_REQ_DATA = 0x21, | 215 | WIIPROTO_REQ_DATA = 0x21, |
| 101 | WIIPROTO_REQ_RETURN = 0x22, | 216 | WIIPROTO_REQ_RETURN = 0x22, |
| 217 | |||
| 218 | /* DRM_K: BB*2 */ | ||
| 102 | WIIPROTO_REQ_DRM_K = 0x30, | 219 | WIIPROTO_REQ_DRM_K = 0x30, |
| 220 | |||
| 221 | /* DRM_KA: BB*2 AA*3 */ | ||
| 103 | WIIPROTO_REQ_DRM_KA = 0x31, | 222 | WIIPROTO_REQ_DRM_KA = 0x31, |
| 223 | |||
| 224 | /* DRM_KE: BB*2 EE*8 */ | ||
| 104 | WIIPROTO_REQ_DRM_KE = 0x32, | 225 | WIIPROTO_REQ_DRM_KE = 0x32, |
| 226 | |||
| 227 | /* DRM_KAI: BB*2 AA*3 II*12 */ | ||
| 105 | WIIPROTO_REQ_DRM_KAI = 0x33, | 228 | WIIPROTO_REQ_DRM_KAI = 0x33, |
| 229 | |||
| 230 | /* DRM_KEE: BB*2 EE*19 */ | ||
| 106 | WIIPROTO_REQ_DRM_KEE = 0x34, | 231 | WIIPROTO_REQ_DRM_KEE = 0x34, |
| 232 | |||
| 233 | /* DRM_KAE: BB*2 AA*3 EE*16 */ | ||
| 107 | WIIPROTO_REQ_DRM_KAE = 0x35, | 234 | WIIPROTO_REQ_DRM_KAE = 0x35, |
| 235 | |||
| 236 | /* DRM_KIE: BB*2 II*10 EE*9 */ | ||
| 108 | WIIPROTO_REQ_DRM_KIE = 0x36, | 237 | WIIPROTO_REQ_DRM_KIE = 0x36, |
| 238 | |||
| 239 | /* DRM_KAIE: BB*2 AA*3 II*10 EE*6 */ | ||
| 109 | WIIPROTO_REQ_DRM_KAIE = 0x37, | 240 | WIIPROTO_REQ_DRM_KAIE = 0x37, |
| 241 | |||
| 242 | /* DRM_E: EE*21 */ | ||
| 110 | WIIPROTO_REQ_DRM_E = 0x3d, | 243 | WIIPROTO_REQ_DRM_E = 0x3d, |
| 244 | |||
| 245 | /* DRM_SKAI1: BB*2 AA*1 II*18 */ | ||
| 111 | WIIPROTO_REQ_DRM_SKAI1 = 0x3e, | 246 | WIIPROTO_REQ_DRM_SKAI1 = 0x3e, |
| 247 | |||
| 248 | /* DRM_SKAI2: BB*2 AA*1 II*18 */ | ||
| 112 | WIIPROTO_REQ_DRM_SKAI2 = 0x3f, | 249 | WIIPROTO_REQ_DRM_SKAI2 = 0x3f, |
| 250 | |||
| 113 | WIIPROTO_REQ_MAX | 251 | WIIPROTO_REQ_MAX |
| 114 | }; | 252 | }; |
| 115 | 253 | ||
| 116 | #define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \ | 254 | #define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \ |
| 117 | dev)) | 255 | dev)) |
| 118 | 256 | ||
| 257 | void __wiimote_schedule(struct wiimote_data *wdata); | ||
| 258 | |||
| 119 | extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm); | 259 | extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm); |
| 260 | extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble); | ||
| 261 | extern void wiiproto_req_leds(struct wiimote_data *wdata, int leds); | ||
| 262 | extern void wiiproto_req_status(struct wiimote_data *wdata); | ||
| 263 | extern void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel); | ||
| 264 | extern void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags); | ||
| 265 | extern void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags); | ||
| 120 | extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, | 266 | extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, |
| 121 | const __u8 *wmem, __u8 size); | 267 | const __u8 *wmem, __u8 size); |
| 122 | extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, | 268 | extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, |
| @@ -129,24 +275,6 @@ extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, | |||
| 129 | extern void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom, | 275 | extern void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom, |
| 130 | __u32 offset, __u16 size); | 276 | __u32 offset, __u16 size); |
| 131 | 277 | ||
| 132 | #ifdef CONFIG_HID_WIIMOTE_EXT | ||
| 133 | |||
| 134 | extern int wiiext_init(struct wiimote_data *wdata); | ||
| 135 | extern void wiiext_deinit(struct wiimote_data *wdata); | ||
| 136 | extern void wiiext_event(struct wiimote_data *wdata, bool plugged); | ||
| 137 | extern bool wiiext_active(struct wiimote_data *wdata); | ||
| 138 | extern void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload); | ||
| 139 | |||
| 140 | #else | ||
| 141 | |||
| 142 | static inline int wiiext_init(void *u) { return 0; } | ||
| 143 | static inline void wiiext_deinit(void *u) { } | ||
| 144 | static inline void wiiext_event(void *u, bool p) { } | ||
| 145 | static inline bool wiiext_active(void *u) { return false; } | ||
| 146 | static inline void wiiext_handle(void *u, const __u8 *p) { } | ||
| 147 | |||
| 148 | #endif | ||
| 149 | |||
| 150 | #ifdef CONFIG_DEBUG_FS | 278 | #ifdef CONFIG_DEBUG_FS |
| 151 | 279 | ||
| 152 | extern int wiidebug_init(struct wiimote_data *wdata); | 280 | extern int wiidebug_init(struct wiimote_data *wdata); |
| @@ -173,11 +301,26 @@ static inline void wiimote_cmd_complete(struct wiimote_data *wdata) | |||
| 173 | complete(&wdata->state.ready); | 301 | complete(&wdata->state.ready); |
| 174 | } | 302 | } |
| 175 | 303 | ||
| 304 | /* requires the state.lock spinlock to be held */ | ||
| 305 | static inline void wiimote_cmd_abort(struct wiimote_data *wdata) | ||
| 306 | { | ||
| 307 | /* Abort synchronous request by waking up the sleeping caller. But | ||
| 308 | * reset the state.cmd field to an invalid value so no further event | ||
| 309 | * handlers will work with it. */ | ||
| 310 | wdata->state.cmd = WIIPROTO_REQ_MAX; | ||
| 311 | complete(&wdata->state.ready); | ||
| 312 | } | ||
| 313 | |||
| 176 | static inline int wiimote_cmd_acquire(struct wiimote_data *wdata) | 314 | static inline int wiimote_cmd_acquire(struct wiimote_data *wdata) |
| 177 | { | 315 | { |
| 178 | return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0; | 316 | return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0; |
| 179 | } | 317 | } |
| 180 | 318 | ||
| 319 | static inline void wiimote_cmd_acquire_noint(struct wiimote_data *wdata) | ||
| 320 | { | ||
| 321 | mutex_lock(&wdata->state.sync); | ||
| 322 | } | ||
| 323 | |||
| 181 | /* requires the state.lock spinlock to be held */ | 324 | /* requires the state.lock spinlock to be held */ |
| 182 | static inline void wiimote_cmd_set(struct wiimote_data *wdata, int cmd, | 325 | static inline void wiimote_cmd_set(struct wiimote_data *wdata, int cmd, |
| 183 | __u32 opt) | 326 | __u32 opt) |
| @@ -196,11 +339,31 @@ static inline int wiimote_cmd_wait(struct wiimote_data *wdata) | |||
| 196 | { | 339 | { |
| 197 | int ret; | 340 | int ret; |
| 198 | 341 | ||
| 342 | /* The completion acts as implicit memory barrier so we can safely | ||
| 343 | * assume that state.cmd is set on success/failure and isn't accessed | ||
| 344 | * by any other thread, anymore. */ | ||
| 345 | |||
| 199 | ret = wait_for_completion_interruptible_timeout(&wdata->state.ready, HZ); | 346 | ret = wait_for_completion_interruptible_timeout(&wdata->state.ready, HZ); |
| 200 | if (ret < 0) | 347 | if (ret < 0) |
| 201 | return -ERESTARTSYS; | 348 | return -ERESTARTSYS; |
| 202 | else if (ret == 0) | 349 | else if (ret == 0) |
| 203 | return -EIO; | 350 | return -EIO; |
| 351 | else if (wdata->state.cmd != WIIPROTO_REQ_NULL) | ||
| 352 | return -EIO; | ||
| 353 | else | ||
| 354 | return 0; | ||
| 355 | } | ||
| 356 | |||
| 357 | static inline int wiimote_cmd_wait_noint(struct wiimote_data *wdata) | ||
| 358 | { | ||
| 359 | unsigned long ret; | ||
| 360 | |||
| 361 | /* no locking needed; see wiimote_cmd_wait() */ | ||
| 362 | ret = wait_for_completion_timeout(&wdata->state.ready, HZ); | ||
| 363 | if (!ret) | ||
| 364 | return -EIO; | ||
| 365 | else if (wdata->state.cmd != WIIPROTO_REQ_NULL) | ||
| 366 | return -EIO; | ||
| 204 | else | 367 | else |
| 205 | return 0; | 368 | return 0; |
| 206 | } | 369 | } |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 2b1799a3b212..879b0ed701a3 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -108,6 +108,7 @@ static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01), | |||
| 108 | static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; | 108 | static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; |
| 109 | static const struct i2c_hid_cmd hid_set_report_cmd = { I2C_HID_CMD(0x03) }; | 109 | static const struct i2c_hid_cmd hid_set_report_cmd = { I2C_HID_CMD(0x03) }; |
| 110 | static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD(0x08) }; | 110 | static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD(0x08) }; |
| 111 | static const struct i2c_hid_cmd hid_no_cmd = { .length = 0 }; | ||
| 111 | 112 | ||
| 112 | /* | 113 | /* |
| 113 | * These definitions are not used here, but are defined by the spec. | 114 | * These definitions are not used here, but are defined by the spec. |
| @@ -259,8 +260,11 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | |||
| 259 | { | 260 | { |
| 260 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 261 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
| 261 | u8 *args = ihid->argsbuf; | 262 | u8 *args = ihid->argsbuf; |
| 263 | const struct i2c_hid_cmd * hidcmd = &hid_set_report_cmd; | ||
| 262 | int ret; | 264 | int ret; |
| 263 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); | 265 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); |
| 266 | u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister); | ||
| 267 | u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength); | ||
| 264 | 268 | ||
| 265 | /* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */ | 269 | /* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */ |
| 266 | u16 size = 2 /* size */ + | 270 | u16 size = 2 /* size */ + |
| @@ -278,8 +282,18 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | |||
| 278 | reportID = 0x0F; | 282 | reportID = 0x0F; |
| 279 | } | 283 | } |
| 280 | 284 | ||
| 281 | args[index++] = dataRegister & 0xFF; | 285 | /* |
| 282 | args[index++] = dataRegister >> 8; | 286 | * use the data register for feature reports or if the device does not |
| 287 | * support the output register | ||
| 288 | */ | ||
| 289 | if (reportType == 0x03 || maxOutputLength == 0) { | ||
| 290 | args[index++] = dataRegister & 0xFF; | ||
| 291 | args[index++] = dataRegister >> 8; | ||
| 292 | } else { | ||
| 293 | args[index++] = outputRegister & 0xFF; | ||
| 294 | args[index++] = outputRegister >> 8; | ||
| 295 | hidcmd = &hid_no_cmd; | ||
| 296 | } | ||
| 283 | 297 | ||
| 284 | args[index++] = size & 0xFF; | 298 | args[index++] = size & 0xFF; |
| 285 | args[index++] = size >> 8; | 299 | args[index++] = size >> 8; |
| @@ -289,7 +303,7 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | |||
| 289 | 303 | ||
| 290 | memcpy(&args[index], buf, data_len); | 304 | memcpy(&args[index], buf, data_len); |
| 291 | 305 | ||
| 292 | ret = __i2c_hid_command(client, &hid_set_report_cmd, reportID, | 306 | ret = __i2c_hid_command(client, hidcmd, reportID, |
| 293 | reportType, args, args_len, NULL, 0); | 307 | reportType, args, args_len, NULL, 0); |
| 294 | if (ret) { | 308 | if (ret) { |
| 295 | dev_err(&client->dev, "failed to set a report to device.\n"); | 309 | dev_err(&client->dev, "failed to set a report to device.\n"); |
