29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
33 #include <linux/sched.h>
34 #include <linux/export.h>
35 #include <linux/slab.h>
37 #include <linux/poll.h>
39 #include <linux/hid.h>
42 static struct dentry *hid_debug_root;
51 { 0, 0,
"Undefined" },
52 { 1, 0,
"GenericDesktop" },
55 {0, 0x04,
"Joystick"},
57 {0, 0x06,
"Keyboard"},
59 {0, 0x08,
"MultiAxis"},
69 {0, 0x39,
"HatSwitch"},
70 {0, 0x3a,
"CountedBuffer"},
71 {0, 0x3b,
"ByteCount"},
72 {0, 0x3c,
"MotionWakeup"},
82 {0, 0x80,
"SystemControl"},
83 {0, 0x81,
"SystemPowerDown"},
84 {0, 0x82,
"SystemSleep"},
85 {0, 0x83,
"SystemWakeUp"},
86 {0, 0x84,
"SystemContextMenu"},
87 {0, 0x85,
"SystemMainMenu"},
88 {0, 0x86,
"SystemAppMenu"},
89 {0, 0x87,
"SystemMenuHelp"},
90 {0, 0x88,
"SystemMenuExit"},
91 {0, 0x89,
"SystemMenuSelect"},
92 {0, 0x8a,
"SystemMenuRight"},
93 {0, 0x8b,
"SystemMenuLeft"},
94 {0, 0x8c,
"SystemMenuUp"},
95 {0, 0x8d,
"SystemMenuDown"},
97 {0, 0x91,
"D-PadDown"},
98 {0, 0x92,
"D-PadRight"},
99 {0, 0x93,
"D-PadLeft"},
100 { 2, 0,
"Simulation" },
101 {0, 0xb0,
"Aileron"},
102 {0, 0xb1,
"AileronTrim"},
103 {0, 0xb2,
"Anti-Torque"},
104 {0, 0xb3,
"Autopilot"},
106 {0, 0xb5,
"Collective"},
107 {0, 0xb6,
"DiveBrake"},
108 {0, 0xb7,
"ElectronicCountermeasures"},
109 {0, 0xb8,
"Elevator"},
110 {0, 0xb9,
"ElevatorTrim"},
112 {0, 0xbb,
"Throttle"},
113 {0, 0xbc,
"FlightCommunications"},
114 {0, 0xbd,
"FlareRelease"},
115 {0, 0xbe,
"LandingGear"},
116 {0, 0xbf,
"ToeBrake"},
117 { 6, 0,
"GenericDeviceControls" },
118 {0, 0x20,
"BatteryStrength" },
119 {0, 0x21,
"WirelessChannel" },
120 {0, 0x22,
"WirelessID" },
121 {0, 0x23,
"DiscoverWirelessControl" },
122 {0, 0x24,
"SecurityCodeCharacterEntered" },
123 {0, 0x25,
"SecurityCodeCharactedErased" },
124 {0, 0x26,
"SecurityCodeCleared" },
125 { 7, 0,
"Keyboard" },
127 {0, 0x01,
"NumLock"},
128 {0, 0x02,
"CapsLock"},
129 {0, 0x03,
"ScrollLock"},
130 {0, 0x04,
"Compose"},
132 {0, 0x4b,
"GenericIndicator"},
134 { 10, 0,
"Ordinal" },
135 { 12, 0,
"Consumer" },
136 {0, 0x238,
"HorizontalWheel"},
137 { 13, 0,
"Digitizers" },
138 {0, 0x01,
"Digitizer"},
140 {0, 0x03,
"LightPen"},
141 {0, 0x04,
"TouchScreen"},
142 {0, 0x05,
"TouchPad"},
146 {0, 0x30,
"TipPressure"},
147 {0, 0x31,
"BarrelPressure"},
148 {0, 0x32,
"InRange"},
150 {0, 0x34,
"UnTouch"},
152 {0, 0x39,
"TabletFunctionKey"},
153 {0, 0x3a,
"ProgramChangeKey"},
155 {0, 0x42,
"TipSwitch"},
156 {0, 0x43,
"SecondaryTipSwitch"},
157 {0, 0x44,
"BarrelSwitch"},
159 {0, 0x46,
"TabletPick"},
160 {0, 0x47,
"Confidence"},
163 {0, 0x51,
"ContactID"},
164 {0, 0x52,
"InputMode"},
165 {0, 0x53,
"DeviceIndex"},
166 {0, 0x54,
"ContactCount"},
167 {0, 0x55,
"ContactMaximumNumber"},
168 { 15, 0,
"PhysicalInterfaceDevice" },
169 {0, 0x00,
"Undefined"},
170 {0, 0x01,
"Physical_Interface_Device"},
172 {0, 0x21,
"Set_Effect_Report"},
173 {0, 0x22,
"Effect_Block_Index"},
174 {0, 0x23,
"Parameter_Block_Offset"},
175 {0, 0x24,
"ROM_Flag"},
176 {0, 0x25,
"Effect_Type"},
177 {0, 0x26,
"ET_Constant_Force"},
178 {0, 0x27,
"ET_Ramp"},
179 {0, 0x28,
"ET_Custom_Force_Data"},
180 {0, 0x30,
"ET_Square"},
181 {0, 0x31,
"ET_Sine"},
182 {0, 0x32,
"ET_Triangle"},
183 {0, 0x33,
"ET_Sawtooth_Up"},
184 {0, 0x34,
"ET_Sawtooth_Down"},
185 {0, 0x40,
"ET_Spring"},
186 {0, 0x41,
"ET_Damper"},
187 {0, 0x42,
"ET_Inertia"},
188 {0, 0x43,
"ET_Friction"},
189 {0, 0x50,
"Duration"},
190 {0, 0x51,
"Sample_Period"},
192 {0, 0x53,
"Trigger_Button"},
193 {0, 0x54,
"Trigger_Repeat_Interval"},
194 {0, 0x55,
"Axes_Enable"},
195 {0, 0x56,
"Direction_Enable"},
196 {0, 0x57,
"Direction"},
197 {0, 0x58,
"Type_Specific_Block_Offset"},
198 {0, 0x59,
"Block_Type"},
199 {0, 0x5A,
"Set_Envelope_Report"},
200 {0, 0x5B,
"Attack_Level"},
201 {0, 0x5C,
"Attack_Time"},
202 {0, 0x5D,
"Fade_Level"},
203 {0, 0x5E,
"Fade_Time"},
204 {0, 0x5F,
"Set_Condition_Report"},
205 {0, 0x60,
"CP_Offset"},
206 {0, 0x61,
"Positive_Coefficient"},
207 {0, 0x62,
"Negative_Coefficient"},
208 {0, 0x63,
"Positive_Saturation"},
209 {0, 0x64,
"Negative_Saturation"},
210 {0, 0x65,
"Dead_Band"},
211 {0, 0x66,
"Download_Force_Sample"},
212 {0, 0x67,
"Isoch_Custom_Force_Enable"},
213 {0, 0x68,
"Custom_Force_Data_Report"},
214 {0, 0x69,
"Custom_Force_Data"},
215 {0, 0x6A,
"Custom_Force_Vendor_Defined_Data"},
216 {0, 0x6B,
"Set_Custom_Force_Report"},
217 {0, 0x6C,
"Custom_Force_Data_Offset"},
218 {0, 0x6D,
"Sample_Count"},
219 {0, 0x6E,
"Set_Periodic_Report"},
221 {0, 0x70,
"Magnitude"},
224 {0, 0x73,
"Set_Constant_Force_Report"},
225 {0, 0x74,
"Set_Ramp_Force_Report"},
226 {0, 0x75,
"Ramp_Start"},
227 {0, 0x76,
"Ramp_End"},
228 {0, 0x77,
"Effect_Operation_Report"},
229 {0, 0x78,
"Effect_Operation"},
230 {0, 0x79,
"Op_Effect_Start"},
231 {0, 0x7A,
"Op_Effect_Start_Solo"},
232 {0, 0x7B,
"Op_Effect_Stop"},
233 {0, 0x7C,
"Loop_Count"},
234 {0, 0x7D,
"Device_Gain_Report"},
235 {0, 0x7E,
"Device_Gain"},
236 {0, 0x7F,
"PID_Pool_Report"},
237 {0, 0x80,
"RAM_Pool_Size"},
238 {0, 0x81,
"ROM_Pool_Size"},
239 {0, 0x82,
"ROM_Effect_Block_Count"},
240 {0, 0x83,
"Simultaneous_Effects_Max"},
241 {0, 0x84,
"Pool_Alignment"},
242 {0, 0x85,
"PID_Pool_Move_Report"},
243 {0, 0x86,
"Move_Source"},
244 {0, 0x87,
"Move_Destination"},
245 {0, 0x88,
"Move_Length"},
246 {0, 0x89,
"PID_Block_Load_Report"},
247 {0, 0x8B,
"Block_Load_Status"},
248 {0, 0x8C,
"Block_Load_Success"},
249 {0, 0x8D,
"Block_Load_Full"},
250 {0, 0x8E,
"Block_Load_Error"},
251 {0, 0x8F,
"Block_Handle"},
252 {0, 0x90,
"PID_Block_Free_Report"},
253 {0, 0x91,
"Type_Specific_Block_Handle"},
254 {0, 0x92,
"PID_State_Report"},
255 {0, 0x94,
"Effect_Playing"},
256 {0, 0x95,
"PID_Device_Control_Report"},
257 {0, 0x96,
"PID_Device_Control"},
258 {0, 0x97,
"DC_Enable_Actuators"},
259 {0, 0x98,
"DC_Disable_Actuators"},
260 {0, 0x99,
"DC_Stop_All_Effects"},
261 {0, 0x9A,
"DC_Device_Reset"},
262 {0, 0x9B,
"DC_Device_Pause"},
263 {0, 0x9C,
"DC_Device_Continue"},
264 {0, 0x9F,
"Device_Paused"},
265 {0, 0xA0,
"Actuators_Enabled"},
266 {0, 0xA4,
"Safety_Switch"},
267 {0, 0xA5,
"Actuator_Override_Switch"},
268 {0, 0xA6,
"Actuator_Power"},
269 {0, 0xA7,
"Start_Delay"},
270 {0, 0xA8,
"Parameter_Block_Size"},
271 {0, 0xA9,
"Device_Managed_Pool"},
272 {0, 0xAA,
"Shared_Parameter_Blocks"},
273 {0, 0xAB,
"Create_New_Effect_Report"},
274 {0, 0xAC,
"RAM_Pool_Available"},
275 { 0x84, 0,
"Power Device" },
276 { 0x84, 0x02,
"PresentStatus" },
277 { 0x84, 0x03,
"ChangeStatus" },
278 { 0x84, 0x04,
"UPS" },
279 { 0x84, 0x05,
"PowerSupply" },
280 { 0x84, 0x10,
"BatterySystem" },
281 { 0x84, 0x11,
"BatterySystemID" },
282 { 0x84, 0x12,
"Battery" },
283 { 0x84, 0x13,
"BatteryID" },
284 { 0x84, 0x14,
"Charger" },
285 { 0x84, 0x15,
"ChargerID" },
286 { 0x84, 0x16,
"PowerConverter" },
287 { 0x84, 0x17,
"PowerConverterID" },
288 { 0x84, 0x18,
"OutletSystem" },
289 { 0x84, 0x19,
"OutletSystemID" },
290 { 0x84, 0x1a,
"Input" },
291 { 0x84, 0x1b,
"InputID" },
292 { 0x84, 0x1c,
"Output" },
293 { 0x84, 0x1d,
"OutputID" },
294 { 0x84, 0x1e,
"Flow" },
295 { 0x84, 0x1f,
"FlowID" },
296 { 0x84, 0x20,
"Outlet" },
297 { 0x84, 0x21,
"OutletID" },
298 { 0x84, 0x22,
"Gang" },
299 { 0x84, 0x24,
"PowerSummary" },
300 { 0x84, 0x25,
"PowerSummaryID" },
301 { 0x84, 0x30,
"Voltage" },
302 { 0x84, 0x31,
"Current" },
303 { 0x84, 0x32,
"Frequency" },
304 { 0x84, 0x33,
"ApparentPower" },
305 { 0x84, 0x35,
"PercentLoad" },
306 { 0x84, 0x40,
"ConfigVoltage" },
307 { 0x84, 0x41,
"ConfigCurrent" },
308 { 0x84, 0x43,
"ConfigApparentPower" },
309 { 0x84, 0x53,
"LowVoltageTransfer" },
310 { 0x84, 0x54,
"HighVoltageTransfer" },
311 { 0x84, 0x56,
"DelayBeforeStartup" },
312 { 0x84, 0x57,
"DelayBeforeShutdown" },
313 { 0x84, 0x58,
"Test" },
314 { 0x84, 0x5a,
"AudibleAlarmControl" },
315 { 0x84, 0x60,
"Present" },
316 { 0x84, 0x61,
"Good" },
317 { 0x84, 0x62,
"InternalFailure" },
318 { 0x84, 0x65,
"Overload" },
319 { 0x84, 0x66,
"OverCharged" },
320 { 0x84, 0x67,
"OverTemperature" },
321 { 0x84, 0x68,
"ShutdownRequested" },
322 { 0x84, 0x69,
"ShutdownImminent" },
323 { 0x84, 0x6b,
"SwitchOn/Off" },
324 { 0x84, 0x6c,
"Switchable" },
325 { 0x84, 0x6d,
"Used" },
326 { 0x84, 0x6e,
"Boost" },
327 { 0x84, 0x73,
"CommunicationLost" },
328 { 0x84, 0xfd,
"iManufacturer" },
329 { 0x84, 0xfe,
"iProduct" },
330 { 0x84, 0xff,
"iSerialNumber" },
331 { 0x85, 0,
"Battery System" },
332 { 0x85, 0x01,
"SMBBatteryMode" },
333 { 0x85, 0x02,
"SMBBatteryStatus" },
334 { 0x85, 0x03,
"SMBAlarmWarning" },
335 { 0x85, 0x04,
"SMBChargerMode" },
336 { 0x85, 0x05,
"SMBChargerStatus" },
337 { 0x85, 0x06,
"SMBChargerSpecInfo" },
338 { 0x85, 0x07,
"SMBSelectorState" },
339 { 0x85, 0x08,
"SMBSelectorPresets" },
340 { 0x85, 0x09,
"SMBSelectorInfo" },
341 { 0x85, 0x29,
"RemainingCapacityLimit" },
342 { 0x85, 0x2c,
"CapacityMode" },
343 { 0x85, 0x42,
"BelowRemainingCapacityLimit" },
344 { 0x85, 0x44,
"Charging" },
345 { 0x85, 0x45,
"Discharging" },
346 { 0x85, 0x4b,
"NeedReplacement" },
347 { 0x85, 0x66,
"RemainingCapacity" },
348 { 0x85, 0x68,
"RunTimeToEmpty" },
349 { 0x85, 0x6a,
"AverageTimeToFull" },
350 { 0x85, 0x83,
"DesignCapacity" },
351 { 0x85, 0x85,
"ManufacturerDate" },
352 { 0x85, 0x89,
"iDeviceChemistry" },
353 { 0x85, 0x8b,
"Rechargeable" },
354 { 0x85, 0x8f,
"iOEMInformation" },
355 { 0x85, 0x8d,
"CapacityGranularity1" },
356 { 0x85, 0xd0,
"ACPresent" },
358 { 0xffff, 0,
"Vendor-specific-FF" },
371 static char *resolv_usage_page(
unsigned page,
struct seq_file *
f) {
382 if (p->
page == page) {
405 buf = resolv_usage_page(usage >> 16, f);
407 pr_err(
"error allocating HID debug buffer\n");
421 if (p->
page == (usage >> 16)) {
423 if (p->
usage == (usage & 0xffff)) {
438 "%04x", usage & 0xffff);
445 static void tab(
int n,
struct seq_file *f) {
468 for (j = 0; j < field->
maxusage; j++) {
483 static const char *systems[5] = {
"None",
"SI Linear",
"SI Rotation",
"English Linear",
"English Rotation" };
484 static const char *
units[5][8] = {
485 {
"None",
"None",
"None",
"None",
"None",
"None",
"None",
"None" },
486 {
"None",
"Centimeter",
"Gram",
"Seconds",
"Kelvin",
"Ampere",
"Candela",
"None" },
487 {
"None",
"Radians",
"Gram",
"Seconds",
"Kelvin",
"Ampere",
"Candela",
"None" },
488 {
"None",
"Inch",
"Slug",
"Seconds",
"Fahrenheit",
"Ampere",
"Candela",
"None" },
489 {
"None",
"Degrees",
"Slug",
"Seconds",
"Fahrenheit",
"Ampere",
"Candela",
"None" }
504 int earlier_unit = 0;
506 tab(n, f);
seq_printf(f,
"Unit(%s : ", systems[sys]);
508 for (i=1 ; i<
sizeof(
__u32)*2 ; i++) {
509 char nibble = data & 0xf;
512 if(earlier_unit++ > 0)
518 int val = nibble & 0x7;
520 val = -((0x7 & ~val) +1);
553 static const char *
table[] = {
"INPUT",
"OUTPUT",
"FEATURE"};
566 for (k = 0; k < report->
maxfield; k++) {
581 struct hid_debug_list *
list;
584 for (i = 0; i <
strlen(buf); i++)
622 static const char *syncs[3] = {
627 static const char *keys[
KEY_MAX + 1] = {
824 static const char *relatives[
REL_MAX + 1] = {
832 static const char *absolutes[
ABS_CNT] = {
857 static const char *misc[
MSC_MAX + 1] = {
862 static const char *leds[
LED_MAX + 1] = {
870 static const char *repeats[
REP_MAX + 1] = {
874 static const char *sounds[
SND_MAX + 1] = {
879 static const char **names[
EV_MAX + 1] = {
888 seq_printf(f,
"%s.%s", events[type] ? events[type] :
"?",
889 names[type] ? (names[type][code] ? names[type][code] :
"?") :
"?");
900 for (i = 0; i < report->
maxfield; i++) {
901 for ( j = 0; j < report->
field[
i]->maxusage; j++) {
902 usage = report->
field[
i]->usage +
j;
905 hid_resolv_event(usage->
type, usage->
code, f);
914 static int hid_debug_rdesc_show(
struct seq_file *f,
void *p)
927 for (i = 0; i <
rsize; i++)
934 hid_dump_input_mapping(hdev, f);
947 struct hid_debug_list *
list;
949 if (!(list = kzalloc(
sizeof(
struct hid_debug_list),
GFP_KERNEL))) {
969 static ssize_t hid_debug_events_read(
struct file *file,
char __user *
buffer,
970 size_t count, loff_t *ppos)
978 if (list->head == list->tail) {
982 while (list->head == list->tail) {
992 if (!list->hdev || !list->hdev->debug) {
1013 if (list->tail == list->head)
1015 if (list->tail > list->head) {
1016 len = list->tail - list->head;
1018 if (
copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
1025 len = HID_DEBUG_BUFSIZE - list->head;
1027 if (
copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
1042 static unsigned int hid_debug_events_poll(
struct file *file,
poll_table *
wait)
1046 poll_wait(file, &list->hdev->debug_wait, wait);
1047 if (list->head != list->tail)
1049 if (!list->hdev->debug)
1054 static int hid_debug_events_release(
struct inode *inode,
struct file *file)
1059 kfree(list->hid_debug_buf);
1066 .open = hid_debug_rdesc_open,
1074 .open = hid_debug_events_open,
1075 .read = hid_debug_events_read,
1076 .poll = hid_debug_events_poll,
1077 .release = hid_debug_events_release,
1086 hdev->
debug_dir, hdev, &hid_debug_rdesc_fops);
1088 hdev->
debug_dir, hdev, &hid_debug_events_fops);