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 ret = hid_parse(hdev); 61 if (ret) { 62 dev_err(&hdev->dev, "parse failed\n"); 63 goto err_free; 64 } 65 66 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | 67 HID_CONNECT_HIDDEV_FORCE); 68 if (ret) { 69 dev_err(&hdev->dev, "hw start failed\n"); 70 goto err_free; 71 } 72 73 ret = sony_set_operational(hdev); 74 if (ret) 75 goto err_stop; 76 77 return 0; 78 err_stop: 79 hid_hw_stop(hdev); 80 err_free: 81 return ret; 82 } 83 84 static const struct hid_device_id sony_devices[] = { 85 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 86 { } 87 }; 88 MODULE_DEVICE_TABLE(hid, sony_devices); 89 90 static struct hid_driver sony_driver = { 91 .name = "sony", 92 .id_table = sony_devices, 93 .probe = sony_probe, 94 }; 95 96 static int sony_init(void) 97 { 98 return hid_register_driver(&sony_driver); 99 } 100 101 static void sony_exit(void) 102 { 103 hid_unregister_driver(&sony_driver); 104 } 105 106 module_init(sony_init); 107 module_exit(sony_exit); 108 MODULE_LICENSE("GPL"); 109 110 HID_COMPAT_LOAD_DRIVER(sony); 111