diff --git a/libfprint/drivers/egis0570.c b/libfprint/drivers/egis0570.c index 0ff607da..f260e2d5 100644 --- a/libfprint/drivers/egis0570.c +++ b/libfprint/drivers/egis0570.c @@ -18,29 +18,75 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include + +#include #define FP_COMPONENT "egis0570" #include "egis0570.h" #include "drivers_api.h" +#include "fp-device.h" /* Packet types */ #define PKT_TYPE_INIT 0 #define PKT_TYPE_REPEAT 1 /* Struct */ +struct CalibrationContext +{ + gboolean img_resp; + int pkt_size; + guint8 *pkt_ptr; + + int cal_step; + + + guint8 req_packet[EGIS0570_PKTSIZE]; + guint8 *calibration_images; + guint8 cal_img_idx; + + guint8 rng_pkt_low; + guint8 rng_pkt_high; + + gint8 repeat_step; + + guint8 pkt_02_value; + + guint8 bs_steps; + guint8 bs_condition; + guint8 bs_mid; + guint8 bs_twos; + guint8 bs_zeros; + guint8 bs_lows[EGIS0570_CAL_BS_ELM]; + guint8 bs_highs[EGIS0570_CAL_BS_ELM]; + unsigned int bs_row_sums[EGIS0570_CAL_BS_ELM]; + guint8 bs_pkts[EGIS0570_CAL_BS_ELM * EGIS0570_PKTSIZE]; + +}; + struct _FpDeviceEgis0570 { - FpImageDevice parent; + FpImageDevice parent; - gboolean running; - gboolean stop; + gboolean running; + gboolean stop; + gboolean calibrating; + gboolean save_resp; - GSList *strips; - guint8 *background; - gsize strips_len; + guint8 resp_state; + guint8 saved_resp; - int pkt_num; - int pkt_type; + GSList *strips; + guint8 *background; + gsize strips_len; + + int pkt_num; + int pkt_type; + + guint8 query_pkts[EGIS0570_INIT_TOTAL][EGIS0570_PKTSIZE]; + guint8 *persistent_data; + struct CalibrationContext *cal_ctx; }; G_DECLARE_FINAL_TYPE (FpDeviceEgis0570, fpi_device_egis0570, FPI, DEVICE_EGIS0570, FpImageDevice); G_DEFINE_TYPE (FpDeviceEgis0570, fpi_device_egis0570, FP_TYPE_IMAGE_DEVICE); @@ -58,10 +104,29 @@ static struct fpi_frame_asmbl_ctx assembling_ctx = { .get_pixel = egis_get_pixel, }; + +enum sm_caliberation_states { + SM_CAL_INIT, + SM_CAL_STEP_LOGIC, + SM_CAL_STATIC_PKT, + SM_CAL_REQ, + SM_CAL_RESP, + SM_CAL_RNG_PKT_REQ, + SM_CAL_RNG_PKT_RESP, + SM_CAL_BS_PK_REQ, + SM_CAL_BS_PK_RESP, + SM_CAL_CHK_NEW_CNF_REQ, + SM_CAL_CHK_NEW_CNF_RESP, + SM_CAL_DONE, + SM_CAL_NUM, +}; + + /* * Service */ + static gboolean is_last_pkt (FpDevice *dev) { @@ -72,9 +137,16 @@ is_last_pkt (FpDevice *dev) gboolean r; - r = ((type == PKT_TYPE_INIT) && (num == (EGIS0570_INIT_TOTAL - 1))); - r |= ((type == PKT_TYPE_REPEAT) && (num == (EGIS0570_REPEAT_TOTAL - 1))); - + if (self->calibrating) + { + struct CalibrationContext *cal_ctx = self->cal_ctx; + r = (cal_ctx->pkt_size - 1) == num; + } + else + { + r = ((type == PKT_TYPE_INIT) && (num == (EGIS0570_INIT_TOTAL - 1))); + r |= ((type == PKT_TYPE_REPEAT) && (num == (EGIS0570_REPEAT_TOTAL - 1))); + } return r; } @@ -221,11 +293,51 @@ recv_data_resp (FpiSsm *ssm, FpDevice *dev) fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, data_resp_cb, NULL); } + +static void +data_cal_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error) +{ + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + struct CalibrationContext *cal_ctx = self->cal_ctx; + + if (error) + { + fpi_ssm_mark_failed (transfer->ssm, error); + return; + } + + // assert bound ? + memcpy (cal_ctx->calibration_images + (cal_ctx->cal_img_idx * EGIS0570_IMGSIZE), transfer->buffer, EGIS0570_IMGSIZE); + cal_ctx->cal_img_idx++; + + fpi_ssm_jump_to_state (transfer->ssm, SM_CAL_STEP_LOGIC); +} + +static void +recv_cal_data_resp (FpiSsm *ssm, FpDevice *dev) +{ + FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev); + + fpi_usb_transfer_fill_bulk (transfer, EGIS0570_EPIN, EGIS0570_CAL_INPSIZE); + + transfer->ssm = ssm; + transfer->short_is_error = TRUE; + + fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, data_cal_resp_cb, NULL); +} + static void cmd_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error) { + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + if (error) fpi_ssm_mark_failed (transfer->ssm, error); + + if (self->save_resp) + self->saved_resp = transfer->buffer[5]; + + fpi_ssm_jump_to_state (transfer->ssm, self->resp_state); } static void @@ -236,6 +348,7 @@ recv_cmd_resp (FpiSsm *ssm, FpDevice *dev) fpi_usb_transfer_fill_bulk (transfer, EGIS0570_EPIN, EGIS0570_PKTSIZE); transfer->ssm = ssm; + transfer->short_is_error = TRUE; fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, cmd_resp_cb, NULL); } @@ -276,7 +389,9 @@ ssm_run_state (FpiSsm *ssm, FpDevice *dev) switch (fpi_ssm_get_cur_state (ssm)) { case SM_INIT: + self->calibrating = FALSE; self->pkt_type = PKT_TYPE_INIT; + self->save_resp = FALSE; fpi_ssm_next_state (ssm); break; @@ -296,7 +411,7 @@ ssm_run_state (FpiSsm *ssm, FpDevice *dev) case SM_REQ: if (self->pkt_type == PKT_TYPE_INIT) - send_cmd_req (ssm, dev, init_pkts[self->pkt_num]); + send_cmd_req (ssm, dev, self->query_pkts[self->pkt_num]); else send_cmd_req (ssm, dev, repeat_pkts[self->pkt_num]); break; @@ -304,9 +419,9 @@ ssm_run_state (FpiSsm *ssm, FpDevice *dev) 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); + self->resp_state = SM_REQ; + recv_cmd_resp (ssm, dev); } else { @@ -330,6 +445,784 @@ ssm_run_state (FpiSsm *ssm, FpDevice *dev) } } +/* + * Calibration + */ + + +static void +set_ctx_pkts_type (FpDeviceEgis0570 *self, guint8 * element_ptr) +{ + self->pkt_type = -1; + for (guint8 i = 0; i < EGIS0570_CAL_STATIC_LIST_SIZEOF; i++) + { + if (EGIS0570_CAL_STATIC_LIST[i] == element_ptr) + { + self->pkt_type = i; + fp_dbg ("ptr said index %d", i); + return; + } + } + fp_dbg ("messed up list for static packets"); +} + +static void +set_ctx_pkts (FpDeviceEgis0570 *self) +{ + struct CalibrationContext *cal_ctx = self->cal_ctx; + + self->pkt_num = 0; + cal_ctx->pkt_ptr = EGIS0570_CAL_STATIC_LIST[self->pkt_type]; + cal_ctx->pkt_size = EGIS0570_CAL_STATIC_LIST_SIZE[self->pkt_type]; +} + + +static void +check_black_white_values (struct CalibrationContext *cal_ctx) +{ + guint8 * white_img = cal_ctx->calibration_images + (0 * EGIS0570_IMGSIZE); + guint8 * black_img = cal_ctx->calibration_images + (1 * EGIS0570_IMGSIZE); + + for (size_t i = 0; i < EGIS0570_IMGSIZE; i++) + { + if (white_img[i] != 0xfe || black_img[i] != 0x00) + { + fp_dbg ("Black and white values are not right!"); + break; + } + } +} + + +static void +sum_pictures (guint8 * data, unsigned int * sums, guint8 f_idx, guint8 l_idx) +{ + for (guint8 pic_idx = f_idx; pic_idx <= l_idx; pic_idx++) + { + for (guint8 i = IMG_COL_IGNORE ; i < EGIS0570_IMGWIDTH - IMG_COL_IGNORE ; i++) + { + sums[0] += data[pic_idx * EGIS0570_IMGSIZE + i]; + sums[1] += data[pic_idx * EGIS0570_IMGSIZE + i + 1 * EGIS0570_IMGWIDTH]; + sums[2] += data[pic_idx * EGIS0570_IMGSIZE + i + 2 * EGIS0570_IMGWIDTH]; + sums[3] += data[pic_idx * EGIS0570_IMGSIZE + i + 3 * EGIS0570_IMGWIDTH]; + sums[4] += data[pic_idx * EGIS0570_IMGSIZE + i + 4 * EGIS0570_IMGWIDTH]; + sums[5] += data[pic_idx * EGIS0570_IMGSIZE + i + 5 * EGIS0570_IMGWIDTH]; + sums[6] += data[pic_idx * EGIS0570_IMGSIZE + i + 28 * EGIS0570_IMGWIDTH]; + } + } +} + +static void +apply_next_step_setting (FpiSsm *ssm, FpDeviceEgis0570 *self) +{ + struct CalibrationContext *cal_ctx = self->cal_ctx; + + cal_ctx->cal_step++; + cal_ctx->pkt_size = 0; + cal_ctx->img_resp = FALSE; + + self->pkt_num = 0; + self->pkt_type = -1; + self->save_resp = FALSE; + + if (cal_ctx->cal_step == EGIS0570_CAL_PROC_SIZEOF) + { + fp_dbg ("calibration step is higher thatn expected."); + return; + } + fp_dbg ("Procedure Index %d", cal_ctx->cal_step); + + switch (calibration_procedure[cal_ctx->cal_step]) + { + case CAL_CONF_PKT: + set_ctx_pkts_type (self, *EGIS0570_CAL_CONFIGURATION_MODE_PKT); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_PKT_ZERO_RNG: + set_ctx_pkts_type (self, *EGIS0570_CAL_PKT_ZERO_RANGE); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_CAPT_AREA: + set_ctx_pkts_type (self, *EGIS0570_CAL_CAPTURING_AREA); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_SENS_AND_EMIT: + set_ctx_pkts_type (self, *EGIS0570_CAL_SENSOR_AND_EMITTER); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_RNG_20_58: + cal_ctx->rng_pkt_low = 0x20; + cal_ctx->rng_pkt_high = 0x58; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = 0x00; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_RNG_60_D0: + cal_ctx->rng_pkt_low = 0x60; + cal_ctx->rng_pkt_high = 0xd0; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = 0x00; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_WHITE_SET: + set_ctx_pkts_type (self, *EGIS0570_CAL_WHITE_SETTING); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_BLACK_WHITE_GET_IMG: + set_ctx_pkts_type (self, *EGIS0570_CAL_BLACK_WHITE_GET_IMAGE); + cal_ctx->img_resp = TRUE; + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_BLACK_WHITE_AFTER_IMAGE: + set_ctx_pkts_type (self, *EGIS0570_CAL_BLACK_WHITE_AFTER_IMAGE); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_BLACK_SET: + set_ctx_pkts_type (self, *EGIS0570_CAL_BLACK_SETTING); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_CHECK_BLACK_WHITE: + check_black_white_values (cal_ctx); + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + case CAL_5_ROWS_ZEROS: + /* repeat this case*/ + if (cal_ctx->repeat_step == 0) + { + cal_ctx->repeat_step--; + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + } + cal_ctx->cal_step--; + if (cal_ctx->repeat_step == -1) + cal_ctx->repeat_step = 12; + /* end repeat */ + + if (cal_ctx->repeat_step % 2) + cal_ctx->rng_pkt_low = 0x58 - ((12 - cal_ctx->repeat_step) / 2); + else + cal_ctx->rng_pkt_low = 0x20 + ((12 - cal_ctx->repeat_step) / 2); + + cal_ctx->rng_pkt_high = cal_ctx->rng_pkt_low; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = 0x00; + cal_ctx->repeat_step--; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_BLACK_WHITE_CLEAR: + set_ctx_pkts_type (self, *EGIS0570_CAL_BLACK_WHITE_CLEAR); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_RNG_60_D1: + cal_ctx->rng_pkt_low = 0x60; + cal_ctx->rng_pkt_high = 0xd1; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = 0x00; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_MID_BLACK_SET: + set_ctx_pkts_type (self, *EGIS0570_CAL_MIDDLE_BLACK_SETTING); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_GET_IMG: + set_ctx_pkts_type (self, *EGIS0570_CAL_GET_IMAGE); + cal_ctx->img_resp = TRUE; + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_AFTER_IMG: + set_ctx_pkts_type (self, *EGIS0570_CAL_AFTER_IMAGE); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_GET_9: + /* repeat this case*/ + if (cal_ctx->repeat_step == 0) + { + cal_ctx->repeat_step--; + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + } + cal_ctx->cal_step--; + if (cal_ctx->repeat_step == -1) + cal_ctx->repeat_step = 9 * 3; // 27 + /* end repeat */ + + if (cal_ctx->repeat_step % 3 == 0) + { + set_ctx_pkts_type (self, *EGIS0570_CAL_REPEAT); + } + else if (cal_ctx->repeat_step % 3 == 2) + { + set_ctx_pkts_type (self, *EGIS0570_CAL_GET_IMAGE); + cal_ctx->img_resp = TRUE; + } + else + { + set_ctx_pkts_type (self, *EGIS0570_CAL_AFTER_IMAGE); + } + cal_ctx->repeat_step--; + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + + case CAL_GET_21: + /* repeat this case*/ + if (cal_ctx->repeat_step == 0) + { + cal_ctx->repeat_step--; + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + } + cal_ctx->cal_step--; + if (cal_ctx->repeat_step == -1) + cal_ctx->repeat_step = 21 * 3; // 27 + /* end repeat */ + + if (cal_ctx->repeat_step % 3 == 0) + { + set_ctx_pkts_type (self, *EGIS0570_CAL_REPEAT); + } + else if (cal_ctx->repeat_step % 3 == 2) + { + set_ctx_pkts_type (self, *EGIS0570_CAL_GET_IMAGE); + cal_ctx->img_resp = TRUE; + } + else + { + set_ctx_pkts_type (self, *EGIS0570_CAL_AFTER_IMAGE); + } + cal_ctx->repeat_step--; + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_BORDER_WHITE_SET: + set_ctx_pkts_type (self, *EGIS0570_CAL_BORDER_WHITE_SETTING); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + + case CAL_FIRST_BS_SET: + cal_ctx->bs_steps = 0; + cal_ctx->bs_condition = 0x7f; + cal_ctx->bs_mid = 0; + + for (guint8 i = 0; i < EGIS0570_CAL_BS_ELM; i++) + { + cal_ctx->bs_lows[i] = 0x00; + cal_ctx->bs_highs[i] = 0xff; + cal_ctx->bs_row_sums[i] = 0x00; + for (guint8 k = 0; k < EGIS0570_PKTSIZE; k++) + cal_ctx->bs_pkts[i * EGIS0570_PKTSIZE + k] = init_pkts[i * 2][k]; + cal_ctx->bs_pkts[(i + 1) * EGIS0570_PKTSIZE - 1] = 0x00; + } + cal_ctx->bs_pkts[EGIS0570_CAL_BS_ELM * EGIS0570_PKTSIZE - 2] = 0x3c; + + set_ctx_pkts_type (self, *EGIS0570_CAL_FIRST_BS_SETTING); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + + case CAL_BS_CHK_SET: + if (cal_ctx->bs_condition && cal_ctx->bs_steps < 8) + { + cal_ctx->cal_img_idx = 0; + cal_ctx->bs_steps++; + fp_dbg ("CALIBERATION: BINARY SEARCH: CONDITION: %b, STEPS: %d", cal_ctx->bs_condition, cal_ctx->bs_steps); + for (guint8 i = 0; i < EGIS0570_CAL_BS_ELM; i++) + { + fp_dbg ("CALIBERATION: BINARY SEARCH: %d: LOW: %x, HIGH: %x", i, cal_ctx->bs_lows[i], cal_ctx->bs_highs[i]); + cal_ctx->bs_row_sums[i] = 0; + } + + fpi_ssm_jump_to_state (ssm, SM_CAL_BS_PK_REQ); + } + else + { + cal_ctx->cal_step += 6;// Based on calibration_procedure. + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + } + break; + + case CAL_PKT_02: + cal_ctx->rng_pkt_low = 0x02; + cal_ctx->rng_pkt_high = 0x02; + cal_ctx->req_packet[4] = 0x00; + cal_ctx->req_packet[6] = cal_ctx->pkt_02_value; + cal_ctx->pkt_02_value = 0xff; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_BEFORE_IMG: + set_ctx_pkts_type (self, *EGIS0570_CAL_BEFORE_GET_IMAGE); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_BS_JUMP: + sum_pictures (cal_ctx->calibration_images, cal_ctx->bs_row_sums, cal_ctx->cal_img_idx - 10, cal_ctx->cal_img_idx - 1); + + for (guint8 i = 0; i < EGIS0570_CAL_BS_ELM; i++) + { + cal_ctx->bs_row_sums[i] /= 10 * (EGIS0570_IMGWIDTH - (2 * IMG_COL_IGNORE)); + fp_dbg ("CALIBERATION: BINARY SEARCH: %d: PKT: %x, ROW_SUM: %d", i, cal_ctx->bs_pkts[i * EGIS0570_PKTSIZE + 6], cal_ctx->bs_row_sums[i]); + if (cal_ctx->bs_row_sums[i] >= TARGET_UPPER + (SIDE_DIFF * (i < 6))) + cal_ctx->bs_lows[i] = cal_ctx->bs_pkts[i * EGIS0570_PKTSIZE + 6] + ((cal_ctx->bs_highs[i] - cal_ctx->bs_lows[i]) == 1); + else if (cal_ctx->bs_row_sums[i] <= TARGET_LOWER + (SIDE_DIFF * (i < 6))) + cal_ctx->bs_highs[i] = cal_ctx->bs_pkts[i * EGIS0570_PKTSIZE + 6]; + else + cal_ctx->bs_condition = cal_ctx->bs_condition & (0x7f - (1 << i)); + } + + cal_ctx->cal_step = cal_ctx->cal_step - 7;// Based on calibration_procedure. + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + case CAL_BS_END: + if (cal_ctx->bs_steps >= 8) + fp_dbg ("CALIBERATION: ERROR EXTRA STEPS ON BINARY SEARCH."); + + /* save in list */ + for (guint8 i = 0; i < EGIS0570_CAL_BS_ELM; i++) + { + self->persistent_data[i] = ((cal_ctx->bs_pkts[6 * EGIS0570_PKTSIZE + 6] * (i < 6)) > cal_ctx->bs_pkts[i * EGIS0570_PKTSIZE + 6]) ? 0x00 : (cal_ctx->bs_pkts[i * EGIS0570_PKTSIZE + 6] - (cal_ctx->bs_pkts[6 * EGIS0570_PKTSIZE + 6] * (i < 6))); + fp_dbg ("CALIBERATION: SAVED presistenet data %x", self->persistent_data[i]); + } + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + + case CAL_PKT_15_0: + cal_ctx->cal_img_idx = 0; + + cal_ctx->rng_pkt_low = 0x15; + cal_ctx->rng_pkt_high = 0x15; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = 0x00; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_PKT_16_3C: + cal_ctx->rng_pkt_low = 0x16; + cal_ctx->rng_pkt_high = 0x16; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = self->persistent_data[6]; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_CHK_NEW_CONF: + for (guint8 i = 0; i < (EGIS0570_CAL_BS_ELM - 1); i++) + cal_ctx->bs_pkts[i * EGIS0570_PKTSIZE + 6] = self->persistent_data[i]; + cal_ctx->pkt_02_value = 0x00; + fpi_ssm_jump_to_state (ssm, SM_CAL_CHK_NEW_CNF_REQ); + break; + + case CAL_NO_IMG_CAP_AREA: + cal_ctx->cal_img_idx = 0; + + set_ctx_pkts_type (self, *EGIS0570_CAL_NO_IMAGE_CAPTURING_AREA); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_NO_IMG_SET_0: + set_ctx_pkts_type (self, *EGIS0570_CAL_NO_IMAGE_SETTING_0); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_NO_IMG_03_1C: + self->save_resp = TRUE; + cal_ctx->rng_pkt_low = 0x03; + cal_ctx->rng_pkt_high = 0x03; + cal_ctx->req_packet[4] = 0x00; + cal_ctx->req_packet[6] = 0x1C; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_NO_CHK_03_80: + if (self->saved_resp != 0x80) + fp_dbg ("unexpected value (%x)for 0x00 0x03 0x1c -> 0x80.", self->saved_resp); + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + case CAL_NO_SET_03_80: + cal_ctx->rng_pkt_low = 0x03; + cal_ctx->rng_pkt_high = 0x03; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = self->saved_resp; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_NO_IMG_14_BS_SET: + cal_ctx->bs_steps = 0; + cal_ctx->bs_condition = 0x01; + cal_ctx->bs_mid = 0; + cal_ctx->bs_lows[0] = 0x00; + cal_ctx->bs_highs[0] = 0x3f; + + set_ctx_pkts_type (self, *EGIS0570_CAL_NO_IMAGE_BINARY_14_SETTING); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + + case CAL_NO_IMG_14_BS_CHK_SET: + if (cal_ctx->bs_condition && cal_ctx->bs_steps < 6 ) + { + cal_ctx->bs_twos = 0; + cal_ctx->bs_zeros = 0; + cal_ctx->bs_steps++; + + fp_dbg ("CALIBERATION: NO IMAGE 14: CONDITION: %b, STEPS: %d", cal_ctx->bs_condition, cal_ctx->bs_steps); + fp_dbg ("CALIBERATION: NO IMAGE 14: LOW: %x, HIGH: %x", cal_ctx->bs_lows[0], cal_ctx->bs_highs[0]); + + self->save_resp = FALSE; + cal_ctx->rng_pkt_low = 0x14; + cal_ctx->rng_pkt_high = 0x14; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = cal_ctx->bs_lows[0] + ((cal_ctx->bs_highs[0] - cal_ctx->bs_lows[0]) / 2); + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + } + else + { + cal_ctx->cal_step += 3; // Based on calibration_procedure. // + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + } + break; + + + case CAL_NO_IMG_16_BS_CHK_SET_15: + if (cal_ctx->bs_condition && cal_ctx->bs_steps < 7) + { + cal_ctx->bs_twos = 0; + cal_ctx->bs_zeros = 0; + cal_ctx->bs_steps++; + + fp_dbg ("CALIBERATION: NO IMAGE 16: CONDITION: %b, STEPS: %d", cal_ctx->bs_condition, cal_ctx->bs_steps); + fp_dbg ("CALIBERATION: NO IMAGE 16: LOW: %x, HIGH: %x", cal_ctx->bs_lows[0], cal_ctx->bs_highs[0]); + + self->save_resp = FALSE; + cal_ctx->rng_pkt_low = 0x15; + cal_ctx->rng_pkt_high = 0x15; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = 0x00; + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + } + else + { + cal_ctx->cal_step += 4; // Based on calibration_procedure. + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + } + break; + + case CAL_NO_IMG_16_BS_SET_16: + self->save_resp = FALSE; + cal_ctx->rng_pkt_low = 0x16; + cal_ctx->rng_pkt_high = 0x16; + cal_ctx->req_packet[4] = 0x01; + cal_ctx->req_packet[6] = cal_ctx->bs_lows[0] + ((cal_ctx->bs_highs[0] - cal_ctx->bs_lows[0]) / 2); + fpi_ssm_jump_to_state (ssm, SM_CAL_RNG_PKT_REQ); + break; + + case CAL_NO_IMG_PRE_FIRST: + set_ctx_pkts_type (self, *EGIS0570_CAL_NO_IMAGE_PRE_FIRST); + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + case CAL_NO_IMG_GET_8: + /* repeat this case*/ + if (cal_ctx->repeat_step == 0) + { + + if (self->saved_resp == 0x02) + cal_ctx->bs_twos++; + else if(self->saved_resp == 0x00) + cal_ctx->bs_zeros++; + else + fp_dbg ("unexpected value for no img 14/16 request (%x)", self->saved_resp); + + cal_ctx->repeat_step--; + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + } + cal_ctx->cal_step--; + if (cal_ctx->repeat_step == -1) + cal_ctx->repeat_step = 8; + /* end repeat */ + + if (cal_ctx->repeat_step < 8) + { + if (self->saved_resp == 0x02) + cal_ctx->bs_twos++; + else if(self->saved_resp == 0x00) + cal_ctx->bs_zeros++; + else + fp_dbg ("unexpected value for no img 14/16 request (%x)", self->saved_resp); + } + + set_ctx_pkts_type (self, *EGIS0570_CAL_NO_IMAGE_REQUEST); + self->save_resp = TRUE; + cal_ctx->repeat_step--; + fpi_ssm_jump_to_state (ssm, SM_CAL_STATIC_PKT); + break; + + + case CAL_NO_IMG_14_BS_JUMP: + if (cal_ctx->bs_twos > cal_ctx->bs_zeros) + cal_ctx->bs_highs[0] = cal_ctx->req_packet[6]; + else if (cal_ctx->bs_twos < cal_ctx->bs_zeros) + cal_ctx->bs_lows[0] = cal_ctx->req_packet[6]; + else + cal_ctx->bs_condition = 0x00; + + fp_dbg ("no image bs 14: twos: %d, zeros: %d.", cal_ctx->bs_twos, cal_ctx->bs_zeros); + + cal_ctx->cal_step = cal_ctx->cal_step - 4;// Based on calibration_procedure. + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + + case CAL_NO_IMG_16_BS_JUMP: + if (cal_ctx->bs_twos > cal_ctx->bs_zeros) + cal_ctx->bs_highs[0] = cal_ctx->req_packet[6]; + else if (cal_ctx->bs_twos < cal_ctx->bs_zeros) + cal_ctx->bs_lows[0] = cal_ctx->req_packet[6]; + else + cal_ctx->bs_condition = 0x00; + + fp_dbg ("no image bs 16: twos: %d, zeros: %d.", cal_ctx->bs_twos, cal_ctx->bs_zeros); + + cal_ctx->cal_step = cal_ctx->cal_step - 5;// Based on calibration_procedure. + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + case CAL_NO_IMG_14_BS_END: + if (cal_ctx->bs_steps >= 6) + fp_dbg ("CALIBERATION: ERROR EXTRA STEPS ON BINARY SEARCH."); + + /* save in list */ + fp_dbg ("NO BS 14 found value (%x), set value (0x00)", cal_ctx->req_packet[6]); + self->persistent_data[8] = 0x00; + + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + case CAL_NO_IMG_16_BS_SET: + cal_ctx->bs_steps = 0; + cal_ctx->bs_condition = 0x01; + cal_ctx->bs_mid = 0; + cal_ctx->bs_lows[0] = 0x00; + cal_ctx->bs_highs[0] = 0x7f; + + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + case CAL_NO_IMG_16_BS_END: + if (cal_ctx->bs_steps >= 7) + fp_dbg ("CALIBERATION: ERROR EXTRA STEPS ON BINARY SEARCH."); + + /* save in list */ + fp_dbg ("NO BS 16 found value (%x), set value (0x0a)", cal_ctx->req_packet[6]); + self->persistent_data[7] = 0x0a; + + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + break; + + case CAL_END: + fpi_ssm_jump_to_state (ssm, SM_CAL_DONE); + break; + + default: + g_assert_not_reached (); + } +} + +static void +ssm_cal_run_state (FpiSsm *ssm, FpDevice *dev) +{ + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + struct CalibrationContext *cal_ctx = self->cal_ctx; + + switch (fpi_ssm_get_cur_state (ssm)) + { + case SM_CAL_INIT: + cal_ctx->cal_step = -1; + cal_ctx->repeat_step = -1; + cal_ctx->calibration_images = g_malloc (EGIS0570_CAL_IMG_TOT * EGIS0570_IMGSIZE); + memcpy (cal_ctx->req_packet, EGIS0570_CAL_NO_IMAGE_REQUEST[1], EGIS0570_PKTSIZE); + cal_ctx->cal_img_idx = 0; + cal_ctx->pkt_02_value = 0xff; + + self->pkt_num = 0; + self->pkt_type = 0; + self->persistent_data = g_malloc0 (PRESISTENT_DATA_LENGTH); + self->save_resp = FALSE; + self->saved_resp = 0x00; + fpi_ssm_next_state (ssm); + break; + + case SM_CAL_STEP_LOGIC: + apply_next_step_setting (ssm, self); + break; + + case SM_CAL_STATIC_PKT: + set_ctx_pkts (self); + fpi_ssm_next_state (ssm); + break; + + case SM_CAL_REQ: + send_cmd_req (ssm, dev, cal_ctx->pkt_ptr + (EGIS0570_PKTSIZE * self->pkt_num)); + break; + + case SM_CAL_RESP: + if (is_last_pkt (dev) == FALSE) + { + self->pkt_num += 1; + self->resp_state = SM_CAL_REQ; + recv_cmd_resp (ssm, dev); + } + else + { + if (cal_ctx->img_resp) + { + recv_cal_data_resp (ssm, dev); + } + else + { + self->resp_state = SM_CAL_STEP_LOGIC; + recv_cmd_resp (ssm, dev); + } + } + break; + + case SM_CAL_RNG_PKT_REQ: + if (cal_ctx->rng_pkt_low <= cal_ctx->rng_pkt_high) + { + cal_ctx->req_packet[5] = cal_ctx->rng_pkt_low; + send_cmd_req (ssm, dev, cal_ctx->req_packet); + } + else + { + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + } + break; + + case SM_CAL_RNG_PKT_RESP: + cal_ctx->rng_pkt_low++; + self->resp_state = SM_CAL_RNG_PKT_REQ; + recv_cmd_resp (ssm, dev); + break; + + + case SM_CAL_BS_PK_REQ: + if (self->pkt_num < EGIS0570_CAL_BS_ELM) + { + if (cal_ctx->bs_condition & (1 << self->pkt_num)) + { + cal_ctx->bs_mid = cal_ctx->bs_lows[self->pkt_num] + ((cal_ctx->bs_highs[self->pkt_num] - cal_ctx->bs_lows[self->pkt_num]) / 2); + cal_ctx->bs_pkts[self->pkt_num * EGIS0570_PKTSIZE + 6] = cal_ctx->bs_mid; + cal_ctx->pkt_02_value = (cal_ctx->pkt_02_value > cal_ctx->bs_mid) ? cal_ctx->bs_mid : cal_ctx->pkt_02_value; + send_cmd_req (ssm, dev, cal_ctx->bs_pkts + (self->pkt_num * EGIS0570_PKTSIZE)); + } + else + { + self->pkt_num++; + fpi_ssm_jump_to_state (ssm, SM_CAL_BS_PK_REQ); + } + } + else + { + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + } + break; + + case SM_CAL_BS_PK_RESP: + self->pkt_num += 1; + self->resp_state = SM_CAL_BS_PK_REQ; + recv_cmd_resp (ssm, dev); + break; + + case SM_CAL_CHK_NEW_CNF_REQ: + if (self->pkt_num == (EGIS0570_CAL_BS_ELM * 2 - 1)) + { + fpi_ssm_jump_to_state (ssm, SM_CAL_STEP_LOGIC); + } + else + { + if (self->pkt_num < 6) + { + send_cmd_req (ssm, dev, cal_ctx->bs_pkts + (self->pkt_num * EGIS0570_PKTSIZE)); + } + else if (self->pkt_num < 12) + { + cal_ctx->bs_pkts[(self->pkt_num - 6) * EGIS0570_PKTSIZE + 5] = 0x58 - (self->pkt_num - 6); + send_cmd_req (ssm, dev, cal_ctx->bs_pkts + ((self->pkt_num - 6) * EGIS0570_PKTSIZE)); + } + else + { + cal_ctx->bs_pkts[6 * EGIS0570_PKTSIZE + 6] = 0x00; + send_cmd_req (ssm, dev, cal_ctx->bs_pkts + (6 * EGIS0570_PKTSIZE)); + } + } + break; + + case SM_CAL_CHK_NEW_CNF_RESP: + self->pkt_num += 1; + self->resp_state = SM_CAL_CHK_NEW_CNF_REQ; + recv_cmd_resp (ssm, dev); + break; + + case SM_CAL_DONE: + g_clear_pointer (&cal_ctx->calibration_images, g_free); + fpi_ssm_mark_completed (ssm); + break; + + default: + g_assert_not_reached (); + } +} + +static void +set_query_pkts (FpDeviceEgis0570 *self, guchar * data) +{ + // 20, 58 + self->query_pkts[0][6] = data[0]; + self->query_pkts[1][6] = data[0]; + // 21, 57 + self->query_pkts[2][6] = data[1]; + self->query_pkts[3][6] = data[1]; + // 22, 56 + self->query_pkts[4][6] = data[2]; + self->query_pkts[5][6] = data[2]; + // 23, 55 + self->query_pkts[6][6] = data[3]; + self->query_pkts[7][6] = data[3]; + // 24, 54 + self->query_pkts[8][6] = data[4]; + self->query_pkts[9][6] = data[4]; + // 25, 53 + self->query_pkts[10][6] = data[5]; + self->query_pkts[11][6] = data[5]; + // 16 + self->query_pkts[12][6] = data[6]; + // 9 + self->query_pkts[13][6] = data[7]; + // 14 + self->query_pkts[14][6] = data[8]; +} + /* * Activation */ @@ -362,6 +1255,50 @@ dev_activate (FpImageDevice *dev) fpi_image_device_activate_complete (dev, NULL); } + +/* + * Calibration Activation + */ + +static void +cal_loop_complete (FpiSsm *ssm, FpDevice *dev, GError *error) +{ + FpImageDevice *img_dev = FP_IMAGE_DEVICE (dev); + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + + set_query_pkts (self, self->persistent_data); + + // TODO to save uncomment + /* + * GError *save_error = NULL; + * fp_device_set_persistent_data (dev, self->persistent_data, PRESISTENT_DATA_LENGTH, &save_error); + * + * if (save_error) + * fpi_image_device_session_error (img_dev, save_error); + */ + + g_clear_pointer (&self->persistent_data, g_free); + + g_clear_pointer (&self->cal_ctx, g_free); + + if (error) + fpi_image_device_session_error (img_dev, error); + + fpi_image_device_open_complete (img_dev, error); +} + +static void +cal_activate (FpImageDevice *dev) +{ + FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), ssm_cal_run_state, SM_CAL_NUM); + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + + self->calibrating = TRUE; + self->cal_ctx = malloc (sizeof (struct CalibrationContext)); + + fpi_ssm_start (ssm, cal_loop_complete); +} + /* * Opening */ @@ -373,7 +1310,49 @@ dev_init (FpImageDevice *dev) g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error); - fpi_image_device_open_complete (dev, error); + FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev); + memcpy (self->query_pkts, init_pkts, EGIS0570_INIT_TOTAL * EGIS0570_PKTSIZE); + fp_dbg ("initialization"); + + + switch (fpi_device_get_driver_data (FP_DEVICE (dev))) + { + case PACKET_VERSION_1: + fpi_image_device_open_complete (dev, error); + fp_dbg ("static driver"); + break; + + case PACKET_CALIBRATION: + fp_dbg ("calibration driver"); + + gsize length; + // check if caliberation happend + + // TODO comment next line + length = 0; + + // TODO change the if part. + // if (fp_device_get_persistent_data (FP_DEVICE (dev), &self->persistent_data, &length, &error)) + if (TRUE) + { + if (length == PRESISTENT_DATA_LENGTH) + { + fp_dbg ("saved data"); + + set_query_pkts (self, self->persistent_data); + + fpi_image_device_open_complete (dev, error); + } + else + { + fp_dbg ("no Saved data, len is: %ld", length); + g_clear_pointer (&self->persistent_data, g_free); + cal_activate (dev); + } + } + break; + } + } /* @@ -410,9 +1389,11 @@ dev_deactivate (FpImageDevice *dev) */ static const FpIdEntry id_table[] = { - { .vid = 0x1c7a, .pid = 0x0570, }, - { .vid = 0x1c7a, .pid = 0x0571, }, - { .vid = 0, .pid = 0, }, + { .vid = 0x1c7a, .pid = 0x0570, .driver_data = PACKET_CALIBRATION}, + // { .vid = 0x1c7a, .pid = 0x0570, .driver_data = PACKET_VERSION_1}, + { .vid = 0x1c7a, .pid = 0x0571, .driver_data = PACKET_CALIBRATION}, + // { .vid = 0x1c7a, .pid = 0x0571, .driver_data = PACKET_VERSION_1}, + { .vid = 0, .pid = 0, .driver_data = 0}, }; static void diff --git a/libfprint/drivers/egis0570.h b/libfprint/drivers/egis0570.h index 2c8f0457..a974c434 100644 --- a/libfprint/drivers/egis0570.h +++ b/libfprint/drivers/egis0570.h @@ -18,10 +18,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "drivers_api.h" + #ifndef __EGIS0570_H #define __EGIS0570_H 1 + /* * Device data */ @@ -54,6 +57,33 @@ #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 */ +// }; + static unsigned char init_pkts[][EGIS0570_PKTSIZE] = { { 0x45, 0x47, 0x49, 0x53, 0x01, 0x20, 0x3f }, @@ -66,6 +96,8 @@ static unsigned char init_pkts[][EGIS0570_PKTSIZE] = { 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, 0x25, 0x00 }, + { 0x45, 0x47, 0x49, 0x53, 0x01, 0x53, 0x00 }, { 0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3e }, { 0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0b }, { 0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x03 }, @@ -175,3 +207,386 @@ static unsigned char repeat_pkts[][EGIS0570_PKTSIZE] = #define EGIS0570_RESIZE 2 #endif + + +// Calibration + +enum driver_version { + PACKET_CALIBRATION, + PACKET_VERSION_1, + NONE, +}; + +#define PRESISTENT_DATA_LENGTH 9 +#define EGIS0570_CAL_IMG_TOT 22 //124 +#define EGIS0570_CAL_INPSIZE 6528 +#define EGIS0570_CAL_BS_ELM 7 + + +#define IMG_COL_IGNORE 23 +#define TARGET_UPPER 80 +#define TARGET_LOWER 70 +// #define SIDE_DIFF (-10) +#define SIDE_DIFF (+5) + +/* static pkts */ +static guint8 EGIS0570_CAL_CONFIGURATION_MODE_PKT[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0d, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0e, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x1f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x05, 0x08}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0xff} +}; + +static guint8 EGIS0570_CAL_PKT_ZERO_RANGE[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x01, 0x10}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x04, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x05, 0x08}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x06, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x07, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x08, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0a, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0b, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0c, 0xff}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0d, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0e, 0x00} +}; + + +static guint8 EGIS0570_CAL_CAPTURING_AREA[][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} +}; + +static guint8 EGIS0570_CAL_SENSOR_AND_EMITTER[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x15}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x08} +}; + + +static guint8 EGIS0570_CAL_WHITE_SETTING[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x3f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x00} +}; + +static guint8 EGIS0570_CAL_BLACK_WHITE_GET_IMAGE[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x20}, + {0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0x33} +}; + +static guint8 EGIS0570_CAL_BLACK_WHITE_AFTER_IMAGE[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x00} +}; + +static guint8 EGIS0570_CAL_BLACK_SETTING[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x03}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0xff}, + {0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0xff} +}; + +static guint8 EGIS0570_CAL_BLACK_WHITE_CLEAR[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x00}, + {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, 0x01, 0x09, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00} +}; + + +static guint8 EGIS0570_CAL_MIDDLE_BLACK_SETTING[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x7f}, + {0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x7f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f} +}; + +static guint8 EGIS0570_CAL_GET_IMAGE[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0x33} +}; + +static guint8 EGIS0570_CAL_AFTER_IMAGE[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f} +}; + +static guint8 EGIS0570_CAL_REPEAT[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x0f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f} +}; + +static guint8 EGIS0570_CAL_BORDER_WHITE_SETTING[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3f}, + {0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x3f}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f} +}; + + +static guint8 EGIS0570_CAL_FIRST_BS_SETTING[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00}, +}; + +static guint8 EGIS0570_CAL_BEFORE_GET_IMAGE[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f} +}; + +static guint8 EGIS0570_CAL_NO_IMAGE_CAPTURING_AREA[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x1c}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x1c}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x31}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x40} +}; + +static guint8 EGIS0570_CAL_NO_IMAGE_SETTING_0[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x05}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x08, 0x1c} +}; + +static guint8 EGIS0570_CAL_NO_IMAGE_BINARY_14_SETTING[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0b, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0c, 0xff}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0d, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x0e, 0xff}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x1d}, + {0x45, 0x47, 0x49, 0x53, 0x01, 0x04, 0x00} +}; + +static guint8 EGIS0570_CAL_NO_IMAGE_PRE_FIRST[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x01, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x00, 0x01, 0x00} +}; + + +static guint8 EGIS0570_CAL_NO_IMAGE_REQUEST[][EGIS0570_PKTSIZE] = +{ + {0x45, 0x47, 0x49, 0x53, 0x01, 0x01, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x00, 0x01, 0x00}, + {0x45, 0x47, 0x49, 0x53, 0x00, 0x01, 0x00} +}; + + +#define EGIS0570_CAL_STATIC_LIST_SIZEOF (sizeof ((EGIS0570_CAL_STATIC_LIST)) / sizeof ((EGIS0570_CAL_STATIC_LIST[0]))) + +static guint8 * EGIS0570_CAL_STATIC_LIST[] = { + *EGIS0570_CAL_CONFIGURATION_MODE_PKT, + *EGIS0570_CAL_PKT_ZERO_RANGE, + *EGIS0570_CAL_CAPTURING_AREA, + *EGIS0570_CAL_SENSOR_AND_EMITTER, + *EGIS0570_CAL_WHITE_SETTING, + *EGIS0570_CAL_BLACK_WHITE_GET_IMAGE, + *EGIS0570_CAL_BLACK_WHITE_AFTER_IMAGE, + *EGIS0570_CAL_BLACK_SETTING, + *EGIS0570_CAL_BLACK_WHITE_CLEAR, + *EGIS0570_CAL_MIDDLE_BLACK_SETTING, + *EGIS0570_CAL_GET_IMAGE, + *EGIS0570_CAL_AFTER_IMAGE, + *EGIS0570_CAL_REPEAT, + *EGIS0570_CAL_BORDER_WHITE_SETTING, + *EGIS0570_CAL_FIRST_BS_SETTING, + *EGIS0570_CAL_BEFORE_GET_IMAGE, + *EGIS0570_CAL_NO_IMAGE_CAPTURING_AREA, + *EGIS0570_CAL_NO_IMAGE_SETTING_0, + *EGIS0570_CAL_NO_IMAGE_BINARY_14_SETTING, + *EGIS0570_CAL_NO_IMAGE_PRE_FIRST, + *EGIS0570_CAL_NO_IMAGE_REQUEST, +}; + + +#define EGIS0570_HELPER_PKT_SIZEOF(x) (sizeof (x) / sizeof (x[0])) + +static guint8 EGIS0570_CAL_STATIC_LIST_SIZE[] = { + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_CONFIGURATION_MODE_PKT), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_PKT_ZERO_RANGE), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_CAPTURING_AREA), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_SENSOR_AND_EMITTER), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_WHITE_SETTING), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BLACK_WHITE_GET_IMAGE), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BLACK_WHITE_AFTER_IMAGE), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BLACK_SETTING), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BLACK_WHITE_CLEAR), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_MIDDLE_BLACK_SETTING), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_GET_IMAGE), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_AFTER_IMAGE), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_REPEAT), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BORDER_WHITE_SETTING), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_FIRST_BS_SETTING), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_BEFORE_GET_IMAGE), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_CAPTURING_AREA), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_SETTING_0), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_BINARY_14_SETTING), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_PRE_FIRST), + EGIS0570_HELPER_PKT_SIZEOF (EGIS0570_CAL_NO_IMAGE_REQUEST), +}; + + +/* Calibration logic */ +enum cal_proc_en { + CAL_CONF_PKT, + CAL_PKT_ZERO_RNG, + CAL_CAPT_AREA, + CAL_SENS_AND_EMIT, + CAL_RNG_20_58, + CAL_RNG_60_D0, + CAL_WHITE_SET, + CAL_BLACK_WHITE_GET_IMG, + CAL_BLACK_WHITE_AFTER_IMAGE, + CAL_BLACK_SET, + CAL_CHECK_BLACK_WHITE, + CAL_5_ROWS_ZEROS, + CAL_BLACK_WHITE_CLEAR, + CAL_RNG_60_D1, + CAL_MID_BLACK_SET, + CAL_GET_IMG, + CAL_AFTER_IMG, + CAL_GET_9, + CAL_BORDER_WHITE_SET, + CAL_FIRST_BS_SET, + CAL_BS_CHK_SET, + CAL_PKT_02, + CAL_BEFORE_IMG, + CAL_BS_JUMP, + CAL_BS_END, + CAL_PKT_15_0, + CAL_PKT_16_3C, + CAL_CHK_NEW_CONF, + CAL_GET_21, + CAL_NO_IMG_CAP_AREA, + CAL_NO_IMG_SET_0, + CAL_NO_IMG_03_1C, + CAL_NO_CHK_03_80, + CAL_NO_SET_03_80, + CAL_NO_IMG_14_BS_SET, + CAL_NO_IMG_14_BS_CHK_SET, + CAL_NO_IMG_PRE_FIRST, + CAL_NO_IMG_GET_8, + CAL_NO_IMG_14_BS_JUMP, + CAL_NO_IMG_14_BS_END, + CAL_NO_IMG_16_BS_SET, + CAL_NO_IMG_16_BS_CHK_SET_15, + CAL_NO_IMG_16_BS_SET_16, + CAL_NO_IMG_16_BS_JUMP, + CAL_NO_IMG_16_BS_END, + + + CAL_END, +}; + + +#define EGIS0570_CAL_PROC_SIZEOF (sizeof ((calibration_procedure)) / sizeof ((calibration_procedure[0]))) + +static guint8 calibration_procedure[] = { + // conf + CAL_CONF_PKT, + // sensor check + CAL_PKT_ZERO_RNG, + CAL_CAPT_AREA, + CAL_SENS_AND_EMIT, + CAL_RNG_20_58, + CAL_RNG_60_D0, + CAL_WHITE_SET, + CAL_BLACK_WHITE_GET_IMG, + CAL_BLACK_WHITE_AFTER_IMAGE, + CAL_BLACK_SET, + CAL_BLACK_WHITE_GET_IMG, + CAL_BLACK_WHITE_AFTER_IMAGE, + CAL_CHECK_BLACK_WHITE, + // not binary 16 + CAL_CAPT_AREA, + CAL_5_ROWS_ZEROS, + CAL_BLACK_WHITE_CLEAR, + CAL_RNG_20_58, + CAL_RNG_60_D1, + CAL_MID_BLACK_SET, + CAL_GET_IMG, + CAL_AFTER_IMG, + CAL_GET_9, + CAL_BORDER_WHITE_SET, + CAL_GET_IMG, + CAL_AFTER_IMG, + CAL_GET_9, + // binary + CAL_FIRST_BS_SET, + CAL_BS_CHK_SET, // 0 + CAL_PKT_02, // 1 + CAL_BEFORE_IMG, // 2 + CAL_GET_IMG, // 3 + CAL_AFTER_IMG, // 4 + CAL_GET_9, // 5 + CAL_BS_JUMP, // 6 + CAL_BS_END, // 7 + // check pictures. + CAL_PKT_15_0, + CAL_PKT_16_3C, + CAL_CHK_NEW_CONF, + CAL_PKT_02, + CAL_BEFORE_IMG, + CAL_GET_IMG, + CAL_AFTER_IMG, + CAL_GET_21, + // no image 14 + CAL_NO_IMG_CAP_AREA, + CAL_NO_IMG_SET_0, + CAL_NO_IMG_03_1C, + CAL_NO_CHK_03_80, + CAL_NO_SET_03_80, + CAL_NO_IMG_14_BS_SET, + CAL_NO_IMG_14_BS_CHK_SET, // 0 + CAL_NO_IMG_PRE_FIRST, // 1 + CAL_NO_IMG_GET_8, // 2 + CAL_NO_IMG_14_BS_JUMP, // 3 + CAL_NO_IMG_14_BS_END, // 4 + // no image 16 + CAL_NO_IMG_16_BS_SET, + CAL_NO_IMG_16_BS_CHK_SET_15, // 0 + CAL_NO_IMG_16_BS_SET_16, // 1 + CAL_NO_IMG_PRE_FIRST, // 2 + CAL_NO_IMG_GET_8, // 3 + CAL_NO_IMG_16_BS_JUMP, // 4 + CAL_NO_IMG_16_BS_END, // 5 + // end + CAL_CONF_PKT, + CAL_CONF_PKT, + + CAL_END, +}; diff --git a/tests/egis0570/capture.pcapng b/tests/egis0570/capture.pcapng index 1f7ef8a2..4697624d 100644 Binary files a/tests/egis0570/capture.pcapng and b/tests/egis0570/capture.pcapng differ diff --git a/tests/egis0570/capture.png b/tests/egis0570/capture.png index 107fd6a6..711429a6 100644 Binary files a/tests/egis0570/capture.png and b/tests/egis0570/capture.png differ diff --git a/tests/egis0570/device b/tests/egis0570/device index 3001bd98..cdbd17f3 100644 --- a/tests/egis0570/device +++ b/tests/egis0570/device @@ -1,30 +1,44 @@ P: /devices/pci0000:00/0000:00:14.0/usb1/1-9 -N: bus/usb/001/005=12011001000000087A1C700541100102030109022000010100A0320904000002FF0000000705830240000007050402400003 -E: DEVNAME=/dev/bus/usb/001/005 +N: bus/usb/001/013=12011001000000087A1C700541100102030109022000010100A0320904000002FF0000000705830240000007050402400003 +E: BUSNUM=001 +E: CURRENT_TAGS=:seat: +E: DEVNAME=/dev/bus/usb/001/013 +E: DEVNUM=013 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_AUTOSUSPEND=1 +E: ID_BUS=usb +E: ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_9 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 allowlist +E: ID_PATH_WITH_USB_REVISION=pci-0000:00:14.0-usbv2-0:9 +E: ID_PERSIST=0 +E: ID_REVISION=1041 +E: ID_SERIAL=EgisTec_EgisTec_Touch_Fingerprint_Sensor_0007989A +E: ID_SERIAL_SHORT=0007989A +E: ID_USB_INTERFACES=:ff0000: +E: ID_USB_MODEL=EgisTec_Touch_Fingerprint_Sensor +E: ID_USB_MODEL_ENC=EgisTec\x20Touch\x20Fingerprint\x20Sensor +E: ID_USB_MODEL_ID=0570 +E: ID_USB_REVISION=1041 +E: ID_USB_SERIAL=EgisTec_EgisTec_Touch_Fingerprint_Sensor_0007989A +E: ID_USB_SERIAL_SHORT=0007989A +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=12 +E: PRODUCT=1c7a/570/1041 +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 @@ -38,32 +52,34 @@ A: bNumInterfaces= 1\n A: bcdDevice=1041\n A: bmAttributes=a0\n A: busnum=1\n -A: configuration=\n +A: configuration= H: descriptors=12011001000000087A1C700541100102030109022000010100A0320904000002FF0000000705830240000007050402400003 -A: dev=189:4\n -A: devnum=5\n +A: dev=189:12\n +A: devnum=13\n A: devpath=9\n L: driver=../../../../../bus/usb/drivers/usb +L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1d/device:1e/device:28 A: idProduct=0570\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=unknown\n +A: physical_location/vertical_position=upper\n L: port=../1-0:1.0/usb1-port9 -A: power/active_duration=362352\n -A: power/async=enabled\n +A: power/active_duration=434262\n A: power/autosuspend=2\n A: power/autosuspend_delay_ms=2000\n -A: power/connected_duration=5526124\n +A: power/connected_duration=2971461\n A: power/control=auto\n A: power/level=auto\n -A: power/persist=1\n -A: power/runtime_active_kids=0\n -A: power/runtime_active_time=365097\n -A: power/runtime_enabled=enabled\n +A: power/persist=0\n +A: power/runtime_active_time=436346\n A: power/runtime_status=active\n -A: power/runtime_suspended_time=5160752\n -A: power/runtime_usage=0\n +A: power/runtime_suspended_time=2534879\n A: power/wakeup=disabled\n A: power/wakeup_abort_count=\n A: power/wakeup_active=\n @@ -77,41 +93,52 @@ A: product=EgisTec Touch Fingerprint Sensor\n A: quirks=0x0\n A: removable=fixed\n A: rx_lanes=1\n -A: serial=W700B41B\n +A: serial=0007989A\n A: speed=12\n A: tx_lanes=1\n -A: urbnum=8040\n +A: urbnum=95937\n A: version= 1.10\n P: /devices/pci0000:00/0000:00:14.0/usb1 -N: bus/usb/001/001=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C +N: bus/usb/001/001=12010002090001406B1D020017060302010109021900010100E0000904000001090000000705810304000C +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: 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_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_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_MODEL_ID=0002 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: ID_REVISION=0617 +E: ID_SERIAL=Linux_6.17.5-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=0617 +E: ID_USB_SERIAL=Linux_6.17.5-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.17.5-arch1-1_xhci-hcd +E: ID_USB_VENDOR_ENC=Linux\x206.17.5-arch1-1\x20xhci-hcd +E: ID_USB_VENDOR_ID=1d6b +E: ID_VENDOR=Linux_6.17.5-arch1-1_xhci-hcd +E: ID_VENDOR_ENC=Linux\x206.17.5-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/617 +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 @@ -123,34 +150,31 @@ A: bMaxPacketSize0=64\n A: bMaxPower=0mA\n A: bNumConfigurations=1\n A: bNumInterfaces= 1\n -A: bcdDevice=0508\n +A: bcdDevice=0617\n A: bmAttributes=e0\n A: busnum=1\n -A: configuration=\n -H: descriptors=12010002090001406B1D020008050302010109021900010100E0000904000001090000000705810304000C +A: configuration= +H: descriptors=12010002090001406B1D020017060302010109021900010100E0000904000001090000000705810304000C 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:1d/device:1e A: idProduct=0002\n A: idVendor=1d6b\n A: interface_authorized_default=1\n A: ltm_capable=no\n -A: manufacturer=Linux 5.8.0-59-generic xhci-hcd\n +A: manufacturer=Linux 6.17.5-arch1-1 xhci-hcd\n A: maxchild=12\n -A: power/active_duration=378024\n -A: power/async=enabled\n +A: power/active_duration=1253682\n A: power/autosuspend=0\n A: power/autosuspend_delay_ms=0\n -A: power/connected_duration=5527220\n +A: power/connected_duration=6204832\n A: power/control=auto\n A: power/level=auto\n -A: power/runtime_active_kids=1\n -A: power/runtime_active_time=377962\n -A: power/runtime_enabled=enabled\n +A: power/runtime_active_time=1253672\n A: power/runtime_status=active\n -A: power/runtime_suspended_time=5149253\n -A: power/runtime_usage=0\n +A: power/runtime_suspended_time=4951157\n A: power/wakeup=disabled\n A: power/wakeup_abort_count=\n A: power/wakeup_active=\n @@ -167,62 +191,72 @@ A: rx_lanes=1\n A: serial=0000:00:14.0\n A: speed=480\n A: tx_lanes=1\n -A: urbnum=956\n +A: urbnum=2401\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:v00008086d00009D2Fsv00001025sd0000118Cbc0Csc03i30 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: PCI_SUBSYS_ID=1025:118C 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\n A: broken_parity_status=0\n A: class=0x0c0330\n -H: config=86802F9D060490022130030C00008000040021A400000000000000000000000000000000000000000000000025108E11000000007000000000000000FF010000 +H: config=86802F9D060490022130030C00008000040011B100000000000000000000000000000000000000000000000025108C11000000007000000000000000FF010000FD01348088C60F8000000000000000005B6ECE0F000000000000000000000000306000000000000000000000000000000180C2C10800000000000000000000000500B7001803E0FE0000000000000000090014F01000400100000000C10A080000080000001800008F400200000104000100000002000000100000000C000000000000000000000000000000000000000100000002000000000000000C000000000000000000000000000000000000000000000000000000B30F410800000000 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 -A: irq=127\n -A: local_cpulist=0-7\n -A: local_cpus=ff\n -A: modalias=pci:v00008086d00009D2Fsv00001025sd0000118Ebc0Csc03i30\n +L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1d +A: irq=123\n +A: local_cpulist=0-3\n +A: local_cpus=f\n +A: modalias=pci:v00008086d00009D2Fsv00001025sd0000118Cbc0Csc03i30\n A: msi_bus=1\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: 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 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\n -A: power/async=enabled\n -A: power/control=on\n -A: power/runtime_active_kids=1\n -A: power/runtime_active_time=5524703\n -A: power/runtime_enabled=forbidden\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 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n +A: power/control=auto\n +A: power/runtime_active_time=1256085\n A: power/runtime_status=active\n -A: power/runtime_suspended_time=3373\n -A: power/runtime_usage=1\n +A: power/runtime_suspended_time=4949020\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_active_count=7\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: 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\n +A: power/wakeup_expire_count=7\n +A: power/wakeup_last_time_ms=3233739\n +A: power/wakeup_max_time_ms=108\n +A: power/wakeup_total_time_ms=736\n +A: power_state=D0\n +A: resource=0x00000000b1110000 0x00000000b111ffff 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=0x118e\n +A: subsystem_device=0x118c\n A: subsystem_vendor=0x1025\n A: vendor=0x8086\n