From 6e53f9a99099590f263fab95a742ab6160b1b1a8 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 4 Jun 2011 12:47:02 +0000 Subject: [PATCH] * Make the quirky device mechanism a bit more useful by allowing an init function that is triggered before the protocol handlers are added. * Use the quirky device mechanism to support the Sony SIXAXIS controller (the PS3 one). It requires a specific get_report to become operational. Note that you still have to push the PS button to enable it after plugging in. Note also that only the two analog sticks are reported as axis, the analog values of the buttons as well as the motion sensors aren't described by the HID descriptor and therefore aren't accessible. The digital button states (on/off only) work however. A fixed descriptor could possibly be crafted to support the missing features later on though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41902 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../drivers/input/usb_hid/HIDDevice.cpp | 29 +++++++++----- .../kernel/drivers/input/usb_hid/Jamfile | 2 + .../drivers/input/usb_hid/QuirkyDevices.cpp | 40 +++++++++++++++++++ .../drivers/input/usb_hid/QuirkyDevices.h | 25 +++++------- 4 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.cpp diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp index 9db4753d23..a7c9a7bf2a 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp @@ -39,24 +39,29 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config, { uint8 *reportDescriptor = NULL; size_t descriptorLength = 0; - bool isQuirky = false; + quirky_init_function quirkyInit = NULL; + bool hasFixedDescriptor = false; const usb_device_descriptor *deviceDescriptor = gUSBModule->get_device_descriptor(device); // check for quirky devices first and don't bother in that case - for (int32 i = 0; i < sQuirkyDeviceCount; i++) { - usb_hid_quirky_device &quirky = sQuirkyDevices[i]; + for (int32 i = 0; i < gQuirkyDeviceCount; i++) { + usb_hid_quirky_device &quirky = gQuirkyDevices[i]; if (deviceDescriptor->vendor_id == quirky.vendor_id && deviceDescriptor->product_id == quirky.product_id) { - reportDescriptor = (uint8 *)quirky.fixed_descriptor; - descriptorLength = quirky.descriptor_length; - isQuirky = true; - break; + + quirkyInit = quirky.init_function; + if (quirky.fixed_descriptor != NULL) { + reportDescriptor = (uint8 *)quirky.fixed_descriptor; + descriptorLength = quirky.descriptor_length; + hasFixedDescriptor = true; + break; + } } } - if (!isQuirky) { + if (!hasFixedDescriptor) { // conforming device, read HID and report descriptors descriptorLength = sizeof(usb_hid_descriptor); usb_hid_descriptor *hidDescriptor @@ -122,7 +127,7 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config, status_t result = fParser.ParseReportDescriptor(reportDescriptor, descriptorLength); - if (!isQuirky) + if (!hasFixedDescriptor) free(reportDescriptor); if (result != B_OK) { @@ -166,6 +171,12 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config, return; } + if (quirkyInit != NULL) { + fStatus = quirkyInit(device, config, interfaceIndex); + if (fStatus != B_OK) + return; + } + ProtocolHandler::AddHandlers(*this, fProtocolHandlerList, fProtocolHandlerCount); fStatus = B_OK; diff --git a/src/add-ons/kernel/drivers/input/usb_hid/Jamfile b/src/add-ons/kernel/drivers/input/usb_hid/Jamfile index bdccce7c81..913ccd2ea1 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/Jamfile +++ b/src/add-ons/kernel/drivers/input/usb_hid/Jamfile @@ -16,6 +16,8 @@ KernelAddon usb_hid : HIDReport.cpp HIDReportItem.cpp + QuirkyDevices.cpp + ProtocolHandler.cpp JoystickProtocolHandler.cpp diff --git a/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.cpp b/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.cpp new file mode 100644 index 0000000000..8e45e7b2e0 --- /dev/null +++ b/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.cpp @@ -0,0 +1,40 @@ +/* + * Copyright 2011 Michael Lotz + * Distributed under the terms of the MIT license. + */ + + +#include "QuirkyDevices.h" + +#include + +#include + + +status_t +sixaxis_init(usb_device device, const usb_configuration_info *config, + size_t interfaceIndex) +{ + TRACE_ALWAYS("found SIXAXIS controller, putting it in operational mode\n"); + uint8 dummy[18]; + status_t result = gUSBModule->send_request(device, USB_REQTYPE_INTERFACE_IN + | USB_REQTYPE_CLASS, B_USB_REQUEST_HID_GET_REPORT, 0x03f2 /* ? */, + interfaceIndex, sizeof(dummy), dummy, NULL); + if (result != B_OK) { + TRACE_ALWAYS("failed to set operational mode: %s\n", strerror(result)); + } + + return result; +} + + +#define ADD_QUIRKY_DEVICE(vendorID, productID, descriptor, init) \ + { vendorID, productID, sizeof(descriptor), descriptor, init } + +usb_hid_quirky_device gQuirkyDevices[] = { + // Sony SIXAXIS controller (PS3) needs a GET_REPORT to become operational + ADD_QUIRKY_DEVICE(0x054c, 0x0268, NULL, sixaxis_init), +}; + +int32 gQuirkyDeviceCount + = sizeof(gQuirkyDevices) / sizeof(gQuirkyDevices[0]); diff --git a/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h b/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h index fe7c251b85..181c10bf80 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h +++ b/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h @@ -5,23 +5,20 @@ #ifndef USB_HID_QUIRKY_DEVICES #define USB_HID_QUIRKY_DEVICES -static uint8 sDescriptorExample[] = { 0x00, 0x00 }; +#include "Driver.h" + +typedef status_t (*quirky_init_function)(usb_device device, + const usb_configuration_info *config, size_t interfaceIndex); struct usb_hid_quirky_device { - uint16 vendor_id; - uint16 product_id; - size_t descriptor_length; - const uint8 * fixed_descriptor; + uint16 vendor_id; + uint16 product_id; + size_t descriptor_length; + const uint8 * fixed_descriptor; + quirky_init_function init_function; }; -#define ADD_QUIRKY_DEVICE(vendorID, productID, descriptor) \ - { vendorID, productID, sizeof(descriptor), descriptor } - -static usb_hid_quirky_device sQuirkyDevices[] = { - ADD_QUIRKY_DEVICE(0xffff, 0xffff, sDescriptorExample) -}; - -static int32 sQuirkyDeviceCount - = sizeof(sQuirkyDevices) / sizeof(sQuirkyDevices[0]); +extern usb_hid_quirky_device gQuirkyDevices[]; +extern int32 gQuirkyDeviceCount; #endif // USB_HID_QUIRKY_DEVICES