* [PATCH] HID: hid-lenovo-go-s: restore OS_TYPE after resume from s2idle
@ 2026-04-20 18:15 Matthew Schwartz
0 siblings, 0 replies; only message in thread
From: Matthew Schwartz @ 2026-04-20 18:15 UTC (permalink / raw)
To: derekjohn.clark, jikos, bentiss
Cc: mpearson-lenovo, linux-input, linux-kernel, Matthew Schwartz
The controller MCU does not persist OS_TYPE across power cycles. During
s2idle resume, the USB device may be power-cycled, causing the OS_TYPE
setting to revert to the default Windows value.
Add a reset_resume callback so that this is correctly restored after
resume.
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
---
drivers/hid/hid-lenovo-go-s.c | 44 +++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/hid/hid-lenovo-go-s.c b/drivers/hid/hid-lenovo-go-s.c
index 01c7bdd4fbe0..ff1782a75191 100644
--- a/drivers/hid/hid-lenovo-go-s.c
+++ b/drivers/hid/hid-lenovo-go-s.c
@@ -1369,6 +1369,14 @@ static void cfg_setup(struct work_struct *work)
"Failed to retrieve IMU Manufacturer: %i\n", ret);
return;
}
+
+ ret = mcu_property_out(drvdata.hdev, GET_GAMEPAD_CFG, FEATURE_OS_MODE,
+ NULL, 0);
+ if (ret) {
+ dev_err(&drvdata.hdev->dev,
+ "Failed to retrieve OS Mode: %i\n", ret);
+ return;
+ }
}
static int hid_gos_cfg_probe(struct hid_device *hdev,
@@ -1427,6 +1435,27 @@ static void hid_gos_cfg_remove(struct hid_device *hdev)
hid_set_drvdata(hdev, NULL);
}
+static int hid_gos_cfg_reset_resume(struct hid_device *hdev)
+{
+ u8 os_mode = drvdata.os_mode;
+ int ret;
+
+ ret = mcu_property_out(drvdata.hdev, SET_GAMEPAD_CFG,
+ FEATURE_OS_MODE, &os_mode, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mcu_property_out(drvdata.hdev, GET_GAMEPAD_CFG,
+ FEATURE_OS_MODE, NULL, 0);
+ if (ret < 0)
+ return ret;
+
+ if (drvdata.os_mode != os_mode)
+ return -ENODEV;
+
+ return 0;
+}
+
static int hid_gos_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
@@ -1481,6 +1510,20 @@ static void hid_gos_remove(struct hid_device *hdev)
}
}
+static int hid_gos_reset_resume(struct hid_device *hdev)
+{
+ int ep = get_endpoint_address(hdev);
+
+ switch (ep) {
+ case GO_S_CFG_INTF_IN:
+ return hid_gos_cfg_reset_resume(hdev);
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static const struct hid_device_id hid_gos_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_QHE,
USB_DEVICE_ID_LENOVO_LEGION_GO_S_XINPUT) },
@@ -1496,6 +1539,7 @@ static struct hid_driver hid_lenovo_go_s = {
.probe = hid_gos_probe,
.remove = hid_gos_remove,
.raw_event = hid_gos_raw_event,
+ .reset_resume = hid_gos_reset_resume,
};
module_hid_driver(hid_lenovo_go_s);
--
2.53.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-04-20 18:15 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-20 18:15 [PATCH] HID: hid-lenovo-go-s: restore OS_TYPE after resume from s2idle Matthew Schwartz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox