1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * HID driver for Steelseries devices 4 * 5 * Copyright (c) 2013 Simon Wood 6 * Copyright (c) 2023 Bastien Nocera 7 */ 8 9 /* 10 */ 11 12 #include <linux/device.h> 13 #include <linux/hid.h> 14 #include <linux/module.h> 15 #include <linux/usb.h> 16 #include <linux/leds.h> 17 18 #include "hid-ids.h" 19 20 #define STEELSERIES_SRWS1 BIT(0) 21 #define STEELSERIES_ARCTIS_1 BIT(1) 22 #define STEELSERIES_ARCTIS_9 BIT(2) 23 24 struct steelseries_device { 25 struct hid_device *hdev; 26 unsigned long quirks; 27 28 struct delayed_work battery_work; 29 spinlock_t lock; 30 bool removed; 31 32 struct power_supply_desc battery_desc; 33 struct power_supply *battery; 34 uint8_t battery_capacity; 35 bool headset_connected; 36 bool battery_charging; 37 }; 38 39 #if IS_BUILTIN(CONFIG_LEDS_CLASS) || \ 40 (IS_MODULE(CONFIG_LEDS_CLASS) && IS_MODULE(CONFIG_HID_STEELSERIES)) 41 #define SRWS1_NUMBER_LEDS 15 42 struct steelseries_srws1_data { 43 __u16 led_state; 44 /* the last element is used for setting all leds simultaneously */ 45 struct led_classdev *led[SRWS1_NUMBER_LEDS + 1]; 46 }; 47 #endif 48 49 /* Fixed report descriptor for Steelseries SRW-S1 wheel controller 50 * 51 * The original descriptor hides the sensitivity and assists dials 52 * a custom vendor usage page. This inserts a patch to make them 53 * appear in the 'Generic Desktop' usage. 54 */ 55 56 static const __u8 steelseries_srws1_rdesc_fixed[] = { 57 0x05, 0x01, /* Usage Page (Desktop) */ 58 0x09, 0x08, /* Usage (MultiAxis), Changed */ 59 0xA1, 0x01, /* Collection (Application), */ 60 0xA1, 0x02, /* Collection (Logical), */ 61 0x95, 0x01, /* Report Count (1), */ 62 0x05, 0x01, /* Changed Usage Page (Desktop), */ 63 0x09, 0x30, /* Changed Usage (X), */ 64 0x16, 0xF8, 0xF8, /* Logical Minimum (-1800), */ 65 0x26, 0x08, 0x07, /* Logical Maximum (1800), */ 66 0x65, 0x14, /* Unit (Degrees), */ 67 0x55, 0x0F, /* Unit Exponent (15), */ 68 0x75, 0x10, /* Report Size (16), */ 69 0x81, 0x02, /* Input (Variable), */ 70 0x09, 0x31, /* Changed Usage (Y), */ 71 0x15, 0x00, /* Logical Minimum (0), */ 72 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 73 0x75, 0x0C, /* Report Size (12), */ 74 0x81, 0x02, /* Input (Variable), */ 75 0x09, 0x32, /* Changed Usage (Z), */ 76 0x15, 0x00, /* Logical Minimum (0), */ 77 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 78 0x75, 0x0C, /* Report Size (12), */ 79 0x81, 0x02, /* Input (Variable), */ 80 0x05, 0x01, /* Usage Page (Desktop), */ 81 0x09, 0x39, /* Usage (Hat Switch), */ 82 0x25, 0x07, /* Logical Maximum (7), */ 83 0x35, 0x00, /* Physical Minimum (0), */ 84 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ 85 0x65, 0x14, /* Unit (Degrees), */ 86 0x75, 0x04, /* Report Size (4), */ 87 0x95, 0x01, /* Report Count (1), */ 88 0x81, 0x02, /* Input (Variable), */ 89 0x25, 0x01, /* Logical Maximum (1), */ 90 0x45, 0x01, /* Physical Maximum (1), */ 91 0x65, 0x00, /* Unit, */ 92 0x75, 0x01, /* Report Size (1), */ 93 0x95, 0x03, /* Report Count (3), */ 94 0x81, 0x01, /* Input (Constant), */ 95 0x05, 0x09, /* Usage Page (Button), */ 96 0x19, 0x01, /* Usage Minimum (01h), */ 97 0x29, 0x11, /* Usage Maximum (11h), */ 98 0x95, 0x11, /* Report Count (17), */ 99 0x81, 0x02, /* Input (Variable), */ 100 /* ---- Dial patch starts here ---- */ 101 0x05, 0x01, /* Usage Page (Desktop), */ 102 0x09, 0x33, /* Usage (RX), */ 103 0x75, 0x04, /* Report Size (4), */ 104 0x95, 0x02, /* Report Count (2), */ 105 0x15, 0x00, /* Logical Minimum (0), */ 106 0x25, 0x0b, /* Logical Maximum (b), */ 107 0x81, 0x02, /* Input (Variable), */ 108 0x09, 0x35, /* Usage (RZ), */ 109 0x75, 0x04, /* Report Size (4), */ 110 0x95, 0x01, /* Report Count (1), */ 111 0x25, 0x03, /* Logical Maximum (3), */ 112 0x81, 0x02, /* Input (Variable), */ 113 /* ---- Dial patch ends here ---- */ 114 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 115 0x09, 0x01, /* Usage (01h), */ 116 0x75, 0x04, /* Changed Report Size (4), */ 117 0x95, 0x0D, /* Changed Report Count (13), */ 118 0x81, 0x02, /* Input (Variable), */ 119 0xC0, /* End Collection, */ 120 0xA1, 0x02, /* Collection (Logical), */ 121 0x09, 0x02, /* Usage (02h), */ 122 0x75, 0x08, /* Report Size (8), */ 123 0x95, 0x10, /* Report Count (16), */ 124 0x91, 0x02, /* Output (Variable), */ 125 0xC0, /* End Collection, */ 126 0xC0 /* End Collection */ 127 }; 128 129 #if IS_BUILTIN(CONFIG_LEDS_CLASS) || \ 130 (IS_MODULE(CONFIG_LEDS_CLASS) && IS_MODULE(CONFIG_HID_STEELSERIES)) 131 static void steelseries_srws1_set_leds(struct hid_device *hdev, __u16 leds) 132 { 133 struct list_head *report_list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 134 struct hid_report *report = list_entry(report_list->next, struct hid_report, list); 135 __s32 *value = report->field[0]->value; 136 137 value[0] = 0x40; 138 value[1] = leds & 0xFF; 139 value[2] = leds >> 8; 140 value[3] = 0x00; 141 value[4] = 0x00; 142 value[5] = 0x00; 143 value[6] = 0x00; 144 value[7] = 0x00; 145 value[8] = 0x00; 146 value[9] = 0x00; 147 value[10] = 0x00; 148 value[11] = 0x00; 149 value[12] = 0x00; 150 value[13] = 0x00; 151 value[14] = 0x00; 152 value[15] = 0x00; 153 154 hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 155 156 /* Note: LED change does not show on device until the device is read/polled */ 157 } 158 159 static void steelseries_srws1_led_all_set_brightness(struct led_classdev *led_cdev, 160 enum led_brightness value) 161 { 162 struct device *dev = led_cdev->dev->parent; 163 struct hid_device *hid = to_hid_device(dev); 164 struct steelseries_srws1_data *drv_data = hid_get_drvdata(hid); 165 166 if (!drv_data) { 167 hid_err(hid, "Device data not found."); 168 return; 169 } 170 171 if (value == LED_OFF) 172 drv_data->led_state = 0; 173 else 174 drv_data->led_state = (1 << (SRWS1_NUMBER_LEDS + 1)) - 1; 175 176 steelseries_srws1_set_leds(hid, drv_data->led_state); 177 } 178 179 static enum led_brightness steelseries_srws1_led_all_get_brightness(struct led_classdev *led_cdev) 180 { 181 struct device *dev = led_cdev->dev->parent; 182 struct hid_device *hid = to_hid_device(dev); 183 struct steelseries_srws1_data *drv_data; 184 185 drv_data = hid_get_drvdata(hid); 186 187 if (!drv_data) { 188 hid_err(hid, "Device data not found."); 189 return LED_OFF; 190 } 191 192 return (drv_data->led_state >> SRWS1_NUMBER_LEDS) ? LED_FULL : LED_OFF; 193 } 194 195 static void steelseries_srws1_led_set_brightness(struct led_classdev *led_cdev, 196 enum led_brightness value) 197 { 198 struct device *dev = led_cdev->dev->parent; 199 struct hid_device *hid = to_hid_device(dev); 200 struct steelseries_srws1_data *drv_data = hid_get_drvdata(hid); 201 int i, state = 0; 202 203 if (!drv_data) { 204 hid_err(hid, "Device data not found."); 205 return; 206 } 207 208 for (i = 0; i < SRWS1_NUMBER_LEDS; i++) { 209 if (led_cdev != drv_data->led[i]) 210 continue; 211 212 state = (drv_data->led_state >> i) & 1; 213 if (value == LED_OFF && state) { 214 drv_data->led_state &= ~(1 << i); 215 steelseries_srws1_set_leds(hid, drv_data->led_state); 216 } else if (value != LED_OFF && !state) { 217 drv_data->led_state |= 1 << i; 218 steelseries_srws1_set_leds(hid, drv_data->led_state); 219 } 220 break; 221 } 222 } 223 224 static enum led_brightness steelseries_srws1_led_get_brightness(struct led_classdev *led_cdev) 225 { 226 struct device *dev = led_cdev->dev->parent; 227 struct hid_device *hid = to_hid_device(dev); 228 struct steelseries_srws1_data *drv_data; 229 int i, value = 0; 230 231 drv_data = hid_get_drvdata(hid); 232 233 if (!drv_data) { 234 hid_err(hid, "Device data not found."); 235 return LED_OFF; 236 } 237 238 for (i = 0; i < SRWS1_NUMBER_LEDS; i++) 239 if (led_cdev == drv_data->led[i]) { 240 value = (drv_data->led_state >> i) & 1; 241 break; 242 } 243 244 return value ? LED_FULL : LED_OFF; 245 } 246 247 static int steelseries_srws1_probe(struct hid_device *hdev, 248 const struct hid_device_id *id) 249 { 250 int ret, i; 251 struct led_classdev *led; 252 size_t name_sz; 253 char *name; 254 255 struct steelseries_srws1_data *drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); 256 257 if (drv_data == NULL) { 258 hid_err(hdev, "can't alloc SRW-S1 memory\n"); 259 return -ENOMEM; 260 } 261 262 hid_set_drvdata(hdev, drv_data); 263 264 ret = hid_parse(hdev); 265 if (ret) { 266 hid_err(hdev, "parse failed\n"); 267 goto err_free; 268 } 269 270 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 16)) { 271 ret = -ENODEV; 272 goto err_free; 273 } 274 275 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 276 if (ret) { 277 hid_err(hdev, "hw start failed\n"); 278 goto err_free; 279 } 280 281 /* register led subsystem */ 282 drv_data->led_state = 0; 283 for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) 284 drv_data->led[i] = NULL; 285 286 steelseries_srws1_set_leds(hdev, 0); 287 288 name_sz = strlen(hdev->uniq) + 16; 289 290 /* 'ALL', for setting all LEDs simultaneously */ 291 led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); 292 if (!led) { 293 hid_err(hdev, "can't allocate memory for LED ALL\n"); 294 goto err_led; 295 } 296 297 name = (void *)(&led[1]); 298 snprintf(name, name_sz, "SRWS1::%s::RPMALL", hdev->uniq); 299 led->name = name; 300 led->brightness = 0; 301 led->max_brightness = 1; 302 led->brightness_get = steelseries_srws1_led_all_get_brightness; 303 led->brightness_set = steelseries_srws1_led_all_set_brightness; 304 305 drv_data->led[SRWS1_NUMBER_LEDS] = led; 306 ret = led_classdev_register(&hdev->dev, led); 307 if (ret) 308 goto err_led; 309 310 /* Each individual LED */ 311 for (i = 0; i < SRWS1_NUMBER_LEDS; i++) { 312 led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); 313 if (!led) { 314 hid_err(hdev, "can't allocate memory for LED %d\n", i); 315 goto err_led; 316 } 317 318 name = (void *)(&led[1]); 319 snprintf(name, name_sz, "SRWS1::%s::RPM%d", hdev->uniq, i+1); 320 led->name = name; 321 led->brightness = 0; 322 led->max_brightness = 1; 323 led->brightness_get = steelseries_srws1_led_get_brightness; 324 led->brightness_set = steelseries_srws1_led_set_brightness; 325 326 drv_data->led[i] = led; 327 ret = led_classdev_register(&hdev->dev, led); 328 329 if (ret) { 330 hid_err(hdev, "failed to register LED %d. Aborting.\n", i); 331 err_led: 332 /* Deregister all LEDs (if any) */ 333 for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) { 334 led = drv_data->led[i]; 335 drv_data->led[i] = NULL; 336 if (!led) 337 continue; 338 led_classdev_unregister(led); 339 kfree(led); 340 } 341 goto out; /* but let the driver continue without LEDs */ 342 } 343 } 344 out: 345 return 0; 346 err_free: 347 kfree(drv_data); 348 return ret; 349 } 350 351 static void steelseries_srws1_remove(struct hid_device *hdev) 352 { 353 int i; 354 struct led_classdev *led; 355 356 struct steelseries_srws1_data *drv_data = hid_get_drvdata(hdev); 357 358 if (drv_data) { 359 /* Deregister LEDs (if any) */ 360 for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) { 361 led = drv_data->led[i]; 362 drv_data->led[i] = NULL; 363 if (!led) 364 continue; 365 led_classdev_unregister(led); 366 kfree(led); 367 } 368 369 } 370 371 hid_hw_stop(hdev); 372 kfree(drv_data); 373 } 374 #endif 375 376 #define STEELSERIES_HEADSET_BATTERY_TIMEOUT_MS 3000 377 378 #define ARCTIS_1_BATTERY_RESPONSE_LEN 8 379 #define ARCTIS_9_BATTERY_RESPONSE_LEN 64 380 static const char arctis_1_battery_request[] = { 0x06, 0x12 }; 381 static const char arctis_9_battery_request[] = { 0x00, 0x20 }; 382 383 static int steelseries_headset_request_battery(struct hid_device *hdev, 384 const char *request, size_t len) 385 { 386 u8 *write_buf; 387 int ret; 388 389 /* Request battery information */ 390 write_buf = kmemdup(request, len, GFP_KERNEL); 391 if (!write_buf) 392 return -ENOMEM; 393 394 hid_dbg(hdev, "Sending battery request report"); 395 ret = hid_hw_raw_request(hdev, request[0], write_buf, len, 396 HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 397 if (ret < (int)len) { 398 hid_err(hdev, "hid_hw_raw_request() failed with %d\n", ret); 399 ret = -ENODATA; 400 } 401 402 kfree(write_buf); 403 return ret; 404 } 405 406 static void steelseries_headset_fetch_battery(struct hid_device *hdev) 407 { 408 struct steelseries_device *sd = hid_get_drvdata(hdev); 409 int ret = 0; 410 411 if (sd->quirks & STEELSERIES_ARCTIS_1) 412 ret = steelseries_headset_request_battery(hdev, 413 arctis_1_battery_request, sizeof(arctis_1_battery_request)); 414 else if (sd->quirks & STEELSERIES_ARCTIS_9) 415 ret = steelseries_headset_request_battery(hdev, 416 arctis_9_battery_request, sizeof(arctis_9_battery_request)); 417 418 if (ret < 0) 419 hid_dbg(hdev, 420 "Battery query failed (err: %d)\n", ret); 421 } 422 423 static int battery_capacity_to_level(int capacity) 424 { 425 if (capacity >= 50) 426 return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 427 if (capacity >= 20) 428 return POWER_SUPPLY_CAPACITY_LEVEL_LOW; 429 return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; 430 } 431 432 static void steelseries_headset_battery_timer_tick(struct work_struct *work) 433 { 434 struct steelseries_device *sd = container_of(work, 435 struct steelseries_device, battery_work.work); 436 struct hid_device *hdev = sd->hdev; 437 438 steelseries_headset_fetch_battery(hdev); 439 } 440 441 #define STEELSERIES_PREFIX "SteelSeries " 442 #define STEELSERIES_PREFIX_LEN strlen(STEELSERIES_PREFIX) 443 444 static int steelseries_headset_battery_get_property(struct power_supply *psy, 445 enum power_supply_property psp, 446 union power_supply_propval *val) 447 { 448 struct steelseries_device *sd = power_supply_get_drvdata(psy); 449 int ret = 0; 450 451 switch (psp) { 452 case POWER_SUPPLY_PROP_MODEL_NAME: 453 val->strval = sd->hdev->name; 454 while (!strncmp(val->strval, STEELSERIES_PREFIX, STEELSERIES_PREFIX_LEN)) 455 val->strval += STEELSERIES_PREFIX_LEN; 456 break; 457 case POWER_SUPPLY_PROP_MANUFACTURER: 458 val->strval = "SteelSeries"; 459 break; 460 case POWER_SUPPLY_PROP_PRESENT: 461 val->intval = 1; 462 break; 463 case POWER_SUPPLY_PROP_STATUS: 464 if (sd->headset_connected) { 465 val->intval = sd->battery_charging ? 466 POWER_SUPPLY_STATUS_CHARGING : 467 POWER_SUPPLY_STATUS_DISCHARGING; 468 } else 469 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 470 break; 471 case POWER_SUPPLY_PROP_SCOPE: 472 val->intval = POWER_SUPPLY_SCOPE_DEVICE; 473 break; 474 case POWER_SUPPLY_PROP_CAPACITY: 475 val->intval = sd->battery_capacity; 476 break; 477 case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 478 val->intval = battery_capacity_to_level(sd->battery_capacity); 479 break; 480 default: 481 ret = -EINVAL; 482 break; 483 } 484 return ret; 485 } 486 487 static void 488 steelseries_headset_set_wireless_status(struct hid_device *hdev, 489 bool connected) 490 { 491 struct usb_interface *intf; 492 493 if (!hid_is_usb(hdev)) 494 return; 495 496 intf = to_usb_interface(hdev->dev.parent); 497 usb_set_wireless_status(intf, connected ? 498 USB_WIRELESS_STATUS_CONNECTED : 499 USB_WIRELESS_STATUS_DISCONNECTED); 500 } 501 502 static enum power_supply_property steelseries_headset_battery_props[] = { 503 POWER_SUPPLY_PROP_MODEL_NAME, 504 POWER_SUPPLY_PROP_MANUFACTURER, 505 POWER_SUPPLY_PROP_PRESENT, 506 POWER_SUPPLY_PROP_STATUS, 507 POWER_SUPPLY_PROP_SCOPE, 508 POWER_SUPPLY_PROP_CAPACITY, 509 POWER_SUPPLY_PROP_CAPACITY_LEVEL, 510 }; 511 512 static int steelseries_headset_battery_register(struct steelseries_device *sd) 513 { 514 static atomic_t battery_no = ATOMIC_INIT(0); 515 struct power_supply_config battery_cfg = { .drv_data = sd, }; 516 unsigned long n; 517 int ret; 518 519 sd->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; 520 sd->battery_desc.properties = steelseries_headset_battery_props; 521 sd->battery_desc.num_properties = ARRAY_SIZE(steelseries_headset_battery_props); 522 sd->battery_desc.get_property = steelseries_headset_battery_get_property; 523 sd->battery_desc.use_for_apm = 0; 524 n = atomic_inc_return(&battery_no) - 1; 525 sd->battery_desc.name = devm_kasprintf(&sd->hdev->dev, GFP_KERNEL, 526 "steelseries_headset_battery_%ld", n); 527 if (!sd->battery_desc.name) 528 return -ENOMEM; 529 530 /* avoid the warning of 0% battery while waiting for the first info */ 531 steelseries_headset_set_wireless_status(sd->hdev, false); 532 sd->battery_capacity = 100; 533 sd->battery_charging = false; 534 535 sd->battery = devm_power_supply_register(&sd->hdev->dev, 536 &sd->battery_desc, &battery_cfg); 537 if (IS_ERR(sd->battery)) { 538 ret = PTR_ERR(sd->battery); 539 hid_err(sd->hdev, 540 "%s:power_supply_register failed with error %d\n", 541 __func__, ret); 542 return ret; 543 } 544 power_supply_powers(sd->battery, &sd->hdev->dev); 545 546 INIT_DELAYED_WORK(&sd->battery_work, steelseries_headset_battery_timer_tick); 547 steelseries_headset_fetch_battery(sd->hdev); 548 549 if (sd->quirks & STEELSERIES_ARCTIS_9) { 550 /* The first fetch_battery request can remain unanswered in some cases */ 551 schedule_delayed_work(&sd->battery_work, 552 msecs_to_jiffies(STEELSERIES_HEADSET_BATTERY_TIMEOUT_MS)); 553 } 554 555 return 0; 556 } 557 558 static bool steelseries_is_vendor_usage_page(struct hid_device *hdev, uint8_t usage_page) 559 { 560 return hdev->rdesc[0] == 0x06 && 561 hdev->rdesc[1] == usage_page && 562 hdev->rdesc[2] == 0xff; 563 } 564 565 static int steelseries_probe(struct hid_device *hdev, const struct hid_device_id *id) 566 { 567 struct steelseries_device *sd; 568 int ret; 569 570 sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL); 571 if (!sd) 572 return -ENOMEM; 573 hid_set_drvdata(hdev, sd); 574 sd->hdev = hdev; 575 sd->quirks = id->driver_data; 576 577 if (sd->quirks & STEELSERIES_SRWS1) { 578 #if IS_BUILTIN(CONFIG_LEDS_CLASS) || \ 579 (IS_MODULE(CONFIG_LEDS_CLASS) && IS_MODULE(CONFIG_HID_STEELSERIES)) 580 return steelseries_srws1_probe(hdev, id); 581 #else 582 return -ENODEV; 583 #endif 584 } 585 586 ret = hid_parse(hdev); 587 if (ret) 588 return ret; 589 590 if (sd->quirks & STEELSERIES_ARCTIS_9 && 591 !steelseries_is_vendor_usage_page(hdev, 0xc0)) 592 return -ENODEV; 593 594 spin_lock_init(&sd->lock); 595 596 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 597 if (ret) 598 return ret; 599 600 ret = hid_hw_open(hdev); 601 if (ret) 602 return ret; 603 604 if (steelseries_headset_battery_register(sd) < 0) 605 hid_err(sd->hdev, 606 "Failed to register battery for headset\n"); 607 608 return ret; 609 } 610 611 static void steelseries_remove(struct hid_device *hdev) 612 { 613 struct steelseries_device *sd = hid_get_drvdata(hdev); 614 unsigned long flags; 615 616 if (sd->quirks & STEELSERIES_SRWS1) { 617 #if IS_BUILTIN(CONFIG_LEDS_CLASS) || \ 618 (IS_MODULE(CONFIG_LEDS_CLASS) && IS_MODULE(CONFIG_HID_STEELSERIES)) 619 steelseries_srws1_remove(hdev); 620 #endif 621 return; 622 } 623 624 spin_lock_irqsave(&sd->lock, flags); 625 sd->removed = true; 626 spin_unlock_irqrestore(&sd->lock, flags); 627 628 cancel_delayed_work_sync(&sd->battery_work); 629 630 hid_hw_close(hdev); 631 hid_hw_stop(hdev); 632 } 633 634 static const __u8 *steelseries_srws1_report_fixup(struct hid_device *hdev, 635 __u8 *rdesc, unsigned int *rsize) 636 { 637 if (hdev->vendor != USB_VENDOR_ID_STEELSERIES || 638 hdev->product != USB_DEVICE_ID_STEELSERIES_SRWS1) 639 return rdesc; 640 641 if (*rsize >= 115 && rdesc[11] == 0x02 && rdesc[13] == 0xc8 642 && rdesc[29] == 0xbb && rdesc[40] == 0xc5) { 643 hid_info(hdev, "Fixing up Steelseries SRW-S1 report descriptor\n"); 644 *rsize = sizeof(steelseries_srws1_rdesc_fixed); 645 return steelseries_srws1_rdesc_fixed; 646 } 647 return rdesc; 648 } 649 650 static uint8_t steelseries_headset_map_capacity(uint8_t capacity, uint8_t min_in, uint8_t max_in) 651 { 652 if (capacity >= max_in) 653 return 100; 654 if (capacity <= min_in) 655 return 0; 656 return (capacity - min_in) * 100 / (max_in - min_in); 657 } 658 659 static int steelseries_headset_raw_event(struct hid_device *hdev, 660 struct hid_report *report, u8 *read_buf, 661 int size) 662 { 663 struct steelseries_device *sd = hid_get_drvdata(hdev); 664 int capacity = sd->battery_capacity; 665 bool connected = sd->headset_connected; 666 bool charging = sd->battery_charging; 667 unsigned long flags; 668 669 /* Not a headset */ 670 if (sd->quirks & STEELSERIES_SRWS1) 671 return 0; 672 673 if (sd->quirks & STEELSERIES_ARCTIS_1) { 674 hid_dbg(sd->hdev, 675 "Parsing raw event for Arctis 1 headset (%*ph)\n", size, read_buf); 676 if (size < ARCTIS_1_BATTERY_RESPONSE_LEN || 677 memcmp(read_buf, arctis_1_battery_request, sizeof(arctis_1_battery_request))) { 678 if (!delayed_work_pending(&sd->battery_work)) 679 goto request_battery; 680 return 0; 681 } 682 if (read_buf[2] == 0x01) { 683 connected = false; 684 capacity = 100; 685 } else { 686 connected = true; 687 capacity = read_buf[3]; 688 } 689 } 690 691 if (sd->quirks & STEELSERIES_ARCTIS_9) { 692 hid_dbg(sd->hdev, 693 "Parsing raw event for Arctis 9 headset (%*ph)\n", size, read_buf); 694 if (size < ARCTIS_9_BATTERY_RESPONSE_LEN) { 695 if (!delayed_work_pending(&sd->battery_work)) 696 goto request_battery; 697 return 0; 698 } 699 700 if (read_buf[0] == 0xaa && read_buf[1] == 0x01) { 701 connected = true; 702 charging = read_buf[4] == 0x01; 703 704 /* 705 * Found no official documentation about min and max. 706 * Values defined by testing. 707 */ 708 capacity = steelseries_headset_map_capacity(read_buf[3], 0x68, 0x9d); 709 } else { 710 /* 711 * Device is off and sends the last known status read_buf[1] == 0x03 or 712 * there is no known status of the device read_buf[0] == 0x55 713 */ 714 connected = false; 715 charging = false; 716 } 717 } 718 719 if (connected != sd->headset_connected) { 720 hid_dbg(sd->hdev, 721 "Connected status changed from %sconnected to %sconnected\n", 722 sd->headset_connected ? "" : "not ", 723 connected ? "" : "not "); 724 sd->headset_connected = connected; 725 steelseries_headset_set_wireless_status(hdev, connected); 726 } 727 728 if (capacity != sd->battery_capacity) { 729 hid_dbg(sd->hdev, 730 "Battery capacity changed from %d%% to %d%%\n", 731 sd->battery_capacity, capacity); 732 sd->battery_capacity = capacity; 733 power_supply_changed(sd->battery); 734 } 735 736 if (charging != sd->battery_charging) { 737 hid_dbg(sd->hdev, 738 "Battery charging status changed from %scharging to %scharging\n", 739 sd->battery_charging ? "" : "not ", 740 charging ? "" : "not "); 741 sd->battery_charging = charging; 742 power_supply_changed(sd->battery); 743 } 744 745 request_battery: 746 spin_lock_irqsave(&sd->lock, flags); 747 if (!sd->removed) 748 schedule_delayed_work(&sd->battery_work, 749 msecs_to_jiffies(STEELSERIES_HEADSET_BATTERY_TIMEOUT_MS)); 750 spin_unlock_irqrestore(&sd->lock, flags); 751 752 return 0; 753 } 754 755 static const struct hid_device_id steelseries_devices[] = { 756 { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1), 757 .driver_data = STEELSERIES_SRWS1 }, 758 759 { /* SteelSeries Arctis 1 Wireless for XBox */ 760 HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, 0x12b6), 761 .driver_data = STEELSERIES_ARCTIS_1 }, 762 763 { /* SteelSeries Arctis 9 Wireless for XBox */ 764 HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, 0x12c2), 765 .driver_data = STEELSERIES_ARCTIS_9 }, 766 767 { } 768 }; 769 MODULE_DEVICE_TABLE(hid, steelseries_devices); 770 771 static struct hid_driver steelseries_driver = { 772 .name = "steelseries", 773 .id_table = steelseries_devices, 774 .probe = steelseries_probe, 775 .remove = steelseries_remove, 776 .report_fixup = steelseries_srws1_report_fixup, 777 .raw_event = steelseries_headset_raw_event, 778 }; 779 780 module_hid_driver(steelseries_driver); 781 MODULE_DESCRIPTION("HID driver for Steelseries devices"); 782 MODULE_LICENSE("GPL"); 783 MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>"); 784 MODULE_AUTHOR("Simon Wood <simon@mungewell.org>"); 785 MODULE_AUTHOR("Christian Mayer <git@mayer-bgk.de>"); 786