Skip to content

Restore reg_07 after setting the sample rate on Elan firmware 0x381f17 - #68

Open
arvedviehweger wants to merge 1 commit into
acidanthera:masterfrom
arvedviehweger:elan-restore-reg07
Open

arvedviehweger wants to merge 1 commit into
acidanthera:masterfrom
arvedviehweger:elan-restore-reg07

Conversation

@arvedviehweger

Copy link
Copy Markdown

Closes acidanthera/bugtracker#1220

Problem

On Elan hardware version 4 touchpads with firmware 0x381f17, the touchpad attaches and looks entirely healthy in IORegistry — correct logical/physical ranges, VoodooInputSupported, trackpad preferences applied — but it reports no motion and no clicks at all.

elantechSetupPS2 enables absolute mode by writing reg_07, and then sends a set sample rate command as part of the resolution/rate request:

elantechSetAbsoluteMode()   ->  writes reg_07 = 0x01   (absolute mode on)
kDP_SetMouseSampleRate      ->  clears reg_07          (absolute mode off)
kDP_Enable                  ->  touchpad streams relative packets

This firmware loses reg_07 on a set rate command, so absolute mode is gone before data reporting is even switched on.

The driver keeps parsing the stream as 6 byte v4 packets. Since 6 is a multiple of the 3 byte relative packet size, the alignment stays stable and packet[0] is always a real relative byte 0, which always has bit 3 set. That is precisely what the non-CRC branch of the sanity check in elantechPacketCheckV4 rejects:

sanity_check = ((packet[0] & 0x08) == 0x00 && (packet[3] & 0x1c) == 0x10);

Every packet is therefore discarded as PACKET_UNKNOWN and no input ever reaches VoodooInput.

For reference, 0x381f17 resolves to crc_enabled = 0 (fw_version & 0x4000 == 0) and ic_version = 8, so this is the branch that applies.

Fix

Write reg_07 back after the sample rate command, gated on the affected firmware.

Linux carries the same quirk for exactly this firmware, installing a set_rate hook that rewrites the register after every rate change (elantech_set_rate_restore_reg_07 in drivers/input/mouse/elantech.c):

This writes the reg_07 value again to the hardware at the end of every set_rate call because the register loses its value. reg_07 allows setting absolute mode on v4 hardware

VoodooPS2 has no set_rate indirection, and the only set rate call site is this one request, so the hook collapses into a single conditional write.

kDP_Enable is moved out of that request and issued separately afterwards, so the register write still happens while the touchpad is quiet. elantechWriteReg sends its own multi-command PS/2 sequence, and running that against an already streaming touchpad risks interleaving with data packets.

There was already a commented-out sketch of the Linux hook at this spot; it is replaced by the working implementation.

Scope

  • The reg_07 restore is gated on info.fw_version == 0x381f17. No other device executes it — short-circuit evaluation means elantechWriteReg is not even called.
  • Splitting the request affects all Elan devices, but sends the identical commands in the identical order, just across two PS/2 requests instead of one. All three callers of elantechSetupPS2 (start, kPS2M_resetTouchpad, setDevicePowerState) already called setTouchPadEnable(true) immediately afterwards, so kDP_Enable was being sent twice before this change and still is — no change in that behaviour.
  • The fix also covers wake and reset, since both paths re-run elantechSetupPS2.

Testing

Tested on an ASUS TP500LN (Elan v4, fw 381f17, bus 0), the same hardware as the linked issue. The touchpad went from completely unresponsive to fully working, including multi-finger gestures. Release build of all targets succeeds.

Note that the unrelated VoodooPS2Trackpad: Identify TouchPad command returned incorrect byte 2 (of 3): 0x04 line in that issue is emitted by the Synaptics probe correctly rejecting a non-Synaptics device, and is unrelated to this bug.

elantechSetupPS2 puts hardware version 4 touchpads into absolute mode by
writing reg_07, and then sends a set sample rate command. On firmware
0x381f17 that command clears reg_07, so the touchpad drops back to
relative mode before data reporting is even enabled.

The driver still parses the stream as 6 byte v4 packets. Byte 0 of a
standard relative packet always has bit 3 set, which is exactly what the
non-CRC sanity check in elantechPacketCheckV4 rejects, so every packet is
discarded as PACKET_UNKNOWN. The touchpad attaches and looks correct in
IORegistry, but reports no motion and no clicks at all.

Write reg_07 back after the sample rate command. Data reporting is moved
into a separate request afterwards so the register write still happens
while the touchpad is quiet. Linux fixes this the same way through a
set_rate hook, see elantech_set_rate_restore_reg_07.

Fixes: acidanthera/bugtracker#1220
@arvedviehweger

Copy link
Copy Markdown
Author

If anyone would like to give it a go here is the ZIP file attached to this comment which includes the kext.

VoodooPS2Controller-2.3.8-RELEASE.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

voodoops2elan is loaded on Elan v4 but no move or click

1 participant