1 /*
2  * UPEK TouchStrip Sensor-Only driver for libfprint
3  * Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
4  *
5  * TCS4C (USB ID 147e:1000) support:
6  * Copyright (C) 2010 Hugo Grostabussiat <dw23.devel@gmail.com>
7  *
8  * TCRD5B (USB ID 147e:1001) support:
9  * Copyright (C) 2014 Vasily Khoruzhick <anarsoul@gmail.com>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #define FP_COMPONENT "upeksonly"
27 
28 #include <errno.h>
29 #include <string.h>
30 
31 #include <glib.h>
32 #include <libusb.h>
33 
34 #include <fp_internal.h>
35 
36 #include <assembling.h>
37 
38 #include "upeksonly.h"
39 #include "driver_ids.h"
40 
41 #define CTRL_TIMEOUT	1000
42 #define NUM_BULK_TRANSFERS 24
43 #define MAX_ROWS 2048
44 #define MIN_ROWS 64
45 
46 #define BLANK_THRESHOLD 250
47 #define FINGER_PRESENT_THRESHOLD 32
48 #define FINGER_REMOVED_THRESHOLD 100
49 #define DIFF_THRESHOLD 13
50 
51 enum {
52 	UPEKSONLY_2016,
53 	UPEKSONLY_1000,
54 	UPEKSONLY_1001,
55 };
56 
57 struct img_transfer_data {
58 	int idx;
59 	struct fp_img_dev *dev;
60 	gboolean flying;
61 	gboolean cancelling;
62 };
63 
64 enum sonly_kill_transfers_action {
65 	NOT_KILLING = 0,
66 
67 	/* abort a SSM with an error code */
68 	ABORT_SSM,
69 
70 	/* report an image session error */
71 	IMG_SESSION_ERROR,
72 
73 	/* iterate a SSM to the next state */
74 	ITERATE_SSM,
75 
76 	/* call a callback */
77 	EXEC_CALLBACK,
78 };
79 
80 enum sonly_fs {
81 	AWAIT_FINGER,
82 	FINGER_DETECTED,
83 	FINGER_REMOVED,
84 };
85 
86 struct sonly_dev {
87 	gboolean capturing;
88 	gboolean deactivating;
89 	uint8_t read_reg_result;
90 
91 	int dev_model;
92 	int img_width;
93 
94 	struct fpi_ssm *loopsm;
95 	struct libusb_transfer *img_transfer[NUM_BULK_TRANSFERS];
96 	struct img_transfer_data *img_transfer_data;
97 	int num_flying;
98 
99 	GSList *rows;
100 	size_t num_rows;
101 	unsigned char *rowbuf;
102 	int rowbuf_offset;
103 
104 	int wraparounds;
105 	int num_blank;
106 	int num_nonblank;
107 	enum sonly_fs finger_state;
108 	int last_seqnum;
109 
110 	enum sonly_kill_transfers_action killing_transfers;
111 	int kill_status_code;
112 	union {
113 		struct fpi_ssm *kill_ssm;
114 		void (*kill_cb)(struct fp_img_dev *dev);
115 	};
116 };
117 
118 
119 /* Calculade squared standand deviation of sum of two lines */
upeksonly_get_deviation2(struct fpi_line_asmbl_ctx * ctx,GSList * line1,GSList * line2)120 static int upeksonly_get_deviation2(struct fpi_line_asmbl_ctx *ctx,
121 			  GSList *line1, GSList *line2)
122 {
123 	unsigned char *buf1 = line1->data, *buf2 = line2->data;
124 	int res = 0, mean = 0, i;
125 	for (i = 0; i < ctx->line_width; i+= 2)
126 		mean += (int)buf1[i + 1] + (int)buf2[i];
127 
128 	mean /= (ctx->line_width / 2);
129 
130 	for (i = 0; i < ctx->line_width; i+= 2) {
131 		int dev = (int)buf1[i + 1] + (int)buf2[i] - mean;
132 		res += dev*dev;
133 	}
134 
135 	return res / (ctx->line_width / 2);
136 }
137 
138 
upeksonly_get_pixel(struct fpi_line_asmbl_ctx * ctx,GSList * row,unsigned x)139 static unsigned char upeksonly_get_pixel(struct fpi_line_asmbl_ctx *ctx,
140 				   GSList *row,
141 				   unsigned x)
142 {
143 	unsigned char *buf;
144 	unsigned offset;
145 
146 	/* The scans from this device are rolled right by two colums */
147 	if (x < ctx->line_width - 2)
148 		offset = x + 2;
149 	else if ((x > ctx->line_width - 2) && (x < ctx->line_width))
150 		offset = x - (ctx->line_width - 2);
151 	else
152 		return 0;
153 	/* Each 2nd pixel is shifted 2 pixels down */
154 	if ((!(x & 1)) && g_slist_next(row) && g_slist_next(g_slist_next(row)))
155 		buf = g_slist_next(g_slist_next(row))->data;
156 	else
157 		buf = row->data;
158 
159 	return buf[offset];
160 }
161 
162 static struct fpi_line_asmbl_ctx assembling_ctx = {
163 	.max_height = 1024,
164 	.resolution = 8,
165 	.median_filter_size = 25,
166 	.max_search_offset = 30,
167 	.get_deviation = upeksonly_get_deviation2,
168 	.get_pixel = upeksonly_get_pixel,
169 };
170 
171 /***** IMAGE PROCESSING *****/
172 
free_img_transfers(struct sonly_dev * sdev)173 static void free_img_transfers(struct sonly_dev *sdev)
174 {
175 	int i;
176 	for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
177 		struct libusb_transfer *transfer = sdev->img_transfer[i];
178 		if (!transfer)
179 			continue;
180 
181 		g_free(transfer->buffer);
182 		libusb_free_transfer(transfer);
183 	}
184 	g_free(sdev->img_transfer_data);
185 }
186 
last_transfer_killed(struct fp_img_dev * dev)187 static void last_transfer_killed(struct fp_img_dev *dev)
188 {
189 	struct sonly_dev *sdev = dev->priv;
190 	switch (sdev->killing_transfers) {
191 	case ABORT_SSM:
192 		fp_dbg("abort ssm error %d", sdev->kill_status_code);
193 		fpi_ssm_mark_aborted(sdev->kill_ssm, sdev->kill_status_code);
194 		return;
195 	case ITERATE_SSM:
196 		fp_dbg("iterate ssm");
197 		fpi_ssm_next_state(sdev->kill_ssm);
198 		return;
199 	case IMG_SESSION_ERROR:
200 		fp_dbg("session error %d", sdev->kill_status_code);
201 		fpi_imgdev_session_error(dev, sdev->kill_status_code);
202 		return;
203 	default:
204 		return;
205 	}
206 }
207 
cancel_img_transfers(struct fp_img_dev * dev)208 static void cancel_img_transfers(struct fp_img_dev *dev)
209 {
210 	struct sonly_dev *sdev = dev->priv;
211 	int i;
212 
213 	if (sdev->num_flying == 0) {
214 		last_transfer_killed(dev);
215 		return;
216 	}
217 
218 	for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
219 		struct img_transfer_data *idata = &sdev->img_transfer_data[i];
220 		if (!idata->flying || idata->cancelling)
221 			continue;
222 		fp_dbg("cancelling transfer %d", i);
223 		int r = libusb_cancel_transfer(sdev->img_transfer[i]);
224 		if (r < 0)
225 			fp_dbg("cancel failed error %d", r);
226 		idata->cancelling = TRUE;
227 	}
228 }
229 
is_capturing(struct sonly_dev * sdev)230 static gboolean is_capturing(struct sonly_dev *sdev)
231 {
232 	return sdev->num_rows < MAX_ROWS && (sdev->finger_state != FINGER_REMOVED);
233 }
234 
handoff_img(struct fp_img_dev * dev)235 static void handoff_img(struct fp_img_dev *dev)
236 {
237 	struct sonly_dev *sdev = dev->priv;
238 	struct fp_img *img;
239 
240 	GSList *elem = sdev->rows;
241 
242 	if (!elem) {
243 		fp_err("no rows?");
244 		return;
245 	}
246 
247 	sdev->rows = g_slist_reverse(sdev->rows);
248 
249 	fp_dbg("%d rows", sdev->num_rows);
250 	img = fpi_assemble_lines(&assembling_ctx, sdev->rows, sdev->num_rows);
251 
252 	g_slist_free_full(sdev->rows, g_free);
253 	sdev->rows = NULL;
254 
255 	fpi_imgdev_image_captured(dev, img);
256 	fpi_imgdev_report_finger_status(dev, FALSE);
257 
258 	sdev->killing_transfers = ITERATE_SSM;
259 	sdev->kill_ssm = sdev->loopsm;
260 	cancel_img_transfers(dev);
261 }
262 
row_complete(struct fp_img_dev * dev)263 static void row_complete(struct fp_img_dev *dev)
264 {
265 	struct sonly_dev *sdev = dev->priv;
266 	sdev->rowbuf_offset = -1;
267 
268 	if (sdev->num_rows > 0) {
269 		unsigned char *lastrow = sdev->rows->data;
270 		int std_sq_dev, mean_sq_diff;
271 
272 		std_sq_dev = fpi_std_sq_dev(sdev->rowbuf, sdev->img_width);
273 		mean_sq_diff = fpi_mean_sq_diff_norm(lastrow, sdev->rowbuf, sdev->img_width);
274 
275 		switch (sdev->finger_state) {
276 		case AWAIT_FINGER:
277 			if (sdev->deactivating) {
278 				sdev->killing_transfers = ITERATE_SSM;
279 				sdev->kill_ssm = sdev->loopsm;
280 				cancel_img_transfers(dev);
281 			}
282 			fp_dbg("std_sq_dev: %d", std_sq_dev);
283 			if (std_sq_dev > BLANK_THRESHOLD) {
284 				sdev->num_nonblank++;
285 			} else {
286 				sdev->num_nonblank = 0;
287 			}
288 
289 			if (sdev->num_nonblank > FINGER_PRESENT_THRESHOLD) {
290 				sdev->finger_state = FINGER_DETECTED;
291 				fpi_imgdev_report_finger_status(dev, TRUE);
292 			} else {
293 				return;
294 			}
295 			break;
296 		case FINGER_DETECTED:
297 		case FINGER_REMOVED:
298 		default:
299 			break;
300 		}
301 
302 		if (std_sq_dev > BLANK_THRESHOLD) {
303 			sdev->num_blank = 0;
304 		} else {
305 			sdev->num_blank++;
306 			/* Don't consider the scan complete unless theres at least
307 			 * MIN_ROWS recorded or very long blank read occurred.
308 			 *
309 			 * Typical problem spot: one brief touch before starting the
310 			 * actual scan. Happens most commonly if scan is started
311 			 * from before the first joint resulting in a gap after the inital touch.
312 			 */
313 			if (sdev->num_blank > FINGER_REMOVED_THRESHOLD) {
314 				sdev->finger_state = FINGER_REMOVED;
315 				fp_dbg("detected finger removal. Blank rows: %d, Full rows: %d", sdev->num_blank, sdev->num_rows);
316 				handoff_img(dev);
317 				return;
318 			}
319 		}
320 		fp_dbg("mean_sq_diff: %d, std_sq_dev: %d", mean_sq_diff, std_sq_dev);
321 		fp_dbg("num_blank: %d", sdev->num_blank);
322 		if (mean_sq_diff < DIFF_THRESHOLD) {
323 			return;
324 		}
325 	}
326 
327 	switch (sdev->finger_state) {
328 	case AWAIT_FINGER:
329 		if (!sdev->num_rows) {
330 			sdev->rows = g_slist_prepend(sdev->rows, sdev->rowbuf);
331 			sdev->num_rows++;
332 		} else {
333 			return;
334 		}
335 		break;
336 	case FINGER_DETECTED:
337 	case FINGER_REMOVED:
338 		sdev->rows = g_slist_prepend(sdev->rows, sdev->rowbuf);
339 		sdev->num_rows++;
340 		break;
341 	}
342 	sdev->rowbuf = NULL;
343 
344 	if (sdev->num_rows >= MAX_ROWS) {
345 		fp_dbg("row limit met");
346 		handoff_img(dev);
347 	}
348 }
349 
350 /* add data to row buffer */
add_to_rowbuf(struct fp_img_dev * dev,unsigned char * data,int size)351 static void add_to_rowbuf(struct fp_img_dev *dev, unsigned char *data, int size)
352 {
353 	struct sonly_dev *sdev = dev->priv;
354 
355 	memcpy(sdev->rowbuf + sdev->rowbuf_offset, data, size);
356 	sdev->rowbuf_offset += size;
357 	if (sdev->rowbuf_offset >= sdev->img_width)
358 		row_complete(dev);
359 
360 }
361 
start_new_row(struct sonly_dev * sdev,unsigned char * data,int size)362 static void start_new_row(struct sonly_dev *sdev, unsigned char *data, int size)
363 {
364 	if (!sdev->rowbuf)
365 		sdev->rowbuf = g_malloc(sdev->img_width);
366 	memcpy(sdev->rowbuf, data, size);
367 	sdev->rowbuf_offset = size;
368 }
369 
370 /* returns number of bytes left to be copied into rowbuf (capped to 62)
371  * or -1 if we aren't capturing anything */
rowbuf_remaining(struct sonly_dev * sdev)372 static int rowbuf_remaining(struct sonly_dev *sdev)
373 {
374 	int r;
375 
376 	if (sdev->rowbuf_offset == -1)
377 		return -1;
378 
379 	r = sdev->img_width - sdev->rowbuf_offset;
380 	if (r > 62)
381 		r = 62;
382 	return r;
383 }
384 
handle_packet(struct fp_img_dev * dev,unsigned char * data)385 static void handle_packet(struct fp_img_dev *dev, unsigned char *data)
386 {
387 	struct sonly_dev *sdev = dev->priv;
388 	uint16_t seqnum = data[0] << 8 | data[1];
389 	int abs_base_addr;
390 	int for_rowbuf;
391 	int next_row_addr;
392 	int diff;
393 	unsigned char dummy_data[62];
394 
395 	/* Init dummy data to something neutral */
396 	memset (dummy_data, 204, 62);
397 
398 	data += 2; /* skip sequence number */
399 	if (seqnum != sdev->last_seqnum + 1) {
400 		if (seqnum != 0 && sdev->last_seqnum != 16383) {
401 			int missing_data = seqnum - sdev->last_seqnum;
402 			int i;
403 			fp_warn("lost %d packets of data between %d and %d", missing_data, sdev->last_seqnum, seqnum );
404 
405 			/* Minimize distortions for readers that lose a lot of packets */
406 			for (i =1; i < missing_data; i++) {
407 				abs_base_addr = (sdev->last_seqnum + 1) * 62;
408 
409 				/* If possible take the replacement data from last row */
410 				if (sdev->num_rows > 1) {
411 					int row_left = sdev->img_width - sdev->rowbuf_offset;
412 					unsigned char *last_row = g_slist_nth_data (sdev->rows, 0);
413 
414 					if (row_left >= 62) {
415 						memcpy(dummy_data, last_row + sdev->rowbuf_offset, 62);
416 					} else {
417 						memcpy(dummy_data, last_row + sdev->rowbuf_offset, row_left);
418 						memcpy(dummy_data + row_left, last_row , 62 - row_left);
419 					}
420 				}
421 
422 				fp_warn("adding dummy input for %d, i=%d", sdev->last_seqnum + i, i);
423 				for_rowbuf = rowbuf_remaining(sdev);
424 				if (for_rowbuf != -1) {
425 					add_to_rowbuf(dev, dummy_data, for_rowbuf);
426 					/* row boundary */
427 					if (for_rowbuf < 62) {
428 						start_new_row(sdev, dummy_data + for_rowbuf, 62 - for_rowbuf);
429 					}
430 				} else if (abs_base_addr % sdev->img_width == 0) {
431 					start_new_row(sdev, dummy_data, 62);
432 				} else {
433 					/* does the data in the packet reside on a row boundary?
434 					 * if so capture it */
435 					next_row_addr = ((abs_base_addr / sdev->img_width) + 1) * sdev->img_width;
436 					diff = next_row_addr - abs_base_addr;
437 					if (diff < 62)
438 						start_new_row(sdev, dummy_data + diff, 62 - diff);
439 				}
440 				sdev->last_seqnum = sdev->last_seqnum + 1;
441 			}
442 		}
443 	}
444 	if (seqnum <= sdev->last_seqnum) {
445 		fp_dbg("detected wraparound");
446 		sdev->wraparounds++;
447 	}
448 
449 	sdev->last_seqnum = seqnum;
450 	seqnum += sdev->wraparounds * 16384;
451 	abs_base_addr = seqnum * 62;
452 
453 	/* are we already capturing a row? if so append the data to the
454 	 * row buffer */
455 	for_rowbuf = rowbuf_remaining(sdev);
456 	if (for_rowbuf != -1) {
457 		add_to_rowbuf(dev, data, for_rowbuf);
458 		/*row boundary*/
459 		if (for_rowbuf < 62) {
460 			start_new_row(sdev, data + for_rowbuf, 62 - for_rowbuf);
461 		}
462 		return;
463 	}
464 
465 	/* does the packet START on a boundary? if so we want it in full */
466 	if (abs_base_addr % sdev->img_width == 0) {
467 		start_new_row(sdev, data, 62);
468 		return;
469 	}
470 
471 	/* does the data in the packet reside on a row boundary?
472 	 * if so capture it */
473 	next_row_addr = ((abs_base_addr / sdev->img_width) + 1) * sdev->img_width;
474 	diff = next_row_addr - abs_base_addr;
475 	if (diff < 62)
476 		start_new_row(sdev, data + diff, 62 - diff);
477 }
478 
img_data_cb(struct libusb_transfer * transfer)479 static void img_data_cb(struct libusb_transfer *transfer)
480 {
481 	struct img_transfer_data *idata = transfer->user_data;
482 	struct fp_img_dev *dev = idata->dev;
483 	struct sonly_dev *sdev = dev->priv;
484 	int i;
485 
486 	idata->flying = FALSE;
487 	idata->cancelling = FALSE;
488 	sdev->num_flying--;
489 
490 	if (sdev->killing_transfers) {
491 		if (sdev->num_flying == 0)
492 			last_transfer_killed(dev);
493 
494 		/* don't care about error or success if we're terminating */
495 		return;
496 	}
497 
498 	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
499 		fp_warn("bad status %d, terminating session", transfer->status);
500 		sdev->killing_transfers = IMG_SESSION_ERROR;
501 		sdev->kill_status_code = transfer->status;
502 		cancel_img_transfers(dev);
503 	}
504 
505 	/* there are 64 packets in the transfer buffer
506 	 * each packet is 64 bytes in length
507 	 * the first 2 bytes are a sequence number
508 	 * then there are 62 bytes for image data
509 	 */
510 	for (i = 0; i < 4096; i += 64) {
511 		if (!is_capturing(sdev))
512 			return;
513 		handle_packet(dev, transfer->buffer + i);
514 	}
515 
516 	if (is_capturing(sdev)) {
517 		int r = libusb_submit_transfer(transfer);
518 		if (r < 0) {
519 			fp_warn("failed resubmit, error %d", r);
520 			sdev->killing_transfers = IMG_SESSION_ERROR;
521 			sdev->kill_status_code = r;
522 			cancel_img_transfers(dev);
523 			return;
524 		}
525 		sdev->num_flying++;
526 		idata->flying = TRUE;
527 	}
528 }
529 
530 /***** STATE MACHINE HELPERS *****/
531 
532 struct write_regs_data {
533 	struct fpi_ssm *ssm;
534 	struct libusb_transfer *transfer;
535 	const struct sonly_regwrite *regs;
536 	size_t num_regs;
537 	size_t regs_written;
538 };
539 
write_regs_finished(struct write_regs_data * wrdata,int result)540 static void write_regs_finished(struct write_regs_data *wrdata, int result)
541 {
542 	g_free(wrdata->transfer->buffer);
543 	libusb_free_transfer(wrdata->transfer);
544 	if (result == 0)
545 		fpi_ssm_next_state(wrdata->ssm);
546 	else
547 		fpi_ssm_mark_aborted(wrdata->ssm, result);
548 	g_free(wrdata);
549 }
550 
551 
write_regs_iterate(struct write_regs_data * wrdata)552 static void write_regs_iterate(struct write_regs_data *wrdata)
553 {
554 	struct libusb_control_setup *setup;
555 	const struct sonly_regwrite *regwrite;
556 	int r;
557 
558 	if (wrdata->regs_written >= wrdata->num_regs) {
559 		write_regs_finished(wrdata, 0);
560 		return;
561 	}
562 
563 	regwrite = &wrdata->regs[wrdata->regs_written];
564 
565 	fp_dbg("set %02x=%02x", regwrite->reg, regwrite->value);
566 	setup = libusb_control_transfer_get_setup(wrdata->transfer);
567 	setup->wIndex = regwrite->reg;
568 	wrdata->transfer->buffer[LIBUSB_CONTROL_SETUP_SIZE] = regwrite->value;
569 
570 	r = libusb_submit_transfer(wrdata->transfer);
571 	if (r < 0)
572 		write_regs_finished(wrdata, r);
573 }
574 
write_regs_cb(struct libusb_transfer * transfer)575 static void write_regs_cb(struct libusb_transfer *transfer)
576 {
577 	struct write_regs_data *wrdata = transfer->user_data;
578 	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
579 		write_regs_finished(wrdata, transfer->status);
580 		return;
581 	}
582 
583 	wrdata->regs_written++;
584 	write_regs_iterate(wrdata);
585 }
586 
sm_write_regs(struct fpi_ssm * ssm,const struct sonly_regwrite * regs,size_t num_regs)587 static void sm_write_regs(struct fpi_ssm *ssm,
588 	const struct sonly_regwrite *regs, size_t num_regs)
589 {
590 	struct write_regs_data *wrdata = g_malloc(sizeof(*wrdata));
591 	unsigned char *data;
592 
593 	wrdata->transfer = libusb_alloc_transfer(0);
594 	if (!wrdata->transfer) {
595 		g_free(wrdata);
596 		fpi_ssm_mark_aborted(ssm, -ENOMEM);
597 		return;
598 	}
599 
600 	data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
601 	libusb_fill_control_setup(data, 0x40, 0x0c, 0, 0, 1);
602 	libusb_fill_control_transfer(wrdata->transfer, ssm->dev->udev, data,
603 		write_regs_cb, wrdata, CTRL_TIMEOUT);
604 	wrdata->transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK;
605 
606 	wrdata->ssm = ssm;
607 	wrdata->regs = regs;
608 	wrdata->num_regs = num_regs;
609 	wrdata->regs_written = 0;
610 	write_regs_iterate(wrdata);
611 }
612 
sm_write_reg_cb(struct libusb_transfer * transfer)613 static void sm_write_reg_cb(struct libusb_transfer *transfer)
614 {
615 	struct fpi_ssm *ssm = transfer->user_data;
616 	g_free(transfer->buffer);
617 	if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
618 		fpi_ssm_mark_aborted(ssm, -EIO);
619 	else
620 		fpi_ssm_next_state(ssm);
621 
622 }
623 
sm_write_reg(struct fpi_ssm * ssm,uint8_t reg,uint8_t value)624 static void sm_write_reg(struct fpi_ssm *ssm, uint8_t reg, uint8_t value)
625 {
626 	struct fp_img_dev *dev = ssm->priv;
627 	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
628 	unsigned char *data;
629 	int r;
630 
631 	if (!transfer) {
632 		fpi_ssm_mark_aborted(ssm, -ENOMEM);
633 		return;
634 	}
635 
636 	fp_dbg("set %02x=%02x", reg, value);
637 	data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
638 	libusb_fill_control_setup(data, 0x40, 0x0c, 0, reg, 1);
639 	libusb_fill_control_transfer(transfer, dev->udev, data, sm_write_reg_cb,
640 		ssm, CTRL_TIMEOUT);
641 
642 	data[LIBUSB_CONTROL_SETUP_SIZE] = value;
643 	transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK |
644 		LIBUSB_TRANSFER_FREE_TRANSFER;
645 
646 	r = libusb_submit_transfer(transfer);
647 	if (r < 0) {
648 		g_free(data);
649 		libusb_free_transfer(transfer);
650 		fpi_ssm_mark_aborted(ssm, r);
651 	}
652 }
653 
sm_read_reg_cb(struct libusb_transfer * transfer)654 static void sm_read_reg_cb(struct libusb_transfer *transfer)
655 {
656 	struct fpi_ssm *ssm = transfer->user_data;
657 	struct fp_img_dev *dev = ssm->priv;
658 	struct sonly_dev *sdev = dev->priv;
659 
660 	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
661 		fpi_ssm_mark_aborted(ssm, -EIO);
662 	} else {
663 		sdev->read_reg_result = libusb_control_transfer_get_data(transfer)[0];
664 		fp_dbg("read reg result = %02x", sdev->read_reg_result);
665 		fpi_ssm_next_state(ssm);
666 	}
667 
668 	g_free(transfer->buffer);
669 }
670 
sm_read_reg(struct fpi_ssm * ssm,uint8_t reg)671 static void sm_read_reg(struct fpi_ssm *ssm, uint8_t reg)
672 {
673 	struct fp_img_dev *dev = ssm->priv;
674 	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
675 	unsigned char *data;
676 	int r;
677 
678 	if (!transfer) {
679 		fpi_ssm_mark_aborted(ssm, -ENOMEM);
680 		return;
681 	}
682 
683 	fp_dbg("read reg %02x", reg);
684 	data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 8);
685 	libusb_fill_control_setup(data, 0xc0, 0x0c, 0, reg, 8);
686 	libusb_fill_control_transfer(transfer, dev->udev, data, sm_read_reg_cb,
687 		ssm, CTRL_TIMEOUT);
688 	transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK |
689 		LIBUSB_TRANSFER_FREE_TRANSFER;
690 
691 	r = libusb_submit_transfer(transfer);
692 	if (r < 0) {
693 		g_free(data);
694 		libusb_free_transfer(transfer);
695 		fpi_ssm_mark_aborted(ssm, r);
696 	}
697 }
698 
sm_await_intr_cb(struct libusb_transfer * transfer)699 static void sm_await_intr_cb(struct libusb_transfer *transfer)
700 {
701 	struct fpi_ssm *ssm = transfer->user_data;
702 	struct fp_img_dev *dev = ssm->priv;
703 	struct sonly_dev *sdev = dev->priv;
704 
705 	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
706 		g_free(transfer->buffer);
707 		fpi_ssm_mark_aborted(ssm, transfer->status);
708 		return;
709 	}
710 
711 	fp_dbg("interrupt received: %02x %02x %02x %02x",
712 		transfer->buffer[0], transfer->buffer[1],
713 		transfer->buffer[2], transfer->buffer[3]);
714 	g_free(transfer->buffer);
715 
716 	sdev->finger_state = FINGER_DETECTED;
717 	fpi_imgdev_report_finger_status(dev, TRUE);
718 	fpi_ssm_next_state(ssm);
719 }
720 
sm_await_intr(struct fpi_ssm * ssm)721 static void sm_await_intr(struct fpi_ssm *ssm)
722 {
723 	struct fp_img_dev *dev = ssm->priv;
724 	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
725 	unsigned char *data;
726 	int r;
727 
728 	if (!transfer) {
729 		fpi_ssm_mark_aborted(ssm, -ENOMEM);
730 		return;
731 	}
732 
733 	fp_dbg("");
734 	data = g_malloc(4);
735 	libusb_fill_interrupt_transfer(transfer, dev->udev, 0x83, data, 4,
736 		sm_await_intr_cb, ssm, 0);
737 	transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK |
738 		LIBUSB_TRANSFER_FREE_TRANSFER;
739 
740 	r = libusb_submit_transfer(transfer);
741 	if (r < 0) {
742 		libusb_free_transfer(transfer);
743 		g_free(data);
744 		fpi_ssm_mark_aborted(ssm, r);
745 	}
746 }
747 
748 /***** AWAIT FINGER *****/
749 
750 enum awfsm_2016_states {
751 	AWFSM_2016_WRITEV_1,
752 	AWFSM_2016_READ_01,
753 	AWFSM_2016_WRITE_01,
754 	AWFSM_2016_WRITEV_2,
755 	AWFSM_2016_READ_13,
756 	AWFSM_2016_WRITE_13,
757 	AWFSM_2016_WRITEV_3,
758 	AWFSM_2016_READ_07,
759 	AWFSM_2016_WRITE_07,
760 	AWFSM_2016_WRITEV_4,
761 	AWFSM_2016_NUM_STATES,
762 };
763 
764 enum awfsm_1000_states {
765 	AWFSM_1000_WRITEV_1,
766 	AWFSM_1000_WRITEV_2,
767 	AWFSM_1000_NUM_STATES,
768 };
769 
awfsm_2016_run_state(struct fpi_ssm * ssm)770 static void awfsm_2016_run_state(struct fpi_ssm *ssm)
771 {
772 	struct fp_img_dev *dev = ssm->priv;
773 	struct sonly_dev *sdev = dev->priv;
774 
775 	switch (ssm->cur_state) {
776 	case AWFSM_2016_WRITEV_1:
777 		sm_write_regs(ssm, awfsm_2016_writev_1, G_N_ELEMENTS(awfsm_2016_writev_1));
778 		break;
779 	case AWFSM_2016_READ_01:
780 		sm_read_reg(ssm, 0x01);
781 		break;
782 	case AWFSM_2016_WRITE_01:
783 		if (sdev->read_reg_result != 0xc6)
784 			sm_write_reg(ssm, 0x01, 0x46);
785 		else
786 			sm_write_reg(ssm, 0x01, 0xc6);
787 		break;
788 	case AWFSM_2016_WRITEV_2:
789 		sm_write_regs(ssm, awfsm_2016_writev_2, G_N_ELEMENTS(awfsm_2016_writev_2));
790 		break;
791 	case AWFSM_2016_READ_13:
792 		sm_read_reg(ssm, 0x13);
793 		break;
794 	case AWFSM_2016_WRITE_13:
795 		if (sdev->read_reg_result != 0x45)
796 			sm_write_reg(ssm, 0x13, 0x05);
797 		else
798 			sm_write_reg(ssm, 0x13, 0x45);
799 		break;
800 	case AWFSM_2016_WRITEV_3:
801 		sm_write_regs(ssm, awfsm_2016_writev_3, G_N_ELEMENTS(awfsm_2016_writev_3));
802 		break;
803 	case AWFSM_2016_READ_07:
804 		sm_read_reg(ssm, 0x07);
805 		break;
806 	case AWFSM_2016_WRITE_07:
807 		if (sdev->read_reg_result != 0x10 && sdev->read_reg_result != 0x90)
808 			fp_warn("odd reg7 value %x", sdev->read_reg_result);
809 		sm_write_reg(ssm, 0x07, sdev->read_reg_result);
810 		break;
811 	case AWFSM_2016_WRITEV_4:
812 		sm_write_regs(ssm, awfsm_2016_writev_4, G_N_ELEMENTS(awfsm_2016_writev_4));
813 		break;
814 	}
815 }
816 
awfsm_1000_run_state(struct fpi_ssm * ssm)817 static void awfsm_1000_run_state(struct fpi_ssm *ssm)
818 {
819 	switch (ssm->cur_state) {
820 	case AWFSM_1000_WRITEV_1:
821 		sm_write_regs(ssm, awfsm_1000_writev_1, G_N_ELEMENTS(awfsm_1000_writev_1));
822 		break;
823 	case AWFSM_1000_WRITEV_2:
824 		sm_write_regs(ssm, awfsm_1000_writev_2, G_N_ELEMENTS(awfsm_1000_writev_2));
825 		break;
826 	}
827 }
828 
829 /***** CAPTURE MODE *****/
830 
831 enum capsm_2016_states {
832 	CAPSM_2016_INIT,
833 	CAPSM_2016_WRITE_15,
834 	CAPSM_2016_WRITE_30,
835 	CAPSM_2016_FIRE_BULK,
836 	CAPSM_2016_WRITEV,
837 	CAPSM_2016_NUM_STATES,
838 };
839 
840 enum capsm_1000_states {
841 	CAPSM_1000_INIT,
842 	CAPSM_1000_FIRE_BULK,
843 	CAPSM_1000_WRITEV,
844 	CAPSM_1000_NUM_STATES,
845 };
846 
847 enum capsm_1001_states {
848 	CAPSM_1001_INIT,
849 	CAPSM_1001_FIRE_BULK,
850 	CAPSM_1001_WRITEV_1,
851 	CAPSM_1001_WRITEV_2,
852 	CAPSM_1001_WRITEV_3,
853 	CAPSM_1001_WRITEV_4,
854 	CAPSM_1001_WRITEV_5,
855 	CAPSM_1001_NUM_STATES,
856 };
857 
capsm_fire_bulk(struct fpi_ssm * ssm)858 static void capsm_fire_bulk(struct fpi_ssm *ssm)
859 {
860 	struct fp_img_dev *dev = ssm->priv;
861 	struct sonly_dev *sdev = dev->priv;
862 	int i;
863 	for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
864 		int r = libusb_submit_transfer(sdev->img_transfer[i]);
865 		if (r < 0) {
866 			if (i == 0) {
867 				/* first one failed: easy peasy */
868 				fpi_ssm_mark_aborted(ssm, r);
869 				return;
870 			}
871 
872 			/* cancel all flying transfers, and request that the SSM
873 			 * gets aborted when the last transfer has dropped out of
874 			 * the sky */
875 			sdev->killing_transfers = ABORT_SSM;
876 			sdev->kill_ssm = ssm;
877 			sdev->kill_status_code = r;
878 			cancel_img_transfers(dev);
879 			return;
880 		}
881 		sdev->img_transfer_data[i].flying = TRUE;
882 		sdev->num_flying++;
883 	}
884 	sdev->capturing = TRUE;
885 	fpi_ssm_next_state(ssm);
886 }
887 
capsm_2016_run_state(struct fpi_ssm * ssm)888 static void capsm_2016_run_state(struct fpi_ssm *ssm)
889 {
890 	struct fp_img_dev *dev = ssm->priv;
891 	struct sonly_dev *sdev = dev->priv;
892 
893 	switch (ssm->cur_state) {
894 	case CAPSM_2016_INIT:
895 		sdev->rowbuf_offset = -1;
896 		sdev->num_rows = 0;
897 		sdev->wraparounds = -1;
898 		sdev->num_blank = 0;
899 		sdev->num_nonblank = 0;
900 		sdev->finger_state = FINGER_DETECTED;
901 		sdev->last_seqnum = 16383;
902 		sdev->killing_transfers = 0;
903 		fpi_ssm_next_state(ssm);
904 		break;
905 	case CAPSM_2016_WRITE_15:
906 		sm_write_reg(ssm, 0x15, 0x20);
907 		break;
908 	case CAPSM_2016_WRITE_30:
909 		sm_write_reg(ssm, 0x30, 0xe0);
910 		break;
911 	case CAPSM_2016_FIRE_BULK: ;
912 		capsm_fire_bulk (ssm);
913 		break;
914 	case CAPSM_2016_WRITEV:
915 		sm_write_regs(ssm, capsm_2016_writev, G_N_ELEMENTS(capsm_2016_writev));
916 		break;
917 	}
918 }
919 
capsm_1000_run_state(struct fpi_ssm * ssm)920 static void capsm_1000_run_state(struct fpi_ssm *ssm)
921 {
922 	struct fp_img_dev *dev = ssm->priv;
923 	struct sonly_dev *sdev = dev->priv;
924 
925 	switch (ssm->cur_state) {
926 	case CAPSM_1000_INIT:
927 		sdev->rowbuf_offset = -1;
928 		sdev->num_rows = 0;
929 		sdev->wraparounds = -1;
930 		sdev->num_blank = 0;
931 		sdev->num_nonblank = 0;
932 		sdev->finger_state = FINGER_DETECTED;
933 		sdev->last_seqnum = 16383;
934 		sdev->killing_transfers = 0;
935 		fpi_ssm_next_state(ssm);
936 		break;
937 	case CAPSM_1000_FIRE_BULK: ;
938 		capsm_fire_bulk (ssm);
939 		break;
940 	case CAPSM_1000_WRITEV:
941 		sm_write_regs(ssm, capsm_1000_writev, G_N_ELEMENTS(capsm_1000_writev));
942 		break;
943 	}
944 }
945 
capsm_1001_run_state(struct fpi_ssm * ssm)946 static void capsm_1001_run_state(struct fpi_ssm *ssm)
947 {
948 	struct fp_img_dev *dev = ssm->priv;
949 	struct sonly_dev *sdev = dev->priv;
950 
951 	switch (ssm->cur_state) {
952 	case CAPSM_1001_INIT:
953 		sdev->rowbuf_offset = -1;
954 		sdev->num_rows = 0;
955 		sdev->wraparounds = -1;
956 		sdev->num_blank = 0;
957 		sdev->num_nonblank = 0;
958 		sdev->finger_state = AWAIT_FINGER;
959 		sdev->last_seqnum = 16383;
960 		sdev->killing_transfers = 0;
961 		fpi_ssm_next_state(ssm);
962 		break;
963 	case CAPSM_1001_FIRE_BULK: ;
964 		capsm_fire_bulk (ssm);
965 		break;
966 	case CAPSM_1001_WRITEV_1:
967 		sm_write_regs(ssm, capsm_1001_writev_1, G_N_ELEMENTS(capsm_1001_writev_1));
968 		break;
969 	case CAPSM_1001_WRITEV_2:
970 		sm_write_regs(ssm, capsm_1001_writev_2, G_N_ELEMENTS(capsm_1001_writev_2));
971 		break;
972 	case CAPSM_1001_WRITEV_3:
973 		sm_write_regs(ssm, capsm_1001_writev_3, G_N_ELEMENTS(capsm_1001_writev_3));
974 		break;
975 	case CAPSM_1001_WRITEV_4:
976 		sm_write_regs(ssm, capsm_1001_writev_4, G_N_ELEMENTS(capsm_1001_writev_4));
977 		break;
978 	case CAPSM_1001_WRITEV_5:
979 		sm_write_regs(ssm, capsm_1001_writev_5, G_N_ELEMENTS(capsm_1001_writev_5));
980 		break;
981 	}
982 }
983 
984 /***** DEINITIALIZATION *****/
985 
986 enum deinitsm_2016_states {
987 	DEINITSM_2016_WRITEV,
988 	DEINITSM_2016_NUM_STATES,
989 };
990 
991 enum deinitsm_1000_states {
992 	DEINITSM_1000_WRITEV,
993 	DEINITSM_1000_NUM_STATES,
994 };
995 
996 enum deinitsm_1001_states {
997 	DEINITSM_1001_WRITEV,
998 	DEINITSM_1001_NUM_STATES,
999 };
1000 
deinitsm_2016_run_state(struct fpi_ssm * ssm)1001 static void deinitsm_2016_run_state(struct fpi_ssm *ssm)
1002 {
1003 	switch (ssm->cur_state) {
1004 	case DEINITSM_2016_WRITEV:
1005 		sm_write_regs(ssm, deinitsm_2016_writev, G_N_ELEMENTS(deinitsm_2016_writev));
1006 		break;
1007 	}
1008 }
1009 
deinitsm_1000_run_state(struct fpi_ssm * ssm)1010 static void deinitsm_1000_run_state(struct fpi_ssm *ssm)
1011 {
1012 	switch (ssm->cur_state) {
1013 	case DEINITSM_1000_WRITEV:
1014 		sm_write_regs(ssm, deinitsm_1000_writev, G_N_ELEMENTS(deinitsm_1000_writev));
1015 		break;
1016 	}
1017 }
1018 
deinitsm_1001_run_state(struct fpi_ssm * ssm)1019 static void deinitsm_1001_run_state(struct fpi_ssm *ssm)
1020 {
1021 	switch (ssm->cur_state) {
1022 	case DEINITSM_1001_WRITEV:
1023 		sm_write_regs(ssm, deinitsm_1001_writev, G_N_ELEMENTS(deinitsm_1001_writev));
1024 		break;
1025 	}
1026 }
1027 
1028 /***** INITIALIZATION *****/
1029 
1030 enum initsm_2016_states {
1031 	INITSM_2016_WRITEV_1,
1032 	INITSM_2016_READ_09,
1033 	INITSM_2016_WRITE_09,
1034 	INITSM_2016_READ_13,
1035 	INITSM_2016_WRITE_13,
1036 	INITSM_2016_WRITE_04,
1037 	INITSM_2016_WRITE_05,
1038 	INITSM_2016_NUM_STATES,
1039 };
1040 
1041 enum initsm_1000_states {
1042 	INITSM_1000_WRITEV_1,
1043 	INITSM_1000_NUM_STATES,
1044 };
1045 
1046 enum initsm_1001_states {
1047 	INITSM_1001_WRITEV_1,
1048 	INITSM_1001_WRITEV_2,
1049 	INITSM_1001_WRITEV_3,
1050 	INITSM_1001_WRITEV_4,
1051 	INITSM_1001_WRITEV_5,
1052 	INITSM_1001_NUM_STATES,
1053 };
1054 
initsm_2016_run_state(struct fpi_ssm * ssm)1055 static void initsm_2016_run_state(struct fpi_ssm *ssm)
1056 {
1057 	struct fp_img_dev *dev = ssm->priv;
1058 	struct sonly_dev *sdev = dev->priv;
1059 
1060 	switch (ssm->cur_state) {
1061 	case INITSM_2016_WRITEV_1:
1062 		sm_write_regs(ssm, initsm_2016_writev_1, G_N_ELEMENTS(initsm_2016_writev_1));
1063 		break;
1064 	case INITSM_2016_READ_09:
1065 		sm_read_reg(ssm, 0x09);
1066 		break;
1067 	case INITSM_2016_WRITE_09:
1068 		sm_write_reg(ssm, 0x09, sdev->read_reg_result & ~0x08);
1069 		break;
1070 	case INITSM_2016_READ_13:
1071 		sm_read_reg(ssm, 0x13);
1072 		break;
1073 	case INITSM_2016_WRITE_13:
1074 		sm_write_reg(ssm, 0x13, sdev->read_reg_result & ~0x10);
1075 		break;
1076 	case INITSM_2016_WRITE_04:
1077 		sm_write_reg(ssm, 0x04, 0x00);
1078 		break;
1079 	case INITSM_2016_WRITE_05:
1080 		sm_write_reg(ssm, 0x05, 0x00);
1081 		break;
1082 	}
1083 }
1084 
initsm_1000_run_state(struct fpi_ssm * ssm)1085 static void initsm_1000_run_state(struct fpi_ssm *ssm)
1086 {
1087 	switch (ssm->cur_state) {
1088 	case INITSM_1000_WRITEV_1:
1089 		sm_write_regs(ssm, initsm_1000_writev_1, G_N_ELEMENTS(initsm_1000_writev_1));
1090 		break;
1091 	}
1092 }
1093 
initsm_1001_run_state(struct fpi_ssm * ssm)1094 static void initsm_1001_run_state(struct fpi_ssm *ssm)
1095 {
1096 	switch (ssm->cur_state) {
1097 	case INITSM_1001_WRITEV_1:
1098 		sm_write_regs(ssm, initsm_1001_writev_1, G_N_ELEMENTS(initsm_1001_writev_1));
1099 		break;
1100 	case INITSM_1001_WRITEV_2:
1101 		sm_write_regs(ssm, initsm_1001_writev_2, G_N_ELEMENTS(initsm_1001_writev_2));
1102 		break;
1103 	case INITSM_1001_WRITEV_3:
1104 		sm_write_regs(ssm, initsm_1001_writev_3, G_N_ELEMENTS(initsm_1001_writev_3));
1105 		break;
1106 	case INITSM_1001_WRITEV_4:
1107 		sm_write_regs(ssm, initsm_1001_writev_4, G_N_ELEMENTS(initsm_1001_writev_4));
1108 		break;
1109 	case INITSM_1001_WRITEV_5:
1110 		sm_write_regs(ssm, initsm_1001_writev_5, G_N_ELEMENTS(initsm_1001_writev_5));
1111 		break;
1112 	}
1113 }
1114 
1115 /***** CAPTURE LOOP *****/
1116 
1117 enum loopsm_states {
1118 	LOOPSM_RUN_AWFSM,
1119 	LOOPSM_AWAIT_FINGER,
1120 	LOOPSM_RUN_CAPSM,
1121 	LOOPSM_CAPTURE,
1122 	LOOPSM_RUN_DEINITSM,
1123 	LOOPSM_FINAL,
1124 	LOOPSM_NUM_STATES,
1125 };
1126 
loopsm_run_state(struct fpi_ssm * ssm)1127 static void loopsm_run_state(struct fpi_ssm *ssm)
1128 {
1129 	struct fp_img_dev *dev = ssm->priv;
1130 	struct sonly_dev *sdev = dev->priv;
1131 
1132 	switch (ssm->cur_state) {
1133 	case LOOPSM_RUN_AWFSM: ;
1134 		switch (sdev->dev_model) {
1135 		case UPEKSONLY_1001:
1136 			if (sdev->deactivating) {
1137 				fpi_ssm_mark_completed(ssm);
1138 			} else {
1139 				fpi_ssm_next_state(ssm);
1140 			}
1141 		break;
1142 		default:
1143 			if (sdev->deactivating) {
1144 				fpi_ssm_mark_completed(ssm);
1145 			} else {
1146 				struct fpi_ssm *awfsm = NULL;
1147 				switch (sdev->dev_model) {
1148 				case UPEKSONLY_2016:
1149 					awfsm = fpi_ssm_new(dev->dev, awfsm_2016_run_state,
1150 						AWFSM_2016_NUM_STATES);
1151 					break;
1152 				case UPEKSONLY_1000:
1153 					awfsm = fpi_ssm_new(dev->dev, awfsm_1000_run_state,
1154 						AWFSM_1000_NUM_STATES);
1155 					break;
1156 				}
1157 				awfsm->priv = dev;
1158 				fpi_ssm_start_subsm(ssm, awfsm);
1159 			}
1160 			break;
1161 		}
1162 		break;
1163 	case LOOPSM_AWAIT_FINGER:
1164 		switch (sdev->dev_model) {
1165 		case UPEKSONLY_1001:
1166 			fpi_ssm_next_state(ssm);
1167 			break;
1168 		default:
1169 			sm_await_intr(ssm);
1170 			break;
1171 		}
1172 		break;
1173 	case LOOPSM_RUN_CAPSM: ;
1174 		struct fpi_ssm *capsm = NULL;
1175 		switch (sdev->dev_model) {
1176 		case UPEKSONLY_2016:
1177 			capsm = fpi_ssm_new(dev->dev, capsm_2016_run_state,
1178 				CAPSM_2016_NUM_STATES);
1179 			break;
1180 		case UPEKSONLY_1000:
1181 			capsm = fpi_ssm_new(dev->dev, capsm_1000_run_state,
1182 				CAPSM_1000_NUM_STATES);
1183 			break;
1184 		case UPEKSONLY_1001:
1185 			capsm = fpi_ssm_new(dev->dev, capsm_1001_run_state,
1186 				CAPSM_1001_NUM_STATES);
1187 			break;
1188 		}
1189 		capsm->priv = dev;
1190 		fpi_ssm_start_subsm(ssm, capsm);
1191 		break;
1192 	case LOOPSM_CAPTURE:
1193 		break;
1194 	case LOOPSM_RUN_DEINITSM: ;
1195 		struct fpi_ssm *deinitsm = NULL;
1196 		switch (sdev->dev_model) {
1197 		case UPEKSONLY_2016:
1198 			deinitsm = fpi_ssm_new(dev->dev, deinitsm_2016_run_state,
1199 				DEINITSM_2016_NUM_STATES);
1200 			break;
1201 		case UPEKSONLY_1000:
1202 			deinitsm = fpi_ssm_new(dev->dev, deinitsm_1000_run_state,
1203 				DEINITSM_1000_NUM_STATES);
1204 			break;
1205 		case UPEKSONLY_1001:
1206 			deinitsm = fpi_ssm_new(dev->dev, deinitsm_1001_run_state,
1207 				DEINITSM_1001_NUM_STATES);
1208 			break;
1209 		}
1210 		sdev->capturing = FALSE;
1211 		deinitsm->priv = dev;
1212 		fpi_ssm_start_subsm(ssm, deinitsm);
1213 		break;
1214 	case LOOPSM_FINAL:
1215 		fpi_ssm_jump_to_state(ssm, LOOPSM_RUN_AWFSM);
1216 		break;
1217 	}
1218 
1219 }
1220 
1221 /***** DRIVER STUFF *****/
1222 
deactivate_done(struct fp_img_dev * dev)1223 static void deactivate_done(struct fp_img_dev *dev)
1224 {
1225 	struct sonly_dev *sdev = dev->priv;
1226 
1227 	fp_dbg("");
1228 	free_img_transfers(sdev);
1229 	g_free(sdev->rowbuf);
1230 	sdev->rowbuf = NULL;
1231 
1232 	if (sdev->rows) {
1233 		g_slist_foreach(sdev->rows, (GFunc) g_free, NULL);
1234 		sdev->rows = NULL;
1235 	}
1236 
1237 	fpi_imgdev_deactivate_complete(dev);
1238 }
1239 
dev_deactivate(struct fp_img_dev * dev)1240 static void dev_deactivate(struct fp_img_dev *dev)
1241 {
1242 	struct sonly_dev *sdev = dev->priv;
1243 
1244 	if (!sdev->capturing) {
1245 		deactivate_done(dev);
1246 		return;
1247 	}
1248 
1249 	sdev->deactivating = TRUE;
1250 	sdev->killing_transfers = ITERATE_SSM;
1251 	sdev->kill_ssm = sdev->loopsm;
1252 	cancel_img_transfers(dev);
1253 }
1254 
loopsm_complete(struct fpi_ssm * ssm)1255 static void loopsm_complete(struct fpi_ssm *ssm)
1256 {
1257 	struct fp_img_dev *dev = ssm->priv;
1258 	struct sonly_dev *sdev = dev->priv;
1259 	int r = ssm->error;
1260 
1261 	fpi_ssm_free(ssm);
1262 
1263 	if (sdev->deactivating) {
1264 		deactivate_done(dev);
1265 		return;
1266 	}
1267 
1268 	if (r) {
1269 		fpi_imgdev_session_error(dev, r);
1270 		return;
1271 	}
1272 }
1273 
initsm_complete(struct fpi_ssm * ssm)1274 static void initsm_complete(struct fpi_ssm *ssm)
1275 {
1276 	struct fp_img_dev *dev = ssm->priv;
1277 	struct sonly_dev *sdev = dev->priv;
1278 	int r = ssm->error;
1279 
1280 	fpi_ssm_free(ssm);
1281 	fpi_imgdev_activate_complete(dev, r);
1282 	if (r != 0)
1283 		return;
1284 
1285 	sdev->loopsm = fpi_ssm_new(dev->dev, loopsm_run_state, LOOPSM_NUM_STATES);
1286 	sdev->loopsm->priv = dev;
1287 	fpi_ssm_start(sdev->loopsm, loopsm_complete);
1288 }
1289 
dev_activate(struct fp_img_dev * dev,enum fp_imgdev_state state)1290 static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
1291 {
1292 	struct sonly_dev *sdev = dev->priv;
1293 	struct fpi_ssm *ssm = NULL;
1294 	int i;
1295 
1296 	sdev->deactivating = FALSE;
1297 	sdev->capturing = FALSE;
1298 
1299 	memset(sdev->img_transfer, 0,
1300 		NUM_BULK_TRANSFERS * sizeof(struct libusb_transfer *));
1301 	sdev->img_transfer_data =
1302 		g_malloc0(sizeof(struct img_transfer_data) * NUM_BULK_TRANSFERS);
1303 	sdev->num_flying = 0;
1304 	for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
1305 		unsigned char *data;
1306 		sdev->img_transfer[i] = libusb_alloc_transfer(0);
1307 		if (!sdev->img_transfer[i]) {
1308 			free_img_transfers(sdev);
1309 			return -ENOMEM;
1310 		}
1311 		sdev->img_transfer_data[i].idx = i;
1312 		sdev->img_transfer_data[i].dev = dev;
1313 		data = g_malloc(4096);
1314 		libusb_fill_bulk_transfer(sdev->img_transfer[i], dev->udev, 0x81, data,
1315 			4096, img_data_cb, &sdev->img_transfer_data[i], 0);
1316 	}
1317 
1318 	switch (sdev->dev_model) {
1319 	case UPEKSONLY_2016:
1320 		ssm = fpi_ssm_new(dev->dev, initsm_2016_run_state, INITSM_2016_NUM_STATES);
1321 		break;
1322 	case UPEKSONLY_1000:
1323 		ssm = fpi_ssm_new(dev->dev, initsm_1000_run_state, INITSM_1000_NUM_STATES);
1324 		break;
1325 	case UPEKSONLY_1001:
1326 		ssm = fpi_ssm_new(dev->dev, initsm_1001_run_state, INITSM_1001_NUM_STATES);
1327 		break;
1328 	}
1329 	ssm->priv = dev;
1330 	fpi_ssm_start(ssm, initsm_complete);
1331 	return 0;
1332 }
1333 
dev_init(struct fp_img_dev * dev,unsigned long driver_data)1334 static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
1335 {
1336 	int r;
1337 	struct sonly_dev *sdev;
1338 
1339 	r = libusb_set_configuration(dev->udev, 1);
1340 	if (r < 0) {
1341 		fp_err("could not set configuration 1");
1342 		return r;
1343 	}
1344 
1345 	r = libusb_claim_interface(dev->udev, 0);
1346 	if (r < 0) {
1347 		fp_err("could not claim interface 0: %s", libusb_error_name(r));
1348 		return r;
1349 	}
1350 
1351 	sdev = dev->priv = g_malloc0(sizeof(struct sonly_dev));
1352 	sdev->dev_model = (int)driver_data;
1353 	switch (driver_data) {
1354 	case UPEKSONLY_1000:
1355 		sdev->img_width = IMG_WIDTH_1000;
1356 		upeksonly_driver.img_width = IMG_WIDTH_1000;
1357 		assembling_ctx.line_width = IMG_WIDTH_1000;
1358 		break;
1359 	case UPEKSONLY_1001:
1360 		sdev->img_width = IMG_WIDTH_1001;
1361 		upeksonly_driver.img_width = IMG_WIDTH_1001;
1362 		upeksonly_driver.bz3_threshold = 25;
1363 		assembling_ctx.line_width = IMG_WIDTH_1001;
1364 		break;
1365 	case UPEKSONLY_2016:
1366 		sdev->img_width = IMG_WIDTH_2016;
1367 		upeksonly_driver.img_width = IMG_WIDTH_2016;
1368 		assembling_ctx.line_width = IMG_WIDTH_2016;
1369 		break;
1370 	}
1371 	fpi_imgdev_open_complete(dev, 0);
1372 	return 0;
1373 }
1374 
dev_deinit(struct fp_img_dev * dev)1375 static void dev_deinit(struct fp_img_dev *dev)
1376 {
1377 	g_free(dev->priv);
1378 	libusb_release_interface(dev->udev, 0);
1379 	fpi_imgdev_close_complete(dev);
1380 }
1381 
dev_discover(struct libusb_device_descriptor * dsc,uint32_t * devtype)1382 static int dev_discover(struct libusb_device_descriptor *dsc, uint32_t *devtype)
1383 {
1384 	if (dsc->idProduct == 0x2016) {
1385 		if (dsc->bcdDevice == 1) /* Revision 1 is what we're interested in */
1386 			return 1;
1387 	}
1388 	if (dsc->idProduct == 0x1000) {
1389 		if (dsc->bcdDevice == 0x0033) /* Looking for revision 0.33 */
1390 			return 1;
1391 	}
1392 
1393 	if (dsc->idProduct == 0x1001)
1394 		return 1;
1395 
1396 	return 0;
1397 }
1398 
1399 static const struct usb_id id_table[] = {
1400 	{ .vendor = 0x147e, .product = 0x2016, .driver_data = UPEKSONLY_2016 },
1401 	{ .vendor = 0x147e, .product = 0x1000, .driver_data = UPEKSONLY_1000 },
1402 	{ .vendor = 0x147e, .product = 0x1001, .driver_data = UPEKSONLY_1001 },
1403 	{ 0, 0, 0, },
1404 };
1405 
1406 struct fp_img_driver upeksonly_driver = {
1407 	.driver = {
1408 		.id = UPEKSONLY_ID,
1409 		.name = FP_COMPONENT,
1410 		.full_name = "UPEK TouchStrip Sensor-Only",
1411 		.id_table = id_table,
1412 		.scan_type = FP_SCAN_TYPE_SWIPE,
1413 		.discover = dev_discover,
1414 	},
1415 	.flags = 0,
1416 	.img_width = -1,
1417 	.img_height = -1,
1418 
1419 	.open = dev_init,
1420 	.close = dev_deinit,
1421 	.activate = dev_activate,
1422 	.deactivate = dev_deactivate,
1423 };
1424 
1425