1bd28ce00SJiri Slaby /* 2bd28ce00SJiri Slaby * HID driver for some sony "special" devices 3bd28ce00SJiri Slaby * 4bd28ce00SJiri Slaby * Copyright (c) 1999 Andreas Gal 5bd28ce00SJiri Slaby * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 6bd28ce00SJiri Slaby * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 7bd28ce00SJiri Slaby * Copyright (c) 2006-2007 Jiri Kosina 8bd28ce00SJiri Slaby * Copyright (c) 2007 Paul Walmsley 9bd28ce00SJiri Slaby * Copyright (c) 2008 Jiri Slaby 10bd28ce00SJiri Slaby */ 11bd28ce00SJiri Slaby 12bd28ce00SJiri Slaby /* 13bd28ce00SJiri Slaby * This program is free software; you can redistribute it and/or modify it 14bd28ce00SJiri Slaby * under the terms of the GNU General Public License as published by the Free 15bd28ce00SJiri Slaby * Software Foundation; either version 2 of the License, or (at your option) 16bd28ce00SJiri Slaby * any later version. 17bd28ce00SJiri Slaby */ 18bd28ce00SJiri Slaby 19bd28ce00SJiri Slaby #include <linux/device.h> 20bd28ce00SJiri Slaby #include <linux/hid.h> 21bd28ce00SJiri Slaby #include <linux/module.h> 22bd28ce00SJiri Slaby #include <linux/usb.h> 23bd28ce00SJiri Slaby 24bd28ce00SJiri Slaby #include "hid-ids.h" 25bd28ce00SJiri Slaby 26bd28ce00SJiri Slaby /* 27bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 28bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 29bd28ce00SJiri Slaby * events. 30bd28ce00SJiri Slaby */ 31bd28ce00SJiri Slaby static int sony_set_operational(struct hid_device *hdev) 32bd28ce00SJiri Slaby { 33bd28ce00SJiri Slaby struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 34bd28ce00SJiri Slaby struct usb_device *dev = interface_to_usbdev(intf); 35bd28ce00SJiri Slaby __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 36bd28ce00SJiri Slaby int ret; 37bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 38bd28ce00SJiri Slaby 39bd28ce00SJiri Slaby if (!buf) 40bd28ce00SJiri Slaby return -ENOMEM; 41bd28ce00SJiri Slaby 42bd28ce00SJiri Slaby ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 43bd28ce00SJiri Slaby HID_REQ_GET_REPORT, 44bd28ce00SJiri Slaby USB_DIR_IN | USB_TYPE_CLASS | 45bd28ce00SJiri Slaby USB_RECIP_INTERFACE, 46bd28ce00SJiri Slaby (3 << 8) | 0xf2, ifnum, buf, 17, 47bd28ce00SJiri Slaby USB_CTRL_GET_TIMEOUT); 48bd28ce00SJiri Slaby if (ret < 0) 49bd28ce00SJiri Slaby dev_err(&hdev->dev, "can't set operational mode\n"); 50bd28ce00SJiri Slaby 51bd28ce00SJiri Slaby kfree(buf); 52bd28ce00SJiri Slaby 53bd28ce00SJiri Slaby return ret; 54bd28ce00SJiri Slaby } 55bd28ce00SJiri Slaby 56bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 57bd28ce00SJiri Slaby { 58bd28ce00SJiri Slaby int ret; 59bd28ce00SJiri Slaby 60bd28ce00SJiri Slaby ret = hid_parse(hdev); 61bd28ce00SJiri Slaby if (ret) { 62bd28ce00SJiri Slaby dev_err(&hdev->dev, "parse failed\n"); 63bd28ce00SJiri Slaby goto err_free; 64bd28ce00SJiri Slaby } 65bd28ce00SJiri Slaby 66*93c10132SJiri Slaby ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | 67*93c10132SJiri Slaby HID_CONNECT_HIDDEV_FORCE); 68bd28ce00SJiri Slaby if (ret) { 69bd28ce00SJiri Slaby dev_err(&hdev->dev, "hw start failed\n"); 70bd28ce00SJiri Slaby goto err_free; 71bd28ce00SJiri Slaby } 72bd28ce00SJiri Slaby 73bd28ce00SJiri Slaby ret = sony_set_operational(hdev); 74bd28ce00SJiri Slaby if (ret) 75bd28ce00SJiri Slaby goto err_stop; 76bd28ce00SJiri Slaby 77bd28ce00SJiri Slaby return 0; 78bd28ce00SJiri Slaby err_stop: 79bd28ce00SJiri Slaby hid_hw_stop(hdev); 80bd28ce00SJiri Slaby err_free: 81bd28ce00SJiri Slaby return ret; 82bd28ce00SJiri Slaby } 83bd28ce00SJiri Slaby 84bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 85bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 86bd28ce00SJiri Slaby { } 87bd28ce00SJiri Slaby }; 88bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 89bd28ce00SJiri Slaby 90bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 91bd28ce00SJiri Slaby .name = "sony", 92bd28ce00SJiri Slaby .id_table = sony_devices, 93bd28ce00SJiri Slaby .probe = sony_probe, 94bd28ce00SJiri Slaby }; 95bd28ce00SJiri Slaby 96bd28ce00SJiri Slaby static int sony_init(void) 97bd28ce00SJiri Slaby { 98bd28ce00SJiri Slaby return hid_register_driver(&sony_driver); 99bd28ce00SJiri Slaby } 100bd28ce00SJiri Slaby 101bd28ce00SJiri Slaby static void sony_exit(void) 102bd28ce00SJiri Slaby { 103bd28ce00SJiri Slaby hid_unregister_driver(&sony_driver); 104bd28ce00SJiri Slaby } 105bd28ce00SJiri Slaby 106bd28ce00SJiri Slaby module_init(sony_init); 107bd28ce00SJiri Slaby module_exit(sony_exit); 108bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 109bd28ce00SJiri Slaby 110bd28ce00SJiri Slaby HID_COMPAT_LOAD_DRIVER(sony); 111