1 /*
2 * AuthenTec AES1660/AES2660 common routines
3 * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
4 * Copyright (C) 2007 Cyrille Bagard
5 * Copyright (C) 2007-2008,2012 Vasily Khoruzhick
6 *
7 * Based on AES2550 driver
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 "aesX660"
25
26 #include <stdio.h>
27
28 #include <errno.h>
29 #include <string.h>
30
31 #include <libusb.h>
32
33 #include <assembling.h>
34 #include <aeslib.h>
35 #include <fp_internal.h>
36
37 #include "aesx660.h"
38
39 static void start_capture(struct fp_img_dev *dev);
40 static void complete_deactivation(struct fp_img_dev *dev);
41
42 #define EP_IN (1 | LIBUSB_ENDPOINT_IN)
43 #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
44 #define BULK_TIMEOUT 4000
45 #define FRAME_HEIGHT AESX660_FRAME_HEIGHT
46
47 #define min(a, b) (((a) < (b)) ? (a) : (b))
48
aesX660_send_cmd_timeout(struct fpi_ssm * ssm,const unsigned char * cmd,size_t cmd_len,libusb_transfer_cb_fn callback,int timeout)49 static void aesX660_send_cmd_timeout(struct fpi_ssm *ssm, const unsigned char *cmd,
50 size_t cmd_len, libusb_transfer_cb_fn callback, int timeout)
51 {
52 struct fp_img_dev *dev = ssm->priv;
53 struct libusb_transfer *transfer = libusb_alloc_transfer(0);
54 int r;
55
56 if (!transfer) {
57 fpi_ssm_mark_aborted(ssm, -ENOMEM);
58 return;
59 }
60
61 libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT,
62 (unsigned char *)cmd, cmd_len,
63 callback, ssm, timeout);
64 r = libusb_submit_transfer(transfer);
65 if (r < 0) {
66 fp_dbg("failed to submit transfer\n");
67 libusb_free_transfer(transfer);
68 fpi_ssm_mark_aborted(ssm, -ENOMEM);
69 }
70 }
71
aesX660_send_cmd(struct fpi_ssm * ssm,const unsigned char * cmd,size_t cmd_len,libusb_transfer_cb_fn callback)72 static void aesX660_send_cmd(struct fpi_ssm *ssm, const unsigned char *cmd,
73 size_t cmd_len, libusb_transfer_cb_fn callback)
74 {
75 return aesX660_send_cmd_timeout(ssm, cmd, cmd_len, callback, BULK_TIMEOUT);
76 }
77
aesX660_read_response(struct fpi_ssm * ssm,size_t buf_len,libusb_transfer_cb_fn callback)78 static void aesX660_read_response(struct fpi_ssm *ssm, size_t buf_len,
79 libusb_transfer_cb_fn callback)
80 {
81 struct fp_img_dev *dev = ssm->priv;
82 struct libusb_transfer *transfer = libusb_alloc_transfer(0);
83 unsigned char *data;
84 int r;
85
86 if (!transfer) {
87 fpi_ssm_mark_aborted(ssm, -ENOMEM);
88 return;
89 }
90
91 data = g_malloc(buf_len);
92 libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN,
93 data, buf_len,
94 callback, ssm, BULK_TIMEOUT);
95
96 r = libusb_submit_transfer(transfer);
97 if (r < 0) {
98 fp_dbg("Failed to submit rx transfer: %d\n", r);
99 g_free(data);
100 libusb_free_transfer(transfer);
101 fpi_ssm_mark_aborted(ssm, r);
102 }
103 }
104
aesX660_send_cmd_cb(struct libusb_transfer * transfer)105 static void aesX660_send_cmd_cb(struct libusb_transfer *transfer)
106 {
107 struct fpi_ssm *ssm = transfer->user_data;
108
109 if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
110 (transfer->length == transfer->actual_length)) {
111 fpi_ssm_next_state(ssm);
112 } else {
113 fp_dbg("tx transfer status: %d, actual_len: %.4x\n",
114 transfer->status, transfer->actual_length);
115 fpi_ssm_mark_aborted(ssm, -EIO);
116 }
117 libusb_free_transfer(transfer);
118 }
119
aesX660_read_calibrate_data_cb(struct libusb_transfer * transfer)120 static void aesX660_read_calibrate_data_cb(struct libusb_transfer *transfer)
121 {
122 struct fpi_ssm *ssm = transfer->user_data;
123 unsigned char *data = transfer->buffer;
124
125 if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
126 (transfer->length != transfer->actual_length)) {
127 fpi_ssm_mark_aborted(ssm, -EIO);
128 goto out;
129 }
130 /* Calibrate response was read correctly? */
131 if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE) {
132 fp_dbg("Bogus calibrate response: %.2x\n", data[0]);
133 fpi_ssm_mark_aborted(ssm, -EPROTO);
134 goto out;
135 }
136
137 fpi_ssm_next_state(ssm);
138 out:
139 g_free(transfer->buffer);
140 libusb_free_transfer(transfer);
141 }
142
143 /****** FINGER PRESENCE DETECTION ******/
144
145 enum finger_det_states {
146 FINGER_DET_SEND_LED_CMD,
147 FINGER_DET_SEND_FD_CMD,
148 FINGER_DET_READ_FD_DATA,
149 FINGER_DET_SET_IDLE,
150 FINGER_DET_NUM_STATES,
151 };
152
finger_det_read_fd_data_cb(struct libusb_transfer * transfer)153 static void finger_det_read_fd_data_cb(struct libusb_transfer *transfer)
154 {
155 struct fpi_ssm *ssm = transfer->user_data;
156 struct fp_img_dev *dev = ssm->priv;
157 struct aesX660_dev *aesdev = dev->priv;
158 unsigned char *data = transfer->buffer;
159
160 aesdev->fd_data_transfer = NULL;
161
162 if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
163 fp_dbg("Cancelling transfer...\n");
164 fpi_ssm_next_state(ssm);
165 goto out;
166 }
167
168 if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
169 (transfer->length != transfer->actual_length)) {
170 fp_dbg("Failed to read FD data\n");
171 fpi_ssm_mark_aborted(ssm, -EIO);
172 goto out;
173 }
174
175 if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE) {
176 fp_dbg("Bogus FD response: %.2x\n", data[0]);
177 fpi_ssm_mark_aborted(ssm, -EPROTO);
178 goto out;
179 }
180
181 if (data[AESX660_FINGER_PRESENT_OFFSET] == AESX660_FINGER_PRESENT || aesdev->deactivating) {
182 /* Finger present or we're deactivating... */
183 fpi_ssm_next_state(ssm);
184 } else {
185 fp_dbg("Wait for finger returned %.2x as result\n",
186 data[AESX660_FINGER_PRESENT_OFFSET]);
187 fpi_ssm_jump_to_state(ssm, FINGER_DET_SEND_FD_CMD);
188 }
189 out:
190 g_free(data);
191 libusb_free_transfer(transfer);
192 }
193
finger_det_set_idle_cmd_cb(struct libusb_transfer * transfer)194 static void finger_det_set_idle_cmd_cb(struct libusb_transfer *transfer)
195 {
196 struct fpi_ssm *ssm = transfer->user_data;
197
198 if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
199 (transfer->length == transfer->actual_length)) {
200 fpi_ssm_mark_completed(ssm);
201 } else {
202 fpi_ssm_mark_aborted(ssm, -EIO);
203 }
204 libusb_free_transfer(transfer);
205 }
206
finger_det_sm_complete(struct fpi_ssm * ssm)207 static void finger_det_sm_complete(struct fpi_ssm *ssm)
208 {
209 struct fp_img_dev *dev = ssm->priv;
210 struct aesX660_dev *aesdev = dev->priv;
211 int err = ssm->error;
212
213 fp_dbg("Finger detection completed");
214 fpi_imgdev_report_finger_status(dev, TRUE);
215 fpi_ssm_free(ssm);
216
217 if (aesdev->deactivating)
218 complete_deactivation(dev);
219 else if (err)
220 fpi_imgdev_session_error(dev, err);
221 else {
222 fpi_imgdev_report_finger_status(dev, TRUE);
223 start_capture(dev);
224 }
225 }
226
finger_det_run_state(struct fpi_ssm * ssm)227 static void finger_det_run_state(struct fpi_ssm *ssm)
228 {
229 switch (ssm->cur_state) {
230 case FINGER_DET_SEND_LED_CMD:
231 aesX660_send_cmd(ssm, led_blink_cmd, sizeof(led_blink_cmd),
232 aesX660_send_cmd_cb);
233 break;
234 case FINGER_DET_SEND_FD_CMD:
235 aesX660_send_cmd_timeout(ssm, wait_for_finger_cmd, sizeof(wait_for_finger_cmd),
236 aesX660_send_cmd_cb, 0);
237 break;
238 case FINGER_DET_READ_FD_DATA:
239 /* Should return 4 byte of response */
240 aesX660_read_response(ssm, 4, finger_det_read_fd_data_cb);
241 break;
242 case FINGER_DET_SET_IDLE:
243 aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd),
244 finger_det_set_idle_cmd_cb);
245 break;
246 }
247 }
248
start_finger_detection(struct fp_img_dev * dev)249 static void start_finger_detection(struct fp_img_dev *dev)
250 {
251 struct fpi_ssm *ssm;
252 struct aesX660_dev *aesdev = dev->priv;
253
254 if (aesdev->deactivating) {
255 complete_deactivation(dev);
256 return;
257 }
258
259 ssm = fpi_ssm_new(dev->dev, finger_det_run_state, FINGER_DET_NUM_STATES);
260 ssm->priv = dev;
261 fpi_ssm_start(ssm, finger_det_sm_complete);
262 }
263
264 /****** CAPTURE ******/
265
266 enum capture_states {
267 CAPTURE_SEND_LED_CMD,
268 CAPTURE_SEND_CAPTURE_CMD,
269 CAPTURE_READ_STRIPE_DATA,
270 CAPTURE_SET_IDLE,
271 CAPTURE_NUM_STATES,
272 };
273
274 /* Returns number of processed bytes */
process_stripe_data(struct fpi_ssm * ssm,unsigned char * data)275 static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data)
276 {
277 struct fpi_frame *stripe;
278 unsigned char *stripdata;
279 struct fp_img_dev *dev = ssm->priv;
280 struct aesX660_dev *aesdev = dev->priv;
281
282 stripe = g_malloc(aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */
283 stripdata = stripe->data;
284
285 fp_dbg("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET],
286 data[AESX660_LAST_FRAME_OFFSET]);
287
288 stripe->delta_x = (int8_t)data[AESX660_FRAME_DELTA_X_OFFSET];
289 stripe->delta_y = -(int8_t)data[AESX660_FRAME_DELTA_Y_OFFSET];
290 fp_dbg("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y);
291
292 if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK) {
293 memcpy(stripdata, data + AESX660_IMAGE_OFFSET, aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2);
294
295 aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
296 aesdev->strips_len++;
297 return (data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT);
298 } else {
299 return 0;
300 }
301
302 }
303
capture_set_idle_cmd_cb(struct libusb_transfer * transfer)304 static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer)
305 {
306 struct fpi_ssm *ssm = transfer->user_data;
307 struct fp_img_dev *dev = ssm->priv;
308 struct aesX660_dev *aesdev = dev->priv;
309
310 if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
311 (transfer->length == transfer->actual_length)) {
312 struct fp_img *img;
313
314 aesdev->strips = g_slist_reverse(aesdev->strips);
315 img = fpi_assemble_frames(aesdev->assembling_ctx, aesdev->strips, aesdev->strips_len);
316 img->flags |= aesdev->extra_img_flags;
317 g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL);
318 g_slist_free(aesdev->strips);
319 aesdev->strips = NULL;
320 aesdev->strips_len = 0;
321 fpi_imgdev_image_captured(dev, img);
322 fpi_imgdev_report_finger_status(dev, FALSE);
323 fpi_ssm_mark_completed(ssm);
324 } else {
325 fpi_ssm_mark_aborted(ssm, -EIO);
326 }
327 libusb_free_transfer(transfer);
328 }
329
capture_read_stripe_data_cb(struct libusb_transfer * transfer)330 static void capture_read_stripe_data_cb(struct libusb_transfer *transfer)
331 {
332 struct fpi_ssm *ssm = transfer->user_data;
333 struct fp_img_dev *dev = ssm->priv;
334 struct aesX660_dev *aesdev = dev->priv;
335 unsigned char *data = transfer->buffer;
336 int finger_missing = 0;
337 size_t copied, actual_len = transfer->actual_length;
338
339 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
340 fpi_ssm_mark_aborted(ssm, -EIO);
341 goto out;
342 }
343
344 fp_dbg("Got %d bytes of data", actual_len);
345 do {
346 copied = min(aesdev->buffer_max - aesdev->buffer_size, actual_len);
347 memcpy(aesdev->buffer + aesdev->buffer_size,
348 data,
349 copied);
350 actual_len -= copied;
351 data += copied;
352 aesdev->buffer_size += copied;
353 fp_dbg("Copied %.4x bytes into internal buffer",
354 copied);
355 if (aesdev->buffer_size == aesdev->buffer_max) {
356 if (aesdev->buffer_max == AESX660_HEADER_SIZE) {
357 aesdev->buffer_max = aesdev->buffer[AESX660_RESPONSE_SIZE_LSB_OFFSET] +
358 (aesdev->buffer[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8) + AESX660_HEADER_SIZE;
359 fp_dbg("Got frame, type %.2x size %.4x",
360 aesdev->buffer[AESX660_RESPONSE_TYPE_OFFSET],
361 aesdev->buffer_max);
362 continue;
363 } else {
364 finger_missing |= process_stripe_data(ssm, aesdev->buffer);
365 aesdev->buffer_max = AESX660_HEADER_SIZE;
366 aesdev->buffer_size = 0;
367 }
368 }
369 } while (actual_len);
370
371 fp_dbg("finger %s\n", finger_missing ? "missing" : "present");
372
373 if (finger_missing) {
374 fpi_ssm_next_state(ssm);
375 } else {
376 fpi_ssm_jump_to_state(ssm, CAPTURE_READ_STRIPE_DATA);
377 }
378 out:
379 g_free(transfer->buffer);
380 libusb_free_transfer(transfer);
381 }
382
capture_run_state(struct fpi_ssm * ssm)383 static void capture_run_state(struct fpi_ssm *ssm)
384 {
385 struct fp_img_dev *dev = ssm->priv;
386 struct aesX660_dev *aesdev = dev->priv;
387
388 switch (ssm->cur_state) {
389 case CAPTURE_SEND_LED_CMD:
390 aesX660_send_cmd(ssm, led_solid_cmd, sizeof(led_solid_cmd),
391 aesX660_send_cmd_cb);
392 break;
393 case CAPTURE_SEND_CAPTURE_CMD:
394 aesdev->buffer_size = 0;
395 aesdev->buffer_max = AESX660_HEADER_SIZE;
396 aesX660_send_cmd(ssm, aesdev->start_imaging_cmd,
397 aesdev->start_imaging_cmd_len,
398 aesX660_send_cmd_cb);
399 break;
400 case CAPTURE_READ_STRIPE_DATA:
401 aesX660_read_response(ssm, AESX660_BULK_TRANSFER_SIZE,
402 capture_read_stripe_data_cb);
403 break;
404 case CAPTURE_SET_IDLE:
405 fp_dbg("Got %d frames\n", aesdev->strips_len);
406 aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd),
407 capture_set_idle_cmd_cb);
408 break;
409 }
410 }
411
capture_sm_complete(struct fpi_ssm * ssm)412 static void capture_sm_complete(struct fpi_ssm *ssm)
413 {
414 struct fp_img_dev *dev = ssm->priv;
415 struct aesX660_dev *aesdev = dev->priv;
416 int err = ssm->error;
417
418 fp_dbg("Capture completed");
419 fpi_ssm_free(ssm);
420
421 if (aesdev->deactivating)
422 complete_deactivation(dev);
423 else if (err)
424 fpi_imgdev_session_error(dev, err);
425 else
426 start_finger_detection(dev);
427 }
428
start_capture(struct fp_img_dev * dev)429 static void start_capture(struct fp_img_dev *dev)
430 {
431 struct aesX660_dev *aesdev = dev->priv;
432 struct fpi_ssm *ssm;
433
434 if (aesdev->deactivating) {
435 complete_deactivation(dev);
436 return;
437 }
438
439 ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES);
440 fp_dbg("");
441 ssm->priv = dev;
442 fpi_ssm_start(ssm, capture_sm_complete);
443 }
444
445 /****** INITIALIZATION/DEINITIALIZATION ******/
446
447 enum activate_states {
448 ACTIVATE_SET_IDLE,
449 ACTIVATE_SEND_READ_ID_CMD,
450 ACTIVATE_READ_ID,
451 ACTIVATE_SEND_CALIBRATE_CMD,
452 ACTIVATE_READ_CALIBRATE_DATA,
453 ACTIVATE_SEND_INIT_CMD,
454 ACTIVATE_READ_INIT_RESPONSE,
455 ACTIVATE_NUM_STATES,
456 };
457
activate_read_id_cb(struct libusb_transfer * transfer)458 static void activate_read_id_cb(struct libusb_transfer *transfer)
459 {
460 struct fpi_ssm *ssm = transfer->user_data;
461 struct fp_img_dev *dev = ssm->priv;
462 struct aesX660_dev *aesdev = dev->priv;
463 unsigned char *data = transfer->buffer;
464
465 if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
466 (transfer->length != transfer->actual_length)) {
467 fp_dbg("read_id cmd failed\n");
468 fpi_ssm_mark_aborted(ssm, -EIO);
469 goto out;
470 }
471 /* ID was read correctly */
472 if (data[0] == 0x07) {
473 fp_dbg("Sensor device id: %.2x%2x, bcdDevice: %.2x.%.2x, init status: %.2x\n",
474 data[4], data[3], data[5], data[6], data[7]);
475 } else {
476 fp_dbg("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
477 fpi_ssm_mark_aborted(ssm, -EPROTO);
478 goto out;
479 }
480
481 switch (aesdev->init_seq_idx) {
482 case 0:
483 aesdev->init_seq = aesdev->init_seqs[0];
484 aesdev->init_seq_len = aesdev->init_seqs_len[0];
485 aesdev->init_seq_idx = 1;
486 aesdev->init_cmd_idx = 0;
487 /* Do calibration only after 1st init sequence */
488 fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_INIT_CMD);
489 break;
490 case 1:
491 aesdev->init_seq = aesdev->init_seqs[1];
492 aesdev->init_seq_len = aesdev->init_seqs_len[1];
493 aesdev->init_seq_idx = 2;
494 aesdev->init_cmd_idx = 0;
495 fpi_ssm_next_state(ssm);
496 break;
497 default:
498 fp_dbg("Failed to init device! init status: %.2x\n", data[7]);
499 fpi_ssm_mark_aborted(ssm, -EPROTO);
500 break;
501
502 }
503
504 out:
505 g_free(transfer->buffer);
506 libusb_free_transfer(transfer);
507 }
508
activate_read_init_cb(struct libusb_transfer * transfer)509 static void activate_read_init_cb(struct libusb_transfer *transfer)
510 {
511 struct fpi_ssm *ssm = transfer->user_data;
512 struct fp_img_dev *dev = ssm->priv;
513 struct aesX660_dev *aesdev = dev->priv;
514 unsigned char *data = transfer->buffer;
515
516 fp_dbg("read_init_cb\n");
517
518 if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) ||
519 (transfer->length != transfer->actual_length)) {
520 fp_dbg("read_init transfer status: %d, actual_len: %d\n", transfer->status, transfer->actual_length);
521 fpi_ssm_mark_aborted(ssm, -EIO);
522 goto out;
523 }
524 /* ID was read correctly */
525 if (data[0] != 0x42 || data[3] != 0x01) {
526 fp_dbg("Bogus read init response: %.2x %.2x\n", data[0],
527 data[3]);
528 fpi_ssm_mark_aborted(ssm, -EPROTO);
529 goto out;
530 }
531 aesdev->init_cmd_idx++;
532 if (aesdev->init_cmd_idx == aesdev->init_seq_len) {
533 if (aesdev->init_seq_idx < 2)
534 fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_READ_ID_CMD);
535 else
536 fpi_ssm_mark_completed(ssm);
537 goto out;
538 }
539
540 fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_INIT_CMD);
541 out:
542 g_free(transfer->buffer);
543 libusb_free_transfer(transfer);
544 }
545
activate_run_state(struct fpi_ssm * ssm)546 static void activate_run_state(struct fpi_ssm *ssm)
547 {
548 struct fp_img_dev *dev = ssm->priv;
549 struct aesX660_dev *aesdev = dev->priv;
550
551 switch (ssm->cur_state) {
552 case ACTIVATE_SET_IDLE:
553 aesdev->init_seq_idx = 0;
554 fp_dbg("Activate: set idle\n");
555 aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd),
556 aesX660_send_cmd_cb);
557 break;
558 case ACTIVATE_SEND_READ_ID_CMD:
559 fp_dbg("Activate: read ID\n");
560 aesX660_send_cmd(ssm, read_id_cmd, sizeof(read_id_cmd),
561 aesX660_send_cmd_cb);
562 break;
563 case ACTIVATE_READ_ID:
564 /* Should return 8-byte response */
565 aesX660_read_response(ssm, 8, activate_read_id_cb);
566 break;
567 case ACTIVATE_SEND_INIT_CMD:
568 fp_dbg("Activate: send init seq #%d cmd #%d\n",
569 aesdev->init_seq_idx,
570 aesdev->init_cmd_idx);
571 aesX660_send_cmd(ssm,
572 aesdev->init_seq[aesdev->init_cmd_idx].cmd,
573 aesdev->init_seq[aesdev->init_cmd_idx].len,
574 aesX660_send_cmd_cb);
575 break;
576 case ACTIVATE_READ_INIT_RESPONSE:
577 fp_dbg("Activate: read init response\n");
578 /* Should return 4-byte response */
579 aesX660_read_response(ssm, 4, activate_read_init_cb);
580 break;
581 case ACTIVATE_SEND_CALIBRATE_CMD:
582 aesX660_send_cmd(ssm, calibrate_cmd, sizeof(calibrate_cmd),
583 aesX660_send_cmd_cb);
584 break;
585 case ACTIVATE_READ_CALIBRATE_DATA:
586 /* Should return 4-byte response */
587 aesX660_read_response(ssm, 4, aesX660_read_calibrate_data_cb);
588 break;
589 }
590 }
591
activate_sm_complete(struct fpi_ssm * ssm)592 static void activate_sm_complete(struct fpi_ssm *ssm)
593 {
594 struct fp_img_dev *dev = ssm->priv;
595 int err = ssm->error;
596 fp_dbg("status %d", err);
597 fpi_imgdev_activate_complete(dev, err);
598 fpi_ssm_free(ssm);
599
600 if (!err)
601 start_finger_detection(dev);
602 }
603
aesX660_dev_activate(struct fp_img_dev * dev,enum fp_imgdev_state state)604 int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
605 {
606 struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state,
607 ACTIVATE_NUM_STATES);
608 ssm->priv = dev;
609 fpi_ssm_start(ssm, activate_sm_complete);
610 return 0;
611 }
612
aesX660_dev_deactivate(struct fp_img_dev * dev)613 void aesX660_dev_deactivate(struct fp_img_dev *dev)
614 {
615 struct aesX660_dev *aesdev = dev->priv;
616
617 if (aesdev->fd_data_transfer)
618 libusb_cancel_transfer(aesdev->fd_data_transfer);
619
620 aesdev->deactivating = TRUE;
621 }
622
complete_deactivation(struct fp_img_dev * dev)623 static void complete_deactivation(struct fp_img_dev *dev)
624 {
625 struct aesX660_dev *aesdev = dev->priv;
626 fp_dbg("");
627
628 aesdev->deactivating = FALSE;
629 g_slist_free(aesdev->strips);
630 aesdev->strips = NULL;
631 aesdev->strips_len = 0;
632 fpi_imgdev_deactivate_complete(dev);
633 }
634