egistec: Add new driver
This supports 1c7a:0570 Co-Authored-By: Maxim Kolesnikov <kolesnikov@svyazcom.ru>
This commit is contained in:
parent
29048c51db
commit
f7290255e0
6 changed files with 629 additions and 2 deletions
|
@ -64,6 +64,11 @@ usb:v08FFp5731*
|
||||||
usb:v5501p08FF*
|
usb:v5501p08FF*
|
||||||
ID_AUTOSUSPEND=1
|
ID_AUTOSUSPEND=1
|
||||||
|
|
||||||
|
# Supported by libfprint driver egis0570
|
||||||
|
usb:v1C7Ap0570*
|
||||||
|
usb:v1C7Ap0571*
|
||||||
|
ID_AUTOSUSPEND=1
|
||||||
|
|
||||||
# Supported by libfprint driver elan
|
# Supported by libfprint driver elan
|
||||||
usb:v04F3p0903*
|
usb:v04F3p0903*
|
||||||
usb:v04F3p0907*
|
usb:v04F3p0907*
|
||||||
|
@ -264,7 +269,6 @@ usb:v147Ep1002*
|
||||||
usb:v1491p0088*
|
usb:v1491p0088*
|
||||||
usb:v16D1p1027*
|
usb:v16D1p1027*
|
||||||
usb:v1C7Ap0300*
|
usb:v1C7Ap0300*
|
||||||
usb:v1C7Ap0570*
|
|
||||||
usb:v1C7Ap0575*
|
usb:v1C7Ap0575*
|
||||||
usb:v27C6p5042*
|
usb:v27C6p5042*
|
||||||
usb:v27C6p5110*
|
usb:v27C6p5110*
|
||||||
|
|
444
libfprint/drivers/egis0570.c
Normal file
444
libfprint/drivers/egis0570.c
Normal file
|
@ -0,0 +1,444 @@
|
||||||
|
/*
|
||||||
|
* Egis Technology Inc. (aka. LighTuning) 0570 driver for libfprint
|
||||||
|
* Copyright (C) 2021 Maxim Kolesnikov <kolesnikov@svyazcom.ru>
|
||||||
|
* Copyright (C) 2021 Saeed/Ali Rk <saeed.ali.rahimi@gmail.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 "egis0570"
|
||||||
|
|
||||||
|
#include "egis0570.h"
|
||||||
|
#include "drivers_api.h"
|
||||||
|
|
||||||
|
/* Packet types */
|
||||||
|
#define PKT_TYPE_INIT 0
|
||||||
|
#define PKT_TYPE_REPEAT 1
|
||||||
|
|
||||||
|
/* Struct */
|
||||||
|
struct _FpDeviceEgis0570
|
||||||
|
{
|
||||||
|
FpImageDevice parent;
|
||||||
|
|
||||||
|
gboolean running;
|
||||||
|
gboolean stop;
|
||||||
|
|
||||||
|
GSList *strips;
|
||||||
|
guint8 *background;
|
||||||
|
gsize strips_len;
|
||||||
|
|
||||||
|
int pkt_num;
|
||||||
|
int pkt_type;
|
||||||
|
};
|
||||||
|
G_DECLARE_FINAL_TYPE (FpDeviceEgis0570, fpi_device_egis0570, FPI, DEVICE_EGIS0570, FpImageDevice);
|
||||||
|
G_DEFINE_TYPE (FpDeviceEgis0570, fpi_device_egis0570, FP_TYPE_IMAGE_DEVICE);
|
||||||
|
|
||||||
|
static unsigned char
|
||||||
|
egis_get_pixel (struct fpi_frame_asmbl_ctx *ctx, struct fpi_frame *frame, unsigned int x, unsigned int y)
|
||||||
|
{
|
||||||
|
return frame->data[x + y * ctx->frame_width];
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct fpi_frame_asmbl_ctx assembling_ctx = {
|
||||||
|
.frame_width = EGIS0570_IMGWIDTH,
|
||||||
|
.frame_height = EGIS0570_RFMGHEIGHT,
|
||||||
|
.image_width = EGIS0570_IMGWIDTH * 4 / 3,
|
||||||
|
.get_pixel = egis_get_pixel,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Service
|
||||||
|
*/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_last_pkt (FpDevice *dev)
|
||||||
|
{
|
||||||
|
FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev);
|
||||||
|
|
||||||
|
int type = self->pkt_type;
|
||||||
|
int num = self->pkt_num;
|
||||||
|
|
||||||
|
gboolean r;
|
||||||
|
|
||||||
|
r = ((type == PKT_TYPE_INIT) && (num == (EGIS0570_INIT_TOTAL - 1)));
|
||||||
|
r |= ((type == PKT_TYPE_REPEAT) && (num == (EGIS0570_REPEAT_TOTAL - 1)));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a bit for each frame on whether or not a finger has been detected.
|
||||||
|
* e.g. 00110 means that there is a finger in frame two and three.
|
||||||
|
*/
|
||||||
|
static char
|
||||||
|
postprocess_frames (FpDeviceEgis0570 *self, guint8 * img)
|
||||||
|
{
|
||||||
|
size_t mean[EGIS0570_IMGCOUNT] = {0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
if (!self->background)
|
||||||
|
{
|
||||||
|
self->background = g_malloc (EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT);
|
||||||
|
memset (self->background, 255, EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT);
|
||||||
|
|
||||||
|
for (size_t k = 0; k < EGIS0570_IMGCOUNT; k += 1)
|
||||||
|
{
|
||||||
|
guint8 * frame = &img[(k * EGIS0570_IMGSIZE) + EGIS0570_RFMDIS * EGIS0570_IMGWIDTH];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT; i += 1)
|
||||||
|
self->background[i] = MIN (self->background[i], frame[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t k = 0; k < EGIS0570_IMGCOUNT; k += 1)
|
||||||
|
{
|
||||||
|
guint8 * frame = &img[(k * EGIS0570_IMGSIZE) + EGIS0570_RFMDIS * EGIS0570_IMGWIDTH];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT; i += 1)
|
||||||
|
{
|
||||||
|
if (frame[i] - EGIS0570_MARGIN > self->background[i])
|
||||||
|
frame[i] -= self->background[i];
|
||||||
|
else
|
||||||
|
frame[i] = 0;
|
||||||
|
|
||||||
|
mean[k] += frame[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
mean[k] /= EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
char result = 0;
|
||||||
|
|
||||||
|
for (size_t k = 0; k < EGIS0570_IMGCOUNT; k += 1)
|
||||||
|
{
|
||||||
|
fp_dbg ("Finger status (picture number, mean) : %ld , %ld", k, mean[k]);
|
||||||
|
if (mean[k] > EGIS0570_MIN_MEAN)
|
||||||
|
result |= 1 << k;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device communication
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error)
|
||||||
|
{
|
||||||
|
unsigned char *stripdata;
|
||||||
|
gboolean end = FALSE;
|
||||||
|
FpImageDevice *img_self = FP_IMAGE_DEVICE (dev);
|
||||||
|
FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int where_finger_is = postprocess_frames (self, transfer->buffer);
|
||||||
|
|
||||||
|
if (where_finger_is > 0)
|
||||||
|
{
|
||||||
|
FpiImageDeviceState state;
|
||||||
|
|
||||||
|
fpi_image_device_report_finger_status (img_self, TRUE);
|
||||||
|
|
||||||
|
g_object_get (dev, "fpi-image-device-state", &state, NULL);
|
||||||
|
if (state == FPI_IMAGE_DEVICE_STATE_CAPTURE)
|
||||||
|
{
|
||||||
|
for (size_t k = 0; k < EGIS0570_IMGCOUNT; k += 1)
|
||||||
|
{
|
||||||
|
if (where_finger_is & (1 << k))
|
||||||
|
{
|
||||||
|
struct fpi_frame *stripe = g_malloc (EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT + sizeof (struct fpi_frame));
|
||||||
|
stripe->delta_x = 0;
|
||||||
|
stripe->delta_y = 0;
|
||||||
|
stripdata = stripe->data;
|
||||||
|
memcpy (stripdata, (transfer->buffer) + (((k) * EGIS0570_IMGSIZE) + EGIS0570_IMGWIDTH * EGIS0570_RFMDIS), EGIS0570_IMGWIDTH * EGIS0570_RFMGHEIGHT);
|
||||||
|
self->strips = g_slist_prepend (self->strips, stripe);
|
||||||
|
self->strips_len += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
{
|
||||||
|
if (!self->stop && (self->strips_len > 0))
|
||||||
|
{
|
||||||
|
FpImage *img;
|
||||||
|
self->strips = g_slist_reverse (self->strips);
|
||||||
|
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
||||||
|
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
||||||
|
img->flags |= (FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_PARTIAL);
|
||||||
|
g_slist_free_full (self->strips, g_free);
|
||||||
|
self->strips = NULL;
|
||||||
|
self->strips_len = 0;
|
||||||
|
FpImage *resizeImage = fpi_image_resize (img, EGIS0570_RESIZE, EGIS0570_RESIZE);
|
||||||
|
fpi_image_device_image_captured (img_self, resizeImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_image_device_report_finger_status (img_self, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_ssm_next_state (transfer->ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recv_data_resp (FpiSsm *ssm, FpDevice *dev)
|
||||||
|
{
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk (transfer, EGIS0570_EPIN, EGIS0570_INPSIZE);
|
||||||
|
|
||||||
|
transfer->ssm = ssm;
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
|
||||||
|
fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, data_resp_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_resp_cb (FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
fpi_ssm_mark_failed (transfer->ssm, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recv_cmd_resp (FpiSsm *ssm, FpDevice *dev)
|
||||||
|
{
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk (transfer, EGIS0570_EPIN, EGIS0570_PKTSIZE);
|
||||||
|
|
||||||
|
transfer->ssm = ssm;
|
||||||
|
|
||||||
|
fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, cmd_resp_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_cmd_req (FpiSsm *ssm, FpDevice *dev, unsigned char *pkt)
|
||||||
|
{
|
||||||
|
FpiUsbTransfer *transfer = fpi_usb_transfer_new (dev);
|
||||||
|
|
||||||
|
fpi_usb_transfer_fill_bulk_full (transfer, EGIS0570_EPOUT, pkt, EGIS0570_PKTSIZE, NULL);
|
||||||
|
|
||||||
|
transfer->ssm = ssm;
|
||||||
|
transfer->short_is_error = TRUE;
|
||||||
|
|
||||||
|
fpi_usb_transfer_submit (transfer, EGIS0570_TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SSM States
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum sm_states {
|
||||||
|
SM_INIT,
|
||||||
|
SM_START,
|
||||||
|
SM_REQ,
|
||||||
|
SM_RESP,
|
||||||
|
SM_REC_DATA,
|
||||||
|
SM_DONE,
|
||||||
|
SM_STATES_NUM
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
ssm_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||||
|
{
|
||||||
|
FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev);
|
||||||
|
FpImageDevice *img_dev = FP_IMAGE_DEVICE (dev);
|
||||||
|
|
||||||
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
|
case SM_INIT:
|
||||||
|
self->pkt_type = PKT_TYPE_INIT;
|
||||||
|
fpi_ssm_next_state (ssm);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SM_START:
|
||||||
|
if (self->stop)
|
||||||
|
{
|
||||||
|
fp_dbg ("deactivating, marking completed");
|
||||||
|
fpi_ssm_mark_completed (ssm);
|
||||||
|
fpi_image_device_deactivate_complete (img_dev, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->pkt_num = 0;
|
||||||
|
fpi_ssm_next_state (ssm);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SM_REQ:
|
||||||
|
if (self->pkt_type == PKT_TYPE_INIT)
|
||||||
|
send_cmd_req (ssm, dev, init_pkts[self->pkt_num]);
|
||||||
|
else
|
||||||
|
send_cmd_req (ssm, dev, repeat_pkts[self->pkt_num]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SM_RESP:
|
||||||
|
if (is_last_pkt (dev) == FALSE)
|
||||||
|
{
|
||||||
|
recv_cmd_resp (ssm, dev);
|
||||||
|
self->pkt_num += 1;
|
||||||
|
fpi_ssm_jump_to_state (ssm, SM_REQ);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (self->pkt_type == PKT_TYPE_INIT)
|
||||||
|
self->pkt_type = PKT_TYPE_REPEAT;
|
||||||
|
|
||||||
|
fpi_ssm_next_state (ssm);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SM_REC_DATA:
|
||||||
|
recv_data_resp (ssm, dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SM_DONE:
|
||||||
|
fpi_ssm_jump_to_state (ssm, SM_START);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Activation
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
loop_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
|
{
|
||||||
|
FpImageDevice *img_dev = FP_IMAGE_DEVICE (dev);
|
||||||
|
FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev);
|
||||||
|
|
||||||
|
self->running = FALSE;
|
||||||
|
g_clear_pointer (&self->background, g_free);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
fpi_image_device_session_error (img_dev, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_activate (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev);
|
||||||
|
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), ssm_run_state, SM_STATES_NUM);
|
||||||
|
|
||||||
|
self->stop = FALSE;
|
||||||
|
|
||||||
|
fpi_ssm_start (ssm, loop_complete);
|
||||||
|
|
||||||
|
self->running = TRUE;
|
||||||
|
|
||||||
|
fpi_image_device_activate_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opening
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_init (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||||
|
|
||||||
|
fpi_image_device_open_complete (dev, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Closing
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_deinit (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error);
|
||||||
|
|
||||||
|
fpi_image_device_close_complete (dev, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deactivation
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_deactivate (FpImageDevice *dev)
|
||||||
|
{
|
||||||
|
FpDeviceEgis0570 *self = FPI_DEVICE_EGIS0570 (dev);
|
||||||
|
|
||||||
|
if (self->running)
|
||||||
|
self->stop = TRUE;
|
||||||
|
else
|
||||||
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Driver data
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const FpIdEntry id_table[] = {
|
||||||
|
{ .vid = 0x1c7a, .pid = 0x0570, },
|
||||||
|
{ .vid = 0x1c7a, .pid = 0x0571, },
|
||||||
|
{ .vid = 0, .pid = 0, },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_egis0570_init (FpDeviceEgis0570 *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_egis0570_class_init (FpDeviceEgis0570Class *klass)
|
||||||
|
{
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
|
dev_class->id = "egis0570";
|
||||||
|
dev_class->full_name = "Egis Technology Inc. (aka. LighTuning) 0570";
|
||||||
|
dev_class->type = FP_DEVICE_TYPE_USB;
|
||||||
|
dev_class->id_table = id_table;
|
||||||
|
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
|
||||||
|
|
||||||
|
img_class->img_open = dev_init;
|
||||||
|
img_class->img_close = dev_deinit;
|
||||||
|
img_class->activate = dev_activate;
|
||||||
|
img_class->deactivate = dev_deactivate;
|
||||||
|
|
||||||
|
img_class->img_width = EGIS0570_IMGWIDTH;
|
||||||
|
img_class->img_height = -1;
|
||||||
|
|
||||||
|
img_class->bz3_threshold = EGIS0570_BZ3_THRESHOLD; /* security issue */
|
||||||
|
}
|
177
libfprint/drivers/egis0570.h
Normal file
177
libfprint/drivers/egis0570.h
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* Egis Technology Inc. (aka. LighTuning) 0570 driver for libfprint
|
||||||
|
* Copyright (C) 2021 Maxim Kolesnikov <kolesnikov@svyazcom.ru>
|
||||||
|
* Copyright (C) 2021 Saeed/Ali Rk <saeed.ali.rahimi@gmail.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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __EGIS0570_H
|
||||||
|
|
||||||
|
#define __EGIS0570_H 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device data
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EGIS0570_CONF 1
|
||||||
|
#define EGIS0570_INTF 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device endpoints
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EGIS0570_EPOUT 0x04 /* ( 4 | FPI_USB_ENDPOINT_OUT ) */
|
||||||
|
#define EGIS0570_EPIN 0x83 /* ( 3 | FPI_USB_ENDPOINT_IN ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialization packets (7 bytes each)
|
||||||
|
*
|
||||||
|
* First 4 bytes are equivalent to string "EGIS", which must be just a company identificator
|
||||||
|
* Other 3 bytes are not recognized yet and may be not important, as they are always the same
|
||||||
|
|
||||||
|
* Answers for each packet contain 7 bytes again
|
||||||
|
* First 4 bytes are reversed "EGIS", which is "SIGE", which is company ID again
|
||||||
|
* Other 3 bytes are not recognized yet
|
||||||
|
* But there is a pattern.
|
||||||
|
* Sending last packet makes sensor return image
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EGIS0570_TIMEOUT 10000
|
||||||
|
#define EGIS0570_PKTSIZE 7
|
||||||
|
|
||||||
|
#define EGIS0570_INIT_TOTAL (sizeof ((init_pkts)) / sizeof ((init_pkts[0])))
|
||||||
|
|
||||||
|
static unsigned char init_pkts[][EGIS0570_PKTSIZE] =
|
||||||
|
{
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x20, 0x3f },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x58, 0x3f },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x21, 0x09 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x57, 0x09 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x22, 0x03 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x56, 0x03 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x23, 0x01 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x55, 0x01 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x24, 0x01 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x54, 0x01 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3e },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0b },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x03 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x00 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x38 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x00 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x71 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x80 },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe } /* image returned after this packet */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* There is another Packet !
|
||||||
|
* That just Work the same !!
|
||||||
|
* And the Size is different !!!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
#define EGIS0570_INIT_TOTAL2 (sizeof((init_pkts2)) / sizeof((init_pkts2[0])))
|
||||||
|
|
||||||
|
static unsigned char init_pkts2[][EGIS0570_PKTSIZE] =
|
||||||
|
{
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x10, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x11, 0x38},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x12, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x13, 0x71},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x20, 0x3f},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x58, 0x3f},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x21, 0x07},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x57, 0x07},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x22, 0x02},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x56, 0x02},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x23, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x55, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x24, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x54, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x25, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x53, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x15, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x16, 0x3b},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x09, 0x0a},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x14, 0x00},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x03, 0x80},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x80},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f},
|
||||||
|
{0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe}
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After sending initial packets device returns image data (32512 bytes)
|
||||||
|
* To ask device to send image data again, host needs to send four additional packets
|
||||||
|
* Further work is to repeatedly send four repeat packets and read image data
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EGIS0570_INPSIZE 32512
|
||||||
|
|
||||||
|
/* 5 image with captured in different time of size 114 * 57 = 6498
|
||||||
|
* 5 * 6498 = 32490 plus 22 extra unrecognized char size data
|
||||||
|
* Two continuous image in this 5 images may have time delay of less than 20ms
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EGIS0570_IMGSIZE 6498
|
||||||
|
#define EGIS0570_IMGWIDTH 114
|
||||||
|
#define EGIS0570_IMGHEIGHT 57
|
||||||
|
|
||||||
|
/* size of middle area that is used from each frame */
|
||||||
|
#define EGIS0570_RFMGHEIGHT 17
|
||||||
|
/* rows to ignore from top and bottom of the image*/
|
||||||
|
#define EGIS0570_RFMDIS (EGIS0570_IMGHEIGHT - EGIS0570_RFMGHEIGHT) / 2
|
||||||
|
#define EGIS0570_IMGCOUNT 5
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Image repeat request
|
||||||
|
* First 4 bytes are the same as in initialization packets
|
||||||
|
* Have no idea what the other 3 bytes mean
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EGIS0570_REPEAT_TOTAL (sizeof ((repeat_pkts)) / sizeof ((repeat_pkts[0])))
|
||||||
|
|
||||||
|
static unsigned char repeat_pkts[][EGIS0570_PKTSIZE] =
|
||||||
|
{
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x0f },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x00, 0x02, 0x0f },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x01, 0x02, 0x2f },
|
||||||
|
{ 0x45, 0x47, 0x49, 0x53, 0x06, 0x00, 0xfe } /* image returned after this packet */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This sensor is small so I decided to reduce bz3_threshold from
|
||||||
|
* 40 to 10 to have more success to fail ratio
|
||||||
|
* Bozorth3 Algorithm seems not fine at the end
|
||||||
|
* foreget about security :))
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EGIS0570_BZ3_THRESHOLD 25 /* and even less What a joke */
|
||||||
|
|
||||||
|
#define EGIS0570_MIN_MEAN 20
|
||||||
|
#define EGIS0570_MARGIN 3
|
||||||
|
|
||||||
|
#define EGIS0570_RESIZE 2
|
||||||
|
|
||||||
|
#endif
|
|
@ -75,7 +75,6 @@ static const FpIdEntry whitelist_id_table[] = {
|
||||||
{ .vid = 0x1491, .pid = 0x0088 },
|
{ .vid = 0x1491, .pid = 0x0088 },
|
||||||
{ .vid = 0x16d1, .pid = 0x1027 },
|
{ .vid = 0x16d1, .pid = 0x1027 },
|
||||||
{ .vid = 0x1c7a, .pid = 0x0300 },
|
{ .vid = 0x1c7a, .pid = 0x0300 },
|
||||||
{ .vid = 0x1c7a, .pid = 0x0570 },
|
|
||||||
{ .vid = 0x1c7a, .pid = 0x0575 },
|
{ .vid = 0x1c7a, .pid = 0x0575 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5042 },
|
{ .vid = 0x27c6, .pid = 0x5042 },
|
||||||
{ .vid = 0x27c6, .pid = 0x5110 },
|
{ .vid = 0x27c6, .pid = 0x5110 },
|
||||||
|
|
|
@ -117,6 +117,8 @@ driver_sources = {
|
||||||
[ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ],
|
[ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ],
|
||||||
'etes603' :
|
'etes603' :
|
||||||
[ 'drivers/etes603.c' ],
|
[ 'drivers/etes603.c' ],
|
||||||
|
'egis0570' :
|
||||||
|
[ 'drivers/egis0570.c' ],
|
||||||
'vfs0050' :
|
'vfs0050' :
|
||||||
[ 'drivers/vfs0050.c' ],
|
[ 'drivers/vfs0050.c' ],
|
||||||
'elan' :
|
'elan' :
|
||||||
|
|
|
@ -113,6 +113,7 @@ default_drivers = [
|
||||||
'vfs301',
|
'vfs301',
|
||||||
'vfs0050',
|
'vfs0050',
|
||||||
'etes603',
|
'etes603',
|
||||||
|
'egis0570',
|
||||||
'vcom5s',
|
'vcom5s',
|
||||||
'synaptics',
|
'synaptics',
|
||||||
'elan',
|
'elan',
|
||||||
|
|
Loading…
Reference in a new issue