Skip to content

Commit

Permalink
Patches accepted for Linux 4.3
Browse files Browse the repository at this point in the history
  • Loading branch information
lentinj committed Aug 14, 2015
1 parent 3abc48b commit bd4f05d
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 0 deletions.
30 changes: 30 additions & 0 deletions kernel-patch/3001-HID-lenovo-Use-constants-for-axes-names.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
From 2decbccdcfcfe19b35ed7424881d57213bfc5a17 Mon Sep 17 00:00:00 2001
From: Jamie Lentin <jm@lentin.co.uk>
Date: Sun, 2 Aug 2015 10:45:39 +0100
Subject: [PATCH 1/3] HID: lenovo: Use constants for axes names

Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
---
drivers/hid/hid-lenovo.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index c4c3f09..65df414 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -117,10 +117,10 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev,

switch (usage->hid & HID_USAGE) {
case 0x0000:
- hid_map_usage(hi, usage, bit, max, EV_REL, 0x06);
+ hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
return 1;
case 0x0001:
- hid_map_usage(hi, usage, bit, max, EV_REL, 0x08);
+ hid_map_usage(hi, usage, bit, max, EV_REL, REL_WHEEL);
return 1;
default:
return -1;
--
2.1.4

31 changes: 31 additions & 0 deletions kernel-patch/3002-HID-lenovo-Add-missing-return-value-check.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
From 543e190688a51d947a024c011a09dbc6ed23a62b Mon Sep 17 00:00:00 2001
From: Jamie Lentin <jm@lentin.co.uk>
Date: Sun, 2 Aug 2015 10:46:10 +0100
Subject: [PATCH 2/3] HID: lenovo: Add missing return-value check

Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
---
drivers/hid/hid-lenovo.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index 65df414..265bfe2 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -178,9 +178,12 @@ static void lenovo_features_set_cptkbd(struct hid_device *hdev)
struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);

ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock);
- ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity);
if (ret)
hid_err(hdev, "Fn-lock setting failed: %d\n", ret);
+
+ ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity);
+ if (ret)
+ hid_err(hdev, "Sensitivity setting failed: %d\n", ret);
}

static ssize_t attr_fn_lock_show_cptkbd(struct device *dev,
--
2.1.4

Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
From 9a8c4f2d805fbc4589ab238e7f04cd1a34f5b922 Mon Sep 17 00:00:00 2001
From: Jamie Lentin <jm@lentin.co.uk>
Date: Sun, 2 Aug 2015 10:49:30 +0100
Subject: [PATCH 3/3] HID: lenovo: Hide middle-button press until release

Don't relay a middle button press to userspace until release, and then
only if there was no scroll events inbetween. This is closer to what
Xorg's wheel emulation does, and avoids spurious middle-click pastes.

Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
---
drivers/hid/hid-lenovo.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)

diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index 265bfe2..629d988 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -37,6 +37,7 @@ struct lenovo_drvdata_tpkbd {
};

struct lenovo_drvdata_cptkbd {
+ u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */
bool fn_lock;
int sensitivity;
};
@@ -287,6 +288,53 @@ static int lenovo_raw_event(struct hid_device *hdev,
return 0;
}

+static int lenovo_event_cptkbd(struct hid_device *hdev,
+ struct hid_field *field, struct hid_usage *usage, __s32 value)
+{
+ struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
+
+ /* "wheel" scroll events */
+ if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
+ usage->code == REL_HWHEEL)) {
+ /* Scroll events disable middle-click event */
+ cptkbd_data->middlebutton_state = 2;
+ return 0;
+ }
+
+ /* Middle click events */
+ if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) {
+ if (value == 1) {
+ cptkbd_data->middlebutton_state = 1;
+ } else if (value == 0) {
+ if (cptkbd_data->middlebutton_state == 1) {
+ /* No scrolling inbetween, send middle-click */
+ input_event(field->hidinput->input,
+ EV_KEY, BTN_MIDDLE, 1);
+ input_sync(field->hidinput->input);
+ input_event(field->hidinput->input,
+ EV_KEY, BTN_MIDDLE, 0);
+ input_sync(field->hidinput->input);
+ }
+ cptkbd_data->middlebutton_state = 0;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+static int lenovo_event(struct hid_device *hdev, struct hid_field *field,
+ struct hid_usage *usage, __s32 value)
+{
+ switch (hdev->product) {
+ case USB_DEVICE_ID_LENOVO_CUSBKBD:
+ case USB_DEVICE_ID_LENOVO_CBTKBD:
+ return lenovo_event_cptkbd(hdev, field, usage, value);
+ default:
+ return 0;
+ }
+}
+
static int lenovo_features_set_tpkbd(struct hid_device *hdev)
{
struct hid_report *report;
@@ -674,6 +722,7 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
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;
cptkbd_data->sensitivity = 0x05;
lenovo_features_set_cptkbd(hdev);
@@ -781,6 +830,7 @@ static struct hid_driver lenovo_driver = {
.probe = lenovo_probe,
.remove = lenovo_remove,
.raw_event = lenovo_raw_event,
+ .event = lenovo_event,
};
module_hid_driver(lenovo_driver);

--
2.1.4

0 comments on commit bd4f05d

Please sign in to comment.