aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJJ Ding <jj_ding@emc.com.tw>2011-09-09 13:31:58 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-09-09 13:35:02 -0400
commit1dc6edec127e1fdb89d246189c232fe635d2f921 (patch)
treeed12c72185f5124ae9ef8cfb2e6cc01dc4e12b45
parent28f49616113f3a1fbef789319bfd2122d0c3663f (diff)
Input: elantech - add v4 hardware support
v4 hardware is a true multitouch capable touchpad (up to 5 fingers). The packet format is quite complex, please see protocol document for reference. Signed-off-by: JJ Ding <jj_ding@emc.com.tw> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--Documentation/input/elantech.txt170
-rw-r--r--drivers/input/mouse/elantech.c249
-rw-r--r--drivers/input/mouse/elantech.h29
3 files changed, 432 insertions, 16 deletions
diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
index cee08eecda43..5602eb71ad5d 100644
--- a/Documentation/input/elantech.txt
+++ b/Documentation/input/elantech.txt
@@ -32,6 +32,12 @@ Contents
32 6.2 Native absolute mode 6 byte packet format 32 6.2 Native absolute mode 6 byte packet format
33 6.2.1 One/Three finger touch 33 6.2.1 One/Three finger touch
34 6.2.2 Two finger touch 34 6.2.2 Two finger touch
35 7. Hardware version 4
36 7.1 Registers
37 7.2 Native absolute mode 6 byte packet format
38 7.2.1 Status packet
39 7.2.2 Head packet
40 7.2.3 Motion packet
35 41
36 42
37 43
@@ -573,3 +579,167 @@ The packet format is exactly the same for two finger touch, except the hardware
573sends two 6 byte packets. The first packet contains data for the first finger, 579sends two 6 byte packets. The first packet contains data for the first finger,
574the second packet has data for the second finger. So for two finger touch a 580the second packet has data for the second finger. So for two finger touch a
575total of 12 bytes are sent. 581total of 12 bytes are sent.
582
583/////////////////////////////////////////////////////////////////////////////
584
5857. Hardware version 4
586 ==================
587
5887.1 Registers
589 ~~~~~~~~~
590* reg_07
591
592 bit 7 6 5 4 3 2 1 0
593 0 0 0 0 0 0 0 A
594
595 A: 1 = enable absolute tracking
596
5977.2 Native absolute mode 6 byte packet format
598 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
599v4 hardware is a true multitouch touchpad, capable of tracking up to 5 fingers.
600Unfortunately, due to PS/2's limited bandwidth, its packet format is rather
601complex.
602
603Whenever the numbers or identities of the fingers changes, the hardware sends a
604status packet to indicate how many and which fingers is on touchpad, followed by
605head packets or motion packets. A head packet contains data of finger id, finger
606position (absolute x, y values), width, and pressure. A motion packet contains
607two fingers' position delta.
608
609For example, when status packet tells there are 2 fingers on touchpad, then we
610can expect two following head packets. If the finger status doesn't change,
611the following packets would be motion packets, only sending delta of finger
612position, until we receive a status packet.
613
614One exception is one finger touch. when a status packet tells us there is only
615one finger, the hardware would just send head packets afterwards.
616
6177.2.1 Status packet
618 ~~~~~~~~~~~~~
619
620byte 0:
621
622 bit 7 6 5 4 3 2 1 0
623 . . . . 0 1 R L
624
625 L, R = 1 when Left, Right mouse button pressed
626
627byte 1:
628
629 bit 7 6 5 4 3 2 1 0
630 . . . ft4 ft3 ft2 ft1 ft0
631
632 ft4 ft3 ft2 ft1 ft0 ftn = 1 when finger n is on touchpad
633
634byte 2: not used
635
636byte 3:
637
638 bit 7 6 5 4 3 2 1 0
639 . . . 1 0 0 0 0
640
641 constant bits
642
643byte 4:
644
645 bit 7 6 5 4 3 2 1 0
646 p . . . . . . .
647
648 p = 1 for palm
649
650byte 5: not used
651
6527.2.2 Head packet
653 ~~~~~~~~~~~
654
655byte 0:
656
657 bit 7 6 5 4 3 2 1 0
658 w3 w2 w1 w0 0 1 R L
659
660 L, R = 1 when Left, Right mouse button pressed
661 w3..w0 = finger width (spans how many trace lines)
662
663byte 1:
664
665 bit 7 6 5 4 3 2 1 0
666 p7 p6 p5 p4 x11 x10 x9 x8
667
668byte 2:
669
670 bit 7 6 5 4 3 2 1 0
671 x7 x6 x5 x4 x3 x2 x1 x0
672
673 x11..x0 = absolute x value (horizontal)
674
675byte 3:
676
677 bit 7 6 5 4 3 2 1 0
678 id2 id1 id0 1 0 0 0 1
679
680 id2..id0 = finger id
681
682byte 4:
683
684 bit 7 6 5 4 3 2 1 0
685 p3 p1 p2 p0 y11 y10 y9 y8
686
687 p7..p0 = pressure
688
689byte 5:
690
691 bit 7 6 5 4 3 2 1 0
692 y7 y6 y5 y4 y3 y2 y1 y0
693
694 y11..y0 = absolute y value (vertical)
695
6967.2.3 Motion packet
697 ~~~~~~~~~~~~~
698
699byte 0:
700
701 bit 7 6 5 4 3 2 1 0
702 id2 id1 id0 w 0 1 R L
703
704 L, R = 1 when Left, Right mouse button pressed
705 id2..id0 = finger id
706 w = 1 when delta overflows (> 127 or < -128), in this case
707 firmware sends us (delta x / 5) and (delta y / 5)
708
709byte 1:
710
711 bit 7 6 5 4 3 2 1 0
712 x7 x6 x5 x4 x3 x2 x1 x0
713
714 x7..x0 = delta x (two's complement)
715
716byte 2:
717
718 bit 7 6 5 4 3 2 1 0
719 y7 y6 y5 y4 y3 y2 y1 y0
720
721 y7..y0 = delta y (two's complement)
722
723byte 3:
724
725 bit 7 6 5 4 3 2 1 0
726 id2 id1 id0 1 0 0 1 0
727
728 id2..id0 = finger id
729
730byte 4:
731
732 bit 7 6 5 4 3 2 1 0
733 x7 x6 x5 x4 x3 x2 x1 x0
734
735 x7..x0 = delta x (two's complement)
736
737byte 5:
738
739 bit 7 6 5 4 3 2 1 0
740 y7 y6 y5 y4 y3 y2 y1 y0
741
742 y7..y0 = delta y (two's complement)
743
744 byte 0 ~ 2 for one finger
745 byte 3 ~ 5 for another
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 9cfc70ae83fd..b8733b377266 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -84,7 +84,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
84 unsigned char param[3]; 84 unsigned char param[3];
85 int rc = 0; 85 int rc = 0;
86 86
87 if (reg < 0x10 || reg > 0x26) 87 if (reg < 0x07 || reg > 0x26)
88 return -1; 88 return -1;
89 89
90 if (reg > 0x11 && reg < 0x20) 90 if (reg > 0x11 && reg < 0x20)
@@ -109,7 +109,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
109 } 109 }
110 break; 110 break;
111 111
112 case 3: 112 case 3 ... 4:
113 if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || 113 if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
114 elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || 114 elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
115 elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || 115 elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
@@ -122,8 +122,10 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
122 122
123 if (rc) 123 if (rc)
124 pr_err("failed to read register 0x%02x.\n", reg); 124 pr_err("failed to read register 0x%02x.\n", reg);
125 else 125 else if (etd->hw_version != 4)
126 *val = param[0]; 126 *val = param[0];
127 else
128 *val = param[1];
127 129
128 return rc; 130 return rc;
129} 131}
@@ -137,7 +139,7 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
137 struct elantech_data *etd = psmouse->private; 139 struct elantech_data *etd = psmouse->private;
138 int rc = 0; 140 int rc = 0;
139 141
140 if (reg < 0x10 || reg > 0x26) 142 if (reg < 0x07 || reg > 0x26)
141 return -1; 143 return -1;
142 144
143 if (reg > 0x11 && reg < 0x20) 145 if (reg > 0x11 && reg < 0x20)
@@ -176,6 +178,20 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
176 rc = -1; 178 rc = -1;
177 } 179 }
178 break; 180 break;
181
182 case 4:
183 if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
184 elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
185 elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
186 elantech_ps2_command(psmouse, NULL, reg) ||
187 elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
188 elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) ||
189 elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
190 elantech_ps2_command(psmouse, NULL, val) ||
191 elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) {
192 rc = -1;
193 }
194 break;
179 } 195 }
180 196
181 if (rc) 197 if (rc)
@@ -409,12 +425,12 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse,
409 * byte 1: . . . . ax11 ax10 ax9 ax8 425 * byte 1: . . . . ax11 ax10 ax9 ax8
410 * byte 2: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 426 * byte 2: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
411 */ 427 */
412 etd->prev_x = ((packet[1] & 0x0f) << 8) | packet[2]; 428 etd->mt[0].x = ((packet[1] & 0x0f) << 8) | packet[2];
413 /* 429 /*
414 * byte 4: . . . . ay11 ay10 ay9 ay8 430 * byte 4: . . . . ay11 ay10 ay9 ay8
415 * byte 5: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 431 * byte 5: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0
416 */ 432 */
417 etd->prev_y = etd->y_max - 433 etd->mt[0].y = etd->y_max -
418 (((packet[4] & 0x0f) << 8) | packet[5]); 434 (((packet[4] & 0x0f) << 8) | packet[5]);
419 /* 435 /*
420 * wait for next packet 436 * wait for next packet
@@ -423,8 +439,8 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse,
423 } 439 }
424 440
425 /* packet_type == PACKET_V3_TAIL */ 441 /* packet_type == PACKET_V3_TAIL */
426 x1 = etd->prev_x; 442 x1 = etd->mt[0].x;
427 y1 = etd->prev_y; 443 y1 = etd->mt[0].y;
428 x2 = ((packet[1] & 0x0f) << 8) | packet[2]; 444 x2 = ((packet[1] & 0x0f) << 8) | packet[2];
429 y2 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); 445 y2 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
430 break; 446 break;
@@ -450,6 +466,129 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse,
450 input_sync(dev); 466 input_sync(dev);
451} 467}
452 468
469static void elantech_input_sync_v4(struct psmouse *psmouse)
470{
471 struct input_dev *dev = psmouse->dev;
472 unsigned char *packet = psmouse->packet;
473
474 input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
475 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
476 input_mt_report_pointer_emulation(dev, true);
477 input_sync(dev);
478}
479
480static void process_packet_status_v4(struct psmouse *psmouse)
481{
482 struct input_dev *dev = psmouse->dev;
483 unsigned char *packet = psmouse->packet;
484 unsigned fingers;
485 int i;
486
487 /* notify finger state change */
488 fingers = packet[1] & 0x1f;
489 for (i = 0; i < ETP_MAX_FINGERS; i++) {
490 if ((fingers & (1 << i)) == 0) {
491 input_mt_slot(dev, i);
492 input_mt_report_slot_state(dev, MT_TOOL_FINGER, false);
493 }
494 }
495
496 elantech_input_sync_v4(psmouse);
497}
498
499static void process_packet_head_v4(struct psmouse *psmouse)
500{
501 struct input_dev *dev = psmouse->dev;
502 struct elantech_data *etd = psmouse->private;
503 unsigned char *packet = psmouse->packet;
504 int id = ((packet[3] & 0xe0) >> 5) - 1;
505 int pres, traces;
506
507 if (id < 0)
508 return;
509
510 etd->mt[id].x = ((packet[1] & 0x0f) << 8) | packet[2];
511 etd->mt[id].y = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]);
512 pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
513 traces = (packet[0] & 0xf0) >> 4;
514
515 input_mt_slot(dev, id);
516 input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
517
518 input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x);
519 input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y);
520 input_report_abs(dev, ABS_MT_PRESSURE, pres);
521 input_report_abs(dev, ABS_MT_TOUCH_MAJOR, traces * etd->width);
522 /* report this for backwards compatibility */
523 input_report_abs(dev, ABS_TOOL_WIDTH, traces);
524
525 elantech_input_sync_v4(psmouse);
526}
527
528static void process_packet_motion_v4(struct psmouse *psmouse)
529{
530 struct input_dev *dev = psmouse->dev;
531 struct elantech_data *etd = psmouse->private;
532 unsigned char *packet = psmouse->packet;
533 int weight, delta_x1 = 0, delta_y1 = 0, delta_x2 = 0, delta_y2 = 0;
534 int id, sid;
535
536 id = ((packet[0] & 0xe0) >> 5) - 1;
537 if (id < 0)
538 return;
539
540 sid = ((packet[3] & 0xe0) >> 5) - 1;
541 weight = (packet[0] & 0x10) ? ETP_WEIGHT_VALUE : 1;
542 /*
543 * Motion packets give us the delta of x, y values of specific fingers,
544 * but in two's complement. Let the compiler do the conversion for us.
545 * Also _enlarge_ the numbers to int, in case of overflow.
546 */
547 delta_x1 = (signed char)packet[1];
548 delta_y1 = (signed char)packet[2];
549 delta_x2 = (signed char)packet[4];
550 delta_y2 = (signed char)packet[5];
551
552 etd->mt[id].x += delta_x1 * weight;
553 etd->mt[id].y -= delta_y1 * weight;
554 input_mt_slot(dev, id);
555 input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x);
556 input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y);
557
558 if (sid >= 0) {
559 etd->mt[sid].x += delta_x2 * weight;
560 etd->mt[sid].y -= delta_y2 * weight;
561 input_mt_slot(dev, sid);
562 input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[sid].x);
563 input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[sid].y);
564 }
565
566 elantech_input_sync_v4(psmouse);
567}
568
569static void elantech_report_absolute_v4(struct psmouse *psmouse,
570 int packet_type)
571{
572 switch (packet_type) {
573 case PACKET_V4_STATUS:
574 process_packet_status_v4(psmouse);
575 break;
576
577 case PACKET_V4_HEAD:
578 process_packet_head_v4(psmouse);
579 break;
580
581 case PACKET_V4_MOTION:
582 process_packet_motion_v4(psmouse);
583 break;
584
585 case PACKET_UNKNOWN:
586 default:
587 /* impossible to get here */
588 break;
589 }
590}
591
453static int elantech_packet_check_v1(struct psmouse *psmouse) 592static int elantech_packet_check_v1(struct psmouse *psmouse)
454{ 593{
455 struct elantech_data *etd = psmouse->private; 594 struct elantech_data *etd = psmouse->private;
@@ -504,7 +643,7 @@ static int elantech_packet_check_v2(struct psmouse *psmouse)
504 643
505/* 644/*
506 * We check the constant bits to determine what packet type we get, 645 * We check the constant bits to determine what packet type we get,
507 * so packet checking is mandatory for v3 hardware. 646 * so packet checking is mandatory for v3 and later hardware.
508 */ 647 */
509static int elantech_packet_check_v3(struct psmouse *psmouse) 648static int elantech_packet_check_v3(struct psmouse *psmouse)
510{ 649{
@@ -527,6 +666,25 @@ static int elantech_packet_check_v3(struct psmouse *psmouse)
527 return PACKET_UNKNOWN; 666 return PACKET_UNKNOWN;
528} 667}
529 668
669static int elantech_packet_check_v4(struct psmouse *psmouse)
670{
671 unsigned char *packet = psmouse->packet;
672
673 if ((packet[0] & 0x0c) == 0x04 &&
674 (packet[3] & 0x1f) == 0x11)
675 return PACKET_V4_HEAD;
676
677 if ((packet[0] & 0x0c) == 0x04 &&
678 (packet[3] & 0x1f) == 0x12)
679 return PACKET_V4_MOTION;
680
681 if ((packet[0] & 0x0c) == 0x04 &&
682 (packet[3] & 0x1f) == 0x10)
683 return PACKET_V4_STATUS;
684
685 return PACKET_UNKNOWN;
686}
687
530/* 688/*
531 * Process byte stream from mouse and handle complete packets 689 * Process byte stream from mouse and handle complete packets
532 */ 690 */
@@ -567,6 +725,14 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
567 725
568 elantech_report_absolute_v3(psmouse, packet_type); 726 elantech_report_absolute_v3(psmouse, packet_type);
569 break; 727 break;
728
729 case 4:
730 packet_type = elantech_packet_check_v4(psmouse);
731 if (packet_type == PACKET_UNKNOWN)
732 return PSMOUSE_BAD_DATA;
733
734 elantech_report_absolute_v4(psmouse, packet_type);
735 break;
570 } 736 }
571 737
572 return PSMOUSE_FULL_PACKET; 738 return PSMOUSE_FULL_PACKET;
@@ -610,6 +776,13 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
610 rc = -1; 776 rc = -1;
611 777
612 break; 778 break;
779
780 case 4:
781 etd->reg_07 = 0x01;
782 if (elantech_write_reg(psmouse, 0x07, etd->reg_07))
783 rc = -1;
784
785 goto skip_readback_reg_10; /* v4 has no reg 0x10 to read */
613 } 786 }
614 787
615 if (rc == 0) { 788 if (rc == 0) {
@@ -637,6 +810,7 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
637 } 810 }
638 } 811 }
639 812
813 skip_readback_reg_10:
640 if (rc) 814 if (rc)
641 pr_err("failed to initialise registers.\n"); 815 pr_err("failed to initialise registers.\n");
642 816
@@ -645,10 +819,12 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
645 819
646static int elantech_set_range(struct psmouse *psmouse, 820static int elantech_set_range(struct psmouse *psmouse,
647 unsigned int *x_min, unsigned int *y_min, 821 unsigned int *x_min, unsigned int *y_min,
648 unsigned int *x_max, unsigned int *y_max) 822 unsigned int *x_max, unsigned int *y_max,
823 unsigned int *width)
649{ 824{
650 struct elantech_data *etd = psmouse->private; 825 struct elantech_data *etd = psmouse->private;
651 unsigned char param[3]; 826 unsigned char param[3];
827 unsigned char traces;
652 int i; 828 int i;
653 829
654 switch (etd->hw_version) { 830 switch (etd->hw_version) {
@@ -684,6 +860,19 @@ static int elantech_set_range(struct psmouse *psmouse,
684 *x_max = (0x0f & param[0]) << 8 | param[1]; 860 *x_max = (0x0f & param[0]) << 8 | param[1];
685 *y_max = (0xf0 & param[0]) << 4 | param[2]; 861 *y_max = (0xf0 & param[0]) << 4 | param[2];
686 break; 862 break;
863
864 case 4:
865 if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
866 return -1;
867
868 *x_max = (0x0f & param[0]) << 8 | param[1];
869 *y_max = (0xf0 & param[0]) << 4 | param[2];
870 traces = etd->capabilities[1];
871 if ((traces < 2) || (traces > *x_max))
872 return -1;
873
874 *width = *x_max / (traces - 1);
875 break;
687 } 876 }
688 877
689 return 0; 878 return 0;
@@ -696,9 +885,9 @@ static int elantech_set_input_params(struct psmouse *psmouse)
696{ 885{
697 struct input_dev *dev = psmouse->dev; 886 struct input_dev *dev = psmouse->dev;
698 struct elantech_data *etd = psmouse->private; 887 struct elantech_data *etd = psmouse->private;
699 unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0; 888 unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0;
700 889
701 if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max)) 890 if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
702 return -1; 891 return -1;
703 892
704 __set_bit(EV_KEY, dev->evbit); 893 __set_bit(EV_KEY, dev->evbit);
@@ -742,9 +931,37 @@ static int elantech_set_input_params(struct psmouse *psmouse)
742 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); 931 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
743 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); 932 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
744 break; 933 break;
934
935 case 4:
936 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
937 /* For X to recognize me as touchpad. */
938 input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
939 input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
940 /*
941 * range of pressure and width is the same as v2,
942 * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility.
943 */
944 input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2,
945 ETP_PMAX_V2, 0, 0);
946 input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
947 ETP_WMAX_V2, 0, 0);
948 /* Multitouch capable pad, up to 5 fingers. */
949 input_mt_init_slots(dev, ETP_MAX_FINGERS);
950 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
951 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
952 input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2,
953 ETP_PMAX_V2, 0, 0);
954 /*
955 * The firmware reports how many trace lines the finger spans,
956 * convert to surface unit as Protocol-B requires.
957 */
958 input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 0,
959 ETP_WMAX_V2 * width, 0, 0);
960 break;
745 } 961 }
746 962
747 etd->y_max = y_max; 963 etd->y_max = y_max;
964 etd->width = width;
748 965
749 return 0; 966 return 0;
750} 967}
@@ -816,6 +1033,7 @@ static ssize_t elantech_set_int_attr(struct psmouse *psmouse,
816 elantech_show_int_attr, \ 1033 elantech_show_int_attr, \
817 elantech_set_int_attr) 1034 elantech_set_int_attr)
818 1035
1036ELANTECH_INT_ATTR(reg_07, 0x07);
819ELANTECH_INT_ATTR(reg_10, 0x10); 1037ELANTECH_INT_ATTR(reg_10, 0x10);
820ELANTECH_INT_ATTR(reg_11, 0x11); 1038ELANTECH_INT_ATTR(reg_11, 0x11);
821ELANTECH_INT_ATTR(reg_20, 0x20); 1039ELANTECH_INT_ATTR(reg_20, 0x20);
@@ -829,6 +1047,7 @@ ELANTECH_INT_ATTR(debug, 0);
829ELANTECH_INT_ATTR(paritycheck, 0); 1047ELANTECH_INT_ATTR(paritycheck, 0);
830 1048
831static struct attribute *elantech_attrs[] = { 1049static struct attribute *elantech_attrs[] = {
1050 &psmouse_attr_reg_07.dattr.attr,
832 &psmouse_attr_reg_10.dattr.attr, 1051 &psmouse_attr_reg_10.dattr.attr,
833 &psmouse_attr_reg_11.dattr.attr, 1052 &psmouse_attr_reg_11.dattr.attr,
834 &psmouse_attr_reg_20.dattr.attr, 1053 &psmouse_attr_reg_20.dattr.attr,
@@ -957,12 +1176,16 @@ static int elantech_reconnect(struct psmouse *psmouse)
957 */ 1176 */
958static int elantech_set_properties(struct elantech_data *etd) 1177static int elantech_set_properties(struct elantech_data *etd)
959{ 1178{
1179 int ver = (etd->fw_version & 0x0f0000) >> 16;
1180
960 if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600) 1181 if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600)
961 etd->hw_version = 1; 1182 etd->hw_version = 1;
962 else if (etd->fw_version < 0x150600) 1183 else if (etd->fw_version < 0x150600)
963 etd->hw_version = 2; 1184 etd->hw_version = 2;
964 else if ((etd->fw_version & 0x0f0000) >> 16 == 5) 1185 else if (ver == 5)
965 etd->hw_version = 3; 1186 etd->hw_version = 3;
1187 else if (ver == 6)
1188 etd->hw_version = 4;
966 else 1189 else
967 return -1; 1190 return -1;
968 1191
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index 236c33cdc708..7ecaef0c07c4 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -82,14 +82,37 @@
82#define ETP_WMAX_V2 15 82#define ETP_WMAX_V2 15
83 83
84/* 84/*
85 * v3 hardware has 2 kinds of packet types. 85 * v3 hardware has 2 kinds of packet types,
86 * v4 hardware has 3.
86 */ 87 */
87#define PACKET_UNKNOWN 0x01 88#define PACKET_UNKNOWN 0x01
88#define PACKET_DEBOUNCE 0x02 89#define PACKET_DEBOUNCE 0x02
89#define PACKET_V3_HEAD 0x03 90#define PACKET_V3_HEAD 0x03
90#define PACKET_V3_TAIL 0x04 91#define PACKET_V3_TAIL 0x04
92#define PACKET_V4_HEAD 0x05
93#define PACKET_V4_MOTION 0x06
94#define PACKET_V4_STATUS 0x07
95
96/*
97 * track up to 5 fingers for v4 hardware
98 */
99#define ETP_MAX_FINGERS 5
100
101/*
102 * weight value for v4 hardware
103 */
104#define ETP_WEIGHT_VALUE 5
105
106/*
107 * The base position for one finger, v4 hardware
108 */
109struct finger_pos {
110 unsigned int x;
111 unsigned int y;
112};
91 113
92struct elantech_data { 114struct elantech_data {
115 unsigned char reg_07;
93 unsigned char reg_10; 116 unsigned char reg_10;
94 unsigned char reg_11; 117 unsigned char reg_11;
95 unsigned char reg_20; 118 unsigned char reg_20;
@@ -108,8 +131,8 @@ struct elantech_data {
108 unsigned int fw_version; 131 unsigned int fw_version;
109 unsigned int single_finger_reports; 132 unsigned int single_finger_reports;
110 unsigned int y_max; 133 unsigned int y_max;
111 unsigned int prev_x; 134 unsigned int width;
112 unsigned int prev_y; 135 struct finger_pos mt[ETP_MAX_FINGERS];
113 unsigned char parity[256]; 136 unsigned char parity[256];
114}; 137};
115 138