* Reimplement the descriptor patching mechanism for quirky devices by a function
to build a new descriptor using a HIDWriter. This way a completely new descriptor can be built on the fly or a fixed already patched blob can be written to the writer if desired. * Implemented writing a new report descriptor for Sony SIXAXIS controllers. The descriptor also includes the pressure sensitive button states (exposed as 12 axes) and the accelerometers/gyroscope (exposed as another 4 axes). While the motion sensing data is now available (and fun to look at), the usefulness is fairly limited, as the values are not scaled/transformed in any way. It might be possible to generically do such transformations using unit descriptions, but those are not implemented yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41925 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
517851a173
commit
d3260cdb5f
@ -10,6 +10,7 @@
|
|||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
#include "HIDDevice.h"
|
#include "HIDDevice.h"
|
||||||
#include "HIDReport.h"
|
#include "HIDReport.h"
|
||||||
|
#include "HIDWriter.h"
|
||||||
#include "ProtocolHandler.h"
|
#include "ProtocolHandler.h"
|
||||||
#include "QuirkyDevices.h"
|
#include "QuirkyDevices.h"
|
||||||
|
|
||||||
@ -39,25 +40,29 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config,
|
|||||||
{
|
{
|
||||||
uint8 *reportDescriptor = NULL;
|
uint8 *reportDescriptor = NULL;
|
||||||
size_t descriptorLength = 0;
|
size_t descriptorLength = 0;
|
||||||
quirky_init_function quirkyInit = NULL;
|
|
||||||
bool hasFixedDescriptor = false;
|
|
||||||
|
|
||||||
const usb_device_descriptor *deviceDescriptor
|
const usb_device_descriptor *deviceDescriptor
|
||||||
= gUSBModule->get_device_descriptor(device);
|
= gUSBModule->get_device_descriptor(device);
|
||||||
|
|
||||||
// check for quirky devices first and don't bother in that case
|
// check for quirky devices first and don't bother in that case
|
||||||
|
HIDWriter descriptorWriter;
|
||||||
|
bool hasFixedDescriptor = false;
|
||||||
|
quirky_init_function quirkyInit = NULL;
|
||||||
for (int32 i = 0; i < gQuirkyDeviceCount; i++) {
|
for (int32 i = 0; i < gQuirkyDeviceCount; i++) {
|
||||||
usb_hid_quirky_device &quirky = gQuirkyDevices[i];
|
usb_hid_quirky_device &quirky = gQuirkyDevices[i];
|
||||||
if (deviceDescriptor->vendor_id == quirky.vendor_id
|
if (deviceDescriptor->vendor_id == quirky.vendor_id
|
||||||
&& deviceDescriptor->product_id == quirky.product_id) {
|
&& deviceDescriptor->product_id == quirky.product_id) {
|
||||||
|
|
||||||
quirkyInit = quirky.init_function;
|
quirkyInit = quirky.init_function;
|
||||||
if (quirky.fixed_descriptor != NULL) {
|
if (quirky.build_descriptor != NULL
|
||||||
reportDescriptor = (uint8 *)quirky.fixed_descriptor;
|
&& quirky.build_descriptor(descriptorWriter) == B_OK) {
|
||||||
descriptorLength = quirky.descriptor_length;
|
|
||||||
|
reportDescriptor = (uint8 *)descriptorWriter.Buffer();
|
||||||
|
descriptorLength = descriptorWriter.BufferLength();
|
||||||
hasFixedDescriptor = true;
|
hasFixedDescriptor = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,16 +6,20 @@
|
|||||||
|
|
||||||
#include "QuirkyDevices.h"
|
#include "QuirkyDevices.h"
|
||||||
|
|
||||||
|
#include "HIDWriter.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <usb/USB_hid.h>
|
#include <usb/USB_hid.h>
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
sixaxis_init(usb_device device, const usb_configuration_info *config,
|
sixaxis_init(usb_device device, const usb_configuration_info *config,
|
||||||
size_t interfaceIndex)
|
size_t interfaceIndex)
|
||||||
{
|
{
|
||||||
TRACE_ALWAYS("found SIXAXIS controller, putting it in operational mode\n");
|
TRACE_ALWAYS("found SIXAXIS controller, putting it in operational mode\n");
|
||||||
|
|
||||||
|
// an extra get_report is required for the SIXAXIS to become operational
|
||||||
uint8 dummy[18];
|
uint8 dummy[18];
|
||||||
status_t result = gUSBModule->send_request(device, USB_REQTYPE_INTERFACE_IN
|
status_t result = gUSBModule->send_request(device, USB_REQTYPE_INTERFACE_IN
|
||||||
| USB_REQTYPE_CLASS, B_USB_REQUEST_HID_GET_REPORT, 0x03f2 /* ? */,
|
| USB_REQTYPE_CLASS, B_USB_REQUEST_HID_GET_REPORT, 0x03f2 /* ? */,
|
||||||
@ -28,12 +32,64 @@ sixaxis_init(usb_device device, const usb_configuration_info *config,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define ADD_QUIRKY_DEVICE(vendorID, productID, descriptor, init) \
|
static status_t
|
||||||
{ vendorID, productID, sizeof(descriptor), descriptor, init }
|
sixaxis_build_descriptor(HIDWriter &writer)
|
||||||
|
{
|
||||||
|
writer.BeginCollection(COLLECTION_APPLICATION,
|
||||||
|
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_JOYSTICK);
|
||||||
|
|
||||||
|
main_item_data_converter converter;
|
||||||
|
converter.flat_data = 0; // defaults
|
||||||
|
converter.main_data.array_variable = 1;
|
||||||
|
converter.main_data.no_preferred = 1;
|
||||||
|
|
||||||
|
// unknown / padding
|
||||||
|
writer.DefineInputPadding(1, 1, 8);
|
||||||
|
|
||||||
|
// digital button state on/off
|
||||||
|
writer.DefineInputData(1, 19, 1, converter.main_data, 0, 1,
|
||||||
|
B_HID_USAGE_PAGE_BUTTON, 1);
|
||||||
|
|
||||||
|
// padding to 32 bit boundary
|
||||||
|
writer.DefineInputPadding(1, 13, 1);
|
||||||
|
|
||||||
|
// left analog stick
|
||||||
|
writer.DefineInputData(1, 1, 8, converter.main_data, 0, 255,
|
||||||
|
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
|
||||||
|
writer.DefineInputData(1, 1, 8, converter.main_data, 0, 255,
|
||||||
|
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Y);
|
||||||
|
|
||||||
|
// right analog stick
|
||||||
|
writer.DefineInputData(1, 1, 8, converter.main_data, 0, 255,
|
||||||
|
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
|
||||||
|
writer.DefineInputData(1, 1, 8, converter.main_data, 0, 255,
|
||||||
|
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Y);
|
||||||
|
|
||||||
|
// unknown / padding
|
||||||
|
writer.DefineInputPadding(1, 4, 8);
|
||||||
|
|
||||||
|
// pressure sensitive button states
|
||||||
|
writer.DefineInputData(1, 12, 8, converter.main_data, 0, 255,
|
||||||
|
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VNO, B_HID_UID_GD_VNO);
|
||||||
|
|
||||||
|
// unknown / padding / operation mode / battery status / connection ...
|
||||||
|
writer.DefineInputPadding(1, 15, 8);
|
||||||
|
|
||||||
|
// accelerometer x, y and z
|
||||||
|
writer.DefineInputData(1, 3, 16, converter.main_data, 0, UINT16_MAX,
|
||||||
|
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VX);
|
||||||
|
|
||||||
|
// gyroscope
|
||||||
|
writer.DefineInputData(1, 1, 16, converter.main_data, 0, UINT16_MAX,
|
||||||
|
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VBRZ);
|
||||||
|
|
||||||
|
return writer.EndCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
usb_hid_quirky_device gQuirkyDevices[] = {
|
usb_hid_quirky_device gQuirkyDevices[] = {
|
||||||
// Sony SIXAXIS controller (PS3) needs a GET_REPORT to become operational
|
// Sony SIXAXIS controller (PS3) needs a GET_REPORT to become operational
|
||||||
ADD_QUIRKY_DEVICE(0x054c, 0x0268, NULL, sixaxis_init),
|
{ 0x054c, 0x0268, sixaxis_init, sixaxis_build_descriptor }
|
||||||
};
|
};
|
||||||
|
|
||||||
int32 gQuirkyDeviceCount
|
int32 gQuirkyDeviceCount
|
||||||
|
@ -7,15 +7,17 @@
|
|||||||
|
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
|
|
||||||
|
class HIDWriter;
|
||||||
|
|
||||||
typedef status_t (*quirky_init_function)(usb_device device,
|
typedef status_t (*quirky_init_function)(usb_device device,
|
||||||
const usb_configuration_info *config, size_t interfaceIndex);
|
const usb_configuration_info *config, size_t interfaceIndex);
|
||||||
|
typedef status_t (*quirky_build_descriptor)(HIDWriter &writer);
|
||||||
|
|
||||||
struct usb_hid_quirky_device {
|
struct usb_hid_quirky_device {
|
||||||
uint16 vendor_id;
|
uint16 vendor_id;
|
||||||
uint16 product_id;
|
uint16 product_id;
|
||||||
size_t descriptor_length;
|
|
||||||
const uint8 * fixed_descriptor;
|
|
||||||
quirky_init_function init_function;
|
quirky_init_function init_function;
|
||||||
|
quirky_build_descriptor build_descriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern usb_hid_quirky_device gQuirkyDevices[];
|
extern usb_hid_quirky_device gQuirkyDevices[];
|
||||||
|
Loading…
Reference in New Issue
Block a user