mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-09 07:14:48 +08:00
hid: lenovo: Resend all settings on reset_resume for compact keyboards
commit2f2bd7cbd1
upstream. The USB Compact Keyboard variant requires a reset_resume function to restore keyboard configuration after a suspend in some situations. Move configuration normally done on probe to lenovo_features_set_cptkbd(), then recycle this for use on reset_resume. Without, the keyboard and driver would end up in an inconsistent state, breaking middle-button scrolling amongst other problems, and twiddling sysfs values wouldn't help as the middle-button mode won't be set until the driver is reloaded. Tested on a USB and Bluetooth Thinkpad Compact Keyboard. CC: stable@vger.kernel.org Fixes:94eefa2713
("HID: lenovo: Use native middle-button mode for compact keyboards") Signed-off-by: Jamie Lentin <jm@lentin.co.uk> Signed-off-by: Martin Kepplinger <martink@posteo.de> Link: https://lore.kernel.org/r/20231002150914.22101-1-martink@posteo.de Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7fb9d792c0
commit
465b557215
@ -526,6 +526,19 @@ static void lenovo_features_set_cptkbd(struct hid_device *hdev)
|
||||
int ret;
|
||||
struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
|
||||
|
||||
/*
|
||||
* Tell the keyboard a driver understands it, and turn F7, F9, F11 into
|
||||
* regular keys
|
||||
*/
|
||||
ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03);
|
||||
if (ret)
|
||||
hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
|
||||
|
||||
/* Switch middle button to native mode */
|
||||
ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01);
|
||||
if (ret)
|
||||
hid_warn(hdev, "Failed to switch middle button: %d\n", ret);
|
||||
|
||||
ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock);
|
||||
if (ret)
|
||||
hid_err(hdev, "Fn-lock setting failed: %d\n", ret);
|
||||
@ -1148,22 +1161,6 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
|
||||
}
|
||||
hid_set_drvdata(hdev, cptkbd_data);
|
||||
|
||||
/*
|
||||
* Tell the keyboard a driver understands it, and turn F7, F9, F11 into
|
||||
* regular keys (Compact only)
|
||||
*/
|
||||
if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD ||
|
||||
hdev->product == USB_DEVICE_ID_LENOVO_CBTKBD) {
|
||||
ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03);
|
||||
if (ret)
|
||||
hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Switch middle button to native mode */
|
||||
ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01);
|
||||
if (ret)
|
||||
hid_warn(hdev, "Failed to switch middle button: %d\n", ret);
|
||||
|
||||
/* Set keyboard settings to known state */
|
||||
cptkbd_data->middlebutton_state = 0;
|
||||
cptkbd_data->fn_lock = true;
|
||||
@ -1286,6 +1283,24 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int lenovo_reset_resume(struct hid_device *hdev)
|
||||
{
|
||||
switch (hdev->product) {
|
||||
case USB_DEVICE_ID_LENOVO_CUSBKBD:
|
||||
case USB_DEVICE_ID_LENOVO_TPIIUSBKBD:
|
||||
if (hdev->type == HID_TYPE_USBMOUSE)
|
||||
lenovo_features_set_cptkbd(hdev);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void lenovo_remove_tpkbd(struct hid_device *hdev)
|
||||
{
|
||||
struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev);
|
||||
@ -1402,6 +1417,9 @@ static struct hid_driver lenovo_driver = {
|
||||
.raw_event = lenovo_raw_event,
|
||||
.event = lenovo_event,
|
||||
.report_fixup = lenovo_report_fixup,
|
||||
#ifdef CONFIG_PM
|
||||
.reset_resume = lenovo_reset_resume,
|
||||
#endif
|
||||
};
|
||||
module_hid_driver(lenovo_driver);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user