aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2018-07-11 06:38:31 -0400
committerJiri Kosina <jkosina@suse.cz>2018-07-17 09:25:39 -0400
commit2f612de2d67dca26191e6c3db544f4c30beb6838 (patch)
tree98f07c15e8bcb61e816c85338e75c87f62a44de1
parentf109b43ad9af6b5a003b6619cb2242fde19009ce (diff)
HID: elan: Correctly report MT_PRESSURE instead of TOOL_WIDTH
Elan has given me a (GPL-ed) Android driver for their non HID-mt touchpads to help improve the upstream support. Acoording to Elan what we are currently reporting as tool-width really is a per-touch pressure. This always has a maximum of 255, so there is no need to make the max configurable. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-elan.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/hid/hid-elan.c b/drivers/hid/hid-elan.c
index 907b724b9435..d0971f5e5523 100644
--- a/drivers/hid/hid-elan.c
+++ b/drivers/hid/hid-elan.c
@@ -23,6 +23,7 @@
23#define ELAN_MT_FIRST_FINGER 0x82 23#define ELAN_MT_FIRST_FINGER 0x82
24#define ELAN_MT_SECOND_FINGER 0x83 24#define ELAN_MT_SECOND_FINGER 0x83
25#define ELAN_INPUT_REPORT_SIZE 8 25#define ELAN_INPUT_REPORT_SIZE 8
26#define ELAN_MAX_PRESSURE 255
26 27
27#define ELAN_MUTE_LED_REPORT 0xBC 28#define ELAN_MUTE_LED_REPORT 0xBC
28#define ELAN_LED_REPORT_SIZE 8 29#define ELAN_LED_REPORT_SIZE 8
@@ -31,7 +32,6 @@ struct elan_touchpad_settings {
31 u8 max_fingers; 32 u8 max_fingers;
32 u16 max_x; 33 u16 max_x;
33 u16 max_y; 34 u16 max_y;
34 u8 max_w;
35 int usb_bInterfaceNumber; 35 int usb_bInterfaceNumber;
36}; 36};
37 37
@@ -92,8 +92,8 @@ static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi)
92 drvdata->settings->max_x, 0, 0); 92 drvdata->settings->max_x, 0, 0);
93 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 93 input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
94 drvdata->settings->max_y, 0, 0); 94 drvdata->settings->max_y, 0, 0);
95 input_set_abs_params(input, ABS_TOOL_WIDTH, 0, 95 input_set_abs_params(input, ABS_MT_PRESSURE, 0, ELAN_MAX_PRESSURE,
96 drvdata->settings->max_w, 0, 0); 96 0, 0);
97 97
98 __set_bit(BTN_LEFT, input->keybit); 98 __set_bit(BTN_LEFT, input->keybit);
99 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 99 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
@@ -122,7 +122,7 @@ static void elan_report_mt_slot(struct elan_drvdata *drvdata, u8 *data,
122 unsigned int slot_num) 122 unsigned int slot_num)
123{ 123{
124 struct input_dev *input = drvdata->input; 124 struct input_dev *input = drvdata->input;
125 int x, y, w; 125 int x, y, p;
126 126
127 bool active = !!data; 127 bool active = !!data;
128 128
@@ -132,11 +132,11 @@ static void elan_report_mt_slot(struct elan_drvdata *drvdata, u8 *data,
132 x = ((data[0] & 0xF0) << 4) | data[1]; 132 x = ((data[0] & 0xF0) << 4) | data[1];
133 y = drvdata->settings->max_y - 133 y = drvdata->settings->max_y -
134 (((data[0] & 0x07) << 8) | data[2]); 134 (((data[0] & 0x07) << 8) | data[2]);
135 w = data[4]; 135 p = data[4];
136 136
137 input_report_abs(input, ABS_MT_POSITION_X, x); 137 input_report_abs(input, ABS_MT_POSITION_X, x);
138 input_report_abs(input, ABS_MT_POSITION_Y, y); 138 input_report_abs(input, ABS_MT_POSITION_Y, y);
139 input_report_abs(input, ABS_TOOL_WIDTH, w); 139 input_report_abs(input, ABS_MT_PRESSURE, p);
140 } 140 }
141} 141}
142 142
@@ -158,7 +158,7 @@ static void elan_report_input(struct elan_drvdata *drvdata, u8 *data)
158 * byte 5: x8 x7 x6 x5 x4 x3 x2 x1 158 * byte 5: x8 x7 x6 x5 x4 x3 x2 x1
159 * byte 6: y8 y7 y6 y5 y4 y3 y2 y1 159 * byte 6: y8 y7 y6 y5 y4 y3 y2 y1
160 * byte 7: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1 160 * byte 7: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1
161 * byte 8: w8 w7 w6 w5 w4 w3 w2 w1 161 * byte 8: p8 p7 p6 p5 p4 p3 p2 p1
162 * 162 *
163 * packet structure for ELAN_MT_SECOND_FINGER: 163 * packet structure for ELAN_MT_SECOND_FINGER:
164 * 164 *
@@ -167,15 +167,17 @@ static void elan_report_input(struct elan_drvdata *drvdata, u8 *data)
167 * byte 3: x8 x7 x6 x5 x4 x3 x2 x1 167 * byte 3: x8 x7 x6 x5 x4 x3 x2 x1
168 * byte 4: y8 y7 y6 y5 y4 y3 y2 y1 168 * byte 4: y8 y7 y6 y5 y4 y3 y2 y1
169 * byte 5: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1 169 * byte 5: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1
170 * byte 6: w8 w7 w6 w5 w4 w3 w2 w1 170 * byte 6: p8 p7 p6 p5 p4 p3 p2 p1
171 * byte 7: 0 0 0 0 0 0 0 0 171 * byte 7: 0 0 0 0 0 0 0 0
172 * byte 8: 0 0 0 0 0 0 0 0 172 * byte 8: 0 0 0 0 0 0 0 0
173 * 173 *
174 * f5-f1: finger touch bits 174 * f5-f1: finger touch bits
175 * L: clickpad button 175 * L: clickpad button
176 * sy / sx: not sure yet, but this looks like rectangular 176 * sy / sx: finger width / height expressed in traces, the total number
177 * area for finger 177 * of traces can be queried by doing a HID_REQ_SET_REPORT
178 * w: looks like finger width 178 * { 0x0d, 0x05, 0x03, 0x05, 0x01 } followed by a GET, in the
179 * returned buf, buf[3]=no-x-traces, buf[4]=no-y-traces.
180 * p: pressure
179 */ 181 */
180 182
181 if (data[0] == ELAN_SINGLE_FINGER) { 183 if (data[0] == ELAN_SINGLE_FINGER) {
@@ -386,7 +388,6 @@ static const struct elan_touchpad_settings hp_x2_10_touchpad_data = {
386 .max_fingers = 5, 388 .max_fingers = 5,
387 .max_x = 2930, 389 .max_x = 2930,
388 .max_y = 1250, 390 .max_y = 1250,
389 .max_w = 255,
390 .usb_bInterfaceNumber = 1, 391 .usb_bInterfaceNumber = 1,
391}; 392};
392 393