[PATCH] HID: steelseries: Add support for Arctis 7 (2018)

From: Erik Håkansson

Date: Tue Sep 01 2026 - 16:35:50 EST


The headset reports connection and battery status on HID interface
5. When the device is disconnected, ignore incoming battery
reports as they will incorrectly report battery level 0.

Clamp overreported battery values to 100% and add USB ID 1038:12ad
to the driver's device tables.

Signed-off-by: Erik Håkansson <erikhakan@xxxxxxxxx>
---
Information available online suggests that at least two other Arctis 7
revisions (2017 and 2019) exist, with different device IDs. Without
access to those devices, their protocol compatibility cannot be
verified, so this patch only adds support for the 2018 model.

drivers/hid/Kconfig | 3 +-
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-quirks.c | 1 +
drivers/hid/hid-steelseries-arctis.c | 44 ++++++++++++++++++++++++++++
4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index aa7fa11a0197..06f7c35b619f 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -1210,7 +1210,8 @@ config HID_STEELSERIES
depends on USB_HID
help
Support for Steelseries SRW-S1 steering wheel, and the Steelseries
- Arctis 1 Wireless for XBox headset.
+ Arctis 1 Wireless for XBox, Arctis 7 (2018), Arctis 9, and Arctis
+ Nova headsets.

config HID_SUNPLUS
tristate "Sunplus wireless desktop"
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 341bf587863b..1867f480ebc0 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1394,6 +1394,7 @@
#define USB_VENDOR_ID_STEELSERIES 0x1038
#define USB_DEVICE_ID_STEELSERIES_SRWS1 0x1410
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_1_X 0x12b6
+#define USB_DEVICE_ID_STEELSERIES_ARCTIS_7_2018 0x12ad
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_9 0x12c2
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_NOVA_5_X 0x2253
#define USB_DEVICE_ID_STEELSERIES_ARCTIS_NOVA_7 0x2202
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 8a0b51d47040..4862d7356120 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -751,6 +751,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
#if IS_ENABLED(CONFIG_HID_STEELSERIES)
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_1_X) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_7_2018) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_9) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_NOVA_5_X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_NOVA_7) },
diff --git a/drivers/hid/hid-steelseries-arctis.c b/drivers/hid/hid-steelseries-arctis.c
index 23fb0cebd72a..fa33fbd94889 100644
--- a/drivers/hid/hid-steelseries-arctis.c
+++ b/drivers/hid/hid-steelseries-arctis.c
@@ -101,6 +101,19 @@ static int steelseries_arctis_1_request_status(struct hid_device *hdev)
return steelseries_send_output_report(hdev, data, sizeof(data));
}

+static int steelseries_arctis_7_2018_request_status(struct hid_device *hdev)
+{
+ const u8 connection[] = { 0x06, 0x14 };
+ const u8 battery[] = { 0x06, 0x18 };
+ int ret;
+
+ ret = steelseries_send_output_report(hdev, connection, sizeof(connection));
+ if (ret)
+ return ret;
+
+ return steelseries_send_output_report(hdev, battery, sizeof(battery));
+}
+
static int steelseries_arctis_9_request_status(struct hid_device *hdev)
{
const u8 data[] = { 0x00, 0x20 };
@@ -152,6 +165,27 @@ static void steelseries_arctis_1_parse_status(struct steelseries_device *sd,
sd->battery_capacity = data[3];
}

+static void steelseries_arctis_7_2018_parse_status(struct steelseries_device *sd,
+ u8 *data, int size)
+{
+ if (size < 3 || data[0] != 0x06)
+ return;
+
+ switch (data[1]) {
+ case 0x14:
+ /* 0x03 means that the headset is connected to the transmitter. */
+ sd->headset_connected = data[2] == 0x03;
+ break;
+ case 0x18:
+ if (!sd->headset_connected)
+ break;
+
+ /* The Arctis 7 sometimes overreports battery. Cap to 100. */
+ sd->battery_capacity = steelseries_map_capacity(data[2], 0, 100);
+ break;
+ }
+}
+
static void steelseries_arctis_9_parse_status(struct steelseries_device *sd,
u8 *data, int size)
{
@@ -232,6 +266,13 @@ static const struct steelseries_device_info arctis_1_info = {
.parse_status = steelseries_arctis_1_parse_status,
};

+static const struct steelseries_device_info arctis_7_2018_info = {
+ .sync_interface = 5,
+ .capabilities = SS_CAP_BATTERY,
+ .request_status = steelseries_arctis_7_2018_request_status,
+ .parse_status = steelseries_arctis_7_2018_parse_status,
+};
+
static const struct steelseries_device_info arctis_9_info = {
.sync_interface = 0,
.capabilities = SS_CAP_BATTERY,
@@ -653,6 +694,9 @@ static const struct hid_device_id steelseries_arctis_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES,
USB_DEVICE_ID_STEELSERIES_ARCTIS_1_X),
.driver_data = (unsigned long)&arctis_1_info },
+ { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES,
+ USB_DEVICE_ID_STEELSERIES_ARCTIS_7_2018),
+ .driver_data = (unsigned long)&arctis_7_2018_info },
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES,
USB_DEVICE_ID_STEELSERIES_ARCTIS_9),
.driver_data = (unsigned long)&arctis_9_info },

base-commit: 786262be6048deab760f68c8acc2c85607165894
--
2.55.0