aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJJ Ding <jj_ding@emc.com.tw>2011-09-09 13:26:16 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-09-09 13:34:36 -0400
commit230282a77bcec97f4d0a54e50a44caab5eb39d5c (patch)
tree4944a12840bb35cabeef7b63803ed8cb0f4bab1c /drivers
parent461a791765da501f73e3d5957788267101e800d2 (diff)
Input: elantech - use firmware provided x, y ranges
With newer hardware, the touchpad provides range info. Let's use it. Signed-off-by: JJ Ding <jj_ding@emc.com.tw> Acked-by: Daniel Kurtz <djkurtz@chromium.org> Acked-by: Éric Piel <eric.piel@tremplin-utc.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/mouse/elantech.c71
-rw-r--r--drivers/input/mouse/elantech.h3
2 files changed, 58 insertions, 16 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index cd8e2e5ced86..296b6a6250fd 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -223,7 +223,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
223 input_report_abs(dev, ABS_X, 223 input_report_abs(dev, ABS_X,
224 ((packet[1] & 0x0c) << 6) | packet[2]); 224 ((packet[1] & 0x0c) << 6) | packet[2]);
225 input_report_abs(dev, ABS_Y, 225 input_report_abs(dev, ABS_Y,
226 ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3])); 226 etd->y_max - (((packet[1] & 0x03) << 8) | packet[3]));
227 } 227 }
228 228
229 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); 229 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
@@ -233,7 +233,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
233 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); 233 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
234 234
235 if (etd->fw_version < 0x020000 && 235 if (etd->fw_version < 0x020000 &&
236 (etd->capabilities & ETP_CAP_HAS_ROCKER)) { 236 (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) {
237 /* rocker up */ 237 /* rocker up */
238 input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); 238 input_report_key(dev, BTN_FORWARD, packet[0] & 0x40);
239 /* rocker down */ 239 /* rocker down */
@@ -298,7 +298,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
298 * byte 4: . . . . y11 y10 y9 y8 298 * byte 4: . . . . y11 y10 y9 y8
299 * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 299 * byte 5: y7 y6 y5 y4 y3 y2 y1 y0
300 */ 300 */
301 y1 = ETP_YMAX_V2 - (((packet[4] & 0x0f) << 8) | packet[5]); 301 y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
302 302
303 pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); 303 pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
304 width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4); 304 width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
@@ -313,7 +313,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
313 */ 313 */
314 x1 = (((packet[0] & 0x10) << 4) | packet[1]) << 2; 314 x1 = (((packet[0] & 0x10) << 4) | packet[1]) << 2;
315 /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ 315 /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
316 y1 = ETP_YMAX_V2 - 316 y1 = etd->y_max -
317 ((((packet[0] & 0x20) << 3) | packet[2]) << 2); 317 ((((packet[0] & 0x20) << 3) | packet[2]) << 2);
318 /* 318 /*
319 * byte 3: . . by8 bx8 . . . . 319 * byte 3: . . by8 bx8 . . . .
@@ -321,7 +321,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
321 */ 321 */
322 x2 = (((packet[3] & 0x10) << 4) | packet[4]) << 2; 322 x2 = (((packet[3] & 0x10) << 4) | packet[4]) << 2;
323 /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ 323 /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
324 y2 = ETP_YMAX_V2 - 324 y2 = etd->y_max -
325 ((((packet[3] & 0x20) << 3) | packet[5]) << 2); 325 ((((packet[3] & 0x20) << 3) | packet[5]) << 2);
326 326
327 /* Unknown so just report sensible values */ 327 /* Unknown so just report sensible values */
@@ -468,6 +468,41 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
468 return rc; 468 return rc;
469} 469}
470 470
471static void elantech_set_range(struct psmouse *psmouse,
472 unsigned int *x_min, unsigned int *y_min,
473 unsigned int *x_max, unsigned int *y_max)
474{
475 struct elantech_data *etd = psmouse->private;
476 int i;
477
478 switch (etd->hw_version) {
479 case 1:
480 *x_min = ETP_XMIN_V1;
481 *y_min = ETP_YMIN_V1;
482 *x_max = ETP_XMAX_V1;
483 *y_max = ETP_YMAX_V1;
484 break;
485
486 case 2:
487 if (etd->fw_version == 0x020800 ||
488 etd->fw_version == 0x020b00 ||
489 etd->fw_version == 0x020030) {
490 *x_min = ETP_XMIN_V2;
491 *y_min = ETP_YMIN_V2;
492 *x_max = ETP_XMAX_V2;
493 *y_max = ETP_YMAX_V2;
494 } else {
495 i = (etd->fw_version > 0x020800 &&
496 etd->fw_version < 0x020900) ? 1 : 2;
497 *x_min = 0;
498 *y_min = 0;
499 *x_max = (etd->capabilities[1] - i) * 64;
500 *y_max = (etd->capabilities[2] - i) * 64;
501 }
502 break;
503 }
504}
505
471/* 506/*
472 * Set the appropriate event bits for the input subsystem 507 * Set the appropriate event bits for the input subsystem
473 */ 508 */
@@ -475,6 +510,9 @@ static void elantech_set_input_params(struct psmouse *psmouse)
475{ 510{
476 struct input_dev *dev = psmouse->dev; 511 struct input_dev *dev = psmouse->dev;
477 struct elantech_data *etd = psmouse->private; 512 struct elantech_data *etd = psmouse->private;
513 unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0;
514
515 elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max);
478 516
479 __set_bit(EV_KEY, dev->evbit); 517 __set_bit(EV_KEY, dev->evbit);
480 __set_bit(EV_ABS, dev->evbit); 518 __set_bit(EV_ABS, dev->evbit);
@@ -492,18 +530,18 @@ static void elantech_set_input_params(struct psmouse *psmouse)
492 case 1: 530 case 1:
493 /* Rocker button */ 531 /* Rocker button */
494 if (etd->fw_version < 0x020000 && 532 if (etd->fw_version < 0x020000 &&
495 (etd->capabilities & ETP_CAP_HAS_ROCKER)) { 533 (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) {
496 __set_bit(BTN_FORWARD, dev->keybit); 534 __set_bit(BTN_FORWARD, dev->keybit);
497 __set_bit(BTN_BACK, dev->keybit); 535 __set_bit(BTN_BACK, dev->keybit);
498 } 536 }
499 input_set_abs_params(dev, ABS_X, ETP_XMIN_V1, ETP_XMAX_V1, 0, 0); 537 input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
500 input_set_abs_params(dev, ABS_Y, ETP_YMIN_V1, ETP_YMAX_V1, 0, 0); 538 input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
501 break; 539 break;
502 540
503 case 2: 541 case 2:
504 __set_bit(BTN_TOOL_QUADTAP, dev->keybit); 542 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
505 input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); 543 input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
506 input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); 544 input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
507 if (etd->reports_pressure) { 545 if (etd->reports_pressure) {
508 input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, 546 input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2,
509 ETP_PMAX_V2, 0, 0); 547 ETP_PMAX_V2, 0, 0);
@@ -512,10 +550,12 @@ static void elantech_set_input_params(struct psmouse *psmouse)
512 } 550 }
513 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); 551 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
514 input_mt_init_slots(dev, 2); 552 input_mt_init_slots(dev, 2);
515 input_set_abs_params(dev, ABS_MT_POSITION_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); 553 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
516 input_set_abs_params(dev, ABS_MT_POSITION_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); 554 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
517 break; 555 break;
518 } 556 }
557
558 etd->y_max = y_max;
519} 559}
520 560
521struct elantech_attr_data { 561struct elantech_attr_data {
@@ -769,13 +809,14 @@ int elantech_init(struct psmouse *psmouse)
769 pr_info("assuming hardware version %d, firmware version %d.%d.%d\n", 809 pr_info("assuming hardware version %d, firmware version %d.%d.%d\n",
770 etd->hw_version, param[0], param[1], param[2]); 810 etd->hw_version, param[0], param[1], param[2]);
771 811
772 if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { 812 if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
813 etd->capabilities)) {
773 pr_err("failed to query capabilities.\n"); 814 pr_err("failed to query capabilities.\n");
774 goto init_fail; 815 goto init_fail;
775 } 816 }
776 pr_info("Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", 817 pr_info("Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n",
777 param[0], param[1], param[2]); 818 etd->capabilities[0], etd->capabilities[1],
778 etd->capabilities = param[0]; 819 etd->capabilities[2]);
779 820
780 /* 821 /*
781 * This firmware suffers from misreporting coordinates when 822 * This firmware suffers from misreporting coordinates when
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index 1c5894efda5a..b54ea27d10af 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -93,13 +93,14 @@ struct elantech_data {
93 unsigned char reg_25; 93 unsigned char reg_25;
94 unsigned char reg_26; 94 unsigned char reg_26;
95 unsigned char debug; 95 unsigned char debug;
96 unsigned char capabilities; 96 unsigned char capabilities[3];
97 bool paritycheck; 97 bool paritycheck;
98 bool jumpy_cursor; 98 bool jumpy_cursor;
99 bool reports_pressure; 99 bool reports_pressure;
100 unsigned char hw_version; 100 unsigned char hw_version;
101 unsigned int fw_version; 101 unsigned int fw_version;
102 unsigned int single_finger_reports; 102 unsigned int single_finger_reports;
103 unsigned int y_max;
103 unsigned char parity[256]; 104 unsigned char parity[256];
104}; 105};
105 106