diff options
-rw-r--r-- | drivers/hid/Kconfig | 7 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-dummy.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 111 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 30 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 2 | ||||
-rw-r--r-- | include/linux/hid.h | 1 |
8 files changed, 123 insertions, 33 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 52b617bf2b93..7ced6476026a 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -182,6 +182,13 @@ config HID_SAMSUNG | |||
182 | ---help--- | 182 | ---help--- |
183 | Support for Samsung IR remote. | 183 | Support for Samsung IR remote. |
184 | 184 | ||
185 | config HID_SONY | ||
186 | tristate "Sony" | ||
187 | default m | ||
188 | depends on USB_HID | ||
189 | ---help--- | ||
190 | Support for Sony PS3 controller. | ||
191 | |||
185 | config HID_SUNPLUS | 192 | config HID_SUNPLUS |
186 | tristate "Sunplus" | 193 | tristate "Sunplus" |
187 | default m | 194 | default m |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 0141ff88008e..4f39b9431ebe 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o | |||
25 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o | 25 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o |
26 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o | 26 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o |
27 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 27 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
28 | obj-$(CONFIG_HID_SONY) += hid-sony.o | ||
28 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o | 29 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o |
29 | 30 | ||
30 | obj-$(CONFIG_USB_HID) += usbhid/ | 31 | obj-$(CONFIG_USB_HID) += usbhid/ |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1b43af072ce0..f527e332b596 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1195,6 +1195,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1195 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1195 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1196 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1196 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1197 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, | 1197 | { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, |
1198 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | ||
1198 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 1199 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
1199 | 1200 | ||
1200 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, | 1201 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, |
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c index cd21dcc41816..1ef3111f7fe7 100644 --- a/drivers/hid/hid-dummy.c +++ b/drivers/hid/hid-dummy.c | |||
@@ -43,6 +43,9 @@ static int __init hid_dummy_init(void) | |||
43 | #ifdef CONFIG_HID_SAMSUNG_MODULE | 43 | #ifdef CONFIG_HID_SAMSUNG_MODULE |
44 | HID_COMPAT_CALL_DRIVER(samsung); | 44 | HID_COMPAT_CALL_DRIVER(samsung); |
45 | #endif | 45 | #endif |
46 | #ifdef CONFIG_HID_SONY_MODULE | ||
47 | HID_COMPAT_CALL_DRIVER(sony); | ||
48 | #endif | ||
46 | #ifdef CONFIG_HID_SUNPLUS_MODULE | 49 | #ifdef CONFIG_HID_SUNPLUS_MODULE |
47 | HID_COMPAT_CALL_DRIVER(sunplus); | 50 | HID_COMPAT_CALL_DRIVER(sunplus); |
48 | #endif | 51 | #endif |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c new file mode 100644 index 000000000000..97668c68f0a6 --- /dev/null +++ b/drivers/hid/hid-sony.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * HID driver for some sony "special" devices | ||
3 | * | ||
4 | * Copyright (c) 1999 Andreas Gal | ||
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | ||
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | ||
7 | * Copyright (c) 2006-2007 Jiri Kosina | ||
8 | * Copyright (c) 2007 Paul Walmsley | ||
9 | * Copyright (c) 2008 Jiri Slaby | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the Free | ||
15 | * Software Foundation; either version 2 of the License, or (at your option) | ||
16 | * any later version. | ||
17 | */ | ||
18 | |||
19 | #include <linux/device.h> | ||
20 | #include <linux/hid.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/usb.h> | ||
23 | |||
24 | #include "hid-ids.h" | ||
25 | |||
26 | /* | ||
27 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | ||
28 | * to "operational". Without this, the ps3 controller will not report any | ||
29 | * events. | ||
30 | */ | ||
31 | static int sony_set_operational(struct hid_device *hdev) | ||
32 | { | ||
33 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
34 | struct usb_device *dev = interface_to_usbdev(intf); | ||
35 | __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | ||
36 | int ret; | ||
37 | char *buf = kmalloc(18, GFP_KERNEL); | ||
38 | |||
39 | if (!buf) | ||
40 | return -ENOMEM; | ||
41 | |||
42 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
43 | HID_REQ_GET_REPORT, | ||
44 | USB_DIR_IN | USB_TYPE_CLASS | | ||
45 | USB_RECIP_INTERFACE, | ||
46 | (3 << 8) | 0xf2, ifnum, buf, 17, | ||
47 | USB_CTRL_GET_TIMEOUT); | ||
48 | if (ret < 0) | ||
49 | dev_err(&hdev->dev, "can't set operational mode\n"); | ||
50 | |||
51 | kfree(buf); | ||
52 | |||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
57 | { | ||
58 | int ret; | ||
59 | |||
60 | hdev->quirks |= HID_QUIRK_HIDDEV; | ||
61 | |||
62 | ret = hid_parse(hdev); | ||
63 | if (ret) { | ||
64 | dev_err(&hdev->dev, "parse failed\n"); | ||
65 | goto err_free; | ||
66 | } | ||
67 | |||
68 | ret = hid_hw_start(hdev); | ||
69 | if (ret) { | ||
70 | dev_err(&hdev->dev, "hw start failed\n"); | ||
71 | goto err_free; | ||
72 | } | ||
73 | |||
74 | ret = sony_set_operational(hdev); | ||
75 | if (ret) | ||
76 | goto err_stop; | ||
77 | |||
78 | return 0; | ||
79 | err_stop: | ||
80 | hid_hw_stop(hdev); | ||
81 | err_free: | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | static const struct hid_device_id sony_devices[] = { | ||
86 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | ||
87 | { } | ||
88 | }; | ||
89 | MODULE_DEVICE_TABLE(hid, sony_devices); | ||
90 | |||
91 | static struct hid_driver sony_driver = { | ||
92 | .name = "sony", | ||
93 | .id_table = sony_devices, | ||
94 | .probe = sony_probe, | ||
95 | }; | ||
96 | |||
97 | static int sony_init(void) | ||
98 | { | ||
99 | return hid_register_driver(&sony_driver); | ||
100 | } | ||
101 | |||
102 | static void sony_exit(void) | ||
103 | { | ||
104 | hid_unregister_driver(&sony_driver); | ||
105 | } | ||
106 | |||
107 | module_init(sony_init); | ||
108 | module_exit(sony_exit); | ||
109 | MODULE_LICENSE("GPL"); | ||
110 | |||
111 | HID_COMPAT_LOAD_DRIVER(sony); | ||
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index e900d597bc2d..b41d0110a75e 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -670,32 +670,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) | |||
670 | usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); | 670 | usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); |
671 | } | 671 | } |
672 | 672 | ||
673 | /* | ||
674 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | ||
675 | * to "operational". Without this, the ps3 controller will not report any | ||
676 | * events. | ||
677 | */ | ||
678 | static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) | ||
679 | { | ||
680 | int result; | ||
681 | char *buf = kmalloc(18, GFP_KERNEL); | ||
682 | |||
683 | if (!buf) | ||
684 | return; | ||
685 | |||
686 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
687 | HID_REQ_GET_REPORT, | ||
688 | USB_DIR_IN | USB_TYPE_CLASS | | ||
689 | USB_RECIP_INTERFACE, | ||
690 | (3 << 8) | 0xf2, ifnum, buf, 17, | ||
691 | USB_CTRL_GET_TIMEOUT); | ||
692 | |||
693 | if (result < 0) | ||
694 | err_hid("%s failed: %d\n", __func__, result); | ||
695 | |||
696 | kfree(buf); | ||
697 | } | ||
698 | |||
699 | static int usbhid_start_finish(struct hid_device *hid) | 673 | static int usbhid_start_finish(struct hid_device *hid) |
700 | { | 674 | { |
701 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | 675 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); |
@@ -723,10 +697,6 @@ static int usbhid_start_finish(struct hid_device *hid) | |||
723 | if ((hid->claimed & HID_CLAIMED_INPUT)) | 697 | if ((hid->claimed & HID_CLAIMED_INPUT)) |
724 | hid_ff_init(hid); | 698 | hid_ff_init(hid); |
725 | 699 | ||
726 | if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER) | ||
727 | hid_fixup_sony_ps3_controller(interface_to_usbdev(intf), | ||
728 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
729 | |||
730 | printk(KERN_INFO); | 700 | printk(KERN_INFO); |
731 | 701 | ||
732 | if (hid->claimed & HID_CLAIMED_INPUT) | 702 | if (hid->claimed & HID_CLAIMED_INPUT) |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index f66d2e43b5d5..a154a7dc1e63 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -46,8 +46,6 @@ static const struct hid_blacklist { | |||
46 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 46 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
47 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, | 47 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, |
48 | 48 | ||
49 | { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER | HID_QUIRK_HIDDEV }, | ||
50 | |||
51 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 49 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
52 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 50 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
53 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, | 51 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 9eac330a1dfa..43aa51a7fa95 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -262,7 +262,6 @@ struct hid_item { | |||
262 | #define HID_QUIRK_BADPAD 0x00000020 | 262 | #define HID_QUIRK_BADPAD 0x00000020 |
263 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | 263 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
264 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 264 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
265 | #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000 | ||
266 | #define HID_QUIRK_RESET_LEDS 0x00100000 | 265 | #define HID_QUIRK_RESET_LEDS 0x00100000 |
267 | #define HID_QUIRK_HIDINPUT 0x00200000 | 266 | #define HID_QUIRK_HIDINPUT 0x00200000 |
268 | #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 | 267 | #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 |