Implement driver for EgisTec EH575 (1c7a:0575) as swipe type sensor

This commit is contained in:
Animeshz 2021-08-11 08:53:49 +05:30
parent dd476c0ccf
commit dca22af462
6 changed files with 580 additions and 1 deletions

20
.vscode/c_cpp_properties.json vendored Normal file
View file

@ -0,0 +1,20 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/**",
"/usr/lib/**",
"${workspaceFolder}/libfprint"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64",
"compileCommands": "${workspaceFolder}/_build/compile_commands.json"
}
],
"version": 4
}

9
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,9 @@
{
"files.associations": {
"string_view": "cpp",
"*.tcc": "c",
"cmath": "c",
"random": "c"
},
"C_Cpp.errorSquiggles": "Disabled"
}

View file

@ -0,0 +1,414 @@
/*
* Egis Technology Inc. (aka. LighTuning) 0575 driver for libfprint
* Copyright (C) 2021 Animesh Sahu <animeshsahu19@yahoo.com>
*
* 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 "egis0575"
#include "egis0575.h"
#include "drivers_api.h"
/*
* ==================== Basic definitions ====================
*/
/* Struct to share data across lifecycle */
struct _FpDeviceEgis0575
{
FpImageDevice parent;
gboolean running;
gboolean stop;
gsize strips_len;
GSList *strips;
Packet *current_pkt;
};
G_DECLARE_FINAL_TYPE(FpDeviceEgis0575, fpi_device_egis0575, FPI, DEVICE_EGIS0575, FpImageDevice);
G_DEFINE_TYPE(FpDeviceEgis0575, fpi_device_egis0575, FP_TYPE_IMAGE_DEVICE);
static unsigned char
egis_get_pixel(struct fpi_frame_asmbl_ctx *ctx, struct fpi_frame *frame, unsigned int x, unsigned int y)
{
return frame->data[x + y * ctx->frame_width];
}
static struct fpi_frame_asmbl_ctx assembling_ctx = {
.frame_width = EGIS0575_IMGWIDTH,
.frame_height = EGIS0575_IMGHEIGHT,
.image_width = EGIS0575_IMGWIDTH * 4 / 3,
.get_pixel = egis_get_pixel,
};
/*
* ==================== Helper functions ====================
*/
#define CONCAT_CHAR(x, y) \
(x << 8 | y)
/* Determines next sequence based off last response_bytes */
static Packet *
next_packet(FpDevice *dev, gint16 response_bytes)
{
FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
Packet *packet = self->current_pkt;
for (size_t i = 0; i < packet->next_mapping_length; i++)
{
if (packet->next_mapping_key[i] == response_bytes)
{
return EGIS0575_PACKETS + packet->next_mapping_idx[i];
}
}
return NULL;
}
/* Checks if self->current_pkt is last packet (packet after which image is returned) */
// static gboolean
// is_last_sequence(FpDevice *dev)
// {
// FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
// unsigned char *sequence = self->current_pkt->sequence;
// return CONCAT_CHAR(sequence[4], sequence[5]) == EGIS0575_ENDING_SEQUENCE_IDENTITY;
// }
/*
* ==================== Data processing ====================
*/
static void finger_present(FpiUsbTransfer *transfer)
{
unsigned char *buffer = transfer->buffer;
int length = transfer->actual_length;
double mean = 0;
double variance = 0;
for (size_t i = 0; i < length; i++)
{
mean += buffer[i];
}
mean /= length;
for (size_t i = 0; i < length; i++)
{
variance += (buffer[i] - mean) * (buffer[i] - mean);
}
variance /= length;
return variance > EGIS0575_MIN_SD * EGIS0575_MIN_SD;
}
static void save_img(FpiUsbTransfer *transfer, FpDevice *dev)
{
FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
if (self->stop)
{
g_slist_free_full(self->strips, g_free);
self->strips_len = 0;
self->strips = NULL;
return;
}
if (!finger_present(transfer))
{
if (self->strips_len > 0)
{
goto START_PROCESSING;
}
}
else
{
struct fpi_frame *stripe = g_malloc(EGIS0575_IMGWIDTH * EGIS0575_RFMGHEIGHT + sizeof(struct fpi_frame));
stripe->delta_x = 0;
stripe->delta_y = 0;
memcpy(stripe->data, (transfer->buffer) + (EGIS0575_IMGWIDTH * EGIS0575_RFMDIS), EGIS0575_IMGWIDTH * EGIS0575_RFMGHEIGHT);
self->strips = g_slist_prepend(self->strips, stripe);
self->strips_len += 1;
}
if (self->strips_len < EGIS0575_CONSECUTIVE_CAPTURES)
{
fpi_ssm_jump_to_state(transfer->ssm, SM_REQ);
}
else
{
START_PROCESSING:
fpi_ssm_next_state(transfer->ssm);
}
}
static void process_img(FpiSsm *ssm, FpDevice *dev)
{
FpImageDevice *img_self = FP_IMAGE_DEVICE(dev);
FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
FpiImageDeviceState state;
fpi_image_device_report_finger_status(img_self, TRUE);
g_object_get(dev, "fpi-image-device-state", &state, NULL);
if (state == FPI_IMAGE_DEVICE_STATE_CAPTURE)
{
if (!self->stop)
{
FpImage *img;
self->strips = g_slist_reverse(self->strips);
fpi_do_movement_estimation(&assembling_ctx, self->strips);
img = fpi_assemble_frames(&assembling_ctx, self->strips);
img->flags |= (FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_PARTIAL);
g_slist_free_full(self->strips, g_free);
self->strips = NULL;
self->strips_len = 0;
FpImage *resizeImage = fpi_image_resize(img, EGIS0575_RESIZE, EGIS0575_RESIZE);
fpi_image_device_image_captured(img_self, resizeImage);
}
fpi_image_device_report_finger_status(img_self, FALSE);
fpi_ssm_next_state(transfer->ssm);
}
}
/*
* ==================== IO ====================
*/
static void
resp_cb(FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error)
{
FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
if (error)
{
fpi_ssm_mark_failed(transfer->ssm, error);
return;
}
if (strncmp(transfer->buffer, "SIGE", 4) == 0) /* Command response received */
{
gint16 response_bytes = CONCAT_CHAR(transfer->buffer[4], transfer->buffer[5]);
Packet *seq = next_packet(dev, response_bytes);
if (seq == NULL)
{
GError *err = g_error_new(G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown sequence detected!");
fpi_ssm_mark_failed(transfer->ssm, err);
g_error_free(err);
}
else
{
self->current_pkt = seq;
fpi_ssm_jump_to_state(transfer->ssm, SM_REQ);
}
}
else /* Image captured */
{
self->current_pkt = EGIS0575_REPEAT_START_PACKET;
save_img(transfer, dev);
}
}
static void
recv_resp(FpiSsm *ssm, FpDevice *dev, int response_length)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
fpi_usb_transfer_fill_bulk(transfer, EGIS0575_EPIN, response_length);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, EGIS0575_TIMEOUT, NULL, resp_cb, NULL);
}
static void
send_req(FpiSsm *ssm, FpDevice *dev, Packet *pkt)
{
FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev);
fpi_usb_transfer_fill_bulk_full(transfer, EGIS0575_EPOUT, pkt->sequence, pkt->length, NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit(transfer, EGIS0575_TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
}
/*
* ==================== SSM loopback ====================
*/
enum sm_states
{
SM_INIT,
SM_START,
SM_REQ,
SM_RESP,
SM_PROCESS_IMG,
SM_DONE,
SM_STATES_NUM
};
static void
ssm_run_state(FpiSsm *ssm, FpDevice *dev)
{
FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
FpImageDevice *img_dev = FP_IMAGE_DEVICE(dev);
switch (fpi_ssm_get_cur_state(ssm))
{
case SM_INIT:
fp_dbg("Starting capture");
self->current_pkt = EGIS0575_PARTIAL_INIT_START_PACKET;
self->strips_len = 0;
self->strips = NULL;
fpi_ssm_next_state(ssm);
break;
case SM_START:
if (self->stop)
{
fp_dbg("Stopping, completed capture");
fpi_ssm_mark_completed(ssm);
fpi_image_device_deactivate_complete(img_dev, NULL);
}
else
{
fpi_ssm_next_state(ssm);
}
break;
case SM_REQ:
send_req(ssm, dev, self->current_pkt);
break;
case SM_RESP:
recv_resp(ssm, dev, self->current_pkt->response_length);
break;
case SM_PROCESS_IMG:
process_imgs(ssm, dev);
break;
case SM_DONE:
fpi_ssm_jump_to_state(ssm, SM_START);
break;
default:
g_assert_not_reached();
}
}
static void
loop_complete(FpiSsm *ssm, FpDevice *dev, GError *error)
{
FpImageDevice *img_dev = FP_IMAGE_DEVICE(dev);
FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
self->running = FALSE;
g_clear_pointer(&self->background, g_free);
if (error)
fpi_image_device_session_error(img_dev, error);
}
/*
* ==================== Top-level command callback & meta-data ====================
*/
static void
dev_init(FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_claim_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
fpi_image_device_open_complete(dev, error);
}
static void
dev_deinit(FpImageDevice *dev)
{
GError *error = NULL;
g_usb_device_release_interface(fpi_device_get_usb_device(FP_DEVICE(dev)), 0, 0, &error);
fpi_image_device_close_complete(dev, error);
}
static void
dev_stop(FpImageDevice *dev)
{
FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
if (self->running)
self->stop = TRUE;
else
fpi_image_device_deactivate_complete(dev, NULL);
}
static void
dev_start(FpImageDevice *dev)
{
FpDeviceEgis0575 *self = FPI_DEVICE_EGIS0575(dev);
FpiSsm *ssm = fpi_ssm_new(FP_DEVICE(dev), ssm_run_state, SM_STATES_NUM);
self->stop = FALSE;
fpi_ssm_start(ssm, loop_complete);
self->running = TRUE;
fpi_image_device_activate_complete(dev, NULL);
}
static const FpIdEntry id_table[] = {{
.vid = 0x1c7a,
.pid = 0x0575,
}};
static void
fpi_device_egis0575_init(FpDeviceEgis0575 *self)
{
}
static void
fpi_device_egis0575_class_init(FpDeviceEgis0575Class *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS(klass);
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS(klass);
dev_class->id = "egis0575";
dev_class->full_name = "LighTuning Technology Inc. EgisTec EH575";
dev_class->type = FP_DEVICE_TYPE_USB;
dev_class->id_table = id_table;
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
img_class->img_open = dev_init;
img_class->img_close = dev_deinit;
img_class->activate = dev_start;
img_class->deactivate = dev_stop;
img_class->img_width = EGIS0575_IMGWIDTH;
img_class->img_height = EGIS0575_IMGHEIGHT;
img_class->bz3_threshold = EGIS0575_BZ3_THRESHOLD;
}

View file

@ -0,0 +1,135 @@
/*
* Egis Technology Inc. (aka. LighTuning) 0575 driver for libfprint
* Copyright (C) 2021 Animesh Sahu <animeshsahu19@yahoo.com>
*
* 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
*/
#pragma once
/*
* Device data
*/
#define EGIS0575_CONFIGURATION 1
#define EGIS0575_INTERFACE 0
/*
* Device endpoints
*/
#define EGIS0575_EPOUT 0x01 /* ( 1 | FPI_USB_ENDPOINT_OUT ) */
#define EGIS0575_EPIN 0x82 /* ( 2 | FPI_USB_ENDPOINT_IN ) */
/*
* Image polling sequences
*
* First 4 bytes of packet to be sent is "EGIS", rest are unknown but a specific pattern was observed!
* First 4 bytes of response is "SIGE"
*
* Partial sequence usually takes less than half of the sequences to return the image,
* in-case it is not available for use, full sequence is going to be redirected after
* the resonse to the third packet of partial sequence series.
*/
typedef struct Packet
{
int length;
unsigned char *sequence;
int response_length;
int next_mapping_length;
int *next_mapping_key;
int *next_mapping_idx;
} Packet;
#define EGIS0575_PACKETS_TOTAL 51
static const Packet EGIS0575_PACKETS[] = {
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x01, 0x06}, .response_length = 7, .next_mapping_length = 2, .next_mapping_key = (int[]){0x0100, 0x0104}, .next_mapping_idx = (int[]){49, 31}}, // 0
{.length = 9, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x63, 0x2c, 0x02, 0x00, 0x57}, .response_length = 9, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2C02}, .next_mapping_idx = (int[]){2}}, // 1
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x2d, 0x02}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2D47}, .next_mapping_idx = (int[]){3}}, // 2
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x62, 0x67, 0x03}, .response_length = 10, .next_mapping_length = 1, .next_mapping_key = (int[]){0x6703}, .next_mapping_idx = (int[]){4}}, // 3
{.length = 9, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x63, 0x2c, 0x02, 0x00, 0x13}, .response_length = 9, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2C02}, .next_mapping_idx = (int[]){5}}, // 4
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0x02}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x00AB}, .next_mapping_idx = (int[]){6}}, // 5
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x64, 0x14, 0xec}, .response_length = 5356, .next_mapping_length = 0, .next_mapping_key = (int[]){}, .next_mapping_idx = (int[]){}}, // 6
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x2d, 0x20}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2D20}, .next_mapping_idx = (int[]){8}}, // 7
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0x20}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x00AA}, .next_mapping_idx = (int[]){9}}, // 8
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x01, 0x20}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0100}, .next_mapping_idx = (int[]){1}}, // 9
{.length = 13, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x63, 0x26, 0x06, 0x06, 0x60, 0x06, 0x05, 0x2f, 0x06}, .response_length = 13, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2606}, .next_mapping_idx = (int[]){14}}, // 10
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0x66}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x00AA}, .next_mapping_idx = (int[]){12}}, // 11
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x01, 0x66}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0100}, .next_mapping_idx = (int[]){1}}, // 12
{.length = 18, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x63, 0x09, 0x0b, 0x83, 0x24, 0x00, 0x44, 0x0f, 0x08, 0x20, 0x20, 0x01, 0x05, 0x12}, .response_length = 18, .next_mapping_length = 1, .next_mapping_key = (int[]){0x090B}, .next_mapping_idx = (int[]){10}}, // 13
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x23, 0x00}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2300}, .next_mapping_idx = (int[]){15}}, // 14
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x24, 0x33}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2433}, .next_mapping_idx = (int[]){16}}, // 15
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x20, 0x00}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2000}, .next_mapping_idx = (int[]){17}}, // 16
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x21, 0x66}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x2166}, .next_mapping_idx = (int[]){11}}, // 17
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x0f, 0x03}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0F20}, .next_mapping_idx = (int[]){4}}, // 18
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x40, 0x20}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x4000}, .next_mapping_idx = (int[]){13}}, // 19
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x0c, 0x22}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0C22}, .next_mapping_idx = (int[]){24}}, // 20
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x0a, 0xfc}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0AFC}, .next_mapping_idx = (int[]){30}}, // 21
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x0a, 0xf4}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0AF4}, .next_mapping_idx = (int[]){23}}, // 22
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x0c, 0x44}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0C44}, .next_mapping_idx = (int[]){27}}, // 23
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x0b, 0x03}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0B03}, .next_mapping_idx = (int[]){21}}, // 24
{.length = 18, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x63, 0x09, 0x0b, 0x83, 0xf4, 0x03, 0x44, 0x03, 0x0c, 0x17, 0x20, 0x01, 0x0a, 0x72}, .response_length = 18, .next_mapping_length = 1, .next_mapping_key = (int[]){0x090B}, .next_mapping_idx = (int[]){26}}, // 25
{.length = 9, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x63, 0x01, 0x02, 0x0c, 0x03}, .response_length = 9, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0102}, .next_mapping_idx = (int[]){20}}, // 26
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x40, 0x00}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x4000}, .next_mapping_idx = (int[]){28}}, // 27
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x40, 0x00}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x4000}, .next_mapping_idx = (int[]){29}}, // 28
{.length = 9, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x71, 0x02, 0x02, 0x01, 0x0c}, .response_length = 9, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0202}, .next_mapping_idx = (int[]){13}}, // 29
{.length = 13, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x71, 0x45, 0x06, 0x00, 0xbe, 0x87, 0x13, 0x00, 0x03}, .response_length = 13, .next_mapping_length = 1, .next_mapping_key = (int[]){0x4506}, .next_mapping_idx = (int[]){31}}, // 30
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x40, 0x06}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x4083}, .next_mapping_idx = (int[]){22}}, // 31
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0x00}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x00AA}, .next_mapping_idx = (int[]){33}}, // 32
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x01, 0x00}, .response_length = 7, .next_mapping_length = 3, .next_mapping_key = (int[]){0x0100, 0x0101, 0x0104}, .next_mapping_idx = (int[]){22, 41, 22}}, // 33
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x50, 0x03}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x5003}, .next_mapping_idx = (int[]){35}}, // 34
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x50, 0x03}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x5082}, .next_mapping_idx = (int[]){36}}, // 35
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x73, 0x14, 0xec}, .response_length = 5356, .next_mapping_length = 1, .next_mapping_key = (int[]){0x201F}, .next_mapping_idx = (int[]){37}}, // 36
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x40, 0xec}, .response_length = 7, .next_mapping_length = 2, .next_mapping_key = (int[]){0x4000, 0x4083}, .next_mapping_idx = (int[]){10, 22}}, // 37
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0xfc}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x00AA}, .next_mapping_idx = (int[]){39}}, // 38
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x01, 0xfc}, .response_length = 7, .next_mapping_length = 2, .next_mapping_key = (int[]){0x0100, 0x0101}, .next_mapping_idx = (int[]){40, 32}}, // 39
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x40, 0xfc}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x4000}, .next_mapping_idx = (int[]){13}}, // 40
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x0a, 0xfd}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0AFD}, .next_mapping_idx = (int[]){42}}, // 41
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x35, 0x02}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x3502}, .next_mapping_idx = (int[]){43}}, // 42
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x80, 0x00}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x8000}, .next_mapping_idx = (int[]){44}}, // 43
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x80, 0x00}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x8002}, .next_mapping_idx = (int[]){21}}, // 44
{.length = 9, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x63, 0x01, 0x02, 0x0f, 0x03}, .response_length = 9, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0102}, .next_mapping_idx = (int[]){20}}, // 45
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x61, 0x09, 0x83}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0983}, .next_mapping_idx = (int[]){10}}, // 46
{.length = 13, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x71, 0x45, 0x06, 0x00, 0xac, 0x87, 0x13, 0x00, 0x03}, .response_length = 13, .next_mapping_length = 1, .next_mapping_key = (int[]){0x4506}, .next_mapping_idx = (int[]){0}}, // 47
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x40, 0x66}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x4000}, .next_mapping_idx = (int[]){20}}, // 48
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x60, 0x00, 0x06}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x00AA}, .next_mapping_idx = (int[]){0}}, // 49
{.length = 7, .sequence = (unsigned char[]){0x45, 0x47, 0x49, 0x53, 0x97, 0x00, 0x00}, .response_length = 7, .next_mapping_length = 1, .next_mapping_key = (int[]){0x0000}, .next_mapping_idx = (int[]){32}}, // 50
};
static const Packet *EGIS0575_PARTIAL_INIT_START_PACKET = EGIS0575_PACKETS + 38;
static const Packet *EGIS0575_REPEAT_START_PACKET = EGIS0575_PACKETS + 7;
// #define EGIS0575_ENDING_SEQUENCE_IDENTITY 0x14ec /* concat index 5 & 6 of polling sequence */
#define EGIS0575_IMGWIDTH 103
#define EGIS0575_IMGHEIGHT 52
#define EGIS0575_IMGSIZE (EGIS0575_IMGWIDTH * EGIS0575_IMGHEIGHT)
/*
* Copies threshold values of egis0570, because both have quite similar dimensions :)
*/
#define EGIS0575_BZ3_THRESHOLD 25
#define EGIS0575_RFMGHEIGHT 12
#define EGIS0575_RFMDIS (EGIS0575_IMGHEIGHT - EGIS0575_RFMGHEIGHT) / 2
#define EGIS0575_RESIZE 2
/* Minimum standard deviation required to validate finger is present, usual value roam around 20-50 */
#define EGIS0575_MIN_SD 15
#define EGIS0575_TIMEOUT 10000
#define EGIS0575_CONSECUTIVE_CAPTURES 5

View file

@ -75,7 +75,6 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x1491, .pid = 0x0088 },
{ .vid = 0x16d1, .pid = 0x1027 },
{ .vid = 0x1c7a, .pid = 0x0300 },
{ .vid = 0x1c7a, .pid = 0x0575 },
{ .vid = 0x27c6, .pid = 0x5042 },
{ .vid = 0x27c6, .pid = 0x5110 },
{ .vid = 0x27c6, .pid = 0x5117 },

View file

@ -119,6 +119,8 @@ driver_sources = {
[ 'drivers/etes603.c' ],
'egis0570' :
[ 'drivers/egis0570.c' ],
'egis0575' :
[ 'drivers/egis0575.c' ],
'vfs0050' :
[ 'drivers/vfs0050.c' ],
'elan' :