Skip to content

Commit 6129a4f

Browse files
authored
Create goodix.c
1 parent 514e221 commit 6129a4f

File tree

1 file changed

+370
-0
lines changed

1 file changed

+370
-0
lines changed
Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
/*
2+
* Goodix 5110 driver for libfprint
3+
*
4+
* Copyright (C) 2021 Alexander Meiler <[email protected]>
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#define FP_COMPONENT "goodixtls"
22+
23+
#include "drivers_api.h"
24+
#include "goodix.h"
25+
26+
struct _FpiDeviceGoodixTLS
27+
{
28+
FpImageDevice parent;
29+
30+
/* device config */
31+
// unsigned short dev_type;
32+
char *fw_ver;
33+
// void (*process_frame) (unsigned short *raw_frame,
34+
// GSList ** frames);
35+
/* end device config */
36+
37+
/* commands */
38+
const struct goodix_cmd *cmd;
39+
int cmd_timeout;
40+
/* end commands */
41+
42+
/* state */
43+
gboolean active;
44+
gboolean deactivating;
45+
unsigned char *last_read;
46+
// unsigned char calib_atts_left;
47+
// unsigned char calib_status;
48+
unsigned short *background;
49+
// unsigned char frame_width;
50+
// unsigned char frame_height;
51+
// unsigned char raw_frame_height;
52+
// int num_frames;
53+
// GSList *frames;
54+
/* end state */
55+
};
56+
G_DEFINE_TYPE (FpiDeviceGoodixTLS, fpi_device_goodixtls, FP_TYPE_IMAGE_DEVICE);
57+
58+
static void
59+
goodix_cmd_done (FpiSsm *ssm)
60+
{
61+
G_DEBUG_HERE ();
62+
fpi_ssm_next_state (ssm);
63+
}
64+
65+
static void
66+
goodix_cmd_read (FpiSsm *ssm, FpDevice *dev, int response_len)
67+
{
68+
FpiDeviceGoodixTLS *self = FPI_DEVICE_GOODIXTLS (dev);
69+
FpiUsbTransfer *transfer;
70+
GCancellable *cancellable = NULL;
71+
//int response_len = self->cmd->response_len;
72+
73+
G_DEBUG_HERE ();
74+
75+
if (self->cmd->response_len == GOODIX_CMD_SKIP_READ)
76+
{
77+
fp_dbg ("skipping read, not expecting anything");
78+
goodix_cmd_done (ssm);
79+
return;
80+
}
81+
82+
g_clear_pointer (&self->last_read, g_free);
83+
84+
transfer = fpi_usb_transfer_new (dev);
85+
transfer->ssm = ssm;
86+
transfer->short_is_error = TRUE;
87+
88+
fpi_usb_transfer_fill_bulk (transfer,
89+
GOODIX_EP_CMD_IN,
90+
response_len);
91+
92+
fpi_usb_transfer_submit (transfer, self->cmd_timeout, cancellable, goodix_cmd_cb, NULL);
93+
}
94+
95+
static void
96+
goodix_cmd_cb (FpiUsbTransfer *transfer, FpDevice *dev,
97+
gpointer user_data, GError *error)
98+
{
99+
FpiSsm *ssm = transfer->ssm;
100+
FpiDeviceGoodixTLS *self = FPI_DEVICE_GOODIXTLS (dev);
101+
102+
G_DEBUG_HERE ();
103+
104+
if (error)
105+
{
106+
/* XXX: In the cancellation case we used to not
107+
* mark the SSM as failed?! */
108+
fpi_ssm_mark_failed (transfer->ssm, error);
109+
return;
110+
}
111+
112+
/* XXX: We used to reset the device in error cases! */
113+
if (transfer->endpoint & FPI_USB_ENDPOINT_IN)
114+
{
115+
/* just finished receiving */
116+
self->last_read = g_memdup (transfer->buffer, transfer->actual_length);
117+
//fp_dbg("%lu", transfer->actual_length);
118+
if(self->cmd->cmd == read_fw.cmd)
119+
{
120+
if(transfer->actual_length == self->cmd->response_len)
121+
{
122+
// We got ACK, now wait for the firmware string packet
123+
G_DEBUG_HERE ();
124+
goodix_cmd_read (ssm, dev, self->cmd->response_len_2);
125+
}
126+
else
127+
{
128+
// Reading the firmware version
129+
self->fw_ver = g_memdup (&self->last_read[7], self->cmd->response_len_2);
130+
G_DEBUG_HERE ();
131+
goodix_cmd_done (ssm);
132+
}
133+
}
134+
else
135+
{
136+
goodix_cmd_done (ssm);
137+
}
138+
}
139+
else
140+
{
141+
/* just finished sending */
142+
G_DEBUG_HERE ();
143+
goodix_cmd_read (ssm, dev, self->cmd->response_len);
144+
}
145+
}
146+
147+
static void
148+
goodix_run_cmd (FpiSsm *ssm,
149+
FpDevice *dev,
150+
const struct goodix_cmd *cmd,
151+
int cmd_timeout)
152+
{
153+
FpiDeviceGoodixTLS *self = FPI_DEVICE_GOODIXTLS (dev);
154+
FpiUsbTransfer *transfer;
155+
GCancellable *cancellable = NULL;
156+
157+
self->cmd = cmd;
158+
159+
transfer = fpi_usb_transfer_new (dev);
160+
transfer->ssm = ssm;
161+
transfer->short_is_error = TRUE;
162+
163+
fpi_usb_transfer_fill_bulk_full (transfer,
164+
GOODIX_EP_CMD_OUT,
165+
(guint8 *) cmd->cmd,
166+
GOODIX_CMD_LEN,
167+
NULL);
168+
169+
fpi_usb_transfer_submit (transfer,
170+
cmd_timeout,
171+
cancellable,
172+
goodix_cmd_cb,
173+
NULL);
174+
}
175+
176+
/* ------------------------------------------------------------------------------- */
177+
178+
/* ---- ACTIVE SECTION START ---- */
179+
180+
enum activate_states {
181+
ACTIVATE_NOP1,
182+
ACTIVATE_ENABLE_CHIP,
183+
ACTIVATE_NOP2,
184+
ACTIVATE_GET_FW_VER,
185+
ACTIVATE_VERIFY_FW_VER,
186+
ACTIVATE_NUM_STATES
187+
};
188+
189+
static void
190+
activate_run_state (FpiSsm *ssm, FpDevice *dev)
191+
{
192+
FpiDeviceGoodixTLS *self = FPI_DEVICE_GOODIXTLS (dev);
193+
194+
G_DEBUG_HERE ();
195+
196+
switch (fpi_ssm_get_cur_state (ssm))
197+
{
198+
// NOP seems to do nothing, but the Windows driver does it in places too
199+
case ACTIVATE_NOP1:
200+
case ACTIVATE_NOP2:
201+
goodix_run_cmd(ssm, dev, &nop, GOODIX_CMD_TIMEOUT);
202+
break;
203+
204+
case ACTIVATE_ENABLE_CHIP:
205+
goodix_run_cmd(ssm, dev, &enable_chip, GOODIX_CMD_TIMEOUT);
206+
break;
207+
208+
case ACTIVATE_GET_FW_VER:
209+
goodix_run_cmd(ssm, dev, &read_fw, GOODIX_CMD_TIMEOUT);
210+
break;
211+
212+
case ACTIVATE_VERIFY_FW_VER:
213+
if(strcmp(self->fw_ver, GOODIX_FIRMWARE_VERSION_SUPPORTED) == 0)
214+
{
215+
// The firmware version supports the 0xF2 command to directly read from the MCU SRAM
216+
fpi_ssm_mark_completed (ssm);
217+
}
218+
else
219+
{
220+
// The firmware version is unsupported
221+
fpi_ssm_mark_failed (ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "Unsupported firmware!"));
222+
}
223+
}
224+
}
225+
226+
static void
227+
activate_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
228+
{
229+
FpImageDevice *idev = FP_IMAGE_DEVICE (dev);
230+
231+
G_DEBUG_HERE ();
232+
233+
fpi_image_device_activate_complete (idev, error);
234+
235+
}
236+
237+
static void
238+
goodix_activate (FpImageDevice *dev)
239+
{
240+
FpiDeviceGoodixTLS *self = FPI_DEVICE_GOODIXTLS (dev);
241+
242+
G_DEBUG_HERE ();
243+
goodix_dev_reset_state (self);
244+
245+
FpiSsm *ssm =
246+
fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
247+
ACTIVATE_NUM_STATES);
248+
249+
fpi_ssm_start (ssm, activate_complete);
250+
}
251+
252+
/* ---- ACTIVE SECTION END ---- */
253+
254+
/* ------------------------------------------------------------------------------- */
255+
256+
/* ---- DEV SECTION START ---- */
257+
258+
static void
259+
dev_init (FpImageDevice *dev)
260+
{
261+
GError *error = NULL;
262+
// FpiDeviceGoodix *self;
263+
264+
G_DEBUG_HERE ();
265+
266+
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), 0, 0, &error))
267+
{
268+
fpi_image_device_open_complete (dev, error);
269+
return;
270+
}
271+
272+
// self = FPI_DEVICE_GOODIXTLS (dev);
273+
274+
fpi_image_device_open_complete (dev, NULL);
275+
}
276+
277+
static void
278+
goodix_dev_reset_state (FpiDeviceGoodixTLS *goodixdev)
279+
{
280+
G_DEBUG_HERE ();
281+
282+
goodixdev->cmd = NULL;
283+
goodixdev->cmd_timeout = GOODIX_CMD_TIMEOUT;
284+
285+
g_free (goodixdev->last_read);
286+
goodixdev->last_read = NULL;
287+
}
288+
289+
static void
290+
dev_deinit (FpImageDevice *dev)
291+
{
292+
GError *error = NULL;
293+
FpiDeviceGoodixTLS *self = FPI_DEVICE_GOODIXTLS (dev);
294+
295+
G_DEBUG_HERE ();
296+
297+
goodix_dev_reset_state (self);
298+
g_free (self->background);
299+
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
300+
0, 0, &error);
301+
fpi_image_device_close_complete (dev, error);
302+
}
303+
304+
static void
305+
dev_activate (FpImageDevice *dev)
306+
{
307+
G_DEBUG_HERE ();
308+
goodix_activate (dev);
309+
}
310+
311+
static void
312+
dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
313+
{
314+
//FpiDeviceGoodix *self = FPI_DEVICE_GOODIX (dev);
315+
316+
G_DEBUG_HERE ();
317+
}
318+
319+
static void
320+
dev_deactivate (FpImageDevice *dev)
321+
{
322+
FpiDeviceGoodixTLS *self = FPI_DEVICE_GOODIXTLS (dev);
323+
324+
G_DEBUG_HERE ();
325+
326+
if (!self->active)
327+
/* The device is inactive already, complete the operation immediately. */
328+
fpi_image_device_deactivate_complete (dev, NULL);
329+
else
330+
/* The device is not yet inactive, flag that we are deactivating (and
331+
* need to signal back deactivation).
332+
* Note that any running capture will be cancelled already if needed. */
333+
self->deactivating = TRUE;
334+
}
335+
336+
/* ---- DEV SECTION END ---- */
337+
338+
/* ------------------------------------------------------------------------------- */
339+
340+
/* ---- FPI SECTION START ---- */
341+
342+
static void
343+
fpi_device_goodixtls_init (FpiDeviceGoodixTLS *self)
344+
{
345+
// nothing to be done here, move along
346+
}
347+
348+
static void
349+
fpi_device_goodixtls_class_init (FpiDeviceGoodixTLSClass *class)
350+
{
351+
FpDeviceClass *dev_class = FP_DEVICE_CLASS (class);
352+
FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (class);
353+
354+
dev_class->id = "goodix";
355+
dev_class->full_name = "Goodix 5110 Fingerprint Sensor";
356+
dev_class->type = FP_DEVICE_TYPE_USB;
357+
dev_class->id_table = goodix_id_table;
358+
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
359+
360+
img_class->img_open = dev_init;
361+
img_class->img_close = dev_deinit;
362+
img_class->activate = dev_activate;
363+
img_class->deactivate = dev_deactivate;
364+
img_class->change_state = dev_change_state;
365+
366+
// ToDo
367+
img_class->bz3_threshold = 24;
368+
}
369+
370+
/* ---- FPI SECTION END ---- */

0 commit comments

Comments
 (0)