Commit cfe60c06 authored by Igor Filatov's avatar Igor Filatov

Add Elan driver

parent d82847a6
......@@ -23,7 +23,7 @@ AC_SUBST(lt_major)
AC_SUBST(lt_revision)
AC_SUBST(lt_age)
all_drivers="upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes2660 aes3500 aes4000 vfs101 vfs301 vfs5011 upektc_img etes603 vfs0050"
all_drivers="upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes2660 aes3500 aes4000 vfs101 vfs301 vfs5011 upektc_img etes603 vfs0050 elan"
require_imaging='no'
require_aeslib='no'
......@@ -49,6 +49,7 @@ enable_vfs5011='no'
enable_upektc_img='no'
enable_etes603='no'
enable_vfs0050='no'
enable_elan='no'
AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers],
[List of drivers to enable])],
......@@ -155,6 +156,10 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do
AC_DEFINE([ENABLE_VFS0050], [], [Build Validity VFS0050 driver])
enable_vfs0050="yes"
;;
elan)
AC_DEFINE([ENABLE_ELAN], [], [Build Elan driver])
enable_elan="yes"
;;
esac
done
......@@ -181,6 +186,7 @@ AM_CONDITIONAL([ENABLE_VFS5011], [test "$enable_vfs5011" = "yes"])
AM_CONDITIONAL([ENABLE_UPEKTC_IMG], [test "$enable_upektc_img" = "yes"])
AM_CONDITIONAL([ENABLE_ETES603], [test "$enable_etes603" = "yes"])
AM_CONDITIONAL([ENABLE_VFS0050], [test "$enable_vfs0050" = "yes"])
AM_CONDITIONAL([ENABLE_ELAN], [test "$enable_elan" = "yes"])
PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1])
......@@ -407,6 +413,11 @@ if test x$enable_vfs0050 != xno ; then
else
AC_MSG_NOTICE([ vfs0050 driver disabled])
fi
if test x$enable_elan != xno ; then
AC_MSG_NOTICE([** elan driver enabled])
else
AC_MSG_NOTICE([ elan driver disabled])
fi
if test x$require_aeslib != xno ; then
AC_MSG_NOTICE([** aeslib helper functions enabled])
else
......
......@@ -22,6 +22,7 @@ VFS5011_SRC = drivers/vfs5011.c drivers/vfs5011_proto.h
UPEKTC_IMG_SRC = drivers/upektc_img.c drivers/upektc_img.h
ETES603_SRC = drivers/etes603.c
VFS0050_SRC = drivers/vfs0050.c drivers/vfs0050.h
ELAN_SRC = drivers/elan.c drivers/elan.h
EXTRA_DIST = \
$(UPEKE2_SRC) \
......@@ -44,6 +45,7 @@ EXTRA_DIST = \
$(UPEKTC_IMG_SRC) \
$(ETES603_SRC) \
$(VFS0050_SRC) \
$(ELAN_SRC) \
drivers/aesx660.c \
drivers/aesx660.h \
drivers/aes3k.c \
......@@ -190,6 +192,10 @@ if ENABLE_VFS0050
DRIVER_SRC += $(VFS0050_SRC)
endif
if ENABLE_ELAN
DRIVER_SRC += $(ELAN_SRC)
endif
if REQUIRE_PIXMAN
OTHER_SRC += pixman.c
libfprint_la_CFLAGS += $(IMAGING_CFLAGS)
......
......@@ -401,6 +401,9 @@ static struct fp_img_driver * const img_drivers[] = {
#ifdef ENABLE_VFS0050
&vfs0050_driver,
#endif
#ifdef ENABLE_ELAN
&elan_driver,
#endif
/*#ifdef ENABLE_FDU2000
&fdu2000_driver,
#endif
......
......@@ -41,6 +41,7 @@ enum {
ETES603_ID = 18,
VFS5011_ID = 19,
VFS0050_ID = 20,
ELAN_ID = 21,
};
#endif
This diff is collapsed.
/*
* Elan driver for libfprint
*
* Copyright (C) 2017 Igor Filatov <ia.filatov@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 __ELAN_H
#define __ELAN_H
#include <string.h>
#include <libusb.h>
/* number of pixels to discard on left and right (along raw image height)
* because they have different intensity from the rest of the frame */
#define ELAN_FRAME_MARGIN 12
/* min and max frames in a capture */
#define ELAN_MIN_FRAMES 7
#define ELAN_MAX_FRAMES 30
/* number of frames to drop at the end of capture because frames captured
* while the finger is being lifted can be bad */
#define ELAN_SKIP_LAST_FRAMES 1
#define ELAN_CMD_LEN 0x2
#define ELAN_EP_CMD_OUT (0x1 | LIBUSB_ENDPOINT_OUT)
#define ELAN_EP_CMD_IN (0x3 | LIBUSB_ENDPOINT_IN)
#define ELAN_EP_IMG_IN (0x2 | LIBUSB_ENDPOINT_IN)
/* usual command timeout and timeout for when we need to check if the finger is
* still on the device */
#define ELAN_CMD_TIMEOUT 10000
#define ELAN_FINGER_TIMEOUT 200
struct elan_cmd {
unsigned char cmd[ELAN_CMD_LEN];
int response_len;
int response_in;
};
static const struct elan_cmd get_sensor_dim_cmds[] = {
{
.cmd = {0x00, 0x0c},
.response_len = 0x4,
.response_in = ELAN_EP_CMD_IN,
},
};
static const size_t get_sensor_dim_cmds_len =
array_n_elements(get_sensor_dim_cmds);
static const struct elan_cmd init_start_cmds[] = {
{
.cmd = {0x40, 0x19},
.response_len = 0x2,
.response_in = ELAN_EP_CMD_IN,
},
{
.cmd = {0x40, 0x2a},
.response_len = 0x2,
.response_in = ELAN_EP_CMD_IN,
},
};
static const size_t init_start_cmds_len = array_n_elements(init_start_cmds);
static const struct elan_cmd read_cmds[] = {
/* raw frame sizes are calculated from image dimesions reported by the
* device */
{
.cmd = {0x00, 0x09},
.response_len = -1,
.response_in = ELAN_EP_IMG_IN,
},
};
const size_t read_cmds_len = array_n_elements(read_cmds);
/* issued after data reads during init and calibration */
static const struct elan_cmd init_end_cmds[] = {
{
.cmd = {0x40, 0x24},
.response_len = 0x2,
.response_in = ELAN_EP_CMD_IN,
},
};
static const size_t init_end_cmds_len = array_n_elements(init_end_cmds);
/* same command 2 times
* original driver may observe return value to determine how many times it
* should be repeated */
static const struct elan_cmd calibrate_start_cmds[] = {
{
.cmd = {0x40, 0x23},
.response_len = 0x1,
.response_in = ELAN_EP_CMD_IN,
},
{
.cmd = {0x40, 0x23},
.response_len = 0x1,
.response_in = ELAN_EP_CMD_IN,
},
};
static const size_t calibrate_start_cmds_len =
array_n_elements(calibrate_start_cmds);
/* issued after data reads during init and calibration */
static const struct elan_cmd calibrate_end_cmds[] = {
{
.cmd = {0x40, 0x24},
.response_len = 0x2,
.response_in = ELAN_EP_CMD_IN,
},
};
static const size_t calibrate_end_cmds_len =
array_n_elements(calibrate_end_cmds);
static const struct elan_cmd capture_start_cmds[] = {
/* led on */
{
.cmd = {0x40, 0x31},
.response_len = 0x0,
.response_in = ELAN_EP_CMD_IN,
},
};
static size_t capture_start_cmds_len = array_n_elements(capture_start_cmds);
static const struct elan_cmd capture_wait_finger_cmds[] = {
/* wait for finger
* subsequent read will not complete until finger is placed on the reader */
{
.cmd = {0x40, 0x3f},
.response_len = 0x1,
.response_in = ELAN_EP_CMD_IN,
},
};
static size_t capture_wait_finger_cmds_len =
array_n_elements(capture_wait_finger_cmds);
static const struct elan_cmd deactivate_cmds[] = {
/* led off */
{
.cmd = {0x00, 0x0b},
.response_len = 0x0,
.response_in = ELAN_EP_CMD_IN,
},
};
static const size_t deactivate_cmds_len = array_n_elements(deactivate_cmds);
static void elan_cmd_cb(struct libusb_transfer *transfer);
static void elan_cmd_read(struct fpi_ssm *ssm);
static void elan_run_next_cmd(struct fpi_ssm *ssm);
static void elan_capture(struct fp_img_dev *dev);
#endif
......@@ -308,6 +308,9 @@ extern struct fp_img_driver etes603_driver;
#ifdef ENABLE_VFS0050
extern struct fp_img_driver vfs0050_driver;
#endif
#ifdef ENABLE_ELAN
extern struct fp_img_driver elan_driver;
#endif
extern libusb_context *fpi_usb_ctx;
extern GSList *opened_devices;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment