1 /*
2  * EgisTec ES603 driver for libfprint
3  * Copyright (C) 2012 Patrick Marlier
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /* EgisTec ES603 device information
21  *   Sensor area: 192 x 4 pixels
22  *   Sensor gray: 16 gray levels/sensor pixel
23  *   Sensor resolution: 508 dpi
24  *   USB Manufacturer ID: 1C7A
25  *   USB Product ID: 0603
26  *
27  * Possible compatibility LTT-SS500/SS501
28  *
29  * Extra features not present in this driver (see https://code.google.com/p/etes603):
30  *   Tuning of DTVRT for contact detection
31  *   Contact detection via capacitance
32  *   Capture mode using assembled frames (usually better quality)
33  *
34  */
35 
36 #include <string.h>
37 #include <stdint.h>
38 #include <stdarg.h>
39 #include <errno.h>
40 #include <assert.h>
41 #include <libusb.h>
42 #include <glib.h>
43 
44 #define FP_COMPONENT "etes603"
45 #include <fp_internal.h>
46 #include "driver_ids.h"
47 
48 /* libusb defines */
49 #define EP_IN              0x81
50 #define EP_OUT             0x02
51 /* Note that 1000 ms is usually enough but with CMD_READ_FE could be longer
52  * since the sensor is waiting motion. */
53 #define BULK_TIMEOUT       1000
54 
55 /* es603 defines */
56 #define FRAME_WIDTH        192  /* pixels per row */
57 #define FRAME_HEIGHT       4    /* number of rows */
58 #define FRAME_SIZE         384  /* size in bytes (4 bits per pixels) */
59 #define FE_WIDTH           256  /* pixels per row for Fly-Estimation */
60 #define FE_HEIGHT          500  /* number of rows for Fly-Estimation */
61 #define FE_SIZE            64000 /* size in bytes (4 bits per pixels) */
62 
63 #define GAIN_SMALL_INIT    0x23 /* Initial small gain */
64 #define VRT_MAX	           0x3F /* Maximum value for VRT */
65 #define VRB_MAX            0x3A /* Maximum value for VRB */
66 #define DTVRT_MAX          0x3A /* Maximum value for DTVRT */
67 #define DCOFFSET_MIN       0x00 /* Minimum value for DCoffset */
68 #define DCOFFSET_MAX       0x35 /* Maximum value for DCoffset */
69 
70 /* es603 commands */
71 #define CMD_READ_REG       0x01
72 #define CMD_WRITE_REG      0x02
73 #define CMD_READ_FRAME     0x03 /* Read the sensor area */
74 #define CMD_READ_FE        0x06 /* Read a fingerprint using Fly-Estimation */
75 #define CMD_20             0x20 /* ? */
76 #define CMD_25             0x25 /* ? */
77 #define CMD_60             0x60 /* ? */
78 
79 #define CMD_OK             0x01 /* Command successfully executed */
80 
81 /* es603 registers */
82 #define REG_MAX            0x18 /* Maximum number of registers in one message */
83 #define REG_MODE_CONTROL   0x02 /* Mode control */
84 #define REG_03             0x03 /* Contact register? */
85 #define REG_04             0x04 /* ? */
86 #define REG_10             0x10 /* MVS FRMBUF control */
87 #define REG_1A             0x1A /* ? */
88 /* BEGIN init sensor */
89 #define REG_20             0x20 /* (def: 0x00) */
90 #define REG_21             0x21 /* Small gain (def: 0x23) */
91 #define REG_22             0x22 /* Normal gain (def: 0x21) */
92 #define REG_23             0x23 /* Large gain (def: 0x20) */
93 #define REG_24             0x24 /* (def: 0x14) */
94 #define REG_25             0x25 /* (def: 0x6A) */
95 #define REG_26             0x26 /* VRB again? (def: 0x00) */
96 #define REG_27             0x27 /* VRT again? (def: 0x00) */
97 #define REG_28             0x28 /* (def: 0x00) */
98 #define REG_29             0x29 /* (def: 0xC0) */
99 #define REG_2A             0x2A /* (def: 0x50) */
100 #define REG_2B             0x2B /* (def: 0x50) */
101 #define REG_2C             0x2C /* (def: 0x4D) */
102 #define REG_2D             0x2D /* (def: 0x03) */
103 #define REG_2E             0x2E /* (def: 0x06) */
104 #define REG_2F             0x2F /* (def: 0x06) */
105 #define REG_30             0x30 /* (def: 0x10) */
106 #define REG_31             0x31 /* (def: 0x02) */
107 #define REG_32             0x32 /* (def: 0x14) */
108 #define REG_33             0x33 /* (def: 0x34) */
109 #define REG_34             0x34 /* (def: 0x01) */
110 #define REG_35             0x35 /* (def: 0x08) */
111 #define REG_36             0x36 /* (def: 0x03) */
112 #define REG_37             0x37 /* (def: 0x21) */
113 /* END init sensor */
114 
115 #define REG_ENC1           0x41 /* Encryption 1 */
116 #define REG_ENC2           0x42
117 #define REG_ENC3           0x43
118 #define REG_ENC4           0x44
119 #define REG_ENC5           0x45
120 #define REG_ENC6           0x46
121 #define REG_ENC7           0x47
122 #define REG_ENC8           0x48 /* Encryption 8 */
123 
124 #define REG_50             0x50 /* ? For contact detection */
125 #define REG_51             0x51 /* ? */
126 #define REG_59             0x59 /* ? */
127 #define REG_5A             0x5A /* ? */
128 #define REG_5B             0x5B /* ? */
129 
130 #define REG_INFO0          0x70 /* Sensor model byte0 */
131 #define REG_INFO1          0x71 /* Sensor model byte1 */
132 #define REG_INFO2          0x72 /* Sensor model byte2 */
133 #define REG_INFO3          0x73 /* Sensor model byte3 */
134 
135 #define REG_GAIN           0xE0
136 #define REG_VRT            0xE1
137 #define REG_VRB            0xE2
138 #define REG_DTVRT          0xE3 /* used for contact detection */
139 #define REG_VCO_CONTROL    0xE5 /* 0x13 (IDLE?), 0x14 (REALTIME) */
140 #define REG_DCOFFSET       0xE6
141 
142 #define REG_F0             0xF0 /* ? init:0x00 close:0x01 */
143 #define REG_F2             0xF2 /* ? init:0x00 close:0x4E */
144 
145 #define REG_MODE_SLEEP     0x30 /* Sleep mode */
146 #define REG_MODE_CONTACT   0x31 /* Contact mode */
147 #define REG_MODE_SENSOR    0x33 /* Sensor mode */
148 #define REG_MODE_FP        0x34 /* FingerPrint mode (Fly-Estimation®) */
149 
150 #define REG_VCO_IDLE       0x13
151 #define REG_VCO_RT         0x14 /* Realtime */
152 
153 /* The size of the message header is 5 plus 1 for the command. */
154 #define MSG_HDR_SIZE       6
155 
156 /* This structure must be packed because it is a the raw message sent. */
157 struct egis_msg {
158 	uint8_t magic[5]; /* out: 'EGIS' 0x09 / in: 'SIGE' 0x0A */
159 	uint8_t cmd;
160 	union {
161 		struct {
162 			uint8_t nb;
163 			uint8_t regs[REG_MAX];
164 		} egis_readreg;
165 		struct {
166 			uint8_t regs[REG_MAX];
167 		} sige_readreg;
168 		struct {
169 			uint8_t nb;
170 			struct {
171 				uint8_t reg;
172 				uint8_t val;
173 			} regs[REG_MAX];
174 		} egis_writereg;
175 		struct {
176 			uint8_t length_factor;
177 			uint8_t length;
178 			uint8_t use_gvv;
179 			uint8_t gain;
180 			uint8_t vrt;
181 			uint8_t vrb;
182 		} egis_readf;
183 		struct {
184 			uint8_t len[2];
185 			uint8_t val[3];
186 		} egis_readfp;
187 		struct {
188 			uint8_t val[5];
189 		} sige_misc;
190 		uint8_t padding[0x40-6]; /* Ensure size of 0x40 */
191 	};
192 } __attribute__((packed));
193 
194 
195 /* Structure to keep information between asynchronous functions. */
196 struct etes603_dev {
197 	uint8_t regs[256];
198 	struct egis_msg *req;
199 	size_t req_len;
200 	struct egis_msg *ans;
201 	size_t ans_len;
202 
203 	uint8_t *fp;
204 	uint16_t fp_height;
205 
206 	uint8_t tunedc_min;
207 	uint8_t tunedc_max;
208 
209 	/* Device parameters */
210 	uint8_t gain;
211 	uint8_t dcoffset;
212 	uint8_t vrt;
213 	uint8_t vrb;
214 
215 	unsigned int is_active;
216 };
217 
218 static void m_start_fingerdetect(struct fp_img_dev *idev);
219 /*
220  * Prepare the header of the message to be sent to the device.
221  */
msg_header_prepare(struct egis_msg * msg)222 static void msg_header_prepare(struct egis_msg *msg)
223 {
224 	msg->magic[0] = 'E';
225 	msg->magic[1] = 'G';
226 	msg->magic[2] = 'I';
227 	msg->magic[3] = 'S';
228 	msg->magic[4] = 0x09;
229 }
230 
231 /*
232  * Check that the header of the received message is correct.
233  */
msg_header_check(struct egis_msg * msg)234 static int msg_header_check(struct egis_msg *msg)
235 {
236 	if (msg->magic[0] == 'S' && msg->magic[1] == 'I'
237 	    && msg->magic[2] == 'G' && msg->magic[3] == 'E'
238 	    && msg->magic[4] == 0x0A)
239 		return 0;
240 	return -1;
241 }
242 
243 /*
244  * Prepare message to ask for a frame.
245  */
msg_get_frame(struct etes603_dev * dev,uint8_t use_gvv,uint8_t gain,uint8_t vrt,uint8_t vrb)246 static void msg_get_frame(struct etes603_dev *dev,
247 	uint8_t use_gvv, uint8_t gain, uint8_t vrt, uint8_t vrb)
248 {
249 	struct egis_msg *msg = dev->req;
250 	msg_header_prepare(msg);
251 	msg->cmd = CMD_READ_FRAME;
252 	msg->egis_readf.length_factor = 0x01;
253 	/* length should be 0xC0 */
254 	msg->egis_readf.length = FRAME_WIDTH;
255 	msg->egis_readf.use_gvv = use_gvv;
256 	/* if use_gvv is set, gain/vrt/vrb are used */
257 	msg->egis_readf.gain = gain;
258 	msg->egis_readf.vrt = vrt;
259 	msg->egis_readf.vrb = vrb;
260 
261 	dev->req_len = MSG_HDR_SIZE + 6;
262 	dev->ans_len = FRAME_SIZE;
263 }
264 
265 /*
266  * Prepare message to ask for a fingerprint frame.
267  */
msg_get_fp(struct etes603_dev * dev,uint8_t len0,uint8_t len1,uint8_t v2,uint8_t v3,uint8_t v4)268 static void msg_get_fp(struct etes603_dev *dev, uint8_t len0, uint8_t len1,
269 	uint8_t v2, uint8_t v3, uint8_t v4)
270 {
271 	struct egis_msg *msg = dev->req;
272 	msg_header_prepare(msg);
273 	msg->cmd = CMD_READ_FE;
274 	/* Unknown values and always same on captured frames.
275 	 * 1st 2nd bytes is unsigned short for height, but only on value range
276 	 * 0x01 0xF4 (500), 0x02 0x00 (512), 0x02 0xF4 (756) are ok
277 	 */
278 	msg->egis_readfp.len[0] = len0;
279 	msg->egis_readfp.len[1] = len1;
280 	/* 3rd byte : ?? but changes frame size
281 	 * 4th byte : 0x00 -> can change width
282 	 * 5th byte : motion sensibility?
283 	 */
284 	msg->egis_readfp.val[0] = v2;
285 	msg->egis_readfp.val[1] = v3;
286 	msg->egis_readfp.val[2] = v4;
287 
288 	dev->req_len = MSG_HDR_SIZE + 5;
289 	dev->ans_len = FE_SIZE;
290 }
291 
292 /*
293  * Prepare message to read registers from the sensor.
294  * Variadic argument pattern: int reg, ...
295  */
msg_get_regs(struct etes603_dev * dev,int n_args,...)296 static void msg_get_regs(struct etes603_dev *dev, int n_args, ... )
297 {
298 	struct egis_msg *msg = dev->req;
299 	va_list ap;
300 	int i;
301 
302 	assert(n_args > 0 && n_args <= REG_MAX);
303 
304 	msg_header_prepare(msg);
305 	msg->cmd = CMD_READ_REG;
306 	msg->egis_readreg.nb = n_args;
307 	va_start(ap, n_args);
308 	for (i = 0; i < n_args; i++) {
309 		msg->egis_readreg.regs[i] = va_arg(ap, int);
310 	}
311 	va_end(ap);
312 
313 	dev->req_len = MSG_HDR_SIZE + 1 + n_args;
314 	dev->ans_len = MSG_HDR_SIZE + 1 + n_args;
315 }
316 
317 /*
318  * Parse the result of read register command.
319  */
msg_parse_regs(struct etes603_dev * dev)320 static int msg_parse_regs(struct etes603_dev *dev)
321 {
322 	size_t i, n_args;
323 	struct egis_msg *msg_req = dev->req;
324 	struct egis_msg *msg_ans = dev->ans;
325 	n_args = dev->ans_len - MSG_HDR_SIZE;
326 
327 	if (msg_header_check(msg_ans)) {
328 		return -1;
329 	}
330 	if (msg_ans->cmd != CMD_OK) {
331 		return -2;
332 	}
333 
334 	for (i = 0; i < n_args; i++) {
335 		int reg = msg_req->egis_readreg.regs[i];
336 		dev->regs[reg] = msg_ans->sige_readreg.regs[i];
337 	}
338 	return 0;
339 }
340 
341 /*
342  * Prepare message to write sensor's registers.
343  * Variadic arguments are: int reg, int val, ...
344  */
msg_set_regs(struct etes603_dev * dev,int n_args,...)345 static void msg_set_regs(struct etes603_dev *dev, int n_args, ...)
346 {
347 	struct egis_msg *msg = dev->req;
348 	va_list ap;
349 	int i;
350 
351 	assert(n_args != 0 && n_args % 2 == 0 && n_args <= REG_MAX * 2);
352 
353 	msg_header_prepare(msg);
354 	msg->cmd = CMD_WRITE_REG;
355 	msg->egis_writereg.nb = n_args / 2;
356 
357 	va_start(ap, n_args);
358 	for (i = 0; i < n_args / 2; i++) {
359 		msg->egis_writereg.regs[i].reg = va_arg(ap, int);
360 		msg->egis_writereg.regs[i].val = va_arg(ap, int);
361 	}
362 	va_end(ap);
363 
364 	dev->req_len = MSG_HDR_SIZE + 1 + n_args;
365 	dev->ans_len = MSG_HDR_SIZE + 1;
366 }
367 
msg_check_ok(struct etes603_dev * dev)368 static int msg_check_ok(struct etes603_dev *dev)
369 {
370 	struct egis_msg *msg = dev->ans;
371 	if (msg_header_check(msg)) {
372 		goto err;
373 	}
374 	if (msg->cmd != CMD_OK) {
375 		goto err;
376 	}
377 	return 0;
378 err:
379 	return -1;
380 }
381 
382 /*
383  * Check the model of the sensor.
384  */
check_info(struct etes603_dev * dev)385 static int check_info(struct etes603_dev *dev)
386 {
387 	if (dev->regs[0x70] == 0x4A && dev->regs[0x71] == 0x44
388 	    && dev->regs[0x72] == 0x49 && dev->regs[0x73] == 0x31)
389 		return 0;
390 	fp_err("unknown device parameters (REG_70:%02X REG_71:%02X "
391 		"REG_FIRMWARE:%02X REG_VERSION:%02X)",
392 		dev->regs[0x70], dev->regs[0x71], dev->regs[0x72],
393 		dev->regs[0x73]);
394 	return -1;
395 }
396 
msg_get_cmd20(struct etes603_dev * dev)397 static void msg_get_cmd20(struct etes603_dev *dev)
398 {
399 	struct egis_msg *msg = dev->req;
400 	msg_header_prepare(msg);
401 	msg->cmd = CMD_20;
402 	dev->req_len = MSG_HDR_SIZE;
403 }
404 
msg_check_cmd20(struct etes603_dev * dev)405 static int msg_check_cmd20(struct etes603_dev *dev)
406 {
407 	struct egis_msg *msg = dev->ans;
408 	if (msg_header_check(msg)) {
409 		fp_err("msg_header_check failed");
410 		return -1;
411 	}
412 	/* status or flashtype/flashinfo or ? */
413 	if (msg->cmd != 0x05
414 	    || msg->sige_misc.val[0] != 0x00
415 	    || msg->sige_misc.val[1] != 0x00) {
416 		fp_warn("unexpected answer CMD_20 from device(%02X %02X %02X)",
417 			msg->cmd, msg->sige_misc.val[0], msg->sige_misc.val[1]);
418 	}
419 
420 	return 0;
421 }
422 
msg_get_cmd25(struct etes603_dev * dev)423 static void msg_get_cmd25(struct etes603_dev *dev)
424 {
425 	struct egis_msg *msg = dev->req;
426 	msg_header_prepare(msg);
427 	msg->cmd = CMD_25;
428 	dev->req_len = MSG_HDR_SIZE;
429 }
430 
msg_check_cmd25(struct etes603_dev * dev)431 static int msg_check_cmd25(struct etes603_dev *dev)
432 {
433 	struct egis_msg *msg = dev->ans;
434 	if (msg_header_check(msg)) {
435 		fp_err("msg_header_check failed");
436 		goto err;
437 	}
438 	if (msg->cmd != CMD_OK) {
439 		fp_err("CMD_OK failed");
440 		goto err;
441 	}
442 	/* flashtype or status or ? */
443 	if (msg->sige_misc.val[0] != 0x00) {
444 		fp_warn("unexpected answer for CMD_25 (%02X)",
445 			msg->sige_misc.val[0]);
446 	}
447 	return 0;
448 err:
449 	return -1;
450 }
451 
msg_set_mode_control(struct etes603_dev * dev,uint8_t mode)452 static void msg_set_mode_control(struct etes603_dev *dev, uint8_t mode)
453 {
454 	msg_set_regs(dev, 2, REG_MODE_CONTROL, mode);
455 }
456 
457 
458 /* Processing functions */
459 
460 /*
461  * Return the brightness of a 4bpp frame
462  */
process_get_brightness(uint8_t * f,size_t s)463 static unsigned int process_get_brightness(uint8_t *f, size_t s)
464 {
465 	unsigned int i, sum = 0;
466 	for (i = 0; i < s; i++) {
467 		sum += f[i] >> 4;
468 		sum += f[i] & 0x0F;
469 	}
470 	return sum;
471 }
472 
473 /*
474  * Return the histogram of a 4bpp frame
475  */
process_hist(uint8_t * f,size_t s,float stat[5])476 static void process_hist(uint8_t *f, size_t s, float stat[5])
477 {
478 	float hist[16];
479 	float black_mean, white_mean;
480 	int i;
481 	/* Clean histogram */
482 	for (i = 0; i < 16; i++)
483 		hist[i] = 0.0;
484 	for (i = 0; i < s; i++) {
485 		hist[f[i] >> 4]++;
486 		hist[f[i] & 0x0F]++;
487 	}
488 	/* histogram average */
489 	for (i = 0; i < 16; i++) {
490 		hist[i] = hist[i] / (s * 2);
491 	}
492 	/* Average black/white pixels (full black and full white pixels
493 	 * are excluded). */
494 	black_mean = white_mean = 0.0;
495 	for (i = 1; i < 8; i++)
496 		black_mean += hist[i];
497 	for (i = 8; i < 15; i++)
498 		white_mean += hist[i];
499 	stat[0] = hist[0];
500 	stat[1] = black_mean;
501 	stat[2] = black_mean+white_mean;
502 	stat[3] = white_mean;
503 	stat[4] = hist[15];
504 	fp_dbg("fullb=%6f black=%6f grey=%6f white=%6f fullw=%6f",
505 		hist[0], black_mean, black_mean+white_mean, white_mean,
506 		hist[15]);
507 }
508 
509 /*
510  * Return true if the frame is almost empty.
511  */
process_frame_empty(uint8_t * frame,size_t size)512 static int process_frame_empty(uint8_t *frame, size_t size)
513 {
514 	unsigned int sum = process_get_brightness(frame, size);
515 	/* Allow an average of 'threshold' luminosity per pixel */
516 	if (sum < size)
517 		return 1;
518 	return 0;
519 }
520 
521 /* Transform 4 bits image to 8 bits image */
process_4to8_bpp(uint8_t * input,unsigned int input_size,uint8_t * output)522 static void process_4to8_bpp(uint8_t *input, unsigned int input_size,
523 	uint8_t *output)
524 {
525 	unsigned int i, j = 0;
526 	for (i = 0; i < input_size; i++, j += 2) {
527 		/* 16 gray levels transform to 256 levels using << 4 */
528 		output[j] = input[i] & 0xF0;
529 		output[j+1] = input[i] << 4;
530 	}
531 }
532 
533 /*
534  * Remove duplicated lines at the end of a fingerprint.
535  */
process_remove_fp_end(struct etes603_dev * dev)536 static void process_remove_fp_end(struct etes603_dev *dev)
537 {
538 	unsigned int i;
539 	/* 2 last lines with Fly-Estimation are the empty pattern. */
540 	uint8_t *pattern = dev->fp + (dev->fp_height - 2) * FE_WIDTH / 2;
541 	for (i = 2; i < dev->fp_height; i+= 2) {
542 		if (memcmp(pattern, pattern - (i * FE_WIDTH / 2), FE_WIDTH))
543 			break;
544 	}
545 	dev->fp_height -= i;
546 	fp_dbg("Removing %d empty lines from image", i - 2);
547 }
548 
reset_param(struct etes603_dev * dev)549 static void reset_param(struct etes603_dev *dev)
550 {
551 	dev->dcoffset = 0;
552 	dev->vrt = 0;
553 	dev->vrb = 0;
554 	dev->gain = 0;
555 }
556 
557 
558 /* Asynchronous stuff */
559 
560 enum {
561 	INIT_CHECK_INFO_REQ,
562 	INIT_CHECK_INFO_ANS,
563 	INIT_CMD20_REQ,
564 	INIT_CMD20_ANS,
565 	INIT_CMD25_REQ,
566 	INIT_CMD25_ANS,
567 	INIT_SENSOR_REQ,
568 	INIT_SENSOR_ANS,
569 	INIT_ENC_REQ,
570 	INIT_ENC_ANS,
571 	INIT_REGS_REQ,
572 	INIT_REGS_ANS,
573 	INIT_NUM_STATES
574 };
575 
576 enum {
577 	TUNEDC_INIT,
578 	TUNEDC_SET_DCOFFSET_REQ,
579 	TUNEDC_SET_DCOFFSET_ANS,
580 	TUNEDC_GET_FRAME_REQ,
581 	TUNEDC_GET_FRAME_ANS,
582 	TUNEDC_FINAL_SET_REG2122_REQ,
583 	TUNEDC_FINAL_SET_REG2122_ANS,
584 	TUNEDC_FINAL_SET_GAIN_REQ,
585 	TUNEDC_FINAL_SET_GAIN_ANS,
586 	TUNEDC_FINAL_SET_DCOFFSET_REQ,
587 	TUNEDC_FINAL_SET_DCOFFSET_ANS,
588 	TUNEDC_NUM_STATES
589 };
590 
591 enum {
592 	TUNEVRB_INIT,
593 	TUNEVRB_GET_GAIN_REQ,
594 	TUNEVRB_GET_GAIN_ANS,
595 	TUNEVRB_GET_DCOFFSET_REQ,
596 	TUNEVRB_GET_DCOFFSET_ANS,
597 	TUNEVRB_SET_DCOFFSET_REQ,
598 	TUNEVRB_SET_DCOFFSET_ANS,
599 	TUNEVRB_FRAME_REQ,
600 	TUNEVRB_FRAME_ANS,
601 	TUNEVRB_FINAL_SET_DCOFFSET_REQ,
602 	TUNEVRB_FINAL_SET_DCOFFSET_ANS,
603 	TUNEVRB_FINAL_SET_REG2627_REQ,
604 	TUNEVRB_FINAL_SET_REG2627_ANS,
605 	TUNEVRB_FINAL_SET_GAINVRTVRB_REQ,
606 	TUNEVRB_FINAL_SET_GAINVRTVRB_ANS,
607 	TUNEVRB_FINAL_SET_MODE_SLEEP_REQ,
608 	TUNEVRB_FINAL_SET_MODE_SLEEP_ANS,
609 	TUNEVRB_NUM_STATES
610 };
611 
612 enum {
613 	FGR_FPA_INIT_SET_MODE_SLEEP_REQ,
614 	FGR_FPA_INIT_SET_MODE_SLEEP_ANS,
615 	FGR_FPA_INIT_SET_DCOFFSET_REQ,
616 	FGR_FPA_INIT_SET_DCOFFSET_ANS,
617 	FGR_FPA_INIT_SET_GAINVRTVRB_REQ,
618 	FGR_FPA_INIT_SET_GAINVRTVRB_ANS,
619 	FGR_FPA_INIT_SET_VCO_CONTROL_RT_REQ,
620 	FGR_FPA_INIT_SET_VCO_CONTROL_RT_ANS,
621 	FGR_FPA_INIT_SET_REG04_REQ,
622 	FGR_FPA_INIT_SET_REG04_ANS,
623 	FGR_FPA_INIT_SET_MODE_SENSOR_REQ,
624 	FGR_FPA_INIT_SET_MODE_SENSOR_ANS,
625 	FGR_FPA_GET_FRAME_REQ,
626 	FGR_FPA_GET_FRAME_ANS,
627 	FGR_NUM_STATES
628 };
629 
630 enum {
631 	CAP_FP_INIT_SET_REG10_REQ,
632 	CAP_FP_INIT_SET_REG10_ANS,
633 	CAP_FP_INIT_SET_MODE_FP_REQ,
634 	CAP_FP_INIT_SET_MODE_FP_ANS,
635 	CAP_FP_GET_FP_REQ,
636 	CAP_FP_GET_FP_ANS,
637 	CAP_NUM_STATES
638 };
639 
640 enum {
641 	EXIT_SET_REGS_REQ,
642 	EXIT_SET_REGS_ANS,
643 	EXIT_NUM_STATES
644 };
645 
async_tx(struct fp_img_dev * idev,unsigned int ep,void * cb,void * cb_arg)646 static int async_tx(struct fp_img_dev *idev, unsigned int ep, void *cb,
647 	void *cb_arg)
648 {
649 	struct etes603_dev *dev = idev->priv;
650 	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
651 	unsigned char *buffer;
652 	int length;
653 
654 	if (!transfer)
655 		return -ENOMEM;
656 
657 	if (ep == EP_OUT) {
658 		buffer = (unsigned char *)dev->req;
659 		length = dev->req_len;
660 	} else if (ep == EP_IN) {
661 		buffer = (unsigned char *)dev->ans;
662 		length = dev->ans_len;
663 	} else {
664 		return -EIO;
665 	}
666 	libusb_fill_bulk_transfer(transfer, idev->udev, ep, buffer, length,
667 				  cb, cb_arg, BULK_TIMEOUT);
668 
669 	if (libusb_submit_transfer(transfer)) {
670 		libusb_free_transfer(transfer);
671 		return -EIO;
672 	}
673 	return 0;
674 }
675 
676 
async_tx_cb(struct libusb_transfer * transfer)677 static void async_tx_cb(struct libusb_transfer *transfer)
678 {
679 	struct fpi_ssm *ssm = transfer->user_data;
680 	struct fp_img_dev *idev = ssm->priv;
681 	struct etes603_dev *dev = idev->priv;
682 
683 	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
684 		fp_warn("transfer is not completed (status=%d)",
685 			transfer->status);
686 		fpi_ssm_mark_aborted(ssm, -EIO);
687 		libusb_free_transfer(transfer);
688 	} else {
689 		unsigned char endpoint = transfer->endpoint;
690 		int actual_length = transfer->actual_length;
691 		int length = transfer->length;
692 		/* Freeing now transfer since fpi_ssm_* functions are not
693 		 * returning directly. */
694 		libusb_free_transfer(transfer);
695 		if (endpoint == EP_OUT) {
696 			if (length != actual_length)
697 				fp_warn("length %d != actual_length %d",
698 					length, actual_length);
699 			/* Chained with the answer */
700 			if (async_tx(idev, EP_IN, async_tx_cb, ssm))
701 				fpi_ssm_mark_aborted(ssm, -EIO);
702 		} else if (endpoint == EP_IN) {
703 			dev->ans_len = actual_length;
704 			fpi_ssm_next_state(ssm);
705 		}
706 	}
707 }
708 
m_exit_state(struct fpi_ssm * ssm)709 static void m_exit_state(struct fpi_ssm *ssm)
710 {
711 	struct fp_img_dev *idev = ssm->priv;
712 	struct etes603_dev *dev = idev->priv;
713 
714 	switch (ssm->cur_state) {
715 	case EXIT_SET_REGS_REQ:
716 		msg_set_regs(dev, 4, REG_VCO_CONTROL, REG_VCO_IDLE,
717 			     REG_MODE_CONTROL, REG_MODE_SLEEP);
718 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
719 			goto err;
720 		break;
721 	case EXIT_SET_REGS_ANS:
722 		if (msg_check_ok(dev))
723 			goto err;
724 		fpi_ssm_mark_completed(ssm);
725 		break;
726 	default:
727 		fp_err("Unknown state %d", ssm->cur_state);
728 		goto err;
729 		break;
730 	}
731 
732 	return;
733 err:
734 	fpi_ssm_mark_aborted(ssm, -EIO);
735 }
736 
m_exit_complete(struct fpi_ssm * ssm)737 static void m_exit_complete(struct fpi_ssm *ssm)
738 {
739 	struct fp_img_dev *idev = ssm->priv;
740 
741 	if (ssm->error) {
742 		fp_err("Error switching the device to idle state");
743 	} else {
744 		fp_dbg("The device is now in idle state");
745 	}
746 	fpi_imgdev_deactivate_complete(idev);
747 	fpi_ssm_free(ssm);
748 }
749 
m_exit_start(struct fp_img_dev * idev)750 static void m_exit_start(struct fp_img_dev *idev)
751 {
752 	struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, m_exit_state,
753 					  EXIT_NUM_STATES);
754 	fp_dbg("Switching device to idle mode");
755 	ssm->priv = idev;
756 	fpi_ssm_start(ssm, m_exit_complete);
757 }
758 
m_capture_state(struct fpi_ssm * ssm)759 static void m_capture_state(struct fpi_ssm *ssm)
760 {
761 	struct fp_img_dev *idev = ssm->priv;
762 	struct etes603_dev *dev = idev->priv;
763 
764 	if (dev->is_active == FALSE) {
765 		fpi_ssm_mark_completed(ssm);
766 		return;
767 	}
768 
769 	switch (ssm->cur_state) {
770 	case CAP_FP_INIT_SET_REG10_REQ:
771 		/* Reset fingerprint */
772 		fp_dbg("Capturing a fingerprint...");
773 		memset(dev->fp, 0, FE_SIZE * 2);
774 		dev->fp_height = 0;
775 		msg_set_regs(dev, 2, REG_10, 0x92);
776 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
777 			goto err;
778 		break;
779 	case CAP_FP_INIT_SET_REG10_ANS:
780 		if (msg_check_ok(dev))
781 			goto err;
782 		fpi_ssm_next_state(ssm);
783 		break;
784 	case CAP_FP_INIT_SET_MODE_FP_REQ:
785 		msg_set_mode_control(dev, REG_MODE_FP);
786 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
787 			goto err;
788 		break;
789 	case CAP_FP_INIT_SET_MODE_FP_ANS:
790 		if (msg_check_ok(dev))
791 			goto err;
792 		fp_dbg("Capturing a 1st frame...");
793 		fpi_ssm_next_state(ssm);
794 		break;
795 	case CAP_FP_GET_FP_REQ:
796 		msg_get_fp(dev, 0x01, 0xF4, 0x02, 0x01, 0x64);
797 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
798 			goto err;
799 		break;
800 	case CAP_FP_GET_FP_ANS:
801 		memcpy(dev->fp + dev->fp_height * FE_WIDTH / 2, dev->ans,
802 			FE_SIZE);
803 		dev->fp_height += FE_HEIGHT;
804 		if (dev->fp_height <= FE_HEIGHT) {
805 			/* 2 lines are at least removed each time */
806 			dev->fp_height -= 2;
807 			fp_dbg("Capturing a 2nd frame...");
808 			fpi_ssm_jump_to_state(ssm, CAP_FP_GET_FP_REQ);
809 		} else {
810 			struct fp_img *img;
811 			unsigned int img_size;
812 			/* Remove empty parts 2 times for the 2 frames */
813 			process_remove_fp_end(dev);
814 			process_remove_fp_end(dev);
815 			img_size = dev->fp_height * FE_WIDTH;
816 			img = fpi_img_new(img_size);
817 			/* Images received are white on black, so invert it. */
818 			/* TODO detect sweep direction */
819 			img->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED;
820 			img->height = dev->fp_height;
821 			process_4to8_bpp(dev->fp, img_size / 2, img->data);
822 			fp_dbg("Sending the raw fingerprint image (%dx%d)",
823 				img->width, img->height);
824 			fpi_imgdev_image_captured(idev, img);
825 			fpi_imgdev_report_finger_status(idev, FALSE);
826 			fpi_ssm_mark_completed(ssm);
827 		}
828 		break;
829 	default:
830 		fp_err("Unknown state %d", ssm->cur_state);
831 		goto err;
832 		break;
833 	}
834 
835 	return;
836 err:
837 	fpi_ssm_mark_aborted(ssm, -EIO);
838 }
839 
m_capture_complete(struct fpi_ssm * ssm)840 static void m_capture_complete(struct fpi_ssm *ssm)
841 {
842 	struct fp_img_dev *idev = ssm->priv;
843 	struct etes603_dev *dev = idev->priv;
844 
845 	if (ssm->error) {
846 		if (idev->action_state != IMG_ACQUIRE_STATE_DEACTIVATING) {
847 			fp_err("Error while capturing fingerprint "
848 				"(ssm->error=%d)", ssm->error);
849 			fpi_imgdev_session_error(idev, ssm->error);
850 		}
851 	}
852 	fpi_ssm_free(ssm);
853 
854 	if (dev->is_active == TRUE) {
855 		fp_dbg("Device is still active, restarting finger detection");
856 		m_start_fingerdetect(idev);
857 	} else {
858 		fp_dbg("And it's over.");
859 	}
860 }
861 
m_finger_state(struct fpi_ssm * ssm)862 static void m_finger_state(struct fpi_ssm *ssm)
863 {
864 	struct fp_img_dev *idev = ssm->priv;
865 	struct etes603_dev *dev = idev->priv;
866 
867 	if (dev->is_active == FALSE) {
868 		fpi_ssm_mark_completed(ssm);
869 		return;
870 	}
871 
872 	switch (ssm->cur_state) {
873 	case FGR_FPA_INIT_SET_MODE_SLEEP_REQ:
874 		msg_set_mode_control(dev, REG_MODE_SLEEP);
875 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
876 			goto err;
877 		break;
878 	case FGR_FPA_INIT_SET_MODE_SLEEP_ANS:
879 		if (msg_check_ok(dev))
880 			goto err;
881 		fpi_ssm_next_state(ssm);
882 		break;
883 	case FGR_FPA_INIT_SET_DCOFFSET_REQ:
884 		msg_set_regs(dev, 2, REG_DCOFFSET, dev->dcoffset);
885 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
886 			goto err;
887 		break;
888 	case FGR_FPA_INIT_SET_DCOFFSET_ANS:
889 		if (msg_check_ok(dev))
890 			goto err;
891 		fpi_ssm_next_state(ssm);
892 		break;
893 	case FGR_FPA_INIT_SET_GAINVRTVRB_REQ:
894 		msg_set_regs(dev, 6, REG_GAIN, dev->gain, REG_VRT, dev->vrt,
895 			REG_VRB, dev->vrb);
896 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
897 			goto err;
898 		break;
899 	case FGR_FPA_INIT_SET_GAINVRTVRB_ANS:
900 		if (msg_check_ok(dev))
901 			goto err;
902 		fpi_ssm_next_state(ssm);
903 		break;
904 	case FGR_FPA_INIT_SET_VCO_CONTROL_RT_REQ:
905 		msg_set_regs(dev, 2, REG_VCO_CONTROL, REG_VCO_RT);
906 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
907 			goto err;
908 		break;
909 	case FGR_FPA_INIT_SET_VCO_CONTROL_RT_ANS:
910 		if (msg_check_ok(dev))
911 			goto err;
912 		fpi_ssm_next_state(ssm);
913 		break;
914 	case FGR_FPA_INIT_SET_REG04_REQ:
915 		msg_set_regs(dev, 2, REG_04, 0x00);
916 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
917 			goto err;
918 		break;
919 	case FGR_FPA_INIT_SET_REG04_ANS:
920 		if (msg_check_ok(dev))
921 			goto err;
922 		fpi_ssm_next_state(ssm);
923 		break;
924 	case FGR_FPA_INIT_SET_MODE_SENSOR_REQ:
925 		msg_set_mode_control(dev, REG_MODE_SENSOR);
926 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
927 			goto err;
928 		break;
929 	case FGR_FPA_INIT_SET_MODE_SENSOR_ANS:
930 		if (msg_check_ok(dev))
931 			goto err;
932 		fpi_ssm_next_state(ssm);
933 		break;
934 	case FGR_FPA_GET_FRAME_REQ:
935 		msg_get_frame(dev, 0x00, 0x00, 0x00, 0x00);
936 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
937 			goto err;
938 		break;
939 	case FGR_FPA_GET_FRAME_ANS:
940 		if (process_frame_empty((uint8_t *)dev->ans, FRAME_SIZE)) {
941 			fpi_ssm_jump_to_state(ssm, FGR_FPA_GET_FRAME_REQ);
942 		} else {
943 			fpi_imgdev_report_finger_status(idev, TRUE);
944 			fpi_ssm_mark_completed(ssm);
945 		}
946 		break;
947 	default:
948 		fp_err("Unknown state %d", ssm->cur_state);
949 		goto err;
950 		break;
951 	}
952 
953 	return;
954 err:
955 	fpi_ssm_mark_aborted(ssm, -EIO);
956 }
957 
m_finger_complete(struct fpi_ssm * ssm)958 static void m_finger_complete(struct fpi_ssm *ssm)
959 {
960 	struct fp_img_dev *idev = ssm->priv;
961 	struct etes603_dev *dev = idev->priv;
962 
963 	if (!ssm->error) {
964 		struct fpi_ssm *ssm_cap;
965 		ssm_cap = fpi_ssm_new(idev->dev, m_capture_state,
966 				CAP_NUM_STATES);
967 		ssm_cap->priv = idev;
968 		fpi_ssm_start(ssm_cap, m_capture_complete);
969 	} else {
970 		if (idev->action_state != IMG_ACQUIRE_STATE_DEACTIVATING) {
971 			fp_err("Error while capturing fingerprint "
972 				"(ssm->error=%d)", ssm->error);
973 			fpi_imgdev_session_error(idev, -4);
974 		}
975 		dev->is_active = FALSE;
976 	}
977 
978 	fpi_ssm_free(ssm);
979 }
980 
m_start_fingerdetect(struct fp_img_dev * idev)981 static void m_start_fingerdetect(struct fp_img_dev *idev)
982 {
983 	struct fpi_ssm *ssmf;
984 	ssmf = fpi_ssm_new(idev->dev, m_finger_state, FGR_NUM_STATES);
985 	ssmf->priv = idev;
986 	fpi_ssm_start(ssmf, m_finger_complete);
987 }
988 
989 /*
990  * Tune value of VRT and VRB for contrast and brightness.
991  */
m_tunevrb_state(struct fpi_ssm * ssm)992 static void m_tunevrb_state(struct fpi_ssm *ssm)
993 {
994 	struct fp_img_dev *idev = ssm->priv;
995 	struct etes603_dev *dev = idev->priv;
996 	float hist[5];
997 
998 	if (dev->is_active == FALSE) {
999 		fpi_ssm_mark_completed(ssm);
1000 		return;
1001 	}
1002 
1003 	switch (ssm->cur_state) {
1004 	case TUNEVRB_INIT:
1005 		fp_dbg("Tuning of VRT/VRB");
1006 		assert(dev->dcoffset);
1007 		/* VRT(reg E1)=0x0A and VRB(reg E2)=0x10 are starting values */
1008 		dev->vrt = 0x0A;
1009 		dev->vrb = 0x10;
1010 		fpi_ssm_next_state(ssm);
1011 		break;
1012 	case TUNEVRB_GET_GAIN_REQ:
1013 		msg_get_regs(dev, 1, REG_GAIN);
1014 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1015 			goto err;
1016 		break;
1017 	case TUNEVRB_GET_GAIN_ANS:
1018 		if (msg_parse_regs(dev))
1019 			goto err;
1020 		fpi_ssm_next_state(ssm);
1021 		break;
1022 	case TUNEVRB_GET_DCOFFSET_REQ:
1023 		msg_get_regs(dev, 1, REG_DCOFFSET);
1024 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1025 			goto err;
1026 		break;
1027 	case TUNEVRB_GET_DCOFFSET_ANS:
1028 		if (msg_parse_regs(dev))
1029 			goto err;
1030 		fpi_ssm_next_state(ssm);
1031 		break;
1032 	case TUNEVRB_SET_DCOFFSET_REQ:
1033 		/* Reduce DCoffset by 1 to allow tuning */
1034 		msg_set_regs(dev, 2, REG_DCOFFSET, dev->dcoffset - 1);
1035 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1036 			goto err;
1037 		break;
1038 	case TUNEVRB_SET_DCOFFSET_ANS:
1039 		if (msg_check_ok(dev))
1040 			goto err;
1041 		fpi_ssm_next_state(ssm);
1042 		break;
1043 	case TUNEVRB_FRAME_REQ:
1044 		fp_dbg("Testing VRT=0x%02X VRB=0x%02X", dev->vrt, dev->vrb);
1045 		msg_get_frame(dev, 0x01, dev->gain, dev->vrt, dev->vrb);
1046 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1047 			goto err;
1048 		break;
1049 	case TUNEVRB_FRAME_ANS:
1050 		process_hist((uint8_t *)dev->ans, FRAME_SIZE, hist);
1051 		/* Note that this tuning could probably be improved */
1052 		if (hist[0] + hist[1] > 0.95) {
1053 			if (dev->vrt <= 0 || dev->vrb <= 0) {
1054 				fp_dbg("Image is too dark, reducing DCOffset");
1055 				dev->dcoffset--;
1056 				fpi_ssm_jump_to_state(ssm, TUNEVRB_INIT);
1057 			} else {
1058 				dev->vrt--;
1059 				dev->vrb--;
1060 				fpi_ssm_jump_to_state(ssm, TUNEVRB_FRAME_REQ);
1061 			}
1062 			break;
1063 		}
1064 		if (hist[4] > 0.95) {
1065 			fp_dbg("Image is too bright, increasing DCOffset");
1066 			dev->dcoffset++;
1067 			fpi_ssm_jump_to_state(ssm, TUNEVRB_INIT);
1068 			break;
1069 		}
1070 		if (hist[4] + hist[3] > 0.4) {
1071 			if (dev->vrt >= 2 * dev->vrb - 0x0a) {
1072 				dev->vrt++; dev->vrb++;
1073 			} else {
1074 				dev->vrt++;
1075 			}
1076 			/* Check maximum for vrt/vrb */
1077 			/* TODO if maximum is reached, leave with an error? */
1078 			if (dev->vrt > VRT_MAX)
1079 				dev->vrt = VRT_MAX;
1080 			if (dev->vrb > VRB_MAX)
1081 				dev->vrb = VRB_MAX;
1082 			fpi_ssm_jump_to_state(ssm, TUNEVRB_FRAME_REQ);
1083 			break;
1084 		}
1085 		fpi_ssm_next_state(ssm);
1086 		break;
1087 	case TUNEVRB_FINAL_SET_DCOFFSET_REQ:
1088 		fp_dbg("-> VRT=0x%02X VRB=0x%02X", dev->vrt, dev->vrb);
1089 		/* Reset the DCOffset */
1090 		msg_set_regs(dev, 2, REG_DCOFFSET, dev->dcoffset);
1091 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1092 			goto err;
1093 		break;
1094 	case TUNEVRB_FINAL_SET_DCOFFSET_ANS:
1095 		if (msg_check_ok(dev))
1096 			goto err;
1097 		fpi_ssm_next_state(ssm);
1098 		break;
1099 	case TUNEVRB_FINAL_SET_REG2627_REQ:
1100 		/* In traces, REG_26/REG_27 are set. purpose? values? */
1101 		msg_set_regs(dev, 4, REG_26, 0x11, REG_27, 0x00);
1102 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1103 			goto err;
1104 		break;
1105 	case TUNEVRB_FINAL_SET_REG2627_ANS:
1106 		if (msg_check_ok(dev))
1107 			goto err;
1108 		fpi_ssm_next_state(ssm);
1109 		break;
1110 	case TUNEVRB_FINAL_SET_GAINVRTVRB_REQ:
1111 		/* Set Gain/VRT/VRB values found */
1112 		msg_set_regs(dev, 6, REG_GAIN, dev->gain, REG_VRT, dev->vrt,
1113 			     REG_VRB, dev->vrb);
1114 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1115 			goto err;
1116 		break;
1117 	case TUNEVRB_FINAL_SET_GAINVRTVRB_ANS:
1118 		if (msg_check_ok(dev))
1119 			goto err;
1120 		/* In traces, Gain/VRT/VRB are read again. */
1121 		fpi_ssm_next_state(ssm);
1122 		break;
1123 	case TUNEVRB_FINAL_SET_MODE_SLEEP_REQ:
1124 		msg_set_mode_control(dev, REG_MODE_SLEEP);
1125 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1126 			goto err;
1127 		break;
1128 	case TUNEVRB_FINAL_SET_MODE_SLEEP_ANS:
1129 		if (msg_check_ok(dev))
1130 			goto err;
1131 		fpi_ssm_mark_completed(ssm);
1132 		break;
1133 	default:
1134 		fp_err("Unknown state %d", ssm->cur_state);
1135 		goto err;
1136 		break;
1137 	}
1138 
1139 	return;
1140 err:
1141 	fpi_ssm_mark_aborted(ssm, -EIO);
1142 }
1143 
m_tunevrb_complete(struct fpi_ssm * ssm)1144 static void m_tunevrb_complete(struct fpi_ssm *ssm)
1145 {
1146 	struct fp_img_dev *idev = ssm->priv;
1147 
1148 	fpi_imgdev_activate_complete(idev, ssm->error != 0);
1149 	if (!ssm->error) {
1150 		fp_dbg("Tuning is done. Starting finger detection.");
1151 		m_start_fingerdetect(idev);
1152 	} else {
1153 		struct etes603_dev *dev = idev->priv;
1154 		fp_err("Error while tuning VRT");
1155 		dev->is_active = FALSE;
1156 		reset_param(dev);
1157 		fpi_imgdev_session_error(idev, -3);
1158 	}
1159 	fpi_ssm_free(ssm);
1160 }
1161 
1162 /*
1163  * This function tunes the DCoffset value and adjusts the gain value if
1164  * required.
1165  */
m_tunedc_state(struct fpi_ssm * ssm)1166 static void m_tunedc_state(struct fpi_ssm *ssm)
1167 {
1168 	struct fp_img_dev *idev = ssm->priv;
1169 	struct etes603_dev *dev = idev->priv;
1170 
1171 	if (dev->is_active == FALSE) {
1172 		fpi_ssm_mark_completed(ssm);
1173 		return;
1174 	}
1175 
1176 	/* TODO To get better results, tuning could be done 3 times as in
1177 	 * captured traffic to make sure that the value is correct. */
1178 	/* The default gain should work but it may reach a DCOffset limit so in
1179 	 * this case we decrease the gain. */
1180 	switch (ssm->cur_state) {
1181 	case TUNEDC_INIT:
1182 		/* reg_e0 = 0x23 is sensor normal/small gain */
1183 		dev->gain = GAIN_SMALL_INIT;
1184 		dev->tunedc_min = DCOFFSET_MIN;
1185 		dev->tunedc_max = DCOFFSET_MAX;
1186 		fp_dbg("Tuning DCoffset");
1187 		fpi_ssm_next_state(ssm);
1188 		break;
1189 	case TUNEDC_SET_DCOFFSET_REQ:
1190 		/* Dichotomic search to find at which value the frame becomes
1191 		 * almost black. */
1192 		dev->dcoffset = (dev->tunedc_max + dev->tunedc_min) / 2;
1193 		fp_dbg("Testing DCoffset=0x%02X Gain=0x%02X", dev->dcoffset,
1194 			dev->gain);
1195 		msg_set_regs(dev, 2, REG_DCOFFSET, dev->dcoffset);
1196 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1197 			goto err;
1198 		break;
1199 	case TUNEDC_SET_DCOFFSET_ANS:
1200 		if (msg_check_ok(dev))
1201 			goto err;
1202 		fpi_ssm_next_state(ssm);
1203 		break;
1204 	case TUNEDC_GET_FRAME_REQ:
1205 		/* vrt:0x15 vrb:0x10 are constant in all tuning frames. */
1206 		msg_get_frame(dev, 0x01, dev->gain, 0x15, 0x10);
1207 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1208 			goto err;
1209 		break;
1210 	case TUNEDC_GET_FRAME_ANS:
1211 		if (process_frame_empty((uint8_t *)dev->ans, FRAME_WIDTH))
1212 			dev->tunedc_max = dev->dcoffset;
1213 		else
1214 			dev->tunedc_min = dev->dcoffset;
1215 		if (dev->tunedc_min + 1 < dev->tunedc_max) {
1216 			fpi_ssm_jump_to_state(ssm, TUNEDC_SET_DCOFFSET_REQ);
1217 		} else if (dev->tunedc_max < DCOFFSET_MAX) {
1218 			dev->dcoffset = dev->tunedc_max + 1;
1219 			fpi_ssm_next_state(ssm);
1220 		} else {
1221 			dev->gain--;
1222 			fpi_ssm_jump_to_state(ssm, TUNEDC_SET_DCOFFSET_REQ);
1223 		}
1224 		break;
1225 	case TUNEDC_FINAL_SET_REG2122_REQ:
1226 		fp_dbg("-> DCoffset=0x%02X Gain=0x%02X", dev->dcoffset,
1227 			dev->gain);
1228 		/* ??? how reg21 / reg22 are calculated */
1229 		msg_set_regs(dev, 4, REG_21, 0x23, REG_22, 0x21);
1230 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1231 			goto err;
1232 		break;
1233 	case TUNEDC_FINAL_SET_REG2122_ANS:
1234 		if (msg_check_ok(dev))
1235 			goto err;
1236 		fpi_ssm_next_state(ssm);
1237 		break;
1238 	case TUNEDC_FINAL_SET_GAIN_REQ:
1239 		msg_set_regs(dev, 2, REG_GAIN, dev->gain);
1240 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1241 			goto err;
1242 		break;
1243 	case TUNEDC_FINAL_SET_GAIN_ANS:
1244 		fpi_ssm_next_state(ssm);
1245 		break;
1246 	case TUNEDC_FINAL_SET_DCOFFSET_REQ:
1247 		msg_set_regs(dev, 2, REG_DCOFFSET, dev->dcoffset);
1248 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1249 			goto err;
1250 		break;
1251 	case TUNEDC_FINAL_SET_DCOFFSET_ANS:
1252 		/* In captured traffic, read GAIN, VRT, and VRB registers. */
1253 		if (msg_check_ok(dev))
1254 			goto err;
1255 		fpi_ssm_mark_completed(ssm);
1256 		break;
1257 	default:
1258 		fp_err("Unknown state %d", ssm->cur_state);
1259 		goto err;
1260 		break;
1261 	}
1262 
1263 	return;
1264 err:
1265 	fpi_ssm_mark_aborted(ssm, -EIO);
1266 
1267 }
1268 
m_tunedc_complete(struct fpi_ssm * ssm)1269 static void m_tunedc_complete(struct fpi_ssm *ssm)
1270 {
1271 	struct fp_img_dev *idev = ssm->priv;
1272 	if (!ssm->error) {
1273 		struct fpi_ssm *ssm_tune;
1274 		ssm_tune = fpi_ssm_new(idev->dev, m_tunevrb_state,
1275 					TUNEVRB_NUM_STATES);
1276 		ssm_tune->priv = idev;
1277 		fpi_ssm_start(ssm_tune, m_tunevrb_complete);
1278 	} else {
1279 		struct etes603_dev *dev = idev->priv;
1280 		fp_err("Error while tuning DCOFFSET");
1281 		dev->is_active = FALSE;
1282 		reset_param(dev);
1283 		fpi_imgdev_session_error(idev, -2);
1284 	}
1285 	fpi_ssm_free(ssm);
1286 }
1287 
m_init_state(struct fpi_ssm * ssm)1288 static void m_init_state(struct fpi_ssm *ssm)
1289 {
1290 	struct fp_img_dev *idev = ssm->priv;
1291 	struct etes603_dev *dev = idev->priv;
1292 
1293 	if (dev->is_active == FALSE) {
1294 		fpi_ssm_mark_completed(ssm);
1295 		return;
1296 	}
1297 
1298 	switch (ssm->cur_state) {
1299 	case INIT_CHECK_INFO_REQ:
1300 		msg_get_regs(dev, 4, REG_INFO0, REG_INFO1, REG_INFO2,
1301 			     REG_INFO3);
1302 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1303 			goto err;
1304 		break;
1305 	case INIT_CHECK_INFO_ANS:
1306 		if (msg_parse_regs(dev))
1307 			goto err;
1308 		if (check_info(dev))
1309 			goto err;
1310 		fpi_ssm_next_state(ssm);
1311 		break;
1312 	case INIT_CMD20_REQ:
1313 		msg_get_cmd20(dev);
1314 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1315 			goto err;
1316 		break;
1317 	case INIT_CMD20_ANS:
1318 		if (msg_check_cmd20(dev))
1319 			goto err;
1320 		fpi_ssm_next_state(ssm);
1321 		break;
1322 	case INIT_CMD25_REQ:
1323 		msg_get_cmd25(dev);
1324 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1325 			goto err;
1326 		break;
1327 	case INIT_CMD25_ANS:
1328 		if (msg_check_cmd25(dev))
1329 			goto err;
1330 		fpi_ssm_next_state(ssm);
1331 		break;
1332 	case INIT_SENSOR_REQ:
1333 		/* In captured traffic, those are splitted. */
1334 		msg_set_regs(dev, 18, REG_MODE_CONTROL, REG_MODE_SLEEP,
1335 			REG_50, 0x0F, REG_GAIN, 0x04, REG_VRT, 0x08,
1336 			REG_VRB, 0x0D, REG_VCO_CONTROL, REG_VCO_RT,
1337 			REG_DCOFFSET, 0x36, REG_F0, 0x00, REG_F2, 0x00);
1338 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1339 			goto err;
1340 		break;
1341 	case INIT_SENSOR_ANS:
1342 		if (msg_check_ok(dev))
1343 			goto err;
1344 		fpi_ssm_next_state(ssm);
1345 		break;
1346 	case INIT_ENC_REQ:
1347 		/* Initialize encryption registers without encryption. */
1348 		/* Set registers from 0x41 to 0x48 (0x8 regs) */
1349 		msg_set_regs(dev, 16, REG_ENC1, 0x12, REG_ENC2, 0x34,
1350 		     REG_ENC3, 0x56, REG_ENC4, 0x78, REG_ENC5, 0x90,
1351 		     REG_ENC6, 0xAB, REG_ENC7, 0xCD, REG_ENC8, 0xEF);
1352 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1353 			goto err;
1354 		break;
1355 	case INIT_ENC_ANS:
1356 		if (msg_check_ok(dev))
1357 			goto err;
1358 		fpi_ssm_next_state(ssm);
1359 		break;
1360 	case INIT_REGS_REQ:
1361 		/* Set register from 0x20 to 0x37 (0x18 regs) */
1362 		msg_set_regs(dev, 48,
1363 		     REG_20, 0x00, REG_21, 0x23, REG_22, 0x21, REG_23, 0x20,
1364 		     REG_24, 0x14, REG_25, 0x6A, REG_26, 0x00, REG_27, 0x00,
1365 		     REG_28, 0x00, REG_29, 0xC0, REG_2A, 0x50, REG_2B, 0x50,
1366 		     REG_2C, 0x4D, REG_2D, 0x03, REG_2E, 0x06, REG_2F, 0x06,
1367 		     REG_30, 0x10, REG_31, 0x02, REG_32, 0x14, REG_33, 0x34,
1368 		     REG_34, 0x01, REG_35, 0x08, REG_36, 0x03, REG_37, 0x21);
1369 		if (async_tx(idev, EP_OUT, async_tx_cb, ssm))
1370 			goto err;
1371 		break;
1372 	case INIT_REGS_ANS:
1373 		if (msg_check_ok(dev))
1374 			goto err;
1375 		fpi_ssm_mark_completed(ssm);
1376 		break;
1377 	default:
1378 		fp_err("Unknown state %d", ssm->cur_state);
1379 		goto err;
1380 		break;
1381 	}
1382 
1383 	return;
1384 err:
1385 	fpi_ssm_mark_aborted(ssm, -EIO);
1386 
1387 }
1388 
m_init_complete(struct fpi_ssm * ssm)1389 static void m_init_complete(struct fpi_ssm *ssm)
1390 {
1391 	struct fp_img_dev *idev = ssm->priv;
1392 	if (!ssm->error) {
1393 		struct fpi_ssm *ssm_tune;
1394 		ssm_tune = fpi_ssm_new(idev->dev, m_tunedc_state,
1395 					TUNEDC_NUM_STATES);
1396 		ssm_tune->priv = idev;
1397 		fpi_ssm_start(ssm_tune, m_tunedc_complete);
1398 	} else {
1399 		struct etes603_dev *dev = idev->priv;
1400 		fp_err("Error initializing the device");
1401 		dev->is_active = FALSE;
1402 		reset_param(dev);
1403 		fpi_imgdev_session_error(idev, -1);
1404 	}
1405 	fpi_ssm_free(ssm);
1406 }
1407 
dev_activate(struct fp_img_dev * idev,enum fp_imgdev_state state)1408 static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
1409 {
1410 	struct etes603_dev *dev = idev->priv;
1411 	struct fpi_ssm *ssm;
1412 
1413 	assert(dev);
1414 
1415 	if (state != IMGDEV_STATE_AWAIT_FINGER_ON) {
1416 		fp_err("The driver is in an unexpected state: %d.", state);
1417 		fpi_imgdev_activate_complete(idev, 1);
1418 		return -1;
1419 	}
1420 
1421 	/* Reset info and data */
1422 	dev->is_active = TRUE;
1423 
1424 	if (dev->dcoffset == 0) {
1425 		fp_dbg("Tuning device...");
1426 		ssm = fpi_ssm_new(idev->dev, m_init_state, INIT_NUM_STATES);
1427 		ssm->priv = idev;
1428 		fpi_ssm_start(ssm, m_init_complete);
1429 	} else {
1430 		fp_dbg("Using previous tuning (DCOFFSET=0x%02X,VRT=0x%02X,"
1431 			"VRB=0x%02X,GAIN=0x%02X).", dev->dcoffset, dev->vrt,
1432 			dev->vrb, dev->gain);
1433 		fpi_imgdev_activate_complete(idev, 0);
1434 		ssm = fpi_ssm_new(idev->dev, m_finger_state, FGR_NUM_STATES);
1435 		ssm->priv = idev;
1436 		fpi_ssm_start(ssm, m_finger_complete);
1437 	}
1438 	return 0;
1439 }
1440 
dev_deactivate(struct fp_img_dev * idev)1441 static void dev_deactivate(struct fp_img_dev *idev)
1442 {
1443 	struct etes603_dev *dev = idev->priv;
1444 
1445 	fp_dbg("deactivating");
1446 
1447 	/* this can be called even if still activated. */
1448 	if (dev->is_active == TRUE) {
1449 		dev->is_active = FALSE;
1450 		m_exit_start(idev);
1451 	}
1452 }
1453 
dev_open(struct fp_img_dev * idev,unsigned long driver_data)1454 static int dev_open(struct fp_img_dev *idev, unsigned long driver_data)
1455 {
1456 	int ret;
1457 	struct etes603_dev *dev;
1458 
1459 	dev = g_malloc0(sizeof(struct etes603_dev));
1460 	idev->priv = dev;
1461 
1462 	dev->req = g_malloc(sizeof(struct egis_msg));
1463 	dev->ans = g_malloc(FE_SIZE);
1464 	dev->fp = g_malloc(FE_SIZE * 4);
1465 
1466 	ret = libusb_claim_interface(idev->udev, 0);
1467 	if (ret != LIBUSB_SUCCESS) {
1468 		fp_err("libusb_claim_interface failed on interface 0: %s", libusb_error_name(ret));
1469 		return ret;
1470 	}
1471 
1472 	fpi_imgdev_open_complete(idev, 0);
1473 	return 0;
1474 }
1475 
dev_close(struct fp_img_dev * idev)1476 static void dev_close(struct fp_img_dev *idev)
1477 {
1478 	struct etes603_dev *dev = idev->priv;
1479 
1480 	g_free(dev->req);
1481 	g_free(dev->ans);
1482 	g_free(dev->fp);
1483 	g_free(dev);
1484 
1485 	libusb_release_interface(idev->udev, 0);
1486 	fpi_imgdev_close_complete(idev);
1487 }
1488 
1489 static const struct usb_id id_table[] = {
1490 	/* EgisTec (aka Lightuning) ES603 */
1491 	{ .vendor = 0x1c7a, .product = 0x0603},
1492 	{ 0, 0, 0, },
1493 };
1494 
1495 struct fp_img_driver etes603_driver = {
1496 	.driver = {
1497 		.id = ETES603_ID,
1498 		.name = FP_COMPONENT,
1499 		.full_name = "EgisTec ES603",
1500 		.id_table = id_table,
1501 		.scan_type = FP_SCAN_TYPE_SWIPE,
1502 	},
1503 	.flags = 0,
1504 	.img_height = -1,
1505 	.img_width = 256,
1506 
1507 	.open = dev_open,
1508 	.close = dev_close,
1509 	.activate = dev_activate,
1510 	.deactivate = dev_deactivate,
1511 };
1512 
1513