1 /*
2  * AuthenTec AES1660 driver for libfprint
3  * Copyright (C) 2012 Vasily Khoruzhick
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 #define FP_COMPONENT "aes1660"
21 
22 #include <stdio.h>
23 
24 #include <errno.h>
25 #include <string.h>
26 
27 #include <libusb.h>
28 
29 #include <fp_internal.h>
30 
31 #include <assembling.h>
32 #include <aeslib.h>
33 
34 #include "aesx660.h"
35 #include "aes1660.h"
36 #include "driver_ids.h"
37 
38 #define FRAME_WIDTH 128
39 #define IMAGE_WIDTH	(FRAME_WIDTH + (FRAME_WIDTH / 2))
40 
41 static struct fpi_frame_asmbl_ctx assembling_ctx = {
42 	.frame_width = FRAME_WIDTH,
43 	.frame_height = AESX660_FRAME_HEIGHT,
44 	.image_width = IMAGE_WIDTH,
45 	.get_pixel = aes_get_pixel,
46 };
47 
dev_init(struct fp_img_dev * dev,unsigned long driver_data)48 static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
49 {
50 	/* TODO check that device has endpoints we're using */
51 	int r;
52 	struct aesX660_dev *aesdev;
53 
54 	r = libusb_claim_interface(dev->udev, 0);
55 	if (r < 0) {
56 		fp_err("could not claim interface 0: %s", libusb_error_name(r));
57 		return r;
58 	}
59 
60 	dev->priv = aesdev = g_malloc0(sizeof(struct aesX660_dev));
61 	aesdev->buffer = g_malloc0(AES1660_FRAME_SIZE + AESX660_HEADER_SIZE);
62 	aesdev->init_seqs[0] = aes1660_init_1;
63 	aesdev->init_seqs_len[0] = array_n_elements(aes1660_init_1);
64 	aesdev->init_seqs[1] = aes1660_init_2;
65 	aesdev->init_seqs_len[1] = array_n_elements(aes1660_init_2);
66 	aesdev->start_imaging_cmd = (unsigned char *)aes1660_start_imaging_cmd;
67 	aesdev->start_imaging_cmd_len = sizeof(aes1660_start_imaging_cmd);
68 	aesdev->assembling_ctx = &assembling_ctx;
69 	aesdev->extra_img_flags = FP_IMG_PARTIAL;
70 
71 	fpi_imgdev_open_complete(dev, 0);
72 	return 0;
73 }
74 
dev_deinit(struct fp_img_dev * dev)75 static void dev_deinit(struct fp_img_dev *dev)
76 {
77 	struct aesX660_dev *aesdev = dev->priv;
78 	g_free(aesdev->buffer);
79 	g_free(aesdev);
80 	libusb_release_interface(dev->udev, 0);
81 	fpi_imgdev_close_complete(dev);
82 }
83 
84 static const struct usb_id id_table[] = {
85 	{ .vendor = 0x08ff, .product = 0x1660 },
86 	{ .vendor = 0x08ff, .product = 0x1680 },
87 	{ .vendor = 0x08ff, .product = 0x1681 },
88 	{ .vendor = 0x08ff, .product = 0x1682 },
89 	{ .vendor = 0x08ff, .product = 0x1683 },
90 	{ .vendor = 0x08ff, .product = 0x1684 },
91 	{ .vendor = 0x08ff, .product = 0x1685 },
92 	{ .vendor = 0x08ff, .product = 0x1686 },
93 	{ .vendor = 0x08ff, .product = 0x1687 },
94 	{ .vendor = 0x08ff, .product = 0x1688 },
95 	{ .vendor = 0x08ff, .product = 0x1689 },
96 	{ .vendor = 0x08ff, .product = 0x168a },
97 	{ .vendor = 0x08ff, .product = 0x168b },
98 	{ .vendor = 0x08ff, .product = 0x168c },
99 	{ .vendor = 0x08ff, .product = 0x168d },
100 	{ .vendor = 0x08ff, .product = 0x168e },
101 	{ .vendor = 0x08ff, .product = 0x168f },
102 	{ 0, 0, 0, },
103 };
104 
105 struct fp_img_driver aes1660_driver = {
106 	.driver = {
107 		.id = AES1660_ID,
108 		.name = FP_COMPONENT,
109 		.full_name = "AuthenTec AES1660",
110 		.id_table = id_table,
111 		.scan_type = FP_SCAN_TYPE_SWIPE,
112 	},
113 	.flags = 0,
114 	.img_height = -1,
115 	.img_width = FRAME_WIDTH + FRAME_WIDTH / 2,
116 	.bz3_threshold = 20,
117 
118 	.open = dev_init,
119 	.close = dev_deinit,
120 	.activate = aesX660_dev_activate,
121 	.deactivate = aesX660_dev_deactivate,
122 };
123