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"
32 #include <fp_internal.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
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 ******/
66 uint8_t read_regs_retry_count
;
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
;
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
;
88 if (transfer
->status
!= LIBUSB_TRANSFER_COMPLETED
) {
90 } else if (transfer
->length
!= transfer
->actual_length
) {
94 retdata
= transfer
->buffer
;
97 rdata
->callback(rdata
->dev
, r
, retdata
, rdata
->user_data
);
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
;
110 g_free(rdata
->regwrite
);
114 transfer
= libusb_alloc_transfer(0);
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
);
127 libusb_free_transfer(transfer
);
134 rdata
->callback(dev
, result
, NULL
, rdata
->user_data
);
138 static void read_regs(struct fp_img_dev
*dev
, aes2501_read_regs_cb callback
,
141 /* FIXME: regwrite is dynamic because of asynchronity. is this really
143 struct aes_regwrite
*regwrite
= g_malloc(sizeof(*regwrite
));
144 struct aes2501_read_regs
*rdata
= g_malloc(sizeof(*rdata
));
147 regwrite
->reg
= AES2501_REG_CTRL2
;
148 regwrite
->value
= AES2501_CTRL2_READ_REGS
;
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");
166 if (!(FIRST_AES2501_REG
<= target
&& target
<= LAST_AES2501_REG
)) {
167 fp_err("out of range");
171 target
-= FIRST_AES2501_REG
;
173 return data
[target
+ 1];
176 static void generic_write_regv_cb(struct fp_img_dev
*dev
, int result
,
179 struct fpi_ssm
*ssm
= user_data
;
181 fpi_ssm_next_state(ssm
);
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
);
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);
211 fpi_ssm_mark_aborted(ssm
, -ENOMEM
);
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
);
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
)
233 uint16_t *histogram
= (uint16_t *)(data
+ 1);
238 if (threshold
> 0x0f)
241 /* FIXME endianness */
242 for (i
= threshold
; i
< 16; i
++)
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
)
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 */
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 */
269 if (error
< *min_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
;
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
;
291 /* Rotating given data by 90 degrees
292 * Taken from document describing aes2501 image format
293 * TODO: move reversing detection here */
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
);
301 output
-= FRAME_SIZE
;
303 output
+= FRAME_SIZE
;
304 list_entry
= g_slist_next(list_entry
);
307 /* Detecting where frames overlaped */
309 for (frame
= 1; frame
< num_strips
; frame
++) {
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
);
322 static void assemble_and_submit_image(struct fp_img_dev
*dev
)
324 struct aes2501_dev
*aesdev
= dev
->priv
;
327 unsigned int errors_sum
, r_errors_sum
;
329 BUG_ON(aesdev
->strips_len
== 0);
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");
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 },
383 { AES2501_REG_TREGC
, AES2501_TREGC_ENABLE
},
384 { AES2501_REG_TREGD
, 0x1a },
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
;
400 if (transfer
->status
!= LIBUSB_TRANSFER_COMPLETED
) {
401 fpi_imgdev_session_error(dev
, -EIO
);
403 } else if (transfer
->length
!= transfer
->actual_length
) {
404 fpi_imgdev_session_error(dev
, -EPROTO
);
408 /* examine histogram to determine finger presence */
409 for (i
= 1; i
< 9; i
++)
410 sum
+= (data
[i
] & 0xf) + (data
[i
] >> 4);
412 /* finger present, start capturing */
413 fpi_imgdev_report_finger_status(dev
, TRUE
);
416 /* no finger, poll for a new histogram */
417 start_finger_detection(dev
);
422 libusb_free_transfer(transfer
);
425 static void finger_det_reqs_cb(struct fp_img_dev
*dev
, int result
,
428 struct libusb_transfer
*transfer
;
433 fpi_imgdev_session_error(dev
, result
);
437 transfer
= libusb_alloc_transfer(0);
439 fpi_imgdev_session_error(dev
, -ENOMEM
);
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
);
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
;
460 if (aesdev
->deactivating
) {
461 complete_deactivation(dev
);
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
},
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 },
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
,
537 CAPTURE_WRITE_REQS_2
,
539 CAPTURE_REQUEST_STRIP
,
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
;
554 if (transfer
->status
!= LIBUSB_TRANSFER_COMPLETED
) {
555 fpi_ssm_mark_aborted(ssm
, -EIO
);
557 } else if (transfer
->length
!= transfer
->actual_length
) {
558 fpi_ssm_mark_aborted(ssm
, -EPROTO
);
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,
571 fpi_ssm_mark_aborted(ssm
, threshold
);
575 sum
= sum_histogram_values(data
+ 1 + 192*8, threshold
& 0x0f);
577 fpi_ssm_mark_aborted(ssm
, sum
);
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 */
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
);
595 /* obtain next strip */
596 fpi_ssm_jump_to_state(ssm
, CAPTURE_REQUEST_STRIP
);
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
;
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
);
615 case CAPTURE_READ_DATA_1
:
616 generic_read_ignore_data(ssm
, 159);
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
);
622 case CAPTURE_READ_DATA_2
:
623 generic_read_ignore_data(ssm
, 159);
625 case CAPTURE_REQUEST_STRIP
:
626 if (aesdev
->deactivating
)
627 fpi_ssm_mark_completed(ssm
);
629 aes_write_regv(dev
, strip_scan_reqs
, G_N_ELEMENTS(strip_scan_reqs
),
630 generic_write_regv_cb
, ssm
);
632 case CAPTURE_READ_STRIP
: ;
633 struct libusb_transfer
*transfer
= libusb_alloc_transfer(0);
637 fpi_ssm_mark_aborted(ssm
, -ENOMEM
);
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
);
648 libusb_free_transfer(transfer
);
649 fpi_ssm_mark_aborted(ssm
, r
);
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
;
661 if (aesdev
->deactivating
)
662 complete_deactivation(dev
);
664 fpi_imgdev_session_error(dev
, ssm
->error
);
666 start_finger_detection(dev
);
670 static void start_capture(struct fp_img_dev
*dev
)
672 struct aes2501_dev
*aesdev
= dev
->priv
;
675 if (aesdev
->deactivating
) {
676 complete_deactivation(dev
);
680 ssm
= fpi_ssm_new(dev
->dev
, capture_run_state
, CAPTURE_NUM_STATES
);
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
},
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 },
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
[] = {
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 },
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
[] = {
763 { AES2501_REG_CTRL1
, AES2501_CTRL1_MASTER_RESET
},
764 { AES2501_REG_EXCITCTRL
, 0x40 },
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
{
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
;
798 fpi_ssm_mark_aborted(ssm
, status
);
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
);
804 fpi_ssm_next_state(ssm
);
808 static void activate_init3_cb(struct fp_img_dev
*dev
, int result
,
811 struct fpi_ssm
*ssm
= user_data
;
813 fpi_ssm_jump_to_state(ssm
, READ_REGS
);
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:
829 aes_write_regv(init_2);
830 read_regs(into buffer);
832 while (buffer[0x5f] == 0x6b) {
833 aes_write_regv(init_3);
834 read_regs(into buffer);
838 aes_write_regv(init_4);
841 switch (ssm
->cur_state
) {
843 aes_write_regv(dev
, init_1
, G_N_ELEMENTS(init_1
),
844 generic_write_regv_cb
, ssm
);
847 fp_dbg("read data 1");
848 generic_read_ignore_data(ssm
, 20);
851 aes_write_regv(dev
, init_2
, G_N_ELEMENTS(init_2
),
852 generic_write_regv_cb
, ssm
);
855 read_regs(dev
, activate_read_regs_cb
, ssm
);
858 aes_write_regv(dev
, init_4
, G_N_ELEMENTS(init_4
),
859 activate_init3_cb
, ssm
);
862 aes_write_regv(dev
, init_4
, G_N_ELEMENTS(init_4
),
863 generic_write_regv_cb
, ssm
);
866 aes_write_regv(dev
, init_5
, G_N_ELEMENTS(init_5
),
867 generic_write_regv_cb
, ssm
);
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
);
879 start_finger_detection(dev
);
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
);
889 aesdev
->read_regs_retry_count
= 0;
890 fpi_ssm_start(ssm
, activate_sm_complete
);
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
;
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 */
922 r
= libusb_claim_interface(dev
->udev
, 0);
924 fp_err("could not claim interface 0");
928 dev
->priv
= g_malloc0(sizeof(struct aes2501_dev
));
929 fpi_imgdev_open_complete(dev
, 0);
933 static void dev_deinit(struct fp_img_dev
*dev
)
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 */
946 struct fp_img_driver aes2501_driver
= {
949 .name
= FP_COMPONENT
,
950 .full_name
= "AuthenTec AES2501",
951 .id_table
= id_table
,
952 .scan_type
= FP_SCAN_TYPE_SWIPE
,
960 .activate
= dev_activate
,
961 .deactivate
= dev_deactivate
,