Ticket #15051: QuirkyDevices.cpp

File QuirkyDevices.cpp, 5.2 KB (added by MelanieFox, 5 years ago)
Line 
1/*
2 * Copyright 2011 Michael Lotz <mmlr@mlotz.ch>
3 * Distributed under the terms of the MIT license.
4 */
5
6
7#include "QuirkyDevices.h"
8
9#include "HIDWriter.h"
10
11#include <string.h>
12
13#include <usb/USB_hid.h>
14
15static status_t
16sixaxis_init(usb_device device, const usb_configuration_info *config,
17 size_t interfaceIndex)
18{
19 TRACE_ALWAYS("found SIXAXIS controller, putting it in operational mode\n");
20
21 // an extra get_report is required for the SIXAXIS to become operational
22 uint8 dummy[18];
23 status_t result = gUSBModule->send_request(device, USB_REQTYPE_INTERFACE_IN
24 | USB_REQTYPE_CLASS, B_USB_REQUEST_HID_GET_REPORT, 0x03f2 /* ? */,
25 interfaceIndex, sizeof(dummy), dummy, NULL);
26 if (result != B_OK) {
27 TRACE_ALWAYS("failed to set operational mode: %s\n", strerror(result));
28 }
29
30 return result;
31}
32
33
34static status_t
35sixaxis_build_descriptor(HIDWriter &writer)
36{
37 writer.BeginCollection(COLLECTION_APPLICATION,
38 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_JOYSTICK);
39
40 main_item_data_converter converter;
41 converter.flat_data = 0; // defaults
42 converter.main_data.array_variable = 1;
43 converter.main_data.no_preferred = 1;
44
45 writer.SetReportID(1);
46
47 // unknown / padding
48 writer.DefineInputPadding(1, 8);
49
50 // digital button state on/off
51 writer.DefineInputData(19, 1, converter.main_data, 0, 1,
52 B_HID_USAGE_PAGE_BUTTON, 1);
53
54 // padding to 32 bit boundary
55 writer.DefineInputPadding(13, 1);
56
57 // left analog stick
58 writer.DefineInputData(1, 8, converter.main_data, 0, 255,
59 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
60 writer.DefineInputData(1, 8, converter.main_data, 0, 255,
61 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Y);
62
63 // right analog stick
64 writer.DefineInputData(1, 8, converter.main_data, 0, 255,
65 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
66 writer.DefineInputData(1, 8, converter.main_data, 0, 255,
67 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Y);
68
69 // unknown / padding
70 writer.DefineInputPadding(4, 8);
71
72 // pressure sensitive button states
73 writer.DefineInputData(12, 8, converter.main_data, 0, 255,
74 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VNO, B_HID_UID_GD_VNO);
75
76 // unknown / padding / operation mode / battery status / connection ...
77 writer.DefineInputPadding(15, 8);
78
79 // accelerometer x, y and z
80 writer.DefineInputData(3, 16, converter.main_data, 0, UINT16_MAX,
81 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VX);
82
83 // gyroscope
84 writer.DefineInputData(1, 16, converter.main_data, 0, UINT16_MAX,
85 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_VBRZ);
86
87 return writer.EndCollection();
88}
89
90
91static status_t
92xbox360_build_descriptor(HIDWriter &writer)
93{
94 writer.BeginCollection(COLLECTION_APPLICATION,
95 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_JOYSTICK);
96
97 main_item_data_converter converter;
98 converter.flat_data = 0; // defaults
99 converter.main_data.array_variable = 1;
100 converter.main_data.no_preferred = 1;
101
102 // unknown / padding / byte count
103 writer.DefineInputPadding(2, 8);
104
105 // dpad / buttons
106 writer.DefineInputData(11, 1, converter.main_data, 0, 1,
107 B_HID_USAGE_PAGE_BUTTON, 1);
108 writer.DefineInputPadding(1, 1);
109 writer.DefineInputData(4, 1, converter.main_data, 0, 1,
110 B_HID_USAGE_PAGE_BUTTON, 12);
111
112 // triggers
113 writer.DefineInputData(1, 8, converter.main_data, 0, 255,
114 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Z);
115 writer.DefineInputData(1, 8, converter.main_data, 0, 255,
116 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_RZ);
117
118 // sticks
119 writer.DefineInputData(2, 16, converter.main_data, -32768, 32767,
120 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
121 writer.DefineInputData(2, 16, converter.main_data, -32768, 32767,
122 B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
123
124 // unknown / padding
125 writer.DefineInputPadding(6, 8);
126
127 return writer.EndCollection();
128}
129
130static status_t decus_build_descriptor(HIDWriter &writer)
131{
132 uint8 rdesc[66] = {
1330x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x85, 0x01, 0x09, 0x01, 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01,
1340x29, 0x05, 0x15, 0x00, 0x25, 0x01, 0x95, 0x05, 0x75, 0x01, 0x81, 0x02, 0x95, 0x03, 0x75, 0x01,
1350x81, 0x03, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x16, 0x00, 0x80, 0x26, 0xFF, 0x7F, 0x75, 0x10,
1360x95, 0x02, 0x81, 0x06, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06,
1370xC0, 0xC0
138 };
139
140 return writer.Write( &rdesc, sizeof( rdesc ));
141}
142
143usb_hid_quirky_device gQuirkyDevices[] = {
144 {
145 // The Sony SIXAXIS controller (PS3) needs a GET_REPORT to become
146 // operational which we do in sixaxis_init. Also the normal report
147 // descriptor doesn't contain items for the motion sensing data
148 // and pressure sensitive buttons, so we constrcut a new report
149 // descriptor that includes those extra items.
150 0x054c, 0x0268, USB_INTERFACE_CLASS_HID, 0, 0,
151 sixaxis_init, sixaxis_build_descriptor
152 },
153
154 {
155 // XBOX 360 controllers aren't really HID (marked vendor specific).
156 // They therefore don't provide a HID/report descriptor either. The
157 // input stream is HID-like enough though. We therefore claim support
158 // and build a report descriptor of our own.
159 0, 0, 0xff /* vendor specific */, 0x5d /* XBOX controller */, 0x01,
160 NULL, xbox360_build_descriptor
161 },
162 {
163 0x1ea7, 0x1006, USB_INTERFACE_CLASS_HID, 0x01, 0x02, NULL, decus_build_descriptor
164 }
165};
166
167int32 gQuirkyDeviceCount
168 = sizeof(gQuirkyDevices) / sizeof(gQuirkyDevices[0]);