From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt1-f173.google.com (mail-qt1-f173.google.com [209.85.160.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F1063C196A for ; Fri, 27 Feb 2026 23:50:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.173 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772236257; cv=none; b=DVOTN+dUxgfel/89boT8W197KMXdg6UbqsZq1DDFY92gU8b5mSJtxGbBoomW58WM4+UO5sOkCsFHiU3d7REv9PWUvyPucNYpurF+TaFazWAaLJNoOcDOQ6qpQj01O9LgxYpsdeQjaJR09DVSMKsKeA//ZlpCfntRviFk1YlF854= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772236257; c=relaxed/simple; bh=A15BqvscuB/5RlxbCSq+CxiKXhvoqtQlKONYCcIV1X8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qZDEsvSRdcieFNhVlmOZelU2uEpEO5yA0dgNW65TUbq7VphWEHR4CBRbGNnOiS/MELYNONWNZQmH/6DstYS841QJNATwXj0Bk1cURXT2KN3CKvQ7PMprK1GUZlk0zj0j/Mszmr4Kl4LbxUr7VfyyUmQn1ju7QIbHlJHbbTUJLb4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=YPW5TmSK; arc=none smtp.client-ip=209.85.160.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YPW5TmSK" Received: by mail-qt1-f173.google.com with SMTP id d75a77b69052e-506bcb23a78so23336411cf.3 for ; Fri, 27 Feb 2026 15:50:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772236254; x=1772841054; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RRZhtJE4k765hzYv6/aXtPlhnTj2a1sOWdrMMQeHH0s=; b=YPW5TmSKg5iO14lpLa8bW3Ct4axoRWnH8WWePHeAaLhA1FI3GpP3pT8Mm4Q3q22r/u 90K+DSnkbSjEobK0vD7GdMzEETe7Klikzeo6IPUisJkSrsDzkJjo+DgB6ZswpfJMrzro 2n/3m9n+0xzIzNDBNBllHqnaGBkifZdIvZn4y+6Imt8hELHnBiSXIarQbNmyyCMdEMa+ tcVPKa0PlcIJ2QgSe5EGP8giJu4A9AaPA3Ypi9aIkggG0W1zxrmUDUfONGp8Vc6H+itk uIdF7k+iHY1YkTRq0NeRF/T90aNAUj0m0M1gyylRAIOiJxKfcRCYRkhTRyngpa8YZlTn Ry8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772236254; x=1772841054; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=RRZhtJE4k765hzYv6/aXtPlhnTj2a1sOWdrMMQeHH0s=; b=t0qUZOfq8B3yO8CREbomX/pYCD97BFNTdClegL+OcyoTQi0nfuiG0pVLRcgLa55PiT tYGXiMQ138gDR1hJxMG+6RQUe+s4hORsfQdVGU8Ml3JgawkAmfsqRRLYm3lNE454szyG q0E98kQZM4B1bw/dnMqf7+iZUONLoKmZJ5HTIpjpPsqlP6pioRRtaXnZUQF7CXi2T5Jt Vm0oLcp8H21eVyCTurPL97tVXu2tGWr9XDU6Ce3Cc/rr0TTm6qzfFr7NibZqFFxfMMa6 fpry9mSm8g0rfNTgO/o0/rcemL6WrFNndzt8Z4Lt+Cr3n6kFI/WyHEuXma0FX8herS9L SmTQ== X-Forwarded-Encrypted: i=1; AJvYcCW0NUH6cSBOV+mfXhmqBMGGM4qRy36gk3NnNQMnQcl1Yhm2Esp+gMDCwo4yak7vAi5FmCP+52YYF96dlDE=@vger.kernel.org X-Gm-Message-State: AOJu0Yzz1pIJUX3/jfcPPky74rh9VDaBalCXRXraSIyoTD3g8b77zVz5 FBRJJEPYC7AfIqh2vqp0xyxGO8OHraG1lunKhKvbOOIJAfuqKvfMH0ML X-Gm-Gg: ATEYQzzlMWD2N7piWzXEWqZIhPXWyBTnBHltmzXT2QsR/6PwaH+1KG2LTStwUeX1Xnq Gv8NQNNvy2RE8NUbEKW4GrlcFEd15zqkl/PKQMsPDs+M7kfZyqCFoYehvLreqSyDjHyZzX+toqZ JTbxuE9BCdAN1/5m7wCYQ96qekzUbceMoI7Haoq9q6kkW8RwSP6JvIxDNL/r/MKLiQdc1GMz+n4 5AzZwZpArnk+O+gQVNMzFHbxaGVQrzz2H72mGwJ9edcSyVexnzvzge67ZJtD0yhlqH1gpmVF3pR YHDuS85cDXnjLMEkRpjr+3Ww7Y6PwmK4pblQyrxYa3xqMdaKAq2Nct7UixyaY10jSJnBa7lNOo4 m0fYq27Za/RV4N9N1ZECBu0YWh0g/m+IMvmIzQPzgQLz5Hk82MT80mR7krk1fVnjoYg/+IfHcGO SjDYSbhqwgbLkwTZrh4sm91BaJFQXExSM+j6oJXSoHNUzbvnSEdQ== X-Received: by 2002:ac8:5f4e:0:b0:501:3e36:1513 with SMTP id d75a77b69052e-507526b9e5amr67620731cf.6.1772236254291; Fri, 27 Feb 2026 15:50:54 -0800 (PST) Received: from achantapc.tail227c81.ts.net ([128.172.224.28]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-899c715a87esm52397446d6.4.2026.02.27.15.50.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Feb 2026 15:50:53 -0800 (PST) From: Sriman Achanta To: Jiri Kosina , Benjamin Tissoires Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Bastien Nocera , Simon Wood , Christian Mayer , Sriman Achanta Subject: [PATCH v3 10/18] HID: steelseries: Add settings poll infrastructure Date: Fri, 27 Feb 2026 18:50:34 -0500 Message-ID: <20260227235042.410062-11-srimanachanta@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260227235042.410062-1-srimanachanta@gmail.com> References: <20260227235042.410062-1-srimanachanta@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Some headset settings (sidetone level, mic volume, etc.) are not reported spontaneously but must be explicitly requested from the device. Introduce a separate delayed work item (settings_work) for fetching these persistent settings, independent of the existing status work. Settings are requested once at probe time and again whenever the headset reconnects after being disconnected. Device info structs gain request_settings and parse_settings hooks for model-specific implementations. The SS_CAP_EXTERNAL_CONFIG capability flag marks devices whose writable controls can also be changed from the headset hardware directly; writable ALSA controls on such devices will be marked volatile. The initial implementation adds the Arctis Nova 7 Gen2 audio settings request (0x00, 0x20). Signed-off-by: Sriman Achanta --- drivers/hid/hid-steelseries.c | 37 ++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c index 8c6116d02f19..f2423c350154 100644 --- a/drivers/hid/hid-steelseries.c +++ b/drivers/hid/hid-steelseries.c @@ -26,6 +26,7 @@ #define SS_CAP_MIC_MUTE BIT(2) #define SS_CAP_BT_ENABLED BIT(3) #define SS_CAP_BT_DEVICE_CONNECTED BIT(4) +#define SS_CAP_EXTERNAL_CONFIG BIT(5) #define SS_QUIRK_STATUS_SYNC_POLL BIT(0) @@ -40,6 +41,9 @@ struct steelseries_device_info { int (*request_status)(struct hid_device *hdev); void (*parse_status)(struct steelseries_device *sd, u8 *data, int size); + + int (*request_settings)(struct hid_device *hdev); + void (*parse_settings)(struct steelseries_device *sd, u8 *data, int size); }; struct steelseries_device { @@ -49,6 +53,7 @@ struct steelseries_device { bool use_async_protocol; struct delayed_work status_work; + struct delayed_work settings_work; struct power_supply_desc battery_desc; struct power_supply *battery; @@ -690,6 +695,14 @@ static void steelseries_arctis_nova_7_gen2_parse_status(struct steelseries_devic } } +static int steelseries_arctis_nova_7_gen2_request_settings(struct hid_device *hdev) +{ + const u8 data[] = { 0x00, 0x20 }; + + return steelseries_send_output_report(hdev, data, sizeof(data)); +} + + static void steelseries_arctis_nova_pro_parse_status(struct steelseries_device *sd, u8 *data, int size) { @@ -791,9 +804,11 @@ static const struct steelseries_device_info arctis_nova_7_gen2_info = { .sync_interface = 3, .async_interface = 5, .capabilities = SS_CAP_BATTERY | SS_CAP_CHATMIX | SS_CAP_MIC_MUTE | - SS_CAP_BT_ENABLED | SS_CAP_BT_DEVICE_CONNECTED, + SS_CAP_BT_ENABLED | SS_CAP_BT_DEVICE_CONNECTED | + SS_CAP_EXTERNAL_CONFIG, .request_status = steelseries_arctis_nova_request_status, .parse_status = steelseries_arctis_nova_7_gen2_parse_status, + .request_settings = steelseries_arctis_nova_7_gen2_request_settings, }; static const struct steelseries_device_info arctis_nova_pro_info = { @@ -901,6 +916,15 @@ static void steelseries_status_timer_work_handler(struct work_struct *work) spin_unlock_irqrestore(&sd->lock, flags); } +static void steelseries_settings_work_handler(struct work_struct *work) +{ + struct steelseries_device *sd = container_of( + work, struct steelseries_device, settings_work.work); + + if (sd->info->request_settings) + sd->info->request_settings(sd->hdev); +} + static int steelseries_battery_register(struct steelseries_device *sd) { static atomic_t battery_no = ATOMIC_INIT(0); @@ -1185,6 +1209,9 @@ static int steelseries_raw_event(struct hid_device *hdev, sd->info->parse_status(sd, data, size); + if (sd->info->parse_settings) + sd->info->parse_settings(sd, data, size); + if (sd->headset_connected != old_connected) { hid_dbg(hdev, "Connected status changed from %sconnected to %sconnected\n", @@ -1194,6 +1221,9 @@ static int steelseries_raw_event(struct hid_device *hdev, if (sd->headset_connected && !old_connected && sd->use_async_protocol && is_async_interface) { schedule_delayed_work(&sd->status_work, 0); + if (sd->info->request_settings) + schedule_delayed_work(&sd->settings_work, + msecs_to_jiffies(10)); } if (sd->battery) { @@ -1329,7 +1359,11 @@ static int steelseries_probe(struct hid_device *hdev, #endif INIT_DELAYED_WORK(&sd->status_work, steelseries_status_timer_work_handler); + INIT_DELAYED_WORK(&sd->settings_work, steelseries_settings_work_handler); + schedule_delayed_work(&sd->status_work, msecs_to_jiffies(100)); + if (info->request_settings) + schedule_delayed_work(&sd->settings_work, msecs_to_jiffies(200)); return 0; } @@ -1415,6 +1449,7 @@ static void steelseries_remove(struct hid_device *hdev) spin_unlock_irqrestore(&sd->lock, flags); cancel_delayed_work_sync(&sd->status_work); + cancel_delayed_work_sync(&sd->settings_work); } hid_hw_close(hdev); -- 2.53.0