* Copyright 2011 Michael Lotz <mmlr@mlotz.ch>
* Distributed under the terms of the MIT license.
*/
#include "QuirkyDevices.h"
#include "HIDWriter.h"
#include <string.h>
#include <usb/USB_hid.h>
static 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;
}
static status_t
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;
converter.main_data.array_variable = 1;
converter.main_data.no_preferred = 1;
writer.SetReportID(1);
writer.DefineInputPadding(1, 8);
writer.DefineInputData(19, 1, converter.main_data, 0, 1,
B_HID_USAGE_PAGE_BUTTON, 1);
writer.DefineInputPadding(13, 1);
writer.DefineInputData(1, 8, converter.main_data, 0, 255,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
writer.DefineInputData(1, 8, converter.main_data, 0, 255,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Y);
writer.DefineInputData(1, 8, converter.main_data, 0, 255,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
writer.DefineInputData(1, 8, converter.main_data, 0, 255,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Y);
writer.DefineInputPadding(4, 8);
writer.DefineInputData(12, 8, converter.main_data, 0, 255,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VNO, B_HID_UID_GD_VNO);
writer.DefineInputPadding(15, 8);
writer.DefineInputData(3, 16, converter.main_data, 0, UINT16_MAX,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VX);
writer.DefineInputData(1, 16, converter.main_data, 0, UINT16_MAX,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VBRZ);
return writer.EndCollection();
}
static status_t
elecom_build_descriptor(HIDWriter &writer)
{
uint8 patchedDescriptor[] = {
0x05, 0x01,
0x09, 0x02,
0xA1, 0x01,
0x09, 0x01,
0xA1, 0x00,
0x85, 0x01,
0x95, 0x06,
0x75, 0x01,
0x05, 0x09,
0x19, 0x01,
0x29, 0x06,
0x15, 0x00,
0x25, 0x01,
0x81, 0x02,
0x95, 0x01,
0x75, 0x02,
0x81, 0x01,
0x75, 0x10,
0x95, 0x02,
0x05, 0x01,
0x09, 0x30,
0x09, 0x31,
0x16, 0x00, 0x80,
0x26, 0xFF, 0x7F,
0x81, 0x06,
0xC0,
0xA1, 0x00,
0x95, 0x01,
0x75, 0x08,
0x05, 0x01,
0x09, 0x38,
0x15, 0x81,
0x25, 0x7F,
0x81, 0x06,
0xC0,
0xA1, 0x00,
0x95, 0x01,
0x75, 0x08,
0x05, 0x0C,
0x0A, 0x38, 0x02,
0x15, 0x81,
0x25, 0x7F,
0x81, 0x06,
0xC0,
0xC0,
0x06, 0x01, 0xFF,
0x09, 0x00,
0xA1, 0x01,
0x85, 0x02,
0x09, 0x00,
0x15, 0x00,
0x26, 0xFF, 0x00,
0x75, 0x08,
0x95, 0x07,
0x81, 0x02,
0xC0,
0x05, 0x0C,
0x09, 0x01,
0xA1, 0x01,
0x85, 0x05,
0x19, 0x00,
0x2A, 0x3C, 0x02,
0x15, 0x00,
0x26, 0x3C, 0x02,
0x95, 0x01,
0x75, 0x10,
0x81, 0x00,
0xC0,
0x05, 0x01,
0x09, 0x80,
0xA1, 0x01,
0x85, 0x03,
0x19, 0x81,
0x29, 0x83,
0x15, 0x00,
0x25, 0x01,
0x75, 0x01,
0x95, 0x03,
0x81, 0x02,
0x95, 0x05,
0x81, 0x01,
0xC0,
0x06, 0xBC, 0xFF,
0x09, 0x88,
0xA1, 0x01,
0x85, 0x04,
0x95, 0x01,
0x75, 0x08,
0x15, 0x00,
0x26, 0xFF, 0x00,
0x19, 0x00,
0x2A, 0xFF, 0x00,
0x81, 0x00,
0xC0,
0x06, 0x02, 0xFF,
0x09, 0x02,
0xA1, 0x01,
0x85, 0x06,
0x09, 0x02,
0x15, 0x00,
0x26, 0xFF, 0x00,
0x75, 0x08,
0x95, 0x07,
0xB1, 0x02,
0xC0,
};
return writer.Write(&patchedDescriptor, sizeof(patchedDescriptor));
}
static status_t
xbox360_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;
converter.main_data.array_variable = 1;
converter.main_data.no_preferred = 1;
writer.DefineInputPadding(2, 8);
writer.DefineInputData(11, 1, converter.main_data, 0, 1,
B_HID_USAGE_PAGE_BUTTON, 1);
writer.DefineInputPadding(1, 1);
writer.DefineInputData(4, 1, converter.main_data, 0, 1,
B_HID_USAGE_PAGE_BUTTON, 12);
writer.DefineInputData(1, 8, converter.main_data, 0, 255,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Z);
writer.DefineInputData(1, 8, converter.main_data, 0, 255,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_RZ);
writer.DefineInputData(2, 16, converter.main_data, -32768, 32767,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
writer.DefineInputData(2, 16, converter.main_data, -32768, 32767,
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
writer.DefineInputPadding(6, 8);
return writer.EndCollection();
}
usb_hid_quirky_device gQuirkyDevices[] = {
{
0x054c, 0x0268, USB_INTERFACE_CLASS_HID, 0, 0,
sixaxis_init, sixaxis_build_descriptor
},
{
0x056e, 0x00fd, USB_INTERFACE_CLASS_HID, 0, 0,
NULL, elecom_build_descriptor
},
{
0, 0, 0xff , 0x5d , 0x01,
NULL, xbox360_build_descriptor
}
};
int32 gQuirkyDeviceCount
= sizeof(gQuirkyDevices) / sizeof(gQuirkyDevices[0]);