aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 14:58:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 14:58:49 -0400
commit4637f40f200063973553ce3c4c1ac6c247e4535c (patch)
treeff317a0dfb67cae313a208d120edd5102730044d /drivers/input/mouse
parent5129df03d0c44b2d5a5f9d7d52f3b079706b9a8f (diff)
parentb73077eb03f510a84b102fb97640e595a958403c (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (40 commits) Input: ADP5589 - new driver for I2C Keypad Decoder and I/O Expander Input: tsc2007 - add X, Y and Z fuzz factors to platform data Input: tsc2007 - add poll_period parameter to platform data Input: tsc2007 - add poll_delay parameter to platform data Input: tsc2007 - add max_rt parameter to platform data Input: tsc2007 - debounce pressure measurement Input: ad714x - fix captouch wheel option algorithm Input: ad714x - allow platform code to specify irqflags Input: ad714x - fix threshold and completion interrupt masks Input: ad714x - fix up input configuration Input: elantech - remove support for proprietary X driver Input: elantech - report multitouch with proper ABS_MT messages Input: elantech - export pressure and width when supported Input: elantech - describe further the protocol Input: atmel_tsadcc - correct call to input_free_device Input: add driver FSL MPR121 capacitive touch sensor Input: remove useless synchronize_rcu() calls Input: ads7846 - fix gpio_pendown configuration Input: ads7846 - add possibility to use external vref on ads7846 Input: rotary-encoder - add support for half-period encoders ...
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/elantech.c72
-rw-r--r--drivers/input/mouse/elantech.h6
2 files changed, 61 insertions, 17 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 04d9bf320a4f..32503565faf9 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -16,6 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/input.h> 18#include <linux/input.h>
19#include <linux/input/mt.h>
19#include <linux/serio.h> 20#include <linux/serio.h>
20#include <linux/libps2.h> 21#include <linux/libps2.h>
21#include "psmouse.h" 22#include "psmouse.h"
@@ -242,15 +243,37 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
242 input_sync(dev); 243 input_sync(dev);
243} 244}
244 245
246static void elantech_set_slot(struct input_dev *dev, int slot, bool active,
247 unsigned int x, unsigned int y)
248{
249 input_mt_slot(dev, slot);
250 input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
251 if (active) {
252 input_report_abs(dev, ABS_MT_POSITION_X, x);
253 input_report_abs(dev, ABS_MT_POSITION_Y, y);
254 }
255}
256
257/* x1 < x2 and y1 < y2 when two fingers, x = y = 0 when not pressed */
258static void elantech_report_semi_mt_data(struct input_dev *dev,
259 unsigned int num_fingers,
260 unsigned int x1, unsigned int y1,
261 unsigned int x2, unsigned int y2)
262{
263 elantech_set_slot(dev, 0, num_fingers != 0, x1, y1);
264 elantech_set_slot(dev, 1, num_fingers == 2, x2, y2);
265}
266
245/* 267/*
246 * Interpret complete data packets and report absolute mode input events for 268 * Interpret complete data packets and report absolute mode input events for
247 * hardware version 2. (6 byte packets) 269 * hardware version 2. (6 byte packets)
248 */ 270 */
249static void elantech_report_absolute_v2(struct psmouse *psmouse) 271static void elantech_report_absolute_v2(struct psmouse *psmouse)
250{ 272{
273 struct elantech_data *etd = psmouse->private;
251 struct input_dev *dev = psmouse->dev; 274 struct input_dev *dev = psmouse->dev;
252 unsigned char *packet = psmouse->packet; 275 unsigned char *packet = psmouse->packet;
253 int fingers, x1, y1, x2, y2; 276 unsigned int fingers, x1 = 0, y1 = 0, x2 = 0, y2 = 0, width = 0, pres = 0;
254 277
255 /* byte 0: n1 n0 . . . . R L */ 278 /* byte 0: n1 n0 . . . . R L */
256 fingers = (packet[0] & 0xc0) >> 6; 279 fingers = (packet[0] & 0xc0) >> 6;
@@ -270,14 +293,18 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
270 * byte 1: . . . . . x10 x9 x8 293 * byte 1: . . . . . x10 x9 x8
271 * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 294 * byte 2: x7 x6 x5 x4 x4 x2 x1 x0
272 */ 295 */
273 input_report_abs(dev, ABS_X, 296 x1 = ((packet[1] & 0x07) << 8) | packet[2];
274 ((packet[1] & 0x07) << 8) | packet[2]);
275 /* 297 /*
276 * byte 4: . . . . . . y9 y8 298 * byte 4: . . . . . . y9 y8
277 * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 299 * byte 5: y7 y6 y5 y4 y3 y2 y1 y0
278 */ 300 */
279 input_report_abs(dev, ABS_Y, 301 y1 = ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]);
280 ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5])); 302
303 input_report_abs(dev, ABS_X, x1);
304 input_report_abs(dev, ABS_Y, y1);
305
306 pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
307 width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
281 break; 308 break;
282 309
283 case 2: 310 case 2:
@@ -303,23 +330,24 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
303 */ 330 */
304 input_report_abs(dev, ABS_X, x1 << 2); 331 input_report_abs(dev, ABS_X, x1 << 2);
305 input_report_abs(dev, ABS_Y, y1 << 2); 332 input_report_abs(dev, ABS_Y, y1 << 2);
306 /* 333
307 * For compatibility with the proprietary X Elantech driver 334 /* Unknown so just report sensible values */
308 * report both coordinates as hat coordinates 335 pres = 127;
309 */ 336 width = 7;
310 input_report_abs(dev, ABS_HAT0X, x1);
311 input_report_abs(dev, ABS_HAT0Y, y1);
312 input_report_abs(dev, ABS_HAT1X, x2);
313 input_report_abs(dev, ABS_HAT1Y, y2);
314 break; 337 break;
315 } 338 }
316 339
340 elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
317 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); 341 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
318 input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); 342 input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
319 input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); 343 input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
320 input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); 344 input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
321 input_report_key(dev, BTN_LEFT, packet[0] & 0x01); 345 input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
322 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); 346 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
347 if (etd->reports_pressure) {
348 input_report_abs(dev, ABS_PRESSURE, pres);
349 input_report_abs(dev, ABS_TOOL_WIDTH, width);
350 }
323 351
324 input_sync(dev); 352 input_sync(dev);
325} 353}
@@ -478,10 +506,16 @@ static void elantech_set_input_params(struct psmouse *psmouse)
478 __set_bit(BTN_TOOL_QUADTAP, dev->keybit); 506 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
479 input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); 507 input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
480 input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); 508 input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
481 input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0); 509 if (etd->reports_pressure) {
482 input_set_abs_params(dev, ABS_HAT0Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0); 510 input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2,
483 input_set_abs_params(dev, ABS_HAT1X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0); 511 ETP_PMAX_V2, 0, 0);
484 input_set_abs_params(dev, ABS_HAT1Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0); 512 input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
513 ETP_WMAX_V2, 0, 0);
514 }
515 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
516 input_mt_init_slots(dev, 2);
517 input_set_abs_params(dev, ABS_MT_POSITION_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
518 input_set_abs_params(dev, ABS_MT_POSITION_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
485 break; 519 break;
486 } 520 }
487} 521}
@@ -725,6 +759,10 @@ int elantech_init(struct psmouse *psmouse)
725 etd->debug = 1; 759 etd->debug = 1;
726 /* Don't know how to do parity checking for version 2 */ 760 /* Don't know how to do parity checking for version 2 */
727 etd->paritycheck = 0; 761 etd->paritycheck = 0;
762
763 if (etd->fw_version >= 0x020800)
764 etd->reports_pressure = true;
765
728 } else { 766 } else {
729 etd->hw_version = 1; 767 etd->hw_version = 1;
730 etd->paritycheck = 1; 768 etd->paritycheck = 1;
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index aa4aac5d2198..fabb2b99615c 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -77,6 +77,11 @@
77#define ETP_YMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2) 77#define ETP_YMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2)
78#define ETP_YMAX_V2 ( 768 - ETP_EDGE_FUZZ_V2) 78#define ETP_YMAX_V2 ( 768 - ETP_EDGE_FUZZ_V2)
79 79
80#define ETP_PMIN_V2 0
81#define ETP_PMAX_V2 255
82#define ETP_WMIN_V2 0
83#define ETP_WMAX_V2 15
84
80/* 85/*
81 * For two finger touches the coordinate of each finger gets reported 86 * For two finger touches the coordinate of each finger gets reported
82 * separately but with reduced resolution. 87 * separately but with reduced resolution.
@@ -102,6 +107,7 @@ struct elantech_data {
102 unsigned char capabilities; 107 unsigned char capabilities;
103 bool paritycheck; 108 bool paritycheck;
104 bool jumpy_cursor; 109 bool jumpy_cursor;
110 bool reports_pressure;
105 unsigned char hw_version; 111 unsigned char hw_version;
106 unsigned int fw_version; 112 unsigned int fw_version;
107 unsigned int single_finger_reports; 113 unsigned int single_finger_reports;