aes3k: add aes3500 driver

This driver supports AES3500 device (08ff:5731) and utilizes common routines from
AES4000.
This commit is contained in:
Juvenn Woo 2013-05-21 13:40:36 +08:00 committed by Vasily Khoruzhick
parent 12c1088777
commit aeca32fc12
6 changed files with 216 additions and 1 deletions

View file

@ -23,7 +23,7 @@ AC_SUBST(lt_major)
AC_SUBST(lt_revision) AC_SUBST(lt_revision)
AC_SUBST(lt_age) AC_SUBST(lt_age)
all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes2660 aes4000 vfs101 vfs301" all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes2660 aes3500 aes4000 vfs101 vfs301"
require_imaging='no' require_imaging='no'
require_aeslib='no' require_aeslib='no'
@ -41,6 +41,7 @@ enable_aes1660='no'
enable_aes2501='no' enable_aes2501='no'
enable_aes2550='no' enable_aes2550='no'
enable_aes2660='no' enable_aes2660='no'
enable_aes3500='no'
enable_aes4000='no' enable_aes4000='no'
enable_vfs101='no' enable_vfs101='no'
enable_vfs301='no' enable_vfs301='no'
@ -112,6 +113,13 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do
require_aesX660="yes" require_aesX660="yes"
enable_aes2660="yes" enable_aes2660="yes"
;; ;;
aes3500)
AC_DEFINE([ENABLE_AES3500], [], [Build AuthenTec AES3500 driver])
require_aeslib="yes"
require_imaging="yes"
require_aes3k="yes"
enable_aes3500="yes"
;;
aes4000) aes4000)
AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver]) AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver])
require_aeslib="yes" require_aeslib="yes"
@ -142,6 +150,7 @@ AM_CONDITIONAL([ENABLE_AES1660], [test "$enable_aes1660" = "yes"])
AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"]) AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"])
AM_CONDITIONAL([ENABLE_AES2550], [test "$enable_aes2550" = "yes"]) AM_CONDITIONAL([ENABLE_AES2550], [test "$enable_aes2550" = "yes"])
AM_CONDITIONAL([ENABLE_AES2660], [test "$enable_aes2660" = "yes"]) AM_CONDITIONAL([ENABLE_AES2660], [test "$enable_aes2660" = "yes"])
AM_CONDITIONAL([ENABLE_AES3500], [test "$enable_aes3500" = "yes"])
AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"]) AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"])
AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"]) AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"])
AM_CONDITIONAL([REQUIRE_AESX660], [test "$require_aesX660" = "yes"]) AM_CONDITIONAL([REQUIRE_AESX660], [test "$require_aesX660" = "yes"])
@ -344,6 +353,11 @@ if test x$enable_aes2660 != xno ; then
else else
AC_MSG_NOTICE([ aes2660 driver disabled]) AC_MSG_NOTICE([ aes2660 driver disabled])
fi fi
if test x$enable_aes3500 != xno ; then
AC_MSG_NOTICE([** aes3500 driver enabled])
else
AC_MSG_NOTICE([ aes3500 driver disabled])
fi
if test x$enable_aes4000 != xno ; then if test x$enable_aes4000 != xno ; then
AC_MSG_NOTICE([** aes4000 driver enabled]) AC_MSG_NOTICE([** aes4000 driver enabled])
else else

View file

@ -12,6 +12,7 @@ AES1660_SRC = drivers/aes1660.c drivers/aes1660.h
AES2501_SRC = drivers/aes2501.c drivers/aes2501.h AES2501_SRC = drivers/aes2501.c drivers/aes2501.h
AES2550_SRC = drivers/aes2550.c drivers/aes2550.h AES2550_SRC = drivers/aes2550.c drivers/aes2550.h
AES2660_SRC = drivers/aes2660.c drivers/aes2660.h AES2660_SRC = drivers/aes2660.c drivers/aes2660.h
AES3500_SRC = drivers/aes3500.c
AES4000_SRC = drivers/aes4000.c AES4000_SRC = drivers/aes4000.c
FDU2000_SRC = drivers/fdu2000.c FDU2000_SRC = drivers/fdu2000.c
VCOM5S_SRC = drivers/vcom5s.c VCOM5S_SRC = drivers/vcom5s.c
@ -29,6 +30,7 @@ EXTRA_DIST = \
$(AES2501_SRC) \ $(AES2501_SRC) \
$(AES2550_SRC) \ $(AES2550_SRC) \
$(AES2660_SRC) \ $(AES2660_SRC) \
$(AES3500_SRC) \
$(AES4000_SRC) \ $(AES4000_SRC) \
$(FDU2000_SRC) \ $(FDU2000_SRC) \
$(VCOM5S_SRC) \ $(VCOM5S_SRC) \
@ -147,6 +149,10 @@ if ENABLE_AES2660
DRIVER_SRC += $(AES2660_SRC) DRIVER_SRC += $(AES2660_SRC)
endif endif
if ENABLE_AES3500
DRIVER_SRC += $(AES3500_SRC)
endif
if ENABLE_AES4000 if ENABLE_AES4000
DRIVER_SRC += $(AES4000_SRC) DRIVER_SRC += $(AES4000_SRC)
endif endif

View file

@ -349,6 +349,9 @@ static struct fp_driver * const primitive_drivers[] = {
}; };
static struct fp_img_driver * const img_drivers[] = { static struct fp_img_driver * const img_drivers[] = {
#ifdef ENABLE_AES3500
&aes3500_driver,
#endif
#ifdef ENABLE_AES4000 #ifdef ENABLE_AES4000
&aes4000_driver, &aes4000_driver,
#endif #endif

188
libfprint/drivers/aes3500.c Normal file
View file

@ -0,0 +1,188 @@
/*
* AuthenTec AES3500 driver for libfprint
*
* AES3500 is a press-typed sensor, which captures image in 128x128
* pixels.
*
* Thanks Rafael Toledo for the Windows driver and the help.
*
* This work is derived from Daniel Drake's AES4000 driver.
*
* Copyright (C) 2011-2013 Juvenn Woo <machese@gmail.com>
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* 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 "aes3500"
#include <errno.h>
#include <glib.h>
#include <libusb.h>
#include <aeslib.h>
#include <fp_internal.h>
#include "aes3k.h"
#include "driver_ids.h"
#define DATA_BUFLEN 0x2089
/* image size = FRAME_WIDTH x FRAME_WIDTH */
#define FRAME_WIDTH 128
#define FRAME_SIZE (FRAME_WIDTH * AES3K_FRAME_HEIGHT / 2)
#define FRAME_NUMBER (FRAME_WIDTH / AES3K_FRAME_HEIGHT)
#define ENLARGE_FACTOR 2
static struct aes_regwrite init_reqs[] = {
/* master reset */
{ 0x80, 0x01 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
{ 0x81, 0x00 },
{ 0x80, 0x00 },
{ 0, 0 },
/* scan reset */
{ 0x80, 0x02 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
/* disable register buffering */
{ 0x80, 0x04 },
{ 0, 0 },
{ 0x80, 0x00 },
{ 0, 0 },
{ 0x81, 0x00 },
{ 0, 0 },
/* windows driver reads registers now (81 02) */
{ 0x80, 0x00 },
{ 0x81, 0x00 },
/* set excitation bias current: 2mhz drive ring frequency,
* 4V drive ring voltage, 16.5mA excitation bias */
{ 0x82, 0x04 },
/* continuously sample drive ring for finger detection,
* 62.50ms debounce delay */
{ 0x83, 0x13 },
{ 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
{ 0x85, 0x3d }, /* set calibration capacitance */
{ 0x86, 0x03 }, /* detect drive voltage */
{ 0x87, 0x01 }, /* set detection frequency to 125khz */
{ 0x88, 0x02 }, /* set column scan period */
{ 0x89, 0x02 }, /* set measure drive */
{ 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
{ 0x8b, 0x33 }, /* set matrix pattern */
{ 0x8c, 0x0f }, /* set demodulation phase 1 */
{ 0x8d, 0x04 }, /* set demodulation phase 2 */
{ 0x8e, 0x23 }, /* set sensor gain */
{ 0x8f, 0x07 }, /* set image parameters */
{ 0x90, 0x00 }, /* carrier offset null */
{ 0x91, 0x1c }, /* set A/D reference high */
{ 0x92, 0x08 }, /* set A/D reference low */
{ 0x93, 0x00 }, /* set start row to 0 */
{ 0x94, 0x07 }, /* set end row */
{ 0x95, 0x00 }, /* set start column to 0 */
{ 0x96, 0x1f }, /* set end column */
{ 0x97, 0x04 }, /* data format and thresholds */
{ 0x98, 0x28 }, /* image data control */
{ 0x99, 0x00 }, /* disable general purpose outputs */
{ 0x9a, 0x0b }, /* set initial scan state */
{ 0x9b, 0x00 }, /* clear challenge word bits */
{ 0x9c, 0x00 }, /* clear challenge word bits */
{ 0x9d, 0x09 }, /* set some challenge word bits */
{ 0x9e, 0x53 }, /* clear challenge word bits */
{ 0x9f, 0x6b }, /* set some challenge word bits */
{ 0, 0 },
{ 0x80, 0x00 },
{ 0x81, 0x00 },
{ 0, 0 },
{ 0x81, 0x04 },
{ 0, 0 },
{ 0x81, 0x00 },
};
static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
{
int r;
struct aes3k_dev *aesdev;
r = libusb_claim_interface(dev->udev, 0);
if (r < 0)
fp_err("could not claim interface 0");
aesdev = dev->priv = g_malloc0(sizeof(struct aes3k_dev));
if (!aesdev)
return -ENOMEM;
if (r == 0)
aesdev->data_buflen = DATA_BUFLEN;
aesdev->frame_width = FRAME_WIDTH;
aesdev->frame_size = FRAME_SIZE;
aesdev->frame_number = FRAME_NUMBER;
aesdev->enlarge_factor = ENLARGE_FACTOR;
aesdev->init_reqs = init_reqs;
aesdev->init_reqs_len = G_N_ELEMENTS(init_reqs);
fpi_imgdev_open_complete(dev, 0);
return r;
}
static void dev_deinit(struct fp_img_dev *dev)
{
struct aes3k_dev *aesdev = dev->priv;
g_free(aesdev);
libusb_release_interface(dev->udev, 0);
fpi_imgdev_close_complete(dev);
}
static const struct usb_id id_table[] = {
{ .vendor = 0x08ff, .product = 0x5731 },
{ 0, 0, 0, },
};
struct fp_img_driver aes3500_driver = {
.driver = {
.id = AES3500_ID,
.name = FP_COMPONENT,
.full_name = "AuthenTec AES3500",
.id_table = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
.flags = 0,
.img_height = FRAME_WIDTH * ENLARGE_FACTOR,
.img_width = FRAME_WIDTH * ENLARGE_FACTOR,
/* temporarily lowered until image quality improves */
.bz3_threshold = 9,
.open = dev_init,
.close = dev_deinit,
.activate = aes3k_dev_activate,
.deactivate = aes3k_dev_deactivate,
};

View file

@ -36,6 +36,7 @@ enum {
UPEKE2_ID = 13, UPEKE2_ID = 13,
AES1660_ID = 14, AES1660_ID = 14,
AES2660_ID = 15, AES2660_ID = 15,
AES3500_ID = 16,
}; };
#endif #endif

View file

@ -267,6 +267,9 @@ extern struct fp_img_driver aes2550_driver;
#ifdef ENABLE_AES2660 #ifdef ENABLE_AES2660
extern struct fp_img_driver aes2660_driver; extern struct fp_img_driver aes2660_driver;
#endif #endif
#ifdef ENABLE_AES3500
extern struct fp_img_driver aes3500_driver;
#endif
#ifdef ENABLE_AES4000 #ifdef ENABLE_AES4000
extern struct fp_img_driver aes4000_driver; extern struct fp_img_driver aes4000_driver;
#endif #endif