/[linux-patches]/genpatches-2.6/tags/3.0-14/2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch
Gentoo

Diff of /genpatches-2.6/tags/3.0-14/2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

genpatches-2.6/trunk/3.0/2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch Revision 1984 genpatches-2.6/tags/3.0-14/2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch Revision 2038
1From eb431563c721ef18736a36462e669062821702c5 Mon Sep 17 00:00:00 2001 1From 0d2064f77fc5b1d983a0b6bf39b08c36d7b58d68 Mon Sep 17 00:00:00 2001
2From: Seth Forshee <seth.forshee@canonical.com> 2From: Seth Forshee <seth.forshee@canonical.com>
3Date: Wed, 14 Sep 2011 11:40:39 -0500 3Date: Wed, 14 Sep 2011 11:40:39 -0500
4Subject: [PATCH 5/8] Input: ALPS - Add support for protocol versions 3 and 4 4Subject: [PATCH 5/8] Input: ALPS - Add support for protocol versions 3 and 4
5 5
6Currently only single-touch, multi-touch to be added in the future. 6This patch adds support for two ALPS touchpad protocols not
7supported currently by the driver, which I am arbitrarily naming
8version 3 and version 4. Support is single-touch only at this time,
9although both protocols are capable of limited multitouch support.
10
11Thanks to Andrew Skalski, who did the initial reverse-engineering
12of the v3 protocol.
13
14Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
7--- 15---
8 drivers/input/mouse/alps.c | 792 +++++++++++++++++++++++++++++++++++++++++--- 16 drivers/input/mouse/alps.c | 787 +++++++++++++++++++++++++++++++++++++++++---
9 drivers/input/mouse/alps.h | 14 + 17 drivers/input/mouse/alps.h | 14 +
10 2 files changed, 768 insertions(+), 38 deletions(-) 18 2 files changed, 763 insertions(+), 38 deletions(-)
11 19
12diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c 20diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
13index 14d1f64..43949d4 100644 21index 14d1f64..8419c14 100644
14--- a/drivers/input/mouse/alps.c 22--- a/drivers/input/mouse/alps.c
15+++ b/drivers/input/mouse/alps.c 23+++ b/drivers/input/mouse/alps.c
16@@ -30,6 +30,50 @@ 24@@ -30,6 +30,50 @@
17 #define dbg(format, arg...) do {} while (0) 25 #define dbg(format, arg...) do {} while (0)
18 #endif 26 #endif
127-static void alps_process_packet(struct psmouse *psmouse) 135-static void alps_process_packet(struct psmouse *psmouse)
128+static void alps_process_packet_v1_v2(struct psmouse *psmouse) 136+static void alps_process_packet_v1_v2(struct psmouse *psmouse)
129 { 137 {
130 struct alps_data *priv = psmouse->private; 138 struct alps_data *priv = psmouse->private;
131 const struct alps_model_info *model = priv->i; 139 const struct alps_model_info *model = priv->i;
132@@ -210,6 +257,206 @@ static void alps_process_packet(struct psmouse *psmouse) 140@@ -210,6 +257,226 @@ static void alps_process_packet(struct psmouse *psmouse)
133 input_sync(dev); 141 input_sync(dev);
134 } 142 }
135 143
136+static void alps_process_trackstick_packet_v3(struct psmouse *psmouse) 144+static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
137+{ 145+{
166+ y /= 8; 174+ y /= 8;
167+ 175+
168+ input_report_rel(dev, REL_X, x); 176+ input_report_rel(dev, REL_X, x);
169+ input_report_rel(dev, REL_Y, -y); 177+ input_report_rel(dev, REL_Y, -y);
170+ 178+
179+ /*
180+ * Most ALPS models report the trackstick buttons in the touchpad
181+ * packets, but a few report them here. No reliable way has been
182+ * found to differentiate between the models upfront, so we enable
183+ * the quirk in response to seeing a button press in the trackstick
184+ * packet.
185+ */
186+ left = packet[3] & 0x01;
187+ right = packet[3] & 0x02;
188+ middle = packet[3] & 0x04;
189+
190+ if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) &&
191+ (left || right || middle))
192+ priv->quirks |= ALPS_QUIRK_TRACKSTICK_BUTTONS;
193+
171+ if (priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) { 194+ if (priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) {
172+ left = packet[3] & 0x01;
173+ right = packet[3] & 0x02;
174+ middle = packet[3] & 0x04;
175+
176+ input_report_key(dev, BTN_LEFT, left); 195+ input_report_key(dev, BTN_LEFT, left);
177+ input_report_key(dev, BTN_RIGHT, right); 196+ input_report_key(dev, BTN_RIGHT, right);
178+ input_report_key(dev, BTN_MIDDLE, middle); 197+ input_report_key(dev, BTN_MIDDLE, middle);
179+ } 198+ }
180+ 199+
227+ x = ((packet[1] & 0x7f) << 4) | ((packet[4] & 0x30) >> 2) | 246+ x = ((packet[1] & 0x7f) << 4) | ((packet[4] & 0x30) >> 2) |
228+ ((packet[0] & 0x30) >> 4); 247+ ((packet[0] & 0x30) >> 4);
229+ y = ((packet[2] & 0x7f) << 4) | (packet[4] & 0x0f); 248+ y = ((packet[2] & 0x7f) << 4) | (packet[4] & 0x0f);
230+ z = packet[5] & 0x7f; 249+ z = packet[5] & 0x7f;
231+ 250+
251+ /*
252+ * Sometimes the hardware sends a single packet with z = 0
253+ * in the middle of a stream. Real releases generate packets
254+ * with x, y, and z all zero, so these seem to be flukes.
255+ * Ignore them.
256+ */
257+ if (x && y && !z)
258+ return;
259+
232+ if (z >= 64) { 260+ if (z >= 64) {
233+ input_report_key(dev, BTN_TOUCH, 1); 261+ input_report_key(dev, BTN_TOUCH, 1);
234+ } else { 262+ } else {
235+ input_report_key(dev, BTN_TOUCH, 0); 263+ input_report_key(dev, BTN_TOUCH, 0);
236+ } 264+ }
334+} 362+}
335+ 363+
336 static void alps_report_bare_ps2_packet(struct psmouse *psmouse, 364 static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
337 unsigned char packet[], 365 unsigned char packet[],
338 bool report_buttons) 366 bool report_buttons)
339@@ -381,11 +628,126 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) 367@@ -381,11 +648,126 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
340 return PSMOUSE_GOOD_DATA; 368 return PSMOUSE_GOOD_DATA;
341 } 369 }
342 370
343+static int alps_command_mode_send_nibble(struct psmouse *psmouse, int nibble) 371+static int alps_command_mode_send_nibble(struct psmouse *psmouse, int nibble)
344+{ 372+{
461 unsigned char param[4]; 489 unsigned char param[4];
462+ const struct alps_model_info *model = NULL; 490+ const struct alps_model_info *model = NULL;
463 int i; 491 int i;
464 492
465 /* 493 /*
466@@ -431,12 +793,38 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int 494@@ -431,12 +813,38 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
467 *version = (param[0] << 8) | (param[1] << 4) | i; 495 *version = (param[0] << 8) | (param[1] << 4) | i;
468 } 496 }
469 497
470- for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) 498- for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
471+ for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) { 499+ for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
475+ sizeof(alps_model_data[i].signature))) { 503+ sizeof(alps_model_data[i].signature))) {
476+ model = alps_model_data + i; 504+ model = alps_model_data + i;
477+ break; 505+ break;
478+ } 506+ }
479+ } 507+ }
480 508+
481- return NULL;
482+ if (model && model->proto_version > ALPS_PROTO_V2) { 509+ if (model && model->proto_version > ALPS_PROTO_V2) {
483+ /* 510+ /*
484+ * Need to check command mode response to identify 511+ * Need to check command mode response to identify
485+ * model 512+ * model
486+ */ 513+ */
499+ 526+
500+ if (!model) 527+ if (!model)
501+ pr_debug("alps.c: Unknown command mode response %2.2x\n", param[0]); 528+ pr_debug("alps.c: Unknown command mode response %2.2x\n", param[0]);
502+ } 529+ }
503+ } 530+ }
504+ 531
532- return NULL;
505+ return model; 533+ return model;
506 } 534 }
507 535
508 /* 536 /*
509@@ -444,7 +832,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int 537@@ -444,7 +852,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
510 * subsequent commands. It looks like glidepad is behind stickpointer, 538 * subsequent commands. It looks like glidepad is behind stickpointer,
511 * I'd thought it would be other way around... 539 * I'd thought it would be other way around...
512 */ 540 */
513-static int alps_passthrough_mode(struct psmouse *psmouse, bool enable) 541-static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
514+static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable) 542+static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable)
515 { 543 {
516 struct ps2dev *ps2dev = &psmouse->ps2dev; 544 struct ps2dev *ps2dev = &psmouse->ps2dev;
517 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; 545 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
518@@ -461,7 +849,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, bool enable) 546@@ -461,7 +869,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
519 return 0; 547 return 0;
520 } 548 }
521 549
522-static int alps_absolute_mode(struct psmouse *psmouse) 550-static int alps_absolute_mode(struct psmouse *psmouse)
523+static int alps_absolute_mode_v1_v2(struct psmouse *psmouse) 551+static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
524 { 552 {
525 struct ps2dev *ps2dev = &psmouse->ps2dev; 553 struct ps2dev *ps2dev = &psmouse->ps2dev;
526 554
527@@ -540,13 +928,13 @@ static int alps_poll(struct psmouse *psmouse) 555@@ -540,13 +948,13 @@ static int alps_poll(struct psmouse *psmouse)
528 return -1; 556 return -1;
529 557
530 if (priv->i->flags & ALPS_PASS) 558 if (priv->i->flags & ALPS_PASS)
531- alps_passthrough_mode(psmouse, true); 559- alps_passthrough_mode(psmouse, true);
532+ alps_passthrough_mode_v2(psmouse, true); 560+ alps_passthrough_mode_v2(psmouse, true);
538- alps_passthrough_mode(psmouse, false); 566- alps_passthrough_mode(psmouse, false);
539+ alps_passthrough_mode_v2(psmouse, false); 567+ alps_passthrough_mode_v2(psmouse, false);
540 568
541 if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) 569 if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
542 goto out; 570 goto out;
543@@ -567,13 +955,13 @@ out: 571@@ -567,13 +975,13 @@ out:
544 return ret; 572 return ret;
545 } 573 }
546 574
547-static int alps_hw_init(struct psmouse *psmouse) 575-static int alps_hw_init(struct psmouse *psmouse)
548+static int alps_hw_init_v1_v2(struct psmouse *psmouse) 576+static int alps_hw_init_v1_v2(struct psmouse *psmouse)
554- alps_passthrough_mode(psmouse, true)) { 582- alps_passthrough_mode(psmouse, true)) {
555+ alps_passthrough_mode_v2(psmouse, true)) { 583+ alps_passthrough_mode_v2(psmouse, true)) {
556 return -1; 584 return -1;
557 } 585 }
558 586
559@@ -582,13 +970,13 @@ static int alps_hw_init(struct psmouse *psmouse) 587@@ -582,13 +990,13 @@ static int alps_hw_init(struct psmouse *psmouse)
560 return -1; 588 return -1;
561 } 589 }
562 590
563- if (alps_absolute_mode(psmouse)) { 591- if (alps_absolute_mode(psmouse)) {
564+ if (alps_absolute_mode_v1_v2(psmouse)) { 592+ if (alps_absolute_mode_v1_v2(psmouse)) {
570- alps_passthrough_mode(psmouse, false)) { 598- alps_passthrough_mode(psmouse, false)) {
571+ alps_passthrough_mode_v2(psmouse, false)) { 599+ alps_passthrough_mode_v2(psmouse, false)) {
572 return -1; 600 return -1;
573 } 601 }
574 602
575@@ -601,6 +989,320 @@ static int alps_hw_init(struct psmouse *psmouse) 603@@ -601,6 +1009,295 @@ static int alps_hw_init(struct psmouse *psmouse)
576 return 0; 604 return 0;
577 } 605 }
578 606
579+/* 607+/*
580+ * Enable or disable passthrough mode to the trackstick. Must be in 608+ * Enable or disable passthrough mode to the trackstick. Must be in
613+ return -1; 641+ return -1;
614+ 642+
615+ return 0; 643+ return 0;
616+} 644+}
617+ 645+
618+/*
619+ * Trackstick E7 reports for models affected by trackstick button
620+ * reporting quirk
621+ */
622+static const unsigned char trackstick_quirk_sigs[][3] = {
623+ { 0x42, 0x02, 0x14 },
624+ { 0x32, 0x01, 0x28 },
625+};
626+
627+static int alps_hw_init_v3(struct psmouse *psmouse) 646+static int alps_hw_init_v3(struct psmouse *psmouse)
628+{ 647+{
629+ struct alps_data *priv = psmouse->private; 648+ struct alps_data *priv = psmouse->private;
630+ struct ps2dev *ps2dev = &psmouse->ps2dev; 649+ struct ps2dev *ps2dev = &psmouse->ps2dev;
631+ int reg_val; 650+ int reg_val;
632+ unsigned char param[4]; 651+ unsigned char param[4];
633+ int i;
634+ 652+
635+ priv->nibble_commands = alps_v3_nibble_commands; 653+ priv->nibble_commands = alps_v3_nibble_commands;
636+ priv->addr_command = PSMOUSE_CMD_RESET_WRAP; 654+ priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
637+ 655+
638+ if (alps_enter_command_mode(psmouse, NULL)) 656+ if (alps_enter_command_mode(psmouse, NULL))
666+ } else { 684+ } else {
667+ pr_debug("alps.c: trackstick E7 report: %2.2x %2.2x %2.2x\n", 685+ pr_debug("alps.c: trackstick E7 report: %2.2x %2.2x %2.2x\n",
668+ param[0], param[1], param[2]); 686+ param[0], param[1], param[2]);
669+ 687+
670+ /* 688+ /*
671+ * Most models report trackstick buttons in the
672+ * touchpad packets, but some report them in the
673+ * trackstick packets instead. It appears we can
674+ * detect these using the trackstick E7 report.
675+ */
676+ for (i = 0; i < ARRAY_SIZE(trackstick_quirk_sigs); i++) {
677+ if (!memcmp(param, trackstick_quirk_sigs[i],
678+ sizeof(trackstick_quirk_sigs[i]))) {
679+ pr_debug("alps.c: enabling trackstick button quirk\n");
680+ priv->quirks |= ALPS_QUIRK_TRACKSTICK_BUTTONS;
681+ break;
682+ }
683+ }
684+
685+ /*
686+ * Not sure what this does, but it is absolutely 689+ * Not sure what this does, but it is absolutely
687+ * essential. Without it, the touchpad does not 690+ * essential. Without it, the touchpad does not
688+ * work at all and the trackstick just emits normal 691+ * work at all and the trackstick just emits normal
689+ * PS/2 packets. 692+ * PS/2 packets.
690+ */ 693+ */
891+} 894+}
892+ 895+
893 static int alps_reconnect(struct psmouse *psmouse) 896 static int alps_reconnect(struct psmouse *psmouse)
894 { 897 {
895 const struct alps_model_info *model; 898 const struct alps_model_info *model;
896@@ -641,6 +1343,8 @@ int alps_init(struct psmouse *psmouse) 899@@ -641,6 +1338,8 @@ int alps_init(struct psmouse *psmouse)
897 900
898 psmouse->private = priv; 901 psmouse->private = priv;
899 902
900+ psmouse_reset(psmouse); 903+ psmouse_reset(psmouse);
901+ 904+
902 model = alps_get_model(psmouse, &version); 905 model = alps_get_model(psmouse, &version);
903 if (!model) 906 if (!model)
904 goto init_fail; 907 goto init_fail;
905@@ -668,8 +1372,20 @@ int alps_init(struct psmouse *psmouse) 908@@ -668,8 +1367,20 @@ int alps_init(struct psmouse *psmouse)
906 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); 909 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
907 910
908 dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); 911 dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
909- input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); 912- input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
910- input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); 913- input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
923+ } 926+ }
924+ 927+
925 input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); 928 input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
926 929
927 if (model->flags & ALPS_WHEEL) { 930 if (model->flags & ALPS_WHEEL) {
928@@ -712,7 +1428,7 @@ int alps_init(struct psmouse *psmouse) 931@@ -712,7 +1423,7 @@ int alps_init(struct psmouse *psmouse)
929 psmouse->poll = alps_poll; 932 psmouse->poll = alps_poll;
930 psmouse->disconnect = alps_disconnect; 933 psmouse->disconnect = alps_disconnect;
931 psmouse->reconnect = alps_reconnect; 934 psmouse->reconnect = alps_reconnect;
932- psmouse->pktsize = 6; 935- psmouse->pktsize = 6;
933+ psmouse->pktsize = model->proto_version == ALPS_PROTO_V4 ? 8 : 6; 936+ psmouse->pktsize = model->proto_version == ALPS_PROTO_V4 ? 8 : 6;

Legend:
Removed from v.1984  
changed lines
  Added in v.2038

  ViewVC Help
Powered by ViewVC 1.1.20