forked from SanniZ/fpc1020-driver
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfpc1020_common.h
322 lines (256 loc) · 9.94 KB
/
fpc1020_common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/* FPC1020 Touch sensor driver
*
* Copyright (c) 2013,2014 Fingerprint Cards AB <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License Version 2
* as published by the Free Software Foundation.
*/
#ifndef LINUX_SPI_FPC1020_COMMON_H
#define LINUX_SPI_FPC1020_COMMON_H
#define DEBUG
#include <linux/cdev.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/semaphore.h>
#include <linux/spi/spi.h>
#include <linux/wait.h>
#include <linux/version.h>
#ifndef CONFIG_OF
#include <linux/spi/fpc1020.h>
#include <linux/spi/fpc1020_regs.h>
#else
#include "fpc1020.h"
#include "fpc1020_regs.h"
#endif
/* -------------------------------------------------------------------- */
/* platform compatibility */
/* -------------------------------------------------------------------- */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
#define __devinit
#define __devinitdata
#define __devinitconst
#define __devexit
#define __devexitdata
#define __devexitconst
#define __devexit_p
#endif
/* -------------------------------------------------------------------- */
/* fpc1020 driver constants */
/* -------------------------------------------------------------------- */
extern const bool target_little_endian;
#define FPC1020_DEV_NAME "fpc1020"
/* set '0' for dynamic assignment, or '> 0' for static assignment */
#define FPC1020_MAJOR 0
#define FPC1020_SPI_CLOCK_SPEED (8 * 1000000U)
#define FPC1020_BUFFER_MAX_IMAGES 3
#define FPC1020_MAX_ADC_SETTINGS (FPC1020_BUFFER_MAX_IMAGES + 1)
#define FPC1020_DEFAULT_IRQ_TIMEOUT_MS (100 * HZ / 1000)
#define FPC1020_STATUS_REG_RESET_VALUE 0x1e
#define FPC1020_STATUS_REG_MODE_MASK ( \
FPC_1020_STATUS_REG_BIT_MAIN_IDLE_CMD | \
FPC_1020_STATUS_REG_BIT_SYNC_PWR_IDLE | \
FPC_1020_STATUS_REG_BIT_PWR_DWN_OSC_HIN)
#define FPC1020_STATUS_REG_IN_DEEP_SLEEP_MODE 0
#define FPC1020_STATUS_REG_IN_SLEEP_MODE 0
#define FPC1020_STATUS_REG_IN_IDLE_MODE ( \
FPC_1020_STATUS_REG_BIT_MAIN_IDLE_CMD | \
FPC_1020_STATUS_REG_BIT_SYNC_PWR_IDLE | \
FPC_1020_STATUS_REG_BIT_PWR_DWN_OSC_HIN)
#define FPC1020_SLEEP_RETRIES 5
#define FPC1020_SLEEP_RETRY_TIME_US 1000
#define FPC1020_RESET_RETRIES 2
#define FPC1020_RESET_LOW_US 1000
#define FPC1020_RESET_HIGH1_US 100
#define FPC1020_RESET_HIGH2_US 1250
#define FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS 20
#define FPC1020_WAKEUP_DETECT_ZONE_COUNT 2
#define FPC1020_WAKEUP_DETECT_ROWS 8
#define FPC1020_WAKEUP_DETECT_COLS 8
#define FPC1020_PXL_BIAS_CTRL 0x0F00
/* -------------------------------------------------------------------- */
/* fpc1020 data types */
/* -------------------------------------------------------------------- */
typedef enum {
FPC_1020_STATUS_REG_BIT_IRQ = 1 << 0,
FPC_1020_STATUS_REG_BIT_MAIN_IDLE_CMD = 1 << 1,
FPC_1020_STATUS_REG_BIT_SYNC_PWR_IDLE = 1 << 2,
FPC_1020_STATUS_REG_BIT_PWR_DWN_OSC_HIN = 1 << 3,
FPC_1020_STATUS_REG_BIT_FIFO_EMPTY = 1 << 4,
FPC_1020_STATUS_REG_BIT_FIFO_FULL = 1 << 5,
FPC_1020_STATUS_REG_BIT_MISO_EDGRE_RISE_EN = 1 << 6
} fpc1020_status_reg_t;
typedef enum {
FPC1020_CMD_FINGER_PRESENT_QUERY = 32,
FPC1020_CMD_WAIT_FOR_FINGER_PRESENT = 36,
FPC1020_CMD_ACTIVATE_SLEEP_MODE = 40,
FPC1020_CMD_ACTIVATE_DEEP_SLEEP_MODE = 44,
FPC1020_CMD_ACTIVATE_IDLE_MODE = 52,
FPC1020_CMD_CAPTURE_IMAGE = 192,
FPC1020_CMD_READ_IMAGE = 196,
FPC1020_CMD_SOFT_RESET = 248
} fpc1020_cmd_t;
typedef enum {
FPC_1020_IRQ_REG_BIT_FINGER_DOWN = 1 << 0,
FPC_1020_IRQ_REG_BIT_ERROR = 1 << 2,
FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA = 1 << 5,
FPC_1020_IRQ_REG_BIT_COMMAND_DONE = 1 << 7,
FPC_1020_IRQ_REG_BITS_REBOOT = 0xff
} fpc1020_irq_reg_t;
typedef enum {
FPC1020_CAPTURE_STATE_IDLE = 0,
FPC1020_CAPTURE_STATE_STARTED,
FPC1020_CAPTURE_STATE_PENDING,
FPC1020_CAPTURE_STATE_WRITE_SETTINGS,
FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN,
FPC1020_CAPTURE_STATE_ACQUIRE,
FPC1020_CAPTURE_STATE_FETCH,
FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP,
FPC1020_CAPTURE_STATE_COMPLETED,
FPC1020_CAPTURE_STATE_FAILED,
} fpc1020_capture_state_t;
typedef struct fpc1020_worker_struct {
struct task_struct *thread;
struct semaphore sem_idle;
wait_queue_head_t wq_wait_job;
int req_mode;
bool stop_request;
} fpc1020_worker_t;
typedef struct fpc1020_capture_struct {
fpc1020_capture_mode_t current_mode;
fpc1020_capture_state_t state;
u32 read_offset;
u32 available_bytes;
wait_queue_head_t wq_data_avail;
int last_error;
bool read_pending_eof;
bool deferred_finger_up;
} fpc1020_capture_task_t;
typedef struct fpc1020_input_struct {
bool enabled;
} fpc1020_input_task_t;
typedef struct fpc1020_setup {
u8 adc_gain[FPC1020_MAX_ADC_SETTINGS];
u8 adc_shift[FPC1020_MAX_ADC_SETTINGS];
u16 pxl_ctrl[FPC1020_MAX_ADC_SETTINGS];
u8 capture_settings_mux;
u8 capture_count;
fpc1020_capture_mode_t capture_mode;
u8 capture_row_start; /* Row 0-191 */
u8 capture_row_count; /* Rows <= 192 */
u8 capture_col_start; /* ADC group 0-23 */
u8 capture_col_groups; /* ADC groups, 1-24 */
u8 capture_finger_up_threshold;
u8 capture_finger_down_threshold;
u8 finger_detect_threshold;
u8 wakeup_detect_rows[FPC1020_WAKEUP_DETECT_ZONE_COUNT];
u8 wakeup_detect_cols[FPC1020_WAKEUP_DETECT_ZONE_COUNT];
} fpc1020_setup_t;
typedef struct fpc1020_diag {
const char *chip_id; /* RO */
u8 selftest; /* RO */
u16 spi_register; /* RW */
u8 spi_regsize; /* RO */
u8 spi_data; /* RW */
u16 last_capture_time; /* RO*/
} fpc1020_diag_t;
typedef struct fpc1020_chip_info {
fpc1020_chip_t type;
u8 revision;
u8 pixel_rows;
u8 pixel_columns;
u8 adc_group_size;
}fpc1020_chip_info_t;
typedef struct {
struct spi_device *spi;
struct class *class;
struct device *device;
struct cdev cdev;
dev_t devno;
fpc1020_chip_info_t chip;
u32 cs_gpio;
u32 reset_gpio;
u32 irq_gpio;
int irq;
wait_queue_head_t wq_irq_return;
bool interrupt_done;
struct semaphore mutex;
u8 *huge_buffer;
size_t huge_buffer_size;
fpc1020_worker_t worker;
fpc1020_capture_task_t capture;
fpc1020_setup_t setup;
fpc1020_diag_t diag;
bool soft_reset_enabled;
struct regulator *vcc_spi;
struct regulator *vdd_ana;
struct regulator *vdd_io;
bool power_enabled;
int vddtx_mv;
bool txout_boost;
struct input_dev *input_dev;
fpc1020_input_task_t input;
} fpc1020_data_t;
typedef struct {
fpc1020_reg_t reg;
bool write;
u16 reg_size;
u8 *dataptr;
} fpc1020_reg_access_t;
/* -------------------------------------------------------------------- */
/* function prototypes */
/* -------------------------------------------------------------------- */
extern size_t fpc1020_calc_huge_buffer_minsize(fpc1020_data_t *fpc1020);
extern int fpc1020_manage_huge_buffer(fpc1020_data_t *fpc1020,
size_t new_size);
extern int fpc1020_setup_defaults(fpc1020_data_t *fpc1020);
extern int fpc1020_gpio_reset(fpc1020_data_t *fpc1020);
extern int fpc1020_spi_reset(fpc1020_data_t *fpc1020);
extern int fpc1020_reset(fpc1020_data_t *fpc1020);
extern int fpc1020_check_hw_id(fpc1020_data_t *fpc1020);
extern const char *fpc1020_hw_id_text(fpc1020_data_t *fpc1020);
extern int fpc1020_write_sensor_setup(fpc1020_data_t *fpc1020);
extern int fpc1020_wait_for_irq(fpc1020_data_t *fpc1020, int timeout);
extern int fpc1020_read_irq(fpc1020_data_t *fpc1020, bool clear_irq);
extern int fpc1020_read_status_reg(fpc1020_data_t *fpc1020);
extern int fpc1020_reg_access(fpc1020_data_t *fpc1020,
fpc1020_reg_access_t *reg_data);
extern int fpc1020_cmd(fpc1020_data_t *fpc1020, fpc1020_cmd_t cmd,
u8 wait_irq_mask);
extern int fpc1020_wait_finger_present(fpc1020_data_t *fpc1020);
extern int fpc1020_check_finger_present_raw(fpc1020_data_t *fpc1020);
extern int fpc1020_check_finger_present_sum(fpc1020_data_t *fpc1020);
extern int fpc1020_wake_up(fpc1020_data_t *fpc1020);
extern int fpc1020_sleep(fpc1020_data_t *fpc1020, bool deep_sleep);
extern int fpc1020_fetch_image(fpc1020_data_t *fpc1020,
u8 *buffer,
int offset,
size_t image_size_bytes,
size_t buff_size);
extern bool fpc1020_check_in_range_u64(u64 val, u64 min, u64 max);
extern int fpc1020_calc_finger_detect_threshold_min(fpc1020_data_t *fpc1020);
extern int fpc1020_set_finger_detect_threshold(fpc1020_data_t *fpc1020,
int measured_val);
#define FPC1020_MK_REG_READ_BYTES(__dst, __reg, __count, __ptr) { \
(__dst).reg = FPC1020_REG_TO_ACTUAL((__reg)); \
(__dst).reg_size = (__count); \
(__dst).write = false; \
(__dst).dataptr = (__ptr); }
#define FPC1020_MK_REG_READ(__dst, __reg, __ptr) { \
(__dst).reg = FPC1020_REG_TO_ACTUAL((__reg)); \
(__dst).reg_size = FPC1020_REG_SIZE((__reg)); \
(__dst).write = false; \
(__dst).dataptr = (u8 *)(__ptr); }
#define FPC1020_MK_REG_WRITE_BYTES(__dst, __reg, __count, __ptr) { \
(__dst).reg = FPC1020_REG_TO_ACTUAL((__reg)); \
(__dst).reg_size = (__count); \
(__dst).write = true; \
(__dst).dataptr = (__ptr); }
#define FPC1020_MK_REG_WRITE(__dst, __reg, __ptr) { \
(__dst).reg = FPC1020_REG_TO_ACTUAL((__reg)); \
(__dst).reg_size = FPC1020_REG_SIZE((__reg)); \
(__dst).write = true; \
(__dst).dataptr = (u8 *)(__ptr); }
#define FPC1020_FINGER_DETECT_ZONE_MASK 0x0FFFU
#endif /* LINUX_SPI_FPC1020_COMMON_H */