* 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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -16,6 +16,8 @@ KernelAddon usb_hid :
|
||||
HIDReport.cpp
|
||||
HIDReportItem.cpp
|
||||
|
||||
QuirkyDevices.cpp
|
||||
|
||||
ProtocolHandler.cpp
|
||||
|
||||
JoystickProtocolHandler.cpp
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2011 Michael Lotz <[email protected]>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
|
||||
#include "QuirkyDevices.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <usb/USB_hid.h>
|
||||
|
||||
|
||||
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]);
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user