Introduce shared functions for authentec drivers
Currently provides register writing functionality only, more common ground will be moved here soon.
This commit is contained in:
parent
8e0e8e4386
commit
e228f2c7da
6 changed files with 183 additions and 189 deletions
|
@ -56,6 +56,8 @@ libfprint_la_SOURCES = \
|
||||||
data.c \
|
data.c \
|
||||||
img.c \
|
img.c \
|
||||||
imgdev.c \
|
imgdev.c \
|
||||||
|
aeslib.c \
|
||||||
|
aeslib.h \
|
||||||
$(DRIVER_SRC) \
|
$(DRIVER_SRC) \
|
||||||
$(NBIS_SRC)
|
$(NBIS_SRC)
|
||||||
|
|
||||||
|
|
95
libfprint/aeslib.c
Normal file
95
libfprint/aeslib.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Shared functions between libfprint Authentec drivers
|
||||||
|
* Copyright (C) 2007 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 "aeslib"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "fp_internal.h"
|
||||||
|
#include "aeslib.h"
|
||||||
|
|
||||||
|
#define MAX_REGWRITES_PER_REQUEST 16
|
||||||
|
|
||||||
|
#define BULK_TIMEOUT 4000
|
||||||
|
#define EP_IN (1 | USB_ENDPOINT_IN)
|
||||||
|
#define EP_OUT (2 | USB_ENDPOINT_OUT)
|
||||||
|
|
||||||
|
static int do_write_regv(struct fp_img_dev *dev, struct aes_regwrite *regs,
|
||||||
|
unsigned int num)
|
||||||
|
{
|
||||||
|
size_t alloc_size = num * 2;
|
||||||
|
unsigned char *data = g_malloc(alloc_size);
|
||||||
|
unsigned int i;
|
||||||
|
size_t offset = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
data[offset++] = regs[i].reg;
|
||||||
|
data[offset++] = regs[i].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = usb_bulk_write(dev->udev, EP_OUT, data, alloc_size, BULK_TIMEOUT);
|
||||||
|
g_free(data);
|
||||||
|
if (r < 0) {
|
||||||
|
fp_err("bulk write error %d", r);
|
||||||
|
return r;
|
||||||
|
} else if ((unsigned int) r < alloc_size) {
|
||||||
|
fp_err("unexpected short write %d/%d", r, alloc_size);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aes_write_regv(struct fp_img_dev *dev, struct aes_regwrite *regs,
|
||||||
|
unsigned int num)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
int skip = 0;
|
||||||
|
int add_offset = 0;
|
||||||
|
fp_dbg("write %d regs", num);
|
||||||
|
|
||||||
|
for (i = 0; i < num; i += add_offset + skip) {
|
||||||
|
int r, j;
|
||||||
|
int limit = MIN(num, i + MAX_REGWRITES_PER_REQUEST);
|
||||||
|
skip = 0;
|
||||||
|
|
||||||
|
if (!regs[i].reg) {
|
||||||
|
add_offset = 0;
|
||||||
|
skip = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = i; j < limit; j++)
|
||||||
|
if (!regs[j].reg) {
|
||||||
|
skip = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_offset = j - i;
|
||||||
|
r = do_write_regv(dev, ®s[i], add_offset);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
34
libfprint/aeslib.h
Normal file
34
libfprint/aeslib.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Shared functions between libfprint Authentec drivers
|
||||||
|
* Copyright (C) 2007 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __AESLIB_H__
|
||||||
|
#define __AESLIB_H__
|
||||||
|
|
||||||
|
#include <fp_internal.h>
|
||||||
|
|
||||||
|
struct aes_regwrite {
|
||||||
|
unsigned char reg;
|
||||||
|
unsigned char value;
|
||||||
|
};
|
||||||
|
|
||||||
|
int aes_write_regv(struct fp_img_dev *dev, struct aes_regwrite *regs,
|
||||||
|
unsigned int num);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
|
|
||||||
|
#include <aeslib.h>
|
||||||
#include <fp_internal.h>
|
#include <fp_internal.h>
|
||||||
|
|
||||||
/* FIXME these need checking */
|
/* FIXME these need checking */
|
||||||
|
@ -36,7 +37,6 @@
|
||||||
#define EP_OUT (2 | USB_ENDPOINT_OUT)
|
#define EP_OUT (2 | USB_ENDPOINT_OUT)
|
||||||
|
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
#define MAX_REGWRITES_PER_REQUEST 16
|
|
||||||
|
|
||||||
#define FIRST_AES1610_REG 0x1B
|
#define FIRST_AES1610_REG 0x1B
|
||||||
#define LAST_AES1610_REG 0xFF
|
#define LAST_AES1610_REG 0xFF
|
||||||
|
@ -60,66 +60,6 @@
|
||||||
/* FIXME reduce substantially */
|
/* FIXME reduce substantially */
|
||||||
#define MAX_FRAMES 350
|
#define MAX_FRAMES 350
|
||||||
|
|
||||||
struct aes1610_regwrite {
|
|
||||||
unsigned char reg;
|
|
||||||
unsigned char value;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int do_write_regv(struct fp_img_dev *dev, const struct aes1610_regwrite *regs,
|
|
||||||
unsigned int num)
|
|
||||||
{
|
|
||||||
size_t alloc_size = num * 2;
|
|
||||||
unsigned char *data = g_malloc(alloc_size);
|
|
||||||
unsigned int i;
|
|
||||||
size_t offset = 0;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
|
||||||
data[offset++] = regs[i].reg;
|
|
||||||
data[offset++] = regs[i].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = usb_bulk_write(dev->udev, EP_OUT, data, alloc_size, BULK_TIMEOUT);
|
|
||||||
g_free(data);
|
|
||||||
if (r < 0) {
|
|
||||||
fp_err("bulk write error %d", r);
|
|
||||||
return r;
|
|
||||||
} else if (r < (int) alloc_size) {
|
|
||||||
fp_err("unexpected short write %d/%d", r, alloc_size);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int write_regv(struct fp_img_dev *dev, const struct aes1610_regwrite *regs,
|
|
||||||
unsigned int num)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
int skip = 0;
|
|
||||||
int add_offset = 0;
|
|
||||||
fp_dbg("write %d regs", num);
|
|
||||||
|
|
||||||
for (i = 0; i < num; i += add_offset + skip) {
|
|
||||||
int r, j;
|
|
||||||
int limit = MIN(num, i + MAX_REGWRITES_PER_REQUEST);
|
|
||||||
skip = 0;
|
|
||||||
|
|
||||||
for (j = i; j < limit; j++)
|
|
||||||
if (!regs[j].reg) {
|
|
||||||
skip = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_offset = j - i;
|
|
||||||
r = do_write_regv(dev, ®s[i], add_offset);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int read_data(struct fp_img_dev *dev, unsigned char *data, size_t len)
|
static int read_data(struct fp_img_dev *dev, unsigned char *data, size_t len)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
@ -136,19 +76,14 @@ static int read_data(struct fp_img_dev *dev, unsigned char *data, size_t len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct aes1610_regwrite init[] = {
|
static const struct aes_regwrite init[] = {
|
||||||
{ 0x82, 0x00 }
|
{ 0x82, 0x00 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes1610_regwrite stop_reader[] = {
|
static const struct aes_regwrite stop_reader[] = {
|
||||||
{ 0xFF, 0x00 }
|
{ 0xFF, 0x00 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int do_init(struct fp_img_dev *dev)
|
|
||||||
{
|
|
||||||
return write_regv(dev, init, G_N_ELEMENTS(init));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
@ -161,12 +96,12 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
||||||
|
|
||||||
/* FIXME check endpoints */
|
/* FIXME check endpoints */
|
||||||
|
|
||||||
return do_init(dev);
|
return aes_write_regv(dev, init, G_N_ELEMENTS(init));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_exit(struct fp_img_dev *dev)
|
static int do_exit(struct fp_img_dev *dev)
|
||||||
{
|
{
|
||||||
return write_regv(dev, stop_reader, G_N_ELEMENTS(stop_reader));
|
return aes_write_regv(dev, stop_reader, G_N_ELEMENTS(stop_reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_exit(struct fp_img_dev *dev)
|
static void dev_exit(struct fp_img_dev *dev)
|
||||||
|
@ -175,7 +110,7 @@ static void dev_exit(struct fp_img_dev *dev)
|
||||||
usb_release_interface(dev->udev, 0);
|
usb_release_interface(dev->udev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct aes1610_regwrite finger_det_reqs[] = {
|
static const struct aes_regwrite finger_det_reqs[] = {
|
||||||
{ 0x80, 0x01 },
|
{ 0x80, 0x01 },
|
||||||
{ 0x80, 0x12 },
|
{ 0x80, 0x12 },
|
||||||
{ 0x85, 0x00 },
|
{ 0x85, 0x00 },
|
||||||
|
@ -200,7 +135,7 @@ static const struct aes1610_regwrite finger_det_reqs[] = {
|
||||||
{ 0x81, 0x04 }
|
{ 0x81, 0x04 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes1610_regwrite finger_det_none[] = {
|
static const struct aes_regwrite finger_det_none[] = {
|
||||||
{ 0x80, 0x01 },
|
{ 0x80, 0x01 },
|
||||||
{ 0x82, 0x00 },
|
{ 0x82, 0x00 },
|
||||||
{ 0x86, 0x00 },
|
{ 0x86, 0x00 },
|
||||||
|
@ -215,7 +150,7 @@ static int detect_finger(struct fp_img_dev *dev)
|
||||||
int i;
|
int i;
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
r = write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs));
|
r = aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -228,7 +163,7 @@ static int detect_finger(struct fp_img_dev *dev)
|
||||||
|
|
||||||
/* We need to answer something if no finger has been detected */
|
/* We need to answer something if no finger has been detected */
|
||||||
if (sum <= 20) {
|
if (sum <= 20) {
|
||||||
r = write_regv(dev, finger_det_none, G_N_ELEMENTS(finger_det_none));
|
r = aes_write_regv(dev, finger_det_none, G_N_ELEMENTS(finger_det_none));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -327,7 +262,7 @@ static unsigned int assemble(unsigned char *input, unsigned char *output,
|
||||||
return image_height;
|
return image_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct aes1610_regwrite capture_reqs[] = {
|
static const struct aes_regwrite capture_reqs[] = {
|
||||||
{ 0x80, 0x01 },
|
{ 0x80, 0x01 },
|
||||||
{ 0x80, 0x12 },
|
{ 0x80, 0x12 },
|
||||||
{ 0x84, 0x01 },
|
{ 0x84, 0x01 },
|
||||||
|
@ -453,7 +388,7 @@ static const struct aes1610_regwrite capture_reqs[] = {
|
||||||
{ 0x81, 0x01 }
|
{ 0x81, 0x01 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes1610_regwrite strip_scan_reqs[] = {
|
static const struct aes_regwrite strip_scan_reqs[] = {
|
||||||
{ 0xBE, 0x23 },
|
{ 0xBE, 0x23 },
|
||||||
{ 0x29, 0x06 },
|
{ 0x29, 0x06 },
|
||||||
{ 0x2A, 0x35 },
|
{ 0x2A, 0x35 },
|
||||||
|
@ -461,7 +396,7 @@ static const struct aes1610_regwrite strip_scan_reqs[] = {
|
||||||
{ 0xFF, 0x00 }
|
{ 0xFF, 0x00 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes1610_regwrite capture_stop[] = {
|
static const struct aes_regwrite capture_stop[] = {
|
||||||
{ 0x81,0x00 }
|
{ 0x81,0x00 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -482,7 +417,7 @@ static int capture(struct fp_img_dev *dev, gboolean unconditional,
|
||||||
/* FIXME can do better here in terms of buffer management? */
|
/* FIXME can do better here in terms of buffer management? */
|
||||||
fp_dbg("");
|
fp_dbg("");
|
||||||
|
|
||||||
r = write_regv(dev, capture_reqs, G_N_ELEMENTS(capture_reqs));
|
r = aes_write_regv(dev, capture_reqs, G_N_ELEMENTS(capture_reqs));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -507,7 +442,7 @@ static int capture(struct fp_img_dev *dev, gboolean unconditional,
|
||||||
/* we start at 2 because we captured 2 frames above. the above captures
|
/* we start at 2 because we captured 2 frames above. the above captures
|
||||||
* should possibly be moved into the loop below, or discarded altogether */
|
* should possibly be moved into the loop below, or discarded altogether */
|
||||||
for (nstrips = 2; nstrips < MAX_FRAMES - 2; nstrips++) {
|
for (nstrips = 2; nstrips < MAX_FRAMES - 2; nstrips++) {
|
||||||
r = write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs));
|
r = aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err;
|
goto err;
|
||||||
r = read_data(dev, buf, 665);
|
r = read_data(dev, buf, 665);
|
||||||
|
@ -544,7 +479,7 @@ static int capture(struct fp_img_dev *dev, gboolean unconditional,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop));
|
r = aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err;
|
goto err;
|
||||||
r = read_data(dev, buf, 665);
|
r = read_data(dev, buf, 665);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
|
|
||||||
|
#include <aeslib.h>
|
||||||
#include <fp_internal.h>
|
#include <fp_internal.h>
|
||||||
#include "aes2501.h"
|
#include "aes2501.h"
|
||||||
|
|
||||||
|
@ -36,7 +37,6 @@
|
||||||
#define EP_OUT (2 | USB_ENDPOINT_OUT)
|
#define EP_OUT (2 | USB_ENDPOINT_OUT)
|
||||||
|
|
||||||
#define BULK_TIMEOUT 4000
|
#define BULK_TIMEOUT 4000
|
||||||
#define MAX_REGWRITES_PER_REQUEST 16
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The AES2501 is an imaging device using a swipe-type sensor. It samples
|
* The AES2501 is an imaging device using a swipe-type sensor. It samples
|
||||||
|
@ -57,66 +57,6 @@
|
||||||
/* FIXME reduce substantially */
|
/* FIXME reduce substantially */
|
||||||
#define MAX_FRAMES 150
|
#define MAX_FRAMES 150
|
||||||
|
|
||||||
struct aes2501_regwrite {
|
|
||||||
unsigned char reg;
|
|
||||||
unsigned char value;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int do_write_regv(struct fp_img_dev *dev, struct aes2501_regwrite *regs,
|
|
||||||
unsigned int num)
|
|
||||||
{
|
|
||||||
size_t alloc_size = num * 2;
|
|
||||||
unsigned char *data = g_malloc(alloc_size);
|
|
||||||
unsigned int i;
|
|
||||||
size_t offset = 0;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
|
||||||
data[offset++] = regs[i].reg;
|
|
||||||
data[offset++] = regs[i].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = usb_bulk_write(dev->udev, EP_OUT, data, alloc_size, BULK_TIMEOUT);
|
|
||||||
g_free(data);
|
|
||||||
if (r < 0) {
|
|
||||||
fp_err("bulk write error %d", r);
|
|
||||||
return r;
|
|
||||||
} else if (r < alloc_size) {
|
|
||||||
fp_err("unexpected short write %d/%d", r, alloc_size);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int write_regv(struct fp_img_dev *dev, struct aes2501_regwrite *regs,
|
|
||||||
unsigned int num)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
int skip = 0;
|
|
||||||
int add_offset = 0;
|
|
||||||
fp_dbg("write %d regs", num);
|
|
||||||
|
|
||||||
for (i = 0; i < num; i += add_offset + skip) {
|
|
||||||
int r, j;
|
|
||||||
int limit = MIN(num, i + MAX_REGWRITES_PER_REQUEST);
|
|
||||||
skip = 0;
|
|
||||||
|
|
||||||
for (j = i; j < limit; j++)
|
|
||||||
if (!regs[j].reg) {
|
|
||||||
skip = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_offset = j - i;
|
|
||||||
r = do_write_regv(dev, ®s[i], add_offset);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int read_data(struct fp_img_dev *dev, unsigned char *data, size_t len)
|
static int read_data(struct fp_img_dev *dev, unsigned char *data, size_t len)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
@ -136,20 +76,20 @@ static int read_data(struct fp_img_dev *dev, unsigned char *data, size_t len)
|
||||||
static int read_regs(struct fp_img_dev *dev, unsigned char *data)
|
static int read_regs(struct fp_img_dev *dev, unsigned char *data)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
const struct aes2501_regwrite regwrite = {
|
const struct aes_regwrite regwrite = {
|
||||||
AES2501_REG_CTRL2, AES2501_CTRL2_READ_REGS
|
AES2501_REG_CTRL2, AES2501_CTRL2_READ_REGS
|
||||||
};
|
};
|
||||||
|
|
||||||
fp_dbg("");
|
fp_dbg("");
|
||||||
|
|
||||||
r = write_regv(dev, ®write, 1);
|
r = aes_write_regv(dev, ®write, 1);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return read_data(dev, data, 126);
|
return read_data(dev, data, 126);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct aes2501_regwrite init_1[] = {
|
static const struct aes_regwrite init_1[] = {
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0xb0, 0x27 }, /* Reserved? */
|
{ 0xb0, 0x27 }, /* Reserved? */
|
||||||
|
@ -193,7 +133,7 @@ static const struct aes2501_regwrite init_1[] = {
|
||||||
{ AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
|
{ AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes2501_regwrite init_2[] = {
|
static const struct aes_regwrite init_2[] = {
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
||||||
{ AES2501_REG_EXCITCTRL, 0x40 },
|
{ AES2501_REG_EXCITCTRL, 0x40 },
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
||||||
|
@ -203,7 +143,7 @@ static const struct aes2501_regwrite init_2[] = {
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes2501_regwrite init_3[] = {
|
static const struct aes_regwrite init_3[] = {
|
||||||
{ 0xff, 0x00 },
|
{ 0xff, 0x00 },
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
||||||
{ AES2501_REG_AUTOCALOFFSET, 0x41 },
|
{ AES2501_REG_AUTOCALOFFSET, 0x41 },
|
||||||
|
@ -212,7 +152,7 @@ static const struct aes2501_regwrite init_3[] = {
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes2501_regwrite init_4[] = {
|
static const struct aes_regwrite init_4[] = {
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
||||||
{ AES2501_REG_EXCITCTRL, 0x40 },
|
{ AES2501_REG_EXCITCTRL, 0x40 },
|
||||||
{ 0xb0, 0x27 },
|
{ 0xb0, 0x27 },
|
||||||
|
@ -222,7 +162,7 @@ static const struct aes2501_regwrite init_4[] = {
|
||||||
{ AES2501_REG_AUTOCALOFFSET, 0x41 },
|
{ AES2501_REG_AUTOCALOFFSET, 0x41 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes2501_regwrite init_5[] = {
|
static const struct aes_regwrite init_5[] = {
|
||||||
{ 0xb0, 0x27 },
|
{ 0xb0, 0x27 },
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
||||||
{ AES2501_REG_EXCITCTRL, 0x40 },
|
{ AES2501_REG_EXCITCTRL, 0x40 },
|
||||||
|
@ -248,7 +188,7 @@ static int do_init(struct fp_img_dev *dev)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* part 1, probably not needed */
|
/* part 1, probably not needed */
|
||||||
r = write_regv(dev, init_1, G_N_ELEMENTS(init_1));
|
r = aes_write_regv(dev, init_1, G_N_ELEMENTS(init_1));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -257,7 +197,7 @@ static int do_init(struct fp_img_dev *dev)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* part 2 */
|
/* part 2 */
|
||||||
r = write_regv(dev, init_2, G_N_ELEMENTS(init_2));
|
r = aes_write_regv(dev, init_2, G_N_ELEMENTS(init_2));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -269,7 +209,7 @@ static int do_init(struct fp_img_dev *dev)
|
||||||
fp_dbg("reg 0xaf = %x", buffer[0x5f]);
|
fp_dbg("reg 0xaf = %x", buffer[0x5f]);
|
||||||
i = 0;
|
i = 0;
|
||||||
while (buffer[0x5f] == 0x6b) {
|
while (buffer[0x5f] == 0x6b) {
|
||||||
r = write_regv(dev, init_3, G_N_ELEMENTS(init_3));
|
r = aes_write_regv(dev, init_3, G_N_ELEMENTS(init_3));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
r = read_regs(dev, buffer);
|
r = read_regs(dev, buffer);
|
||||||
|
@ -280,12 +220,12 @@ static int do_init(struct fp_img_dev *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* part 4 */
|
/* part 4 */
|
||||||
r = write_regv(dev, init_4, G_N_ELEMENTS(init_4));
|
r = aes_write_regv(dev, init_4, G_N_ELEMENTS(init_4));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* part 5 */
|
/* part 5 */
|
||||||
return write_regv(dev, init_5, G_N_ELEMENTS(init_5));
|
return aes_write_regv(dev, init_5, G_N_ELEMENTS(init_5));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
||||||
|
@ -308,7 +248,7 @@ static void dev_exit(struct fp_img_dev *dev)
|
||||||
usb_release_interface(dev->udev, 0);
|
usb_release_interface(dev->udev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct aes2501_regwrite finger_det_reqs[] = {
|
static const struct aes_regwrite finger_det_reqs[] = {
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
||||||
{ AES2501_REG_EXCITCTRL, 0x40 },
|
{ AES2501_REG_EXCITCTRL, 0x40 },
|
||||||
{ AES2501_REG_DETCTRL,
|
{ AES2501_REG_DETCTRL,
|
||||||
|
@ -343,7 +283,7 @@ static int detect_finger(struct fp_img_dev *dev)
|
||||||
int i;
|
int i;
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
r = write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs));
|
r = aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -485,7 +425,7 @@ static unsigned int assemble(unsigned char *input, unsigned char *output,
|
||||||
return image_height;
|
return image_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct aes2501_regwrite capture_reqs_1[] = {
|
static const struct aes_regwrite capture_reqs_1[] = {
|
||||||
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
{ AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ AES2501_REG_EXCITCTRL, 0x40 },
|
{ AES2501_REG_EXCITCTRL, 0x40 },
|
||||||
|
@ -519,7 +459,7 @@ static const struct aes2501_regwrite capture_reqs_1[] = {
|
||||||
{ AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
|
{ AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes2501_regwrite capture_reqs_2[] = {
|
static const struct aes_regwrite capture_reqs_2[] = {
|
||||||
{ AES2501_REG_IMAGCTRL,
|
{ AES2501_REG_IMAGCTRL,
|
||||||
AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE |
|
AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE |
|
||||||
AES2501_IMAGCTRL_IMG_DATA_DISABLE },
|
AES2501_IMAGCTRL_IMG_DATA_DISABLE },
|
||||||
|
@ -531,7 +471,7 @@ static const struct aes2501_regwrite capture_reqs_2[] = {
|
||||||
{ AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
|
{ AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aes2501_regwrite strip_scan_reqs[] = {
|
static const struct aes_regwrite strip_scan_reqs[] = {
|
||||||
{ AES2501_REG_IMAGCTRL,
|
{ AES2501_REG_IMAGCTRL,
|
||||||
AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE },
|
AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE },
|
||||||
{ AES2501_REG_STRTCOL, 0x00 },
|
{ AES2501_REG_STRTCOL, 0x00 },
|
||||||
|
@ -558,7 +498,7 @@ static int capture(struct fp_img_dev *dev, gboolean unconditional,
|
||||||
/* FIXME can do better here in terms of buffer management? */
|
/* FIXME can do better here in terms of buffer management? */
|
||||||
fp_dbg("");
|
fp_dbg("");
|
||||||
|
|
||||||
r = write_regv(dev, capture_reqs_1, G_N_ELEMENTS(capture_reqs_1));
|
r = aes_write_regv(dev, capture_reqs_1, G_N_ELEMENTS(capture_reqs_1));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -566,7 +506,7 @@ static int capture(struct fp_img_dev *dev, gboolean unconditional,
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = write_regv(dev, capture_reqs_2, G_N_ELEMENTS(capture_reqs_2));
|
r = aes_write_regv(dev, capture_reqs_2, G_N_ELEMENTS(capture_reqs_2));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -583,7 +523,7 @@ static int capture(struct fp_img_dev *dev, gboolean unconditional,
|
||||||
for (nstrips = 0; nstrips < MAX_FRAMES; nstrips++) {
|
for (nstrips = 0; nstrips < MAX_FRAMES; nstrips++) {
|
||||||
int threshold;
|
int threshold;
|
||||||
|
|
||||||
r = write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs));
|
r = aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err;
|
goto err;
|
||||||
r = read_data(dev, buf, 1705);
|
r = read_data(dev, buf, 1705);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
|
|
||||||
|
#include <aeslib.h>
|
||||||
#include <fp_internal.h>
|
#include <fp_internal.h>
|
||||||
|
|
||||||
#define CTRL_TIMEOUT 1000
|
#define CTRL_TIMEOUT 1000
|
||||||
|
@ -33,25 +34,6 @@
|
||||||
#define NR_SUBARRAYS 6
|
#define NR_SUBARRAYS 6
|
||||||
#define SUBARRAY_LEN 768
|
#define SUBARRAY_LEN 768
|
||||||
|
|
||||||
static int write_reg(struct fp_img_dev *dev, unsigned char reg,
|
|
||||||
unsigned char value)
|
|
||||||
{
|
|
||||||
unsigned char data[] = { reg, value };
|
|
||||||
int r;
|
|
||||||
|
|
||||||
fp_dbg("%02x=%02x", reg, value);
|
|
||||||
r = usb_bulk_write(dev->udev, EP_OUT, data, sizeof(data), CTRL_TIMEOUT);
|
|
||||||
if (r < 0) {
|
|
||||||
fp_err("bulk write error %d", r);
|
|
||||||
return r;
|
|
||||||
} else if (r < sizeof(data)) {
|
|
||||||
fp_err("unexpected short write %d/%d", r, sizeof(data));
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void process_subarray(unsigned char *src, unsigned char *dst)
|
static void process_subarray(unsigned char *src, unsigned char *dst)
|
||||||
{
|
{
|
||||||
int col, row;
|
int col, row;
|
||||||
|
@ -66,26 +48,31 @@ static void process_subarray(unsigned char *src, unsigned char *dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct aes4000_regwrite {
|
static const struct aes_regwrite init_reqs[] = {
|
||||||
unsigned char reg;
|
|
||||||
unsigned char value;
|
|
||||||
} init_reqs[] = {
|
|
||||||
/* master reset */
|
/* master reset */
|
||||||
{ 0x80, 0x01 },
|
{ 0x80, 0x01 },
|
||||||
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
|
{ 0, 0 },
|
||||||
|
|
||||||
/* scan reset */
|
/* scan reset */
|
||||||
{ 0x80, 0x02 },
|
{ 0x80, 0x02 },
|
||||||
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
|
{ 0, 0 },
|
||||||
|
|
||||||
/* disable register buffering */
|
/* disable register buffering */
|
||||||
{ 0x80, 0x04 },
|
{ 0x80, 0x04 },
|
||||||
|
{ 0, 0 },
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
|
{ 0, 0 },
|
||||||
/* windows driver reads registers now (81 02) */
|
/* windows driver reads registers now (81 02) */
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
|
@ -126,10 +113,13 @@ static const struct aes4000_regwrite {
|
||||||
{ 0x9d, 0x09 }, /* set some challenge word bits */
|
{ 0x9d, 0x09 }, /* set some challenge word bits */
|
||||||
{ 0x9e, 0x53 }, /* clear challenge word bits */
|
{ 0x9e, 0x53 }, /* clear challenge word bits */
|
||||||
{ 0x9f, 0x6b }, /* set some challenge word bits */
|
{ 0x9f, 0x6b }, /* set some challenge word bits */
|
||||||
|
{ 0, 0 },
|
||||||
|
|
||||||
{ 0x80, 0x00 },
|
{ 0x80, 0x00 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
|
{ 0, 0 },
|
||||||
{ 0x81, 0x04 },
|
{ 0x81, 0x04 },
|
||||||
|
{ 0, 0 },
|
||||||
{ 0x81, 0x00 },
|
{ 0x81, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -142,11 +132,9 @@ static int capture(struct fp_img_dev *dev, gboolean unconditional,
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS(init_reqs); i++) {
|
r = aes_write_regv(dev, init_reqs, G_N_ELEMENTS(init_reqs));
|
||||||
r = write_reg(dev, init_reqs[i].reg, init_reqs[i].value);
|
if (r < 0)
|
||||||
if (r < 0)
|
return r;
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
img = fpi_img_new_for_imgdev(dev);
|
img = fpi_img_new_for_imgdev(dev);
|
||||||
data = g_malloc(DATA_BUFLEN);
|
data = g_malloc(DATA_BUFLEN);
|
||||||
|
|
Loading…
Reference in a new issue