Loading drivers/hid/hid-lenovo.c +79 −39 Original line number Diff line number Diff line Loading @@ -51,7 +51,12 @@ struct lenovo_drvdata { int select_right; int sensitivity; int press_speed; u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ /* 0: Up * 1: Down (undecided) * 2: Scrolling * 3: Patched firmware, disable workaround */ u8 middlebutton_state; bool fn_lock; }; Loading Loading @@ -521,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); Loading Loading @@ -668,6 +686,22 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, { struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); if (cptkbd_data->middlebutton_state != 3) { /* REL_X and REL_Y events during middle button pressed * are only possible on patched, bug-free firmware * so set middlebutton_state to 3 * to never apply workaround anymore */ if (cptkbd_data->middlebutton_state == 1 && usage->type == EV_REL && (usage->code == REL_X || usage->code == REL_Y)) { cptkbd_data->middlebutton_state = 3; /* send middle button press which was hold before */ input_event(field->hidinput->input, EV_KEY, BTN_MIDDLE, 1); input_sync(field->hidinput->input); } /* "wheel" scroll events */ if (usage->type == EV_REL && (usage->code == REL_WHEEL || usage->code == REL_HWHEEL)) { Loading @@ -694,6 +728,7 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, } return 1; } } if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { /* Loading Loading @@ -1126,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; Loading Loading @@ -1264,6 +1283,24 @@ static int lenovo_probe(struct hid_device *hdev, 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); Loading Loading @@ -1380,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 Loading
drivers/hid/hid-lenovo.c +79 −39 Original line number Diff line number Diff line Loading @@ -51,7 +51,12 @@ struct lenovo_drvdata { int select_right; int sensitivity; int press_speed; u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ /* 0: Up * 1: Down (undecided) * 2: Scrolling * 3: Patched firmware, disable workaround */ u8 middlebutton_state; bool fn_lock; }; Loading Loading @@ -521,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); Loading Loading @@ -668,6 +686,22 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, { struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); if (cptkbd_data->middlebutton_state != 3) { /* REL_X and REL_Y events during middle button pressed * are only possible on patched, bug-free firmware * so set middlebutton_state to 3 * to never apply workaround anymore */ if (cptkbd_data->middlebutton_state == 1 && usage->type == EV_REL && (usage->code == REL_X || usage->code == REL_Y)) { cptkbd_data->middlebutton_state = 3; /* send middle button press which was hold before */ input_event(field->hidinput->input, EV_KEY, BTN_MIDDLE, 1); input_sync(field->hidinput->input); } /* "wheel" scroll events */ if (usage->type == EV_REL && (usage->code == REL_WHEEL || usage->code == REL_HWHEEL)) { Loading @@ -694,6 +728,7 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, } return 1; } } if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { /* Loading Loading @@ -1126,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; Loading Loading @@ -1264,6 +1283,24 @@ static int lenovo_probe(struct hid_device *hdev, 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); Loading Loading @@ -1380,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