samsung7305: Add driver for Samsung 04e8:7305 fingerprint sensor

Adds an image driver for the Samsung USB fingerprint sensor
(04e8:7305) shipped in the Samsung Notebook 7 Spin
(NP730QAA-K02US). The protocol was reverse-engineered from
USB captures of the Windows vendor driver.

The sensor is a 56x192 8-bit grayscale area sensor. Capture
requires a 4-trigger sequence (3 pre-capture strip reads plus
one full-frame read) and a vendor control-transfer bracket
(heartbeat / response-length prime / wait-ready doorbell on
EP0) around every bulk transfer.

The sensor is physically a press sensor but is declared as
FP_SCAN_TYPE_SWIPE and assembled from multiple frames via
fpi_assemble_frames(), because NBIS's minutia extractor needs
more ridge area than a single 56x192 frame provides. An
inline comment near ASSEMBLE_STRIDE explains the rationale
and references drivers/elan.c for precedent.

A umockdev-based capture test is included. Protocol
documentation and development history:
https://github.com/jwhall/samsung7305

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Justin Hall 2026-04-23 11:19:31 -04:00
parent d79f157282
commit eed716e117
8 changed files with 1566 additions and 0 deletions

View file

@ -256,6 +256,11 @@ usb:v2541pFA03*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver samsung7305
usb:v04E8p7305*
ID_AUTOSUSPEND=1
ID_PERSIST=0
# Supported by libfprint driver synaptics
usb:v06CBp00BD*
usb:v06CBp00C2*

File diff suppressed because it is too large Load diff

View file

@ -137,6 +137,8 @@ driver_sources = {
[ 'drivers/elanspi.c' ],
'nb1010' :
[ 'drivers/nb1010.c' ],
'samsung7305' :
[ 'drivers/samsung7305.c' ],
'virtual_image' :
[ 'drivers/virtual-image.c' ],
'virtual_device' :

View file

@ -141,6 +141,7 @@ default_drivers = [
'upekts',
'goodixmoc',
'nb1010',
'samsung7305',
'fpcmoc',
'realtek',
'focaltech_moc',

View file

@ -59,6 +59,7 @@ drivers_tests = [
'realtek',
'realtek-5816',
'focaltech_moc',
'samsung7305',
]
if get_option('introspection')

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

261
tests/samsung7305/device Normal file
View file

@ -0,0 +1,261 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-8
N: bus/usb/001/005=1201000200000008E804057300000102000109022700010100E0320904000003FF02000007050102400000070582024000000705830340000A
E: BUSNUM=001
E: CURRENT_TAGS=:seat:
E: DEVNAME=/dev/bus/usb/001/005
E: DEVNUM=005
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
E: ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_8
E: ID_INTEGRATION=internal
E: ID_MODEL=Fingerprint_Device
E: ID_MODEL_ENC=Fingerprint\x20Device
E: ID_MODEL_ID=7305
E: ID_PATH=pci-0000:00:14.0-usb-0:8
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_8
E: ID_PATH_WITH_USB_REVISION=pci-0000:00:14.0-usbv2-0:8
E: ID_REVISION=0000
E: ID_SERIAL=Samsung_Fingerprint_Device
E: ID_USB_INTERFACES=:ff0200:
E: ID_USB_MODEL=Fingerprint_Device
E: ID_USB_MODEL_ENC=Fingerprint\x20Device
E: ID_USB_MODEL_ID=7305
E: ID_USB_REVISION=0000
E: ID_USB_SERIAL=Samsung_Fingerprint_Device
E: ID_USB_VENDOR=Samsung
E: ID_USB_VENDOR_ENC=Samsung
E: ID_USB_VENDOR_ID=04e8
E: ID_VENDOR=Samsung
E: ID_VENDOR_ENC=Samsung
E: ID_VENDOR_FROM_DATABASE=Samsung Electronics Co., Ltd
E: ID_VENDOR_ID=04e8
E: MAJOR=189
E: MINOR=4
E: PRODUCT=4e8/7305/0
E: SUBSYSTEM=usb
E: TAGS=:seat:
E: TYPE=0/0/0
A: authorized=1\n
A: avoid_reset_quirk=0\n
A: bConfigurationValue=1\n
A: bDeviceClass=00\n
A: bDeviceProtocol=00\n
A: bDeviceSubClass=00\n
A: bMaxPacketSize0=8\n
A: bMaxPower=100mA\n
A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n
A: bcdDevice=0000\n
A: bmAttributes=e0\n
A: busnum=1\n
A: configuration=
H: descriptors=1201000200000008E804057300000102000109022700010100E0320904000003FF02000007050102400000070582024000000705830340000A
A: dev=189:4\n
A: devnum=5\n
A: devpath=8\n
L: driver=../../../../../bus/usb/drivers/usb
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4d/device:4e/device:57
A: idProduct=7305\n
A: idVendor=04e8\n
A: ltm_capable=no\n
A: manufacturer=Samsung\n
A: maxchild=0\n
A: physical_location/dock=no\n
A: physical_location/horizontal_position=center\n
A: physical_location/lid=no\n
A: physical_location/panel=unknown\n
A: physical_location/vertical_position=center\n
L: port=../1-0:1.0/usb1-port8
A: power/active_duration=3119015\n
A: power/autosuspend=2\n
A: power/autosuspend_delay_ms=2000\n
A: power/connected_duration=3119015\n
A: power/control=on\n
A: power/level=on\n
A: power/persist=0\n
A: power/runtime_active_time=3118779\n
A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n
A: power/wakeup=disabled\n
A: power/wakeup_abort_count=\n
A: power/wakeup_active=\n
A: power/wakeup_active_count=\n
A: power/wakeup_count=\n
A: power/wakeup_expire_count=\n
A: power/wakeup_last_time_ms=\n
A: power/wakeup_max_time_ms=\n
A: power/wakeup_total_time_ms=\n
A: product=Fingerprint Device\n
A: quirks=0x0\n
A: removable=fixed\n
A: rx_lanes=1\n
A: speed=12\n
A: tx_lanes=1\n
A: urbnum=5360\n
A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0/usb1
N: bus/usb/001/001=12010002090001406B1D020019060302010109021900010100E0000904000001090000000705810304000C
E: BUSNUM=001
E: CURRENT_TAGS=:seat:
E: DEVNAME=/dev/bus/usb/001/001
E: DEVNUM=001
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_AUTOSUSPEND=1
E: ID_BUS=usb
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_FROM_DATABASE=2.0 root hub
E: ID_MODEL_ID=0002
E: ID_PATH=pci-0000:00:14.0
E: ID_PATH_TAG=pci-0000_00_14_0
E: ID_REVISION=0619
E: ID_SERIAL=Linux_6.19.11-arch1-1_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_SERIAL_SHORT=0000:00:14.0
E: ID_USB_INTERFACES=:090000:
E: ID_USB_MODEL=xHCI_Host_Controller
E: ID_USB_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_USB_MODEL_ID=0002
E: ID_USB_REVISION=0619
E: ID_USB_SERIAL=Linux_6.19.11-arch1-1_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_USB_SERIAL_SHORT=0000:00:14.0
E: ID_USB_VENDOR=Linux_6.19.11-arch1-1_xhci-hcd
E: ID_USB_VENDOR_ENC=Linux\x206.19.11-arch1-1\x20xhci-hcd
E: ID_USB_VENDOR_ID=1d6b
E: ID_VENDOR=Linux_6.19.11-arch1-1_xhci-hcd
E: ID_VENDOR_ENC=Linux\x206.19.11-arch1-1\x20xhci-hcd
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
E: ID_VENDOR_ID=1d6b
E: MAJOR=189
E: MINOR=0
E: PRODUCT=1d6b/2/619
E: SUBSYSTEM=usb
E: TAGS=:seat:
E: TYPE=9/0/1
A: authorized=1\n
A: authorized_default=1\n
A: avoid_reset_quirk=0\n
A: bConfigurationValue=1\n
A: bDeviceClass=09\n
A: bDeviceProtocol=01\n
A: bDeviceSubClass=00\n
A: bMaxPacketSize0=64\n
A: bMaxPower=0mA\n
A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n
A: bcdDevice=0619\n
A: bmAttributes=e0\n
A: busnum=1\n
A: configuration=
H: descriptors=12010002090001406B1D020019060302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0\n
A: devnum=1\n
A: devpath=0\n
L: driver=../../../../bus/usb/drivers/usb
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4d/device:4e
A: idProduct=0002\n
A: idVendor=1d6b\n
A: interface_authorized_default=1\n
A: ltm_capable=no\n
A: manufacturer=Linux 6.19.11-arch1-1 xhci-hcd\n
A: maxchild=12\n
A: power/active_duration=3119934\n
A: power/autosuspend=0\n
A: power/autosuspend_delay_ms=0\n
A: power/connected_duration=3119934\n
A: power/control=auto\n
A: power/level=auto\n
A: power/runtime_active_time=3119932\n
A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n
A: power/wakeup=disabled\n
A: power/wakeup_abort_count=\n
A: power/wakeup_active=\n
A: power/wakeup_active_count=\n
A: power/wakeup_count=\n
A: power/wakeup_expire_count=\n
A: power/wakeup_last_time_ms=\n
A: power/wakeup_max_time_ms=\n
A: power/wakeup_total_time_ms=\n
A: product=xHCI Host Controller\n
A: quirks=0x0\n
A: removable=unknown\n
A: rx_lanes=1\n
A: serial=0000:00:14.0\n
A: speed=480\n
A: tx_lanes=1\n
A: urbnum=255\n
A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0
E: DRIVER=xhci_hcd
E: ID_AUTOSUSPEND=1
E: ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller
E: ID_PATH=pci-0000:00:14.0
E: ID_PATH_TAG=pci-0000_00_14_0
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: MODALIAS=pci:v00008086d00009D2Fsv0000144Dsd0000C165bc0Csc03i30
E: PCI_CLASS=C0330
E: PCI_ID=8086:9D2F
E: PCI_SLOT_NAME=0000:00:14.0
E: PCI_SUBSYS_ID=144D:C165
E: SUBSYSTEM=pci
A: ari_enabled=0\n
A: broken_parity_status=0\n
A: class=0x0c0330\n
H: config=86802F9D060490022130030C00008000040021F70000000000000000000000000000000000000000000000004D1465C10000000070000000000000000B010000FD01348088C60F8000000000000000005B6ECE0F000000000000000000000000306000000000000000000000000000000180C2C10800000000000000000000000500B7001803E0FE0000000000000000090014F01000400100000000C10A080000080000001800008F40020000010400FF0F0000000000000000000000000000000000000000000000000000000000003F000000000000000000000000000000000000000000000000000000000000000000000000000000B30F410800000000
A: consistent_dma_mask_bits=64\n
A: d3cold_allowed=1\n
A: dbc=disabled\n
A: dbc_bInterfaceProtocol=01\n
A: dbc_bcdDevice=0010\n
A: dbc_idProduct=0010\n
A: dbc_idVendor=1d6b\n
A: dbc_poll_interval_ms=64\n
A: device=0x9d2f\n
A: dma_mask_bits=64\n
L: driver=../../../bus/pci/drivers/xhci_hcd
A: driver_override=(null)\n
A: enable=1\n
L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:4d
A: irq=122\n
A: local_cpulist=0-7\n
A: local_cpus=ff\n
A: modalias=pci:v00008086d00009D2Fsv0000144Dsd0000C165bc0Csc03i30\n
A: msi_bus=1\n
A: msi_irqs/122=msi\n
A: msi_irqs/123=msi\n
A: msi_irqs/124=msi\n
A: msi_irqs/125=msi\n
A: msi_irqs/126=msi\n
A: msi_irqs/127=msi\n
A: msi_irqs/128=msi\n
A: msi_irqs/129=msi\n
A: numa_node=-1\n
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 256 port bw ctx arrays 0 0 256 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 8 9 2112 9\nxHCI ring segments 33 33 4096 33\nbuffer-2048 0 0 2048 0\nbuffer-512 3 8 512 1\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n
A: power/control=auto\n
A: power/runtime_active_time=3120191\n
A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n
A: power/wakeup=enabled\n
A: power/wakeup_abort_count=0\n
A: power/wakeup_active=0\n
A: power/wakeup_active_count=0\n
A: power/wakeup_count=0\n
A: power/wakeup_expire_count=0\n
A: power/wakeup_last_time_ms=0\n
A: power/wakeup_max_time_ms=0\n
A: power/wakeup_total_time_ms=0\n
A: power_state=D0\n
A: resource=0x00000000f7210000 0x00000000f721ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n
A: revision=0x21\n
A: subsystem_device=0xc165\n
A: subsystem_vendor=0x144d\n
A: vendor=0x8086\n