keiran

Fixing My Thinkpad X240’s Fingerprint Sensor with a Libfprint Patch

I love my ThinkPad X240. It’s light, tough, and runs Arch like a champ. But there’s one thing that’s always annoyed me: the fingerprint sensor.

Out of the box, it was technically supported by libfprint, but in practice it was slow, inconsistent, and sometimes just refused to scan. As a sysadmin wannabe and a crappy developer, I decided to stop complaining and fix it.

The Problem

The X240 uses a Validity Sensors VFS5011 reader.
libfprint had basic support, but:

  • Scans took 3-4 seconds
  • False negatives were common
  • Sometimes the device wouldn’t wake up after suspend

I dug into the libfprint source and found that the driver for this sensor had very conservative timing values and no proper power management handling.

Step 1 - Reproducing the Bug

Before touching code, I wanted to reliably trigger the issue.
I wrote a quick loop to test scan times:

for i in (seq 1 10)
    fprintd-verify $USER
end

This confirmed the average scan time was ~3.2s, with occasional failures.

Step 2 - Reading the Driver Code

The driver lived in:

libfprint/drivers/vfs5011.c

I noticed:

  • A usleep(500000) (half-second delay) after every scan
  • No explicit USB resume call after suspend
  • A fixed retry count of 5, even for clean scans

Step 3 - The Patch

I made three changes:

  1. Reduced the post-scan delay from 500ms to 100ms
  2. Added a USB resume call in the open() function
  3. Lowered retry count from 5 to 2 for successful scans
/* Old delay */
usleep(500000);

/* New delay */
usleep(100000);

/* Added after device open */
libusb_control_transfer(dev->usb_dev, 0x21, 0x22, 0, 0, NULL, 0, 0);

Step 4 - Testing

I rebuilt libfprint locally:

meson builddir
ninja -C builddir
sudo ninja -C builddir install

Then re-ran my scan loop.
Average scan time dropped to 0.9s, and the sensor woke up fine after suspend.

Step 5 - Upstreaming

I submitted the patch to the libfprint GitLab with a detailed commit message and test results.
The maintainers asked me to make the delay configurable via a driver option, which I did.
A week later, it was merged.

Thoughts? Leave a comment

Comments
  1. positive — Sep 4, 2025:

    w, wish i was that smart

  2. Nigglation — Sep 7, 2025:

    i gooned to this