X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=drivers%2Fhid%2Fhid-sony.c;h=677bb3da10e8d4149d5d6583f943f6a767c9d3c1;hp=9fa03491518554559a5bd385f6f29c64188351ce;hb=8b66a16f25f819bb1f132f075c5c01a288776cf8;hpb=41fa92302be7fa37c5c38e17e2097d3e5e9da13a diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 9fa034915185..677bb3da10e8 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -24,7 +24,9 @@ #include "hid-ids.h" -#define VAIO_RDESC_CONSTANT 0x0001 +#define VAIO_RDESC_CONSTANT (1 << 0) +#define SIXAXIS_CONTROLLER_USB (1 << 1) +#define SIXAXIS_CONTROLLER_BT (1 << 2) struct sony_sc { unsigned long quirks; @@ -45,12 +47,31 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, return rdesc; } +static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, + size_t count, unsigned char report_type) +{ + struct usb_interface *intf = to_usb_interface(hid->dev.parent); + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *interface = intf->cur_altsetting; + int report_id = buf[0]; + int ret; + + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + HID_REQ_SET_REPORT, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + ((report_type + 1) << 8) | report_id, + interface->desc.bInterfaceNumber, buf, count, + USB_CTRL_SET_TIMEOUT); + + return ret; +} + /* * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller * to "operational". Without this, the ps3 controller will not report any * events. */ -static int sony_set_operational_usb(struct hid_device *hdev) +static int sixaxis_set_operational_usb(struct hid_device *hdev) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct usb_device *dev = interface_to_usbdev(intf); @@ -75,7 +96,7 @@ static int sony_set_operational_usb(struct hid_device *hdev) return ret; } -static int sony_set_operational_bt(struct hid_device *hdev) +static int sixaxis_set_operational_bt(struct hid_device *hdev) { unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); @@ -109,16 +130,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_free; } - switch (hdev->bus) { - case BUS_USB: - ret = sony_set_operational_usb(hdev); - break; - case BUS_BLUETOOTH: - ret = sony_set_operational_bt(hdev); - break; - default: - ret = 0; + if (sc->quirks & SIXAXIS_CONTROLLER_USB) { + hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; + ret = sixaxis_set_operational_usb(hdev); } + else if (sc->quirks & SIXAXIS_CONTROLLER_BT) + ret = sixaxis_set_operational_bt(hdev); + else + ret = 0; if (ret < 0) goto err_stop; @@ -138,8 +157,10 @@ static void sony_remove(struct hid_device *hdev) } static const struct hid_device_id sony_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), + .driver_data = SIXAXIS_CONTROLLER_USB }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), + .driver_data = SIXAXIS_CONTROLLER_BT }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), .driver_data = VAIO_RDESC_CONSTANT }, { }