Input: elantech - describe further the protocol

For some Dell laptops, Ubuntu had a special version of the elantech
driver with more knowledge on the devices. It can be found there:
http://zinc.ubuntu.com/git?p=mid-team/hardy-netbook.git;a=blob;f=drivers/input/mouse/elantech.c;h=d0e2cafed162428f72e3654f4dda85e08ea486b3;hb=refs/heads/abi-22

By inspecting the source code, and doing some test on a real hardware, I
have completed the protocol specification (especially for the 6 bytes
protocol). It also adds information about the mapping between the
version reported by the device and the protocol to use.

Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net>
Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
Éric Piel 2011-05-16 22:45:54 -07:00 committed by Dmitry Torokhov
parent 215ef98677
commit 71c6d18859

View File

@ -34,7 +34,8 @@ Contents
Currently the Linux Elantech touchpad driver is aware of two different Currently the Linux Elantech touchpad driver is aware of two different
hardware versions unimaginatively called version 1 and version 2. Version 1 hardware versions unimaginatively called version 1 and version 2. Version 1
is found in "older" laptops and uses 4 bytes per packet. Version 2 seems to is found in "older" laptops and uses 4 bytes per packet. Version 2 seems to
be introduced with the EeePC and uses 6 bytes per packet. be introduced with the EeePC and uses 6 bytes per packet, and provides
additional features such as position of two fingers, and width of the touch.
The driver tries to support both hardware versions and should be compatible The driver tries to support both hardware versions and should be compatible
with the Xorg Synaptics touchpad driver and its graphical configuration with the Xorg Synaptics touchpad driver and its graphical configuration
@ -94,18 +95,44 @@ Currently the Linux Elantech touchpad driver provides two extra knobs under
can check these bits and reject any packet that appears corrupted. Using can check these bits and reject any packet that appears corrupted. Using
this knob you can bypass that check. this knob you can bypass that check.
It is not known yet whether hardware version 2 provides the same parity Hardware version 2 does not provide the same parity bits. Only some basic
bits. Hence checking is disabled by default. Currently even turning it on data consistency checking can be done. For now checking is disabled by
will do nothing. default. Currently even turning it on will do nothing.
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
3. Differentiating hardware versions
=================================
3. Hardware version 1 To detect the hardware version, read the version number as param[0].param[1].param[2]
4 bytes version: (after the arrow is the name given in the Dell-provided driver)
02.00.22 => EF013
02.06.00 => EF019
In the wild, there appear to be more versions, such as 00.01.64, 01.00.21,
02.00.00, 02.00.04, 02.00.06.
6 bytes:
02.00.30 => EF113
02.08.00 => EF023
02.08.XX => EF123
02.0B.00 => EF215
04.01.XX => Scroll_EF051
04.02.XX => EF051
In the wild, there appear to be more versions, such as 04.03.01, 04.04.11. There
appears to be almost no difference, except for EF113, which does not report
pressure/width and has different data consistency checks.
Probably all the versions with param[0] <= 01 can be considered as
4 bytes/firmware 1. The versions < 02.08.00, with the exception of 02.00.30, as
4 bytes/firmware 2. Everything >= 02.08.00 can be considered as 6 bytes.
/////////////////////////////////////////////////////////////////////////////
4. Hardware version 1
================== ==================
3.1 Registers 4.1 Registers
~~~~~~~~~ ~~~~~~~~~
By echoing a hexadecimal value to a register it contents can be altered. By echoing a hexadecimal value to a register it contents can be altered.
@ -168,7 +195,7 @@ For example:
smart edge activation area width? smart edge activation area width?
3.2 Native relative mode 4 byte packet format 4.2 Native relative mode 4 byte packet format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
byte 0: byte 0:
@ -226,9 +253,13 @@ byte 3:
positive = down positive = down
3.3 Native absolute mode 4 byte packet format 4.3 Native absolute mode 4 byte packet format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EF013 and EF019 have a special behaviour (due to a bug in the firmware?), and
when 1 finger is touching, the first 2 position reports must be discarded.
This counting is reset whenever a different number of fingers is reported.
byte 0: byte 0:
firmware version 1.x: firmware version 1.x:
@ -279,11 +310,11 @@ byte 3:
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
4. Hardware version 2 5. Hardware version 2
================== ==================
4.1 Registers 5.1 Registers
~~~~~~~~~ ~~~~~~~~~
By echoing a hexadecimal value to a register it contents can be altered. By echoing a hexadecimal value to a register it contents can be altered.
@ -316,16 +347,41 @@ For example:
0x7f = never i.e. tap again to release) 0x7f = never i.e. tap again to release)
4.2 Native absolute mode 6 byte packet format 5.2 Native absolute mode 6 byte packet format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5.2.1 Parity checking and packet re-synchronization
There is no parity checking, however some consistency checks can be performed.
4.2.1 One finger touch For instance for EF113:
SA1= packet[0];
A1 = packet[1];
B1 = packet[2];
SB1= packet[3];
C1 = packet[4];
D1 = packet[5];
if( (((SA1 & 0x3C) != 0x3C) && ((SA1 & 0xC0) != 0x80)) || // check Byte 1
(((SA1 & 0x0C) != 0x0C) && ((SA1 & 0xC0) == 0x80)) || // check Byte 1 (one finger pressed)
(((SA1 & 0xC0) != 0x80) && (( A1 & 0xF0) != 0x00)) || // check Byte 2
(((SB1 & 0x3E) != 0x38) && ((SA1 & 0xC0) != 0x80)) || // check Byte 4
(((SB1 & 0x0E) != 0x08) && ((SA1 & 0xC0) == 0x80)) || // check Byte 4 (one finger pressed)
(((SA1 & 0xC0) != 0x80) && (( C1 & 0xF0) != 0x00)) ) // check Byte 5
// error detected
For all the other ones, there are just a few constant bits:
if( ((packet[0] & 0x0C) != 0x04) ||
((packet[3] & 0x0f) != 0x02) )
// error detected
In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).
5.2.1 One/Three finger touch
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
byte 0: byte 0:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
n1 n0 . . . . R L n1 n0 w3 w2 . . R L
L, R = 1 when Left, Right mouse button pressed L, R = 1 when Left, Right mouse button pressed
n1..n0 = numbers of fingers on touchpad n1..n0 = numbers of fingers on touchpad
@ -333,24 +389,40 @@ byte 0:
byte 1: byte 1:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
. . . . . x10 x9 x8 p7 p6 p5 p4 . x10 x9 x8
byte 2: byte 2:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x4 x2 x1 x0 x7 x6 x5 x4 x3 x2 x1 x0
x10..x0 = absolute x value (horizontal) x10..x0 = absolute x value (horizontal)
byte 3: byte 3:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
. . . . . . . . n4 vf w1 w0 . . . b2
n4 = set if more than 3 fingers (only in 3 fingers mode)
vf = a kind of flag ? (only on EF123, 0 when finger is over one
of the buttons, 1 otherwise)
w3..w0 = width of the finger touch (not EF113)
b2 (on EF113 only, 0 otherwise), b2.R.L indicates one button pressed:
0 = none
1 = Left
2 = Right
3 = Middle (Left and Right)
4 = Forward
5 = Back
6 = Another one
7 = Another one
byte 4: byte 4:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
. . . . . . y9 y8 p3 p1 p2 p0 . . y9 y8
p7..p0 = pressure (not EF113)
byte 5: byte 5:
@ -363,6 +435,11 @@ byte 5:
4.2.2 Two finger touch 4.2.2 Two finger touch
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
Note that the two pairs of coordinates are not exactly the coordinates of the
two fingers, but only the pair of the lower-left and upper-right coordinates.
So the actual fingers might be situated on the other diagonal of the square
defined by these two points.
byte 0: byte 0:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
@ -376,14 +453,14 @@ byte 1:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
ax8..ax0 = first finger absolute x value ax8..ax0 = lower-left finger absolute x value
byte 2: byte 2:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0
ay8..ay0 = first finger absolute y value ay8..ay0 = lower-left finger absolute y value
byte 3: byte 3:
@ -395,11 +472,11 @@ byte 4:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
bx8..bx0 = second finger absolute x value bx8..bx0 = upper-right finger absolute x value
byte 5: byte 5:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
by7 by8 by5 by4 by3 by2 by1 by0 by7 by8 by5 by4 by3 by2 by1 by0
by8..by0 = second finger absolute y value by8..by0 = upper-right finger absolute y value