From 319881b93a5ee55b1b69ae5a426b9320af78a71c Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Mon, 6 Jul 2026 10:33:40 -0400 Subject: [PATCH] Add sensor type 0x969 (HP ZBook Studio x360 G5, 138a:00ab) The 138a:00ab USB ID is shared across HP machines but maps to different sensor silicon. The EliteBook 840 G5 reports sensor type 0xd51; the ZBook Studio x360 G5 reports 0x969. Both lack native SensorTypeInfo / SensorCaptureProg entries, and empirically both work when aliased to the 0x199 capture profile -- the on-chip matcher accepts the resulting images. Mirror the existing 0xd51 handling for 0x969: - add 0x969 to line_update_type1_devices - alias 0x969 -> 0x199 in open() - accept the b[0]==3 finger interrupt when real_device_type is 0x969 Verified on an HP ZBook Studio x360 G5: init + calibration + enroll (5 stages, enroll-completed) + verify (verify-match). --- validitysensor/sensor.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/validitysensor/sensor.py b/validitysensor/sensor.py index 7ed5e79..f5ff2ff 100644 --- a/validitysensor/sensor.py +++ b/validitysensor/sensor.py @@ -26,6 +26,7 @@ line_update_type1_devices = [ 0xB5, 0x885, 0xB3, 0x143B, 0x1055, 0xE1, 0x8B1, 0xEA, 0xE4, 0xED, 0x1825, 0x1FF5, 0x199, 0xD51, # HP EliteBook 840 G5 (138a:00ab) / HP G6 series (06cb:00b7) + 0x969, # HP ZBook Studio x360 G5 (138a:00ab -- same PID, different silicon) ] @@ -227,14 +228,15 @@ def open(self): self.device_info = identify_sensor() self.real_device_type = self.device_info.type - # Sensor type 0xd51 (HP EliteBook 840 G5 138a:00ab, HP G6 series 06cb:00b7) - # has no native SensorTypeInfo / SensorCaptureProg entry. Empirically the - # 0x199 profile produces images that the on-chip matcher accepts after - # enrollment/verify; the 0xdb profile does not. Spoofing keeps the rest - # of this method (calibration switch, capture program lookup) on a code - # path that works. - if self.device_info.type == 0xd51: - logging.info('Sensor type 0xd51 — aliasing to 0x199 profile') + # Sensor types 0xd51 (HP EliteBook 840 G5 138a:00ab, HP G6 series + # 06cb:00b7) and 0x969 (HP ZBook Studio x360 G5 138a:00ab -- same PID, + # different silicon) have no native SensorTypeInfo / SensorCaptureProg + # entry. Empirically the 0x199 profile produces images that the on-chip + # matcher accepts after enrollment/verify; the 0xdb profile does not. + # Spoofing keeps the rest of this method (calibration switch, capture + # program lookup) on a code path that works. + if self.device_info.type in (0xd51, 0x969): + logging.info('Sensor type 0x%x — aliasing to 0x199 profile' % self.device_info.type) self.device_info.type = 0x199 logging.info('Opening sensor: %s' % self.device_info.name) @@ -738,7 +740,7 @@ def capture(self, mode: CaptureMode) -> typing.Tuple[int, int, int, int]: b = usb.wait_int() if b[0] == 2: break - if b[0] == 3 and getattr(self, 'real_device_type', None) == 0xd51: + if b[0] == 3 and getattr(self, 'real_device_type', None) in (0xd51, 0x969): saved_b = b break