1 /*
2  * Validity Sensors, Inc. VFS5011 Fingerprint Reader driver for libfprint
3  * Copyright (C) 2013 Arseniy Lartsev <arseniy@chalmers.se>
4  *                    AceLan Kao <acelan.kao@canonical.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdio.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <libusb.h>
25 #include <fp_internal.h>
26 #include <assembling.h>
27 #include "driver_ids.h"
28 
29 #include "vfs5011_proto.h"
30 
31 /* =================== sync/async USB transfer sequence ==================== */
32 
33 enum {
34 	ACTION_SEND,
35 	ACTION_RECEIVE,
36 };
37 
38 struct usb_action {
39 	int type;
40 	const char *name;
41 	int endpoint;
42 	int size;
43 	unsigned char *data;
44 	int correct_reply_size;
45 };
46 
47 #define SEND(ENDPOINT, COMMAND) \
48 { \
49 	.type = ACTION_SEND, \
50 	.endpoint = ENDPOINT, \
51 	.name = #COMMAND, \
52 	.size = sizeof(COMMAND), \
53 	.data = COMMAND \
54 },
55 
56 #define RECV(ENDPOINT, SIZE) \
57 { \
58 	.type = ACTION_RECEIVE, \
59 	.endpoint = ENDPOINT, \
60 	.size = SIZE, \
61 	.data = NULL \
62 },
63 
64 #define RECV_CHECK(ENDPOINT, SIZE, EXPECTED) \
65 { \
66 	.type = ACTION_RECEIVE, \
67 	.endpoint = ENDPOINT, \
68 	.size = SIZE, \
69 	.data = EXPECTED, \
70 	.correct_reply_size = sizeof(EXPECTED) \
71 },
72 
73 struct usbexchange_data {
74 	int stepcount;
75 	struct fp_img_dev *device;
76 	struct usb_action *actions;
77 	void *receive_buf;
78 	int timeout;
79 };
80 
81 static void start_scan(struct fp_img_dev *dev);
82 
async_send_cb(struct libusb_transfer * transfer)83 static void async_send_cb(struct libusb_transfer *transfer)
84 {
85 	struct fpi_ssm *ssm = transfer->user_data;
86 	struct usbexchange_data *data = (struct usbexchange_data *)ssm->priv;
87 	struct usb_action *action;
88 
89 	if (ssm->cur_state >= data->stepcount) {
90 		fp_err("Radiation detected!");
91 		fpi_imgdev_session_error(data->device, -EINVAL);
92 		fpi_ssm_mark_aborted(ssm, -EINVAL);
93 		goto out;
94 	}
95 
96 	action = &data->actions[ssm->cur_state];
97 	if (action->type != ACTION_SEND) {
98 		fp_err("Radiation detected!");
99 		fpi_imgdev_session_error(data->device, -EINVAL);
100 		fpi_ssm_mark_aborted(ssm, -EINVAL);
101 		goto out;
102 	}
103 
104 	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
105 		/* Transfer not completed, return IO error */
106 		fp_err("transfer not completed, status = %d", transfer->status);
107 		fpi_imgdev_session_error(data->device, -EIO);
108 		fpi_ssm_mark_aborted(ssm, -EIO);
109 		goto out;
110 	}
111 	if (transfer->length != transfer->actual_length) {
112 		/* Data sended mismatch with expected, return protocol error */
113 		fp_err("length mismatch, got %d, expected %d",
114 			transfer->actual_length, transfer->length);
115 		fpi_imgdev_session_error(data->device, -EIO);
116 		fpi_ssm_mark_aborted(ssm, -EIO);
117 		goto out;
118 	}
119 
120 	/* success */
121 	fpi_ssm_next_state(ssm);
122 
123 out:
124 	libusb_free_transfer(transfer);
125 }
126 
async_recv_cb(struct libusb_transfer * transfer)127 static void async_recv_cb(struct libusb_transfer *transfer)
128 {
129 	struct fpi_ssm *ssm = transfer->user_data;
130 	struct usbexchange_data *data = (struct usbexchange_data *)ssm->priv;
131 	struct usb_action *action;
132 
133 	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
134 		/* Transfer not completed, return IO error */
135 		fp_err("transfer not completed, status = %d", transfer->status);
136 		fpi_imgdev_session_error(data->device, -EIO);
137 		fpi_ssm_mark_aborted(ssm, -EIO);
138 		goto out;
139 	}
140 
141 	if (ssm->cur_state >= data->stepcount) {
142 		fp_err("Radiation detected!");
143 		fpi_imgdev_session_error(data->device, -EINVAL);
144 		fpi_ssm_mark_aborted(ssm, -EINVAL);
145 		goto out;
146 	}
147 
148 	action = &data->actions[ssm->cur_state];
149 	if (action->type != ACTION_RECEIVE) {
150 		fp_err("Radiation detected!");
151 		fpi_imgdev_session_error(data->device, -EINVAL);
152 		fpi_ssm_mark_aborted(ssm, -EINVAL);
153 		goto out;
154 	}
155 
156 	if (action->data != NULL) {
157 		if (transfer->actual_length != action->correct_reply_size) {
158 			fp_err("Got %d bytes instead of %d",
159 				transfer->actual_length,
160 				action->correct_reply_size);
161 			fpi_imgdev_session_error(data->device, -EIO);
162 			fpi_ssm_mark_aborted(ssm, -EIO);
163 			goto out;
164 		}
165 		if (memcmp(transfer->buffer, action->data,
166 					action->correct_reply_size) != 0) {
167 			fp_dbg("Wrong reply:");
168 			fpi_imgdev_session_error(data->device, -EIO);
169 			fpi_ssm_mark_aborted(ssm, -EIO);
170 			goto out;
171 		}
172 	} else
173 		fp_dbg("Got %d bytes out of %d", transfer->actual_length,
174 		       transfer->length);
175 
176 	fpi_ssm_next_state(ssm);
177 out:
178 	libusb_free_transfer(transfer);
179 }
180 
usbexchange_loop(struct fpi_ssm * ssm)181 static void usbexchange_loop(struct fpi_ssm *ssm)
182 {
183 	struct usbexchange_data *data = (struct usbexchange_data *)ssm->priv;
184 	if (ssm->cur_state >= data->stepcount) {
185 		fp_err("Bug detected: state %d out of range, only %d steps",
186 				ssm->cur_state, data->stepcount);
187 		fpi_imgdev_session_error(data->device, -EINVAL);
188 		fpi_ssm_mark_aborted(ssm, -EINVAL);
189 		return;
190 	}
191 
192 	struct usb_action *action = &data->actions[ssm->cur_state];
193 	struct libusb_transfer *transfer;
194 	int ret = -EINVAL;
195 
196 	switch (action->type) {
197 	case ACTION_SEND:
198 		fp_dbg("Sending %s", action->name);
199 		transfer = libusb_alloc_transfer(0);
200 		if (transfer == NULL) {
201 			fp_err("Failed to allocate transfer");
202 			fpi_imgdev_session_error(data->device, -ENOMEM);
203 			fpi_ssm_mark_aborted(ssm, -ENOMEM);
204 			return;
205 		}
206 		libusb_fill_bulk_transfer(transfer, data->device->udev,
207 					  action->endpoint, action->data,
208 					  action->size, async_send_cb, ssm,
209 					  data->timeout);
210 		ret = libusb_submit_transfer(transfer);
211 		break;
212 
213 	case ACTION_RECEIVE:
214 		fp_dbg("Receiving %d bytes", action->size);
215 		transfer = libusb_alloc_transfer(0);
216 		if (transfer == NULL) {
217 			fp_err("Failed to allocate transfer");
218 			fpi_imgdev_session_error(data->device, -ENOMEM);
219 			fpi_ssm_mark_aborted(ssm, -ENOMEM);
220 			return;
221 		}
222 		libusb_fill_bulk_transfer(transfer, data->device->udev,
223 					  action->endpoint, data->receive_buf,
224 					  action->size, async_recv_cb, ssm,
225 					  data->timeout);
226 		ret = libusb_submit_transfer(transfer);
227 		break;
228 
229 	default:
230 		fp_err("Bug detected: invalid action %d", action->type);
231 		fpi_imgdev_session_error(data->device, -EINVAL);
232 		fpi_ssm_mark_aborted(ssm, -EINVAL);
233 		return;
234 	}
235 
236 	if (ret != 0) {
237 		fp_err("USB transfer error: %s", strerror(ret));
238 		fpi_imgdev_session_error(data->device, ret);
239 		fpi_ssm_mark_aborted(ssm, ret);
240 	}
241 }
242 
usb_exchange_async(struct fpi_ssm * ssm,struct usbexchange_data * data)243 static void usb_exchange_async(struct fpi_ssm *ssm,
244 			       struct usbexchange_data *data)
245 {
246 	struct fpi_ssm *subsm = fpi_ssm_new(data->device->dev,
247 					    usbexchange_loop,
248 					    data->stepcount);
249 	subsm->priv = data;
250 	fpi_ssm_start_subsm(ssm, subsm);
251 }
252 
253 /* ====================== utils ======================= */
254 
255 /* Calculade squared standand deviation of sum of two lines */
vfs5011_get_deviation2(struct fpi_line_asmbl_ctx * ctx,GSList * row1,GSList * row2)256 static int vfs5011_get_deviation2(struct fpi_line_asmbl_ctx *ctx, GSList *row1, GSList *row2)
257 {
258 	unsigned char *buf1, *buf2;
259 	int res = 0, mean = 0, i;
260 	const int size = 64;
261 
262 	buf1 = row1->data + 56;
263 	buf2 = row2->data + 168;
264 
265 	for (i = 0; i < size; i++)
266 		mean += (int)buf1[i] + (int)buf2[i];
267 
268 	mean /= size;
269 
270 	for (i = 0; i < size; i++) {
271 		int dev = (int)buf1[i] + (int)buf2[i] - mean;
272 		res += dev*dev;
273 	}
274 
275 	return res / size;
276 }
277 
vfs5011_get_pixel(struct fpi_line_asmbl_ctx * ctx,GSList * row,unsigned x)278 static unsigned char vfs5011_get_pixel(struct fpi_line_asmbl_ctx *ctx,
279 				   GSList *row,
280 				   unsigned x)
281 {
282 	unsigned char *data = row->data + 8;
283 
284 	return data[x];
285 }
286 
287 /* ====================== main stuff ======================= */
288 
289 enum {
290 	CAPTURE_LINES = 256,
291 	MAXLINES = 2000,
292 	MAX_CAPTURE_LINES = 100000,
293 };
294 
295 static struct fpi_line_asmbl_ctx assembling_ctx = {
296 	.line_width = VFS5011_IMAGE_WIDTH,
297 	.max_height = MAXLINES,
298 	.resolution = 10,
299 	.median_filter_size = 25,
300 	.max_search_offset = 30,
301 	.get_deviation = vfs5011_get_deviation2,
302 	.get_pixel = vfs5011_get_pixel,
303 };
304 
305 struct vfs5011_data {
306 	unsigned char *total_buffer;
307 	unsigned char *capture_buffer;
308 	unsigned char *row_buffer;
309 	unsigned char *lastline;
310 	GSList *rows;
311 	int lines_captured, lines_recorded, empty_lines;
312 	int max_lines_captured, max_lines_recorded;
313 	int lines_total, lines_total_allocated;
314 	gboolean loop_running;
315 	gboolean deactivating;
316 	struct usbexchange_data init_sequence;
317 	struct libusb_transfer *flying_transfer;
318 };
319 
320 enum {
321 	DEV_ACTIVATE_REQUEST_FPRINT,
322 	DEV_ACTIVATE_INIT_COMPLETE,
323 	DEV_ACTIVATE_READ_DATA,
324 	DEV_ACTIVATE_DATA_COMPLETE,
325 	DEV_ACTIVATE_PREPARE_NEXT_CAPTURE,
326 	DEV_ACTIVATE_NUM_STATES
327 };
328 
329 enum {
330 	DEV_OPEN_START,
331 	DEV_OPEN_NUM_STATES
332 };
333 
capture_init(struct vfs5011_data * data,int max_captured,int max_recorded)334 static void capture_init(struct vfs5011_data *data, int max_captured,
335 		int max_recorded)
336 {
337 	fp_dbg("capture_init");
338 	data->lastline = NULL;
339 	data->lines_captured = 0;
340 	data->lines_recorded = 0;
341 	data->empty_lines = 0;
342 	data->lines_total = 0;
343 	data->lines_total_allocated = 0;
344 	data->total_buffer = NULL;
345 	data->max_lines_captured = max_captured;
346 	data->max_lines_recorded = max_recorded;
347 }
348 
process_chunk(struct vfs5011_data * data,int transferred)349 static int process_chunk(struct vfs5011_data *data, int transferred)
350 {
351 	enum {
352 		DEVIATION_THRESHOLD = 15*15,
353 		DIFFERENCE_THRESHOLD = 600,
354 		STOP_CHECK_LINES = 50
355 	};
356 
357 	fp_dbg("process_chunk: got %d bytes", transferred);
358 	int lines_captured = transferred/VFS5011_LINE_SIZE;
359 	int i;
360 
361 	for (i = 0; i < lines_captured; i++) {
362 		unsigned char *linebuf = data->capture_buffer
363 					 + i * VFS5011_LINE_SIZE;
364 
365 		if (fpi_std_sq_dev(linebuf + 8, VFS5011_IMAGE_WIDTH)
366 				< DEVIATION_THRESHOLD) {
367 			if (data->lines_captured == 0)
368 				continue;
369 			else
370 				data->empty_lines++;
371 		} else
372 			data->empty_lines = 0;
373 		if (data->empty_lines >= STOP_CHECK_LINES) {
374 			fp_dbg("process_chunk: got %d empty lines, finishing",
375 					data->empty_lines);
376 			return 1;
377 		}
378 
379 		data->lines_captured++;
380 		if (data->lines_captured > data->max_lines_captured) {
381 			fp_dbg("process_chunk: captured %d lines, finishing",
382 					data->lines_captured);
383 			return 1;
384 		}
385 
386 		if ((data->lastline == NULL)
387 			|| (fpi_mean_sq_diff_norm(
388 				data->lastline + 8,
389 				linebuf + 8,
390 				VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD)) {
391 			data->lastline = g_malloc(VFS5011_LINE_SIZE);
392 			data->rows = g_slist_prepend(data->rows, data->lastline);
393 			g_memmove(data->lastline, linebuf, VFS5011_LINE_SIZE);
394 			data->lines_recorded++;
395 			if (data->lines_recorded >= data->max_lines_recorded) {
396 				fp_dbg("process_chunk: recorded %d lines, finishing",
397 						data->lines_recorded);
398 				return 1;
399 			}
400 		}
401 	}
402 	return 0;
403 }
404 
submit_image(struct fpi_ssm * ssm,struct vfs5011_data * data)405 void submit_image(struct fpi_ssm *ssm, struct vfs5011_data *data)
406 {
407 	struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv;
408 	struct fp_img *img;
409 
410 	data->rows = g_slist_reverse(data->rows);
411 
412 	img = fpi_assemble_lines(&assembling_ctx, data->rows, data->lines_recorded);
413 
414 	g_slist_free_full(data->rows, g_free);
415 	data->rows = NULL;
416 
417 	fp_dbg("Image captured, commiting");
418 
419 	fpi_imgdev_image_captured(dev, img);
420 }
421 
chunk_capture_callback(struct libusb_transfer * transfer)422 static void chunk_capture_callback(struct libusb_transfer *transfer)
423 {
424 	struct fpi_ssm *ssm = (struct fpi_ssm *)transfer->user_data;
425 	struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv;
426 	struct vfs5011_data *data = (struct vfs5011_data *)dev->priv;
427 
428 	if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) ||
429 	    (transfer->status == LIBUSB_TRANSFER_TIMED_OUT)) {
430 
431 		if (transfer->actual_length > 0)
432 			fpi_imgdev_report_finger_status(dev, TRUE);
433 
434 		if (process_chunk(data, transfer->actual_length))
435 			fpi_ssm_jump_to_state(ssm, DEV_ACTIVATE_DATA_COMPLETE);
436 		else
437 			fpi_ssm_jump_to_state(ssm, DEV_ACTIVATE_READ_DATA);
438 	} else {
439 		if (!data->deactivating) {
440 			fp_err("Failed to capture data");
441 			fpi_ssm_mark_aborted(ssm, -1);
442 		} else {
443 			fpi_ssm_mark_completed(ssm);
444 		}
445 	}
446 	libusb_free_transfer(transfer);
447 	data->flying_transfer = NULL;
448 }
449 
capture_chunk_async(struct vfs5011_data * data,libusb_device_handle * handle,int nline,int timeout,struct fpi_ssm * ssm)450 static int capture_chunk_async(struct vfs5011_data *data,
451 			       libusb_device_handle *handle, int nline,
452 			       int timeout, struct fpi_ssm *ssm)
453 {
454 	fp_dbg("capture_chunk_async: capture %d lines, already have %d",
455 		nline, data->lines_recorded);
456 	enum {
457 		DEVIATION_THRESHOLD = 15*15,
458 		DIFFERENCE_THRESHOLD = 600,
459 		STOP_CHECK_LINES = 50
460 	};
461 
462 	data->flying_transfer = libusb_alloc_transfer(0);
463 	libusb_fill_bulk_transfer(data->flying_transfer, handle, VFS5011_IN_ENDPOINT_DATA,
464 				  data->capture_buffer,
465 				  nline * VFS5011_LINE_SIZE,
466 				  chunk_capture_callback, ssm, timeout);
467 	return libusb_submit_transfer(data->flying_transfer);
468 }
469 
async_sleep_cb(void * data)470 static void async_sleep_cb(void *data)
471 {
472 	struct fpi_ssm *ssm = data;
473 
474 	fpi_ssm_next_state(ssm);
475 }
476 
477 /*
478  *  Device initialization. Windows driver only does it when the device is
479  *  plugged in, but it doesn't harm to do this every time before scanning the
480  *  image.
481  */
482 struct usb_action vfs5011_initialization[] = {
483 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_01)
484 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64)
485 
486 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_19)
487 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64)
488 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64) /* B5C457F9 */
489 
490 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_00)
491 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64) /* 0000FFFFFFFF */
492 
493 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_01)
494 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64) /* 0000FFFFFFFFFF */
495 
496 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_02)
497 	/* 0000 */
498 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
499 
500 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_01)
501 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64)
502 
503 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_1A)
504 	/* 0000 */
505 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
506 
507 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_03)
508 	/* 0000 */
509 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
510 
511 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_04)
512 	/* 0000 */
513 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
514 	RECV(VFS5011_IN_ENDPOINT_DATA, 256)
515 	RECV(VFS5011_IN_ENDPOINT_DATA, 64)
516 
517 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_1A)
518 	/* 0000 */
519 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
520 
521 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_05)
522 	/* 0000 */
523 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
524 
525 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_01)
526 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64)
527 
528 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_06)
529 	/* 0000 */
530 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
531 	RECV(VFS5011_IN_ENDPOINT_DATA, 17216)
532 	RECV(VFS5011_IN_ENDPOINT_DATA, 32)
533 
534 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_07)
535 	/* 0000 */
536 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
537 	RECV(VFS5011_IN_ENDPOINT_DATA, 45056)
538 
539 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_08)
540 	/* 0000 */
541 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
542 	RECV(VFS5011_IN_ENDPOINT_DATA, 16896)
543 
544 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_09)
545 	/* 0000 */
546 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
547 	RECV(VFS5011_IN_ENDPOINT_DATA, 4928)
548 
549 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_10)
550 	/* 0000 */
551 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
552 	RECV(VFS5011_IN_ENDPOINT_DATA, 5632)
553 
554 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_11)
555 	/* 0000 */
556 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
557 	RECV(VFS5011_IN_ENDPOINT_DATA, 5632)
558 
559 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_12)
560 	/* 0000 */
561 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
562 	RECV(VFS5011_IN_ENDPOINT_DATA, 3328)
563 	RECV(VFS5011_IN_ENDPOINT_DATA, 64)
564 
565 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_13)
566 	/* 0000 */
567 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
568 
569 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_1A)
570 	/* 0000 */
571 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
572 
573 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_03)
574 	/* 0000 */
575 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
576 
577 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_14)
578 	/* 0000 */
579 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
580 	RECV(VFS5011_IN_ENDPOINT_DATA, 4800)
581 
582 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_1A)
583 	/* 0000 */
584 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
585 
586 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_02)
587 	/* 0000 */
588 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
589 
590 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_27)
591 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64)
592 
593 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_1A)
594 	/* 0000 */
595 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
596 
597 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_15)
598 	/* 0000 */
599 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
600 
601 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_16)
602 	RECV(VFS5011_IN_ENDPOINT_CTRL, 2368)
603 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64)
604 	RECV(VFS5011_IN_ENDPOINT_DATA, 4800)
605 
606 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_17)
607 	/* 0000 */
608 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
609 
610 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_init_18)
611 	/* 0000 */
612 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
613 
614 	/*
615 	 * Windows driver does this and it works
616 	 * But in this driver this call never returns...
617 	 * RECV(VFS5011_IN_ENDPOINT_CTRL2, 8) //00D3054000
618 	 */
619 };
620 
621 /* Initiate recording the image */
622 struct usb_action vfs5011_initiate_capture[] = {
623 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_04)
624 	RECV(VFS5011_IN_ENDPOINT_DATA, 64)
625 	RECV(VFS5011_IN_ENDPOINT_DATA, 84032)
626 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
627 
628 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_1A)
629 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
630 
631 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_prepare_00)
632 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
633 
634 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_cmd_1A)
635 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
636 
637 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_prepare_01)
638 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
639 
640 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_prepare_02)
641 	RECV(VFS5011_IN_ENDPOINT_CTRL, 2368)
642 	RECV(VFS5011_IN_ENDPOINT_CTRL, 64)
643 	RECV(VFS5011_IN_ENDPOINT_DATA, 4800)
644 
645 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_prepare_03)
646 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 64, VFS5011_NORMAL_CONTROL_REPLY)
647 	/*
648 	 * Windows driver does this and it works
649 	 * But in this driver this call never returns...
650 	 * RECV(VFS5011_IN_ENDPOINT_CTRL2, 8);
651 	 */
652 
653 	SEND(VFS5011_OUT_ENDPOINT, vfs5011_prepare_04)
654 	RECV_CHECK(VFS5011_IN_ENDPOINT_CTRL, 2368, VFS5011_NORMAL_CONTROL_REPLY)
655 
656 	/*
657 	 * Windows driver does this and it works
658 	 * But in this driver this call never returns...
659 	 * RECV(VFS5011_IN_ENDPOINT_CTRL2, 8);
660 	 */
661 };
662 
663 /* ====================== lifprint interface ======================= */
664 
activate_loop(struct fpi_ssm * ssm)665 static void activate_loop(struct fpi_ssm *ssm)
666 {
667 	enum {READ_TIMEOUT = 0};
668 
669 	struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv;
670 	struct vfs5011_data *data = (struct vfs5011_data *)dev->priv;
671 	int r;
672 	struct fpi_timeout *timeout;
673 
674 	fp_dbg("main_loop: state %d", ssm->cur_state);
675 
676 	if (data->deactivating) {
677 		fp_dbg("deactivating, marking completed");
678 		fpi_ssm_mark_completed(ssm);
679 		return;
680 	}
681 
682 	switch (ssm->cur_state) {
683 	case DEV_ACTIVATE_REQUEST_FPRINT:
684 		data->init_sequence.stepcount =
685 			array_n_elements(vfs5011_initiate_capture);
686 		data->init_sequence.actions = vfs5011_initiate_capture;
687 		data->init_sequence.device = dev;
688 		if (data->init_sequence.receive_buf == NULL)
689 			data->init_sequence.receive_buf =
690 				g_malloc0(VFS5011_RECEIVE_BUF_SIZE);
691 		data->init_sequence.timeout = 1000;
692 		usb_exchange_async(ssm, &data->init_sequence);
693 		break;
694 
695 	case DEV_ACTIVATE_INIT_COMPLETE:
696 		if (data->init_sequence.receive_buf != NULL)
697 			g_free(data->init_sequence.receive_buf);
698 		data->init_sequence.receive_buf = NULL;
699 		capture_init(data, MAX_CAPTURE_LINES, MAXLINES);
700 		fpi_imgdev_activate_complete(dev, 0);
701 		fpi_ssm_next_state(ssm);
702 		break;
703 
704 	case DEV_ACTIVATE_READ_DATA:
705 		r = capture_chunk_async(data, dev->udev, CAPTURE_LINES,
706 					READ_TIMEOUT, ssm);
707 		if (r != 0) {
708 			fp_err("Failed to capture data");
709 			fpi_imgdev_session_error(dev, r);
710 			fpi_ssm_mark_aborted(ssm, r);
711 		}
712 		break;
713 
714 	case DEV_ACTIVATE_DATA_COMPLETE:
715 		timeout = fpi_timeout_add(1, async_sleep_cb, ssm);
716 
717 		if (timeout == NULL) {
718 			/* Failed to add timeout */
719 			fp_err("failed to add timeout");
720 			fpi_imgdev_session_error(dev, -1);
721 			fpi_ssm_mark_aborted(ssm, -1);
722 		}
723 		break;
724 
725 	case DEV_ACTIVATE_PREPARE_NEXT_CAPTURE:
726 		data->init_sequence.stepcount =
727 			array_n_elements(vfs5011_initiate_capture);
728 		data->init_sequence.actions = vfs5011_initiate_capture;
729 		data->init_sequence.device = dev;
730 		if (data->init_sequence.receive_buf == NULL)
731 			data->init_sequence.receive_buf =
732 				g_malloc0(VFS5011_RECEIVE_BUF_SIZE);
733 		data->init_sequence.timeout = VFS5011_DEFAULT_WAIT_TIMEOUT;
734 		usb_exchange_async(ssm, &data->init_sequence);
735 		break;
736 
737 	}
738 }
739 
activate_loop_complete(struct fpi_ssm * ssm)740 static void activate_loop_complete(struct fpi_ssm *ssm)
741 {
742 	struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv;
743 	struct vfs5011_data *data = (struct vfs5011_data *)dev->priv;
744 	int r = ssm->error;
745 
746 	fp_dbg("finishing");
747 	if (data->init_sequence.receive_buf != NULL)
748 		g_free(data->init_sequence.receive_buf);
749 	data->init_sequence.receive_buf = NULL;
750 	/* We don't want to submit image if we're in deactivating process */
751 	if (!data->deactivating) {
752 		submit_image(ssm, data);
753 		fpi_imgdev_report_finger_status(dev, FALSE);
754 	}
755 	fpi_ssm_free(ssm);
756 
757 	data->loop_running = FALSE;
758 
759 	if (data->deactivating) {
760 		fpi_imgdev_deactivate_complete(dev);
761 	} else if (r) {
762 		fpi_imgdev_session_error(dev, r);
763 	} else {
764 		start_scan(dev);
765 	}
766 }
767 
768 
open_loop(struct fpi_ssm * ssm)769 static void open_loop(struct fpi_ssm *ssm)
770 {
771 	struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv;
772 	struct vfs5011_data *data = (struct vfs5011_data *)dev->priv;
773 
774 	switch (ssm->cur_state) {
775 	case DEV_OPEN_START:
776 		data->init_sequence.stepcount =
777 			array_n_elements(vfs5011_initialization);
778 		data->init_sequence.actions = vfs5011_initialization;
779 		data->init_sequence.device = dev;
780 		data->init_sequence.receive_buf =
781 			g_malloc0(VFS5011_RECEIVE_BUF_SIZE);
782 		data->init_sequence.timeout = VFS5011_DEFAULT_WAIT_TIMEOUT;
783 		usb_exchange_async(ssm, &data->init_sequence);
784 		break;
785 	};
786 }
787 
open_loop_complete(struct fpi_ssm * ssm)788 static void open_loop_complete(struct fpi_ssm *ssm)
789 {
790 	struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv;
791 	struct vfs5011_data *data = (struct vfs5011_data *)dev->priv;
792 
793 	g_free(data->init_sequence.receive_buf);
794 	data->init_sequence.receive_buf = NULL;
795 
796 	fpi_imgdev_open_complete(dev, 0);
797 	fpi_ssm_free(ssm);
798 }
799 
dev_open(struct fp_img_dev * dev,unsigned long driver_data)800 static int dev_open(struct fp_img_dev *dev, unsigned long driver_data)
801 {
802 
803 	struct vfs5011_data *data;
804 	int r;
805 
806 	data = (struct vfs5011_data *)g_malloc0(sizeof(*data));
807 	data->capture_buffer =
808 		(unsigned char *)g_malloc0(CAPTURE_LINES * VFS5011_LINE_SIZE);
809 	dev->priv = data;
810 
811 	r = libusb_reset_device(dev->udev);
812 	if (r != 0) {
813 		fp_err("Failed to reset the device");
814 		return r;
815 	}
816 
817 	r = libusb_claim_interface(dev->udev, 0);
818 	if (r != 0) {
819 		fp_err("Failed to claim interface: %s", libusb_error_name(r));
820 		return r;
821 	}
822 
823 	struct fpi_ssm *ssm;
824 	ssm = fpi_ssm_new(dev->dev, open_loop, DEV_OPEN_NUM_STATES);
825 	ssm->priv = dev;
826 	fpi_ssm_start(ssm, open_loop_complete);
827 
828 	return 0;
829 }
830 
dev_close(struct fp_img_dev * dev)831 static void dev_close(struct fp_img_dev *dev)
832 {
833 	libusb_release_interface(dev->udev, 0);
834 	struct vfs5011_data *data = (struct vfs5011_data *)dev->priv;
835 	if (data != NULL) {
836 		g_free(data->capture_buffer);
837 		g_slist_free_full(data->rows, g_free);
838 		g_free(data);
839 	}
840 	fpi_imgdev_close_complete(dev);
841 }
842 
start_scan(struct fp_img_dev * dev)843 static void start_scan(struct fp_img_dev *dev)
844 {
845 	struct vfs5011_data *data = (struct vfs5011_data *)dev->priv;
846 	struct fpi_ssm *ssm;
847 
848 	data->loop_running = TRUE;
849 	fp_dbg("creating ssm");
850 	ssm = fpi_ssm_new(dev->dev, activate_loop, DEV_ACTIVATE_NUM_STATES);
851 	ssm->priv = dev;
852 	fp_dbg("starting ssm");
853 	fpi_ssm_start(ssm, activate_loop_complete);
854 	fp_dbg("ssm done, getting out");
855 }
856 
dev_activate(struct fp_img_dev * dev,enum fp_imgdev_state state)857 static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
858 {
859 	struct vfs5011_data *data = (struct vfs5011_data *)dev->priv;
860 
861 	fp_dbg("device initialized");
862 	data->deactivating = FALSE;
863 
864 	start_scan(dev);
865 
866 	return 0;
867 }
868 
dev_deactivate(struct fp_img_dev * dev)869 static void dev_deactivate(struct fp_img_dev *dev)
870 {
871 	int r;
872 	struct vfs5011_data *data = dev->priv;
873 	if (data->loop_running) {
874 		data->deactivating = TRUE;
875 		if (data->flying_transfer) {
876 			r = libusb_cancel_transfer(data->flying_transfer);
877 			if (r < 0)
878 				fp_dbg("cancel failed error %d", r);
879 		}
880 	} else
881 		fpi_imgdev_deactivate_complete(dev);
882 }
883 
884 static const struct usb_id id_table[] = {
885 	{ .vendor = 0x138a, .product = 0x0010 /* Validity device from some Toshiba laptops */ },
886 	{ .vendor = 0x138a, .product = 0x0011 /* vfs5011 */ },
887 	{ .vendor = 0x138a, .product = 0x0017 /* Validity device from Lenovo T440 laptops */ },
888 	{ .vendor = 0x138a, .product = 0x0018 /* one more Validity device */ },
889 	{ 0, 0, 0, },
890 };
891 
892 struct fp_img_driver vfs5011_driver = {
893 	.driver = {
894 		.id = VFS5011_ID,
895 		.name = "vfs5011",
896 		.full_name = "Validity VFS5011",
897 		.id_table = id_table,
898 		.scan_type = FP_SCAN_TYPE_SWIPE,
899 	},
900 
901 	.flags = 0,
902 	.img_width = VFS5011_IMAGE_WIDTH,
903 	.img_height = -1,
904 	.bz3_threshold = 20,
905 
906 	.open = dev_open,
907 	.close = dev_close,
908 	.activate = dev_activate,
909 	.deactivate = dev_deactivate,
910 };
911 
912