| Arjan Opmeer | 2a0bd75 | 2008-10-16 22:10:19 -0400 | [diff] [blame] | 1 | Elantech Touchpad Driver | 
 | 2 | ======================== | 
 | 3 |  | 
 | 4 | 	Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net> | 
 | 5 |  | 
 | 6 | 	Extra information for hardware version 1 found and | 
 | 7 | 	provided by Steve Havelka | 
 | 8 |  | 
 | 9 | 	Version 2 (EeePC) hardware support based on patches | 
 | 10 | 	received from Woody at Xandros and forwarded to me | 
 | 11 | 	by user StewieGriffin at the eeeuser.com forum | 
 | 12 |  | 
 | 13 |  | 
 | 14 | Contents | 
 | 15 | ~~~~~~~~ | 
 | 16 |  | 
 | 17 |  1. Introduction | 
 | 18 |  2. Extra knobs | 
 | 19 |  3. Hardware version 1 | 
 | 20 |     3.1 Registers | 
 | 21 |     3.2 Native relative mode 4 byte packet format | 
 | 22 |     3.3 Native absolute mode 4 byte packet format | 
 | 23 |  4. Hardware version 2 | 
 | 24 |     4.1 Registers | 
 | 25 |     4.2 Native absolute mode 6 byte packet format | 
 | 26 |         4.2.1 One finger touch | 
 | 27 |         4.2.2 Two finger touch | 
 | 28 |  | 
 | 29 |  | 
 | 30 |  | 
 | 31 | 1. Introduction | 
 | 32 |    ~~~~~~~~~~~~ | 
 | 33 |  | 
 | 34 | Currently the Linux Elantech touchpad driver is aware of two different | 
 | 35 | hardware versions unimaginatively called version 1 and version 2. Version 1 | 
 | 36 | is found in "older" laptops and uses 4 bytes per packet. Version 2 seems to | 
 | 37 | be introduced with the EeePC and uses 6 bytes per packet. | 
 | 38 |  | 
 | 39 | The driver tries to support both hardware versions and should be compatible | 
 | 40 | with the Xorg Synaptics touchpad driver and its graphical configuration | 
 | 41 | utilities. | 
 | 42 |  | 
 | 43 | Additionally the operation of the touchpad can be altered by adjusting the | 
 | 44 | contents of some of its internal registers. These registers are represented | 
 | 45 | by the driver as sysfs entries under /sys/bus/serio/drivers/psmouse/serio? | 
 | 46 | that can be read from and written to. | 
 | 47 |  | 
 | 48 | Currently only the registers for hardware version 1 are somewhat understood. | 
 | 49 | Hardware version 2 seems to use some of the same registers but it is not | 
 | 50 | known whether the bits in the registers represent the same thing or might | 
 | 51 | have changed their meaning. | 
 | 52 |  | 
 | 53 | On top of that, some register settings have effect only when the touchpad is | 
 | 54 | in relative mode and not in absolute mode. As the Linux Elantech touchpad | 
 | 55 | driver always puts the hardware into absolute mode not all information | 
 | 56 | mentioned below can be used immediately. But because there is no freely | 
 | 57 | available Elantech documentation the information is provided here anyway for | 
 | 58 | completeness sake. | 
 | 59 |  | 
 | 60 |  | 
 | 61 | ///////////////////////////////////////////////////////////////////////////// | 
 | 62 |  | 
 | 63 |  | 
 | 64 | 2. Extra knobs | 
 | 65 |    ~~~~~~~~~~~ | 
 | 66 |  | 
 | 67 | Currently the Linux Elantech touchpad driver provides two extra knobs under | 
 | 68 | /sys/bus/serio/drivers/psmouse/serio? for the user. | 
 | 69 |  | 
 | 70 | * debug | 
 | 71 |  | 
 | 72 |    Turn different levels of debugging ON or OFF. | 
 | 73 |  | 
 | 74 |    By echoing "0" to this file all debugging will be turned OFF. | 
 | 75 |  | 
 | 76 |    Currently a value of "1" will turn on some basic debugging and a value of | 
 | 77 |    "2" will turn on packet debugging. For hardware version 1 the default is | 
 | 78 |    OFF. For version 2 the default is "1". | 
 | 79 |  | 
 | 80 |    Turning packet debugging on will make the driver dump every packet | 
 | 81 |    received to the syslog before processing it. Be warned that this can | 
 | 82 |    generate quite a lot of data! | 
 | 83 |  | 
 | 84 | * paritycheck | 
 | 85 |  | 
 | 86 |    Turns parity checking ON or OFF. | 
 | 87 |  | 
 | 88 |    By echoing "0" to this file parity checking will be turned OFF. Any | 
 | 89 |    non-zero value will turn it ON. For hardware version 1 the default is ON. | 
 | 90 |    For version 2 the default it is OFF. | 
 | 91 |  | 
 | 92 |    Hardware version 1 provides basic data integrity verification by | 
 | 93 |    calculating a parity bit for the last 3 bytes of each packet. The driver | 
 | 94 |    can check these bits and reject any packet that appears corrupted. Using | 
 | 95 |    this knob you can bypass that check. | 
 | 96 |  | 
 | 97 |    It is not known yet whether hardware version 2 provides the same parity | 
 | 98 |    bits. Hence checking is disabled by default. Currently even turning it on | 
 | 99 |    will do nothing. | 
 | 100 |  | 
 | 101 |  | 
 | 102 | ///////////////////////////////////////////////////////////////////////////// | 
 | 103 |  | 
 | 104 |  | 
 | 105 | 3. Hardware version 1 | 
 | 106 |    ================== | 
 | 107 |  | 
 | 108 | 3.1 Registers | 
 | 109 |     ~~~~~~~~~ | 
 | 110 |  | 
 | 111 | By echoing a hexadecimal value to a register it contents can be altered. | 
 | 112 |  | 
 | 113 | For example: | 
 | 114 |  | 
 | 115 |    echo -n 0x16 > reg_10 | 
 | 116 |  | 
 | 117 | * reg_10 | 
 | 118 |  | 
 | 119 |    bit   7   6   5   4   3   2   1   0 | 
 | 120 |          B   C   T   D   L   A   S   E | 
 | 121 |  | 
 | 122 |          E: 1 = enable smart edges unconditionally | 
 | 123 |          S: 1 = enable smart edges only when dragging | 
 | 124 |          A: 1 = absolute mode (needs 4 byte packets, see reg_11) | 
 | 125 |          L: 1 = enable drag lock (see reg_22) | 
 | 126 |          D: 1 = disable dynamic resolution | 
 | 127 |          T: 1 = disable tapping | 
 | 128 |          C: 1 = enable corner tap | 
 | 129 |          B: 1 = swap left and right button | 
 | 130 |  | 
 | 131 | * reg_11 | 
 | 132 |  | 
 | 133 |    bit   7   6   5   4   3   2   1   0 | 
 | 134 |          1   0   0   H   V   1   F   P | 
 | 135 |  | 
 | 136 |          P: 1 = enable parity checking for relative mode | 
 | 137 |          F: 1 = enable native 4 byte packet mode | 
 | 138 |          V: 1 = enable vertical scroll area | 
 | 139 |          H: 1 = enable horizontal scroll area | 
 | 140 |  | 
 | 141 | * reg_20 | 
 | 142 |  | 
 | 143 |          single finger width? | 
 | 144 |  | 
 | 145 | * reg_21 | 
 | 146 |  | 
 | 147 |          scroll area width (small: 0x40 ... wide: 0xff) | 
 | 148 |  | 
 | 149 | * reg_22 | 
 | 150 |  | 
 | 151 |          drag lock time out (short: 0x14 ... long: 0xfe; | 
 | 152 |                              0xff = tap again to release) | 
 | 153 |  | 
 | 154 | * reg_23 | 
 | 155 |  | 
 | 156 |          tap make timeout? | 
 | 157 |  | 
 | 158 | * reg_24 | 
 | 159 |  | 
 | 160 |          tap release timeout? | 
 | 161 |  | 
 | 162 | * reg_25 | 
 | 163 |  | 
 | 164 |          smart edge cursor speed (0x02 = slow, 0x03 = medium, 0x04 = fast) | 
 | 165 |  | 
 | 166 | * reg_26 | 
 | 167 |  | 
 | 168 |          smart edge activation area width? | 
 | 169 |  | 
 | 170 |  | 
 | 171 | 3.2 Native relative mode 4 byte packet format | 
 | 172 |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 | 173 |  | 
 | 174 | byte 0: | 
 | 175 |    bit   7   6   5   4   3   2   1   0 | 
 | 176 |          c   c  p2  p1   1   M   R   L | 
 | 177 |  | 
 | 178 |          L, R, M = 1 when Left, Right, Middle mouse button pressed | 
 | 179 |             some models have M as byte 3 odd parity bit | 
 | 180 |          when parity checking is enabled (reg_11, P = 1): | 
 | 181 |             p1..p2 = byte 1 and 2 odd parity bit | 
 | 182 |          c = 1 when corner tap detected | 
 | 183 |  | 
 | 184 | byte 1: | 
 | 185 |    bit   7   6   5   4   3   2   1   0 | 
 | 186 |         dx7 dx6 dx5 dx4 dx3 dx2 dx1 dx0 | 
 | 187 |  | 
 | 188 |          dx7..dx0 = x movement;   positive = right, negative = left | 
 | 189 |          byte 1 = 0xf0 when corner tap detected | 
 | 190 |  | 
 | 191 | byte 2: | 
 | 192 |    bit   7   6   5   4   3   2   1   0 | 
 | 193 |         dy7 dy6 dy5 dy4 dy3 dy2 dy1 dy0 | 
 | 194 |  | 
 | 195 |          dy7..dy0 = y movement;   positive = up,    negative = down | 
 | 196 |  | 
 | 197 | byte 3: | 
 | 198 |    parity checking enabled (reg_11, P = 1): | 
 | 199 |  | 
 | 200 |       bit   7   6   5   4   3   2   1   0 | 
 | 201 |             w   h  n1  n0  ds3 ds2 ds1 ds0 | 
 | 202 |  | 
 | 203 |             normally: | 
 | 204 |                ds3..ds0 = scroll wheel amount and direction | 
 | 205 |                           positive = down or left | 
 | 206 |                           negative = up or right | 
 | 207 |             when corner tap detected: | 
 | 208 |                ds0 = 1 when top right corner tapped | 
 | 209 |                ds1 = 1 when bottom right corner tapped | 
 | 210 |                ds2 = 1 when bottom left corner tapped | 
 | 211 |                ds3 = 1 when top left corner tapped | 
 | 212 |             n1..n0 = number of fingers on touchpad | 
 | 213 |                only models with firmware 2.x report this, models with | 
 | 214 |                firmware 1.x seem to map one, two and three finger taps | 
 | 215 |                directly to L, M and R mouse buttons | 
 | 216 |             h = 1 when horizontal scroll action | 
 | 217 |             w = 1 when wide finger touch? | 
 | 218 |  | 
 | 219 |    otherwise (reg_11, P = 0): | 
 | 220 |  | 
 | 221 |       bit   7   6   5   4   3   2   1   0 | 
 | 222 |            ds7 ds6 ds5 ds4 ds3 ds2 ds1 ds0 | 
 | 223 |  | 
 | 224 |             ds7..ds0 = vertical scroll amount and direction | 
 | 225 |                        negative = up | 
 | 226 |                        positive = down | 
 | 227 |  | 
 | 228 |  | 
 | 229 | 3.3 Native absolute mode 4 byte packet format | 
 | 230 |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 | 231 |  | 
 | 232 | byte 0: | 
 | 233 |    firmware version 1.x: | 
 | 234 |  | 
 | 235 |       bit   7   6   5   4   3   2   1   0 | 
 | 236 |             D   U  p1  p2   1  p3   R   L | 
 | 237 |  | 
 | 238 |             L, R = 1 when Left, Right mouse button pressed | 
 | 239 |             p1..p3 = byte 1..3 odd parity bit | 
 | 240 |             D, U = 1 when rocker switch pressed Up, Down | 
 | 241 |  | 
 | 242 |    firmware version 2.x: | 
 | 243 |  | 
 | 244 |       bit   7   6   5   4   3   2   1   0 | 
 | 245 |            n1  n0  p2  p1   1  p3   R   L | 
 | 246 |  | 
 | 247 |             L, R = 1 when Left, Right mouse button pressed | 
 | 248 |             p1..p3 = byte 1..3 odd parity bit | 
 | 249 |             n1..n0 = number of fingers on touchpad | 
 | 250 |  | 
 | 251 | byte 1: | 
 | 252 |    firmware version 1.x: | 
 | 253 |  | 
 | 254 |       bit   7   6   5   4   3   2   1   0 | 
 | 255 |             f   0  th  tw  x9  x8  y9  y8 | 
 | 256 |  | 
 | 257 |             tw = 1 when two finger touch | 
 | 258 |             th = 1 when three finger touch | 
 | 259 |             f  = 1 when finger touch | 
 | 260 |  | 
 | 261 |    firmware version 2.x: | 
 | 262 |  | 
 | 263 |       bit   7   6   5   4   3   2   1   0 | 
 | 264 |             .   .   .   .  x9  x8  y9  y8 | 
 | 265 |  | 
 | 266 | byte 2: | 
 | 267 |    bit   7   6   5   4   3   2   1   0 | 
 | 268 |         x7  x6  x5  x4  x3  x2  x1  x0 | 
 | 269 |  | 
 | 270 |          x9..x0 = absolute x value (horizontal) | 
 | 271 |  | 
 | 272 | byte 3: | 
 | 273 |    bit   7   6   5   4   3   2   1   0 | 
 | 274 |         y7  y6  y5  y4  y3  y2  y1  y0 | 
 | 275 |  | 
 | 276 |          y9..y0 = absolute y value (vertical) | 
 | 277 |  | 
 | 278 |  | 
 | 279 | ///////////////////////////////////////////////////////////////////////////// | 
 | 280 |  | 
 | 281 |  | 
 | 282 | 4. Hardware version 2 | 
 | 283 |    ================== | 
 | 284 |  | 
 | 285 |  | 
 | 286 | 4.1 Registers | 
 | 287 |     ~~~~~~~~~ | 
 | 288 |  | 
 | 289 | By echoing a hexadecimal value to a register it contents can be altered. | 
 | 290 |  | 
 | 291 | For example: | 
 | 292 |  | 
 | 293 |    echo -n 0x56 > reg_10 | 
 | 294 |  | 
 | 295 | * reg_10 | 
 | 296 |  | 
 | 297 |    bit   7   6   5   4   3   2   1   0 | 
 | 298 |          0   1   0   1   0   1   D   0 | 
 | 299 |  | 
 | 300 |          D: 1 = enable drag and drop | 
 | 301 |  | 
 | 302 | * reg_11 | 
 | 303 |  | 
 | 304 |    bit   7   6   5   4   3   2   1   0 | 
 | 305 |          1   0   0   0   S   0   1   0 | 
 | 306 |  | 
 | 307 |          S: 1 = enable vertical scroll | 
 | 308 |  | 
 | 309 | * reg_21 | 
 | 310 |  | 
 | 311 |          unknown (0x00) | 
 | 312 |  | 
 | 313 | * reg_22 | 
 | 314 |  | 
 | 315 |          drag and drop release time out (short: 0x70 ... long 0x7e; | 
 | 316 |                                    0x7f = never i.e. tap again to release) | 
 | 317 |  | 
 | 318 |  | 
 | 319 | 4.2 Native absolute mode 6 byte packet format | 
 | 320 |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 | 321 |  | 
 | 322 | 4.2.1 One finger touch | 
 | 323 |       ~~~~~~~~~~~~~~~~ | 
 | 324 |  | 
 | 325 | byte 0: | 
 | 326 |  | 
 | 327 |    bit   7   6   5   4   3   2   1   0 | 
 | 328 |         n1  n0   .   .   .   .   R   L | 
 | 329 |  | 
 | 330 |          L, R = 1 when Left, Right mouse button pressed | 
 | 331 |          n1..n0 = numbers of fingers on touchpad | 
 | 332 |  | 
 | 333 | byte 1: | 
 | 334 |  | 
 | 335 |    bit   7   6   5   4   3   2   1   0 | 
 | 336 |         x15 x14 x13 x12 x11 x10 x9  x8 | 
 | 337 |  | 
 | 338 | byte 2: | 
 | 339 |  | 
 | 340 |    bit   7   6   5   4   3   2   1   0 | 
 | 341 |         x7  x6  x5  x4  x4  x2  x1  x0 | 
 | 342 |  | 
 | 343 |          x15..x0 = absolute x value (horizontal) | 
 | 344 |  | 
 | 345 | byte 3: | 
 | 346 |  | 
 | 347 |    bit   7   6   5   4   3   2   1   0 | 
 | 348 |          .   .   .   .   .   .   .   . | 
 | 349 |  | 
 | 350 | byte 4: | 
 | 351 |  | 
 | 352 |    bit   7   6   5   4   3   2   1   0 | 
 | 353 |         y15 y14 y13 y12 y11 y10 y8  y8 | 
 | 354 |  | 
 | 355 | byte 5: | 
 | 356 |  | 
 | 357 |    bit   7   6   5   4   3   2   1   0 | 
 | 358 |         y7  y6  y5  y4  y3  y2  y1  y0 | 
 | 359 |  | 
 | 360 |          y15..y0 = absolute y value (vertical) | 
 | 361 |  | 
 | 362 |  | 
 | 363 | 4.2.2 Two finger touch | 
 | 364 |       ~~~~~~~~~~~~~~~~ | 
 | 365 |  | 
 | 366 | byte 0: | 
 | 367 |  | 
 | 368 |    bit   7   6   5   4   3   2   1   0 | 
 | 369 |         n1  n0  ay8 ax8  .   .   R   L | 
 | 370 |  | 
 | 371 |          L, R = 1 when Left, Right mouse button pressed | 
 | 372 |          n1..n0 = numbers of fingers on touchpad | 
 | 373 |  | 
 | 374 | byte 1: | 
 | 375 |  | 
 | 376 |    bit   7   6   5   4   3   2   1   0 | 
 | 377 |         ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | 
 | 378 |  | 
 | 379 |          ax8..ax0 = first finger absolute x value | 
 | 380 |  | 
 | 381 | byte 2: | 
 | 382 |  | 
 | 383 |    bit   7   6   5   4   3   2   1   0 | 
 | 384 |         ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 | 
 | 385 |  | 
 | 386 |          ay8..ay0 = first finger absolute y value | 
 | 387 |  | 
 | 388 | byte 3: | 
 | 389 |  | 
 | 390 |    bit   7   6   5   4   3   2   1   0 | 
 | 391 |          .   .  by8 bx8  .   .   .   . | 
 | 392 |  | 
 | 393 | byte 4: | 
 | 394 |  | 
 | 395 |    bit   7   6   5   4   3   2   1   0 | 
 | 396 |         bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 | 
 | 397 |  | 
 | 398 |          bx8..bx0 = second finger absolute x value | 
 | 399 |  | 
 | 400 | byte 5: | 
 | 401 |  | 
 | 402 |    bit   7   6   5   4   3   2   1   0 | 
 | 403 |         by7 by8 by5 by4 by3 by2 by1 by0 | 
 | 404 |  | 
 | 405 |          by8..by0 = second finger absolute y value |