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