aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamie Lentin <jm@lentin.co.uk>2014-12-16 16:26:46 -0500
committerJiri Kosina <jkosina@suse.cz>2014-12-17 03:00:16 -0500
commit94eefa27132358434735060c6bbdf61c669bb0ab (patch)
tree00f6a4d763d52223c19a992d1b9c8a4c150ba7a7
parente3cb0acd23258cf5e1a7ea270c98805eff01dcc5 (diff)
HID: lenovo: Use native middle-button mode for compact keyboards
By default the middle button is in a compatibility mode, and generates standard wheel events when dragging with the middle trackpoint button. Unfortunately this is buggy: * The middle button comes up before starting wheel events, causing a middle click on whatever the mouse cursor was sitting on * The USB keyboard always generates the "native" horizontal wheel event, regardless of mode. Instead, enable the "native" mode the Windows driver uses, and add support for the custom events this generates. This fixes the USB keyboard wheel events, and the middle-click up event comes after the wheel events. Signed-off-by: Jamie Lentin <jm@lentin.co.uk> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-lenovo.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index 0f35a76d9c90..c4c3f0952521 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -92,6 +92,38 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev,
92 case 0x00fa: /* Fn-Esc: Fn-lock toggle */ 92 case 0x00fa: /* Fn-Esc: Fn-lock toggle */
93 map_key_clear(KEY_FN_ESC); 93 map_key_clear(KEY_FN_ESC);
94 return 1; 94 return 1;
95 case 0x00fb: /* Middle mouse button (in native mode) */
96 map_key_clear(BTN_MIDDLE);
97 return 1;
98 }
99 }
100
101 /* Compatibility middle/wheel mappings should be ignored */
102 if (usage->hid == HID_GD_WHEEL)
103 return -1;
104 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON &&
105 (usage->hid & HID_USAGE) == 0x003)
106 return -1;
107 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER &&
108 (usage->hid & HID_USAGE) == 0x238)
109 return -1;
110
111 /* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */
112 if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 ||
113 (usage->hid & HID_USAGE_PAGE) == 0xffa10000) {
114 field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE;
115 field->logical_minimum = -127;
116 field->logical_maximum = 127;
117
118 switch (usage->hid & HID_USAGE) {
119 case 0x0000:
120 hid_map_usage(hi, usage, bit, max, EV_REL, 0x06);
121 return 1;
122 case 0x0001:
123 hid_map_usage(hi, usage, bit, max, EV_REL, 0x08);
124 return 1;
125 default:
126 return -1;
95 } 127 }
96 } 128 }
97 129
@@ -633,6 +665,11 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
633 if (ret) 665 if (ret)
634 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 666 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
635 667
668 /* Switch middle button to native mode */
669 ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01);
670 if (ret)
671 hid_warn(hdev, "Failed to switch middle button: %d\n", ret);
672
636 /* Set keyboard settings to known state */ 673 /* Set keyboard settings to known state */
637 cptkbd_data->fn_lock = true; 674 cptkbd_data->fn_lock = true;
638 cptkbd_data->sensitivity = 0x05; 675 cptkbd_data->sensitivity = 0x05;