1 /*
2 * AuthenTec AES3500 driver for libfprint
3 *
4 * AES3500 is a press-typed sensor, which captures image in 128x128
5 * pixels.
6 *
7 * Thanks Rafael Toledo for the Windows driver and the help.
8 *
9 * This work is derived from Daniel Drake's AES4000 driver.
10 *
11 * Copyright (C) 2011-2013 Juvenn Woo <machese@gmail.com>
12 * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
13 *
14 * This library is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as
16 * published by the Free Software Foundation; either version 2.1 of the
17 * License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 */
29
30 #define FP_COMPONENT "aes3500"
31
32 #include <errno.h>
33
34 #include <glib.h>
35 #include <libusb.h>
36
37 #include <aeslib.h>
38 #include <fp_internal.h>
39
40 #include "aes3k.h"
41 #include "driver_ids.h"
42
43 #define DATA_BUFLEN 0x2089
44
45 /* image size = FRAME_WIDTH x FRAME_WIDTH */
46 #define FRAME_WIDTH 128
47 #define FRAME_SIZE (FRAME_WIDTH * AES3K_FRAME_HEIGHT / 2)
48 #define FRAME_NUMBER (FRAME_WIDTH / AES3K_FRAME_HEIGHT)
49 #define ENLARGE_FACTOR 2
50
51
52 static struct aes_regwrite init_reqs[] = {
53 /* master reset */
54 { 0x80, 0x01 },
55 { 0, 0 },
56 { 0x80, 0x00 },
57 { 0, 0 },
58
59 { 0x81, 0x00 },
60 { 0x80, 0x00 },
61 { 0, 0 },
62
63 /* scan reset */
64 { 0x80, 0x02 },
65 { 0, 0 },
66 { 0x80, 0x00 },
67 { 0, 0 },
68
69 /* disable register buffering */
70 { 0x80, 0x04 },
71 { 0, 0 },
72 { 0x80, 0x00 },
73 { 0, 0 },
74
75 { 0x81, 0x00 },
76 { 0, 0 },
77 /* windows driver reads registers now (81 02) */
78 { 0x80, 0x00 },
79 { 0x81, 0x00 },
80
81 /* set excitation bias current: 2mhz drive ring frequency,
82 * 4V drive ring voltage, 16.5mA excitation bias */
83 { 0x82, 0x04 },
84
85 /* continuously sample drive ring for finger detection,
86 * 62.50ms debounce delay */
87 { 0x83, 0x13 },
88
89 { 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */
90 { 0x85, 0x3d }, /* set calibration capacitance */
91 { 0x86, 0x03 }, /* detect drive voltage */
92 { 0x87, 0x01 }, /* set detection frequency to 125khz */
93 { 0x88, 0x02 }, /* set column scan period */
94 { 0x89, 0x02 }, /* set measure drive */
95 { 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */
96 { 0x8b, 0x33 }, /* set matrix pattern */
97 { 0x8c, 0x0f }, /* set demodulation phase 1 */
98 { 0x8d, 0x04 }, /* set demodulation phase 2 */
99 { 0x8e, 0x23 }, /* set sensor gain */
100 { 0x8f, 0x07 }, /* set image parameters */
101 { 0x90, 0x00 }, /* carrier offset null */
102 { 0x91, 0x1c }, /* set A/D reference high */
103 { 0x92, 0x08 }, /* set A/D reference low */
104 { 0x93, 0x00 }, /* set start row to 0 */
105 { 0x94, 0x07 }, /* set end row */
106 { 0x95, 0x00 }, /* set start column to 0 */
107 { 0x96, 0x1f }, /* set end column */
108 { 0x97, 0x04 }, /* data format and thresholds */
109 { 0x98, 0x28 }, /* image data control */
110 { 0x99, 0x00 }, /* disable general purpose outputs */
111 { 0x9a, 0x0b }, /* set initial scan state */
112 { 0x9b, 0x00 }, /* clear challenge word bits */
113 { 0x9c, 0x00 }, /* clear challenge word bits */
114 { 0x9d, 0x09 }, /* set some challenge word bits */
115 { 0x9e, 0x53 }, /* clear challenge word bits */
116 { 0x9f, 0x6b }, /* set some challenge word bits */
117 { 0, 0 },
118
119 { 0x80, 0x00 },
120 { 0x81, 0x00 },
121 { 0, 0 },
122 { 0x81, 0x04 },
123 { 0, 0 },
124 { 0x81, 0x00 },
125 };
126
dev_init(struct fp_img_dev * dev,unsigned long driver_data)127 static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
128 {
129 int r;
130 struct aes3k_dev *aesdev;
131
132 r = libusb_claim_interface(dev->udev, 0);
133 if (r < 0) {
134 fp_err("could not claim interface 0: %s", libusb_error_name(r));
135 return r;
136 }
137
138 aesdev = dev->priv = g_malloc0(sizeof(struct aes3k_dev));
139
140 if (!aesdev)
141 return -ENOMEM;
142
143 aesdev->data_buflen = DATA_BUFLEN;
144 aesdev->frame_width = FRAME_WIDTH;
145 aesdev->frame_size = FRAME_SIZE;
146 aesdev->frame_number = FRAME_NUMBER;
147 aesdev->enlarge_factor = ENLARGE_FACTOR;
148 aesdev->init_reqs = init_reqs;
149 aesdev->init_reqs_len = G_N_ELEMENTS(init_reqs);
150 fpi_imgdev_open_complete(dev, 0);
151
152 return r;
153 }
154
dev_deinit(struct fp_img_dev * dev)155 static void dev_deinit(struct fp_img_dev *dev)
156 {
157 struct aes3k_dev *aesdev = dev->priv;
158 g_free(aesdev);
159 libusb_release_interface(dev->udev, 0);
160 fpi_imgdev_close_complete(dev);
161 }
162
163
164 static const struct usb_id id_table[] = {
165 { .vendor = 0x08ff, .product = 0x5731 },
166 { 0, 0, 0, },
167 };
168
169 struct fp_img_driver aes3500_driver = {
170 .driver = {
171 .id = AES3500_ID,
172 .name = FP_COMPONENT,
173 .full_name = "AuthenTec AES3500",
174 .id_table = id_table,
175 .scan_type = FP_SCAN_TYPE_PRESS,
176 },
177 .flags = 0,
178 .img_height = FRAME_WIDTH * ENLARGE_FACTOR,
179 .img_width = FRAME_WIDTH * ENLARGE_FACTOR,
180
181 /* temporarily lowered until image quality improves */
182 .bz3_threshold = 9,
183
184 .open = dev_init,
185 .close = dev_deinit,
186 .activate = aes3k_dev_activate,
187 .deactivate = aes3k_dev_deactivate,
188 };
189
190