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/led-class-multicolor.h> 26 #include <linux/leds.h> 27 #include <linux/module.h> 28 #include <linux/mutex.h> 29 #include <linux/pm.h> 30 #include <linux/spinlock.h> 31 #include <linux/sysfs.h> 32 #include <linux/types.h> 33 #include <linux/unaligned.h> 34 #include <linux/usb.h> 35 #include <linux/workqueue.h> 36 37 #include "hid-ids.h" 38 39 #define CLAW_OUTPUT_REPORT_ID 0x0f 40 #define CLAW_INPUT_REPORT_ID 0x10 41 42 #define CLAW_PACKET_SIZE 64 43 44 #define CLAW_DINPUT_CFG_INTF_IN 0x82 45 #define CLAW_XINPUT_CFG_INTF_IN 0x83 46 47 #define CLAW_KEYS_MAX 5 48 49 #define CLAW_RGB_ZONES 9 50 #define CLAW_RGB_MAX_FRAMES 8 51 #define CLAW_RGB_FRAME_OFFSET 0x24 52 53 enum claw_command_index { 54 CLAW_COMMAND_TYPE_NONE = 0x00, 55 CLAW_COMMAND_TYPE_READ_PROFILE = 0x04, 56 CLAW_COMMAND_TYPE_READ_PROFILE_ACK = 0x05, 57 CLAW_COMMAND_TYPE_ACK = 0x06, 58 CLAW_COMMAND_TYPE_WRITE_PROFILE_DATA = 0x21, 59 CLAW_COMMAND_TYPE_SYNC_TO_ROM = 0x22, 60 CLAW_COMMAND_TYPE_SWITCH_MODE = 0x24, 61 CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE = 0x26, 62 CLAW_COMMAND_TYPE_GAMEPAD_MODE_ACK = 0x27, 63 CLAW_COMMAND_TYPE_RESET_DEVICE = 0x28, 64 }; 65 66 enum claw_gamepad_mode_index { 67 CLAW_GAMEPAD_MODE_XINPUT = 0x01, 68 CLAW_GAMEPAD_MODE_DINPUT = 0x02, 69 CLAW_GAMEPAD_MODE_DESKTOP = 0x04, 70 }; 71 72 static const char * const claw_gamepad_mode_text[] = { 73 [CLAW_GAMEPAD_MODE_XINPUT] = "xinput", 74 [CLAW_GAMEPAD_MODE_DINPUT] = "dinput", 75 [CLAW_GAMEPAD_MODE_DESKTOP] = "desktop", 76 }; 77 78 enum claw_profile_ack_pending { 79 CLAW_NO_PENDING, 80 CLAW_M1_PENDING, 81 CLAW_M2_PENDING, 82 CLAW_RGB_PENDING, 83 }; 84 85 enum claw_key_index { 86 CLAW_KEY_M1, 87 CLAW_KEY_M2, 88 }; 89 90 enum claw_mkeys_function_index { 91 CLAW_MKEY_FUNCTION_MACRO, 92 CLAW_MKEY_FUNCTION_DISABLED, 93 CLAW_MKEY_FUNCTION_COMBO, 94 }; 95 96 enum claw_mode_field { 97 CLAW_FIELD_GAMEPAD_MODE, 98 CLAW_FIELD_MKEYS_FUNCTION, 99 }; 100 101 static const char * const claw_mkeys_function_text[] = { 102 [CLAW_MKEY_FUNCTION_MACRO] = "macro", 103 [CLAW_MKEY_FUNCTION_DISABLED] = "disabled", 104 [CLAW_MKEY_FUNCTION_COMBO] = "combination", 105 }; 106 107 static const struct { 108 u8 code; 109 const char *name; 110 } claw_button_mapping_key_map[] = { 111 /* Gamepad buttons */ 112 { 0x01, "ABS_HAT0Y_UP" }, 113 { 0x02, "ABS_HAT0Y_DOWN" }, 114 { 0x03, "ABS_HAT0X_LEFT" }, 115 { 0x04, "ABS_HAT0X_RIGHT" }, 116 { 0x05, "BTN_TL" }, 117 { 0x06, "BTN_TR" }, 118 { 0x07, "BTN_THUMBL" }, 119 { 0x08, "BTN_THUMBR" }, 120 { 0x09, "BTN_SOUTH" }, 121 { 0x0a, "BTN_EAST" }, 122 { 0x0b, "BTN_NORTH" }, 123 { 0x0c, "BTN_WEST" }, 124 { 0x0d, "BTN_MODE" }, 125 { 0x0e, "BTN_SELECT" }, 126 { 0x0f, "BTN_START" }, 127 { 0x13, "BTN_TL2"}, 128 { 0x14, "BTN_TR2"}, 129 { 0x15, "ABS_Y_UP"}, 130 { 0x16, "ABS_Y_DOWN"}, 131 { 0x17, "ABS_X_LEFT"}, 132 { 0x18, "ABS_X_RIGHT"}, 133 { 0x19, "ABS_RY_UP"}, 134 { 0x1a, "ABS_RY_DOWN"}, 135 { 0x1b, "ABS_RX_LEFT"}, 136 { 0x1c, "ABS_RX_RIGHT"}, 137 /* Keyboard keys */ 138 { 0x32, "KEY_ESC" }, 139 { 0x33, "KEY_F1" }, 140 { 0x34, "KEY_F2" }, 141 { 0x35, "KEY_F3" }, 142 { 0x36, "KEY_F4" }, 143 { 0x37, "KEY_F5" }, 144 { 0x38, "KEY_F6" }, 145 { 0x39, "KEY_F7" }, 146 { 0x3a, "KEY_F8" }, 147 { 0x3b, "KEY_F9" }, 148 { 0x3c, "KEY_F10" }, 149 { 0x3d, "KEY_F11" }, 150 { 0x3e, "KEY_F12" }, 151 { 0x3f, "KEY_GRAVE" }, 152 { 0x40, "KEY_1" }, 153 { 0x41, "KEY_2" }, 154 { 0x42, "KEY_3" }, 155 { 0x43, "KEY_4" }, 156 { 0x44, "KEY_5" }, 157 { 0x45, "KEY_6" }, 158 { 0x46, "KEY_7" }, 159 { 0x47, "KEY_8" }, 160 { 0x48, "KEY_9" }, 161 { 0x49, "KEY_0" }, 162 { 0x4a, "KEY_MINUS" }, 163 { 0x4b, "KEY_EQUAL" }, 164 { 0x4c, "KEY_BACKSPACE" }, 165 { 0x4d, "KEY_TAB" }, 166 { 0x4e, "KEY_Q" }, 167 { 0x4f, "KEY_W" }, 168 { 0x50, "KEY_E" }, 169 { 0x51, "KEY_R" }, 170 { 0x52, "KEY_T" }, 171 { 0x53, "KEY_Y" }, 172 { 0x54, "KEY_U" }, 173 { 0x55, "KEY_I" }, 174 { 0x56, "KEY_O" }, 175 { 0x57, "KEY_P" }, 176 { 0x58, "KEY_LEFTBRACE" }, 177 { 0x59, "KEY_RIGHTBRACE" }, 178 { 0x5a, "KEY_BACKSLASH" }, 179 { 0x5b, "KEY_CAPSLOCK" }, 180 { 0x5c, "KEY_A" }, 181 { 0x5d, "KEY_S" }, 182 { 0x5e, "KEY_D" }, 183 { 0x5f, "KEY_F" }, 184 { 0x60, "KEY_G" }, 185 { 0x61, "KEY_H" }, 186 { 0x62, "KEY_J" }, 187 { 0x63, "KEY_K" }, 188 { 0x64, "KEY_L" }, 189 { 0x65, "KEY_SEMICOLON" }, 190 { 0x66, "KEY_APOSTROPHE" }, 191 { 0x67, "KEY_ENTER" }, 192 { 0x68, "KEY_LEFTSHIFT" }, 193 { 0x69, "KEY_Z" }, 194 { 0x6a, "KEY_X" }, 195 { 0x6b, "KEY_C" }, 196 { 0x6c, "KEY_V" }, 197 { 0x6d, "KEY_B" }, 198 { 0x6e, "KEY_N" }, 199 { 0x6f, "KEY_M" }, 200 { 0x70, "KEY_COMMA" }, 201 { 0x71, "KEY_DOT" }, 202 { 0x72, "KEY_SLASH" }, 203 { 0x73, "KEY_RIGHTSHIFT" }, 204 { 0x74, "KEY_LEFTCTRL" }, 205 { 0x75, "KEY_LEFTMETA" }, 206 { 0x76, "KEY_LEFTALT" }, 207 { 0x77, "KEY_SPACE" }, 208 { 0x78, "KEY_RIGHTALT" }, 209 { 0x79, "KEY_RIGHTCTRL" }, 210 { 0x7a, "KEY_INSERT" }, 211 { 0x7b, "KEY_HOME" }, 212 { 0x7c, "KEY_PAGEUP" }, 213 { 0x7d, "KEY_DELETE" }, 214 { 0x7e, "KEY_END" }, 215 { 0x7f, "KEY_PAGEDOWN" }, 216 { 0x8a, "KEY_KPENTER" }, 217 { 0x8b, "KEY_KP0" }, 218 { 0x8c, "KEY_KP1" }, 219 { 0x8d, "KEY_KP2" }, 220 { 0x8e, "KEY_KP3" }, 221 { 0x8f, "KEY_KP4" }, 222 { 0x90, "KEY_KP5" }, 223 { 0x91, "KEY_KP6" }, 224 { 0x92, "KEY_KP7" }, 225 { 0x93, "KEY_KP8" }, 226 { 0x94, "KEY_KP9" }, 227 { 0x95, "MD_PLAY" }, 228 { 0x96, "MD_STOP" }, 229 { 0x97, "MD_NEXT" }, 230 { 0x98, "MD_PREV" }, 231 { 0x99, "MD_VOL_UP" }, 232 { 0x9a, "MD_VOL_DOWN" }, 233 { 0x9b, "MD_VOL_MUTE" }, 234 { 0x9c, "KEY_F23" }, 235 /* Mouse events */ 236 { 0xc8, "BTN_LEFT" }, 237 { 0xc9, "BTN_MIDDLE" }, 238 { 0xca, "BTN_RIGHT" }, 239 { 0xcb, "BTN_SIDE" }, 240 { 0xcc, "BTN_EXTRA" }, 241 { 0xcd, "REL_WHEEL_UP" }, 242 { 0xce, "REL_WHEEL_DOWN" }, 243 { 0xff, "DISABLED" }, 244 }; 245 246 enum claw_rgb_effect_index { 247 CLAW_RGB_EFFECT_MONOCOLOR, 248 CLAW_RGB_EFFECT_BREATHE, 249 CLAW_RGB_EFFECT_CHROMA, 250 CLAW_RGB_EFFECT_RAINBOW, 251 CLAW_RGB_EFFECT_FROSTFIRE, 252 }; 253 254 static const char * const claw_rgb_effect_text[] = { 255 [CLAW_RGB_EFFECT_MONOCOLOR] = "monocolor", 256 [CLAW_RGB_EFFECT_BREATHE] = "breathe", 257 [CLAW_RGB_EFFECT_CHROMA] = "chroma", 258 [CLAW_RGB_EFFECT_RAINBOW] = "rainbow", 259 [CLAW_RGB_EFFECT_FROSTFIRE] = "frostfire", 260 }; 261 262 static const u16 button_mapping_addr_old[] = { 263 0x007a, /* M1 */ 264 0x011f, /* M2 */ 265 }; 266 267 static const u16 button_mapping_addr_new[] = { 268 0x00bb, /* M1 */ 269 0x0164, /* M2 */ 270 }; 271 272 static const u16 rgb_addr_old = 0x01fa; 273 static const u16 rgb_addr_new = 0x024a; 274 275 struct claw_command_report { 276 u8 report_id; 277 u8 padding[2]; 278 u8 header_tail; 279 u8 cmd; 280 u8 data[59]; 281 } __packed; 282 283 struct claw_profile_report { 284 u8 profile; 285 __be16 read_addr; 286 } __packed; 287 288 struct claw_mkey_report { 289 struct claw_profile_report; 290 u8 padding_0; 291 u8 padding_1; 292 u8 padding_2; 293 u8 codes[5]; 294 } __packed; 295 296 struct rgb_zone { 297 u8 red; 298 u8 green; 299 u8 blue; 300 }; 301 302 struct rgb_frame { 303 struct rgb_zone zone[CLAW_RGB_ZONES]; 304 }; 305 306 struct claw_rgb_report { 307 struct claw_profile_report; 308 u8 frame_bytes; 309 u8 padding; 310 u8 frame_count; 311 u8 state; /* Always 0x09 */ 312 u8 speed; 313 u8 brightness; 314 struct rgb_frame zone_data; 315 } __packed; 316 317 struct claw_drvdata { 318 /* MCU General Variables */ 319 enum claw_profile_ack_pending profile_pending; 320 struct completion orphan_ack_complete; 321 struct completion send_cmd_complete; 322 struct delayed_work cfg_resume; 323 struct delayed_work cfg_setup; 324 spinlock_t registration_lock; /* Lock for registration read/write */ 325 struct mutex profile_mutex; /* mutex for profile_pending calls */ 326 spinlock_t profile_lock; /* Lock for profile_pending read/write */ 327 struct hid_device *hdev; 328 bool orphan_ack_pending; 329 struct mutex cfg_mutex; /* mutex for synchronous data */ 330 struct mutex rom_mutex; /* mutex for SYNC_TO_ROM calls */ 331 spinlock_t cmd_lock; /* Lock for cmd data read/write */ 332 u8 waiting_cmd; 333 int cmd_status; 334 u16 bcd_device; 335 u8 ep; 336 337 /* Gamepad Variables */ 338 enum claw_mkeys_function_index mkeys_function; 339 enum claw_gamepad_mode_index gamepad_mode; 340 u8 m1_codes[CLAW_KEYS_MAX]; 341 u8 m2_codes[CLAW_KEYS_MAX]; 342 spinlock_t mode_lock; /* Lock for mode data read/write */ 343 const u16 *bmap_addr; 344 bool gp_registered; 345 bool bmap_support; 346 347 /* RGB Variables */ 348 struct rgb_frame rgb_frames[CLAW_RGB_MAX_FRAMES]; 349 enum claw_rgb_effect_index rgb_effect; 350 struct led_classdev_mc led_mc; 351 struct delayed_work rgb_queue; 352 spinlock_t frame_lock; /* lock for rgb_frames read/write */ 353 bool rgb_registered; 354 u8 rgb_frame_count; 355 bool rgb_enabled; 356 u8 rgb_speed; 357 u16 rgb_addr; 358 }; 359 360 static int get_endpoint_address(struct hid_device *hdev) 361 { 362 struct usb_host_endpoint *ep; 363 struct usb_interface *intf; 364 365 intf = to_usb_interface(hdev->dev.parent); 366 ep = intf->cur_altsetting->endpoint; 367 if (ep) 368 return ep->desc.bEndpointAddress; 369 370 return -ENODEV; 371 } 372 373 static int claw_gamepad_mode_event(struct claw_drvdata *drvdata, 374 struct claw_command_report *cmd_rep) 375 { 376 if (cmd_rep->data[0] >= ARRAY_SIZE(claw_gamepad_mode_text) || 377 !claw_gamepad_mode_text[cmd_rep->data[0]] || 378 cmd_rep->data[1] >= ARRAY_SIZE(claw_mkeys_function_text)) 379 return -EINVAL; 380 381 scoped_guard(spinlock_irqsave, &drvdata->mode_lock) { 382 drvdata->gamepad_mode = cmd_rep->data[0]; 383 drvdata->mkeys_function = cmd_rep->data[1]; 384 } 385 386 return 0; 387 } 388 389 static int claw_profile_event(struct claw_drvdata *drvdata, struct claw_command_report *cmd_rep) 390 { 391 enum claw_profile_ack_pending profile; 392 struct claw_mkey_report *mkeys; 393 struct claw_rgb_report *frame; 394 u16 rgb_addr, read_addr; 395 u8 *codes, key, f_idx; 396 u16 frame_calc; 397 int i; 398 399 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 400 profile = drvdata->profile_pending; 401 402 switch (profile) { 403 case CLAW_M1_PENDING: 404 case CLAW_M2_PENDING: 405 key = (profile == CLAW_M1_PENDING) ? CLAW_KEY_M1 : CLAW_KEY_M2; 406 mkeys = (struct claw_mkey_report *)cmd_rep->data; 407 if (be16_to_cpu(mkeys->read_addr) != drvdata->bmap_addr[key]) 408 return -EAGAIN; 409 codes = (profile == CLAW_M1_PENDING) ? drvdata->m1_codes : drvdata->m2_codes; 410 for (i = 0; i < CLAW_KEYS_MAX; i++) 411 codes[i] = (mkeys->codes[i]); 412 break; 413 case CLAW_RGB_PENDING: 414 frame = (struct claw_rgb_report *)cmd_rep->data; 415 rgb_addr = drvdata->rgb_addr; 416 read_addr = be16_to_cpu(frame->read_addr); 417 418 if (read_addr < drvdata->rgb_addr) 419 return -EAGAIN; 420 421 frame_calc = (read_addr - rgb_addr) / CLAW_RGB_FRAME_OFFSET; 422 if (frame_calc >= CLAW_RGB_MAX_FRAMES) { 423 dev_err(&drvdata->hdev->dev, "Got unsupported frame index: %x\n", 424 frame_calc); 425 return -EAGAIN; 426 } 427 f_idx = frame_calc; 428 429 scoped_guard(spinlock_irqsave, &drvdata->frame_lock) { 430 memcpy(&drvdata->rgb_frames[f_idx], &frame->zone_data, 431 sizeof(struct rgb_frame)); 432 433 /* Only use frame 0 for remaining variable assignment */ 434 if (f_idx != 0) 435 break; 436 437 drvdata->rgb_speed = frame->speed; 438 drvdata->led_mc.led_cdev.brightness = frame->brightness; 439 drvdata->led_mc.subled_info[0].intensity = frame->zone_data.zone[0].red; 440 drvdata->led_mc.subled_info[1].intensity = frame->zone_data.zone[0].green; 441 drvdata->led_mc.subled_info[2].intensity = frame->zone_data.zone[0].blue; 442 } 443 444 break; 445 default: 446 dev_dbg(&drvdata->hdev->dev, 447 "Got profile event without changes pending from command: %x\n", 448 cmd_rep->cmd); 449 return -EINVAL; 450 } 451 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 452 drvdata->profile_pending = CLAW_NO_PENDING; 453 454 return 0; 455 } 456 457 static int claw_raw_event(struct claw_drvdata *drvdata, struct hid_report *report, 458 u8 *data, int size) 459 { 460 struct claw_command_report *cmd_rep; 461 int ret = 0; 462 463 if (size != CLAW_PACKET_SIZE) 464 return 0; 465 466 cmd_rep = (struct claw_command_report *)data; 467 468 if (cmd_rep->report_id != CLAW_INPUT_REPORT_ID || cmd_rep->header_tail != 0x3c) 469 return 0; 470 471 dev_dbg(&drvdata->hdev->dev, "Rx data as raw input report: [%*ph]\n", 472 CLAW_PACKET_SIZE, data); 473 474 guard(spinlock_irqsave)(&drvdata->cmd_lock); 475 switch (cmd_rep->cmd) { 476 case CLAW_COMMAND_TYPE_GAMEPAD_MODE_ACK: 477 ret = claw_gamepad_mode_event(drvdata, cmd_rep); 478 if (drvdata->waiting_cmd == CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE) { 479 drvdata->cmd_status = ret; 480 complete(&drvdata->send_cmd_complete); 481 } 482 483 break; 484 case CLAW_COMMAND_TYPE_READ_PROFILE_ACK: 485 ret = claw_profile_event(drvdata, cmd_rep); 486 /* Stale address received, ignore and keep waiting */ 487 if (ret == -EAGAIN) 488 return 0; 489 if (drvdata->waiting_cmd == CLAW_COMMAND_TYPE_READ_PROFILE) { 490 drvdata->cmd_status = ret; 491 complete(&drvdata->send_cmd_complete); 492 } 493 494 break; 495 case CLAW_COMMAND_TYPE_ACK: 496 if (drvdata->orphan_ack_pending) { 497 drvdata->orphan_ack_pending = false; 498 complete(&drvdata->orphan_ack_complete); 499 break; 500 } 501 502 if (drvdata->waiting_cmd == CLAW_COMMAND_TYPE_NONE) { 503 dev_warn(&drvdata->hdev->dev, "Got unexpected ACK from MCU, ignoring\n"); 504 break; 505 } 506 507 drvdata->cmd_status = 0; 508 complete(&drvdata->send_cmd_complete); 509 510 dev_dbg(&drvdata->hdev->dev, "Waiting CMD: %x\n", drvdata->waiting_cmd); 511 512 break; 513 default: 514 dev_dbg(&drvdata->hdev->dev, "Unknown command: %x\n", cmd_rep->cmd); 515 return 0; 516 } 517 518 return ret; 519 } 520 521 static int msi_raw_event(struct hid_device *hdev, struct hid_report *report, 522 u8 *data, int size) 523 { 524 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 525 526 if (!drvdata || (drvdata->ep != CLAW_XINPUT_CFG_INTF_IN && 527 drvdata->ep != CLAW_DINPUT_CFG_INTF_IN)) 528 return 0; 529 530 return claw_raw_event(drvdata, report, data, size); 531 } 532 533 /* Caller must hold drvdata->cfg_mutex. */ 534 static int __claw_hw_output_report(struct hid_device *hdev, u8 index, u8 *data, 535 size_t len, unsigned int timeout) 536 { 537 unsigned char *dmabuf __free(kfree) = NULL; 538 u8 header[] = { CLAW_OUTPUT_REPORT_ID, 0, 0, 0x3c, index }; 539 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 540 size_t header_size = ARRAY_SIZE(header); 541 bool orphaned; 542 int ret; 543 544 lockdep_assert_held(&drvdata->cfg_mutex); 545 546 /* If expecting an orphan ack, hold next event until MCU has time to clear it */ 547 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) 548 orphaned = drvdata->orphan_ack_pending; 549 550 if (orphaned) { 551 wait_for_completion_timeout(&drvdata->orphan_ack_complete, msecs_to_jiffies(25)); 552 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) 553 drvdata->orphan_ack_pending = false; 554 } 555 556 if (header_size + len > CLAW_PACKET_SIZE) 557 return -EINVAL; 558 559 /* We can't use a devm_alloc reusable buffer without side effects during suspend */ 560 dmabuf = kzalloc(CLAW_PACKET_SIZE, GFP_KERNEL); 561 if (!dmabuf) 562 return -ENOMEM; 563 564 memcpy(dmabuf, header, header_size); 565 if (data && len) 566 memcpy(dmabuf + header_size, data, len); 567 568 reinit_completion(&drvdata->send_cmd_complete); 569 570 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) { 571 if (timeout) { 572 drvdata->waiting_cmd = index; 573 drvdata->cmd_status = -ETIMEDOUT; 574 } else { 575 reinit_completion(&drvdata->orphan_ack_complete); 576 drvdata->waiting_cmd = CLAW_COMMAND_TYPE_NONE; 577 drvdata->orphan_ack_pending = true; 578 } 579 } 580 581 dev_dbg(&hdev->dev, "Send data as raw output report: [%*ph]\n", 582 CLAW_PACKET_SIZE, dmabuf); 583 584 ret = hid_hw_output_report(hdev, dmabuf, CLAW_PACKET_SIZE); 585 if (ret < 0) 586 goto err; 587 588 ret = ret == CLAW_PACKET_SIZE ? 0 : -EIO; 589 if (ret) 590 goto err; 591 592 if (timeout) { 593 ret = wait_for_completion_interruptible_timeout(&drvdata->send_cmd_complete, 594 msecs_to_jiffies(timeout)); 595 596 dev_dbg(&hdev->dev, "Remaining timeout: %u\n", ret); 597 ret = ret > 0 ? drvdata->cmd_status : ret ?: -EBUSY; 598 if (ret) 599 goto err; 600 } 601 602 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) 603 drvdata->waiting_cmd = CLAW_COMMAND_TYPE_NONE; 604 605 return ret; 606 607 err: 608 scoped_guard(spinlock_irqsave, &drvdata->cmd_lock) { 609 drvdata->waiting_cmd = CLAW_COMMAND_TYPE_NONE; 610 drvdata->orphan_ack_pending = false; 611 } 612 return ret; 613 } 614 615 static int claw_hw_output_report(struct hid_device *hdev, u8 index, u8 *data, 616 size_t len, unsigned int timeout) 617 { 618 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 619 620 guard(mutex)(&drvdata->cfg_mutex); 621 return __claw_hw_output_report(hdev, index, data, len, timeout); 622 } 623 624 static int claw_switch_mode(struct hid_device *hdev, enum claw_mode_field field, u8 val) 625 { 626 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 627 u8 data[2]; 628 629 guard(mutex)(&drvdata->cfg_mutex); 630 631 scoped_guard(spinlock_irqsave, &drvdata->mode_lock) { 632 switch (field) { 633 case CLAW_FIELD_GAMEPAD_MODE: 634 data[0] = val; 635 data[1] = drvdata->mkeys_function; 636 break; 637 case CLAW_FIELD_MKEYS_FUNCTION: 638 data[0] = drvdata->gamepad_mode; 639 data[1] = val; 640 break; 641 } 642 } 643 644 return __claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_SWITCH_MODE, data, 645 ARRAY_SIZE(data), 0); 646 } 647 648 static ssize_t gamepad_mode_store(struct device *dev, struct device_attribute *attr, 649 const char *buf, size_t count) 650 { 651 struct hid_device *hdev = to_hid_device(dev); 652 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 653 int i, ret = -EINVAL; 654 655 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 656 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 657 if (!smp_load_acquire(&drvdata->gp_registered)) 658 return -ENODEV; 659 } 660 661 for (i = 0; i < ARRAY_SIZE(claw_gamepad_mode_text); i++) { 662 if (claw_gamepad_mode_text[i] && sysfs_streq(buf, claw_gamepad_mode_text[i])) { 663 ret = i; 664 break; 665 } 666 } 667 if (ret < 0) 668 return ret; 669 670 ret = claw_switch_mode(hdev, CLAW_FIELD_GAMEPAD_MODE, ret); 671 if (ret) 672 return ret; 673 674 return count; 675 } 676 677 static ssize_t gamepad_mode_show(struct device *dev, 678 struct device_attribute *attr, char *buf) 679 { 680 struct hid_device *hdev = to_hid_device(dev); 681 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 682 int ret, i; 683 684 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 685 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 686 if (!smp_load_acquire(&drvdata->gp_registered)) 687 return -ENODEV; 688 } 689 690 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE, NULL, 0, 25); 691 if (ret) 692 return ret; 693 694 scoped_guard(spinlock_irqsave, &drvdata->mode_lock) 695 i = drvdata->gamepad_mode; 696 697 if (!claw_gamepad_mode_text[i] || claw_gamepad_mode_text[i][0] == '\0') 698 return sysfs_emit(buf, "unsupported\n"); 699 700 return sysfs_emit(buf, "%s\n", claw_gamepad_mode_text[i]); 701 } 702 static DEVICE_ATTR_RW(gamepad_mode); 703 704 static ssize_t gamepad_mode_index_show(struct device *dev, 705 struct device_attribute *attr, char *buf) 706 { 707 ssize_t count = 0; 708 int i; 709 710 for (i = 0; i < ARRAY_SIZE(claw_gamepad_mode_text); i++) { 711 if (!claw_gamepad_mode_text[i] || claw_gamepad_mode_text[i][0] == '\0') 712 continue; 713 count += sysfs_emit_at(buf, count, "%s ", claw_gamepad_mode_text[i]); 714 } 715 716 if (count) 717 buf[count - 1] = '\n'; 718 719 return count; 720 } 721 static DEVICE_ATTR_RO(gamepad_mode_index); 722 723 static ssize_t mkeys_function_store(struct device *dev, struct device_attribute *attr, 724 const char *buf, size_t count) 725 { 726 struct hid_device *hdev = to_hid_device(dev); 727 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 728 int i, ret = -EINVAL; 729 730 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 731 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 732 if (!smp_load_acquire(&drvdata->gp_registered)) 733 return -ENODEV; 734 } 735 736 for (i = 0; i < ARRAY_SIZE(claw_mkeys_function_text); i++) { 737 if (claw_mkeys_function_text[i] && sysfs_streq(buf, claw_mkeys_function_text[i])) { 738 ret = i; 739 break; 740 } 741 } 742 if (ret < 0) 743 return ret; 744 745 ret = claw_switch_mode(hdev, CLAW_FIELD_MKEYS_FUNCTION, ret); 746 if (ret) 747 return ret; 748 749 return count; 750 } 751 752 static ssize_t mkeys_function_show(struct device *dev, struct device_attribute *attr, 753 char *buf) 754 { 755 struct hid_device *hdev = to_hid_device(dev); 756 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 757 int ret, i; 758 759 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 760 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 761 if (!smp_load_acquire(&drvdata->gp_registered)) 762 return -ENODEV; 763 } 764 765 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE, NULL, 0, 25); 766 if (ret) 767 return ret; 768 769 scoped_guard(spinlock_irqsave, &drvdata->mode_lock) 770 i = drvdata->mkeys_function; 771 772 if (i >= ARRAY_SIZE(claw_mkeys_function_text)) 773 return sysfs_emit(buf, "unsupported\n"); 774 775 return sysfs_emit(buf, "%s\n", claw_mkeys_function_text[i]); 776 } 777 static DEVICE_ATTR_RW(mkeys_function); 778 779 static ssize_t mkeys_function_index_show(struct device *dev, 780 struct device_attribute *attr, char *buf) 781 { 782 int i, count = 0; 783 784 for (i = 0; i < ARRAY_SIZE(claw_mkeys_function_text); i++) 785 count += sysfs_emit_at(buf, count, "%s ", claw_mkeys_function_text[i]); 786 787 if (count) 788 buf[count - 1] = '\n'; 789 790 return count; 791 } 792 static DEVICE_ATTR_RO(mkeys_function_index); 793 794 static ssize_t reset_store(struct device *dev, struct device_attribute *attr, 795 const char *buf, size_t count) 796 { 797 struct hid_device *hdev = to_hid_device(dev); 798 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 799 bool val; 800 int ret; 801 802 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 803 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 804 if (!smp_load_acquire(&drvdata->gp_registered)) 805 return -ENODEV; 806 } 807 808 ret = kstrtobool(buf, &val); 809 if (ret) 810 return ret; 811 812 if (!val) 813 return -EINVAL; 814 815 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_RESET_DEVICE, NULL, 0, 0); 816 if (ret) 817 return ret; 818 819 return count; 820 } 821 static DEVICE_ATTR_WO(reset); 822 823 static int mkey_mapping_name_to_code(const char *name) 824 { 825 int i; 826 827 for (i = 0; i < ARRAY_SIZE(claw_button_mapping_key_map); i++) { 828 if (!strcmp(name, claw_button_mapping_key_map[i].name)) 829 return claw_button_mapping_key_map[i].code; 830 } 831 832 return -EINVAL; 833 } 834 835 static const char *mkey_mapping_code_to_name(u8 code) 836 { 837 int i; 838 839 if (code == 0xff) 840 return NULL; 841 842 for (i = 0; i < ARRAY_SIZE(claw_button_mapping_key_map); i++) { 843 if (claw_button_mapping_key_map[i].code == code) 844 return claw_button_mapping_key_map[i].name; 845 } 846 847 return NULL; 848 } 849 850 static int claw_mkey_store(struct device *dev, const char *buf, u8 mkey) 851 { 852 struct hid_device *hdev = to_hid_device(dev); 853 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 854 struct claw_mkey_report report = { {0x01, cpu_to_be16(drvdata->bmap_addr[mkey])}, 855 0x07, 0x04, 0x00, {0xff, 0xff, 0xff, 0xff, 0xff} }; 856 char **raw_keys __free(argv_free) = NULL; 857 int ret, key_count, i; 858 859 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 860 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 861 if (!smp_load_acquire(&drvdata->gp_registered)) 862 return -ENODEV; 863 } 864 865 raw_keys = argv_split(GFP_KERNEL, buf, &key_count); 866 if (!raw_keys) 867 return -ENOMEM; 868 869 if (key_count > CLAW_KEYS_MAX) 870 return -EINVAL; 871 872 if (key_count == 0) 873 goto set_buttons; 874 875 for (i = 0; i < key_count; i++) { 876 ret = mkey_mapping_name_to_code(raw_keys[i]); 877 if (ret < 0) 878 return ret; 879 880 report.codes[i] = ret; 881 } 882 883 set_buttons: 884 scoped_guard(mutex, &drvdata->rom_mutex) { 885 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_WRITE_PROFILE_DATA, 886 (u8 *)&report, sizeof(report), 25); 887 if (ret) 888 return ret; 889 /* MCU will not send ACK until the USB transaction completes. ACK is sent 890 * immediately after and will hit the stale state machine, before the next 891 * command re-arms the state machine. Timeout 0 ensures no deadlock waiting 892 * for ACK that ill never come. 893 */ 894 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_SYNC_TO_ROM, NULL, 0, 0); 895 } 896 897 return ret; 898 } 899 900 static int claw_mkey_show(struct device *dev, char *buf, enum claw_key_index m_key) 901 { 902 struct hid_device *hdev = to_hid_device(dev); 903 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 904 struct claw_mkey_report report = { {0x01, cpu_to_be16(drvdata->bmap_addr[m_key])}, 0x07 }; 905 int i, ret, count = 0; 906 const char *name; 907 u8 *codes; 908 909 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 910 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 911 if (!smp_load_acquire(&drvdata->gp_registered)) 912 return -ENODEV; 913 } 914 915 codes = (m_key == CLAW_KEY_M1) ? drvdata->m1_codes : drvdata->m2_codes; 916 917 guard(mutex)(&drvdata->profile_mutex); 918 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 919 drvdata->profile_pending = (m_key == CLAW_KEY_M1) ? CLAW_M1_PENDING 920 : CLAW_M2_PENDING; 921 922 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_READ_PROFILE, 923 (u8 *)&report, sizeof(report), 25); 924 if (ret) 925 return ret; 926 927 for (i = 0; i < CLAW_KEYS_MAX; i++) { 928 name = mkey_mapping_code_to_name(codes[i]); 929 if (name) 930 count += sysfs_emit_at(buf, count, "%s ", name); 931 } 932 933 if (!count) 934 return sysfs_emit(buf, "(not set)\n"); 935 936 buf[count - 1] = '\n'; 937 938 return count; 939 } 940 941 static ssize_t button_m1_store(struct device *dev, struct device_attribute *attr, 942 const char *buf, size_t count) 943 { 944 int ret; 945 946 ret = claw_mkey_store(dev, buf, CLAW_KEY_M1); 947 if (ret) 948 return ret; 949 950 return count; 951 } 952 953 static ssize_t button_m1_show(struct device *dev, struct device_attribute *attr, 954 char *buf) 955 { 956 return claw_mkey_show(dev, buf, CLAW_KEY_M1); 957 } 958 static DEVICE_ATTR_RW(button_m1); 959 960 static ssize_t button_m2_store(struct device *dev, struct device_attribute *attr, 961 const char *buf, size_t count) 962 { 963 int ret; 964 965 ret = claw_mkey_store(dev, buf, CLAW_KEY_M2); 966 if (ret) 967 return ret; 968 969 return count; 970 } 971 972 static ssize_t button_m2_show(struct device *dev, struct device_attribute *attr, 973 char *buf) 974 { 975 return claw_mkey_show(dev, buf, CLAW_KEY_M2); 976 } 977 static DEVICE_ATTR_RW(button_m2); 978 979 static ssize_t button_mapping_options_show(struct device *dev, 980 struct device_attribute *attr, char *buf) 981 { 982 int i, count = 0; 983 984 for (i = 0; i < ARRAY_SIZE(claw_button_mapping_key_map); i++) 985 count += sysfs_emit_at(buf, count, "%s ", claw_button_mapping_key_map[i].name); 986 987 if (count) 988 buf[count - 1] = '\n'; 989 990 return count; 991 } 992 static DEVICE_ATTR_RO(button_mapping_options); 993 994 static umode_t claw_gamepad_attr_is_visible(struct kobject *kobj, struct attribute *attr, 995 int n) 996 { 997 struct hid_device *hdev = to_hid_device(kobj_to_dev(kobj)); 998 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 999 1000 if (!drvdata) { 1001 dev_warn(&hdev->dev, 1002 "Failed to get drvdata from kobj. Gamepad attributes are not available.\n"); 1003 return 0; 1004 } 1005 1006 /* Always show attrs available on all firmware */ 1007 if (attr == &dev_attr_gamepad_mode.attr || 1008 attr == &dev_attr_gamepad_mode_index.attr || 1009 attr == &dev_attr_mkeys_function.attr || 1010 attr == &dev_attr_mkeys_function_index.attr || 1011 attr == &dev_attr_reset.attr) 1012 return attr->mode; 1013 1014 /* Hide button mapping attrs if it isn't supported */ 1015 return drvdata->bmap_support ? attr->mode : 0; 1016 } 1017 1018 static struct attribute *claw_gamepad_attrs[] = { 1019 &dev_attr_button_m1.attr, 1020 &dev_attr_button_m2.attr, 1021 &dev_attr_button_mapping_options.attr, 1022 &dev_attr_gamepad_mode.attr, 1023 &dev_attr_gamepad_mode_index.attr, 1024 &dev_attr_mkeys_function.attr, 1025 &dev_attr_mkeys_function_index.attr, 1026 &dev_attr_reset.attr, 1027 NULL, 1028 }; 1029 1030 static const struct attribute_group claw_gamepad_attr_group = { 1031 .attrs = claw_gamepad_attrs, 1032 .is_visible = claw_gamepad_attr_is_visible, 1033 }; 1034 1035 /* Read RGB config from device */ 1036 static int claw_read_rgb_config(struct hid_device *hdev) 1037 { 1038 u8 data[4] = { 0x01, 0x00, 0x00, CLAW_RGB_FRAME_OFFSET }; 1039 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 1040 u16 read_addr = drvdata->rgb_addr; 1041 size_t len = ARRAY_SIZE(data); 1042 int ret, i; 1043 1044 if (!drvdata->rgb_addr) 1045 return -ENODEV; 1046 1047 /* Loop through all 8 pages of RGB data */ 1048 guard(mutex)(&drvdata->profile_mutex); 1049 for (i = 0; i < CLAW_RGB_MAX_FRAMES; i++) { 1050 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 1051 drvdata->profile_pending = CLAW_RGB_PENDING; 1052 data[1] = (read_addr >> 8) & 0xff; 1053 data[2] = read_addr & 0x00ff; 1054 ret = claw_hw_output_report(hdev, CLAW_COMMAND_TYPE_READ_PROFILE, data, len, 25); 1055 if (ret) 1056 return ret; 1057 1058 read_addr += CLAW_RGB_FRAME_OFFSET; 1059 } 1060 1061 return 0; 1062 } 1063 1064 /* Send RGB configuration to device */ 1065 static int claw_write_rgb_state(struct claw_drvdata *drvdata) 1066 { 1067 struct claw_rgb_report report = { {0x01, 0}, CLAW_RGB_FRAME_OFFSET, 0x00, 1068 drvdata->rgb_frame_count, 0x09, drvdata->rgb_speed, 1069 drvdata->led_mc.led_cdev.brightness }; 1070 u16 write_addr = drvdata->rgb_addr; 1071 int f, ret; 1072 1073 if (!drvdata->rgb_addr) 1074 return -ENODEV; 1075 1076 if (!drvdata->rgb_frame_count) 1077 return -EINVAL; 1078 1079 guard(mutex)(&drvdata->rom_mutex); 1080 /* Loop through (up to) 8 pages of RGB data */ 1081 for (f = 0; f < drvdata->rgb_frame_count; f++) { 1082 scoped_guard(spinlock_irqsave, &drvdata->frame_lock) 1083 report.zone_data = drvdata->rgb_frames[f]; 1084 1085 /* Set the MCU address to write the frame data to */ 1086 report.read_addr = cpu_to_be16(write_addr); 1087 1088 /* Serialize the rgb_report and write it to MCU */ 1089 ret = claw_hw_output_report(drvdata->hdev, CLAW_COMMAND_TYPE_WRITE_PROFILE_DATA, 1090 (u8 *)&report, sizeof(report), 25); 1091 if (ret) 1092 return ret; 1093 1094 /* Increment the write addr by the offset for the next frame */ 1095 write_addr += CLAW_RGB_FRAME_OFFSET; 1096 } 1097 1098 /* MCU will not send ACK until the USB transaction completes. ACK is sent 1099 * immediately after and will hit the stale state machine, before the next 1100 * command re-arms the state machine. Timeout 0 ensures no deadlock waiting 1101 * for ACK that ill never come. 1102 */ 1103 ret = claw_hw_output_report(drvdata->hdev, CLAW_COMMAND_TYPE_SYNC_TO_ROM, NULL, 0, 0); 1104 1105 return ret; 1106 } 1107 1108 /* Fill all zones with the same color */ 1109 static void claw_frame_fill_solid(struct rgb_frame *frame, struct rgb_zone zone) 1110 { 1111 int z; 1112 1113 for (z = 0; z < CLAW_RGB_ZONES; z++) 1114 frame->zone[z] = zone; 1115 } 1116 1117 /* Apply solid effect (1 frame, no color) */ 1118 static int claw_apply_disabled(struct claw_drvdata *drvdata) 1119 { 1120 struct rgb_zone off = { 0x00, 0x00, 0x00}; 1121 1122 scoped_guard(spinlock_irqsave, &drvdata->frame_lock) { 1123 drvdata->rgb_frame_count = 1; 1124 claw_frame_fill_solid(&drvdata->rgb_frames[0], off); 1125 } 1126 1127 return claw_write_rgb_state(drvdata); 1128 } 1129 1130 /* Apply solid effect (1 frame, all zones same color) */ 1131 static int claw_apply_monocolor(struct claw_drvdata *drvdata) 1132 { 1133 struct mc_subled *subleds = drvdata->led_mc.subled_info; 1134 struct rgb_zone zone = { subleds[0].intensity, subleds[1].intensity, 1135 subleds[2].intensity }; 1136 1137 scoped_guard(spinlock_irqsave, &drvdata->frame_lock) { 1138 drvdata->rgb_frame_count = 1; 1139 claw_frame_fill_solid(&drvdata->rgb_frames[0], zone); 1140 } 1141 1142 return claw_write_rgb_state(drvdata); 1143 } 1144 1145 /* Apply breathe effect (2 frames: color -> off) */ 1146 static int claw_apply_breathe(struct claw_drvdata *drvdata) 1147 { 1148 struct mc_subled *subleds = drvdata->led_mc.subled_info; 1149 struct rgb_zone zone = { subleds[0].intensity, subleds[1].intensity, 1150 subleds[2].intensity }; 1151 static const struct rgb_zone off = { 0, 0, 0 }; 1152 1153 scoped_guard(spinlock_irqsave, &drvdata->frame_lock) { 1154 drvdata->rgb_frame_count = 2; 1155 claw_frame_fill_solid(&drvdata->rgb_frames[0], zone); 1156 claw_frame_fill_solid(&drvdata->rgb_frames[1], off); 1157 } 1158 1159 return claw_write_rgb_state(drvdata); 1160 } 1161 1162 /* Apply chroma effect (6 frames: rainbow cycle, all zones sync) */ 1163 static int claw_apply_chroma(struct claw_drvdata *drvdata) 1164 { 1165 static const struct rgb_zone colors[] = { 1166 {255, 0, 0}, /* red */ 1167 {255, 255, 0}, /* yellow */ 1168 { 0, 255, 0}, /* green */ 1169 { 0, 255, 255}, /* cyan */ 1170 { 0, 0, 255}, /* blue */ 1171 {255, 0, 255}, /* magenta */ 1172 }; 1173 u8 frame_count = ARRAY_SIZE(colors); 1174 int f; 1175 1176 scoped_guard(spinlock_irqsave, &drvdata->frame_lock) { 1177 drvdata->rgb_frame_count = frame_count; 1178 1179 for (f = 0; f < frame_count; f++) 1180 claw_frame_fill_solid(&drvdata->rgb_frames[f], colors[f]); 1181 } 1182 1183 return claw_write_rgb_state(drvdata); 1184 } 1185 1186 /* Apply rainbow effect (4 frames: rotating colors around joysticks) */ 1187 static int claw_apply_rainbow(struct claw_drvdata *drvdata) 1188 { 1189 static const struct rgb_zone colors[] = { 1190 {255, 0, 0}, /* red */ 1191 { 0, 255, 0}, /* green */ 1192 { 0, 255, 255}, /* cyan */ 1193 { 0, 0, 255}, /* blue */ 1194 }; 1195 u8 frame_count = ARRAY_SIZE(colors); 1196 int f, z; 1197 1198 scoped_guard(spinlock_irqsave, &drvdata->frame_lock) { 1199 drvdata->rgb_frame_count = frame_count; 1200 1201 for (f = 0; f < frame_count; f++) { 1202 for (z = 0; z < 4; z++) { 1203 drvdata->rgb_frames[f].zone[z] = colors[(z + f) % 4]; 1204 drvdata->rgb_frames[f].zone[z + 4] = colors[(z + f) % 4]; 1205 } 1206 drvdata->rgb_frames[f].zone[8] = colors[f]; 1207 } 1208 } 1209 1210 return claw_write_rgb_state(drvdata); 1211 } 1212 1213 /* 1214 * Apply frostfire effect (4 frames: fire vs ice rotating) 1215 * Right joystick: fire red -> dark -> ice blue -> dark (clockwise) 1216 * Left joystick: ice blue -> dark -> fire red -> dark (counter-clockwise) 1217 * ABXY: fire red -> dark -> ice blue -> dark 1218 */ 1219 static int claw_apply_frostfire(struct claw_drvdata *drvdata) 1220 { 1221 static const struct rgb_zone colors[] = { 1222 {255, 0, 0}, /* fire red */ 1223 { 0, 0, 0}, /* dark */ 1224 { 0, 0, 255}, /* ice blue */ 1225 { 0, 0, 0}, /* dark */ 1226 }; 1227 u8 frame_count = ARRAY_SIZE(colors); 1228 int f, z; 1229 1230 scoped_guard(spinlock_irqsave, &drvdata->frame_lock) { 1231 drvdata->rgb_frame_count = frame_count; 1232 1233 for (f = 0; f < frame_count; f++) { 1234 for (z = 0; z < 4; z++) { 1235 drvdata->rgb_frames[f].zone[z] = colors[(z + f) % 4]; 1236 drvdata->rgb_frames[f].zone[z + 4] = colors[(z - f + 6) % 4]; 1237 } 1238 drvdata->rgb_frames[f].zone[8] = colors[f]; 1239 } 1240 } 1241 1242 return claw_write_rgb_state(drvdata); 1243 } 1244 1245 /* Apply current state to device */ 1246 static int claw_apply_rgb_state(struct claw_drvdata *drvdata) 1247 { 1248 if (!drvdata->rgb_enabled) 1249 return claw_apply_disabled(drvdata); 1250 1251 switch (drvdata->rgb_effect) { 1252 case CLAW_RGB_EFFECT_MONOCOLOR: 1253 return claw_apply_monocolor(drvdata); 1254 case CLAW_RGB_EFFECT_BREATHE: 1255 return claw_apply_breathe(drvdata); 1256 case CLAW_RGB_EFFECT_CHROMA: 1257 return claw_apply_chroma(drvdata); 1258 case CLAW_RGB_EFFECT_RAINBOW: 1259 return claw_apply_rainbow(drvdata); 1260 case CLAW_RGB_EFFECT_FROSTFIRE: 1261 return claw_apply_frostfire(drvdata); 1262 default: 1263 dev_err(&drvdata->hdev->dev, "No supported rgb_effect selected\n"); 1264 return -EINVAL; 1265 } 1266 } 1267 1268 static void claw_rgb_queue_fn(struct work_struct *work) 1269 { 1270 struct delayed_work *dwork = container_of(work, struct delayed_work, work); 1271 struct claw_drvdata *drvdata = container_of(dwork, struct claw_drvdata, rgb_queue); 1272 int ret; 1273 1274 if (!drvdata) 1275 return; 1276 1277 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1278 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1279 if (!smp_load_acquire(&drvdata->rgb_registered)) 1280 return; 1281 } 1282 1283 ret = claw_apply_rgb_state(drvdata); 1284 if (ret) 1285 dev_err(&drvdata->hdev->dev, "Failed to apply RGB state: %d\n", ret); 1286 } 1287 1288 static ssize_t effect_store(struct device *dev, 1289 struct device_attribute *attr, 1290 const char *buf, size_t count) 1291 { 1292 struct led_classdev *led_cdev = dev_get_drvdata(dev); 1293 struct led_classdev_mc *led_mc = container_of(led_cdev, struct led_classdev_mc, led_cdev); 1294 struct claw_drvdata *drvdata = container_of(led_mc, struct claw_drvdata, led_mc); 1295 int ret; 1296 1297 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1298 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1299 if (!smp_load_acquire(&drvdata->rgb_registered)) 1300 return -ENODEV; 1301 } 1302 1303 ret = sysfs_match_string(claw_rgb_effect_text, buf); 1304 if (ret < 0) 1305 return ret; 1306 1307 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 1308 drvdata->rgb_effect = ret; 1309 1310 mod_delayed_work(system_wq, &drvdata->rgb_queue, msecs_to_jiffies(50)); 1311 1312 return count; 1313 } 1314 1315 static ssize_t effect_show(struct device *dev, 1316 struct device_attribute *attr, char *buf) 1317 { 1318 struct led_classdev *led_cdev = dev_get_drvdata(dev); 1319 struct led_classdev_mc *led_mc = container_of(led_cdev, struct led_classdev_mc, led_cdev); 1320 struct claw_drvdata *drvdata = container_of(led_mc, struct claw_drvdata, led_mc); 1321 1322 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1323 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1324 if (!smp_load_acquire(&drvdata->rgb_registered)) 1325 return -ENODEV; 1326 } 1327 1328 if (drvdata->rgb_effect >= ARRAY_SIZE(claw_rgb_effect_text)) 1329 return -EINVAL; 1330 1331 return sysfs_emit(buf, "%s\n", claw_rgb_effect_text[drvdata->rgb_effect]); 1332 } 1333 1334 static DEVICE_ATTR_RW(effect); 1335 1336 static ssize_t effect_index_show(struct device *dev, 1337 struct device_attribute *attr, char *buf) 1338 { 1339 int i, count = 0; 1340 1341 for (i = 0; i < ARRAY_SIZE(claw_rgb_effect_text); i++) 1342 count += sysfs_emit_at(buf, count, "%s ", claw_rgb_effect_text[i]); 1343 1344 if (count) 1345 buf[count - 1] = '\n'; 1346 1347 return count; 1348 } 1349 static DEVICE_ATTR_RO(effect_index); 1350 1351 static ssize_t enabled_store(struct device *dev, 1352 struct device_attribute *attr, 1353 const char *buf, size_t count) 1354 { 1355 struct led_classdev *led_cdev = dev_get_drvdata(dev); 1356 struct led_classdev_mc *led_mc = container_of(led_cdev, struct led_classdev_mc, led_cdev); 1357 struct claw_drvdata *drvdata = container_of(led_mc, struct claw_drvdata, led_mc); 1358 bool val; 1359 int ret; 1360 1361 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1362 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1363 if (!smp_load_acquire(&drvdata->rgb_registered)) 1364 return -ENODEV; 1365 } 1366 1367 ret = kstrtobool(buf, &val); 1368 if (ret) 1369 return ret; 1370 1371 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 1372 drvdata->rgb_enabled = val; 1373 1374 mod_delayed_work(system_wq, &drvdata->rgb_queue, msecs_to_jiffies(50)); 1375 1376 return count; 1377 } 1378 1379 static ssize_t enabled_show(struct device *dev, 1380 struct device_attribute *attr, char *buf) 1381 { 1382 struct led_classdev *led_cdev = dev_get_drvdata(dev); 1383 struct led_classdev_mc *led_mc = container_of(led_cdev, struct led_classdev_mc, led_cdev); 1384 struct claw_drvdata *drvdata = container_of(led_mc, struct claw_drvdata, led_mc); 1385 1386 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1387 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1388 if (!smp_load_acquire(&drvdata->rgb_registered)) 1389 return -ENODEV; 1390 } 1391 1392 return sysfs_emit(buf, "%s\n", drvdata->rgb_enabled ? "true" : "false"); 1393 } 1394 static DEVICE_ATTR_RW(enabled); 1395 1396 static ssize_t enabled_index_show(struct device *dev, 1397 struct device_attribute *attr, char *buf) 1398 { 1399 return sysfs_emit(buf, "true false\n"); 1400 } 1401 static DEVICE_ATTR_RO(enabled_index); 1402 1403 static ssize_t speed_store(struct device *dev, struct device_attribute *attr, 1404 const char *buf, size_t count) 1405 { 1406 struct led_classdev *led_cdev = dev_get_drvdata(dev); 1407 struct led_classdev_mc *led_mc = container_of(led_cdev, struct led_classdev_mc, led_cdev); 1408 struct claw_drvdata *drvdata = container_of(led_mc, struct claw_drvdata, led_mc); 1409 unsigned int val, speed; 1410 int ret; 1411 1412 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1413 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1414 if (!smp_load_acquire(&drvdata->rgb_registered)) 1415 return -ENODEV; 1416 } 1417 1418 ret = kstrtouint(buf, 10, &val); 1419 if (ret) 1420 return ret; 1421 1422 if (val > 20) 1423 return -EINVAL; 1424 1425 /* 0 is fastest, invert value for intuitive userspace speed */ 1426 speed = 20 - val; 1427 1428 scoped_guard(spinlock_irqsave, &drvdata->profile_lock) 1429 drvdata->rgb_speed = speed; 1430 1431 mod_delayed_work(system_wq, &drvdata->rgb_queue, msecs_to_jiffies(50)); 1432 1433 return count; 1434 } 1435 1436 static ssize_t speed_show(struct device *dev, struct device_attribute *attr, 1437 char *buf) 1438 { 1439 struct led_classdev *led_cdev = dev_get_drvdata(dev); 1440 struct led_classdev_mc *led_mc = container_of(led_cdev, struct led_classdev_mc, led_cdev); 1441 struct claw_drvdata *drvdata = container_of(led_mc, struct claw_drvdata, led_mc); 1442 u8 speed = 20 - drvdata->rgb_speed; 1443 1444 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1445 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1446 if (!smp_load_acquire(&drvdata->rgb_registered)) 1447 return -ENODEV; 1448 } 1449 1450 return sysfs_emit(buf, "%u\n", speed); 1451 } 1452 static DEVICE_ATTR_RW(speed); 1453 1454 static ssize_t speed_range_show(struct device *dev, 1455 struct device_attribute *attr, char *buf) 1456 { 1457 return sysfs_emit(buf, "0-20\n"); 1458 } 1459 static DEVICE_ATTR_RO(speed_range); 1460 1461 static void claw_led_brightness_set(struct led_classdev *led_cdev, 1462 enum led_brightness _brightness) 1463 { 1464 struct led_classdev_mc *led_mc = container_of(led_cdev, struct led_classdev_mc, led_cdev); 1465 struct claw_drvdata *drvdata = container_of(led_mc, struct claw_drvdata, led_mc); 1466 1467 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1468 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1469 if (!smp_load_acquire(&drvdata->rgb_registered)) 1470 return; 1471 } 1472 1473 mod_delayed_work(system_wq, &drvdata->rgb_queue, msecs_to_jiffies(50)); 1474 } 1475 1476 static struct attribute *claw_rgb_attrs[] = { 1477 &dev_attr_effect.attr, 1478 &dev_attr_effect_index.attr, 1479 &dev_attr_enabled.attr, 1480 &dev_attr_enabled_index.attr, 1481 &dev_attr_speed.attr, 1482 &dev_attr_speed_range.attr, 1483 NULL, 1484 }; 1485 1486 static const struct attribute_group claw_rgb_attr_group = { 1487 .attrs = claw_rgb_attrs, 1488 }; 1489 1490 static struct mc_subled claw_rgb_subled_info[] = { 1491 { 1492 .color_index = LED_COLOR_ID_RED, 1493 .channel = 0x1, 1494 }, 1495 { 1496 .color_index = LED_COLOR_ID_GREEN, 1497 .channel = 0x2, 1498 }, 1499 { 1500 .color_index = LED_COLOR_ID_BLUE, 1501 .channel = 0x3, 1502 }, 1503 }; 1504 1505 static void cfg_setup_fn(struct work_struct *work) 1506 { 1507 struct delayed_work *dwork = container_of(work, struct delayed_work, work); 1508 struct claw_drvdata *drvdata = container_of(dwork, struct claw_drvdata, cfg_setup); 1509 bool gamepad_ready = false, rgb_ready = false, gp_registered, rgb_registered; 1510 int ret; 1511 1512 ret = claw_hw_output_report(drvdata->hdev, CLAW_COMMAND_TYPE_READ_GAMEPAD_MODE, 1513 NULL, 0, 25); 1514 if (ret) { 1515 dev_err(&drvdata->hdev->dev, 1516 "Failed to read gamepad mode: %d\n", ret); 1517 goto prep_rgb; 1518 } 1519 gamepad_ready = true; 1520 1521 prep_rgb: 1522 ret = claw_read_rgb_config(drvdata->hdev); 1523 if (ret) { 1524 dev_err(&drvdata->hdev->dev, 1525 "Failed to read RGB config: %d\n", ret); 1526 goto try_gamepad; 1527 } 1528 rgb_ready = true; 1529 1530 /* Add sysfs attributes after we get the device state */ 1531 try_gamepad: 1532 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) 1533 /* Pairs with smp_store_release from below */ 1534 gp_registered = smp_load_acquire(&drvdata->gp_registered); 1535 1536 if (!gp_registered && gamepad_ready) { 1537 ret = device_add_group(&drvdata->hdev->dev, &claw_gamepad_attr_group); 1538 if (ret) { 1539 dev_err(&drvdata->hdev->dev, 1540 "Failed to create gamepad attrs: %d\n", ret); 1541 goto try_rgb; 1542 } 1543 1544 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1545 /* Pairs with smp_load_acquire in attribute show/store functions */ 1546 smp_store_release(&drvdata->gp_registered, true); 1547 gp_registered = true; 1548 } 1549 } 1550 1551 try_rgb: 1552 /* Add and enable RGB interface once we have the device state */ 1553 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) 1554 /* Pairs with smp_store_release from below */ 1555 rgb_registered = smp_load_acquire(&drvdata->rgb_registered); 1556 1557 if (!rgb_registered && rgb_ready) { 1558 ret = led_classdev_multicolor_register(&drvdata->hdev->dev, 1559 &drvdata->led_mc); 1560 if (ret) { 1561 dev_err(&drvdata->hdev->dev, "Failed to create led device: %d\n", ret); 1562 goto update_kobjects; 1563 } 1564 1565 ret = device_add_group(drvdata->led_mc.led_cdev.dev, &claw_rgb_attr_group); 1566 if (ret) { 1567 dev_err(&drvdata->hdev->dev, "Failed to create RGB attrs: %d\n", ret); 1568 led_classdev_multicolor_unregister(&drvdata->led_mc); 1569 goto update_kobjects; 1570 } 1571 1572 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1573 /* Pairs with smp_load_acquire in attribute show/store functions */ 1574 smp_store_release(&drvdata->rgb_registered, true); 1575 rgb_registered = true; 1576 } 1577 } 1578 1579 update_kobjects: 1580 if (gp_registered) 1581 kobject_uevent(&drvdata->hdev->dev.kobj, KOBJ_CHANGE); 1582 if (rgb_registered) 1583 kobject_uevent(&drvdata->led_mc.led_cdev.dev->kobj, KOBJ_CHANGE); 1584 } 1585 1586 static void cfg_resume_fn(struct work_struct *work) 1587 { 1588 struct delayed_work *dwork = container_of(work, struct delayed_work, work); 1589 struct claw_drvdata *drvdata = container_of(dwork, struct claw_drvdata, cfg_resume); 1590 1591 guard(spinlock_irqsave)(&drvdata->registration_lock); 1592 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1593 if (!smp_load_acquire(&drvdata->gp_registered) || 1594 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1595 !smp_load_acquire(&drvdata->rgb_registered)) 1596 schedule_delayed_work(&drvdata->cfg_setup, msecs_to_jiffies(500)); 1597 } 1598 1599 static void claw_features_supported(struct claw_drvdata *drvdata) 1600 { 1601 u8 major = (drvdata->bcd_device >> 8) & 0xff; 1602 u8 minor = drvdata->bcd_device & 0xff; 1603 1604 if (major == 0x01) { 1605 drvdata->bmap_support = true; 1606 if (minor >= 0x66) { 1607 drvdata->bmap_addr = button_mapping_addr_new; 1608 drvdata->rgb_addr = rgb_addr_new; 1609 } else { 1610 drvdata->bmap_addr = button_mapping_addr_old; 1611 drvdata->rgb_addr = rgb_addr_old; 1612 } 1613 return; 1614 } 1615 1616 if ((major == 0x02 && minor >= 0x17) || major >= 0x03) { 1617 drvdata->bmap_support = true; 1618 drvdata->bmap_addr = button_mapping_addr_new; 1619 drvdata->rgb_addr = rgb_addr_new; 1620 return; 1621 } 1622 1623 drvdata->rgb_addr = rgb_addr_old; 1624 } 1625 1626 static int claw_probe(struct hid_device *hdev, u8 ep) 1627 { 1628 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 1629 struct usb_device *udev = interface_to_usbdev(intf); 1630 struct claw_drvdata *drvdata; 1631 int ret; 1632 1633 drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); 1634 if (!drvdata) 1635 return -ENOMEM; 1636 1637 drvdata->gamepad_mode = CLAW_GAMEPAD_MODE_XINPUT; 1638 drvdata->rgb_enabled = true; 1639 drvdata->hdev = hdev; 1640 drvdata->ep = ep; 1641 1642 /* Determine feature level from firmware version */ 1643 drvdata->bcd_device = le16_to_cpu(udev->descriptor.bcdDevice); 1644 claw_features_supported(drvdata); 1645 1646 if (!drvdata->bmap_support) 1647 dev_dbg(&hdev->dev, "M-Key mapping is not supported. Update firmware to enable.\n"); 1648 1649 /* Device is hardwired and name is guaranteed to be unique */ 1650 drvdata->led_mc.led_cdev.name = "msi_claw:rgb:joystick_rings"; 1651 drvdata->led_mc.led_cdev.brightness = 0x50; 1652 drvdata->led_mc.led_cdev.max_brightness = 0x64; 1653 drvdata->led_mc.led_cdev.color = LED_COLOR_ID_RGB; 1654 drvdata->led_mc.led_cdev.brightness_set = claw_led_brightness_set; 1655 drvdata->led_mc.num_colors = 3; 1656 drvdata->led_mc.subled_info = devm_kmemdup(&hdev->dev, claw_rgb_subled_info, 1657 sizeof(claw_rgb_subled_info), GFP_KERNEL); 1658 if (!drvdata->led_mc.subled_info) 1659 return -ENOMEM; 1660 1661 mutex_init(&drvdata->cfg_mutex); 1662 mutex_init(&drvdata->profile_mutex); 1663 mutex_init(&drvdata->rom_mutex); 1664 spin_lock_init(&drvdata->registration_lock); 1665 spin_lock_init(&drvdata->cmd_lock); 1666 spin_lock_init(&drvdata->mode_lock); 1667 spin_lock_init(&drvdata->profile_lock); 1668 spin_lock_init(&drvdata->frame_lock); 1669 init_completion(&drvdata->orphan_ack_complete); 1670 init_completion(&drvdata->send_cmd_complete); 1671 INIT_DELAYED_WORK(&drvdata->cfg_resume, &cfg_resume_fn); 1672 INIT_DELAYED_WORK(&drvdata->cfg_setup, &cfg_setup_fn); 1673 INIT_DELAYED_WORK(&drvdata->rgb_queue, &claw_rgb_queue_fn); 1674 1675 /* For control interface: open the HID transport for sending commands. */ 1676 ret = hid_hw_open(hdev); 1677 if (ret) 1678 return ret; 1679 1680 hid_set_drvdata(hdev, drvdata); 1681 schedule_delayed_work(&drvdata->cfg_setup, msecs_to_jiffies(500)); 1682 1683 return 0; 1684 } 1685 1686 static int msi_probe(struct hid_device *hdev, const struct hid_device_id *id) 1687 { 1688 int ret; 1689 u8 ep; 1690 1691 if (!hid_is_usb(hdev)) { 1692 ret = -ENODEV; 1693 goto err_probe; 1694 } 1695 1696 ret = hid_parse(hdev); 1697 if (ret) 1698 goto err_probe; 1699 1700 /* Set quirk to create separate input devices per HID application */ 1701 hdev->quirks |= HID_QUIRK_INPUT_PER_APP | HID_QUIRK_MULTI_INPUT; 1702 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 1703 if (ret) 1704 goto err_probe; 1705 1706 /* For non-control interfaces (keyboard/mouse), allow userspace to grab the devices. */ 1707 ret = get_endpoint_address(hdev); 1708 if (ret < 0) 1709 goto err_stop_hw; 1710 1711 ep = ret; 1712 if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN) { 1713 ret = claw_probe(hdev, ep); 1714 if (ret) 1715 goto err_stop_hw; 1716 } 1717 1718 return 0; 1719 1720 err_stop_hw: 1721 hid_hw_stop(hdev); 1722 err_probe: 1723 return dev_err_probe(&hdev->dev, ret, "Failed to init device\n"); 1724 } 1725 1726 static void claw_remove(struct hid_device *hdev) 1727 { 1728 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 1729 bool gp_registered; 1730 bool rgb_registered; 1731 1732 if (!drvdata) 1733 return; 1734 1735 cancel_delayed_work_sync(&drvdata->cfg_resume); 1736 cancel_delayed_work_sync(&drvdata->cfg_setup); 1737 1738 scoped_guard(spinlock_irqsave, &drvdata->registration_lock) { 1739 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1740 gp_registered = smp_load_acquire(&drvdata->gp_registered); 1741 /* Pairs with smp_load_acquire in attribute show/store functions */ 1742 smp_store_release(&drvdata->gp_registered, false); 1743 /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */ 1744 rgb_registered = smp_load_acquire(&drvdata->rgb_registered); 1745 /* Pairs with smp_load_acquire in attribute show/store functions */ 1746 smp_store_release(&drvdata->rgb_registered, false); 1747 } 1748 1749 if (gp_registered) 1750 device_remove_group(&hdev->dev, &claw_gamepad_attr_group); 1751 1752 if (rgb_registered) { 1753 device_remove_group(drvdata->led_mc.led_cdev.dev, &claw_rgb_attr_group); 1754 led_classdev_multicolor_unregister(&drvdata->led_mc); 1755 } 1756 cancel_delayed_work_sync(&drvdata->rgb_queue); 1757 1758 hid_hw_close(hdev); 1759 } 1760 1761 static void msi_remove(struct hid_device *hdev) 1762 { 1763 int ret; 1764 u8 ep; 1765 1766 /* Safe assumption. SET_INTERFACE ioctl can't be used while driver is bound */ 1767 ret = get_endpoint_address(hdev); 1768 if (ret <= 0) 1769 goto hw_stop; 1770 1771 ep = ret; 1772 if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN) 1773 claw_remove(hdev); 1774 1775 hw_stop: 1776 hid_hw_stop(hdev); 1777 } 1778 1779 static int claw_resume(struct hid_device *hdev) 1780 { 1781 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 1782 1783 if (!drvdata) 1784 return -ENODEV; 1785 1786 /* MCU can take up to 500ms to be ready after resume */ 1787 schedule_delayed_work(&drvdata->cfg_resume, msecs_to_jiffies(500)); 1788 return 0; 1789 } 1790 1791 static int msi_resume(struct hid_device *hdev) 1792 { 1793 int ret; 1794 u8 ep; 1795 1796 /* Safe assumption. SET_INTERFACE ioctl can't be used while driver is bound */ 1797 ret = get_endpoint_address(hdev); 1798 if (ret <= 0) 1799 return 0; 1800 1801 ep = ret; 1802 if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN) 1803 return claw_resume(hdev); 1804 1805 return 0; 1806 } 1807 1808 static int claw_suspend(struct hid_device *hdev) 1809 { 1810 struct claw_drvdata *drvdata = hid_get_drvdata(hdev); 1811 1812 if (!drvdata) 1813 return -ENODEV; 1814 1815 cancel_delayed_work_sync(&drvdata->cfg_resume); 1816 cancel_delayed_work_sync(&drvdata->cfg_setup); 1817 cancel_delayed_work_sync(&drvdata->rgb_queue); 1818 1819 return 0; 1820 } 1821 1822 static int msi_suspend(struct hid_device *hdev, pm_message_t msg) 1823 { 1824 int ret; 1825 u8 ep; 1826 1827 /* Safe assumption. SET_INTERFACE ioctl can't be used while driver is bound */ 1828 ret = get_endpoint_address(hdev); 1829 if (ret <= 0) 1830 return 0; 1831 1832 ep = ret; 1833 if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN) 1834 return claw_suspend(hdev); 1835 1836 return 0; 1837 } 1838 1839 static const struct hid_device_id msi_devices[] = { 1840 { HID_USB_DEVICE(USB_VENDOR_ID_MSI_2, USB_DEVICE_ID_MSI_CLAW_XINPUT) }, 1841 { HID_USB_DEVICE(USB_VENDOR_ID_MSI_2, USB_DEVICE_ID_MSI_CLAW_DINPUT) }, 1842 { HID_USB_DEVICE(USB_VENDOR_ID_MSI_2, USB_DEVICE_ID_MSI_CLAW_DESKTOP) }, 1843 { HID_USB_DEVICE(USB_VENDOR_ID_MSI_2, USB_DEVICE_ID_MSI_CLAW_BIOS) }, 1844 { } 1845 }; 1846 MODULE_DEVICE_TABLE(hid, msi_devices); 1847 1848 static struct hid_driver msi_driver = { 1849 .name = "hid-msi", 1850 .id_table = msi_devices, 1851 .raw_event = msi_raw_event, 1852 .probe = msi_probe, 1853 .remove = msi_remove, 1854 .resume = pm_ptr(msi_resume), 1855 .suspend = pm_ptr(msi_suspend), 1856 }; 1857 module_hid_driver(msi_driver); 1858 1859 MODULE_LICENSE("GPL"); 1860 MODULE_AUTHOR("Denis Benato <denis.benato@linux.dev>"); 1861 MODULE_AUTHOR("Zhouwang Huang <honjow311@gmail.com>"); 1862 MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>"); 1863 MODULE_DESCRIPTION("HID driver for MSI Claw Handheld PC gamepads"); 1864