Re: [PATCH v3 5/7] HID: hid-lenovo-go: normalize calibration failure status

From: Derek John Clark

Date: Tue Sep 01 2026 - 12:27:58 EST


On Mon, Aug 31, 2026 at 11:36 PM Aditya Dash <mradityadash@xxxxxxxxx> 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@xxxxxxxxx>
> ---
> 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
>