diff options
| -rw-r--r-- | drivers/hid/Kconfig | 26 | ||||
| -rw-r--r-- | drivers/hid/Makefile | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 8 | ||||
| -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 | 20 | ||||
| -rw-r--r-- | drivers/hid/hid-input.c | 7 | ||||
| -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 |
12 files changed, 736 insertions, 256 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index b93e299eb272..e25fb9829729 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -250,6 +250,12 @@ config HOLTEK_FF | |||
| 250 | 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 |
| 251 | and want to have force feedback support for it. | 251 | and want to have force feedback support for it. |
| 252 | 252 | ||
| 253 | config HID_HUION | ||
| 254 | tristate "Huion tablets" | ||
| 255 | depends on USB_HID | ||
| 256 | ---help--- | ||
| 257 | Support for Huion 580 tablet. | ||
| 258 | |||
| 253 | config HID_KEYTOUCH | 259 | config HID_KEYTOUCH |
| 254 | tristate "Keytouch HID devices" | 260 | tristate "Keytouch HID devices" |
| 255 | depends on HID | 261 | depends on HID |
| @@ -571,15 +577,6 @@ config HID_PRIMAX | |||
| 571 | Support for Primax devices that are not fully compliant with the | 577 | Support for Primax devices that are not fully compliant with the |
| 572 | HID standard. | 578 | HID standard. |
| 573 | 579 | ||
| 574 | config HID_PS3REMOTE | ||
| 575 | tristate "Sony PS3 BD Remote Control" | ||
| 576 | depends on HID | ||
| 577 | ---help--- | ||
| 578 | Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech | ||
| 579 | Harmony Adapter for PS3, which connect over Bluetooth. | ||
| 580 | |||
| 581 | Support for the 6-axis controllers is provided by HID_SONY. | ||
| 582 | |||
| 583 | config HID_ROCCAT | 580 | config HID_ROCCAT |
| 584 | tristate "Roccat device support" | 581 | tristate "Roccat device support" |
| 585 | depends on USB_HID | 582 | depends on USB_HID |
| @@ -604,12 +601,17 @@ config HID_SAMSUNG | |||
| 604 | Support for Samsung InfraRed remote control or keyboards. | 601 | Support for Samsung InfraRed remote control or keyboards. |
| 605 | 602 | ||
| 606 | config HID_SONY | 603 | config HID_SONY |
| 607 | tristate "Sony PS3 controller" | 604 | tristate "Sony PS2/3 accessories" |
| 608 | depends on USB_HID | 605 | depends on USB_HID |
| 606 | depends on NEW_LEDS | ||
| 607 | depends on LEDS_CLASS | ||
| 609 | ---help--- | 608 | ---help--- |
| 610 | Support for Sony PS3 6-axis controllers. | 609 | Support for |
| 611 | 610 | ||
| 612 | 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) | ||
| 613 | 615 | ||
| 614 | config HID_SPEEDLINK | 616 | config HID_SPEEDLINK |
| 615 | tristate "Speedlink VAD Cezanne mouse support" | 617 | tristate "Speedlink VAD Cezanne mouse support" |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 7a0340ace186..ffd0d9826d84 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
| @@ -54,6 +54,7 @@ obj-$(CONFIG_HID_GYRATION) += hid-gyration.o | |||
| 54 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o | 54 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o |
| 55 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o | 55 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o |
| 56 | obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o | 56 | obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o |
| 57 | obj-$(CONFIG_HID_HUION) += hid-huion.o | ||
| 57 | obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o | 58 | obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o |
| 58 | obj-$(CONFIG_HID_ICADE) += hid-icade.o | 59 | obj-$(CONFIG_HID_ICADE) += hid-icade.o |
| 59 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o | 60 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o |
| @@ -94,7 +95,6 @@ hid-picolcd-y += hid-picolcd_debugfs.o | |||
| 94 | endif | 95 | endif |
| 95 | 96 | ||
| 96 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o | 97 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o |
| 97 | obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o | ||
| 98 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ | 98 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ |
| 99 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ | 99 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ |
| 100 | hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ | 100 | 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 b29c956c395c..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 | } |
| @@ -1588,10 +1588,12 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1588 | { 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) }, | 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) }, | 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) }, | ||
| 1591 | { 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) }, |
| 1592 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, | 1593 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, |
| 1593 | { 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) }, |
| 1594 | { 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) }, | ||
| 1595 | { 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) }, |
| 1596 | { 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) }, |
| 1597 | { 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) }, |
| @@ -1684,6 +1686,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1684 | { 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) }, |
| 1685 | { 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) }, |
| 1686 | { 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) }, | ||
| 1687 | { 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) }, |
| 1688 | { 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) }, |
| 1689 | { 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) }, |
| @@ -2046,6 +2050,8 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
| 2046 | { 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) }, |
| 2047 | { 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) }, |
| 2048 | { 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) }, | ||
| 2049 | { 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) }, |
| 2050 | { 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) }, |
| 2051 | { 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-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 a9fcb9ea6c16..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 |
| @@ -449,6 +454,10 @@ | |||
| 449 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 | 454 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 |
| 450 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 | 455 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 |
| 451 | 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 | |||
| 452 | #define USB_VENDOR_ID_JESS 0x0c45 | 461 | #define USB_VENDOR_ID_JESS 0x0c45 |
| 453 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 | 462 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 |
| 454 | 463 | ||
| @@ -469,6 +478,7 @@ | |||
| 469 | 478 | ||
| 470 | #define USB_VENDOR_ID_KYE 0x0458 | 479 | #define USB_VENDOR_ID_KYE 0x0458 |
| 471 | #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 | ||
| 472 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 | 482 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 |
| 473 | #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 | 483 | #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 |
| 474 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 | 484 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 |
| @@ -736,6 +746,8 @@ | |||
| 736 | #define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 | 746 | #define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 |
| 737 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | 747 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 |
| 738 | #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 | ||
| 739 | 751 | ||
| 740 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 | 752 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 |
| 741 | #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 c526a3ccbe5b..7480799e535c 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -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 | ||
