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) 2008 Jiri Slaby 8cc6e0bbbSJiri Kosina * Copyright (c) 2006-2008 Jiri Kosina 9bd28ce00SJiri Slaby */ 10bd28ce00SJiri Slaby 11bd28ce00SJiri Slaby /* 12bd28ce00SJiri Slaby * This program is free software; you can redistribute it and/or modify it 13bd28ce00SJiri Slaby * under the terms of the GNU General Public License as published by the Free 14bd28ce00SJiri Slaby * Software Foundation; either version 2 of the License, or (at your option) 15bd28ce00SJiri Slaby * any later version. 16bd28ce00SJiri Slaby */ 17bd28ce00SJiri Slaby 18bd28ce00SJiri Slaby #include <linux/device.h> 19bd28ce00SJiri Slaby #include <linux/hid.h> 20bd28ce00SJiri Slaby #include <linux/module.h> 215a0e3ad6STejun Heo #include <linux/slab.h> 22bd28ce00SJiri Slaby #include <linux/usb.h> 23bd28ce00SJiri Slaby 24bd28ce00SJiri Slaby #include "hid-ids.h" 25bd28ce00SJiri Slaby 26816651a7SAntonio Ospite #define VAIO_RDESC_CONSTANT (1 << 0) 27816651a7SAntonio Ospite #define SIXAXIS_CONTROLLER_USB (1 << 1) 28816651a7SAntonio Ospite #define SIXAXIS_CONTROLLER_BT (1 << 2) 29cc6e0bbbSJiri Kosina 3061ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = { 3161ab44beSSimon Wood 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, 3261ab44beSSimon Wood 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF, 3361ab44beSSimon Wood 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 3461ab44beSSimon Wood }; 3561ab44beSSimon Wood 36cc6e0bbbSJiri Kosina struct sony_sc { 37cc6e0bbbSJiri Kosina unsigned long quirks; 38cc6e0bbbSJiri Kosina }; 39cc6e0bbbSJiri Kosina 40cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 4173e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 4273e4008dSNikolai Kondrashov unsigned int *rsize) 43cc6e0bbbSJiri Kosina { 44cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 45cc6e0bbbSJiri Kosina 46cc6e0bbbSJiri Kosina if ((sc->quirks & VAIO_RDESC_CONSTANT) && 4773e4008dSNikolai Kondrashov *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { 484291ee30SJoe Perches hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n"); 49cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 50cc6e0bbbSJiri Kosina } 5161ab44beSSimon Wood 5261ab44beSSimon Wood /* The HID descriptor exposed over BT has a trailing zero byte */ 5361ab44beSSimon Wood if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 5461ab44beSSimon Wood ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) && 5561ab44beSSimon Wood rdesc[83] == 0x75) { 5661ab44beSSimon Wood hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); 5761ab44beSSimon Wood memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, 5861ab44beSSimon Wood sizeof(sixaxis_rdesc_fixup)); 5961ab44beSSimon Wood } 6073e4008dSNikolai Kondrashov return rdesc; 61cc6e0bbbSJiri Kosina } 62cc6e0bbbSJiri Kosina 63c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 64c9e4d877SSimon Wood __u8 *rd, int size) 65c9e4d877SSimon Wood { 66c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 67c9e4d877SSimon Wood 68c9e4d877SSimon Wood /* Sixaxis HID report has acclerometers/gyro with MSByte first, this 69c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 70c9e4d877SSimon Wood */ 71c9e4d877SSimon Wood if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) && 72c9e4d877SSimon Wood rd[0] == 0x01 && size == 49) { 73c9e4d877SSimon Wood swap(rd[41], rd[42]); 74c9e4d877SSimon Wood swap(rd[43], rd[44]); 75c9e4d877SSimon Wood swap(rd[45], rd[46]); 76c9e4d877SSimon Wood swap(rd[47], rd[48]); 77c9e4d877SSimon Wood } 78c9e4d877SSimon Wood 79c9e4d877SSimon Wood return 0; 80c9e4d877SSimon Wood } 81c9e4d877SSimon Wood 825710fabfSAntonio Ospite /* 835710fabfSAntonio Ospite * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP 845710fabfSAntonio Ospite * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() 855710fabfSAntonio Ospite * so we need to override that forcing HID Output Reports on the Control EP. 865710fabfSAntonio Ospite * 875710fabfSAntonio Ospite * There is also another issue about HID Output Reports via USB, the Sixaxis 885710fabfSAntonio Ospite * does not want the report_id as part of the data packet, so we have to 895710fabfSAntonio Ospite * discard buf[0] when sending the actual control message, even for numbered 905710fabfSAntonio Ospite * reports, humpf! 915710fabfSAntonio Ospite */ 92569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, 93569b10a5SAntonio Ospite size_t count, unsigned char report_type) 94569b10a5SAntonio Ospite { 95569b10a5SAntonio Ospite struct usb_interface *intf = to_usb_interface(hid->dev.parent); 96569b10a5SAntonio Ospite struct usb_device *dev = interface_to_usbdev(intf); 97569b10a5SAntonio Ospite struct usb_host_interface *interface = intf->cur_altsetting; 98569b10a5SAntonio Ospite int report_id = buf[0]; 99569b10a5SAntonio Ospite int ret; 100569b10a5SAntonio Ospite 1015710fabfSAntonio Ospite if (report_type == HID_OUTPUT_REPORT) { 1025710fabfSAntonio Ospite /* Don't send the Report ID */ 1035710fabfSAntonio Ospite buf++; 1045710fabfSAntonio Ospite count--; 1055710fabfSAntonio Ospite } 1065710fabfSAntonio Ospite 107569b10a5SAntonio Ospite ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 108569b10a5SAntonio Ospite HID_REQ_SET_REPORT, 109569b10a5SAntonio Ospite USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 110569b10a5SAntonio Ospite ((report_type + 1) << 8) | report_id, 111569b10a5SAntonio Ospite interface->desc.bInterfaceNumber, buf, count, 112569b10a5SAntonio Ospite USB_CTRL_SET_TIMEOUT); 113569b10a5SAntonio Ospite 1145710fabfSAntonio Ospite /* Count also the Report ID, in case of an Output report. */ 1155710fabfSAntonio Ospite if (ret > 0 && report_type == HID_OUTPUT_REPORT) 1165710fabfSAntonio Ospite ret++; 1175710fabfSAntonio Ospite 118569b10a5SAntonio Ospite return ret; 119569b10a5SAntonio Ospite } 120569b10a5SAntonio Ospite 121bd28ce00SJiri Slaby /* 122bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 123bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 124bd28ce00SJiri Slaby * events. 125bd28ce00SJiri Slaby */ 126816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 127bd28ce00SJiri Slaby { 128bd28ce00SJiri Slaby struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 129bd28ce00SJiri Slaby struct usb_device *dev = interface_to_usbdev(intf); 130bd28ce00SJiri Slaby __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 131bd28ce00SJiri Slaby int ret; 132bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 133bd28ce00SJiri Slaby 134bd28ce00SJiri Slaby if (!buf) 135bd28ce00SJiri Slaby return -ENOMEM; 136bd28ce00SJiri Slaby 137bd28ce00SJiri Slaby ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 138bd28ce00SJiri Slaby HID_REQ_GET_REPORT, 139bd28ce00SJiri Slaby USB_DIR_IN | USB_TYPE_CLASS | 140bd28ce00SJiri Slaby USB_RECIP_INTERFACE, 141bd28ce00SJiri Slaby (3 << 8) | 0xf2, ifnum, buf, 17, 142bd28ce00SJiri Slaby USB_CTRL_GET_TIMEOUT); 143bd28ce00SJiri Slaby if (ret < 0) 1444291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 145bd28ce00SJiri Slaby 146bd28ce00SJiri Slaby kfree(buf); 147bd28ce00SJiri Slaby 148bd28ce00SJiri Slaby return ret; 149bd28ce00SJiri Slaby } 150bd28ce00SJiri Slaby 151816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 152f9ce7c28SBastien Nocera { 153fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 154f9ce7c28SBastien Nocera return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); 155f9ce7c28SBastien Nocera } 156f9ce7c28SBastien Nocera 157bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 158bd28ce00SJiri Slaby { 159bd28ce00SJiri Slaby int ret; 160cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 161cc6e0bbbSJiri Kosina struct sony_sc *sc; 162cc6e0bbbSJiri Kosina 163cc6e0bbbSJiri Kosina sc = kzalloc(sizeof(*sc), GFP_KERNEL); 164cc6e0bbbSJiri Kosina if (sc == NULL) { 1654291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 166cc6e0bbbSJiri Kosina return -ENOMEM; 167cc6e0bbbSJiri Kosina } 168cc6e0bbbSJiri Kosina 169cc6e0bbbSJiri Kosina sc->quirks = quirks; 170cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 171bd28ce00SJiri Slaby 172bd28ce00SJiri Slaby ret = hid_parse(hdev); 173bd28ce00SJiri Slaby if (ret) { 1744291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 175bd28ce00SJiri Slaby goto err_free; 176bd28ce00SJiri Slaby } 177bd28ce00SJiri Slaby 17893c10132SJiri Slaby ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | 17993c10132SJiri Slaby HID_CONNECT_HIDDEV_FORCE); 180bd28ce00SJiri Slaby if (ret) { 1814291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 182bd28ce00SJiri Slaby goto err_free; 183bd28ce00SJiri Slaby } 184bd28ce00SJiri Slaby 185569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 186569b10a5SAntonio Ospite hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; 187816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 188569b10a5SAntonio Ospite } 189816651a7SAntonio Ospite else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 190816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 191816651a7SAntonio Ospite else 192f9ce7c28SBastien Nocera ret = 0; 193f9ce7c28SBastien Nocera 1944dfdc464SJiri Kosina if (ret < 0) 195bd28ce00SJiri Slaby goto err_stop; 196bd28ce00SJiri Slaby 197bd28ce00SJiri Slaby return 0; 198bd28ce00SJiri Slaby err_stop: 199bd28ce00SJiri Slaby hid_hw_stop(hdev); 200bd28ce00SJiri Slaby err_free: 201cc6e0bbbSJiri Kosina kfree(sc); 202bd28ce00SJiri Slaby return ret; 203bd28ce00SJiri Slaby } 204bd28ce00SJiri Slaby 205cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev) 206cc6e0bbbSJiri Kosina { 207cc6e0bbbSJiri Kosina hid_hw_stop(hdev); 208cc6e0bbbSJiri Kosina kfree(hid_get_drvdata(hdev)); 209cc6e0bbbSJiri Kosina } 210cc6e0bbbSJiri Kosina 211bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 212816651a7SAntonio Ospite { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 213816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_USB }, 21435dca5b4SJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 21535dca5b4SJiri Kosina .driver_data = SIXAXIS_CONTROLLER_USB }, 216816651a7SAntonio Ospite { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 217816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_BT }, 218cc6e0bbbSJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 219cc6e0bbbSJiri Kosina .driver_data = VAIO_RDESC_CONSTANT }, 220bd28ce00SJiri Slaby { } 221bd28ce00SJiri Slaby }; 222bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 223bd28ce00SJiri Slaby 224bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 225bd28ce00SJiri Slaby .name = "sony", 226bd28ce00SJiri Slaby .id_table = sony_devices, 227bd28ce00SJiri Slaby .probe = sony_probe, 228cc6e0bbbSJiri Kosina .remove = sony_remove, 229cc6e0bbbSJiri Kosina .report_fixup = sony_report_fixup, 230c9e4d877SSimon Wood .raw_event = sony_raw_event 231bd28ce00SJiri Slaby }; 232*f425458eSH Hartley Sweeten module_hid_driver(sony_driver); 233bd28ce00SJiri Slaby 234bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 235