| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- /* FPC1020 Touch sensor driver
- *
- * Copyright (c) 2013,2014 Fingerprint Cards AB <tech@fingerprints.com>
- *
- * 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>
- #ifndef CONFIG_OF
- #include <linux/spi/fpc1020.h>
- #include <linux/spi/fpc1020_regs.h>
- #else
- #include "fpc1020.h"
- #include "fpc1020_regs.h"
- #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_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*/
- u16 finger_present_status; /* 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;
- u16 spi_max_khz;
- } 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;
- struct regulator *vdd_tx;
- bool power_enabled;
- int vddtx_mv;
- bool txout_boost;
- u16 force_hwid;
- bool use_regulator_for_bezel;
- u16 spi_freq_khz;
- struct input_dev *input_dev;
- fpc1020_input_task_t input;
- bool use_fpc2050;
- } fpc1020_data_t;
- typedef struct {
- fpc1020_reg_t reg;
- bool write;
- u16 reg_size;
- u8 *dataptr;
- } fpc1020_reg_access_t;
- /* -------------------------------------------------------------------- */
- /* function prototypes */
- /* -------------------------------------------------------------------- */
- extern int mt_set_gpio_dir(unsigned long pin, unsigned long dir);
- extern int mt_get_gpio_dir(unsigned long pin);
- extern int mt_set_gpio_out(unsigned long pin, unsigned long output);
- extern int mt_get_gpio_out(unsigned long pin);
- extern int mt_set_gpio_mode(unsigned long pin, unsigned long mode);
- extern int mt_get_gpio_mode(unsigned long pin);
- extern int mt_set_gpio_pull_enable(unsigned long pin, unsigned long enable);
- extern int mt_gpio_set_debounce(unsigned gpio, unsigned debounce);
- 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_get_finger_present_status(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);
- int fpc1020_gpio_set(int cmd);
- irqreturn_t fpc1020_interrupt(int irq, void *_fpc1020);
- #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 */
|