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