From 4610f2285e6373c2fe4ead0dff4ebf8dabe4e532 Mon Sep 17 00:00:00 2001 From: lichenggang Date: Thu, 16 Apr 2026 15:53:45 +0800 Subject: [PATCH] elan: Add support for 0x0c58 sensor response codes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Elan 04f3:0c58 sensor returns 0xaf during capture which indicates finger removed or sensor busy. Also 0x00 can occur meaning not ready. These responses should trigger a retry instead of failing. To avoid changing behavior for other Elan devices, limit the new retry logic to the 0x0c58 device type and add a small 10ms delay between retries. Additionally, increase calibration attempts from 10 to 30 for 0x0c58 as this sensor needs more time to complete calibration. Source: https://gitlab.freedesktop.org/libfprint/libfprint/-/work_items/763 Signed-off-by: lichenggang Co-Authored-By: Marco Trevisan (TreviƱo) --- libfprint/drivers/elan.c | 9 ++++++++- libfprint/drivers/elan.h | 7 +++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index 1b5d1e70..af631732 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -547,6 +547,13 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev) fpi_image_device_report_finger_status (idev, TRUE); elan_run_cmd (ssm, dev, &get_image_cmd, ELAN_CMD_TIMEOUT); } + else if (self->dev_type == ELAN_0C58 && self->last_read && + (self->last_read[0] == 0x00 || self->last_read[0] == 0xaf)) + { + /* 0x00 - not ready + * 0xaf - finger removed or sensor busy (seen on 0x0c58) */ + fpi_ssm_jump_to_state_delayed (ssm, CAPTURE_WAIT_FINGER, 10); + } else { /* XXX: The timeout is emulated incorrectly, resulting in a zero byte read. */ @@ -795,7 +802,7 @@ elan_calibrate (FpiDeviceElan *self) g_return_if_fail (!self->active); self->active = TRUE; - self->calib_atts_left = ELAN_CALIBRATION_ATTEMPTS; + self->calib_atts_left = ELAN_CALIBRATION_ATTEMPTS (self->dev_type); FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (self), calibrate_run_state, CALIBRATE_NUM_STATES); diff --git a/libfprint/drivers/elan.h b/libfprint/drivers/elan.h index 7d089945..6bbaae04 100644 --- a/libfprint/drivers/elan.h +++ b/libfprint/drivers/elan.h @@ -31,6 +31,7 @@ #define ELAN_0907 (1 << 0) #define ELAN_0C03 (1 << 1) #define ELAN_0C42 (1 << 2) +#define ELAN_0C58 (1 << 3) /* devices which don't require frame rotation before assembling */ #define ELAN_NOT_ROTATED ELAN_0C03 @@ -44,7 +45,9 @@ /* times to retry reading calibration status during one session * generally prevents calibration from looping indefinitely */ -#define ELAN_CALIBRATION_ATTEMPTS 10 +#define ELAN_DEFAULT_CALIBRATION_ATTEMPTS 10 +#define ELAN_CALIBRATION_ATTEMPTS(dev_type) \ + ((dev_type) == ELAN_0C58 ? 30 : ELAN_DEFAULT_CALIBRATION_ATTEMPTS) /* min and max frames in a capture */ #define ELAN_MIN_FRAMES 7 @@ -220,7 +223,7 @@ static const FpIdEntry elan_id_table[] = { {.vid = ELAN_VEND_ID, .pid = 0x0c4f, .driver_data = ELAN_ALL_DEV}, {.vid = ELAN_VEND_ID, .pid = 0x0c63, .driver_data = ELAN_ALL_DEV}, {.vid = ELAN_VEND_ID, .pid = 0x0c6e, .driver_data = ELAN_ALL_DEV}, - {.vid = ELAN_VEND_ID, .pid = 0x0c58, .driver_data = ELAN_ALL_DEV}, + {.vid = ELAN_VEND_ID, .pid = 0x0c58, .driver_data = ELAN_0C58}, {.vid = 0, .pid = 0, .driver_data = 0}, };