aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/Kconfig26
-rw-r--r--drivers/hid/Makefile2
-rw-r--r--drivers/hid/hid-core.c8
-rw-r--r--drivers/hid/hid-huion.c177
-rw-r--r--drivers/hid/hid-hyperv.c4
-rw-r--r--drivers/hid/hid-ids.h20
-rw-r--r--drivers/hid/hid-input.c7
-rw-r--r--drivers/hid/hid-kye.c21
-rw-r--r--drivers/hid/hid-multitouch.c34
-rw-r--r--drivers/hid/hid-ps3remote.c204
-rw-r--r--drivers/hid/hid-roccat.c16
-rw-r--r--drivers/hid/hid-sony.c473
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
253config HID_HUION
254 tristate "Huion tablets"
255 depends on USB_HID
256 ---help---
257 Support for Huion 580 tablet.
258
253config HID_KEYTOUCH 259config 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
574config 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
583config HID_ROCCAT 580config 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
606config HID_SONY 603config 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
614config HID_SPEEDLINK 616config 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
54obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o 54obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
55obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o 55obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o
56obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o 56obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
57obj-$(CONFIG_HID_HUION) += hid-huion.o
57obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o 58obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
58obj-$(CONFIG_HID_ICADE) += hid-icade.o 59obj-$(CONFIG_HID_ICADE) += hid-icade.o
59obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o 60obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
@@ -94,7 +95,6 @@ hid-picolcd-y += hid-picolcd_debugfs.o
94endif 95endif
95 96
96obj-$(CONFIG_HID_PRIMAX) += hid-primax.o 97obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
97obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o
98obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ 98obj-$(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 */
26static __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
71static __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 */
94static 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
106static 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;
144enabling_err:
145 hid_hw_stop(hdev);
146err:
147 return ret;
148}
149
150static 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
160static const struct hid_device_id huion_devices[] = {
161 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
162 { }
163};
164MODULE_DEVICE_TABLE(hid, huion_devices);
165
166static 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};
173module_hid_driver(huion_driver);
174
175MODULE_AUTHOR("Martin Rusko");
176MODULE_DESCRIPTION("Huion HID driver");
177MODULE_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};
412MODULE_DEVICE_TABLE(hid, kye_devices); 433MODULE_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
29static __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
89static 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};
109static 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
145static __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
152static 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
186static 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};
193MODULE_DEVICE_TABLE(hid, ps3remote_devices);
194
195static 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};
201module_hid_driver(ps3remote_driver);
202
203MODULE_LICENSE("GPL");
204MODULE_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
438static void __exit roccat_exit(void) 448static 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
30static const u8 sixaxis_rdesc_fixup[] = { 42static 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
70static __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
130static 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};
150static 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
186static 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
58struct sony_sc { 225struct sony_sc {
59 unsigned long quirks; 226 unsigned long quirks;
227
228 void *extra;
60}; 229};
61 230
231struct buzz_extra {
232 int led_state;
233 struct led_classdev *leds[4];
234};
235
236static __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
243static 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 */
63static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 279static __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
340static 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
450static 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
468static 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
500static 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
527static 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
579error_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
594static 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
195static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 619static 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
243static void sony_remove(struct hid_device *hdev) 676static 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
249static const struct hid_device_id sony_devices[] = { 687static 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};
262MODULE_DEVICE_TABLE(hid, sony_devices); 712MODULE_DEVICE_TABLE(hid, sony_devices);
263 713
264static struct hid_driver sony_driver = { 714static 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};
272module_hid_driver(sony_driver); 723module_hid_driver(sony_driver);
273 724