1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * HID driver for MSI Claw Handheld PC gamepads. 4 * 5 * Provides configuration support for the MSI Claw series of handheld PC 6 * gamepads. Multiple iterations of the device firmware has led to some 7 * quirks for how certain attributes are handled. The original firmware 8 * did not support remapping of the M1 (right) and M2 (left) rear paddles. 9 * Additionally, the MCU RAM address for writing configuration data has 10 * changed twice. Checks are done during probe to enumerate these variances. 11 * 12 * Copyright (c) 2026 Zhouwang Huang <honjow311@gmail.com> 13 * Copyright (c) 2026 Denis Benato <denis.benato@linux.dev> 14 * Copyright (c) 2026 Valve Corporation 15 */ 16 17 #include <linux/array_size.h> 18 #include <linux/cleanup.h> 19 #include <linux/completion.h> 20 #include <linux/container_of.h> 21 #include <linux/delay.h> 22 #include <linux/device.h> 23 #include <linux/hid.h> 24 #include <linux/kobject.h> 25 #include <linux/leds.h> 26 #include <linux/module.h> 27 #include <linux/mutex.h> 28 #include <linux/pm.h> 29 #include <linux/spinlock.h> 30 #include <linux/sysfs.h> 31 #include <linux/types.h> 32 #include <linux/unaligned.h> 33 #include <linux/usb.h> 34 #include <linux/workqueue.h> 35 36 #include "hid-ids.h" 37 38 #define CLAW_OUTPUT_REPORT_ID 0x0f 39 #define CLAW_INPUT_REPORT_ID 0x10 40 41 #define CLAW_PACKET_SIZE 64 42 43 #define CLAW_DINPUT_CFG_INTF_IN 0x82 44 #define CLAW_XINPUT_CFG_INTF_IN 0x83 45 46 #define CLAW_KEYS_MAX 5 47 48 enum claw_command_index { 49 CLAW_COMMAND_TYPE_NONE = 0x00, 50 CLAW_COMMAND_TYPE_READ_PROFILE = 0x04, 51 CLAW_COMMAND_TYPE_READ_PROFILE_ACK = 0x05, 52 CLAW_COMMAND_TYPE_ACK = 0x06, 53 CLAW_COMMAND_TYPE_WRITE_PROFILE_DATA = 0x21, 54 CLAW_COMMAND_TYPE_SYNC_TO_ROM = 0x22, 55 CLAW_COMMAND_TYPE_SWITCH_MODE = 0x24, 56 CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE = 0x26, 57 CLAW_COMMAND_TYPE_GAMEPAD_MODE_ACK = 0x27, 58 CLAW_COMMAND_TYPE_RESET_DEVICE = 0x28, 59 }; 60 61 enum claw_gamepad_mode_index { 62 CLAW_GAMEPAD_MODE_XINPUT = 0x01, 63 CLAW_GAMEPAD_MODE_DINPUT = 0x02, 64 CLAW_GAMEPAD_MODE_DESKTOP = 0x04, 65 }; 66 67 static const char * const claw_gamepad_mode_text[] = { 68 [CLAW_GAMEPAD_MODE_XINPUT] = "xinput", 69 [CLAW_GAMEPAD_MODE_DINPUT] = "dinput", 70 [CLAW_GAMEPAD_MODE_DESKTOP] = "desktop", 71 }; 72 73 enum claw_profile_ack_pending { 74 CLAW_NO_PENDING, 75 CLAW_M1_PENDING, 76 CLAW_M2_PENDING, 77 }; 78 79 enum claw_key_index { 80 CLAW_KEY_M1, 81 CLAW_KEY_M2, 82 }; 83 84 enum claw_mkeys_function_index { 85 CLAW_MKEY_FUNCTION_MACRO, 86 CLAW_MKEY_FUNCTION_DISABLED, 87 CLAW_MKEY_FUNCTION_COMBO, 88 }; 89 90 enum claw_mode_field { 91 CLAW_FIELD_GAMEPAD_MODE, 92 CLAW_FIELD_MKEYS_FUNCTION, 93 }; 94 95 static const char * const claw_mkeys_function_text[] = { 96 [CLAW_MKEY_FUNCTION_MACRO] = "macro", 97 [CLAW_MKEY_FUNCTION_DISABLED] = "disabled", 98 [CLAW_MKEY_FUNCTION_COMBO] = "combination", 99 }; 100 101 static const struct { 102 u8 code; 103 const char *name; 104 } claw_button_mapping_key_map[] = { 105 /* Gamepad buttons */ 106 { 0x01, "ABS_HAT0Y_UP" }, 107 { 0x02, "ABS_HAT0Y_DOWN" }, 108 { 0x03, "ABS_HAT0X_LEFT" }, 109 { 0x04, "ABS_HAT0X_RIGHT" }, 110 { 0x05, "BTN_TL" }, 111 { 0x06, "BTN_TR" }, 112 { 0x07, "BTN_THUMBL" }, 113 { 0x08, "BTN_THUMBR" }, 114 { 0x09, "BTN_SOUTH" }, 115 { 0x0a, "BTN_EAST" }, 116 { 0x0b, "BTN_NORTH" }, 117 { 0x0c, "BTN_WEST" }, 118 { 0x0d, "BTN_MODE" }, 119 { 0x0e, "BTN_SELECT" }, 120 { 0x0f, "BTN_START" }, 121 { 0x13, "BTN_TL2"}, 122 { 0x14, "BTN_TR2"}, 123 { 0x15, "ABS_Y_UP"}, 124 { 0x16, "ABS_Y_DOWN"}, 125 { 0x17, "ABS_X_LEFT"}, 126 { 0x18, "ABS_X_RIGHT"}, 127 { 0x19, "ABS_RY_UP"}, 128 { 0x1a, "ABS_RY_DOWN"}, 129 { 0x1b, "ABS_RX_LEFT"}, 130 { 0x1c, "ABS_RX_RIGHT"}, 131 /* Keyboard keys */ 132 { 0x32, "KEY_ESC" }, 133 { 0x33, "KEY_F1" }, 134 { 0x34, "KEY_F2" }, 135 { 0x35, "KEY_F3" }, 136 { 0x36, "KEY_F4" }, 137 { 0x37, "KEY_F5" }, 138 { 0x38, "KEY_F6" }, 139 { 0x39, "KEY_F7" }, 140 { 0x3a, "KEY_F8" }, 141 { 0x3b, "KEY_F9" }, 142 { 0x3c, "KEY_F10" }, 143 { 0x3d, "KEY_F11" }, 144 { 0x3e, "KEY_F12" }, 145 { 0x3f, "KEY_GRAVE" }, 146 { 0x40, "KEY_1" }, 147 { 0x41, "KEY_2" }, 148 { 0x42, "KEY_3" }, 149 { 0x43, "KEY_4" }, 150 { 0x44, "KEY_5" }, 151 { 0x45, "KEY_6" }, 152 { 0x46, "KEY_7" }, 153 { 0x47, "KEY_8" }, 154 { 0x48, "KEY_9" }, 155 { 0x49, "KEY_0" }, 156 { 0x4a, "KEY_MINUS" }, 157 { 0x4b, "KEY_EQUAL" }, 158 { 0x4c, "KEY_BACKSPACE" }, 159 { 0x4d, "KEY_TAB" }, 160 { 0x4e, "KEY_Q" }, 161 { 0x4f, "KEY_W" }, 162 { 0x50, "KEY_E" }, 163 { 0x51, "KEY_R" }, 164 { 0x52, "KEY_T" }, 165 { 0x53, "KEY_Y" }, 166 { 0x54, "KEY_U" }, 167 { 0x55, "KEY_I" }, 168 { 0x56, "KEY_O" }, 169 { 0x57, "KEY_P" }, 170 { 0x58, "KEY_LEFTBRACE" }, 171 { 0x59, "KEY_RIGHTBRACE" }, 172 { 0x5a, "KEY_BACKSLASH" }, 173 { 0x5b, "KEY_CAPSLOCK" }, 174 { 0x5c, "KEY_A" }, 175 { 0x5d, "KEY_S" }, 176 { 0x5e, "KEY_D" }, 177 { 0x5f, "KEY_F" }, 178 { 0x60, "KEY_G" }, 179 { 0x61, "KEY_H" }, 180 { 0x62, "KEY_J" }, 181 { 0x63, "KEY_K" }, 182 { 0x64, "KEY_L" }, 183 { 0x65, "KEY_SEMICOLON" }, 184 { 0x66, "KEY_APOSTROPHE" }, 185 { 0x67, "KEY_ENTER" }, 186 { 0x68, "KEY_LEFTSHIFT" }, 187 { 0x69, "KEY_Z" }, 188 { 0x6a, "KEY_X" }, 189 { 0x6b, "KEY_C" }, 190 { 0x6c, "KEY_V" }, 191 { 0x6d, "KEY_B" }, 192 { 0x6e, "KEY_N" }, 193 { 0x6f, "KEY_M" }, 194 { 0x70, "KEY_COMMA" }, 195 { 0x71, "KEY_DOT" }, 196 { 0x72, "KEY_SLASH" }, 197 { 0x73, "KEY_RIGHTSHIFT" }, 198 { 0x74, "KEY_LEFTCTRL" }, 199 { 0x75, "KEY_LEFTMETA" }, 200 { 0x76, "KEY_LEFTALT" }, 201 { 0x77, "KEY_SPACE" }, 202 { 0x78, "KEY_RIGHTALT" }, 203 { 0x79, "KEY_RIGHTCTRL" }, 204 { 0x7a, "KEY_INSERT" }, 205 { 0x7b, "KEY_HOME" }, 206 { 0x7c, "KEY_PAGEUP" }, 207 { 0x7d, "KEY_DELETE" }, 208 { 0x7e, "KEY_END" }, 209 { 0x7f, "KEY_PAGEDOWN" }, 210 { 0x8a, "KEY_KPENTER" }, 211 { 0x8b, "KEY_KP0" }, 212 { 0x8c, "KEY_KP1" }, 213 { 0x8d, "KEY_KP2" }, 214 { 0x8e, "KEY_KP3" }, 215 { 0x8f, "KEY_KP4" }, 216 { 0x90, "KEY_KP5" }, 217 { 0x91, "KEY_KP6" }, 218 { 0x92, "KEY_KP7" }, 219 { 0x93, "KEY_KP8" }, 220 { 0x94, "KEY_KP9" }, 221 { 0x95, "MD_PLAY" }, 222 { 0x96, "MD_STOP" }, 223 { 0x97, "MD_NEXT" }, 224 { 0x98, "MD_PREV" }, 225 { 0x99, "MD_VOL_UP" }, 226 { 0x9a, "MD_VOL_DOWN" }, 227 { 0x9b, "MD_VOL_MUTE" }, 228 { 0x9c, "KEY_F23" }, 229 /* Mouse events */ 230 { 0xc8, "BTN_LEFT" }, 231 { 0xc9, "BTN_MIDDLE" }, 232 { 0xca, "BTN_RIGHT" }, 233 { 0xcb, "BTN_SIDE" }, 234 { 0xcc, "BTN_EXTRA" }, 235 { 0xcd, "REL_WHEEL_UP" }, 236 { 0xce, "REL_WHEEL_DOWN" }, 237 { 0xff, "DISABLED" }, 238 }; 239 240 static const u16 button_mapping_addr_old[] = { 241 0x007a, /* M1 */ 242 0x011f, /* M2 */ 243 }; 244 245 static const u16 button_mapping_addr_new[] = { 246 0x00bb, /* M1 */ 247 0x0164, /* M2 */ 248 }; 249 250 struct claw_command_report { 251 u8 report_id; 252 u8 padding[2]; 253 u8 header_tail; 254 u8 cmd; 255 u8 data[59]; 256 } __packed; 257 258 struct claw_profile_report { 259 u8 profile; 260 __be16 read_addr; 261 } __packed; 262 263 struct claw_mkey_report { 264 struct claw_profile_report; 265 u8 padding_0; 266 u8 padding_1; 267 u8 padding_2; 268 u8 codes[5]; 269 } __packed; 270 271 struct claw_drvdata { 272 /* MCU General Variables */ 273 enum claw_profile_ack_pending profile_pending; 274 struct completion orphan_ack_complete; 275 struct completion send_cmd_complete; 276 struct delayed_work cfg_resume; 277 struct delayed_work cfg_setup; 278 spinlock_t registration_lock; /* Lock for registration read/write */ 279 struct mutex profile_mutex; /* mutex for profile_pending calls */ 280 spinlock_t profile_lock; /* Lock for profile_pending read/write */ 281 struct hid_device *hdev; 282 bool orphan_ack_pending; 283 struct mutex cfg_mutex; /* mutex for synchronous data */ 284 struct mutex rom_mutex; /* mutex for SYNC_TO_ROM calls */ 285 spinlock_t cmd_lock; /* Lock for cmd data read/write */ 286 u8 waiting_cmd; 287 int cmd_status; 288 u16 bcd_device; 289 u8 ep; 290 291 /* Gamepad Variables */ 292 enum claw_mkeys_function_index mkeys_function; 293 enum claw_gamepad_mode_index gamepad_mode; 294 u8 m1_codes[CLAW_KEYS_MAX]; 295 u8 m2_codes[CLAW_KEYS_MAX]; 296 const u16 *bmap_addr; 297 spinlock_t mode_lock; /* Lock for mode data read/write */ 298 bool gp_registered; 299 bool bmap_support; 300 }; 301 302 static int get_endpoint_address(struct hid_device *hdev) 303 { 304 struct usb_host_endpoint *ep; 305 struct usb_interface *intf; 306 307 intf = to_usb_interface(hdev->dev.parent); 308 ep = intf->cur_altsetting->endpoint; 309 if (ep) 310 return ep->desc.bEndpointAddress; 311 312 return -ENODEV; 313 } 314 315 static int claw_gamepad_mode_event(struct claw_drvdata *drvdata, 316 struct claw_command_report *cmd_rep) 317 { 318 if (cmd_rep->data[0] >= ARRAY_SIZE(claw_gamepad_mode_text) || 319 !claw_gamepad_mode_text[cmd_rep->data[0]] || 320 cmd_rep->data[1] >= ARRAY_SIZE(claw_mkeys_function_text)) 321 return -EINVAL; 322 323 scoped_guard(spinlock_irqsave, &drvdata->mode_lock) { 324 drvdata->gamepad_mode = cmd_rep->data[0]; 325 drvdata->mkeys_function = cmd_rep->data[1]; 326 } 327 328 return 0; 329 } 330 331 static int claw_profile_event(struct claw_drvdata *drvdata, struct claw_command_report *cmd_rep) 332 { 333 enum claw_profile_ack_pending profile; 334 struct claw_mkey_report *mkeys; 335 u8 *codes, key; 336 int i; 337 338 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 339 profile = drvdata->profile_pending; 340 341 switch (profile) { 342 case CLAW_M1_PENDING: 343 case CLAW_M2_PENDING: 344 key = (profile == CLAW_M1_PENDING) ? CLAW_KEY_M1 : CLAW_KEY_M2; 345 mkeys = (struct claw_mkey_report *)cmd_rep->data; 346 if (be16_to_cpu(mkeys->read_addr) != drvdata->bmap_addr[key]) 347 return -EAGAIN; 348 codes = (profile == CLAW_M1_PENDING) ? drvdata->m1_codes : drvdata->m2_codes; 349 for (i = 0; i < CLAW_KEYS_MAX; i++) 350 codes[i] = (mkeys->codes[i]); 351 break; 352 default: 353 dev_dbg(&drvdata->hdev->dev, 354 "Got profile event without changes pending from command: %x\n", 355 cmd_rep->cmd); 356 return -EINVAL; 357 } 358 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 359 drvdata->profile_pending = CLAW_NO_PENDING; 360 361 return 0; 362 } 363 364 static int claw_raw_event(struct claw_drvdata *drvdata, struct hid_report *report, 365 u8 *data, int size) 366 { 367 struct claw_command_report *cmd_rep; 368 int ret = 0; 369 370 if (size != CLAW_PACKET_SIZE) 371 return 0; 372 373 cmd_rep = (struct claw_command_report *)data; 374 375 if (cmd_rep->report_id != CLAW_INPUT_REPORT_ID || cmd_rep->header_tail != 0x3c) 376 return 0; 377 378 dev_dbg(&drvdata->hdev->dev, "Rx data as raw input report: [%*ph]\n", 379 CLAW_PACKET_SIZE, data); 380 381 guard(spinlock_irqsave)(&drvdata->cmd_lock); 382 switch (cmd_rep->cmd) { 383 case CLAW_COMMAND_TYPE_GAMEPAD_MODE_ACK: 384 ret = claw_gamepad_mode_event(drvdata, cmd_rep); 385 if (drvdata->waiting_cmd == CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE) { 386 drvdata->cmd_status = ret; 387 complete(&drvdata->send_cmd_complete); 388 } 389 390 break; 391 case CLAW_COMMAND_TYPE_READ_PROFILE_ACK: 392 ret = claw_profile_event(drvdata, cmd_rep); 393 /* Stale address received, ignore and keep waiting */ 394 if (ret == -EAGAIN) 395 return 0; 396 if (drvdata->waiting_cmd == CLAW_COMMAND_TYPE_READ_PROFILE) { 397 drvdata->cmd_status = ret; 398 complete(&drvdata->send_cmd_complete); 399 } 400 401 break; 402 case CLAW_COMMAND_TYPE_ACK: 403 if (drvdata->orphan_ack_pending) { 404 drvdata->orphan_ack_pending = false; 405 complete(&drvdata->orphan_ack_complete); 406 break; 407 } 408 409 if (drvdata->waiting_cmd == CLAW_COMMAND_TYPE_NONE) { 410 dev_warn(&drvdata->hdev->dev, "Got unexpected ACK from MCU, ignoring\n"); 411 break; 412 } 413 414 drvdata->cmd_status = 0; 415 complete(&drvdata->send_cmd_complete); 416 417 dev_dbg(&drvdata->hdev->dev, "Waiting CMD: %x\n", drvdata->waiting_cmd); 418 419 break; 420 default: 421 dev_dbg(&drvdata->hdev->dev, "Unknown command: %x\n", cmd_rep->cmd); 422 return 0; 423 } 424 425 return ret; 426 } 427 428 static int msi_raw_event(struct hid_device *hdev, struct hid_report *report, 429 u8 *data, int size) 430 { 431 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 432 433 if (!drvdata || (drvdata->ep != CLAW_XINPUT_CFG_INTF_IN && 434 drvdata->ep != CLAW_DINPUT_CFG_INTF_IN)) 435 return 0; 436 437 return claw_raw_event(drvdata, report, data, size); 438 } 439 440 /* Caller must hold drvdata->cfg_mutex. */ 441 static int __claw_hw_output_report(struct hid_device *hdev, u8 index, u8 *data, 442 size_t len, unsigned int timeout) 443 { 444 unsigned char *dmabuf __free(kfree) = NULL; 445 u8 header[] = { CLAW_OUTPUT_REPORT_ID, 0, 0, 0x3c, index }; 446 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 447 size_t header_size = ARRAY_SIZE(header); 448 bool orphaned; 449 int ret; 450 451 lockdep_assert_held(&drvdata->cfg_mutex); 452 453 /* If expecting an orphan ack, hold next event until MCU has time to clear it */ 454 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) 455 orphaned = drvdata->orphan_ack_pending; 456 457 if (orphaned) { 458 wait_for_completion_timeout(&drvdata->orphan_ack_complete, msecs_to_jiffies(25)); 459 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) 460 drvdata->orphan_ack_pending = false; 461 } 462 463 if (header_size + len > CLAW_PACKET_SIZE) 464 return -EINVAL; 465 466 /* We can't use a devm_alloc reusable buffer without side effects during suspend */ 467 dmabuf = kzalloc(CLAW_PACKET_SIZE, GFP_KERNEL); 468 if (!dmabuf) 469 return -ENOMEM; 470 471 memcpy(dmabuf, header, header_size); 472 if (data && len) 473 memcpy(dmabuf + header_size, data, len); 474 475 reinit_completion(&drvdata->send_cmd_complete); 476 477 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) { 478 if (timeout) { 479 drvdata->waiting_cmd = index; 480 drvdata->cmd_status = -ETIMEDOUT; 481 } else { 482 reinit_completion(&drvdata->orphan_ack_complete); 483 drvdata->waiting_cmd = CLAW_COMMAND_TYPE_NONE; 484 drvdata->orphan_ack_pending = true; 485 } 486 } 487 488 dev_dbg(&hdev->dev, "Send data as raw output report: [%*ph]\n", 489 CLAW_PACKET_SIZE, dmabuf); 490 491 ret = hid_hw_output_report(hdev, dmabuf, CLAW_PACKET_SIZE); 492 if (ret < 0) 493 goto err; 494 495 ret = ret == CLAW_PACKET_SIZE ? 0 : -EIO; 496 if (ret) 497 goto err; 498 499 if (timeout) { 500 ret = wait_for_completion_interruptible_timeout(&drvdata->send_cmd_complete, 501 msecs_to_jiffies(timeout)); 502 503 dev_dbg(&hdev->dev, "Remaining timeout: %u\n", ret); 504 ret = ret > 0 ? drvdata->cmd_status : ret ?: -EBUSY; 505 if (ret) 506 goto err; 507 } 508 509 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) 510 drvdata->waiting_cmd = CLAW_COMMAND_TYPE_NONE; 511 512 return ret; 513 514 err: 515 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) { 516 drvdata->waiting_cmd = CLAW_COMMAND_TYPE_NONE; 517 drvdata->orphan_ack_pending = false; 518 } 519 return ret; 520 } 521 522 static int claw_hw_output_report(struct hid_device *hdev, u8 index, u8 *data, 523 size_t len, unsigned int timeout) 524 { 525 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 526 527 guard(mutex)(&drvdata->cfg_mutex); 528 return __claw_hw_output_report(hdev, index, data, len, timeout); 529 } 530 531 static int claw_switch_mode(struct hid_device *hdev, enum claw_mode_field field, u8 val) 532 { 533 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 534 u8 data[2]; 535 536 guard(mutex)(&drvdata->cfg_mutex); 537 538 scoped_guard(spinlock_irqsave, &drvdata->mode_lock) { 539 switch (field) { 540 case CLAW_FIELD_GAMEPAD_MODE: 541 data[0] = val; 542 data[1] = drvdata->mkeys_function; 543 break; 544 case CLAW_FIELD_MKEYS_FUNCTION: 545 data[0] = drvdata->gamepad_mode; 546 data[1] = val; 547 break; 548 } 549 } 550 551 return __claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_SWITCH_MODE, data, 552 ARRAY_SIZE(data), 0); 553 } 554 555 static ssize_t gamepad_mode_store(struct device *dev, struct device_attribute *attr, 556 const char *buf, size_t count) 557 { 558 struct hid_device *hdev = to_hid_device(dev); 559 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 560 int i, ret = -EINVAL; 561 562 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 563 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 564 if (!smp_load_acquire(&drvdata->gp_registered)) 565 return -ENODEV; 566 } 567 568 for (i = 0; i < ARRAY_SIZE(claw_gamepad_mode_text); i++) { 569 if (claw_gamepad_mode_text[i] && sysfs_streq(buf, claw_gamepad_mode_text[i])) { 570 ret = i; 571 break; 572 } 573 } 574 if (ret < 0) 575 return ret; 576 577 ret = claw_switch_mode(hdev, CLAW_FIELD_GAMEPAD_MODE, ret); 578 if (ret) 579 return ret; 580 581 return count; 582 } 583 584 static ssize_t gamepad_mode_show(struct device *dev, 585 struct device_attribute *attr, char *buf) 586 { 587 struct hid_device *hdev = to_hid_device(dev); 588 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 589 int ret, i; 590 591 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 592 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 593 if (!smp_load_acquire(&drvdata->gp_registered)) 594 return -ENODEV; 595 } 596 597 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE, NULL, 0, 25); 598 if (ret) 599 return ret; 600 601 scoped_guard(spinlock_irqsave, &drvdata->mode_lock) 602 i = drvdata->gamepad_mode; 603 604 if (!claw_gamepad_mode_text[i] || claw_gamepad_mode_text[i][0] == '\0') 605 return sysfs_emit(buf, "unsupported\n"); 606 607 return sysfs_emit(buf, "%s\n", claw_gamepad_mode_text[i]); 608 } 609 static DEVICE_ATTR_RW(gamepad_mode); 610 611 static ssize_t gamepad_mode_index_show(struct device *dev, 612 struct device_attribute *attr, char *buf) 613 { 614 ssize_t count = 0; 615 int i; 616 617 for (i = 0; i < ARRAY_SIZE(claw_gamepad_mode_text); i++) { 618 if (!claw_gamepad_mode_text[i] || claw_gamepad_mode_text[i][0] == '\0') 619 continue; 620 count += sysfs_emit_at(buf, count, "%s ", claw_gamepad_mode_text[i]); 621 } 622 623 if (count) 624 buf[count - 1] = '\n'; 625 626 return count; 627 } 628 static DEVICE_ATTR_RO(gamepad_mode_index); 629 630 static ssize_t mkeys_function_store(struct device *dev, struct device_attribute *attr, 631 const char *buf, size_t count) 632 { 633 struct hid_device *hdev = to_hid_device(dev); 634 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 635 int i, ret = -EINVAL; 636 637 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 638 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 639 if (!smp_load_acquire(&drvdata->gp_registered)) 640 return -ENODEV; 641 } 642 643 for (i = 0; i < ARRAY_SIZE(claw_mkeys_function_text); i++) { 644 if (claw_mkeys_function_text[i] && sysfs_streq(buf, claw_mkeys_function_text[i])) { 645 ret = i; 646 break; 647 } 648 } 649 if (ret < 0) 650 return ret; 651 652 ret = claw_switch_mode(hdev, CLAW_FIELD_MKEYS_FUNCTION, ret); 653 if (ret) 654 return ret; 655 656 return count; 657 } 658 659 static ssize_t mkeys_function_show(struct device *dev, struct device_attribute *attr, 660 char *buf) 661 { 662 struct hid_device *hdev = to_hid_device(dev); 663 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 664 int ret, i; 665 666 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 667 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 668 if (!smp_load_acquire(&drvdata->gp_registered)) 669 return -ENODEV; 670 } 671 672 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE, NULL, 0, 25); 673 if (ret) 674 return ret; 675 676 scoped_guard(spinlock_irqsave, &drvdata->mode_lock) 677 i = drvdata->mkeys_function; 678 679 if (i >= ARRAY_SIZE(claw_mkeys_function_text)) 680 return sysfs_emit(buf, "unsupported\n"); 681 682 return sysfs_emit(buf, "%s\n", claw_mkeys_function_text[i]); 683 } 684 static DEVICE_ATTR_RW(mkeys_function); 685 686 static ssize_t mkeys_function_index_show(struct device *dev, 687 struct device_attribute *attr, char *buf) 688 { 689 int i, count = 0; 690 691 for (i = 0; i < ARRAY_SIZE(claw_mkeys_function_text); i++) 692 count += sysfs_emit_at(buf, count, "%s ", claw_mkeys_function_text[i]); 693 694 if (count) 695 buf[count - 1] = '\n'; 696 697 return count; 698 } 699 static DEVICE_ATTR_RO(mkeys_function_index); 700 701 static ssize_t reset_store(struct device *dev, struct device_attribute *attr, 702 const char *buf, size_t count) 703 { 704 struct hid_device *hdev = to_hid_device(dev); 705 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 706 bool val; 707 int ret; 708 709 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 710 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 711 if (!smp_load_acquire(&drvdata->gp_registered)) 712 return -ENODEV; 713 } 714 715 ret = kstrtobool(buf, &val); 716 if (ret) 717 return ret; 718 719 if (!val) 720 return -EINVAL; 721 722 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_RESET_DEVICE, NULL, 0, 0); 723 if (ret) 724 return ret; 725 726 return count; 727 } 728 static DEVICE_ATTR_WO(reset); 729 730 static int mkey_mapping_name_to_code(const char *name) 731 { 732 int i; 733 734 for (i = 0; i < ARRAY_SIZE(claw_button_mapping_key_map); i++) { 735 if (!strcmp(name, claw_button_mapping_key_map[i].name)) 736 return claw_button_mapping_key_map[i].code; 737 } 738 739 return -EINVAL; 740 } 741 742 static const char *mkey_mapping_code_to_name(u8 code) 743 { 744 int i; 745 746 if (code == 0xff) 747 return NULL; 748 749 for (i = 0; i < ARRAY_SIZE(claw_button_mapping_key_map); i++) { 750 if (claw_button_mapping_key_map[i].code == code) 751 return claw_button_mapping_key_map[i].name; 752 } 753 754 return NULL; 755 } 756 757 static int claw_mkey_store(struct device *dev, const char *buf, u8 mkey) 758 { 759 struct hid_device *hdev = to_hid_device(dev); 760 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 761 struct claw_mkey_report report = { {0x01, cpu_to_be16(drvdata->bmap_addr[mkey])}, 762 0x07, 0x04, 0x00, {0xff, 0xff, 0xff, 0xff, 0xff} }; 763 char **raw_keys __free(argv_free) = NULL; 764 int ret, key_count, i; 765 766 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 767 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 768 if (!smp_load_acquire(&drvdata->gp_registered)) 769 return -ENODEV; 770 } 771 772 raw_keys = argv_split(GFP_KERNEL, buf, &key_count); 773 if (!raw_keys) 774 return -ENOMEM; 775 776 if (key_count > CLAW_KEYS_MAX) 777 return -EINVAL; 778 779 if (key_count == 0) 780 goto set_buttons; 781 782 for (i = 0; i < key_count; i++) { 783 ret = mkey_mapping_name_to_code(raw_keys[i]); 784 if (ret < 0) 785 return ret; 786 787 report.codes[i] = ret; 788 } 789 790 set_buttons: 791 scoped_guard(mutex, &drvdata->rom_mutex) { 792 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_WRITE_PROFILE_DATA, 793 (u8 *)&report, sizeof(report), 25); 794 if (ret) 795 return ret; 796 /* MCU will not send ACK until the USB transaction completes. ACK is sent 797 * immediately after and will hit the stale state machine, before the next 798 * command re-arms the state machine. Timeout 0 ensures no deadlock waiting 799 * for ACK that ill never come. 800 */ 801 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_SYNC_TO_ROM, NULL, 0, 0); 802 } 803 804 return ret; 805 } 806 807 static int claw_mkey_show(struct device *dev, char *buf, enum claw_key_index m_key) 808 { 809 struct hid_device *hdev = to_hid_device(dev); 810 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 811 struct claw_mkey_report report = { {0x01, cpu_to_be16(drvdata->bmap_addr[m_key])}, 0x07 }; 812 int i, ret, count = 0; 813 const char *name; 814 u8 *codes; 815 816 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 817 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 818 if (!smp_load_acquire(&drvdata->gp_registered)) 819 return -ENODEV; 820 } 821 822 codes = (m_key == CLAW_KEY_M1) ? drvdata->m1_codes : drvdata->m2_codes; 823 824 guard(mutex)(&drvdata->profile_mutex); 825 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 826 drvdata->profile_pending = (m_key == CLAW_KEY_M1) ? CLAW_M1_PENDING 827 : CLAW_M2_PENDING; 828 829 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_READ_PROFILE, 830 (u8 *)&report, sizeof(report), 25); 831 if (ret) 832 return ret; 833 834 for (i = 0; i < CLAW_KEYS_MAX; i++) { 835 name = mkey_mapping_code_to_name(codes[i]); 836 if (name) 837 count += sysfs_emit_at(buf, count, "%s ", name); 838 } 839 840 if (!count) 841 return sysfs_emit(buf, "(not set)\n"); 842 843 buf[count - 1] = '\n'; 844 845 return count; 846 } 847 848 static ssize_t button_m1_store(struct device *dev, struct device_attribute *attr, 849 const char *buf, size_t count) 850 { 851 int ret; 852 853 ret = claw_mkey_store(dev, buf, CLAW_KEY_M1); 854 if (ret) 855 return ret; 856 857 return count; 858 } 859 860 static ssize_t button_m1_show(struct device *dev, struct device_attribute *attr, 861 char *buf) 862 { 863 return claw_mkey_show(dev, buf, CLAW_KEY_M1); 864 } 865 static DEVICE_ATTR_RW(button_m1); 866 867 static ssize_t button_m2_store(struct device *dev, struct device_attribute *attr, 868 const char *buf, size_t count) 869 { 870 int ret; 871 872 ret = claw_mkey_store(dev, buf, CLAW_KEY_M2); 873 if (ret) 874 return ret; 875 876 return count; 877 } 878 879 static ssize_t button_m2_show(struct device *dev, struct device_attribute *attr, 880 char *buf) 881 { 882 return claw_mkey_show(dev, buf, CLAW_KEY_M2); 883 } 884 static DEVICE_ATTR_RW(button_m2); 885 886 static ssize_t button_mapping_options_show(struct device *dev, 887 struct device_attribute *attr, char *buf) 888 { 889 int i, count = 0; 890 891 for (i = 0; i < ARRAY_SIZE(claw_button_mapping_key_map); i++) 892 count += sysfs_emit_at(buf, count, "%s ", claw_button_mapping_key_map[i].name); 893 894 if (count) 895 buf[count - 1] = '\n'; 896 897 return count; 898 } 899 static DEVICE_ATTR_RO(button_mapping_options); 900 901 static umode_t claw_gamepad_attr_is_visible(struct kobject *kobj, struct attribute *attr, 902 int n) 903 { 904 struct hid_device *hdev = to_hid_device(kobj_to_dev(kobj)); 905 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 906 907 if (!drvdata) { 908 dev_warn(&hdev->dev, 909 "Failed to get drvdata from kobj. Gamepad attributes are not available.\n"); 910 return 0; 911 } 912 913 /* Always show attrs available on all firmware */ 914 if (attr == &dev_attr_gamepad_mode.attr || 915 attr == &dev_attr_gamepad_mode_index.attr || 916 attr == &dev_attr_mkeys_function.attr || 917 attr == &dev_attr_mkeys_function_index.attr || 918 attr == &dev_attr_reset.attr) 919 return attr->mode; 920 921 /* Hide button mapping attrs if it isn't supported */ 922 return drvdata->bmap_support ? attr->mode : 0; 923 } 924 925 static struct attribute *claw_gamepad_attrs[] = { 926 &dev_attr_button_m1.attr, 927 &dev_attr_button_m2.attr, 928 &dev_attr_button_mapping_options.attr, 929 &dev_attr_gamepad_mode.attr, 930 &dev_attr_gamepad_mode_index.attr, 931 &dev_attr_mkeys_function.attr, 932 &dev_attr_mkeys_function_index.attr, 933 &dev_attr_reset.attr, 934 NULL, 935 }; 936 937 static const struct attribute_group claw_gamepad_attr_group = { 938 .attrs = claw_gamepad_attrs, 939 .is_visible = claw_gamepad_attr_is_visible, 940 }; 941 942 static void cfg_setup_fn(struct work_struct *work) 943 { 944 struct delayed_work *dwork = container_of(work, struct delayed_work, work); 945 struct claw_drvdata *drvdata = container_of(dwork, struct claw_drvdata, cfg_setup); 946 int ret; 947 948 ret = claw_hw_output_report(drvdata->hdev, CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE, 949 NULL, 0, 25); 950 if (ret) { 951 dev_err(&drvdata->hdev->dev, 952 "Failed to setup device, can't read gamepad mode: %d\n", ret); 953 return; 954 } 955 956 /* Add sysfs attributes after we get the device state */ 957 ret = device_add_group(&drvdata->hdev->dev, &claw_gamepad_attr_group); 958 if (ret) { 959 dev_err(&drvdata->hdev->dev, 960 "Failed to setup device, can't create gamepad attrs: %d\n", ret); 961 return; 962 } 963 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) 964 /* Pairs with smp_load_acquire in attribute show/store functions */ 965 smp_store_release(&drvdata->gp_registered, true); 966 967 kobject_uevent(&drvdata->hdev->dev.kobj, KOBJ_CHANGE); 968 } 969 970 static void cfg_resume_fn(struct work_struct *work) 971 { 972 struct delayed_work *dwork = container_of(work, struct delayed_work, work); 973 struct claw_drvdata *drvdata = container_of(dwork, struct claw_drvdata, cfg_resume); 974 975 guard(spinlock_irqsave)(&drvdata->registration_lock); 976 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 977 if (!smp_load_acquire(&drvdata->gp_registered)) 978 schedule_delayed_work(&drvdata->cfg_setup, msecs_to_jiffies(500)); 979 } 980 981 static void claw_features_supported(struct claw_drvdata *drvdata) 982 { 983 u8 major = (drvdata->bcd_device >> 8) & 0xff; 984 u8 minor = drvdata->bcd_device & 0xff; 985 986 if (major == 0x01) { 987 drvdata->bmap_support = true; 988 if (minor >= 0x66) 989 drvdata->bmap_addr = button_mapping_addr_new; 990 else 991 drvdata->bmap_addr = button_mapping_addr_old; 992 return; 993 } 994 995 if ((major == 0x02 && minor >= 0x17) || major >= 0x03) { 996 drvdata->bmap_support = true; 997 drvdata->bmap_addr = button_mapping_addr_new; 998 return; 999 } 1000 } 1001 1002 static int claw_probe(struct hid_device *hdev, u8 ep) 1003 { 1004 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 1005 struct usb_device *udev = interface_to_usbdev(intf); 1006 struct claw_drvdata *drvdata; 1007 int ret; 1008 1009 drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); 1010 if (!drvdata) 1011 return -ENOMEM; 1012 1013 drvdata->gamepad_mode = CLAW_GAMEPAD_MODE_XINPUT; 1014 drvdata->hdev = hdev; 1015 drvdata->ep = ep; 1016 1017 /* Determine feature level from firmware version */ 1018 drvdata->bcd_device = le16_to_cpu(udev->descriptor.bcdDevice); 1019 claw_features_supported(drvdata); 1020 1021 if (!drvdata->bmap_support) 1022 dev_dbg(&hdev->dev, "M-Key mapping is not supported. Update firmware to enable.\n"); 1023 1024 mutex_init(&drvdata->cfg_mutex); 1025 mutex_init(&drvdata->profile_mutex); 1026 mutex_init(&drvdata->rom_mutex); 1027 spin_lock_init(&drvdata->registration_lock); 1028 spin_lock_init(&drvdata->cmd_lock); 1029 spin_lock_init(&drvdata->mode_lock); 1030 spin_lock_init(&drvdata->profile_lock); 1031 init_completion(&drvdata->orphan_ack_complete); 1032 init_completion(&drvdata->send_cmd_complete); 1033 INIT_DELAYED_WORK(&drvdata->cfg_resume, &cfg_resume_fn); 1034 INIT_DELAYED_WORK(&drvdata->cfg_setup, &cfg_setup_fn); 1035 1036 /* For control interface: open the HID transport for sending commands. */ 1037 ret = hid_hw_open(hdev); 1038 if (ret) 1039 return ret; 1040 1041 hid_set_drvdata(hdev, drvdata); 1042 schedule_delayed_work(&drvdata->cfg_setup, msecs_to_jiffies(500)); 1043 1044 return 0; 1045 } 1046 1047 static int msi_probe(struct hid_device *hdev, const struct hid_device_id *id) 1048 { 1049 int ret; 1050 u8 ep; 1051 1052 if (!hid_is_usb(hdev)) { 1053 ret = -ENODEV; 1054 goto err_probe; 1055 } 1056 1057 ret = hid_parse(hdev); 1058 if (ret) 1059 goto err_probe; 1060 1061 /* Set quirk to create separate input devices per HID application */ 1062 hdev->quirks |= HID_QUIRK_INPUT_PER_APP | HID_QUIRK_MULTI_INPUT; 1063 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 1064 if (ret) 1065 goto err_probe; 1066 1067 /* For non-control interfaces (keyboard/mouse), allow userspace to grab the devices. */ 1068 ret = get_endpoint_address(hdev); 1069 if (ret < 0) 1070 goto err_stop_hw; 1071 1072 ep = ret; 1073 if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN) { 1074 ret = claw_probe(hdev, ep); 1075 if (ret) 1076 goto err_stop_hw; 1077 } 1078 1079 return 0; 1080 1081 err_stop_hw: 1082 hid_hw_stop(hdev); 1083 err_probe: 1084 return dev_err_probe(&hdev->dev, ret, "Failed to init device\n"); 1085 } 1086 1087 static void claw_remove(struct hid_device *hdev) 1088 { 1089 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 1090 bool gp_registered; 1091 1092 if (!drvdata) 1093 return; 1094 1095 cancel_delayed_work_sync(&drvdata->cfg_resume); 1096 cancel_delayed_work_sync(&drvdata->cfg_setup); 1097 1098 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1099 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1100 gp_registered = smp_load_acquire(&drvdata->gp_registered); 1101 /* Pairs with smp_load_acquire in attribute show/store functions */ 1102 smp_store_release(&drvdata->gp_registered, false); 1103 } 1104 1105 if (gp_registered) 1106 device_remove_group(&hdev->dev, &claw_gamepad_attr_group); 1107 1108 hid_hw_close(hdev); 1109 } 1110 1111 static void msi_remove(struct hid_device *hdev) 1112 { 1113 int ret; 1114 u8 ep; 1115 1116 /* Safe assumption. SET_INTERFACE ioctl can't be used while driver is bound */ 1117 ret = get_endpoint_address(hdev); 1118 if (ret <= 0) 1119 goto hw_stop; 1120 1121 ep = ret; 1122 if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN) 1123 claw_remove(hdev); 1124 1125 hw_stop: 1126 hid_hw_stop(hdev); 1127 } 1128 1129 static int claw_resume(struct hid_device *hdev) 1130 { 1131 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 1132 1133 if (!drvdata) 1134 return -ENODEV; 1135 1136 /* MCU can take up to 500ms to be ready after resume */ 1137 schedule_delayed_work(&drvdata->cfg_resume, msecs_to_jiffies(500)); 1138 return 0; 1139 } 1140 1141 static int msi_resume(struct hid_device *hdev) 1142 { 1143 int ret; 1144 u8 ep; 1145 1146 /* Safe assumption. SET_INTERFACE ioctl can't be used while driver is bound */ 1147 ret = get_endpoint_address(hdev); 1148 if (ret <= 0) 1149 return 0; 1150 1151 ep = ret; 1152 if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN) 1153 return claw_resume(hdev); 1154 1155 return 0; 1156 } 1157 1158 static int claw_suspend(struct hid_device *hdev) 1159 { 1160 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 1161 1162 if (!drvdata) 1163 return -ENODEV; 1164 1165 cancel_delayed_work_sync(&drvdata->cfg_resume); 1166 cancel_delayed_work_sync(&drvdata->cfg_setup); 1167 1168 return 0; 1169 } 1170 1171 static int msi_suspend(struct hid_device *hdev, pm_message_t msg) 1172 { 1173 int ret; 1174 u8 ep; 1175 1176 /* Safe assumption. SET_INTERFACE ioctl can't be used while driver is bound */ 1177 ret = get_endpoint_address(hdev); 1178 if (ret <= 0) 1179 return 0; 1180 1181 ep = ret; 1182 if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN) 1183 return claw_suspend(hdev); 1184 1185 return 0; 1186 } 1187 1188 static const struct hid_device_id msi_devices[] = { 1189 { HID_USB_DEVICE(USB_VENDOR_ID_MSI_2, USB_DEVICE_ID_MSI_CLAW_XINPUT) }, 1190 { HID_USB_DEVICE(USB_VENDOR_ID_MSI_2, USB_DEVICE_ID_MSI_CLAW_DINPUT) }, 1191 { HID_USB_DEVICE(USB_VENDOR_ID_MSI_2, USB_DEVICE_ID_MSI_CLAW_DESKTOP) }, 1192 { HID_USB_DEVICE(USB_VENDOR_ID_MSI_2, USB_DEVICE_ID_MSI_CLAW_BIOS) }, 1193 { } 1194 }; 1195 MODULE_DEVICE_TABLE(hid, msi_devices); 1196 1197 static struct hid_driver msi_driver = { 1198 .name = "hid-msi", 1199 .id_table = msi_devices, 1200 .raw_event = msi_raw_event, 1201 .probe = msi_probe, 1202 .remove = msi_remove, 1203 .resume = pm_ptr(msi_resume), 1204 .suspend = pm_ptr(msi_suspend), 1205 }; 1206 module_hid_driver(msi_driver); 1207 1208 MODULE_LICENSE("GPL"); 1209 MODULE_AUTHOR("Denis Benato <denis.benato@linux.dev>"); 1210 MODULE_AUTHOR("Zhouwang Huang <honjow311@gmail.com>"); 1211 MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>"); 1212 MODULE_DESCRIPTION("HID driver for MSI Claw Handheld PC gamepads"); 1213