1 /*
2 * AuthenTec AES2501 driver for libfprint
3 * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
4 * Copyright (C) 2007 Cyrille Bagard
5 * Copyright (C) 2007-2008, 2012 Vasily Khoruzhick <anarsoul@gmail.com>
6 *
7 * Based on code from http://home.gna.org/aes2501, relicensed with permission
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #define FP_COMPONENT "aes2501"
25
26 #include <errno.h>
27 #include <string.h>
28
29 #include <libusb.h>
30
31 #include <assembling.h>
32 #include <aeslib.h>
33 #include <fp_internal.h>
34
35 #include "aes2501.h"
36 #include "driver_ids.h"
37
38 static void start_capture(struct fp_img_dev *dev);
39 static void complete_deactivation(struct fp_img_dev *dev);
40
41 /* FIXME these need checking */
42 #define EP_IN (1 | LIBUSB_ENDPOINT_IN)
43 #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
44
45 #define BULK_TIMEOUT 4000
46
47 /*
48 * The AES2501 is an imaging device using a swipe-type sensor. It samples
49 * the finger at preprogrammed intervals, sending a 192x16 frame to the
50 * computer.
51 * Unless the user is scanning their finger unreasonably fast, the frames
52 * *will* overlap. The implementation below detects this overlap and produces
53 * a contiguous image as the end result.
54 * The fact that the user determines the length of the swipe (and hence the
55 * number of useful frames) and also the fact that overlap varies means that
56 * images returned from this driver vary in height.
57 */
58
59 #define FRAME_WIDTH 192
60 #define FRAME_HEIGHT 16
61 #define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
62 #define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2))
63 /* maximum number of frames to read during a scan */
64 /* FIXME reduce substantially */
65 #define MAX_FRAMES 150
66
67 /****** GENERAL FUNCTIONS ******/
68
69 struct aes2501_dev {
70 uint8_t read_regs_retry_count;
71 GSList *strips;
72 size_t strips_len;
73 gboolean deactivating;
74 int no_finger_cnt;
75 };
76
77 static struct fpi_frame_asmbl_ctx assembling_ctx = {
78 .frame_width = FRAME_WIDTH,
79 .frame_height = FRAME_HEIGHT,
80 .image_width = IMAGE_WIDTH,
81 .get_pixel = aes_get_pixel,
82 };
83
84 typedef void (*aes2501_read_regs_cb)(struct fp_img_dev *dev, int status,
85 unsigned char *regs, void *user_data);
86
87 struct aes2501_read_regs {
88 struct fp_img_dev *dev;
89 aes2501_read_regs_cb callback;
90 struct aes_regwrite *regwrite;
91 void *user_data;
92 };
93
read_regs_data_cb(struct libusb_transfer * transfer)94 static void read_regs_data_cb(struct libusb_transfer *transfer)
95 {
96 struct aes2501_read_regs *rdata = transfer->user_data;
97 unsigned char *retdata = NULL;
98 int r;
99
100 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
101 r = -EIO;
102 } else if (transfer->length != transfer->actual_length) {
103 r = -EPROTO;
104 } else {
105 r = 0;
106 retdata = transfer->buffer;
107 }
108
109 rdata->callback(rdata->dev, r, retdata, rdata->user_data);
110 g_free(rdata);
111 g_free(transfer->buffer);
112 libusb_free_transfer(transfer);
113 }
114
read_regs_rq_cb(struct fp_img_dev * dev,int result,void * user_data)115 static void read_regs_rq_cb(struct fp_img_dev *dev, int result, void *user_data)
116 {
117 struct aes2501_read_regs *rdata = user_data;
118 struct libusb_transfer *transfer;
119 unsigned char *data;
120 int r;
121
122 g_free(rdata->regwrite);
123 if (result != 0)
124 goto err;
125
126 transfer = libusb_alloc_transfer(0);
127 if (!transfer) {
128 result = -ENOMEM;
129 goto err;
130 }
131
132 data = g_malloc(126);
133 libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 126,
134 read_regs_data_cb, rdata, BULK_TIMEOUT);
135
136 r = libusb_submit_transfer(transfer);
137 if (r < 0) {
138 g_free(data);
139 libusb_free_transfer(transfer);
140 result = -EIO;
141 goto err;
142 }
143
144 return;
145 err:
146 rdata->callback(dev, result, NULL, rdata->user_data);
147 g_free(rdata);
148 }
149
read_regs(struct fp_img_dev * dev,aes2501_read_regs_cb callback,void * user_data)150 static void read_regs(struct fp_img_dev *dev, aes2501_read_regs_cb callback,
151 void *user_data)
152 {
153 /* FIXME: regwrite is dynamic because of asynchronity. is this really
154 * required? */
155 struct aes_regwrite *regwrite = g_malloc(sizeof(*regwrite));
156 struct aes2501_read_regs *rdata = g_malloc(sizeof(*rdata));
157
158 fp_dbg("");
159 regwrite->reg = AES2501_REG_CTRL2;
160 regwrite->value = AES2501_CTRL2_READ_REGS;
161 rdata->dev = dev;
162 rdata->callback = callback;
163 rdata->user_data = user_data;
164 rdata->regwrite = regwrite;
165
166 aes_write_regv(dev, (const struct aes_regwrite *) regwrite, 1,
167 read_regs_rq_cb, rdata);
168 }
169
170 /* Read the value of a specific register from a register dump */
regval_from_dump(unsigned char * data,uint8_t target)171 static int regval_from_dump(unsigned char *data, uint8_t target)
172 {
173 if (*data != FIRST_AES2501_REG) {
174 fp_err("not a register dump");
175 return -EILSEQ;
176 }
177
178 if (!(FIRST_AES2501_REG <= target && target <= LAST_AES2501_REG)) {
179 fp_err("out of range");
180 return -EINVAL;
181 }
182
183 target -= FIRST_AES2501_REG;
184 target *= 2;
185 return data[target + 1];
186 }
187
generic_write_regv_cb(struct fp_img_dev * dev,int result,void * user_data)188 static void generic_write_regv_cb(struct fp_img_dev *dev, int result,
189 void *user_data)
190 {
191 struct fpi_ssm *ssm = user_data;
192 if (result == 0)
193 fpi_ssm_next_state(ssm);
194 else
195 fpi_ssm_mark_aborted(ssm, result);
196 }
197
198 /* check that read succeeded but ignore all data */
generic_ignore_data_cb(struct libusb_transfer * transfer)199 static void generic_ignore_data_cb(struct libusb_transfer *transfer)
200 {
201 struct fpi_ssm *ssm = transfer->user_data;
202
203 if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
204 fpi_ssm_mark_aborted(ssm, -EIO);
205 else if (transfer->length != transfer->actual_length)
206 fpi_ssm_mark_aborted(ssm, -EPROTO);
207 else
208 fpi_ssm_next_state(ssm);
209
210 g_free(transfer->buffer);
211 libusb_free_transfer(transfer);
212 }
213
214 /* read the specified number of bytes from the IN endpoint but throw them
215 * away, then increment the SSM */
generic_read_ignore_data(struct fpi_ssm * ssm,size_t bytes)216 static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes)
217 {
218 struct libusb_transfer *transfer = libusb_alloc_transfer(0);
219 unsigned char *data;
220 int r;
221
222 if (!transfer) {
223 fpi_ssm_mark_aborted(ssm, -ENOMEM);
224 return;
225 }
226
227 data = g_malloc(bytes);
228 libusb_fill_bulk_transfer(transfer, ssm->dev->udev, EP_IN, data, bytes,
229 generic_ignore_data_cb, ssm, BULK_TIMEOUT);
230
231 r = libusb_submit_transfer(transfer);
232 if (r < 0) {
233 g_free(data);
234 libusb_free_transfer(transfer);
235 fpi_ssm_mark_aborted(ssm, r);
236 }
237 }
238
239 /****** IMAGE PROCESSING ******/
240
sum_histogram_values(unsigned char * data,uint8_t threshold)241 static int sum_histogram_values(unsigned char *data, uint8_t threshold)
242 {
243 int r = 0;
244 int i;
245 uint16_t *histogram = (uint16_t *)(data + 1);
246
247 if (*data != 0xde)
248 return -EILSEQ;
249
250 if (threshold > 0x0f)
251 return -EINVAL;
252
253 /* FIXME endianness */
254 for (i = threshold; i < 16; i++)
255 r += histogram[i];
256
257 return r;
258 }
259
260 /****** FINGER PRESENCE DETECTION ******/
261
262 static const struct aes_regwrite finger_det_reqs[] = {
263 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
264 { AES2501_REG_EXCITCTRL, 0x40 },
265 { AES2501_REG_DETCTRL,
266 AES2501_DETCTRL_DRATE_CONTINUOUS | AES2501_DETCTRL_SDELAY_31_MS },
267 { AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US },
268 { AES2501_REG_MEASDRV, AES2501_MEASDRV_MDRIVE_0_325 | AES2501_MEASDRV_MEASURE_SQUARE },
269 { AES2501_REG_MEASFREQ, AES2501_MEASFREQ_2M },
270 { AES2501_REG_DEMODPHASE1, DEMODPHASE_NONE },
271 { AES2501_REG_DEMODPHASE2, DEMODPHASE_NONE },
272 { AES2501_REG_CHANGAIN,
273 AES2501_CHANGAIN_STAGE2_4X | AES2501_CHANGAIN_STAGE1_16X },
274 { AES2501_REG_ADREFHI, 0x44 },
275 { AES2501_REG_ADREFLO, 0x34 },
276 { AES2501_REG_STRTCOL, 0x16 },
277 { AES2501_REG_ENDCOL, 0x16 },
278 { AES2501_REG_DATFMT, AES2501_DATFMT_BIN_IMG | 0x08 },
279 { AES2501_REG_TREG1, 0x70 },
280 { 0xa2, 0x02 },
281 { 0xa7, 0x00 },
282 { AES2501_REG_TREGC, AES2501_TREGC_ENABLE },
283 { AES2501_REG_TREGD, 0x1a },
284 { 0, 0 },
285 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
286 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
287 { AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
288 };
289
290 static void start_finger_detection(struct fp_img_dev *dev);
291
finger_det_data_cb(struct libusb_transfer * transfer)292 static void finger_det_data_cb(struct libusb_transfer *transfer)
293 {
294 struct fp_img_dev *dev = transfer->user_data;
295 unsigned char *data = transfer->buffer;
296 int i;
297 int sum = 0;
298
299 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
300 fpi_imgdev_session_error(dev, -EIO);
301 goto out;
302 } else if (transfer->length != transfer->actual_length) {
303 fpi_imgdev_session_error(dev, -EPROTO);
304 goto out;
305 }
306
307 /* examine histogram to determine finger presence */
308 for (i = 1; i < 9; i++)
309 sum += (data[i] & 0xf) + (data[i] >> 4);
310 if (sum > 20) {
311 /* finger present, start capturing */
312 fpi_imgdev_report_finger_status(dev, TRUE);
313 start_capture(dev);
314 } else {
315 /* no finger, poll for a new histogram */
316 start_finger_detection(dev);
317 }
318
319 out:
320 g_free(data);
321 libusb_free_transfer(transfer);
322 }
323
finger_det_reqs_cb(struct fp_img_dev * dev,int result,void * user_data)324 static void finger_det_reqs_cb(struct fp_img_dev *dev, int result,
325 void *user_data)
326 {
327 struct libusb_transfer *transfer;
328 unsigned char *data;
329 int r;
330
331 if (result) {
332 fpi_imgdev_session_error(dev, result);
333 return;
334 }
335
336 transfer = libusb_alloc_transfer(0);
337 if (!transfer) {
338 fpi_imgdev_session_error(dev, -ENOMEM);
339 return;
340 }
341
342 data = g_malloc(20);
343 libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 20,
344 finger_det_data_cb, dev, BULK_TIMEOUT);
345
346 r = libusb_submit_transfer(transfer);
347 if (r < 0) {
348 g_free(data);
349 libusb_free_transfer(transfer);
350 fpi_imgdev_session_error(dev, r);
351 }
352 }
353
start_finger_detection(struct fp_img_dev * dev)354 static void start_finger_detection(struct fp_img_dev *dev)
355 {
356 struct aes2501_dev *aesdev = dev->priv;
357 fp_dbg("");
358
359 if (aesdev->deactivating) {
360 complete_deactivation(dev);
361 return;
362 }
363
364 aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs),
365 finger_det_reqs_cb, NULL);
366 }
367
368 /****** CAPTURE ******/
369
370 static const struct aes_regwrite capture_reqs_1[] = {
371 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
372 { 0, 0 },
373 { AES2501_REG_EXCITCTRL, 0x40 },
374 { AES2501_REG_DETCTRL,
375 AES2501_DETCTRL_SDELAY_31_MS | AES2501_DETCTRL_DRATE_CONTINUOUS },
376 { AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US },
377 { AES2501_REG_DEMODPHASE2, 0x7c },
378 { AES2501_REG_MEASDRV,
379 AES2501_MEASDRV_MEASURE_SQUARE | AES2501_MEASDRV_MDRIVE_0_325 },
380 { AES2501_REG_DEMODPHASE1, 0x24 },
381 { AES2501_REG_CHWORD1, 0x00 },
382 { AES2501_REG_CHWORD2, 0x6c },
383 { AES2501_REG_CHWORD3, 0x09 },
384 { AES2501_REG_CHWORD4, 0x54 },
385 { AES2501_REG_CHWORD5, 0x78 },
386 { 0xa2, 0x02 },
387 { 0xa7, 0x00 },
388 { 0xb6, 0x26 },
389 { 0xb7, 0x1a },
390 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
391 { AES2501_REG_IMAGCTRL,
392 AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE |
393 AES2501_IMAGCTRL_IMG_DATA_DISABLE },
394 { AES2501_REG_STRTCOL, 0x10 },
395 { AES2501_REG_ENDCOL, 0x1f },
396 { AES2501_REG_CHANGAIN,
397 AES2501_CHANGAIN_STAGE1_2X | AES2501_CHANGAIN_STAGE2_2X },
398 { AES2501_REG_ADREFHI, 0x70 },
399 { AES2501_REG_ADREFLO, 0x20 },
400 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
401 { AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
402 };
403
404 static const struct aes_regwrite capture_reqs_2[] = {
405 { AES2501_REG_IMAGCTRL,
406 AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE |
407 AES2501_IMAGCTRL_IMG_DATA_DISABLE },
408 { AES2501_REG_STRTCOL, 0x10 },
409 { AES2501_REG_ENDCOL, 0x1f },
410 { AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE1_16X },
411 { AES2501_REG_ADREFHI, 0x70 },
412 { AES2501_REG_ADREFLO, 0x20 },
413 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
414 };
415
416 static struct aes_regwrite strip_scan_reqs[] = {
417 { AES2501_REG_IMAGCTRL,
418 AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE },
419 { AES2501_REG_STRTCOL, 0x00 },
420 { AES2501_REG_ENDCOL, 0x2f },
421 { AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE1_16X },
422 { AES2501_REG_ADREFHI, AES2501_ADREFHI_MAX_VALUE },
423 { AES2501_REG_ADREFLO, 0x20 },
424 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
425 };
426
427 /* capture SM movement:
428 * write reqs and read data 1 + 2,
429 * request and read strip,
430 * jump back to request UNLESS theres no finger, in which case exit SM,
431 * report lack of finger presence, and move to finger detection */
432
433 enum capture_states {
434 CAPTURE_WRITE_REQS_1,
435 CAPTURE_READ_DATA_1,
436 CAPTURE_WRITE_REQS_2,
437 CAPTURE_READ_DATA_2,
438 CAPTURE_REQUEST_STRIP,
439 CAPTURE_READ_STRIP,
440 CAPTURE_NUM_STATES,
441 };
442
capture_read_strip_cb(struct libusb_transfer * transfer)443 static void capture_read_strip_cb(struct libusb_transfer *transfer)
444 {
445 unsigned char *stripdata;
446 struct fpi_ssm *ssm = transfer->user_data;
447 struct fp_img_dev *dev = ssm->priv;
448 struct aes2501_dev *aesdev = dev->priv;
449 unsigned char *data = transfer->buffer;
450 int sum;
451 int threshold;
452
453 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
454 fpi_ssm_mark_aborted(ssm, -EIO);
455 goto out;
456 } else if (transfer->length != transfer->actual_length) {
457 fpi_ssm_mark_aborted(ssm, -EPROTO);
458 goto out;
459 }
460
461 threshold = regval_from_dump(data + 1 + 192*8 + 1 + 16*2 + 1 + 8,
462 AES2501_REG_DATFMT);
463 if (threshold < 0) {
464 fpi_ssm_mark_aborted(ssm, threshold);
465 goto out;
466 }
467
468 sum = sum_histogram_values(data + 1 + 192*8, threshold & 0x0f);
469 if (sum < 0) {
470 fpi_ssm_mark_aborted(ssm, sum);
471 goto out;
472 }
473 fp_dbg("sum=%d", sum);
474
475 if (sum < AES2501_SUM_LOW_THRESH) {
476 strip_scan_reqs[4].value -= 0x8;
477 if (strip_scan_reqs[4].value < AES2501_ADREFHI_MIN_VALUE)
478 strip_scan_reqs[4].value = AES2501_ADREFHI_MIN_VALUE;
479 } else if (sum > AES2501_SUM_HIGH_THRESH) {
480 strip_scan_reqs[4].value += 0x8;
481 if (strip_scan_reqs[4].value > AES2501_ADREFHI_MAX_VALUE)
482 strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
483 }
484 fp_dbg("ADREFHI is %.2x", strip_scan_reqs[4].value);
485
486 /* Sum is 0, maybe finger was removed? Wait for 3 empty frames
487 * to ensure
488 */
489 if (sum == 0) {
490 aesdev->no_finger_cnt++;
491 if (aesdev->no_finger_cnt == 3) {
492 struct fp_img *img;
493
494 aesdev->strips = g_slist_reverse(aesdev->strips);
495 fpi_do_movement_estimation(&assembling_ctx,
496 aesdev->strips, aesdev->strips_len);
497 img = fpi_assemble_frames(&assembling_ctx,
498 aesdev->strips, aesdev->strips_len);
499 img->flags |= FP_IMG_PARTIAL;
500 g_slist_free_full(aesdev->strips, g_free);
501 aesdev->strips = NULL;
502 aesdev->strips_len = 0;
503 fpi_imgdev_image_captured(dev, img);
504 fpi_imgdev_report_finger_status(dev, FALSE);
505 /* marking machine complete will re-trigger finger detection loop */
506 fpi_ssm_mark_completed(ssm);
507 } else {
508 fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
509 }
510 } else {
511 /* obtain next strip */
512 /* FIXME: would preallocating strip buffers be a decent optimization? */
513 struct fpi_frame *stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame));
514 stripe->delta_x = 0;
515 stripe->delta_y = 0;
516 stripdata = stripe->data;
517 memcpy(stripdata, data + 1, 192*8);
518 aesdev->no_finger_cnt = 0;
519 aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
520 aesdev->strips_len++;
521
522 fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
523 }
524
525 out:
526 g_free(data);
527 libusb_free_transfer(transfer);
528 }
529
capture_run_state(struct fpi_ssm * ssm)530 static void capture_run_state(struct fpi_ssm *ssm)
531 {
532 struct fp_img_dev *dev = ssm->priv;
533 struct aes2501_dev *aesdev = dev->priv;
534 int r;
535
536 switch (ssm->cur_state) {
537 case CAPTURE_WRITE_REQS_1:
538 aes_write_regv(dev, capture_reqs_1, G_N_ELEMENTS(capture_reqs_1),
539 generic_write_regv_cb, ssm);
540 break;
541 case CAPTURE_READ_DATA_1:
542 generic_read_ignore_data(ssm, 159);
543 break;
544 case CAPTURE_WRITE_REQS_2:
545 aes_write_regv(dev, capture_reqs_2, G_N_ELEMENTS(capture_reqs_2),
546 generic_write_regv_cb, ssm);
547 break;
548 case CAPTURE_READ_DATA_2:
549 generic_read_ignore_data(ssm, 159);
550 break;
551 case CAPTURE_REQUEST_STRIP:
552 if (aesdev->deactivating)
553 fpi_ssm_mark_completed(ssm);
554 else
555 aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs),
556 generic_write_regv_cb, ssm);
557 break;
558 case CAPTURE_READ_STRIP: ;
559 struct libusb_transfer *transfer = libusb_alloc_transfer(0);
560 unsigned char *data;
561
562 if (!transfer) {
563 fpi_ssm_mark_aborted(ssm, -ENOMEM);
564 break;
565 }
566
567 data = g_malloc(1705);
568 libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 1705,
569 capture_read_strip_cb, ssm, BULK_TIMEOUT);
570
571 r = libusb_submit_transfer(transfer);
572 if (r < 0) {
573 g_free(data);
574 libusb_free_transfer(transfer);
575 fpi_ssm_mark_aborted(ssm, r);
576 }
577 break;
578 };
579 }
580
capture_sm_complete(struct fpi_ssm * ssm)581 static void capture_sm_complete(struct fpi_ssm *ssm)
582 {
583 struct fp_img_dev *dev = ssm->priv;
584 struct aes2501_dev *aesdev = dev->priv;
585
586 fp_dbg("");
587 if (aesdev->deactivating)
588 complete_deactivation(dev);
589 else if (ssm->error)
590 fpi_imgdev_session_error(dev, ssm->error);
591 else
592 start_finger_detection(dev);
593 fpi_ssm_free(ssm);
594 }
595
start_capture(struct fp_img_dev * dev)596 static void start_capture(struct fp_img_dev *dev)
597 {
598 struct aes2501_dev *aesdev = dev->priv;
599 struct fpi_ssm *ssm;
600
601 if (aesdev->deactivating) {
602 complete_deactivation(dev);
603 return;
604 }
605
606 aesdev->no_finger_cnt = 0;
607 /* Reset gain */
608 strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE;
609 ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES);
610 fp_dbg("");
611 ssm->priv = dev;
612 fpi_ssm_start(ssm, capture_sm_complete);
613 }
614
615 /****** INITIALIZATION/DEINITIALIZATION ******/
616
617 static const struct aes_regwrite init_1[] = {
618 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
619 { 0, 0 },
620 { 0xb0, 0x27 }, /* Reserved? */
621 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
622 { AES2501_REG_EXCITCTRL, 0x40 },
623 { 0xff, 0x00 }, /* Reserved? */
624 { 0xff, 0x00 }, /* Reserved? */
625 { 0xff, 0x00 }, /* Reserved? */
626 { 0xff, 0x00 }, /* Reserved? */
627 { 0xff, 0x00 }, /* Reserved? */
628 { 0xff, 0x00 }, /* Reserved? */
629 { 0xff, 0x00 }, /* Reserved? */
630 { 0xff, 0x00 }, /* Reserved? */
631 { 0xff, 0x00 }, /* Reserved? */
632 { 0xff, 0x00 }, /* Reserved? */
633 { 0xff, 0x00 }, /* Reserved? */
634 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
635 { AES2501_REG_EXCITCTRL, 0x40 },
636 { AES2501_REG_DETCTRL,
637 AES2501_DETCTRL_DRATE_CONTINUOUS | AES2501_DETCTRL_SDELAY_31_MS },
638 { AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US },
639 { AES2501_REG_MEASDRV,
640 AES2501_MEASDRV_MDRIVE_0_325 | AES2501_MEASDRV_MEASURE_SQUARE },
641 { AES2501_REG_MEASFREQ, AES2501_MEASFREQ_2M },
642 { AES2501_REG_DEMODPHASE1, DEMODPHASE_NONE },
643 { AES2501_REG_DEMODPHASE2, DEMODPHASE_NONE },
644 { AES2501_REG_CHANGAIN,
645 AES2501_CHANGAIN_STAGE2_4X | AES2501_CHANGAIN_STAGE1_16X },
646 { AES2501_REG_ADREFHI, 0x44 },
647 { AES2501_REG_ADREFLO, 0x34 },
648 { AES2501_REG_STRTCOL, 0x16 },
649 { AES2501_REG_ENDCOL, 0x16 },
650 { AES2501_REG_DATFMT, AES2501_DATFMT_BIN_IMG | 0x08 },
651 { AES2501_REG_TREG1, 0x70 },
652 { 0xa2, 0x02 },
653 { 0xa7, 0x00 },
654 { AES2501_REG_TREGC, AES2501_TREGC_ENABLE },
655 { AES2501_REG_TREGD, 0x1a },
656 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
657 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
658 { AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
659 };
660
661 static const struct aes_regwrite init_2[] = {
662 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
663 { AES2501_REG_EXCITCTRL, 0x40 },
664 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
665 { AES2501_REG_AUTOCALOFFSET, 0x41 },
666 { AES2501_REG_EXCITCTRL, 0x42 },
667 { AES2501_REG_DETCTRL, 0x53 },
668 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
669 };
670
671 static const struct aes_regwrite init_3[] = {
672 { 0xff, 0x00 },
673 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
674 { AES2501_REG_AUTOCALOFFSET, 0x41 },
675 { AES2501_REG_EXCITCTRL, 0x42 },
676 { AES2501_REG_DETCTRL, 0x53 },
677 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
678 };
679
680 static const struct aes_regwrite init_4[] = {
681 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
682 { AES2501_REG_EXCITCTRL, 0x40 },
683 { 0xb0, 0x27 },
684 { AES2501_REG_ENDROW, 0x0a },
685 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
686 { AES2501_REG_DETCTRL, 0x45 },
687 { AES2501_REG_AUTOCALOFFSET, 0x41 },
688 };
689
690 static const struct aes_regwrite init_5[] = {
691 { 0xb0, 0x27 },
692 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
693 { AES2501_REG_EXCITCTRL, 0x40 },
694 { 0xff, 0x00 },
695 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
696 { AES2501_REG_EXCITCTRL, 0x40 },
697 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
698 { AES2501_REG_EXCITCTRL, 0x40 },
699 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
700 { AES2501_REG_EXCITCTRL, 0x40 },
701 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
702 { AES2501_REG_EXCITCTRL, 0x40 },
703 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
704 { AES2501_REG_EXCITCTRL, 0x40 },
705 { AES2501_REG_CTRL1, AES2501_CTRL1_SCAN_RESET },
706 { AES2501_REG_CTRL1, AES2501_CTRL1_SCAN_RESET },
707 };
708
709 enum activate_states {
710 WRITE_INIT_1,
711 READ_DATA_1,
712 WRITE_INIT_2,
713 READ_REGS,
714 WRITE_INIT_3,
715 WRITE_INIT_4,
716 WRITE_INIT_5,
717 ACTIVATE_NUM_STATES,
718 };
719
activate_read_regs_cb(struct fp_img_dev * dev,int status,unsigned char * regs,void * user_data)720 void activate_read_regs_cb(struct fp_img_dev *dev, int status,
721 unsigned char *regs, void *user_data)
722 {
723 struct fpi_ssm *ssm = user_data;
724 struct aes2501_dev *aesdev = dev->priv;
725
726 if (status != 0) {
727 fpi_ssm_mark_aborted(ssm, status);
728 } else {
729 fp_dbg("reg 0xaf = %x", regs[0x5f]);
730 if (regs[0x5f] != 0x6b || ++aesdev->read_regs_retry_count == 13)
731 fpi_ssm_jump_to_state(ssm, WRITE_INIT_4);
732 else
733 fpi_ssm_next_state(ssm);
734 }
735 }
736
activate_init3_cb(struct fp_img_dev * dev,int result,void * user_data)737 static void activate_init3_cb(struct fp_img_dev *dev, int result,
738 void *user_data)
739 {
740 struct fpi_ssm *ssm = user_data;
741 if (result == 0)
742 fpi_ssm_jump_to_state(ssm, READ_REGS);
743 else
744 fpi_ssm_mark_aborted(ssm, result);
745 }
746
activate_run_state(struct fpi_ssm * ssm)747 static void activate_run_state(struct fpi_ssm *ssm)
748 {
749 struct fp_img_dev *dev = ssm->priv;
750
751 /* This state machine isn't as linear as it may appear. After doing init1
752 * and init2 register configuration writes, we have to poll a register
753 * waiting for a specific value. READ_REGS checks the register value, and
754 * if we're ready to move on, we jump to init4. Otherwise, we write init3
755 * and then jump back to READ_REGS. In a synchronous model:
756
757 [...]
758 aes_write_regv(init_2);
759 read_regs(into buffer);
760 i = 0;
761 while (buffer[0x5f] == 0x6b) {
762 aes_write_regv(init_3);
763 read_regs(into buffer);
764 if (++i == 13)
765 break;
766 }
767 aes_write_regv(init_4);
768 */
769
770 switch (ssm->cur_state) {
771 case WRITE_INIT_1:
772 aes_write_regv(dev, init_1, G_N_ELEMENTS(init_1),
773 generic_write_regv_cb, ssm);
774 break;
775 case READ_DATA_1:
776 fp_dbg("read data 1");
777 generic_read_ignore_data(ssm, 20);
778 break;
779 case WRITE_INIT_2:
780 aes_write_regv(dev, init_2, G_N_ELEMENTS(init_2),
781 generic_write_regv_cb, ssm);
782 break;
783 case READ_REGS:
784 read_regs(dev, activate_read_regs_cb, ssm);
785 break;
786 case WRITE_INIT_3:
787 aes_write_regv(dev, init_4, G_N_ELEMENTS(init_4),
788 activate_init3_cb, ssm);
789 break;
790 case WRITE_INIT_4:
791 aes_write_regv(dev, init_4, G_N_ELEMENTS(init_4),
792 generic_write_regv_cb, ssm);
793 break;
794 case WRITE_INIT_5:
795 aes_write_regv(dev, init_5, G_N_ELEMENTS(init_5),
796 generic_write_regv_cb, ssm);
797 break;
798 }
799 }
800
activate_sm_complete(struct fpi_ssm * ssm)801 static void activate_sm_complete(struct fpi_ssm *ssm)
802 {
803 struct fp_img_dev *dev = ssm->priv;
804 fp_dbg("status %d", ssm->error);
805 fpi_imgdev_activate_complete(dev, ssm->error);
806
807 if (!ssm->error)
808 start_finger_detection(dev);
809 fpi_ssm_free(ssm);
810 }
811
dev_activate(struct fp_img_dev * dev,enum fp_imgdev_state state)812 static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
813 {
814 struct aes2501_dev *aesdev = dev->priv;
815 struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state,
816 ACTIVATE_NUM_STATES);
817 ssm->priv = dev;
818 aesdev->read_regs_retry_count = 0;
819 fpi_ssm_start(ssm, activate_sm_complete);
820 return 0;
821 }
822
dev_deactivate(struct fp_img_dev * dev)823 static void dev_deactivate(struct fp_img_dev *dev)
824 {
825 struct aes2501_dev *aesdev = dev->priv;
826 /* FIXME: audit cancellation points, probably need more, specifically
827 * in error handling paths? */
828 aesdev->deactivating = TRUE;
829 }
830
complete_deactivation(struct fp_img_dev * dev)831 static void complete_deactivation(struct fp_img_dev *dev)
832 {
833 struct aes2501_dev *aesdev = dev->priv;
834 fp_dbg("");
835
836 /* FIXME: if we're in the middle of a scan, we should cancel the scan.
837 * maybe we can do this with a master reset, unconditionally? */
838
839 aesdev->deactivating = FALSE;
840 g_slist_free(aesdev->strips);
841 aesdev->strips = NULL;
842 aesdev->strips_len = 0;
843 fpi_imgdev_deactivate_complete(dev);
844 }
845
dev_init(struct fp_img_dev * dev,unsigned long driver_data)846 static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
847 {
848 /* FIXME check endpoints */
849 int r;
850
851 r = libusb_claim_interface(dev->udev, 0);
852 if (r < 0) {
853 fp_err("could not claim interface 0: %s", libusb_error_name(r));
854 return r;
855 }
856
857 dev->priv = g_malloc0(sizeof(struct aes2501_dev));
858 fpi_imgdev_open_complete(dev, 0);
859 return 0;
860 }
861
dev_deinit(struct fp_img_dev * dev)862 static void dev_deinit(struct fp_img_dev *dev)
863 {
864 g_free(dev->priv);
865 libusb_release_interface(dev->udev, 0);
866 fpi_imgdev_close_complete(dev);
867 }
868
869 static const struct usb_id id_table[] = {
870 { .vendor = 0x08ff, .product = 0x2500 }, /* AES2500 */
871 { .vendor = 0x08ff, .product = 0x2580 }, /* AES2501 */
872 { 0, 0, 0, },
873 };
874
875 struct fp_img_driver aes2501_driver = {
876 .driver = {
877 .id = AES2501_ID,
878 .name = FP_COMPONENT,
879 .full_name = "AuthenTec AES2501",
880 .id_table = id_table,
881 .scan_type = FP_SCAN_TYPE_SWIPE,
882 },
883 .flags = 0,
884 .img_height = -1,
885 .img_width = IMAGE_WIDTH,
886
887 .open = dev_init,
888 .close = dev_deinit,
889 .activate = dev_activate,
890 .deactivate = dev_deactivate,
891 };
892
893