Fix fp_get_pollfds()
[libfprint.git] / libfprint / drivers / aes2501.c
blob617bb64f851bc84f977d773cecccc564a15f7570
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 Vasily Khoruzhick
7 * Based on code from http://home.gna.org/aes2501, relicensed with permission
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.
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.
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
24 #define FP_COMPONENT "aes2501"
26 #include <errno.h>
27 #include <string.h>
29 #include <libusb.h>
31 #include <aeslib.h>
32 #include <fp_internal.h>
33 #include "aes2501.h"
35 static void start_capture(struct fp_img_dev *dev);
36 static void complete_deactivation(struct fp_img_dev *dev);
38 /* FIXME these need checking */
39 #define EP_IN (1 | LIBUSB_ENDPOINT_IN)
40 #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
42 #define BULK_TIMEOUT 4000
45 * The AES2501 is an imaging device using a swipe-type sensor. It samples
46 * the finger at preprogrammed intervals, sending a 192x16 frame to the
47 * computer.
48 * Unless the user is scanning their finger unreasonably fast, the frames
49 * *will* overlap. The implementation below detects this overlap and produces
50 * a contiguous image as the end result.
51 * The fact that the user determines the length of the swipe (and hence the
52 * number of useful frames) and also the fact that overlap varies means that
53 * images returned from this driver vary in height.
56 #define FRAME_WIDTH 192
57 #define FRAME_HEIGHT 16
58 #define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT)
59 /* maximum number of frames to read during a scan */
60 /* FIXME reduce substantially */
61 #define MAX_FRAMES 150
63 /****** GENERAL FUNCTIONS ******/
65 struct aes2501_dev {
66 uint8_t read_regs_retry_count;
67 GSList *strips;
68 size_t strips_len;
69 gboolean deactivating;
72 typedef void (*aes2501_read_regs_cb)(struct fp_img_dev *dev, int status,
73 unsigned char *regs, void *user_data);
75 struct aes2501_read_regs {
76 struct fp_img_dev *dev;
77 aes2501_read_regs_cb callback;
78 struct aes_regwrite *regwrite;
79 void *user_data;
82 static void read_regs_data_cb(struct libusb_transfer *transfer)
84 struct aes2501_read_regs *rdata = transfer->user_data;
85 unsigned char *retdata = NULL;
86 int r;
88 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
89 r = -EIO;
90 } else if (transfer->length != transfer->actual_length) {
91 r = -EPROTO;
92 } else {
93 r = 0;
94 retdata = transfer->buffer;
97 rdata->callback(rdata->dev, r, retdata, rdata->user_data);
98 g_free(rdata);
99 g_free(transfer->buffer);
100 libusb_free_transfer(transfer);
103 static void read_regs_rq_cb(struct fp_img_dev *dev, int result, void *user_data)
105 struct aes2501_read_regs *rdata = user_data;
106 struct libusb_transfer *transfer;
107 unsigned char *data;
108 int r;
110 g_free(rdata->regwrite);
111 if (result != 0)
112 goto err;
114 transfer = libusb_alloc_transfer(0);
115 if (!transfer) {
116 result = -ENOMEM;
117 goto err;
120 data = g_malloc(126);
121 libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 126,
122 read_regs_data_cb, rdata, BULK_TIMEOUT);
124 r = libusb_submit_transfer(transfer);
125 if (r < 0) {
126 g_free(data);
127 libusb_free_transfer(transfer);
128 result = -EIO;
129 goto err;
132 return;
133 err:
134 rdata->callback(dev, result, NULL, rdata->user_data);
135 g_free(rdata);
138 static void read_regs(struct fp_img_dev *dev, aes2501_read_regs_cb callback,
139 void *user_data)
141 /* FIXME: regwrite is dynamic because of asynchronity. is this really
142 * required? */
143 struct aes_regwrite *regwrite = g_malloc(sizeof(*regwrite));
144 struct aes2501_read_regs *rdata = g_malloc(sizeof(*rdata));
146 fp_dbg("");
147 regwrite->reg = AES2501_REG_CTRL2;
148 regwrite->value = AES2501_CTRL2_READ_REGS;
149 rdata->dev = dev;
150 rdata->callback = callback;
151 rdata->user_data = user_data;
152 rdata->regwrite = regwrite;
154 aes_write_regv(dev, (const struct aes_regwrite *) regwrite, 1,
155 read_regs_rq_cb, rdata);
158 /* Read the value of a specific register from a register dump */
159 static int regval_from_dump(unsigned char *data, uint8_t target)
161 if (*data != FIRST_AES2501_REG) {
162 fp_err("not a register dump");
163 return -EILSEQ;
166 if (!(FIRST_AES2501_REG <= target && target <= LAST_AES2501_REG)) {
167 fp_err("out of range");
168 return -EINVAL;
171 target -= FIRST_AES2501_REG;
172 target *= 2;
173 return data[target + 1];
176 static void generic_write_regv_cb(struct fp_img_dev *dev, int result,
177 void *user_data)
179 struct fpi_ssm *ssm = user_data;
180 if (result == 0)
181 fpi_ssm_next_state(ssm);
182 else
183 fpi_ssm_mark_aborted(ssm, result);
186 /* check that read succeeded but ignore all data */
187 static void generic_ignore_data_cb(struct libusb_transfer *transfer)
189 struct fpi_ssm *ssm = transfer->user_data;
191 if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
192 fpi_ssm_mark_aborted(ssm, -EIO);
193 else if (transfer->length != transfer->actual_length)
194 fpi_ssm_mark_aborted(ssm, -EPROTO);
195 else
196 fpi_ssm_next_state(ssm);
198 g_free(transfer->buffer);
199 libusb_free_transfer(transfer);
202 /* read the specified number of bytes from the IN endpoint but throw them
203 * away, then increment the SSM */
204 static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes)
206 struct libusb_transfer *transfer = libusb_alloc_transfer(0);
207 unsigned char *data;
208 int r;
210 if (!transfer) {
211 fpi_ssm_mark_aborted(ssm, -ENOMEM);
212 return;
215 data = g_malloc(bytes);
216 libusb_fill_bulk_transfer(transfer, ssm->dev->udev, EP_IN, data, bytes,
217 generic_ignore_data_cb, ssm, BULK_TIMEOUT);
219 r = libusb_submit_transfer(transfer);
220 if (r < 0) {
221 g_free(data);
222 libusb_free_transfer(transfer);
223 fpi_ssm_mark_aborted(ssm, r);
227 /****** IMAGE PROCESSING ******/
229 static int sum_histogram_values(unsigned char *data, uint8_t threshold)
231 int r = 0;
232 int i;
233 uint16_t *histogram = (uint16_t *)(data + 1);
235 if (*data != 0xde)
236 return -EILSEQ;
238 if (threshold > 0x0f)
239 return -EINVAL;
241 /* FIXME endianness */
242 for (i = threshold; i < 16; i++)
243 r += histogram[i];
245 return r;
248 /* find overlapping parts of frames */
249 static unsigned int find_overlap(unsigned char *first_frame,
250 unsigned char *second_frame, unsigned int *min_error)
252 unsigned int dy;
253 unsigned int not_overlapped_height = 0;
254 *min_error = 255 * FRAME_SIZE;
255 for (dy = 0; dy < FRAME_HEIGHT; dy++) {
256 /* Calculating difference (error) between parts of frames */
257 unsigned int i;
258 unsigned int error = 0;
259 for (i = 0; i < FRAME_WIDTH * (FRAME_HEIGHT - dy); i++) {
260 /* Using ? operator to avoid abs function */
261 error += first_frame[i] > second_frame[i] ?
262 (first_frame[i] - second_frame[i]) :
263 (second_frame[i] - first_frame[i]);
266 /* Normalize error */
267 error *= 15;
268 error /= i;
269 if (error < *min_error) {
270 *min_error = error;
271 not_overlapped_height = dy;
273 first_frame += FRAME_WIDTH;
276 return not_overlapped_height;
279 /* assemble a series of frames into a single image */
280 static unsigned int assemble(struct aes2501_dev *aesdev, unsigned char *output,
281 gboolean reverse, unsigned int *errors_sum)
283 uint8_t *assembled = output;
284 int frame;
285 uint32_t image_height = FRAME_HEIGHT;
286 unsigned int min_error;
287 size_t num_strips = aesdev->strips_len;
288 GSList *list_entry = aesdev->strips;
289 *errors_sum = 0;
291 /* Rotating given data by 90 degrees
292 * Taken from document describing aes2501 image format
293 * TODO: move reversing detection here */
295 if (reverse)
296 output += (num_strips - 1) * FRAME_SIZE;
297 for (frame = 0; frame < num_strips; frame++) {
298 aes_assemble_image(list_entry->data, FRAME_WIDTH, FRAME_HEIGHT, output);
300 if (reverse)
301 output -= FRAME_SIZE;
302 else
303 output += FRAME_SIZE;
304 list_entry = g_slist_next(list_entry);
307 /* Detecting where frames overlaped */
308 output = assembled;
309 for (frame = 1; frame < num_strips; frame++) {
310 int not_overlapped;
312 output += FRAME_SIZE;
313 not_overlapped = find_overlap(assembled, output, &min_error);
314 *errors_sum += min_error;
315 image_height += not_overlapped;
316 assembled += FRAME_WIDTH * not_overlapped;
317 memcpy(assembled, output, FRAME_SIZE);
319 return image_height;
322 static void assemble_and_submit_image(struct fp_img_dev *dev)
324 struct aes2501_dev *aesdev = dev->priv;
325 size_t final_size;
326 struct fp_img *img;
327 unsigned int errors_sum, r_errors_sum;
329 BUG_ON(aesdev->strips_len == 0);
331 /* reverse list */
332 aesdev->strips = g_slist_reverse(aesdev->strips);
334 /* create buffer big enough for max image */
335 img = fpi_img_new(aesdev->strips_len * FRAME_SIZE);
337 img->flags = FP_IMG_COLORS_INVERTED;
338 img->height = assemble(aesdev, img->data, FALSE, &errors_sum);
339 img->height = assemble(aesdev, img->data, TRUE, &r_errors_sum);
341 if (r_errors_sum > errors_sum) {
342 img->height = assemble(aesdev, img->data, FALSE, &errors_sum);
343 img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED;
344 fp_dbg("normal scan direction");
345 } else {
346 fp_dbg("reversed scan direction");
349 /* now that overlap has been removed, resize output image buffer */
350 final_size = img->height * FRAME_WIDTH;
351 img = fpi_img_resize(img, final_size);
352 fpi_imgdev_image_captured(dev, img);
354 /* free strips and strip list */
355 g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL);
356 g_slist_free(aesdev->strips);
357 aesdev->strips = NULL;
361 /****** FINGER PRESENCE DETECTION ******/
363 static const struct aes_regwrite finger_det_reqs[] = {
364 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
365 { AES2501_REG_EXCITCTRL, 0x40 },
366 { AES2501_REG_DETCTRL,
367 AES2501_DETCTRL_DRATE_CONTINUOUS | AES2501_DETCTRL_SDELAY_31_MS },
368 { AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US },
369 { AES2501_REG_MEASDRV, AES2501_MEASDRV_MDRIVE_0_325 | AES2501_MEASDRV_MEASURE_SQUARE },
370 { AES2501_REG_MEASFREQ, AES2501_MEASFREQ_2M },
371 { AES2501_REG_DEMODPHASE1, DEMODPHASE_NONE },
372 { AES2501_REG_DEMODPHASE2, DEMODPHASE_NONE },
373 { AES2501_REG_CHANGAIN,
374 AES2501_CHANGAIN_STAGE2_4X | AES2501_CHANGAIN_STAGE1_16X },
375 { AES2501_REG_ADREFHI, 0x44 },
376 { AES2501_REG_ADREFLO, 0x34 },
377 { AES2501_REG_STRTCOL, 0x16 },
378 { AES2501_REG_ENDCOL, 0x16 },
379 { AES2501_REG_DATFMT, AES2501_DATFMT_BIN_IMG | 0x08 },
380 { AES2501_REG_TREG1, 0x70 },
381 { 0xa2, 0x02 },
382 { 0xa7, 0x00 },
383 { AES2501_REG_TREGC, AES2501_TREGC_ENABLE },
384 { AES2501_REG_TREGD, 0x1a },
385 { 0, 0 },
386 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
387 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
388 { AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
391 static void start_finger_detection(struct fp_img_dev *dev);
393 static void finger_det_data_cb(struct libusb_transfer *transfer)
395 struct fp_img_dev *dev = transfer->user_data;
396 unsigned char *data = transfer->buffer;
397 int i;
398 int sum = 0;
400 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
401 fpi_imgdev_session_error(dev, -EIO);
402 goto out;
403 } else if (transfer->length != transfer->actual_length) {
404 fpi_imgdev_session_error(dev, -EPROTO);
405 goto out;
408 /* examine histogram to determine finger presence */
409 for (i = 1; i < 9; i++)
410 sum += (data[i] & 0xf) + (data[i] >> 4);
411 if (sum > 20) {
412 /* finger present, start capturing */
413 fpi_imgdev_report_finger_status(dev, TRUE);
414 start_capture(dev);
415 } else {
416 /* no finger, poll for a new histogram */
417 start_finger_detection(dev);
420 out:
421 g_free(data);
422 libusb_free_transfer(transfer);
425 static void finger_det_reqs_cb(struct fp_img_dev *dev, int result,
426 void *user_data)
428 struct libusb_transfer *transfer;
429 unsigned char *data;
430 int r;
432 if (result) {
433 fpi_imgdev_session_error(dev, result);
434 return;
437 transfer = libusb_alloc_transfer(0);
438 if (!transfer) {
439 fpi_imgdev_session_error(dev, -ENOMEM);
440 return;
443 data = g_malloc(20);
444 libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 20,
445 finger_det_data_cb, dev, BULK_TIMEOUT);
447 r = libusb_submit_transfer(transfer);
448 if (r < 0) {
449 g_free(data);
450 libusb_free_transfer(transfer);
451 fpi_imgdev_session_error(dev, r);
455 static void start_finger_detection(struct fp_img_dev *dev)
457 struct aes2501_dev *aesdev = dev->priv;
458 fp_dbg("");
460 if (aesdev->deactivating) {
461 complete_deactivation(dev);
462 return;
465 aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs),
466 finger_det_reqs_cb, NULL);
469 /****** CAPTURE ******/
471 static const struct aes_regwrite capture_reqs_1[] = {
472 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
473 { 0, 0 },
474 { AES2501_REG_EXCITCTRL, 0x40 },
475 { AES2501_REG_DETCTRL,
476 AES2501_DETCTRL_SDELAY_31_MS | AES2501_DETCTRL_DRATE_CONTINUOUS },
477 { AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US },
478 { AES2501_REG_DEMODPHASE2, 0x7c },
479 { AES2501_REG_MEASDRV,
480 AES2501_MEASDRV_MEASURE_SQUARE | AES2501_MEASDRV_MDRIVE_0_325 },
481 { AES2501_REG_DEMODPHASE1, 0x24 },
482 { AES2501_REG_CHWORD1, 0x00 },
483 { AES2501_REG_CHWORD2, 0x6c },
484 { AES2501_REG_CHWORD3, 0x09 },
485 { AES2501_REG_CHWORD4, 0x54 },
486 { AES2501_REG_CHWORD5, 0x78 },
487 { 0xa2, 0x02 },
488 { 0xa7, 0x00 },
489 { 0xb6, 0x26 },
490 { 0xb7, 0x1a },
491 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
492 { AES2501_REG_IMAGCTRL,
493 AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE |
494 AES2501_IMAGCTRL_IMG_DATA_DISABLE },
495 { AES2501_REG_STRTCOL, 0x10 },
496 { AES2501_REG_ENDCOL, 0x1f },
497 { AES2501_REG_CHANGAIN,
498 AES2501_CHANGAIN_STAGE1_2X | AES2501_CHANGAIN_STAGE2_2X },
499 { AES2501_REG_ADREFHI, 0x70 },
500 { AES2501_REG_ADREFLO, 0x20 },
501 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
502 { AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
505 static const struct aes_regwrite capture_reqs_2[] = {
506 { AES2501_REG_IMAGCTRL,
507 AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE |
508 AES2501_IMAGCTRL_IMG_DATA_DISABLE },
509 { AES2501_REG_STRTCOL, 0x10 },
510 { AES2501_REG_ENDCOL, 0x1f },
511 { AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE1_16X },
512 { AES2501_REG_ADREFHI, 0x70 },
513 { AES2501_REG_ADREFLO, 0x20 },
514 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
517 static const struct aes_regwrite strip_scan_reqs[] = {
518 { AES2501_REG_IMAGCTRL,
519 AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE },
520 { AES2501_REG_STRTCOL, 0x00 },
521 { AES2501_REG_ENDCOL, 0x2f },
522 { AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE1_16X },
523 { AES2501_REG_ADREFHI, 0x5b },
524 { AES2501_REG_ADREFLO, 0x20 },
525 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
528 /* capture SM movement:
529 * write reqs and read data 1 + 2,
530 * request and read strip,
531 * jump back to request UNLESS theres no finger, in which case exit SM,
532 * report lack of finger presence, and move to finger detection */
534 enum capture_states {
535 CAPTURE_WRITE_REQS_1,
536 CAPTURE_READ_DATA_1,
537 CAPTURE_WRITE_REQS_2,
538 CAPTURE_READ_DATA_2,
539 CAPTURE_REQUEST_STRIP,
540 CAPTURE_READ_STRIP,
541 CAPTURE_NUM_STATES,
544 static void capture_read_strip_cb(struct libusb_transfer *transfer)
546 unsigned char *stripdata;
547 struct fpi_ssm *ssm = transfer->user_data;
548 struct fp_img_dev *dev = ssm->priv;
549 struct aes2501_dev *aesdev = dev->priv;
550 unsigned char *data = transfer->buffer;
551 int sum;
552 int threshold;
554 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
555 fpi_ssm_mark_aborted(ssm, -EIO);
556 goto out;
557 } else if (transfer->length != transfer->actual_length) {
558 fpi_ssm_mark_aborted(ssm, -EPROTO);
559 goto out;
562 /* FIXME: would preallocating strip buffers be a decent optimization? */
563 stripdata = g_malloc(192 * 8);
564 memcpy(stripdata, data + 1, 192*8);
565 aesdev->strips = g_slist_prepend(aesdev->strips, stripdata);
566 aesdev->strips_len++;
568 threshold = regval_from_dump(data + 1 + 192*8 + 1 + 16*2 + 1 + 8,
569 AES2501_REG_DATFMT);
570 if (threshold < 0) {
571 fpi_ssm_mark_aborted(ssm, threshold);
572 goto out;
575 sum = sum_histogram_values(data + 1 + 192*8, threshold & 0x0f);
576 if (sum < 0) {
577 fpi_ssm_mark_aborted(ssm, sum);
578 goto out;
580 fp_dbg("sum=%d", sum);
582 /* FIXME: 0 might be too low as a threshold */
583 /* FIXME: sometimes we get 0 in the middle of a scan, should we wait for
584 * a few consecutive zeroes? */
585 /* FIXME: we should have an upper limit on the number of strips */
587 /* If sum is 0, finger has been removed */
588 if (sum == 0) {
589 /* assemble image and submit it to library */
590 assemble_and_submit_image(dev);
591 fpi_imgdev_report_finger_status(dev, FALSE);
592 /* marking machine complete will re-trigger finger detection loop */
593 fpi_ssm_mark_completed(ssm);
594 } else {
595 /* obtain next strip */
596 fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
599 out:
600 g_free(data);
601 libusb_free_transfer(transfer);
604 static void capture_run_state(struct fpi_ssm *ssm)
606 struct fp_img_dev *dev = ssm->priv;
607 struct aes2501_dev *aesdev = dev->priv;
608 int r;
610 switch (ssm->cur_state) {
611 case CAPTURE_WRITE_REQS_1:
612 aes_write_regv(dev, capture_reqs_1, G_N_ELEMENTS(capture_reqs_1),
613 generic_write_regv_cb, ssm);
614 break;
615 case CAPTURE_READ_DATA_1:
616 generic_read_ignore_data(ssm, 159);
617 break;
618 case CAPTURE_WRITE_REQS_2:
619 aes_write_regv(dev, capture_reqs_2, G_N_ELEMENTS(capture_reqs_2),
620 generic_write_regv_cb, ssm);
621 break;
622 case CAPTURE_READ_DATA_2:
623 generic_read_ignore_data(ssm, 159);
624 break;
625 case CAPTURE_REQUEST_STRIP:
626 if (aesdev->deactivating)
627 fpi_ssm_mark_completed(ssm);
628 else
629 aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs),
630 generic_write_regv_cb, ssm);
631 break;
632 case CAPTURE_READ_STRIP: ;
633 struct libusb_transfer *transfer = libusb_alloc_transfer(0);
634 unsigned char *data;
636 if (!transfer) {
637 fpi_ssm_mark_aborted(ssm, -ENOMEM);
638 break;
641 data = g_malloc(1705);
642 libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 1705,
643 capture_read_strip_cb, ssm, BULK_TIMEOUT);
645 r = libusb_submit_transfer(transfer);
646 if (r < 0) {
647 g_free(data);
648 libusb_free_transfer(transfer);
649 fpi_ssm_mark_aborted(ssm, r);
651 break;
655 static void capture_sm_complete(struct fpi_ssm *ssm)
657 struct fp_img_dev *dev = ssm->priv;
658 struct aes2501_dev *aesdev = dev->priv;
660 fp_dbg("");
661 if (aesdev->deactivating)
662 complete_deactivation(dev);
663 else if (ssm->error)
664 fpi_imgdev_session_error(dev, ssm->error);
665 else
666 start_finger_detection(dev);
667 fpi_ssm_free(ssm);
670 static void start_capture(struct fp_img_dev *dev)
672 struct aes2501_dev *aesdev = dev->priv;
673 struct fpi_ssm *ssm;
675 if (aesdev->deactivating) {
676 complete_deactivation(dev);
677 return;
680 ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES);
681 fp_dbg("");
682 ssm->priv = dev;
683 fpi_ssm_start(ssm, capture_sm_complete);
686 /****** INITIALIZATION/DEINITIALIZATION ******/
688 static const struct aes_regwrite init_1[] = {
689 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
690 { 0, 0 },
691 { 0xb0, 0x27 }, /* Reserved? */
692 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
693 { AES2501_REG_EXCITCTRL, 0x40 },
694 { 0xff, 0x00 }, /* Reserved? */
695 { 0xff, 0x00 }, /* Reserved? */
696 { 0xff, 0x00 }, /* Reserved? */
697 { 0xff, 0x00 }, /* Reserved? */
698 { 0xff, 0x00 }, /* Reserved? */
699 { 0xff, 0x00 }, /* Reserved? */
700 { 0xff, 0x00 }, /* Reserved? */
701 { 0xff, 0x00 }, /* Reserved? */
702 { 0xff, 0x00 }, /* Reserved? */
703 { 0xff, 0x00 }, /* Reserved? */
704 { 0xff, 0x00 }, /* Reserved? */
705 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
706 { AES2501_REG_EXCITCTRL, 0x40 },
707 { AES2501_REG_DETCTRL,
708 AES2501_DETCTRL_DRATE_CONTINUOUS | AES2501_DETCTRL_SDELAY_31_MS },
709 { AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US },
710 { AES2501_REG_MEASDRV,
711 AES2501_MEASDRV_MDRIVE_0_325 | AES2501_MEASDRV_MEASURE_SQUARE },
712 { AES2501_REG_MEASFREQ, AES2501_MEASFREQ_2M },
713 { AES2501_REG_DEMODPHASE1, DEMODPHASE_NONE },
714 { AES2501_REG_DEMODPHASE2, DEMODPHASE_NONE },
715 { AES2501_REG_CHANGAIN,
716 AES2501_CHANGAIN_STAGE2_4X | AES2501_CHANGAIN_STAGE1_16X },
717 { AES2501_REG_ADREFHI, 0x44 },
718 { AES2501_REG_ADREFLO, 0x34 },
719 { AES2501_REG_STRTCOL, 0x16 },
720 { AES2501_REG_ENDCOL, 0x16 },
721 { AES2501_REG_DATFMT, AES2501_DATFMT_BIN_IMG | 0x08 },
722 { AES2501_REG_TREG1, 0x70 },
723 { 0xa2, 0x02 },
724 { 0xa7, 0x00 },
725 { AES2501_REG_TREGC, AES2501_TREGC_ENABLE },
726 { AES2501_REG_TREGD, 0x1a },
727 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
728 { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT },
729 { AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE },
732 static const struct aes_regwrite init_2[] = {
733 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
734 { AES2501_REG_EXCITCTRL, 0x40 },
735 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
736 { AES2501_REG_AUTOCALOFFSET, 0x41 },
737 { AES2501_REG_EXCITCTRL, 0x42 },
738 { AES2501_REG_DETCTRL, 0x53 },
739 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
742 static const struct aes_regwrite init_3[] = {
743 { 0xff, 0x00 },
744 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
745 { AES2501_REG_AUTOCALOFFSET, 0x41 },
746 { AES2501_REG_EXCITCTRL, 0x42 },
747 { AES2501_REG_DETCTRL, 0x53 },
748 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
751 static const struct aes_regwrite init_4[] = {
752 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
753 { AES2501_REG_EXCITCTRL, 0x40 },
754 { 0xb0, 0x27 },
755 { AES2501_REG_ENDROW, 0x0a },
756 { AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE },
757 { AES2501_REG_DETCTRL, 0x45 },
758 { AES2501_REG_AUTOCALOFFSET, 0x41 },
761 static const struct aes_regwrite init_5[] = {
762 { 0xb0, 0x27 },
763 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
764 { AES2501_REG_EXCITCTRL, 0x40 },
765 { 0xff, 0x00 },
766 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
767 { AES2501_REG_EXCITCTRL, 0x40 },
768 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
769 { AES2501_REG_EXCITCTRL, 0x40 },
770 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
771 { AES2501_REG_EXCITCTRL, 0x40 },
772 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
773 { AES2501_REG_EXCITCTRL, 0x40 },
774 { AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET },
775 { AES2501_REG_EXCITCTRL, 0x40 },
776 { AES2501_REG_CTRL1, AES2501_CTRL1_SCAN_RESET },
777 { AES2501_REG_CTRL1, AES2501_CTRL1_SCAN_RESET },
780 enum activate_states {
781 WRITE_INIT_1,
782 READ_DATA_1,
783 WRITE_INIT_2,
784 READ_REGS,
785 WRITE_INIT_3,
786 WRITE_INIT_4,
787 WRITE_INIT_5,
788 ACTIVATE_NUM_STATES,
791 void activate_read_regs_cb(struct fp_img_dev *dev, int status,
792 unsigned char *regs, void *user_data)
794 struct fpi_ssm *ssm = user_data;
795 struct aes2501_dev *aesdev = dev->priv;
797 if (status != 0) {
798 fpi_ssm_mark_aborted(ssm, status);
799 } else {
800 fp_dbg("reg 0xaf = %x", regs[0x5f]);
801 if (regs[0x5f] != 0x6b || ++aesdev->read_regs_retry_count == 13)
802 fpi_ssm_jump_to_state(ssm, WRITE_INIT_4);
803 else
804 fpi_ssm_next_state(ssm);
808 static void activate_init3_cb(struct fp_img_dev *dev, int result,
809 void *user_data)
811 struct fpi_ssm *ssm = user_data;
812 if (result == 0)
813 fpi_ssm_jump_to_state(ssm, READ_REGS);
814 else
815 fpi_ssm_mark_aborted(ssm, result);
818 static void activate_run_state(struct fpi_ssm *ssm)
820 struct fp_img_dev *dev = ssm->priv;
822 /* This state machine isn't as linear as it may appear. After doing init1
823 * and init2 register configuration writes, we have to poll a register
824 * waiting for a specific value. READ_REGS checks the register value, and
825 * if we're ready to move on, we jump to init4. Otherwise, we write init3
826 * and then jump back to READ_REGS. In a synchronous model:
828 [...]
829 aes_write_regv(init_2);
830 read_regs(into buffer);
831 i = 0;
832 while (buffer[0x5f] == 0x6b) {
833 aes_write_regv(init_3);
834 read_regs(into buffer);
835 if (++i == 13)
836 break;
838 aes_write_regv(init_4);
841 switch (ssm->cur_state) {
842 case WRITE_INIT_1:
843 aes_write_regv(dev, init_1, G_N_ELEMENTS(init_1),
844 generic_write_regv_cb, ssm);
845 break;
846 case READ_DATA_1:
847 fp_dbg("read data 1");
848 generic_read_ignore_data(ssm, 20);
849 break;
850 case WRITE_INIT_2:
851 aes_write_regv(dev, init_2, G_N_ELEMENTS(init_2),
852 generic_write_regv_cb, ssm);
853 break;
854 case READ_REGS:
855 read_regs(dev, activate_read_regs_cb, ssm);
856 break;
857 case WRITE_INIT_3:
858 aes_write_regv(dev, init_4, G_N_ELEMENTS(init_4),
859 activate_init3_cb, ssm);
860 break;
861 case WRITE_INIT_4:
862 aes_write_regv(dev, init_4, G_N_ELEMENTS(init_4),
863 generic_write_regv_cb, ssm);
864 break;
865 case WRITE_INIT_5:
866 aes_write_regv(dev, init_5, G_N_ELEMENTS(init_5),
867 generic_write_regv_cb, ssm);
868 break;
872 static void activate_sm_complete(struct fpi_ssm *ssm)
874 struct fp_img_dev *dev = ssm->priv;
875 fp_dbg("status %d", ssm->error);
876 fpi_imgdev_activate_complete(dev, ssm->error);
878 if (!ssm->error)
879 start_finger_detection(dev);
880 fpi_ssm_free(ssm);
883 static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
885 struct aes2501_dev *aesdev = dev->priv;
886 struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state,
887 ACTIVATE_NUM_STATES);
888 ssm->priv = dev;
889 aesdev->read_regs_retry_count = 0;
890 fpi_ssm_start(ssm, activate_sm_complete);
891 return 0;
894 static void dev_deactivate(struct fp_img_dev *dev)
896 struct aes2501_dev *aesdev = dev->priv;
897 /* FIXME: audit cancellation points, probably need more, specifically
898 * in error handling paths? */
899 aesdev->deactivating = TRUE;
902 static void complete_deactivation(struct fp_img_dev *dev)
904 struct aes2501_dev *aesdev = dev->priv;
905 fp_dbg("");
907 /* FIXME: if we're in the middle of a scan, we should cancel the scan.
908 * maybe we can do this with a master reset, unconditionally? */
910 aesdev->deactivating = FALSE;
911 g_slist_free(aesdev->strips);
912 aesdev->strips = NULL;
913 aesdev->strips_len = 0;
914 fpi_imgdev_deactivate_complete(dev);
917 static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
919 /* FIXME check endpoints */
920 int r;
922 r = libusb_claim_interface(dev->udev, 0);
923 if (r < 0) {
924 fp_err("could not claim interface 0");
925 return r;
928 dev->priv = g_malloc0(sizeof(struct aes2501_dev));
929 fpi_imgdev_open_complete(dev, 0);
930 return 0;
933 static void dev_deinit(struct fp_img_dev *dev)
935 g_free(dev->priv);
936 libusb_release_interface(dev->udev, 0);
937 fpi_imgdev_close_complete(dev);
940 static const struct usb_id id_table[] = {
941 { .vendor = 0x08ff, .product = 0x2500 }, /* AES2500 */
942 { .vendor = 0x08ff, .product = 0x2580 }, /* AES2501 */
943 { 0, 0, 0, },
946 struct fp_img_driver aes2501_driver = {
947 .driver = {
948 .id = 4,
949 .name = FP_COMPONENT,
950 .full_name = "AuthenTec AES2501",
951 .id_table = id_table,
952 .scan_type = FP_SCAN_TYPE_SWIPE,
954 .flags = 0,
955 .img_height = -1,
956 .img_width = 192,
958 .open = dev_init,
959 .close = dev_deinit,
960 .activate = dev_activate,
961 .deactivate = dev_deactivate,