9. Elantech 觸控板驅動

版權所有 (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net>

Steve Havelka 發現了硬體版本 1 的額外資訊並提供。

基於 Xandros 的 Woody 收到的補丁,以及 eeeuser.com 論壇的 StewieGriffin 使用者轉發給我的補丁,實現了版本 2 (EeePC) 硬體支援。

9.1. 簡介

目前,Linux Elantech 觸控板驅動程式可識別四種不同的硬體版本,分別稱為版本 1、版本 2、版本 3 和版本 4。版本 1 存在於“較舊的”筆記型電腦中,每個資料包使用 4 個位元組。版本 2 似乎是在 EeePC 中引入的,每個資料包使用 6 個位元組,並提供其他功能,例如兩個手指的位置和觸控的寬度。硬體版本 3 每個資料包使用 6 個位元組(對於 2 個手指,則連線兩個 6 位元組資料包),並允許跟蹤最多 3 個手指。硬體版本 4 每個資料包使用 6 個位元組,並且可以將狀態資料包與多個頭或移動資料包組合在一起。硬體版本 4 最多可以跟蹤 5 個手指。

某些硬體版本 3 和版本 4 還具有 trackpoint,它使用單獨的資料包格式。它也是每個資料包 6 個位元組。

該驅動程式嘗試支援兩個硬體版本,並且應與 Xorg Synaptics 觸控板驅動程式及其圖形配置實用程式相容。

請注意,當有 trackpoint 可用時,滑鼠按鈕也與觸控板或 trackpoint 相關聯。在 xorg 中停用觸控板 (TouchPadOff=0) 也會停用與觸控板關聯的按鈕。

此外,可以透過調整其某些內部暫存器的內容來更改觸控板的操作。這些暫存器由驅動程式表示為 /sys/bus/serio/drivers/psmouse/serio? 下的 sysfs 條目,可以從中讀取和寫入。

目前,只有硬體版本 1 的暫存器在某種程度上可以理解。硬體版本 2 似乎使用了一些相同的暫存器,但尚不清楚暫存器中的位是否代表相同的內容或可能已更改其含義。

最重要的是,某些暫存器設定僅在觸控板處於相對模式而不是絕對模式時才有效。由於 Linux Elantech 觸控板驅動程式始終將硬體置於絕對模式,因此並非所有以下提到的資訊都可以立即使用。但是,由於沒有免費的 Elantech 文件,因此無論如何在此處提供該資訊以保持完整性。

9.2. 額外旋鈕

目前,Linux Elantech 觸控板驅動程式在 /sys/bus/serio/drivers/psmouse/serio? 下為使用者提供了三個額外的旋鈕。

  • debug

    開啟或關閉不同級別的除錯。

    透過將“0”回顯到此檔案,所有除錯都將關閉。

    目前,值“1”將開啟一些基本除錯,值“2”將開啟資料包除錯。對於硬體版本 1,預設值為 OFF。對於版本 2,預設值為“1”。

    開啟資料包除錯將使驅動程式在處理之前將收到的每個資料包轉儲到 syslog。請注意,這會生成大量資料!

  • paritycheck

    開啟或關閉奇偶校驗。

    透過將“0”回顯到此檔案,奇偶校驗將被關閉。任何非零值都會將其開啟。對於硬體版本 1,預設值為 ON。對於版本 2,預設值為 OFF。

    硬體版本 1 透過為每個資料包的最後 3 個位元組計算奇偶校驗位來提供基本的資料完整性驗證。驅動程式可以檢查這些位並拒絕任何似乎已損壞的資料包。使用此旋鈕,您可以繞過該檢查。

    硬體版本 2 不提供相同的奇偶校驗位。只能進行一些基本的資料一致性檢查。目前,預設情況下停用檢查。目前,即使將其開啟也不會執行任何操作。

  • crc_enabled

    將 crc_enabled 設定為 0/1。“crc_enabled”是此完整性檢查的官方名稱,即使它不是實際的迴圈冗餘校驗。

    根據 crc_enabled 的狀態,驅動程式會對硬體版本 3 和 4 執行某些基本的資料完整性驗證。驅動程式將拒絕任何似乎已損壞的資料包。使用此旋鈕,可以透過此旋鈕更改 crc_enabled 的狀態。

    讀取 crc_enabled 值將顯示活動值。將“0”或“1”回顯到此檔案會將狀態設定為“0”或“1”。

9.3. 區分硬體版本

要檢測硬體版本,請讀取版本號作為 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

在實際應用中,似乎存在更多版本,例如 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

在實際應用中,似乎存在更多版本,例如 04.03.01、04.04.11。除了 EF113 之外,似乎幾乎沒有區別,後者不報告壓力/寬度並且具有不同的資料一致性檢查。

可能所有 param[0] <= 01 的版本都可以被認為是 4 位元組/韌體 1。除了 02.00.30 之外,< 02.08.00 的版本都可以被認為是 4 位元組/韌體 2。所有 >= 02.08.00 的版本都可以被認為是 6 位元組。

9.4. 硬體版本 1

9.4.1. 暫存器

透過將十六進位制值回顯到暫存器,可以更改其內容。

例如

echo -n 0x16 > reg_10
  • reg_10

    bit   7   6   5   4   3   2   1   0
          B   C   T   D   L   A   S   E
    
          E: 1 = enable smart edges unconditionally
          S: 1 = enable smart edges only when dragging
          A: 1 = absolute mode (needs 4 byte packets, see reg_11)
          L: 1 = enable drag lock (see reg_22)
          D: 1 = disable dynamic resolution
          T: 1 = disable tapping
          C: 1 = enable corner tap
          B: 1 = swap left and right button
    
  • reg_11

    bit   7   6   5   4   3   2   1   0
          1   0   0   H   V   1   F   P
    
          P: 1 = enable parity checking for relative mode
          F: 1 = enable native 4 byte packet mode
          V: 1 = enable vertical scroll area
          H: 1 = enable horizontal scroll area
    
  • reg_20

    single finger width?
    
  • reg_21

    scroll area width (small: 0x40 ... wide: 0xff)
    
  • reg_22

    drag lock time out (short: 0x14 ... long: 0xfe;
                        0xff = tap again to release)
    
  • reg_23

    tap make timeout?
    
  • reg_24

    tap release timeout?
    
  • reg_25

    smart edge cursor speed (0x02 = slow, 0x03 = medium, 0x04 = fast)
    
  • reg_26

    smart edge activation area width?
    

9.4.2. 原生相對模式 4 位元組資料包格式

位元組 0

bit   7   6   5   4   3   2   1   0
      c   c  p2  p1   1   M   R   L

      L, R, M = 1 when Left, Right, Middle mouse button pressed
         some models have M as byte 3 odd parity bit
      when parity checking is enabled (reg_11, P = 1):
         p1..p2 = byte 1 and 2 odd parity bit
      c = 1 when corner tap detected

位元組 1

bit   7   6   5   4   3   2   1   0
     dx7 dx6 dx5 dx4 dx3 dx2 dx1 dx0

      dx7..dx0 = x movement;   positive = right, negative = left
      byte 1 = 0xf0 when corner tap detected

位元組 2

bit   7   6   5   4   3   2   1   0
     dy7 dy6 dy5 dy4 dy3 dy2 dy1 dy0

      dy7..dy0 = y movement;   positive = up,    negative = down

位元組 3

parity checking enabled (reg_11, P = 1):

   bit   7   6   5   4   3   2   1   0
         w   h  n1  n0  ds3 ds2 ds1 ds0

         normally:
            ds3..ds0 = scroll wheel amount and direction
                       positive = down or left
                       negative = up or right
         when corner tap detected:
            ds0 = 1 when top right corner tapped
            ds1 = 1 when bottom right corner tapped
            ds2 = 1 when bottom left corner tapped
            ds3 = 1 when top left corner tapped
         n1..n0 = number of fingers on touchpad
            only models with firmware 2.x report this, models with
            firmware 1.x seem to map one, two and three finger taps
            directly to L, M and R mouse buttons
         h = 1 when horizontal scroll action
         w = 1 when wide finger touch?

otherwise (reg_11, P = 0):

   bit   7   6   5   4   3   2   1   0
        ds7 ds6 ds5 ds4 ds3 ds2 ds1 ds0

         ds7..ds0 = vertical scroll amount and direction
                    negative = up
                    positive = down

9.4.3. 原生絕對模式 4 位元組資料包格式

EF013 和 EF019 具有特殊的行為(由於韌體中的錯誤?),並且當 1 個手指觸控時,必須丟棄前 2 個位置報告。只要報告了不同數量的手指,此計數就會重置。

位元組 0

firmware version 1.x:

   bit   7   6   5   4   3   2   1   0
         D   U  p1  p2   1  p3   R   L

         L, R = 1 when Left, Right mouse button pressed
         p1..p3 = byte 1..3 odd parity bit
         D, U = 1 when rocker switch pressed Up, Down

firmware version 2.x:

   bit   7   6   5   4   3   2   1   0
        n1  n0  p2  p1   1  p3   R   L

         L, R = 1 when Left, Right mouse button pressed
         p1..p3 = byte 1..3 odd parity bit
         n1..n0 = number of fingers on touchpad

位元組 1

firmware version 1.x:

   bit   7   6   5   4   3   2   1   0
         f   0  th  tw  x9  x8  y9  y8

         tw = 1 when two finger touch
         th = 1 when three finger touch
         f  = 1 when finger touch

firmware version 2.x:

   bit   7   6   5   4   3   2   1   0
         .   .   .   .  x9  x8  y9  y8

位元組 2

bit   7   6   5   4   3   2   1   0
     x7  x6  x5  x4  x3  x2  x1  x0

      x9..x0 = absolute x value (horizontal)

位元組 3

bit   7   6   5   4   3   2   1   0
     y7  y6  y5  y4  y3  y2  y1  y0

      y9..y0 = absolute y value (vertical)

9.5. 硬體版本 2

9.5.1. 暫存器

透過將十六進位制值回顯到暫存器,可以更改其內容。

例如

echo -n 0x56 > reg_10
  • reg_10

    bit   7   6   5   4   3   2   1   0
          0   1   0   1   0   1   D   0
    
          D: 1 = enable drag and drop
    
  • reg_11

    bit   7   6   5   4   3   2   1   0
          1   0   0   0   S   0   1   0
    
          S: 1 = enable vertical scroll
    
  • reg_21

    unknown (0x00)
    
  • reg_22

    drag and drop release time out (short: 0x70 ... long 0x7e;
                              0x7f = never i.e. tap again to release)
    

9.5.2. 原生絕對模式 6 位元組資料包格式

9.5.2.1. 奇偶校驗和資料包重新同步

沒有奇偶校驗,但是可以執行一些一致性檢查。

例如對於 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

對於所有其他型號,只有幾個恆定位

if( ((packet[0] & 0x0C) != 0x04) ||
    ((packet[3] & 0x0f) != 0x02) )
        // error detected

如果檢測到錯誤,則所有資料包都將移動一位(並丟棄 packet[0])。

9.5.2.2. 一/三指觸控

位元組 0

bit   7   6   5   4   3   2   1   0
      n1  n0  w3  w2   .   .   R   L

      L, R = 1 when Left, Right mouse button pressed
      n1..n0 = number of fingers on touchpad

位元組 1

bit   7   6   5   4   3   2   1   0
      p7  p6  p5  p4 x11 x10 x9  x8

位元組 2

bit   7   6   5   4   3   2   1   0
      x7  x6  x5  x4  x3  x2  x1  x0

      x11..x0 = absolute x value (horizontal)

位元組 3

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

位元組 4

bit   7   6   5   4   3   2   1   0
     p3  p1  p2  p0  y11 y10 y9  y8

      p7..p0 = pressure (not EF113)

位元組 5

bit   7   6   5   4   3   2   1   0
     y7  y6  y5  y4  y3  y2  y1  y0

      y11..y0 = absolute y value (vertical)

9.5.2.3. 兩指觸控

請注意,這兩對座標不完全是兩個手指的座標,而只是左下角和右上角的座標。因此,實際的手指可能位於由這兩個點定義的正方形的另一條對角線上。

位元組 0

bit   7   6   5   4   3   2   1   0
     n1  n0  ay8 ax8  .   .   R   L

      L, R = 1 when Left, Right mouse button pressed
      n1..n0 = number of fingers on touchpad

位元組 1

bit   7   6   5   4   3   2   1   0
     ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0

      ax8..ax0 = lower-left finger absolute x value

位元組 2

bit   7   6   5   4   3   2   1   0
     ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0

      ay8..ay0 = lower-left finger absolute y value

位元組 3

bit   7   6   5   4   3   2   1   0
      .   .  by8 bx8  .   .   .   .

位元組 4

bit   7   6   5   4   3   2   1   0
     bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0

      bx8..bx0 = upper-right finger absolute x value

位元組 5

bit   7   6   5   4   3   2   1   0
     by7 by8 by5 by4 by3 by2 by1 by0

      by8..by0 = upper-right finger absolute y value

9.6. 硬體版本 3

9.6.1. 暫存器

  • reg_10

    bit   7   6   5   4   3   2   1   0
          0   0   0   0   R   F   T   A
    
          A: 1 = enable absolute tracking
          T: 1 = enable two finger mode auto correct
          F: 1 = disable ABS Position Filter
          R: 1 = enable real hardware resolution
    

9.6.2. 原生絕對模式 6 位元組資料包格式

1 指和 3 指觸控共享相同的 6 位元組資料包格式,不同之處在於 3 指觸控僅報告所有三個手指的中心位置。

韌體將為 2 指觸控傳送 12 個位元組的資料。

關於去抖動:如果盒子的電源不穩定或其他電力問題,或者當手指數量發生變化時,F/W 將傳送“去抖動資料包”以通知驅動程式硬體處於去抖動狀態。去抖動資料包具有以下簽名

byte 0: 0xc4
byte 1: 0xff
byte 2: 0xff
byte 3: 0x02
byte 4: 0xff
byte 5: 0xff

當我們遇到這種資料包時,我們只需忽略它。

9.6.2.1. 一/三指觸控

位元組 0

bit   7   6   5   4   3   2   1   0
     n1  n0  w3  w2   0   1   R   L

     L, R = 1 when Left, Right mouse button pressed
     n1..n0 = number of fingers on touchpad

位元組 1

bit   7   6   5   4   3   2   1   0
     p7  p6  p5  p4 x11 x10  x9  x8

位元組 2

bit   7   6   5   4   3   2   1   0
     x7  x6  x5  x4  x3  x2  x1  x0

     x11..x0 = absolute x value (horizontal)

位元組 3

bit   7   6   5   4   3   2   1   0
      0   0  w1  w0   0   0   1   0

      w3..w0 = width of the finger touch

位元組 4

bit   7   6   5   4   3   2   1   0
     p3  p1  p2  p0  y11 y10 y9  y8

     p7..p0 = pressure

位元組 5

bit   7   6   5   4   3   2   1   0
     y7  y6  y5  y4  y3  y2  y1  y0

     y11..y0 = absolute y value (vertical)

9.6.2.2. 兩指觸控

對於兩指觸控,資料包格式完全相同,只是硬體傳送兩個 6 位元組的資料包。第一個資料包包含第一個手指的資料,第二個資料包包含第二個手指的資料。因此,對於兩指觸控,總共傳送 12 個位元組。

9.7. 硬體版本 4

9.7.1. 暫存器

  • reg_07

    bit   7   6   5   4   3   2   1   0
          0   0   0   0   0   0   0   A
    
          A: 1 = enable absolute tracking
    

9.7.2. 原生絕對模式 6 位元組資料包格式

v4 硬體是一個真正的多點觸控觸控板,能夠跟蹤多達 5 個手指。不幸的是,由於 PS/2 的頻寬有限,其資料包格式相當複雜。

每當手指的數量或身份發生變化時,硬體都會發送一個狀態資料包,指示觸控板上有多少個以及哪些手指,然後是頭資料包或移動資料包。頭資料包包含手指 ID、手指位置(絕對 x、y 值)、寬度和壓力的資料。移動資料包包含兩個手指的位置增量。

例如,當狀態資料包告訴觸控板上有 2 個手指時,我們可以預期會有兩個後續的頭資料包。如果手指狀態沒有改變,則後續資料包將是移動資料包,僅傳送手指位置的增量,直到我們收到狀態資料包。

一個例外是單指觸控。當狀態資料包告訴我們只有一個手指時,硬體只會傳送後續的頭資料包。

9.7.2.1. 狀態資料包

位元組 0

bit   7   6   5   4   3   2   1   0
      .   .   .   .   0   1   R   L

      L, R = 1 when Left, Right mouse button pressed

位元組 1

bit   7   6   5   4   3   2   1   0
      .   .   . ft4 ft3 ft2 ft1 ft0

      ft4 ft3 ft2 ft1 ft0 ftn = 1 when finger n is on touchpad

位元組 2

not used

位元組 3

bit   7   6   5   4   3   2   1   0
      .   .   .   1   0   0   0   0

      constant bits

位元組 4

bit   7   6   5   4   3   2   1   0
      p   .   .   .   .   .   .   .

      p = 1 for palm

位元組 5

not used

9.7.2.2. 頭部資料包

位元組 0

bit   7   6   5   4   3   2   1   0
     w3  w2  w1  w0   0   1   R   L

     L, R = 1 when Left, Right mouse button pressed
     w3..w0 = finger width (spans how many trace lines)

位元組 1

bit   7   6   5   4   3   2   1   0
     p7  p6  p5  p4 x11 x10  x9  x8

位元組 2

bit   7   6   5   4   3   2   1   0
     x7  x6  x5  x4  x3  x2  x1  x0

     x11..x0 = absolute x value (horizontal)

位元組 3

bit   7   6   5   4   3   2   1   0
    id2 id1 id0   1   0   0   0   1

    id2..id0 = finger id

位元組 4

bit   7   6   5   4   3   2   1   0
     p3  p1  p2  p0  y11 y10 y9  y8

     p7..p0 = pressure

位元組 5

bit   7   6   5   4   3   2   1   0
     y7  y6  y5  y4  y3  y2  y1  y0

     y11..y0 = absolute y value (vertical)

9.7.2.3. 移動資料包

位元組 0

bit   7   6   5   4   3   2   1   0
    id2 id1 id0   w   0   1   R   L

    L, R = 1 when Left, Right mouse button pressed
    id2..id0 = finger id
    w = 1 when delta overflows (> 127 or < -128), in this case
    firmware sends us (delta x / 5) and (delta y  / 5)

位元組 1

bit   7   6   5   4   3   2   1   0
     x7  x6  x5  x4  x3  x2  x1  x0

     x7..x0 = delta x (two's complement)

位元組 2

bit   7   6   5   4   3   2   1   0
     y7  y6  y5  y4  y3  y2  y1  y0

     y7..y0 = delta y (two's complement)

位元組 3

bit   7   6   5   4   3   2   1   0
    id2 id1 id0   1   0   0   1   0

    id2..id0 = finger id

位元組 4

bit   7   6   5   4   3   2   1   0
     x7  x6  x5  x4  x3  x2  x1  x0

     x7..x0 = delta x (two's complement)

位元組 5

bit   7   6   5   4   3   2   1   0
     y7  y6  y5  y4  y3  y2  y1  y0

     y7..y0 = delta y (two's complement)

     byte 0 ~ 2 for one finger
     byte 3 ~ 5 for another

9.8. 指點杆(適用於硬體版本 3 和 4)

9.8.1. 暫存器

尚未識別出特殊暫存器。

9.8.2. 原生相對模式 6 位元組資料包格式

9.8.2.1. 狀態資料包

位元組 0

bit   7   6   5   4   3   2   1   0
      0   0  sx  sy   0   M   R   L

位元組 1

bit   7   6   5   4   3   2   1   0
    ~sx   0   0   0   0   0   0   0

位元組 2

bit   7   6   5   4   3   2   1   0
    ~sy   0   0   0   0   0   0   0

位元組 3

bit   7   6   5   4   3   2   1   0
      0   0 ~sy ~sx   0   1   1   0

位元組 4

bit   7   6   5   4   3   2   1   0
     x7  x6  x5  x4  x3  x2  x1  x0

位元組 5

bit   7   6   5   4   3   2   1   0
     y7  y6  y5  y4  y3  y2  y1  y0


      x and y are written in two's complement spread
          over 9 bits with sx/sy the relative top bit and
          x7..x0 and y7..y0 the lower bits.
      ~sx is the inverse of sx, ~sy is the inverse of sy.
      The sign of y is opposite to what the input driver
          expects for a relative movement