* [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration
@ 2026-09-01 6:36 Aditya Dash
2026-09-01 6:36 ` [PATCH v3 1/7] HID: hid-lenovo-go: use the correct calibration commands Aditya Dash
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Aditya Dash @ 2026-09-01 6:36 UTC (permalink / raw)
To: Benjamin Tissoires, Derek J. Clark, Jiri Kosina, Mark Pearson
Cc: linux-input, linux-kernel
This series fixes several issues in the controller configuration and
calibration paths in hid-lenovo-go.
1/7 fixes the calibration attributes, where the command and sub-command
are swapped. 2/7 fixes two right-controller attributes: imu_enabled
selects the bypass feature, and reset targets the left controller.
The configuration interface initializes its command completion after the
HID hardware starts and opens. 3/7 moves that initialization before both
hardware operations.
Before 4/7, any decoded configuration reply completes the shared
completion. The driver then ignores the result of the wait, so an
unrelated reply, a firmware error, an interrupted wait, or a timeout can
still be reported as success.
4/7 tracks one pending request in the driver data and matches replies by
command ID, command, sub-command, and device. It initializes the new
completion and spinlock at the pre-hardware point established by 3/7. It
also returns request errors to the caller.
The firmware has no sequence number, so a late reply with the same tuple
can still match a newer request.
The remaining patches fix calibration status handling.
The calibration status table defines 0x00 as unknown, 0x01 as success,
and 0x02 as failure. A Legion Go 1 returned 0x08 after a Stop was sent
while no calibration was active. The driver stores the raw value as a
status-text index, so a later read returns -EINVAL.
5/7 preserves the defined values and maps larger status values to
failure.
6/7 rejects 'unknown' as an action. The action table contains it at index
zero, but the options attribute advertises only 'start' and 'stop'.
A previous result can also hide a new calibration attempt:
failure -> start -> failure
The status appears unchanged for the whole operation. 7/7 clears the
selected status to unknown before submitting a Start. Stop leaves the
status unchanged.
I built every patch against kernel 7.2.1-ogc3.1.fc44.x86_64 with
W=1 and KCFLAGS=-Werror. I tested the exact final module on an Original
Legion Go. The configuration interface bound without a kernel fault.
An idle Stop result of 0x08 was reported as failure. Writing 'unknown'
returned -EINVAL without an output report or status change. A later Start
produced failure -> unknown -> failure; the final report contained result
0x02 and error 0x0007. The five unselected statuses stayed unchanged.
---
Changes in v3:
- Initialize command completion state before hid_hw_start() and
hid_hw_open().
- Remove the unreachable zero-length calibration action path after
rejecting 'unknown'.
v2 review:
https://lore.kernel.org/all/CAFqHKTnQiTQc6joz-Y6tmjR=C5giF-MuHeBwu3rw+bmFVMQtqw@mail.gmail.com/
v2:
https://lore.kernel.org/all/cover.1788096666.git.mradityadash@gmail.com/
Changes in v2:
- Drop the FPS DPI patch; the existing request is correct.
- Drop the v1 Boolean calibration-result mapping. Preserve values 0x00
through 0x02 and map only larger failure values.
- Move the existing pending command state into the driver data and
initialize it in cfg_probe().
- Use scoped IRQ-save guards and validate the report size and ID together.
- Drop the v1 no-wait calibration path. Correct requests receive their
matching SET replies within the existing 50 ms timeout.
- Reject 'unknown' and clear only the selected status on Start.
v1:
https://lore.kernel.org/all/20260821214810.87826-1-mradityadash@gmail.com/
Aditya Dash (7):
HID: hid-lenovo-go: use the correct calibration commands
HID: hid-lenovo-go: use the right controller selectors
HID: hid-lenovo-go: initialize command completion before hardware
HID: hid-lenovo-go: return configuration request errors
HID: hid-lenovo-go: normalize calibration failure status
HID: hid-lenovo-go: reject unknown calibration action
HID: hid-lenovo-go: clear calibration status on start
drivers/hid/hid-lenovo-go.c | 191 +++++++++++++++++++++++++++---------
1 file changed, 142 insertions(+), 49 deletions(-)
base-commit: 1292bca0f8d835d2ad96d309595b2e97f3106d3d
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 1/7] HID: hid-lenovo-go: use the correct calibration commands
2026-09-01 6:36 [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration Aditya Dash
@ 2026-09-01 6:36 ` Aditya Dash
2026-09-01 6:36 ` [PATCH v3 2/7] HID: hid-lenovo-go: use the right controller selectors Aditya Dash
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Aditya Dash @ 2026-09-01 6:36 UTC (permalink / raw)
To: Benjamin Tissoires, Derek J. Clark, Jiri Kosina, Mark Pearson
Cc: linux-input, linux-kernel
The calibration attributes pass the calibration operation as the command
and the configuration command as the sub-command. This sends each request
with the two fields reversed.
Swap the command and sub-command values for all six calibration attributes.
For example, the malformed left joystick Start request is:
05 00 04 0c 03 01 ...
The corrected request is:
05 00 0c 04 03 01 ...
The bytes identify the output report, configuration group, command,
sub-command, left controller, and Start action, in that order.
Fixes: 995887a10da1 ("HID: hid-lenovo-go: Add Calibration Settings")
Assisted-by: Pi:gpt-5.6-sol
Signed-off-by: Aditya Dash <mradityadash@gmail.com>
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Tested-by: Derek J. Clark <derekjohn.clark@gmail.com>
---
drivers/hid/hid-lenovo-go.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
index 318b1152ff8b..b8248bf8965c 100644
--- a/drivers/hid/hid-lenovo-go.c
+++ b/drivers/hid/hid-lenovo-go.c
@@ -1911,18 +1911,18 @@ LEGO_DEVICE_ATTR_RW(rumble_notification_left, "rumble_notification",
static DEVICE_ATTR_RO_NAMED(rumble_notification_left_index,
"rumble_notification_index");
-static struct go_cfg_attr cal_trigg_left = { TRIGGER_CALIBRATE };
-LEGO_CAL_DEVICE_ATTR(cal_trigg_left, "calibrate_trigger", SET_TRIGGER_CFG,
+static struct go_cfg_attr cal_trigg_left = { SET_TRIGGER_CFG };
+LEGO_CAL_DEVICE_ATTR(cal_trigg_left, "calibrate_trigger", TRIGGER_CALIBRATE,
LEFT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_trigg_left_index, "calibrate_trigger_index");
-static struct go_cfg_attr cal_joy_left = { JOYSTICK_CALIBRATE };
-LEGO_CAL_DEVICE_ATTR(cal_joy_left, "calibrate_joystick", SET_JOYSTICK_CFG,
+static struct go_cfg_attr cal_joy_left = { SET_JOYSTICK_CFG };
+LEGO_CAL_DEVICE_ATTR(cal_joy_left, "calibrate_joystick", JOYSTICK_CALIBRATE,
LEFT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_joy_left_index, "calibrate_joystick_index");
-static struct go_cfg_attr cal_gyro_left = { GYRO_CALIBRATE };
-LEGO_CAL_DEVICE_ATTR(cal_gyro_left, "calibrate_gyro", SET_GYRO_CFG,
+static struct go_cfg_attr cal_gyro_left = { SET_GYRO_CFG };
+LEGO_CAL_DEVICE_ATTR(cal_gyro_left, "calibrate_gyro", GYRO_CALIBRATE,
LEFT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_gyro_left_index, "calibrate_gyro_index");
@@ -2018,18 +2018,18 @@ LEGO_DEVICE_ATTR_RW(rumble_notification_right, "rumble_notification",
static DEVICE_ATTR_RO_NAMED(rumble_notification_right_index,
"rumble_notification_index");
-static struct go_cfg_attr cal_trigg_right = { TRIGGER_CALIBRATE };
-LEGO_CAL_DEVICE_ATTR(cal_trigg_right, "calibrate_trigger", SET_TRIGGER_CFG,
+static struct go_cfg_attr cal_trigg_right = { SET_TRIGGER_CFG };
+LEGO_CAL_DEVICE_ATTR(cal_trigg_right, "calibrate_trigger", TRIGGER_CALIBRATE,
RIGHT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_trigg_right_index, "calibrate_trigger_index");
-static struct go_cfg_attr cal_joy_right = { JOYSTICK_CALIBRATE };
-LEGO_CAL_DEVICE_ATTR(cal_joy_right, "calibrate_joystick", SET_JOYSTICK_CFG,
+static struct go_cfg_attr cal_joy_right = { SET_JOYSTICK_CFG };
+LEGO_CAL_DEVICE_ATTR(cal_joy_right, "calibrate_joystick", JOYSTICK_CALIBRATE,
RIGHT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_joy_right_index, "calibrate_joystick_index");
-static struct go_cfg_attr cal_gyro_right = { GYRO_CALIBRATE };
-LEGO_CAL_DEVICE_ATTR(cal_gyro_right, "calibrate_gyro", SET_GYRO_CFG,
+static struct go_cfg_attr cal_gyro_right = { SET_GYRO_CFG };
+LEGO_CAL_DEVICE_ATTR(cal_gyro_right, "calibrate_gyro", GYRO_CALIBRATE,
RIGHT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_gyro_right_index, "calibrate_gyro_index");
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 2/7] HID: hid-lenovo-go: use the right controller selectors
2026-09-01 6:36 [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration Aditya Dash
2026-09-01 6:36 ` [PATCH v3 1/7] HID: hid-lenovo-go: use the correct calibration commands Aditya Dash
@ 2026-09-01 6:36 ` Aditya Dash
2026-09-01 6:36 ` [PATCH v3 3/7] HID: hid-lenovo-go: initialize command completion before hardware Aditya Dash
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Aditya Dash @ 2026-09-01 6:36 UTC (permalink / raw)
To: Benjamin Tissoires, Derek J. Clark, Jiri Kosina, Mark Pearson
Cc: linux-input, linux-kernel
The right imu_enabled attribute selects FEATURE_IMU_BYPASS, and the right
reset attribute targets the left controller.
Select FEATURE_IMU_ENABLE for the right imu_enabled attribute. Target the
right controller for a right reset.
Fixes: 82cd9bc866e1 ("HID: hid-lenovo-go: Add Feature Status Attributes")
Assisted-by: Pi:gpt-5.6-sol
Signed-off-by: Aditya Dash <mradityadash@gmail.com>
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Tested-by: Derek J. Clark <derekjohn.clark@gmail.com>
---
drivers/hid/hid-lenovo-go.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
index b8248bf8965c..b937d11dd6f6 100644
--- a/drivers/hid/hid-lenovo-go.c
+++ b/drivers/hid/hid-lenovo-go.c
@@ -1999,13 +1999,13 @@ LEGO_DEVICE_ATTR_RW(imu_bypass_right, "imu_bypass_enabled", RIGHT_CONTROLLER,
index, feature_status);
static DEVICE_ATTR_RO_NAMED(imu_bypass_right_index, "imu_bypass_enabled_index");
-static struct go_cfg_attr imu_enabled_right = { FEATURE_IMU_BYPASS };
+static struct go_cfg_attr imu_enabled_right = { FEATURE_IMU_ENABLE };
LEGO_DEVICE_ATTR_RW(imu_enabled_right, "imu_enabled", RIGHT_CONTROLLER, index,
feature_status);
static DEVICE_ATTR_RO_NAMED(imu_enabled_right_index, "imu_enabled_index");
static struct go_cfg_attr reset_right = { FEATURE_RESET_GAMEPAD };
-LEGO_DEVICE_ATTR_WO(reset_right, "reset", LEFT_CONTROLLER, feature_status);
+LEGO_DEVICE_ATTR_WO(reset_right, "reset", RIGHT_CONTROLLER, feature_status);
static struct go_cfg_attr rumble_mode_right = { RUMBLE_MODE };
LEGO_DEVICE_ATTR_RW(rumble_mode_right, "rumble_mode", RIGHT_CONTROLLER, index,
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 3/7] HID: hid-lenovo-go: initialize command completion before hardware
2026-09-01 6:36 [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration Aditya Dash
2026-09-01 6:36 ` [PATCH v3 1/7] HID: hid-lenovo-go: use the correct calibration commands Aditya Dash
2026-09-01 6:36 ` [PATCH v3 2/7] HID: hid-lenovo-go: use the right controller selectors Aditya Dash
@ 2026-09-01 6:36 ` Aditya Dash
2026-09-01 6:36 ` [PATCH v3 4/7] HID: hid-lenovo-go: return configuration request errors Aditya Dash
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Aditya Dash @ 2026-09-01 6:36 UTC (permalink / raw)
To: Benjamin Tissoires, Derek J. Clark, Jiri Kosina, Mark Pearson
Cc: linux-input, linux-kernel
The configuration interface initializes its command completion in
cfg_probe(). The hardware starts and opens before this call. Keep the
completion ready before hardware I/O becomes available.
Identify the interface after parsing it. Initialize the completion for the
configuration interface before starting and opening HID hardware. Keep the
remaining configuration setup in cfg_probe().
Fixes: d69ccfcbc955 ("HID: hid-lenovo-go: Add Lenovo Legion Go Series HID Driver")
Assisted-by: Pi:gpt-5.6-sol
Signed-off-by: Aditya Dash <mradityadash@gmail.com>
---
drivers/hid/hid-lenovo-go.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
index b937d11dd6f6..51e3112780e1 100644
--- a/drivers/hid/hid-lenovo-go.c
+++ b/drivers/hid/hid-lenovo-go.c
@@ -2388,8 +2388,6 @@ static int hid_go_cfg_probe(struct hid_device *hdev,
drvdata.led_cdev = &go_cdev_rgb.led_cdev;
- init_completion(&drvdata.send_cmd_complete);
-
/* Executing calls prior to returning from probe will lock the MCU. Schedule
* initial data call after probe has completed and MCU can accept calls.
*/
@@ -2436,6 +2434,10 @@ static int hid_go_probe(struct hid_device *hdev, const struct hid_device_id *id)
return ret;
}
+ ep = get_endpoint_address(hdev);
+ if (ep == GO_GP_INTF_IN)
+ init_completion(&drvdata.send_cmd_complete);
+
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
hid_err(hdev, "Failed to start HID device\n");
@@ -2449,7 +2451,6 @@ static int hid_go_probe(struct hid_device *hdev, const struct hid_device_id *id)
return ret;
}
- ep = get_endpoint_address(hdev);
if (ep != GO_GP_INTF_IN) {
dev_dbg(&hdev->dev, "Started interface %x as generic HID device\n", ep);
return 0;
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 4/7] HID: hid-lenovo-go: return configuration request errors
2026-09-01 6:36 [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration Aditya Dash
` (2 preceding siblings ...)
2026-09-01 6:36 ` [PATCH v3 3/7] HID: hid-lenovo-go: initialize command completion before hardware Aditya Dash
@ 2026-09-01 6:36 ` Aditya Dash
2026-09-01 6:36 ` [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status Aditya Dash
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Aditya Dash @ 2026-09-01 6:36 UTC (permalink / raw)
To: Benjamin Tissoires, Derek J. Clark, Jiri Kosina, Mark Pearson
Cc: linux-input, linux-kernel
Any decoded configuration reply completes the shared completion. The driver
also ignores the result of its interruptible wait. An unrelated reply, a
firmware error, an interrupted wait, or a timeout can therefore be reported
as success.
Add pending command state to the driver data. Match replies by command ID,
command, sub-command, and device, and return request errors to the caller.
Clear the pending request after an interruption or timeout so a late reply
cannot replace that result.
Keep the existing 50 ms wait for every configuration request. Corrected
calibration requests on an Original Legion Go received their matching SET
replies within 8 ms. The final calibration result remains asynchronous.
The firmware has no sequence number. A late reply with the same tuple can
still match a newer request.
Fixes: d69ccfcbc955 ("HID: hid-lenovo-go: Add Lenovo Legion Go Series HID Driver")
Assisted-by: Pi:gpt-5.6-sol
Signed-off-by: Aditya Dash <mradityadash@gmail.com>
---
drivers/hid/hid-lenovo-go.c | 109 +++++++++++++++++++++++++++++-------
1 file changed, 88 insertions(+), 21 deletions(-)
diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
index 51e3112780e1..deed7acd2dc4 100644
--- a/drivers/hid/hid-lenovo-go.c
+++ b/drivers/hid/hid-lenovo-go.c
@@ -21,6 +21,7 @@
#include <linux/led-class-multicolor.h>
#include <linux/mutex.h>
#include <linux/printk.h>
+#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/unaligned.h>
@@ -31,13 +32,27 @@
#include "hid-ids.h"
#define GO_GP_INTF_IN 0x83
+#define GO_INPUT_REPORT_ID 0x04
#define GO_OUTPUT_REPORT_ID 0x05
#define GO_GP_RESET_SUCCESS 0x01
#define GO_PACKET_SIZE 64
+#define GO_COMMAND_TIMEOUT_MS 50
+
+/* Lenovo replies identify a command and a sub-command, but have no sequence. */
+struct hid_go_cmd {
+ struct completion done;
+ spinlock_t lock; /* protects fields below */
+ bool pending;
+ u8 id;
+ u8 command;
+ u8 sub_command;
+ u8 device;
+ int result;
+};
static struct hid_go_cfg {
struct delayed_work go_cfg_setup;
- struct completion send_cmd_complete;
+ struct hid_go_cmd cmd;
struct led_classdev *led_cdev;
struct hid_device *hdev;
struct mutex cfg_mutex; /*ensure single synchronous output report*/
@@ -331,6 +346,62 @@ static const char *const os_mode_text[] = {
[LINUX] = "linux",
};
+static void hid_go_cmd_arm(u8 id, u8 command, u8 sub_command, u8 device)
+{
+ guard(spinlock_irqsave)(&drvdata.cmd.lock);
+
+ reinit_completion(&drvdata.cmd.done);
+ drvdata.cmd.pending = true;
+ drvdata.cmd.id = id;
+ drvdata.cmd.command = command;
+ drvdata.cmd.sub_command = sub_command;
+ drvdata.cmd.device = device;
+}
+
+static void hid_go_cmd_consume(const struct command_report *cmd_rep, int result)
+{
+ guard(spinlock_irqsave)(&drvdata.cmd.lock);
+
+ if (drvdata.cmd.pending && cmd_rep->id == drvdata.cmd.id &&
+ cmd_rep->cmd == drvdata.cmd.command &&
+ cmd_rep->sub_cmd == drvdata.cmd.sub_command &&
+ cmd_rep->device_type == drvdata.cmd.device) {
+ drvdata.cmd.pending = false;
+ drvdata.cmd.result = result;
+ complete(&drvdata.cmd.done);
+ }
+}
+
+static int hid_go_cmd_finish(long wait_result)
+{
+ guard(spinlock_irqsave)(&drvdata.cmd.lock);
+
+ if (wait_result <= 0) {
+ drvdata.cmd.pending = false;
+ return wait_result < 0 ? wait_result : -ETIMEDOUT;
+ }
+
+ return drvdata.cmd.result;
+}
+
+static int hid_go_cmd_cancel(int result)
+{
+ guard(spinlock_irqsave)(&drvdata.cmd.lock);
+
+ drvdata.cmd.pending = false;
+ return result;
+}
+
+static int hid_go_send_output_report(struct hid_device *hdev, u8 *packet)
+{
+ int ret;
+
+ ret = hid_hw_output_report(hdev, packet, GO_PACKET_SIZE);
+ if (ret < 0)
+ return ret;
+ return ret == GO_PACKET_SIZE ? 0 : -EINVAL;
+}
+
static int hid_go_version_event(struct command_report *cmd_rep)
{
switch (cmd_rep->sub_cmd) {
@@ -654,7 +725,7 @@ static int hid_go_raw_event(struct hid_device *hdev, struct hid_report *report,
struct command_report *cmd_rep;
int ep, ret;
- if (size != GO_PACKET_SIZE)
+ if (size != GO_PACKET_SIZE || data[0] != GO_INPUT_REPORT_ID)
goto passthrough;
ep = get_endpoint_address(hdev);
@@ -707,7 +778,7 @@ static int hid_go_raw_event(struct hid_device *hdev, struct hid_report *report,
dev_dbg(&hdev->dev, "Rx data as raw input report: [%*ph]\n",
GO_PACKET_SIZE, data);
- complete(&drvdata.send_cmd_complete);
+ hid_go_cmd_consume(cmd_rep, ret);
return ret;
passthrough:
@@ -722,7 +793,8 @@ static int mcu_property_out(struct hid_device *hdev, u8 id, u8 command,
unsigned char *dmabuf __free(kfree) = NULL;
u8 header[] = { GO_OUTPUT_REPORT_ID, id, command, index, device };
size_t header_size = ARRAY_SIZE(header);
- int timeout = 50;
+ unsigned long timeout = msecs_to_jiffies(GO_COMMAND_TIMEOUT_MS);
+ long wait_result;
int ret;
if (header_size + len > GO_PACKET_SIZE)
@@ -740,22 +812,14 @@ static int mcu_property_out(struct hid_device *hdev, u8 id, u8 command,
dev_dbg(&hdev->dev, "Send data as raw output report: [%*ph]\n",
GO_PACKET_SIZE, dmabuf);
- ret = hid_hw_output_report(hdev, dmabuf, GO_PACKET_SIZE);
- if (ret < 0)
- return ret;
-
- ret = ret == GO_PACKET_SIZE ? 0 : -EINVAL;
+ hid_go_cmd_arm(id, command, index, device);
+ ret = hid_go_send_output_report(hdev, dmabuf);
if (ret)
- return ret;
-
- ret = wait_for_completion_interruptible_timeout(&drvdata.send_cmd_complete,
- msecs_to_jiffies(timeout));
-
- if (ret == 0) /* timeout occurred */
- ret = -EBUSY;
+ return hid_go_cmd_cancel(ret);
- reinit_completion(&drvdata.send_cmd_complete);
- return 0;
+ wait_result = wait_for_completion_interruptible_timeout(&drvdata.cmd.done,
+ timeout);
+ return hid_go_cmd_finish(wait_result);
}
static ssize_t version_show(struct device *dev, struct device_attribute *attr,
@@ -2362,9 +2426,9 @@ static int hid_go_cfg_probe(struct hid_device *hdev,
if (!buf)
return -ENOMEM;
+ mutex_init(&drvdata.cfg_mutex);
hid_set_drvdata(hdev, &drvdata);
drvdata.hdev = hdev;
- mutex_init(&drvdata.cfg_mutex);
ret = sysfs_create_groups(&hdev->dev.kobj, top_level_attr_groups);
if (ret) {
@@ -2435,8 +2499,11 @@ static int hid_go_probe(struct hid_device *hdev, const struct hid_device_id *id)
}
ep = get_endpoint_address(hdev);
- if (ep == GO_GP_INTF_IN)
- init_completion(&drvdata.send_cmd_complete);
+ if (ep == GO_GP_INTF_IN) {
+ init_completion(&drvdata.cmd.done);
+ spin_lock_init(&drvdata.cmd.lock);
+ drvdata.cmd.pending = false;
+ }
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status
2026-09-01 6:36 [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration Aditya Dash
` (3 preceding siblings ...)
2026-09-01 6:36 ` [PATCH v3 4/7] HID: hid-lenovo-go: return configuration request errors Aditya Dash
@ 2026-09-01 6:36 ` Aditya Dash
2026-09-01 15:57 ` Derek John Clark
2026-09-01 6:36 ` [PATCH v3 6/7] HID: hid-lenovo-go: reject unknown calibration action Aditya Dash
2026-09-01 6:36 ` [PATCH v3 7/7] HID: hid-lenovo-go: clear calibration status on start Aditya Dash
6 siblings, 1 reply; 12+ messages in thread
From: Aditya Dash @ 2026-09-01 6:36 UTC (permalink / raw)
To: Benjamin Tissoires, Derek J. Clark, Jiri Kosina, Mark Pearson
Cc: linux-input, linux-kernel
The driver stores the firmware result byte as an index into the
calibration status text. A Legion Go 1 returned 0x08 after an idle Stop.
The status table has only three entries, so a later read returns -EINVAL.
Keep the defined values 0x00 through 0x02. Treat larger result values as
failure before storing them.
Fixes: 995887a10da1 ("HID: hid-lenovo-go: Add Calibration Settings")
Assisted-by: Pi:gpt-5.6-sol
Signed-off-by: Aditya Dash <mradityadash@gmail.com>
---
drivers/hid/hid-lenovo-go.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
index deed7acd2dc4..59b457683357 100644
--- a/drivers/hid/hid-lenovo-go.c
+++ b/drivers/hid/hid-lenovo-go.c
@@ -648,17 +648,22 @@ static int hid_go_light_event(struct command_report *cmd_rep)
static int hid_go_device_status_event(struct command_report *cmd_rep)
{
+ u8 status = cmd_rep->data[1];
+
+ if (status > CAL_STAT_FAILURE)
+ status = CAL_STAT_FAILURE;
+
switch (cmd_rep->device_type) {
case LEFT_CONTROLLER:
switch (cmd_rep->data[0]) {
case CALDEV_GYROSCOPE:
- drvdata.gp_left_gyro_cal_status = cmd_rep->data[1];
+ drvdata.gp_left_gyro_cal_status = status;
return 0;
case CALDEV_JOYSTICK:
- drvdata.gp_left_joy_cal_status = cmd_rep->data[1];
+ drvdata.gp_left_joy_cal_status = status;
return 0;
case CALDEV_TRIGGER:
- drvdata.gp_left_trigg_cal_status = cmd_rep->data[1];
+ drvdata.gp_left_trigg_cal_status = status;
return 0;
default:
return -EINVAL;
@@ -667,13 +672,13 @@ static int hid_go_device_status_event(struct command_report *cmd_rep)
case RIGHT_CONTROLLER:
switch (cmd_rep->data[0]) {
case CALDEV_GYROSCOPE:
- drvdata.gp_right_gyro_cal_status = cmd_rep->data[1];
+ drvdata.gp_right_gyro_cal_status = status;
return 0;
case CALDEV_JOYSTICK:
- drvdata.gp_right_joy_cal_status = cmd_rep->data[1];
+ drvdata.gp_right_joy_cal_status = status;
return 0;
case CALDEV_TRIGGER:
- drvdata.gp_right_trigg_cal_status = cmd_rep->data[1];
+ drvdata.gp_right_trigg_cal_status = status;
return 0;
default:
return -EINVAL;
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 6/7] HID: hid-lenovo-go: reject unknown calibration action
2026-09-01 6:36 [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration Aditya Dash
` (4 preceding siblings ...)
2026-09-01 6:36 ` [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status Aditya Dash
@ 2026-09-01 6:36 ` Aditya Dash
2026-09-01 6:36 ` [PATCH v3 7/7] HID: hid-lenovo-go: clear calibration status on start Aditya Dash
6 siblings, 0 replies; 12+ messages in thread
From: Aditya Dash @ 2026-09-01 6:36 UTC (permalink / raw)
To: Benjamin Tissoires, Derek J. Clark, Jiri Kosina, Mark Pearson
Cc: linux-input, linux-kernel
The calibration action table includes 'unknown' at index zero. The options
attribute skips that entry and lists only 'start' and 'stop', but the store
searches the full table. Writing 'unknown' sends a request without an
action byte.
Reject CAL_UNKNOWN before building the request. Start and Stop both use a
one-byte action, so pass that size directly.
Fixes: 995887a10da1 ("HID: hid-lenovo-go: Add Calibration Settings")
Assisted-by: Pi:gpt-5.6-sol
Signed-off-by: Aditya Dash <mradityadash@gmail.com>
---
drivers/hid/hid-lenovo-go.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
index 59b457683357..a6dec5490d17 100644
--- a/drivers/hid/hid-lenovo-go.c
+++ b/drivers/hid/hid-lenovo-go.c
@@ -1412,20 +1412,18 @@ static ssize_t calibrate_config_store(struct device *dev,
const char *buf, u8 cmd, u8 sub_cmd,
size_t count, enum dev_type device_type)
{
- size_t size = 1;
- u8 val = 0;
+ u8 val;
int ret;
ret = sysfs_match_string(cal_enabled_text, buf);
if (ret < 0)
return ret;
+ if (ret == CAL_UNKNOWN)
+ return -EINVAL;
val = ret;
- if (!val)
- size = 0;
-
ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, cmd, sub_cmd,
- device_type, &val, size);
+ device_type, &val, sizeof(val));
if (ret < 0)
return ret;
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 7/7] HID: hid-lenovo-go: clear calibration status on start
2026-09-01 6:36 [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration Aditya Dash
` (5 preceding siblings ...)
2026-09-01 6:36 ` [PATCH v3 6/7] HID: hid-lenovo-go: reject unknown calibration action Aditya Dash
@ 2026-09-01 6:36 ` Aditya Dash
6 siblings, 0 replies; 12+ messages in thread
From: Aditya Dash @ 2026-09-01 6:36 UTC (permalink / raw)
To: Benjamin Tissoires, Derek J. Clark, Jiri Kosina, Mark Pearson
Cc: linux-input, linux-kernel
A completed calibration leaves success or failure in its status file. If
the next calibration has the same result, userspace sees no change and
cannot tell when the new attempt starts or finishes.
Link each calibration action attribute to its status field. Set only that
field to unknown before submitting Start. Stop leaves the status unchanged,
and the next firmware result replaces unknown with success or failure.
Fixes: 995887a10da1 ("HID: hid-lenovo-go: Add Calibration Settings")
Assisted-by: Pi:gpt-5.6-sol
Signed-off-by: Aditya Dash <mradityadash@gmail.com>
---
drivers/hid/hid-lenovo-go.c | 38 +++++++++++++++++++++++++++++--------
1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
index a6dec5490d17..749536e19d2d 100644
--- a/drivers/hid/hid-lenovo-go.c
+++ b/drivers/hid/hid-lenovo-go.c
@@ -111,6 +111,11 @@ struct go_cfg_attr {
u8 index;
};
+struct go_cal_cfg_attr {
+ u8 index;
+ u8 *status;
+};
+
struct command_report {
u8 report_id;
u8 id;
@@ -1410,7 +1415,8 @@ static ssize_t device_status_show(struct device *dev,
static ssize_t calibrate_config_store(struct device *dev,
struct device_attribute *attr,
const char *buf, u8 cmd, u8 sub_cmd,
- size_t count, enum dev_type device_type)
+ size_t count, enum dev_type device_type,
+ u8 *cal_status)
{
u8 val;
int ret;
@@ -1422,6 +1428,9 @@ static ssize_t calibrate_config_store(struct device *dev,
return -EINVAL;
val = ret;
+ if (val == CAL_START)
+ *cal_status = CAL_STAT_UNKNOWN;
+
ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, cmd, sub_cmd,
device_type, &val, sizeof(val));
if (ret < 0)
@@ -1818,7 +1827,8 @@ static void hid_go_brightness_set(struct led_classdev *led_cdev,
const char *buf, size_t count) \
{ \
return calibrate_config_store(dev, attr, buf, _name.index, \
- _scmd, count, _dtype); \
+ _scmd, count, _dtype, \
+ _name.status); \
} \
static ssize_t _name##_##_rtype##_show( \
struct device *dev, struct device_attribute *attr, char *buf) \
@@ -1978,17 +1988,23 @@ LEGO_DEVICE_ATTR_RW(rumble_notification_left, "rumble_notification",
static DEVICE_ATTR_RO_NAMED(rumble_notification_left_index,
"rumble_notification_index");
-static struct go_cfg_attr cal_trigg_left = { SET_TRIGGER_CFG };
+static struct go_cal_cfg_attr cal_trigg_left = {
+ SET_TRIGGER_CFG, &drvdata.gp_left_trigg_cal_status
+};
LEGO_CAL_DEVICE_ATTR(cal_trigg_left, "calibrate_trigger", TRIGGER_CALIBRATE,
LEFT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_trigg_left_index, "calibrate_trigger_index");
-static struct go_cfg_attr cal_joy_left = { SET_JOYSTICK_CFG };
+static struct go_cal_cfg_attr cal_joy_left = {
+ SET_JOYSTICK_CFG, &drvdata.gp_left_joy_cal_status
+};
LEGO_CAL_DEVICE_ATTR(cal_joy_left, "calibrate_joystick", JOYSTICK_CALIBRATE,
LEFT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_joy_left_index, "calibrate_joystick_index");
-static struct go_cfg_attr cal_gyro_left = { SET_GYRO_CFG };
+static struct go_cal_cfg_attr cal_gyro_left = {
+ SET_GYRO_CFG, &drvdata.gp_left_gyro_cal_status
+};
LEGO_CAL_DEVICE_ATTR(cal_gyro_left, "calibrate_gyro", GYRO_CALIBRATE,
LEFT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_gyro_left_index, "calibrate_gyro_index");
@@ -2085,17 +2101,23 @@ LEGO_DEVICE_ATTR_RW(rumble_notification_right, "rumble_notification",
static DEVICE_ATTR_RO_NAMED(rumble_notification_right_index,
"rumble_notification_index");
-static struct go_cfg_attr cal_trigg_right = { SET_TRIGGER_CFG };
+static struct go_cal_cfg_attr cal_trigg_right = {
+ SET_TRIGGER_CFG, &drvdata.gp_right_trigg_cal_status
+};
LEGO_CAL_DEVICE_ATTR(cal_trigg_right, "calibrate_trigger", TRIGGER_CALIBRATE,
RIGHT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_trigg_right_index, "calibrate_trigger_index");
-static struct go_cfg_attr cal_joy_right = { SET_JOYSTICK_CFG };
+static struct go_cal_cfg_attr cal_joy_right = {
+ SET_JOYSTICK_CFG, &drvdata.gp_right_joy_cal_status
+};
LEGO_CAL_DEVICE_ATTR(cal_joy_right, "calibrate_joystick", JOYSTICK_CALIBRATE,
RIGHT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_joy_right_index, "calibrate_joystick_index");
-static struct go_cfg_attr cal_gyro_right = { SET_GYRO_CFG };
+static struct go_cal_cfg_attr cal_gyro_right = {
+ SET_GYRO_CFG, &drvdata.gp_right_gyro_cal_status
+};
LEGO_CAL_DEVICE_ATTR(cal_gyro_right, "calibrate_gyro", GYRO_CALIBRATE,
RIGHT_CONTROLLER, index);
static DEVICE_ATTR_RO_NAMED(cal_gyro_right_index, "calibrate_gyro_index");
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status
2026-09-01 6:36 ` [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status Aditya Dash
@ 2026-09-01 15:57 ` Derek John Clark
2026-09-01 17:06 ` Aditya
0 siblings, 1 reply; 12+ messages in thread
From: Derek John Clark @ 2026-09-01 15:57 UTC (permalink / raw)
To: Aditya Dash
Cc: Benjamin Tissoires, Jiri Kosina, Mark Pearson, linux-input, linux-kernel
On Mon, Aug 31, 2026 at 11:36 PM Aditya Dash <mradityadash@gmail.com> wrote:
>
> The driver stores the firmware result byte as an index into the
> calibration status text. A Legion Go 1 returned 0x08 after an idle Stop.
> The status table has only three entries, so a later read returns -EINVAL.
>
> Keep the defined values 0x00 through 0x02. Treat larger result values as
> failure before storing them.
Hi Aditya,
The 0x08 thing seemed odd to me and I meant to dig into the docs sooner.
I think the real reason for the bug you were seeing is a mixup of what data
bytet means what. There is an off by 1 error with using data[1] since
device_type is really the 0 byte for the information payload. data[1] is the
reason code for the failure.
From the docs:
Byte 0: Device Type:
0x01: Gyroscope
0x02: Joystick
0x03: Trigger
0x04: Joystick Trigger (Currently Unused)
Byte 1: Calibration Status:
0x01: Calibration Successful
0x02: Calibration Failed
Byte 2-3: Failure Reason:
Gyro:
0x0001 - Not stationary, timeout
0x0002 - Connection status changed
Joystick:
0x0100 - Joystick not fully deflected
0x0200 - Joystick not centered
0x0400 - Joystick not rotated two turns
0x0800 - Connection status changed
Trigger:
0x0001 - Trigger not fully depressed
0x0002 - Trigger not returned to starting position
0x0004 - Trigger not pressed twice
0x0008 - Connection status changed
Since we're matching on cmd_rep->device_type(byte 0 corollary) I think
switching to data[0] is sufficient to resolve the bug. If my hunch is
correct a trigger and gyro calibration will always succeed in the
driver as it stands. I won't be able to validate this myself for a
couple of hours on actual hardware, but I'll respond after I do.
Thanks,
Derek
> Fixes: 995887a10da1 ("HID: hid-lenovo-go: Add Calibration Settings")
> Assisted-by: Pi:gpt-5.6-sol
> Signed-off-by: Aditya Dash <mradityadash@gmail.com>
> ---
> drivers/hid/hid-lenovo-go.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
> index deed7acd2dc4..59b457683357 100644
> --- a/drivers/hid/hid-lenovo-go.c
> +++ b/drivers/hid/hid-lenovo-go.c
> @@ -648,17 +648,22 @@ static int hid_go_light_event(struct command_report *cmd_rep)
>
> static int hid_go_device_status_event(struct command_report *cmd_rep)
> {
> + u8 status = cmd_rep->data[1];
> +
> + if (status > CAL_STAT_FAILURE)
> + status = CAL_STAT_FAILURE;
> +
> switch (cmd_rep->device_type) {
> case LEFT_CONTROLLER:
> switch (cmd_rep->data[0]) {
> case CALDEV_GYROSCOPE:
> - drvdata.gp_left_gyro_cal_status = cmd_rep->data[1];
> + drvdata.gp_left_gyro_cal_status = status;
> return 0;
> case CALDEV_JOYSTICK:
> - drvdata.gp_left_joy_cal_status = cmd_rep->data[1];
> + drvdata.gp_left_joy_cal_status = status;
> return 0;
> case CALDEV_TRIGGER:
> - drvdata.gp_left_trigg_cal_status = cmd_rep->data[1];
> + drvdata.gp_left_trigg_cal_status = status;
> return 0;
> default:
> return -EINVAL;
> @@ -667,13 +672,13 @@ static int hid_go_device_status_event(struct command_report *cmd_rep)
> case RIGHT_CONTROLLER:
> switch (cmd_rep->data[0]) {
> case CALDEV_GYROSCOPE:
> - drvdata.gp_right_gyro_cal_status = cmd_rep->data[1];
> + drvdata.gp_right_gyro_cal_status = status;
> return 0;
> case CALDEV_JOYSTICK:
> - drvdata.gp_right_joy_cal_status = cmd_rep->data[1];
> + drvdata.gp_right_joy_cal_status = status;
> return 0;
> case CALDEV_TRIGGER:
> - drvdata.gp_right_trigg_cal_status = cmd_rep->data[1];
> + drvdata.gp_right_trigg_cal_status = status;
> return 0;
> default:
> return -EINVAL;
> --
> 2.55.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status
2026-09-01 15:57 ` Derek John Clark
@ 2026-09-01 17:06 ` Aditya
2026-09-02 12:40 ` Derek J. Clark
0 siblings, 1 reply; 12+ messages in thread
From: Aditya @ 2026-09-01 17:06 UTC (permalink / raw)
To: Derek John Clark
Cc: Benjamin Tissoires, Jiri Kosina, Mark Pearson, linux-input, linux-kernel
Hi Derek,
Just to clarify, this behaviour was seen when sending a left
calibration joystick stop command when no calibration was
being performed.
Sending a respective start command returns after 10 seconds
with the error codes you have provided.
Here are the exact requests and responses. Consider ellipsis
to mean that the rest of it is zeros:
Left joystick calibration start:
Request:
05 00 0c 04 03 01 ...
Response (after 10s, no movement):
04 00 a0 02 03 02 02 07 ...
Left joystick calibration stop (when no calibration is running):
Request:
05 00 0c 04 03 02 ...
Response (this is near immediate):
04 00 a0 02 03 02 08 00 ...
Thanks,
Aditya
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status
2026-09-01 17:06 ` Aditya
@ 2026-09-02 12:40 ` Derek J. Clark
2026-09-05 6:10 ` Aditya Dash
0 siblings, 1 reply; 12+ messages in thread
From: Derek J. Clark @ 2026-09-02 12:40 UTC (permalink / raw)
To: Aditya
Cc: Benjamin Tissoires, Jiri Kosina, Mark Pearson, linux-input, linux-kernel
On September 1, 2026 10:06:18 AM PDT, Aditya <mradityadash@gmail.com> wrote:
>Hi Derek,
>
>Just to clarify, this behaviour was seen when sending a left
>calibration joystick stop command when no calibration was
>being performed.
>
>Sending a respective start command returns after 10 seconds
>with the error codes you have provided.
>
>Here are the exact requests and responses. Consider ellipsis
>to mean that the rest of it is zeros:
>
>Left joystick calibration start:
>Request:
> 05 00 0c 04 03 01 ...
>Response (after 10s, no movement):
> 04 00 a0 02 03 02 02 07 ...
This makes it look like the reason code is a bitmask rather than a specific value. Probably more difficult to present in sysfs than the value it provides.
> Left joystick calibration stop (when no calibration is running):
>Request:
> 05 00 0c 04 03 02 ...
>Response (this is near immediate):
> 04 00 a0 02 03 02 08 00 ...
Interesting. This wouldn't be the first time documentation was incomplete or inaccurate from Lenovo so I'm not super surprised. We can then consider a 0x08 response on the status byte as stopped with no call running, vice failed, if you think that information is relevant to the end user. I think it might be. If you stop it with a cal running is there a meaningful difference in the response?
Thanks,
Derek
>Thanks,
>Aditya
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status
2026-09-02 12:40 ` Derek J. Clark
@ 2026-09-05 6:10 ` Aditya Dash
0 siblings, 0 replies; 12+ messages in thread
From: Aditya Dash @ 2026-09-05 6:10 UTC (permalink / raw)
To: Derek J . Clark
Cc: Benjamin Tissoires, Jiri Kosina, Mark Pearson, linux-input, linux-kernel
Hi Derek,
The Stop reply changes based on calibration state. Its status appears to be
the current failure_mask + 1. However, this mask does not always match the
failure mask returned when calibration times out.
Here are some requests and responses from the experiments done:
Joystick calibration:
Left Start:
05 00 0c 04 03 01 ...
Left Stop:
05 00 0c 04 03 02 ...
No movement:
Without Stop:
04 00 a0 02 03 02 02 07 00 ...
With Stop:
04 00 a0 02 03 02 06 00 00 ...
The timeout error contains deflection 0x01, center 0x02, and turns 0x04.
Stop does not set the center bit, giving mask 0x05 and status 0x06.
One full outer turn, returned to center:
Without Stop:
04 00 a0 02 03 02 02 06 00 ...
With Stop:
04 00 a0 02 03 02 05 00 00 ...
The timeout error contains center 0x02 and turns 0x04. Stop does not set the
center bit, giving mask 0x04 and status 0x05.
One full outer turn, then held away from center (right controller):
Without Stop:
04 00 a0 02 04 02 02 06 00 ...
With Stop:
04 00 a0 02 04 02 07 00 00 ...
Two full outer turns, then held away from center:
Without Stop:
04 00 a0 02 03 02 02 02 00 ...
With Stop:
04 00 a0 02 03 02 03 00 00 ...
Stop with no calibration running:
04 00 a0 02 03 02 08 00 00 ...
Trigger calibration:
Start:
05 00 0a 04 03 01 ...
Stop:
05 00 0a 04 03 02 ...
One full press and release:
Without Stop:
04 00 a0 02 03 03 02 00 06 ...
With Stop:
04 00 a0 02 03 03 05 00 00 ...
The nonzero timeout reason byte is 0x06: return 0x02 and press count 0x04.
Stop does not set the return bit, giving mask 0x04 and status 0x05.
Gyroscope calibration:
Start:
05 00 0e 06 03 01 ...
Stop:
05 00 0e 06 03 02 ...
Continuous movement:
Without Stop:
04 00 a0 02 03 01 02 01 00 ...
With Stop:
04 00 a0 02 03 01 02 02 00 ...
The reason changes from 0x0001 to 0x0002 although no connection change was
made. The cause of this discrepancy is not known.
Successful calibration responses were as expected. The corresponding cases
produced the same outcomes on the other controller where repeated.
Connection-change cases are not yet tested.
Thanks,
Aditya
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-09-05 6:11 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-01 6:36 [PATCH v3 0/7] HID: hid-lenovo-go: fix controller configuration Aditya Dash
2026-09-01 6:36 ` [PATCH v3 1/7] HID: hid-lenovo-go: use the correct calibration commands Aditya Dash
2026-09-01 6:36 ` [PATCH v3 2/7] HID: hid-lenovo-go: use the right controller selectors Aditya Dash
2026-09-01 6:36 ` [PATCH v3 3/7] HID: hid-lenovo-go: initialize command completion before hardware Aditya Dash
2026-09-01 6:36 ` [PATCH v3 4/7] HID: hid-lenovo-go: return configuration request errors Aditya Dash
2026-09-01 6:36 ` [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status Aditya Dash
2026-09-01 15:57 ` Derek John Clark
2026-09-01 17:06 ` Aditya
2026-09-02 12:40 ` Derek J. Clark
2026-09-05 6:10 ` Aditya Dash
2026-09-01 6:36 ` [PATCH v3 6/7] HID: hid-lenovo-go: reject unknown calibration action Aditya Dash
2026-09-01 6:36 ` [PATCH v3 7/7] HID: hid-lenovo-go: clear calibration status on start Aditya Dash
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®