diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb index 7057c47..2407652 100644 --- a/data/autosuspend.hwdb +++ b/data/autosuspend.hwdb @@ -64,6 +64,11 @@ usb:v08FFp5731* usb:v5501p08FF* ID_AUTOSUSPEND=1 +# Supported by libfprint driver egis0570 +usb:v1C7Ap0570* +usb:v1C7Ap0571* + ID_AUTOSUSPEND=1 + # Supported by libfprint driver elan usb:v04F3p0903* usb:v04F3p0907* @@ -264,7 +269,6 @@ usb:v147Ep1002* usb:v1491p0088* usb:v16D1p1027* usb:v1C7Ap0300* -usb:v1C7Ap0570* usb:v1C7Ap0575* usb:v27C6p5042* usb:v27C6p5110* diff --git a/libfprint/drivers/egis0570.c b/libfprint/drivers/egis0570.c new file mode 100644 index 0000000..0490195 --- /dev/null +++ b/libfprint/drivers/egis0570.c @@ -0,0 +1,444 @@ +/* + * Egis Technology Inc. (aka. LighTuning) 0570 driver for libfprint + * Copyright (C) 2021 Maxim Kolesnikov + * Copyright (C) 2021 Saeed/Ali Rk + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define FP_COMPONENT "egis0570" + +#include "egis0570.h" +#include "drivers_api.h" + +/* Packet types */ +#define PKT_TYPE_INIT 0 +#define PKT_TYPE_REPEAT 1 + +/* Struct */ +struct _FpDeviceEgis0570 +{ + FpImageDevice parent; + + gboolean running; + gboolean stop; + + GSList *strips; + guint8 *background; + gsize strips_len; + + int pkt_num; + int pkt_type; +}; +G_DECLARE_FINAL_TYPE (FpDeviceEgis0570, fpi_device_egis0570, FPI, DEVICE_EGIS0570, FpImageDevice); +G_DEFINE_TYPE (FpDeviceEgis0570, fpi_device_egis0570, FP_TYPE_IMAGE_DEVICE); + +static unsigned char +egis_get_pixel (struct fpi_frame_asmbl_ctx *ctx, struct fpi_frame *frame, unsigned int x, unsigned int y) +{ + return frame->data[x + y * ctx->frame_width]; +} + +static struct fpi_frame_asmbl_ctx assembling_ctx = { + .frame_width = EGIS0570_IMGWIDTH, + .frame_height = EGIS0570_RFMGHEIGHT, + .image_width = EGIS0570_IMGWIDTH * 4 / 3, + .get_pixel = egis_get_pixel, +}; + +/* + * Service + */ + +static gboolean +is_last_pkt (FpDevice *dev) +{ + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + + int type = self->pkt_type; + int num = self->pkt_num; + + gboolean r; + + r = ((type == PKT_TYPE_INIT) && (num == (EGIS0570_INIT_TOTAL - 1))); + r |= ((type == PKT_TYPE_REPEAT) && (num == (EGIS0570_REPEAT_TOTAL - 1))); + + return r; +} + +/* + * Returns a bit for each frame on whether or not a finger has been detected. + * e.g. 00110 means that there is a finger in frame two and three. + */ +static char +postprocess_frames (FpDeviceEgis0570 *self, guint8 * img) +{ + size_t mean[EGIS0570_IMGCOUNT] = {0, 0, 0, 0, 0}; + + if (!self->background) + { + self->background = g_malloc (EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT); + memset (self->background, 255, EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT); + + for (size_t k = 0; k < EGIS0570_IMGCOUNT; k += 1) + { + guint8 * frame = &img[(k * EGIS0570_IMGSIZE) + EGIS0570_RFMDIS * EGIS0570_IMGWIDTH]; + + for (size_t i = 0; i < EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT; i += 1) + self->background[i] = MIN (self->background[i], frame[i]); + } + + return 0; + } + + for (size_t k = 0; k < EGIS0570_IMGCOUNT; k += 1) + { + guint8 * frame = &img[(k * EGIS0570_IMGSIZE) + EGIS0570_RFMDIS * EGIS0570_IMGWIDTH]; + + for (size_t i = 0; i < EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT; i += 1) + { + if (frame[i] - EGIS0570_MARGIN > self->background[i]) + frame[i] -= self->background[i]; + else + frame[i] = 0; + + mean[k] += frame[i]; + } + + mean[k] /= EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT; + } + + char result = 0; + + for (size_t k = 0; k < EGIS0570_IMGCOUNT; k += 1) + { + fp_dbg ("Finger status (picture number, mean) : %ld , %ld", k, mean[k]); + if (mean[k] > EGIS0570_MIN_MEAN) + result |= 1 << k; + } + + return result; +} + +/* + * Device communication + */ + +static void +data_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error) +{ + unsigned char *stripdata; + gboolean end = FALSE; + FpImageDevice *img_self = FP_IMAGE_DEVICE (dev); + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + + if (error) + { + fpi_ssm_mark_failed (transfer->ssm, error); + return; + } + + int where_finger_is = postprocess_frames (self, transfer->buffer); + + if (where_finger_is > 0) + { + FpiImageDeviceState state; + + fpi_image_device_report_finger_status (img_self, TRUE); + + g_object_get (dev, "fpi-image-device-state", &state, NULL); + if (state == FPI_IMAGE_DEVICE_STATE_CAPTURE) + { + for (size_t k = 0; k < EGIS0570_IMGCOUNT; k += 1) + { + if (where_finger_is & (1 << k)) + { + struct fpi_frame *stripe = g_malloc (EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT + sizeof (struct fpi_frame)); + stripe->delta_x = 0; + stripe->delta_y = 0; + stripdata = stripe->data; + memcpy (stripdata, (transfer->buffer) + (((k) * EGIS0570_IMGSIZE) + EGIS0570_IMGWIDTH * EGIS0570_RFMDIS), EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT); + self->strips = g_slist_prepend (self->strips, stripe); + self->strips_len += 1; + } + else + { + end = TRUE; + break; + } + } + } + } + else + { + end = TRUE; + } + + if (end) + { + if (!self->stop && (self->strips_len > 0)) + { + FpImage *img; + self->strips = g_slist_reverse (self->strips); + fpi_do_movement_estimation (&assembling_ctx, self->strips); + img = fpi_assemble_frames (&assembling_ctx, self->strips); + img->flags |= (FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_PARTIAL); + g_slist_free_full (self->strips, g_free); + self->strips = NULL; + self->strips_len = 0; + FpImage *resizeImage = fpi_image_resize (img, EGIS0570_RESIZE, EGIS0570_RESIZE); + fpi_image_device_image_captured (img_self, resizeImage); + } + + fpi_image_device_report_finger_status (img_self, FALSE); + } + + fpi_ssm_next_state (transfer->ssm); +} + +static void +recv_data_resp (FpiSsm *ssm, FpDevice *dev) +{ + FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev); + + fpi_usb_transfer_fill_bulk (transfer, EGIS0570_EPIN, EGIS0570_INPSIZE); + + transfer->ssm = ssm; + transfer->short_is_error = TRUE; + + fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, data_resp_cb, NULL); +} + +static void +cmd_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error) +{ + if (error) + fpi_ssm_mark_failed (transfer->ssm, error); +} + +static void +recv_cmd_resp (FpiSsm *ssm, FpDevice *dev) +{ + FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev); + + fpi_usb_transfer_fill_bulk (transfer, EGIS0570_EPIN, EGIS0570_PKTSIZE); + + transfer->ssm = ssm; + + fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, cmd_resp_cb, NULL); +} + +static void +send_cmd_req (FpiSsm *ssm, FpDevice *dev, unsigned char *pkt) +{ + FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev); + + fpi_usb_transfer_fill_bulk_full (transfer, EGIS0570_EPOUT, pkt, EGIS0570_PKTSIZE, NULL); + + transfer->ssm = ssm; + transfer->short_is_error = TRUE; + + fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL); +} + +/* + * SSM States + */ + +enum sm_states { + SM_INIT, + SM_START, + SM_REQ, + SM_RESP, + SM_REC_DATA, + SM_DONE, + SM_STATES_NUM +}; + +static void +ssm_run_state (FpiSsm *ssm, FpDevice *dev) +{ + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + FpImageDevice *img_dev = FP_IMAGE_DEVICE (dev); + + switch (fpi_ssm_get_cur_state (ssm)) + { + case SM_INIT: + self->pkt_type = PKT_TYPE_INIT; + fpi_ssm_next_state (ssm); + break; + + case SM_START: + if (self->stop) + { + fp_dbg ("deactivating, marking completed"); + fpi_ssm_mark_completed (ssm); + fpi_image_device_deactivate_complete (img_dev, NULL); + } + else + { + self->pkt_num = 0; + fpi_ssm_next_state (ssm); + } + break; + + case SM_REQ: + if (self->pkt_type == PKT_TYPE_INIT) + send_cmd_req (ssm, dev, init_pkts[self->pkt_num]); + else + send_cmd_req (ssm, dev, repeat_pkts[self->pkt_num]); + break; + + case SM_RESP: + if (is_last_pkt (dev) == FALSE) + { + recv_cmd_resp (ssm, dev); + self->pkt_num += 1; + fpi_ssm_jump_to_state (ssm, SM_REQ); + } + else + { + if (self->pkt_type == PKT_TYPE_INIT) + self->pkt_type = PKT_TYPE_REPEAT; + + fpi_ssm_next_state (ssm); + } + break; + + case SM_REC_DATA: + recv_data_resp (ssm, dev); + break; + + case SM_DONE: + fpi_ssm_jump_to_state (ssm, SM_START); + break; + + default: + g_assert_not_reached (); + } +} + +/* + * Activation + */ + +static void +loop_complete (FpiSsm *ssm, FpDevice *dev, GError *error) +{ + FpImageDevice *img_dev = FP_IMAGE_DEVICE (dev); + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + + self->running = FALSE; + g_clear_pointer (&self->background, g_free); + + if (error) + fpi_image_device_session_error (img_dev, error); +} + +static void +dev_activate (FpImageDevice *dev) +{ + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), ssm_run_state, SM_STATES_NUM); + + self->stop = FALSE; + + fpi_ssm_start (ssm, loop_complete); + + self->running = TRUE; + + fpi_image_device_activate_complete (dev, NULL); +} + +/* + * Opening + */ + +static void +dev_init (FpImageDevice *dev) +{ + GError *error = NULL; + + g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error); + + fpi_image_device_open_complete (dev, error); +} + +/* + * Closing + */ + +static void +dev_deinit (FpImageDevice *dev) +{ + GError *error = NULL; + + g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error); + + fpi_image_device_close_complete (dev, error); +} + +/* + * Deactivation + */ + +static void +dev_deactivate (FpImageDevice *dev) +{ + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + + if (self->running) + self->stop = TRUE; + else + fpi_image_device_deactivate_complete (dev, NULL); +} + +/* + * Driver data + */ + +static const FpIdEntry id_table[] = { + { .vid = 0x1c7a, .pid = 0x0570, }, + { .vid = 0x1c7a, .pid = 0x0571, }, + { .vid = 0, .pid = 0, }, +}; + +static void +fpi_device_egis0570_init (FpDeviceEgis0570 *self) +{ +} + +static void +fpi_device_egis0570_class_init (FpDeviceEgis0570Class *klass) +{ + FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); + FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); + + dev_class->id = "egis0570"; + dev_class->full_name = "Egis Technology Inc. (aka. LighTuning) 0570"; + dev_class->type = FP_DEVICE_TYPE_USB; + dev_class->id_table = id_table; + dev_class->scan_type = FP_SCAN_TYPE_SWIPE; + + img_class->img_open = dev_init; + img_class->img_close = dev_deinit; + img_class->activate = dev_activate; + img_class->deactivate = dev_deactivate; + + img_class->img_width = EGIS0570_IMGWIDTH; + img_class->img_height = -1; + + img_class->bz3_threshold = EGIS0570_BZ3_THRESHOLD; /* security issue */ +} diff --git a/libfprint/drivers/egis0570.h b/libfprint/drivers/egis0570.h new file mode 100644 index 0000000..2c8f045 --- /dev/null +++ b/libfprint/drivers/egis0570.h @@ -0,0 +1,177 @@ +/* + * Egis Technology Inc. (aka. LighTuning) 0570 driver for libfprint + * Copyright (C) 2021 Maxim Kolesnikov + * Copyright (C) 2021 Saeed/Ali Rk + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EGIS0570_H + +#define __EGIS0570_H 1 + +/* + * Device data + */ + +#define EGIS0570_CONF 1 +#define EGIS0570_INTF 0 + +/* + * Device endpoints + */ + +#define EGIS0570_EPOUT 0x04 /* ( 4 | FPI_USB_ENDPOINT_OUT ) */ +#define EGIS0570_EPIN 0x83 /* ( 3 | FPI_USB_ENDPOINT_IN ) */ + +/* + * Initialization packets (7 bytes each) + * + * First 4 bytes are equivalent to string "EGIS", which must be just a company identificator + * Other 3 bytes are not recognized yet and may be not important, as they are always the same + + * Answers for each packet contain 7 bytes again + * First 4 bytes are reversed "EGIS", which is "SIGE", which is company ID again + * Other 3 bytes are not recognized yet + * But there is a pattern. + * Sending last packet makes sensor return image + */ + +#define EGIS0570_TIMEOUT 10000 +#define EGIS0570_PKTSIZE 7 + +#define EGIS0570_INIT_TOTAL (sizeof ((init_pkts)) / sizeof ((init_pkts[0]))) + +static unsigned char init_pkts[][EGIS0570_PKTSIZE] = +{ + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x20, 0x3f }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x58, 0x3f }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x21, 0x09 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x57, 0x09 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x22, 0x03 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x56, 0x03 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x23, 0x01 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x55, 0x01 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x24, 0x01 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x54, 0x01 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3e }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0b }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x03 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x00 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x38 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x00 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x71 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80 }, + { 0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x80 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f }, + { 0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe } /* image returned after this packet */ +}; + +/* There is another Packet ! + * That just Work the same !! + * And the Size is different !!! + */ + +/* + + #define EGIS0570_INIT_TOTAL2 (sizeof((init_pkts2)) / sizeof((init_pkts2[0]))) + + static unsigned char init_pkts2[][EGIS0570_PKTSIZE] = + { + {0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x38}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x71}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x20, 0x3f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x58, 0x3f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x21, 0x07}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x57, 0x07}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x22, 0x02}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x56, 0x02}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x23, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x55, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x24, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x54, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x25, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x53, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3b}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80}, + {0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x80}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f}, + {0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe} + }; + + */ + +/* + * After sending initial packets device returns image data (32512 bytes) + * To ask device to send image data again, host needs to send four additional packets + * Further work is to repeatedly send four repeat packets and read image data + */ + +#define EGIS0570_INPSIZE 32512 + +/* 5 image with captured in different time of size 114 * 57 = 6498 + * 5 * 6498 = 32490 plus 22 extra unrecognized char size data + * Two continuous image in this 5 images may have time delay of less than 20ms + */ + +#define EGIS0570_IMGSIZE 6498 +#define EGIS0570_IMGWIDTH 114 +#define EGIS0570_IMGHEIGHT 57 + +/* size of middle area that is used from each frame */ +#define EGIS0570_RFMGHEIGHT 17 +/* rows to ignore from top and bottom of the image*/ +#define EGIS0570_RFMDIS (EGIS0570_IMGHEIGHT - EGIS0570_RFMGHEIGHT) / 2 +#define EGIS0570_IMGCOUNT 5 + +/* + * Image repeat request + * First 4 bytes are the same as in initialization packets + * Have no idea what the other 3 bytes mean + */ + +#define EGIS0570_REPEAT_TOTAL (sizeof ((repeat_pkts)) / sizeof ((repeat_pkts[0]))) + +static unsigned char repeat_pkts[][EGIS0570_PKTSIZE] = +{ + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f }, + { 0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x0f }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f }, + { 0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe } /* image returned after this packet */ +}; + +/* + * This sensor is small so I decided to reduce bz3_threshold from + * 40 to 10 to have more success to fail ratio + * Bozorth3 Algorithm seems not fine at the end + * foreget about security :)) + */ + +#define EGIS0570_BZ3_THRESHOLD 25 /* and even less What a joke */ + +#define EGIS0570_MIN_MEAN 20 +#define EGIS0570_MARGIN 3 + +#define EGIS0570_RESIZE 2 + +#endif diff --git a/libfprint/fprint-list-udev-hwdb.c b/libfprint/fprint-list-udev-hwdb.c index 42df936..4d44cdf 100644 --- a/libfprint/fprint-list-udev-hwdb.c +++ b/libfprint/fprint-list-udev-hwdb.c @@ -75,7 +75,6 @@ static const FpIdEntry whitelist_id_table[] = { { .vid = 0x1491, .pid = 0x0088 }, { .vid = 0x16d1, .pid = 0x1027 }, { .vid = 0x1c7a, .pid = 0x0300 }, - { .vid = 0x1c7a, .pid = 0x0570 }, { .vid = 0x1c7a, .pid = 0x0575 }, { .vid = 0x27c6, .pid = 0x5042 }, { .vid = 0x27c6, .pid = 0x5110 }, diff --git a/libfprint/meson.build b/libfprint/meson.build index ef287f6..25ed10f 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -117,6 +117,8 @@ driver_sources = { [ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ], 'etes603' : [ 'drivers/etes603.c' ], + 'egis0570' : + [ 'drivers/egis0570.c' ], 'vfs0050' : [ 'drivers/vfs0050.c' ], 'elan' : diff --git a/meson.build b/meson.build index 72dee50..96a3634 100644 --- a/meson.build +++ b/meson.build @@ -113,6 +113,7 @@ default_drivers = [ 'vfs301', 'vfs0050', 'etes603', + 'egis0570', 'vcom5s', 'synaptics', 'elan', diff --git a/tests/egis0570/capture.pcapng b/tests/egis0570/capture.pcapng new file mode 100755 index 0000000..1f7ef8a Binary files /dev/null and b/tests/egis0570/capture.pcapng differ diff --git a/tests/egis0570/capture.png b/tests/egis0570/capture.png new file mode 100644 index 0000000..107fd6a Binary files /dev/null and b/tests/egis0570/capture.png differ diff --git a/tests/egis0570/device b/tests/egis0570/device new file mode 100644 index 0000000..e22dcf1 --- /dev/null +++ b/tests/egis0570/device @@ -0,0 +1,228 @@ +P: /devices/pci0000:00/0000:00:14.0/usb1/1-9 +N: bus/usb/001/005=12011001000000087A1C700541100102030109022000010100A0320904000002FF0000000705830240000007050402400003 +E: DEVNAME=/dev/bus/usb/001/005 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: PRODUCT=1c7a/570/1041 +E: TYPE=0/0/0 +E: BUSNUM=001 +E: DEVNUM=005 +E: MAJOR=189 +E: MINOR=4 +E: SUBSYSTEM=usb +E: ID_VENDOR=EgisTec +E: ID_VENDOR_ENC=EgisTec +E: ID_VENDOR_ID=1c7a +E: ID_MODEL=EgisTec_Touch_Fingerprint_Sensor +E: ID_MODEL_ENC=EgisTec\x20Touch\x20Fingerprint\x20Sensor +E: ID_MODEL_ID=0570 +E: ID_REVISION=1041 +E: ID_SERIAL=EgisTec_EgisTec_Touch_Fingerprint_Sensor_W700B41B +E: ID_SERIAL_SHORT=W700B41B +E: ID_BUS=usb +E: ID_USB_INTERFACES=:ff0000: +E: ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc. +E: ID_PATH=pci-0000:00:14.0-usb-0:9 +E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9 +E: LIBFPRINT_DRIVER=Hardcoded whitelist +A: authorized=1 +A: avoid_reset_quirk=0 +A: bConfigurationValue=1 +A: bDeviceClass=00 +A: bDeviceProtocol=00 +A: bDeviceSubClass=00 +A: bMaxPacketSize0=8 +A: bMaxPower=100mA +A: bNumConfigurations=1 +A: bNumInterfaces= 1 +A: bcdDevice=1041 +A: bmAttributes=a0 +A: busnum=1 +A: configuration= +H: descriptors=12011001000000087A1C700541100102030109022000010100A0320904000002FF0000000705830240000007050402400003 +A: dev=189:4 +A: devnum=5 +A: devpath=9 +L: driver=../../../../../bus/usb/drivers/usb +A: idProduct=0570 +A: idVendor=1c7a +A: ltm_capable=no +A: manufacturer=EgisTec +A: maxchild=0 +L: port=../1-0:1.0/usb1-port9 +A: power/active_duration=362352 +A: power/async=enabled +A: power/autosuspend=2 +A: power/autosuspend_delay_ms=2000 +A: power/connected_duration=5526124 +A: power/control=auto +A: power/level=auto +A: power/persist=1 +A: power/runtime_active_kids=0 +A: power/runtime_active_time=365097 +A: power/runtime_enabled=enabled +A: power/runtime_status=active +A: power/runtime_suspended_time=5160752 +A: power/runtime_usage=0 +A: power/wakeup=disabled +A: power/wakeup_abort_count= +A: power/wakeup_active= +A: power/wakeup_active_count= +A: power/wakeup_count= +A: power/wakeup_expire_count= +A: power/wakeup_last_time_ms= +A: power/wakeup_max_time_ms= +A: power/wakeup_total_time_ms= +A: product=EgisTec Touch Fingerprint Sensor +A: quirks=0x0 +A: removable=fixed +A: rx_lanes=1 +A: serial=W700B41B +A: speed=12 +A: tx_lanes=1 +A: urbnum=8040 +A: version= 1.10 + +P: /devices/pci0000:00/0000:00:14.0/usb1 +N: bus/usb/001/001=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C +E: DEVNAME=/dev/bus/usb/001/001 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: PRODUCT=1d6b/2/508 +E: TYPE=9/0/1 +E: BUSNUM=001 +E: DEVNUM=001 +E: MAJOR=189 +E: MINOR=0 +E: SUBSYSTEM=usb +E: ID_VENDOR=Linux_5.8.0-59-generic_xhci-hcd +E: ID_VENDOR_ENC=Linux\x205.8.0-59-generic\x20xhci-hcd +E: ID_VENDOR_ID=1d6b +E: ID_MODEL=xHCI_Host_Controller +E: ID_MODEL_ENC=xHCI\x20Host\x20Controller +E: ID_MODEL_ID=0002 +E: ID_REVISION=0508 +E: ID_SERIAL=Linux_5.8.0-59-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 +E: ID_SERIAL_SHORT=0000:00:14.0 +E: ID_BUS=usb +E: ID_USB_INTERFACES=:090000: +E: ID_VENDOR_FROM_DATABASE=Linux Foundation +E: ID_MODEL_FROM_DATABASE=2.0 root hub +E: ID_PATH=pci-0000:00:14.0 +E: ID_PATH_TAG=pci-0000_00_14_0 +E: ID_FOR_SEAT=usb-pci-0000_00_14_0 +E: TAGS=:seat: +A: authorized=1 +A: authorized_default=1 +A: avoid_reset_quirk=0 +A: bConfigurationValue=1 +A: bDeviceClass=09 +A: bDeviceProtocol=01 +A: bDeviceSubClass=00 +A: bMaxPacketSize0=64 +A: bMaxPower=0mA +A: bNumConfigurations=1 +A: bNumInterfaces= 1 +A: bcdDevice=0508 +A: bmAttributes=e0 +A: busnum=1 +A: configuration= +H: descriptors=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C +A: dev=189:0 +A: devnum=1 +A: devpath=0 +L: driver=../../../../bus/usb/drivers/usb +A: idProduct=0002 +A: idVendor=1d6b +A: interface_authorized_default=1 +A: ltm_capable=no +A: manufacturer=Linux 5.8.0-59-generic xhci-hcd +A: maxchild=12 +A: power/active_duration=378024 +A: power/async=enabled +A: power/autosuspend=0 +A: power/autosuspend_delay_ms=0 +A: power/connected_duration=5527220 +A: power/control=auto +A: power/level=auto +A: power/runtime_active_kids=1 +A: power/runtime_active_time=377962 +A: power/runtime_enabled=enabled +A: power/runtime_status=active +A: power/runtime_suspended_time=5149253 +A: power/runtime_usage=0 +A: power/wakeup=disabled +A: power/wakeup_abort_count= +A: power/wakeup_active= +A: power/wakeup_active_count= +A: power/wakeup_count= +A: power/wakeup_expire_count= +A: power/wakeup_last_time_ms= +A: power/wakeup_max_time_ms= +A: power/wakeup_total_time_ms= +A: product=xHCI Host Controller +A: quirks=0x0 +A: removable=unknown +A: rx_lanes=1 +A: serial=0000:00:14.0 +A: speed=480 +A: tx_lanes=1 +A: urbnum=956 +A: version= 2.00 + +P: /devices/pci0000:00/0000:00:14.0 +E: DRIVER=xhci_hcd +E: PCI_CLASS=C0330 +E: PCI_ID=8086:9D2F +E: PCI_SUBSYS_ID=1025:118E +E: PCI_SLOT_NAME=0000:00:14.0 +E: MODALIAS=pci:v00008086d00009D2Fsv00001025sd0000118Ebc0Csc03i30 +E: SUBSYSTEM=pci +E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller +E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller +E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI +E: ID_VENDOR_FROM_DATABASE=Intel Corporation +E: ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller +A: ari_enabled=0 +A: broken_parity_status=0 +A: class=0x0c0330 +H: config=86802F9D060490022130030C00008000040021A400000000000000000000000000000000000000000000000025108E11000000007000000000000000FF010000 +A: consistent_dma_mask_bits=64 +A: d3cold_allowed=1 +A: dbc=disabled +A: device=0x9d2f +A: dma_mask_bits=64 +L: driver=../../../bus/pci/drivers/xhci_hcd +A: driver_override=(null) +A: enable=1 +A: irq=127 +A: local_cpulist=0-7 +A: local_cpus=ff +A: modalias=pci:v00008086d00009D2Fsv00001025sd0000118Ebc0Csc03i30 +A: msi_bus=1 +A: msi_irqs/127=msi +A: numa_node=-1 +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 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 9 10 2112 10\nxHCI ring segments 32 36 4096 36\nbuffer-2048 1 2 2048 1\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0 +A: power/async=enabled +A: power/control=on +A: power/runtime_active_kids=1 +A: power/runtime_active_time=5524703 +A: power/runtime_enabled=forbidden +A: power/runtime_status=active +A: power/runtime_suspended_time=3373 +A: power/runtime_usage=1 +A: power/wakeup=enabled +A: power/wakeup_abort_count=0 +A: power/wakeup_active=0 +A: power/wakeup_active_count=0 +A: power/wakeup_count=0 +A: power/wakeup_expire_count=0 +A: power/wakeup_last_time_ms=0 +A: power/wakeup_max_time_ms=0 +A: power/wakeup_total_time_ms=0 +A: resource=0x00000000a4210000 0x00000000a421ffff 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 +A: revision=0x21 +A: subsystem_device=0x118e +A: subsystem_vendor=0x1025 +A: vendor=0x8086 + diff --git a/tests/meson.build b/tests/meson.build index 394ded2..a64936a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -33,6 +33,7 @@ drivers_tests = [ 'vfs7552', 'goodixmoc', 'nb1010', + 'egis0570', ] if get_option('introspection')