diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb index 9d1fd351..c608cd51 100644 --- a/data/autosuspend.hwdb +++ b/data/autosuspend.hwdb @@ -77,6 +77,11 @@ usb:v1C7Ap0571* ID_AUTOSUSPEND=1 ID_PERSIST=0 +# Supported by libfprint driver egis0576 +usb:v1C7Ap0576* + ID_AUTOSUSPEND=1 + ID_PERSIST=0 + # Supported by libfprint driver egismoc usb:v1C7Ap0582* usb:v1C7Ap0583* @@ -444,7 +449,6 @@ usb:v1491p0088* usb:v16D1p1027* usb:v1C7Ap0300* usb:v1C7Ap0575* -usb:v1C7Ap0576* usb:v1C7Ap0577* usb:v1C7Ap057E* usb:v2541p0236* diff --git a/libfprint/drivers/egis0576.c b/libfprint/drivers/egis0576.c new file mode 100644 index 00000000..27e9cd6a --- /dev/null +++ b/libfprint/drivers/egis0576.c @@ -0,0 +1,614 @@ +/* + * Egis Technology Inc. (aka. LighTuning) 0576 driver for libfprint + * Copyright (C) 2026 Marcel (Sprayxe) + * + * 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 "egis0576" + +#include "egis0576.h" + +#include "drivers_api.h" + +/* Sequence types */ +typedef enum { + SEQ_INIT, + SEQ_REPEAT, + SEQ_POLL, + SEQ_IMAGE +} seq_types; + +/* SSM States */ +enum sm_states { + DEV_OPEN, + DEV_START, + DEV_REQ, + DEV_RESP, + DEV_FULFILLED, + NUM_STATES +}; + +/* Struct */ +struct _FpDeviceEgis0576 +{ + FpImageDevice parent; + + gboolean running; + gboolean stop; + + gboolean has_background; + guchar background[EGIS0576_IMG_SIZE]; + + seq_types seq_type; + int seq_pkt_index; + Egis0576Pkt last_sent_pkt; +}; +G_DECLARE_FINAL_TYPE (FpDeviceEgis0576, fpi_device_egis0576, FPI, DEVICE_EGIS0576, FpImageDevice); +G_DEFINE_TYPE (FpDeviceEgis0576, fpi_device_egis0576, FP_TYPE_IMAGE_DEVICE); + +/* + * ======================== + * Processing + * ======================== + */ +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +static void +normalize_img (guchar *bg, guchar *img, double *dark_portion) +{ + // Find diffs, min and max + int diff[EGIS0576_IMG_SIZE]; + int min = 255; + int max = 0; + + for (int i = 0; i < EGIS0576_IMG_SIZE; i++) + { + diff[i] = (int) bg[i] - (int) img[i]; + if (diff[i] < min) + min = diff[i]; + if (diff[i] > max) + max = diff[i]; + } + + max -= EGIS0576_CONTRAST; + min += EGIS0576_CONTRAST; + int range = max - min; + if (range == 0) + range = 1; // Prevent division by zero + + // Adjust contrast / normalize + int count_ridges = 0; + for (int i = 0; i < EGIS0576_IMG_SIZE; i++) + { + int normalized = ((diff[i] - min) * 255) / range; + + if (normalized < 0) + normalized = 0; + else if (normalized > 255) + normalized = 255; + + img[i] = (unsigned char) normalized; + if (img[i] < 170) + count_ridges++; + } + + *dark_portion = (double) count_ridges / EGIS0576_IMG_SIZE; +} + +/* Uses bilinear interpolation */ +static void +upscale_img (guchar *src_img, guchar *dst_img) +{ + const int scale = EGIS0576_IMG_UPSCALE; + const int src_w = EGIS0576_IMG_WIDTH; + const int src_h = EGIS0576_IMG_HEIGHT; + const int dst_w = EGIS0576_IMG_WIDTH_UPSCALE; + const int dst_h = EGIS0576_IMG_HEIGHT_UPSCALE; + + for (int y = 0; y < dst_h; y++) + { + float gy = ((float) y) / scale; + int y1 = (int) gy; + int y2 = (y1 >= src_h - 1) ? src_h - 1 : y1 + 1; + float ty = gy - y1; + + for (int x = 0; x < dst_w; x++) + { + float gx = ((float) x) / scale; + int x1 = (int) gx; + int x2 = (x1 >= src_w - 1) ? src_w - 1 : x1 + 1; + float tx = gx - x1; + + float p00 = src_img[y1 * src_w + x1]; // Top left + float p10 = src_img[y1 * src_w + x2]; // Top right + float p01 = src_img[y2 * src_w + x1]; // Bottom left + float p11 = src_img[y2 * src_w + x2]; // Bottom right + + // Interp. horizontally across the top and bottom + float top_p = p00 * (1.0f - tx) + p10 * tx; + float bottom_p = p01 * (1.0f - tx) + p11 * tx; + + // Interp. vertically between the two horizontal results + float pixel = top_p * (1.0f - ty) + bottom_p * ty; + + // Round instead of floor, just better practice + dst_img[y * dst_w + x] = (guchar) (pixel + 0.5f); + } + } +} + +/* + * As it is already known, libfprint has trouble processing very small images. + * Therefore the 'trick' is to create a canvas that is big enough to be liked by libfprint, + * fill it with 255 (white background) and put an upscaled version of the sensor image into the + * center of that canvas. + */ +static void +upscale_and_pad_img (guchar *img, guchar *canvas) +{ + const int img_width = EGIS0576_IMG_WIDTH_UPSCALE; + const int img_height = EGIS0576_IMG_HEIGHT_UPSCALE; + + // Upscale sensor image + guchar upscaled_img[EGIS0576_IMG_SIZE_UPSCALE]; + + upscale_img (img, upscaled_img); + + // Prepare canvas + memset (canvas, 255, EGIS0576_CANVAS_SIZE); + int offset_x = (EGIS0576_CANVAS_WIDTH - img_width) / 2; + int offset_y = (EGIS0576_CANVAS_HEIGHT - img_height) / 2; + + for (int y = 0; y < img_height; y++) + { + for (int x = 0; x < img_width; x++) + { + int dest_y = y + offset_y; + int dest_x = x + offset_x; + + canvas[dest_y * EGIS0576_CANVAS_WIDTH + dest_x] = upscaled_img[y * img_width + x]; + } + } +} + +static void +process_finger (FpDevice *dev, FpiUsbTransfer *transfer) +{ + FpImageDevice *img_self = FP_IMAGE_DEVICE (dev); + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + + guchar *img = transfer->buffer; + + gint variance = fpi_std_sq_dev (img, EGIS0576_IMG_SIZE); + + if (!self->has_background) + { + /* Background has been gathered, user can put finger on sensor. */ + if (variance < EGIS0576_BG_VARIANCE) + { + memcpy (self->background, img, EGIS0576_IMG_SIZE); + self->has_background = TRUE; + + fpi_device_report_finger_status (dev, FP_FINGER_STATUS_NEEDED); + + self->seq_type = SEQ_REPEAT; + fpi_ssm_next_state_delayed (transfer->ssm, 50); + return; + } + + /* User should remove finger so the driver can grab a clear image. */ + fpi_image_device_retry_scan (img_self, FP_DEVICE_RETRY_REMOVE_FINGER); + + self->seq_type = SEQ_REPEAT; + fpi_ssm_next_state_delayed (transfer->ssm, 500); + return; + } + + gboolean finger_present = FALSE; + double dark_portion = -1; + if (variance > EGIS0576_VARIANCE) + { + normalize_img (self->background, img, &dark_portion); + finger_present = dark_portion > EGIS0576_DARK_PORTION; + } + + fp_dbg ("Finger status (present, variance, dark port) : " + "%d , %d, %.2f", + finger_present, variance, dark_portion); + + if (!finger_present) + { + self->seq_type = SEQ_REPEAT; + fpi_image_device_report_finger_status (img_self, FALSE); + fpi_ssm_next_state_delayed (transfer->ssm, 50); + return; + } + + FpImage *fp_img = fp_image_new (EGIS0576_CANVAS_WIDTH, EGIS0576_CANVAS_HEIGHT); + /* Sensor returns full image */ + upscale_and_pad_img (img, fp_img->data); + + fpi_image_device_report_finger_status (img_self, TRUE); + fpi_image_device_image_captured (img_self, fp_img); + + fpi_ssm_next_state_delayed (transfer->ssm, 50); +} + +static void +process_poll_transfer (FpDevice *dev, FpiUsbTransfer *transfer) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + + if (transfer->actual_length < 6) + { + GError *error + = fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, "Device reported invalid poll."); + fpi_ssm_mark_failed (transfer->ssm, error); + g_error_free (error); + return; + } + + if ((transfer->buffer[6] & 0x01) == 0x01) + { + self->seq_type = SEQ_IMAGE; + fpi_ssm_jump_to_state (transfer->ssm, DEV_REQ); + return; + } + + self->seq_pkt_index += 1; + if (self->seq_pkt_index < EGIS0576_POLL_COUNT) + { + fpi_ssm_jump_to_state (transfer->ssm, DEV_REQ); + return; + } + + GError *error + = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "Device exceeded maximum poll count."); + fpi_ssm_mark_failed (transfer->ssm, error); + g_error_free (error); +} + +/* Verifies that received data is processable. */ +static void +process_image_transfer (FpDevice *dev, FpiUsbTransfer *transfer) +{ + guchar *buffer = transfer->buffer; + gssize buffer_len = transfer->actual_length; + + if (buffer_len != EGIS0576_IMG_SIZE) + { + GError *error = fpi_device_error_new_msg ( + FP_DEVICE_ERROR_DATA_INVALID, "Device image data size does not match expected size."); + fpi_ssm_mark_failed (transfer->ssm, error); + g_error_free (error); + return; + } + + uint sum = 0; + /* Roughly check whether the buffer is empty aka invalid. */ + for (int i = 0; i < MIN (buffer_len, 255); i++) + sum += buffer[i]; + + /* No/invalid data was present. */ + if (sum == 0) + { + GError *error + = fpi_device_error_new_msg (FP_DEVICE_ERROR_DATA_INVALID, "Device reported invalid data."); + fpi_ssm_mark_failed (transfer->ssm, error); + g_error_free (error); + return; + } + + process_finger (dev, transfer); +} + +/* + * ======================== + * I / O + * ======================== + */ +static void +cmd_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + + if (error) + { + fp_dbg ("During the %d sequence an error occurred at pkt index %d", self->seq_type, + self->seq_pkt_index); + fpi_ssm_mark_failed (transfer->ssm, error); + return; + } + + switch (self->seq_type) + { + /* not processed */ + case SEQ_INIT: + case SEQ_REPEAT: + fpi_ssm_jump_to_state (transfer->ssm, DEV_REQ); + break; + + case SEQ_POLL: + process_poll_transfer (dev, transfer); + break; + + case SEQ_IMAGE: + process_image_transfer (dev, transfer); + break; + } +} + +static void +recv_cmd_resp (FpiSsm *ssm, FpDevice *dev, Egis0576Pkt last_pkt) +{ + FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev); + + fpi_usb_transfer_fill_bulk (transfer, EGIS0576_EPIN, last_pkt.res_len); + + transfer->ssm = ssm; + + fpi_usb_transfer_submit (transfer, EGIS0576_TIMEOUT, NULL, cmd_resp_cb, NULL); +} + +static void +send_cmd_req (FpiSsm *ssm, FpDevice *dev, Egis0576Pkt pkt) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev); + + self->last_sent_pkt = pkt; + fpi_usb_transfer_fill_bulk_full (transfer, EGIS0576_EPOUT, pkt.cmd, pkt.len, NULL); + + transfer->ssm = ssm; + transfer->short_is_error = TRUE; + + fpi_usb_transfer_submit (transfer, EGIS0576_TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL); +} + +static gboolean +init_repeat_last_pkt (FpDevice *dev) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + + int type = self->seq_type; + int index = self->seq_pkt_index; + + return (type == SEQ_INIT && index == EGIS0576_INIT_PACKETS_LENGTH - 1) || + (type == SEQ_REPEAT && index == EGIS0576_REPEAT_PACKETS_LENGTH - 1); +} + +static void +recv_cmd (FpiSsm *ssm, FpDevice *dev) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + Egis0576Pkt last_pkt = self->last_sent_pkt; + + switch (self->seq_type) + { + case SEQ_INIT: + case SEQ_REPEAT: + if (!init_repeat_last_pkt (dev)) + { + recv_cmd_resp (ssm, dev, last_pkt); + self->seq_pkt_index += 1; + } + else + { + self->seq_pkt_index = 0; + self->seq_type = SEQ_POLL; + fpi_ssm_jump_to_state (ssm, DEV_REQ); + } + + break; + + case SEQ_POLL: + case SEQ_IMAGE: + recv_cmd_resp (ssm, dev, last_pkt); + break; + } +} + +static void +send_cmd (FpiSsm *ssm, FpDevice *dev) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + + switch (self->seq_type) + { + case SEQ_INIT: + send_cmd_req (ssm, dev, EGIS0576_INIT_PACKETS[self->seq_pkt_index]); + break; + + case SEQ_REPEAT: + send_cmd_req (ssm, dev, EGIS0576_REPEAT_PACKETS[self->seq_pkt_index]); + break; + + case SEQ_POLL: + send_cmd_req (ssm, dev, EGIS0576_POLL_PACKET); + break; + + case SEQ_IMAGE: + send_cmd_req (ssm, dev, EGIS0576_IMAGE_PACKET); + break; + } +} + +static void +ssm_run_state (FpiSsm *ssm, FpDevice *dev) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + + switch (fpi_ssm_get_cur_state (ssm)) + { + case DEV_OPEN: + self->seq_type = SEQ_INIT; + fpi_ssm_jump_to_state (ssm, DEV_START); + break; + + case DEV_START: + if (self->stop) + { + fp_dbg ("Deactivating device, marking completed."); + fpi_ssm_mark_completed (ssm); + return; + } + + self->seq_pkt_index = 0; + fpi_ssm_jump_to_state (ssm, DEV_REQ); + break; + + case DEV_REQ: + send_cmd (ssm, dev); + break; + + case DEV_RESP: + recv_cmd (ssm, dev); + break; + + case DEV_FULFILLED: + fpi_ssm_jump_to_state (ssm, DEV_START); + break; + + default: + g_assert_not_reached (); + } +} + +/* + * ======================== + * SETUP + * ======================== + */ + +static void +sm_cb (FpiSsm *ssm, FpDevice *dev, GError *error) +{ + FpImageDevice *img_dev = FP_IMAGE_DEVICE (dev); + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + + self->running = FALSE; + + if (error && !self->stop) + fpi_image_device_session_error (img_dev, error); + else if (error) + g_error_free (error); + + if (self->stop) + fpi_image_device_deactivate_complete (img_dev, NULL); +} + +/* + * Device activate + */ +static void +dev_activate (FpImageDevice *dev) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), ssm_run_state, NUM_STATES); + + self->stop = FALSE; + + fpi_ssm_start (ssm, sm_cb); + + self->running = TRUE; + + fpi_image_device_activate_complete (dev, NULL); +} + +/* + * Img open + */ +static void +dev_init (FpImageDevice *dev) +{ + GError *error = NULL; + + g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), EGIS0576_INTF, 0, &error); + + fpi_image_device_open_complete (dev, error); +} + +/* + * Img close + */ +static void +dev_deinit (FpImageDevice *dev) +{ + GError *error = NULL; + + g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), EGIS0576_INTF, 0, + &error); + + fpi_image_device_close_complete (dev, error); +} + +/* + * Device deactivate + */ +static void +dev_deactivate (FpImageDevice *dev) +{ + FpDeviceEgis0576 *self = FPI_DEVICE_EGIS0576 (dev); + + if (self->running) + self->stop = TRUE; + else + fpi_image_device_deactivate_complete (dev, NULL); +} + +/* + * Driver ID + */ +static const FpIdEntry id_table[] = { + { + .vid = 0x1c7a, + .pid = 0x0576, + }, + { + .vid = 0, + .pid = 0, + }, +}; + +static void +fpi_device_egis0576_init (FpDeviceEgis0576 *self) +{ +} + +static void +fpi_device_egis0576_class_init (FpDeviceEgis0576Class *klass) +{ + FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass); + FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass); + + dev_class->id = "egis0576"; + dev_class->full_name = "Egis Technology Inc. (aka. LighTuning) 0576"; + dev_class->type = FP_DEVICE_TYPE_USB; + dev_class->id_table = id_table; + dev_class->scan_type = FP_SCAN_TYPE_PRESS; + dev_class->nr_enroll_stages = 20; + dev_class->temp_hot_seconds = 0; + + 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 = EGIS0576_CANVAS_WIDTH; + img_class->img_height = EGIS0576_CANVAS_HEIGHT; + + img_class->bz3_threshold = 10; /* security issue, can score more but not reliably */ +} diff --git a/libfprint/drivers/egis0576.h b/libfprint/drivers/egis0576.h new file mode 100644 index 00000000..a683b3af --- /dev/null +++ b/libfprint/drivers/egis0576.h @@ -0,0 +1,205 @@ +/* + * Egis Technology Inc. (aka. LighTuning) 0576 driver for libfprint + * Copyright (C) 2026 Marcel (Sprayxe) + * + * 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 + */ + +/* Device config */ +#define EGIS0576_INTF 0 + +/* Device endpoints */ +#define EGIS0576_EPOUT 0x01 +#define EGIS0576_EPIN 0x82 + +/* Device transfers */ +#define EGIS0576_TIMEOUT 10000 +#define EGIS0576_POLL_COUNT 3000 + +/* Sensor image */ +#define EGIS0576_IMG_WIDTH 70 +#define EGIS0576_IMG_HEIGHT 57 +#define EGIS0576_IMG_SIZE ((EGIS0576_IMG_WIDTH) *(EGIS0576_IMG_HEIGHT)) + +/* Upscaled sensor image */ +#define EGIS0576_IMG_UPSCALE 2 +#define EGIS0576_IMG_WIDTH_UPSCALE ((EGIS0576_IMG_WIDTH) *(EGIS0576_IMG_UPSCALE)) +#define EGIS0576_IMG_HEIGHT_UPSCALE ((EGIS0576_IMG_HEIGHT) *(EGIS0576_IMG_UPSCALE)) +#define EGIS0576_IMG_SIZE_UPSCALE ((EGIS0576_IMG_WIDTH_UPSCALE) *(EGIS0576_IMG_HEIGHT_UPSCALE)) + +/* Canvas image */ +#define EGIS0576_CANVAS_WIDTH 256 +#define EGIS0576_CANVAS_HEIGHT 256 +#define EGIS0576_CANVAS_SIZE ((EGIS0576_CANVAS_WIDTH) *(EGIS0576_CANVAS_HEIGHT)) + +/* + * These values were acquired by testing with finger present and without finger + * present. + */ +#define EGIS0576_CONTRAST 4 +#define EGIS0576_VARIANCE (3.2 * 3.2) +#define EGIS0576_DARK_PORTION 0.05 +#define EGIS0576_BG_VARIANCE (2.5 * 2.5) + +/* + * + * All packets work like this: + * E G I S + * 0x45, 0x47, 0x49, 0x53, [CMD], [REG], [VALUE(s)] + * + * [CMD] = Command + * [REG] = Register + * [VALUE(s)] = Values to write or read + * [CMD] seem to be: + * 0x60: Read [REG] + * - [VALUE] is set to 0x00? Not sure, 0575 pkts sometimes had a value but 0x00 + * seems to work + * + * 0x61: Write [VALUE] into [REG] + * - [VALUE] is the single byte to write + * + * 0x62: Read starting from [REG] (burst read) + * - [VALUE] is the amount of bytes to read + * + * 0x63: Write starting from [REG] (burst read) + * - [VALUE] consists of: [AMOUNT OF BYTES TO WRITE], [BYTES TO WRITE] + * - example: "0x63, 0x01, 0x02, 0x0f, 0x03" + * -> 0x63 [CMD]; 0x01 [REG]; 0x02 [two bytes]; 0x0f, 0x03 [bytes] + * + * 0x64: Seems to be the command that fetches image data + * - no separate [REG] or [VALUE] + * - it is just the image size (width * size), in our case 70 * 57 = 3990 + * (0x0f96) + * -> So the command is "0x64, 0x0f, 0x96" + * + * Responses always (except the image response) echo back: + * S I G E + * 0x53, 0x49, 0x47, 0x45, ...[CMD], [REG], [VALUE(s)] ? + */ +typedef struct +{ + int len; + unsigned char *cmd; + int res_len; +} Egis0576Pkt; + +/* + * Huge credit goes to Animeshz's efforts on github + * (https://github.com/Animeshz/EgisTec-EH575) + * and on libfprint + * (https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/317) as + * those laid the base for this effort. + * + * Initial tests proved that the EH0575 and the EH0576 seem to work basically + * the same as by just providing the EH0575 packets I was able to occasionally + * get little data out of mine. + * + * I was unable to get the fingerprint reader to work in a VM (both Win10 and + * Win11) and Wireshark USBcap does not allow to be run on Windows-To-Go so I + * could not use any USB captures from Windows. + * + * Therefore, the rest of the reverse engineering was solely done with static + * analysis in Ghidra of the EgisTouchFP0576.dll UMDF driver provided + * by Lenovo + * (https://pcsupport.lenovo.com/de/en/products/laptops-and-netbooks/flex-series/flex-5-14alc7). + * I am no professional "hacker" by any means so I cannot guarantee that these + * are 100% correct but they work :D + */ + +/* + * According to static analysis the driver polls using this packet a max. amount + * of EGIS0576_POLL_COUNT before requesting the image. + * Translated to this driver it checks the following condition in order to + * proceed to requesting the image: + * + * (response_buffer[6] & 0x01) == 0x01 + * + * Based on observation this has been always true for already the first request + * so it essentially runs once. + */ +static const Egis0576Pkt EGIS0576_POLL_PACKET + = { .len = 7, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0x00 }, + .res_len = 9 }; + +/* Fetches the image data. */ +static const Egis0576Pkt EGIS0576_IMAGE_PACKET + = { .len = 7, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x64, 0x0f, 0x96 }, + .res_len = EGIS0576_IMG_SIZE }; + +/* Initialization packets. */ +#define EGIS0576_INIT_PACKETS_LENGTH 30 +static const Egis0576Pkt EGIS0576_INIT_PACKETS[] = { + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x01, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x10, 0xfd }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x35, 0x02 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x80, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x80, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x10, 0xfc }, .res_len = 7 }, + { .len = 9, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x63, 0x01, 0x02, 0x0f, 0x03 }, + .res_len = 9 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x0c, 0x22 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x09, 0x83 }, .res_len = 7 }, + { .len = 13, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x63, 0x26, 0x06, 0x06, 0x60, 0x06, 0x05, + 0x2f, 0x06 }, + .res_len = 13 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x10, 0xf4 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x0c, 0x44 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x50, 0x03 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x50, 0x00 }, .res_len = 7 }, + EGIS0576_IMAGE_PACKET, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x40, 0x00 }, .res_len = 7 }, + { .len = 18, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x63, 0x09, 0x0b, 0x83, 0x24, 0x00, 0x44, + 0x0f, 0x08, 0x20, 0x20, 0x00, 0x00, 0x52 }, + .res_len = 18 }, + { .len = 13, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x63, 0x26, 0x06, 0x06, 0x60, 0x06, 0x05, + 0x2f, 0x06 }, + .res_len = 13 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x23, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x24, 0x38 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x20, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x61, 0x21, 0x45 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x01, 0x00 }, .res_len = 7 }, + { .len = 9, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x63, 0x2c, 0x02, 0x00, 0x57 }, + .res_len = 9 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x2d, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x62, 0x67, 0x03 }, .res_len = 10 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x0f, 0x00 }, .res_len = 7 }, + { .len = 9, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x63, 0x2c, 0x02, 0x00, 0x13 }, + .res_len = 9 } +}; + +/* Repeat packets. */ +#define EGIS0576_REPEAT_PACKETS_LENGTH 5 +static const Egis0576Pkt EGIS0576_REPEAT_PACKETS[] = { + { .len = 9, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x63, 0x2c, 0x02, 0x00, 0x57 }, + .res_len = 9 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x2d, 0x00 }, .res_len = 7 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x62, 0x67, 0x03 }, .res_len = 10 }, + { .len = 7, .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x60, 0x0f, 0x00 }, .res_len = 7 }, + { .len = 9, + .cmd = (unsigned char[]){ 0x45, 0x47, 0x49, 0x53, 0x63, 0x2c, 0x02, 0x00, 0x13 }, + .res_len = 9 } +}; diff --git a/libfprint/fprint-list-udev-hwdb.c b/libfprint/fprint-list-udev-hwdb.c index 6e2adb04..36126981 100644 --- a/libfprint/fprint-list-udev-hwdb.c +++ b/libfprint/fprint-list-udev-hwdb.c @@ -122,7 +122,6 @@ static const FpIdEntry allowlist_id_table[] = { { .vid = 0x16d1, .pid = 0x1027 }, { .vid = 0x1c7a, .pid = 0x0300 }, { .vid = 0x1c7a, .pid = 0x0575 }, - { .vid = 0x1c7a, .pid = 0x0576 }, { .vid = 0x1c7a, .pid = 0x0577 }, { .vid = 0x1c7a, .pid = 0x057e }, { .vid = 0x2541, .pid = 0x0236 }, diff --git a/libfprint/meson.build b/libfprint/meson.build index ae0f6e24..3f34fbf5 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -125,6 +125,8 @@ driver_sources = { [ 'drivers/etes603.c' ], 'egis0570' : [ 'drivers/egis0570.c' ], + 'egis0576' : + [ 'drivers/egis0576.c' ], 'egismoc' : [ 'drivers/egismoc/egismoc.c' ], 'vfs0050' : diff --git a/meson.build b/meson.build index 14fb11f2..faecc168 100644 --- a/meson.build +++ b/meson.build @@ -130,6 +130,7 @@ default_drivers = [ 'vfs0050', 'etes603', 'egis0570', + 'egis0576', 'egismoc', 'vcom5s', 'synaptics', diff --git a/tests/egis0576/capture.pcapng b/tests/egis0576/capture.pcapng new file mode 100644 index 00000000..dd1c2160 Binary files /dev/null and b/tests/egis0576/capture.pcapng differ diff --git a/tests/egis0576/capture.png b/tests/egis0576/capture.png new file mode 100644 index 00000000..b1e6c7ee Binary files /dev/null and b/tests/egis0576/capture.png differ diff --git a/tests/egis0576/device b/tests/egis0576/device new file mode 100644 index 00000000..b033b3bc --- /dev/null +++ b/tests/egis0576/device @@ -0,0 +1,336 @@ +P: /devices/pci0000:00/0000:00:08.1/0000:04:00.4/usb3/3-3 +N: bus/usb/003/002=12010002FF0000407A1C760572150102030109022E00010100A0320904000004FFFF000007050102000200070582020002000705830310000807058403100008 +E: BUSNUM=003 +E: DEVNAME=/dev/bus/usb/003/002 +E: DEVNUM=002 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: ID_AUTOSUSPEND=1 +E: ID_BUS=usb +E: ID_MODEL=EgisTec_EH576 +E: ID_MODEL_ENC=EgisTec\x20EH576 +E: ID_MODEL_ID=0576 +E: ID_PATH=pci-0000:04:00.4-usb-0:3 +E: ID_PATH_TAG=pci-0000_04_00_4-usb-0_3 +E: ID_PATH_WITH_USB_REVISION=pci-0000:04:00.4-usbv2-0:3 +E: ID_PERSIST=0 +E: ID_REVISION=1572 +E: ID_SERIAL=EgisTec_EgisTec_EH576_16D94AAD +E: ID_SERIAL_SHORT=16D94AAD +E: ID_USB_INTERFACES=:ffff00: +E: ID_USB_MODEL=EgisTec_EH576 +E: ID_USB_MODEL_ENC=EgisTec\x20EH576 +E: ID_USB_MODEL_ID=0576 +E: ID_USB_REVISION=1572 +E: ID_USB_SERIAL=EgisTec_EgisTec_EH576_16D94AAD +E: ID_USB_SERIAL_SHORT=16D94AAD +E: ID_USB_VENDOR=EgisTec +E: ID_USB_VENDOR_ENC=EgisTec +E: ID_USB_VENDOR_ID=1c7a +E: ID_VENDOR=EgisTec +E: ID_VENDOR_ENC=EgisTec +E: ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc. +E: ID_VENDOR_ID=1c7a +E: MAJOR=189 +E: MINOR=257 +E: PRODUCT=1c7a/576/1572 +E: SUBSYSTEM=usb +E: TYPE=255/0/0 +E: __DEVCONTEXT=system_u:object_r:usb_device_t:s0 +A: authorized=1\n +A: avoid_reset_quirk=0\n +A: bConfigurationValue=1\n +A: bDeviceClass=ff\n +A: bDeviceProtocol=00\n +A: bDeviceSubClass=00\n +A: bMaxPacketSize0=64\n +A: bMaxPower=100mA\n +A: bNumConfigurations=1\n +A: bNumInterfaces= 1\n +A: bcdDevice=1572\n +A: bmAttributes=a0\n +A: busnum=3\n +A: configuration= +H: descriptors=12010002FF0000407A1C760572150102030109022E00010100A0320904000004FFFF000007050102000200070582020002000705830310000807058403100008 +A: dev=189:257\n +A: devnum=2\n +A: devpath=3\n +L: driver=../../../../../../bus/usb/drivers/usb +L: firmware_node=../../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:10/device:1f/device:20/device:23 +A: idProduct=0576\n +A: idVendor=1c7a\n +A: ltm_capable=no\n +A: manufacturer=EgisTec\n +A: maxchild=0\n +A: physical_location/dock=no\n +A: physical_location/horizontal_position=left\n +A: physical_location/lid=no\n +A: physical_location/panel=top\n +A: physical_location/vertical_position=upper\n +L: port=../3-0:1.0/usb3-port3 +A: power/active_duration=80374\n +A: power/autosuspend=2\n +A: power/autosuspend_delay_ms=2000\n +A: power/connected_duration=1434654\n +A: power/control=auto\n +A: power/level=auto\n +A: power/persist=0\n +A: power/runtime_active_time=80414\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=1353999\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=EgisTec EH576\n +A: quirks=0x0\n +A: removable=fixed\n +A: rx_lanes=1\n +A: serial=16D94AAD\n +A: speed=480\n +A: tx_lanes=1\n +A: urbnum=1516\n +A: version= 2.00\n + +P: /devices/pci0000:00/0000:00:08.1/0000:04:00.4/usb3 +N: bus/usb/003/001=12010002090001406B1D020018060302010109021900010100E0000904000001090000000705810304000C +E: BUSNUM=003 +E: CURRENT_TAGS=:seat: +E: DEVNAME=/dev/bus/usb/003/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_04_00_4 +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:04:00.4 +E: ID_PATH_TAG=pci-0000_04_00_4 +E: ID_REVISION=0618 +E: ID_SERIAL=Linux_6.18.13-200.fc43.x86_64_xhci-hcd_xHCI_Host_Controller_0000:04:00.4 +E: ID_SERIAL_SHORT=0000:04:00.4 +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=0618 +E: ID_USB_SERIAL=Linux_6.18.13-200.fc43.x86_64_xhci-hcd_xHCI_Host_Controller_0000:04:00.4 +E: ID_USB_SERIAL_SHORT=0000:04:00.4 +E: ID_USB_VENDOR=Linux_6.18.13-200.fc43.x86_64_xhci-hcd +E: ID_USB_VENDOR_ENC=Linux\x206.18.13-200.fc43.x86_64\x20xhci-hcd +E: ID_USB_VENDOR_ID=1d6b +E: ID_VENDOR=Linux_6.18.13-200.fc43.x86_64_xhci-hcd +E: ID_VENDOR_ENC=Linux\x206.18.13-200.fc43.x86_64\x20xhci-hcd +E: ID_VENDOR_FROM_DATABASE=Linux Foundation +E: ID_VENDOR_ID=1d6b +E: MAJOR=189 +E: MINOR=256 +E: PRODUCT=1d6b/2/618 +E: SUBSYSTEM=usb +E: TAGS=:seat: +E: TYPE=9/0/1 +E: __DEVCONTEXT=system_u:object_r:usb_device_t:s0 +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=0618\n +A: bmAttributes=e0\n +A: busnum=3\n +A: configuration= +H: descriptors=12010002090001406B1D020018060302010109021900010100E0000904000001090000000705810304000C +A: dev=189:256\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:10/device:1f/device:20 +A: idProduct=0002\n +A: idVendor=1d6b\n +A: interface_authorized_default=1\n +A: ltm_capable=no\n +A: manufacturer=Linux 6.18.13-200.fc43.x86_64 xhci-hcd\n +A: maxchild=4\n +A: power/active_duration=84681\n +A: power/autosuspend=0\n +A: power/autosuspend_delay_ms=0\n +A: power/connected_duration=1434803\n +A: power/control=auto\n +A: power/level=auto\n +A: power/runtime_active_time=84680\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=1350122\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:04:00.4\n +A: speed=480\n +A: tx_lanes=1\n +A: urbnum=74\n +A: version= 2.00\n + +P: /devices/pci0000:00/0000:00:08.1/0000:04:00.4 +E: DRIVER=xhci_hcd +E: ID_MODEL_FROM_DATABASE=Renoir/Cezanne USB 3.1 +E: ID_PATH=pci-0000:04:00.4 +E: ID_PATH_TAG=pci-0000_04_00_4 +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=Advanced Micro Devices, Inc. [AMD] +E: MODALIAS=pci:v00001022d00001639sv000017AAsd00003856bc0Csc03i30 +E: PCI_CLASS=C0330 +E: PCI_ID=1022:1639 +E: PCI_SLOT_NAME=0000:04:00.4 +E: PCI_SUBSYS_ID=17AA:3856 +E: SUBSYSTEM=pci +A: ari_enabled=0\n +A: broken_parity_status=0\n +A: class=0x0c0330\n +H: config=22103916070410000030030C08008000040010FD000000000000000000000000000000000000000000000000AA175638000000004800000000000000FF010000000000000000000009500800AA175638016403C80000000000000000000000003120000010A00200A18F000010290000030D400040000311000000000000000000000000000000001F007100000000001E00800100000100000000000000000005C08600000000000000000000000000000000000000000000000000000000001100078000E00F0000F00F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B00012A010001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +A: consistent_dma_mask_bits=64\n +A: current_link_speed=8.0 GT/s PCIe\n +A: current_link_width=16\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=0x1639\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:10/device:1f +L: iommu=../../0000:00:00.2/iommu/ivhd0 +L: iommu_group=../../../../kernel/iommu_groups/16 +A: irq=45\n +A: link/l0s_aspm=0\n +A: link/l1_aspm=0\n +A: local_cpulist=0-11\n +A: local_cpus=fff\n +A: max_link_speed=8.0 GT/s PCIe\n +A: max_link_width=16\n +A: modalias=pci:v00001022d00001639sv000017AAsd00003856bc0Csc03i30\n +A: msi_bus=1\n +A: msi_irqs/46=msix\n +A: msi_irqs/47=msix\n +A: msi_irqs/48=msix\n +A: msi_irqs/49=msix\n +A: msi_irqs/50=msix\n +A: msi_irqs/51=msix\n +A: msi_irqs/52=msix\n +A: msi_irqs/53=msix\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 4 5 2112 5\nxHCI ring segments 29 33 4096 33\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n +A: power/control=on\n +A: power/runtime_active_time=1435048\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: reset_method=pm\n +A: resource=0x00000000fd100000 0x00000000fd1fffff 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=0x00\n +A: subsystem_device=0x3856\n +A: subsystem_vendor=0x17aa\n +A: vendor=0x1022\n + +P: /devices/pci0000:00/0000:00:08.1 +E: DRIVER=pcieport +E: ID_MODEL_FROM_DATABASE=Renoir Internal PCIe GPP Bridge to Bus +E: ID_PATH=pci-0000:00:08.1 +E: ID_PATH_TAG=pci-0000_00_08_1 +E: ID_PCI_CLASS_FROM_DATABASE=Bridge +E: ID_PCI_INTERFACE_FROM_DATABASE=Normal decode +E: ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge +E: ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc. [AMD] +E: MODALIAS=pci:v00001022d00001635sv000017AAsd0000387Abc06sc04i00 +E: PCI_CLASS=60400 +E: PCI_ID=1022:1635 +E: PCI_SLOT_NAME=0000:00:08.1 +E: PCI_SUBSYS_ID=17AA:387A +E: SUBSYSTEM=pci +A: ari_enabled=0\n +A: broken_parity_status=0\n +A: class=0x060400\n +H: config=221035160704100000000406080081000000000000000000000404001111000000FD40FD016011700400000004000000000000005000000000000000FF01020000000000000000000000000000000000015803C80000000010A042002280000010290000030D7000400C03310000000000004000180001000000000000003100000000001E00800143001F00000000000000000000000000000000000000000005C081000000E0FE0000000000000000000000000000000000000000000000000D000000AA177A380000000000000000000000000000000000000000000000000000000034B205000000000000000000000000000000000000000000000000000B000127010001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001900012A00000000000000007F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F000000000D0001405F001D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000250001410100008001000080000000002600014400000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2700010000000000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +A: consistent_dma_mask_bits=32\n +A: current_link_speed=8.0 GT/s PCIe\n +A: current_link_width=16\n +A: d3cold_allowed=1\n +A: device=0x1635\n +A: dma_mask_bits=32\n +L: driver=../../../bus/pci/drivers/pcieport +A: driver_override=(null)\n +A: enable=2\n +L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:10 +L: iommu=../0000:00:00.2/iommu/ivhd0 +L: iommu_group=../../../kernel/iommu_groups/6 +A: irq=35\n +A: local_cpulist=0-11\n +A: local_cpus=fff\n +A: max_link_speed=8.0 GT/s PCIe\n +A: max_link_width=16\n +A: modalias=pci:v00001022d00001635sv000017AAsd0000387Abc06sc04i00\n +A: msi_bus=1\n +A: msi_irqs/35=msi\n +A: numa_node=-1\n +A: power/autosuspend_delay_ms=100\n +A: power/control=auto\n +A: power/runtime_active_time=1435076\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: reset_method=pm\n +A: resource=0x0000000000000000 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\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000001000 0x0000000000001fff 0x0000000000000101\n0x00000000fd000000 0x00000000fd4fffff 0x0000000000000200\n0x0000000460000000 0x00000004701fffff 0x0000000000102201\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n +A: revision=0x00\n +A: secondary_bus_number=4\n +A: subordinate_bus_number=4\n +A: subsystem_device=0x387a\n +A: subsystem_vendor=0x17aa\n +A: vendor=0x1022\n + diff --git a/tests/meson.build b/tests/meson.build index 07c924be..03f2ecab 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -56,9 +56,10 @@ drivers_tests = [ 'egismoc-0586', 'egismoc-0587', 'fpcmoc', - 'realtek', - 'realtek-5816', + 'realtek', + 'realtek-5816', 'focaltech_moc', + 'egis0576', ] if get_option('introspection')