| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826 |
- /* 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.
- */
- #define DEBUG
- #include <linux/input.h>
- #include <linux/delay.h>
- #include <linux/time.h>
- #ifndef CONFIG_OF
- #include <linux/spi/fpc1020_common.h>
- #include <linux/spi/fpc1020_capture.h>
- #else
- #include "fpc1020_common.h"
- #include "fpc1020_capture.h"
- #endif
- /* -------------------------------------------------------------------- */
- /* function prototypes */
- /* -------------------------------------------------------------------- */
- static size_t fpc1020_calc_image_size(fpc1020_data_t *fpc1020);
- /* -------------------------------------------------------------------- */
- /* function definitions */
- /* -------------------------------------------------------------------- */
- int fpc1020_init_capture(fpc1020_data_t *fpc1020)
- {
- fpc1020->capture.state = FPC1020_CAPTURE_STATE_IDLE;
- fpc1020->capture.current_mode = FPC1020_MODE_IDLE;
- fpc1020->capture.available_bytes = 0;
- fpc1020->capture.deferred_finger_up = false;
- init_waitqueue_head(&fpc1020->capture.wq_data_avail);
- return 0;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_write_capture_setup(fpc1020_data_t *fpc1020)
- {
- return fpc1020_write_sensor_setup(fpc1020);
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_write_test_setup(fpc1020_data_t *fpc1020, u16 pattern)
- {
- int error = 0;
- u8 config = 0x04;
- fpc1020_reg_access_t reg;
- dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, pattern);
- error = fpc1020_write_sensor_setup(fpc1020);
- if (error)
- goto out;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &pattern);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &config);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- error = fpc1020_capture_settings(fpc1020, 0);
- if (error)
- goto out;
- out:
- return error;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_write_cb_test_setup_102x(fpc1020_data_t *fpc1020, bool invert)
- {
- int error = 0;
- u8 temp_u8;
- u16 temp_u16;
- u64 temp_u64;
- fpc1020_reg_access_t reg;
- temp_u16 = (invert) ? 0x55aa : 0xaa55;
- dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, temp_u16);
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u8 = 0x04;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u16 = (invert) ? 0x0f1b : 0x0f0f;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u16 = (invert) ? 0x0800 : 0x00;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u8 = 0x14;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u8 = 0x20;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u64 = 0x1e1e1e1e2d2d2d2d;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- out:
- return error;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_write_cb_test_setup_1155(fpc1020_data_t *fpc1020, bool invert)
- {
- int error = 0;
- u8 temp_u8;
- u16 temp_u16;
- u64 temp_u64;
- fpc1020_reg_access_t reg;
- temp_u16 = (invert) ? 0x55aa : 0xaa55;
- dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, temp_u16);
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u8 = 0x14;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u16 = (invert) ? 0x0f1a : 0x0f0e;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u16 = (invert) ? 0x0800 : 0x0000;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u8 = 0x2f;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u8 = 0x38;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u64 = 0x373737373f3f3f3f;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u64 = 0x5540002d24;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SETUP, &temp_u64);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- out:
- return error;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_write_cb_test_setup_1022(fpc1020_data_t *fpc1020, bool invert)
- {
- int error = 0;
- u8 temp_u8;
- u16 temp_u16;
- /*u64 temp_u64;*/
- fpc1020_reg_access_t reg;
- temp_u16 = (invert) ? 0x55aa : 0xaa55;
- dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, temp_u16);
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u8 = 0x04;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u16 = (invert) ? 0x0f1b : 0x0f0f;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- temp_u16 = (invert) ? 0x0800 : 0x00;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out;
- out:
- return error;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_write_cb_test_setup_1145(fpc1020_data_t *fpc1020, bool invert)
- {
- return fpc1020_write_cb_test_setup_1155(fpc1020, invert);
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_write_cb_test_setup(fpc1020_data_t *fpc1020, bool invert)
- {
- int error = 0;
- switch (fpc1020->chip.type) {
- case FPC1020_CHIP_1035X:
- case FPC1020_CHIP_1022X:
- error = fpc1020_write_cb_test_setup_1022(fpc1020, invert);
- break;
- case FPC1020_CHIP_1155X:
- error = fpc1020_write_cb_test_setup_1155(fpc1020, invert);
- break;
- case FPC1020_CHIP_1145X:
- error = fpc1020_write_cb_test_setup_1145(fpc1020, invert);
- break;
- default:
- error = fpc1020_write_cb_test_setup_102x(fpc1020, invert);
- break;
- }
- return error;
- }
- /* -------------------------------------------------------------------- */
- bool fpc1020_capture_check_ready(fpc1020_data_t *fpc1020)
- {
- fpc1020_capture_state_t state = fpc1020->capture.state;
- return (state == FPC1020_CAPTURE_STATE_IDLE) ||
- (state == FPC1020_CAPTURE_STATE_COMPLETED) ||
- (state == FPC1020_CAPTURE_STATE_FAILED);
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_capture_task(fpc1020_data_t *fpc1020)
- {
- struct timespec ts_t1, ts_t2, ts_t3, ts_delta;
- int time_settings_us[FPC1020_BUFFER_MAX_IMAGES];
- int time_capture_us[FPC1020_BUFFER_MAX_IMAGES];
- int time_capture_sum_us;
- int error = 0;
- bool wait_finger_down = false;
- bool wait_finger_up = false;
- bool adjust_settings;
- fpc1020_capture_mode_t mode = fpc1020->capture.current_mode;
- int current_capture, capture_count;
- int image_offset;
- size_t image_byte_size;
- fpc1020->capture.state = FPC1020_CAPTURE_STATE_WRITE_SETTINGS;
- error = fpc1020_wake_up(fpc1020);
- if (error < 0)
- goto out_error;
- switch (mode) {
- case FPC1020_MODE_CAPTURE_AND_WAIT_FINGER_UP:
- wait_finger_up = true;
- capture_count = fpc1020->setup.capture_count;
- adjust_settings = true;
- error = fpc1020_write_capture_setup(fpc1020);
- break;
- case FPC1020_MODE_WAIT_AND_CAPTURE:
- wait_finger_down =
- wait_finger_up = true;
- case FPC1020_MODE_SINGLE_CAPTURE:
- case FPC1020_MODE_SINGLE_CAPTURE_CAL:
- capture_count = fpc1020->setup.capture_count;
- adjust_settings = true;
- error = fpc1020_write_capture_setup(fpc1020);
- break;
- case FPC1020_MODE_CHECKERBOARD_TEST_NORM:
- capture_count = 1;
- adjust_settings = false;
- error = fpc1020_write_cb_test_setup(fpc1020, false);
- break;
- case FPC1020_MODE_CHECKERBOARD_TEST_INV:
- capture_count = 1;
- adjust_settings = false;
- error = fpc1020_write_cb_test_setup(fpc1020, true);
- break;
- case FPC1020_MODE_BOARD_TEST_ONE:
- capture_count = 1;
- adjust_settings = false;
- error = fpc1020_write_test_setup(fpc1020, 0xffff);
- break;
- case FPC1020_MODE_BOARD_TEST_ZERO:
- capture_count = 1;
- adjust_settings = false;
- error = fpc1020_write_test_setup(fpc1020, 0x0000);
- break;
- case FPC1020_MODE_WAIT_FINGER_DOWN:
- wait_finger_down = true;
- capture_count = 0;
- adjust_settings = false;
- error = fpc1020_write_capture_setup(fpc1020);
- break;
- case FPC1020_MODE_WAIT_FINGER_UP:
- wait_finger_up = true;
- capture_count = 0;
- adjust_settings = false;
- error = fpc1020_write_capture_setup(fpc1020);
- break;
- case FPC1020_MODE_IDLE:
- default:
- capture_count = 0;
- adjust_settings = false;
- error = -EINVAL;
- break;
- }
- if (error < 0)
- goto out_error;
- error = fpc1020_capture_set_crop(fpc1020,
- fpc1020->setup.capture_col_start,
- fpc1020->setup.capture_col_groups,
- fpc1020->setup.capture_row_start,
- fpc1020->setup.capture_row_count);
- if (error < 0)
- goto out_error;
- image_byte_size = fpc1020_calc_image_size(fpc1020);
- dev_dbg(&fpc1020->spi->dev,
- "Start capture, mode %d, (%d frames)\n",
- mode,
- capture_count);
- if (!wait_finger_down)
- fpc1020->capture.deferred_finger_up = false;
- if (wait_finger_down) {
- error = fpc1020_capture_finger_detect_settings(fpc1020);
- if (error < 0)
- goto out_error;
- }
- if (wait_finger_down && fpc1020->capture.deferred_finger_up) {
- fpc1020->capture.state =
- FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP;
- dev_dbg(&fpc1020->spi->dev, "Waiting for (deferred) finger up\n");
- error = fpc1020_capture_wait_finger_up(fpc1020);
- if (error < 0)
- goto out_error;
- dev_dbg(&fpc1020->spi->dev, "Finger up\n");
- fpc1020->capture.deferred_finger_up = false;
- }
- if (wait_finger_down) {
- fpc1020->capture.state =
- FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN;
- error = fpc1020_capture_wait_finger_down(fpc1020);
- if (error < 0)
- goto out_error;
- dev_dbg(&fpc1020->spi->dev, "Finger down\n");
- if (mode == FPC1020_MODE_WAIT_FINGER_DOWN) {
- fpc1020->capture.available_bytes = 4;
- fpc1020->huge_buffer[0] = 'F';
- fpc1020->huge_buffer[1] = ':';
- fpc1020->huge_buffer[2] = 'D';
- fpc1020->huge_buffer[3] = 'N';
- }
- }
- current_capture = 0;
- image_offset = 0;
- fpc1020->diag.last_capture_time = 0;
- if (mode == FPC1020_MODE_SINGLE_CAPTURE_CAL) {
- error = fpc1020_capture_set_sample_mode(fpc1020, true);
- if (error)
- goto out_error;
- }
- while (capture_count && (error >= 0)) {
- getnstimeofday(&ts_t1);
- fpc1020->capture.state = FPC1020_CAPTURE_STATE_ACQUIRE;
- dev_dbg(&fpc1020->spi->dev,
- "Capture, frame #%d\n",
- current_capture + 1);
- error = (!adjust_settings) ? 0 :
- fpc1020_capture_settings(fpc1020, current_capture);
- if (error < 0)
- goto out_error;
- getnstimeofday(&ts_t2);
- error = fpc1020_cmd(fpc1020,
- FPC1020_CMD_CAPTURE_IMAGE,
- FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA);
- if (error < 0)
- goto out_error;
- fpc1020->capture.state = FPC1020_CAPTURE_STATE_FETCH;
- error = fpc1020_fetch_image(fpc1020,
- fpc1020->huge_buffer,
- image_offset,
- image_byte_size,
- (size_t)fpc1020->huge_buffer_size);
- if (error < 0)
- goto out_error;
- fpc1020->capture.available_bytes += (error >= 0) ?
- (int)image_byte_size : 0;
- fpc1020->capture.last_error = error;
- getnstimeofday(&ts_t3);
- ts_delta = timespec_sub(ts_t2, ts_t1);
- time_settings_us[current_capture] =
- ts_delta.tv_sec * USEC_PER_SEC +
- (ts_delta.tv_nsec / NSEC_PER_USEC);
- ts_delta = timespec_sub(ts_t3, ts_t2);
- time_capture_us[current_capture] =
- ts_delta.tv_sec * USEC_PER_SEC +
- (ts_delta.tv_nsec / NSEC_PER_USEC);
- capture_count--;
- current_capture++;
- image_offset += (int)image_byte_size;
- }
- error = fpc1020_capture_set_sample_mode(fpc1020, false);
- if (error)
- goto out_error;
- /* Update finger_present_status after image capture */
- fpc1020_check_finger_present_raw(fpc1020);
- if (mode != FPC1020_MODE_WAIT_FINGER_UP)
- wake_up_interruptible(&fpc1020->capture.wq_data_avail);
- if (wait_finger_up) {
- fpc1020->capture.state =
- FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP;
- error = fpc1020_capture_finger_detect_settings(fpc1020);
- if (error < 0)
- goto out_error;
- error = fpc1020_capture_wait_finger_up(fpc1020);
- if (error == -EINTR) {
- dev_dbg(&fpc1020->spi->dev, "Finger up check interrupted\n");
- fpc1020->capture.deferred_finger_up = true;
- goto out_interrupted;
- } else if (error < 0)
- goto out_error;
- if (mode == FPC1020_MODE_WAIT_FINGER_UP) {
- fpc1020->capture.available_bytes = 4;
- fpc1020->huge_buffer[0] = 'F';
- fpc1020->huge_buffer[1] = ':';
- fpc1020->huge_buffer[2] = 'U';
- fpc1020->huge_buffer[3] = 'P';
- wake_up_interruptible(&fpc1020->capture.wq_data_avail);
- }
- dev_dbg(&fpc1020->spi->dev, "Finger up\n");
- }
- out_interrupted:
- capture_count = 0;
- time_capture_sum_us = 0;
- while (current_capture) {
- current_capture--;
- dev_dbg(&fpc1020->spi->dev,
- "Frame #%d acq. time %d+%d=%d (us)\n",
- capture_count + 1,
- time_settings_us[capture_count],
- time_capture_us[capture_count],
- time_settings_us[capture_count] +
- time_capture_us[capture_count]);
- time_capture_sum_us += time_settings_us[capture_count];
- time_capture_sum_us += time_capture_us[capture_count];
- capture_count++;
- }
- fpc1020->diag.last_capture_time = time_capture_sum_us / 1000;
- dev_dbg(&fpc1020->spi->dev,
- "Total acq. time %d (us)\n", time_capture_sum_us);
- out_error:
- fpc1020->capture.last_error = error;
- if (error) {
- fpc1020->capture.state = FPC1020_CAPTURE_STATE_FAILED;
- dev_err(&fpc1020->spi->dev, "%s %s %d\n", __func__,
- (error == -EINTR) ? "TERMINATED" : "FAILED", error);
- } else {
- fpc1020->capture.state = FPC1020_CAPTURE_STATE_COMPLETED;
- dev_err(&fpc1020->spi->dev, "%s OK\n", __func__);
- }
- return error;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_capture_wait_finger_down(fpc1020_data_t *fpc1020)
- {
- int error;
- bool finger_down = false;
- error = fpc1020_wait_finger_present(fpc1020);
- while (!finger_down && (error >= 0)) {
- if (fpc1020->worker.stop_request)
- error = -EINTR;
- else
- error = fpc1020_check_finger_present_sum(fpc1020);
- if (error > fpc1020->setup.capture_finger_down_threshold)
- finger_down = true;
- else
- msleep(FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS);
- }
- fpc1020_read_irq(fpc1020, true);
- return (finger_down) ? 0 : error;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_capture_wait_finger_up(fpc1020_data_t *fpc1020)
- {
- int error = 0;
- bool finger_up = false;
- while (!finger_up && (error >= 0)) {
- if (fpc1020->worker.stop_request)
- error = -EINTR;
- else
- error = fpc1020_check_finger_present_sum(fpc1020);
- if ((error >= 0) && (error < fpc1020->setup.capture_finger_up_threshold + 1))
- finger_up = true;
- else
- msleep(FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS);
- }
- fpc1020_read_irq(fpc1020, true);
- return (finger_up) ? 0 : error;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_capture_settings(fpc1020_data_t *fpc1020, int select)
- {
- int error = 0;
- fpc1020_reg_access_t reg;
- u16 pxlCtrl;
- u16 adc_shift_gain;
- dev_dbg(&fpc1020->spi->dev, "%s #%d\n", __func__, select);
- if (select >= FPC1020_MAX_ADC_SETTINGS) {
- error = -EINVAL;
- goto out_err;
- }
- pxlCtrl = fpc1020->setup.pxl_ctrl[select];
- pxlCtrl |= FPC1020_PXL_BIAS_CTRL;
- adc_shift_gain = fpc1020->setup.adc_shift[select];
- adc_shift_gain <<= 8;
- adc_shift_gain |= fpc1020->setup.adc_gain[select];
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &pxlCtrl);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out_err;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &adc_shift_gain);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out_err;
- out_err:
- if (error)
- dev_err(&fpc1020->spi->dev, "%s Error %d\n", __func__, error);
- return error;
- }
- int fpc1020_capture_set_sample_mode(fpc1020_data_t *fpc1020, bool single)
- {
- int error = 0;
- fpc1020_reg_access_t reg;
- u8 image_setup;
- u8 image_rd;
- dev_dbg(&fpc1020->spi->dev, "%s single %s\n", __func__, single ?
- "true" : "false");
- if (single) {
- image_setup = 0x0A;
- image_rd = 0x0C;
- } else {
- image_setup = 0x03 | 0x08;
- image_rd = 0x0E;
- }
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMAGE_SETUP, &image_setup);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out_err;
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMG_RD, &image_rd);
- error = fpc1020_reg_access(fpc1020, ®);
- if (error)
- goto out_err;
- out_err:
- if (error)
- dev_err(&fpc1020->spi->dev, "%s Error %d\n", __func__, error);
- return error;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_capture_finger_detect_settings(fpc1020_data_t *fpc1020)
- {
- dev_dbg(&fpc1020->spi->dev, "%s\n", __func__);
- return fpc1020_capture_settings(fpc1020, FPC1020_MAX_ADC_SETTINGS - 1);
- }
- /* -------------------------------------------------------------------- */
- static size_t fpc1020_calc_image_size(fpc1020_data_t *fpc1020)
- {
- int image_byte_size = fpc1020->setup.capture_row_count *
- fpc1020->setup.capture_col_groups *
- fpc1020->chip.adc_group_size;
- dev_dbg(&fpc1020->spi->dev, "%s Rows %d->%d,Cols %d->%d (%d bytes)\n",
- __func__,
- fpc1020->setup.capture_row_start,
- fpc1020->setup.capture_row_start
- + fpc1020->setup.capture_row_count - 1,
- fpc1020->setup.capture_col_start
- * fpc1020->chip.adc_group_size,
- (fpc1020->setup.capture_col_start
- * fpc1020->chip.adc_group_size)
- + (fpc1020->setup.capture_col_groups *
- fpc1020->chip.adc_group_size) - 1,
- image_byte_size
- );
- return image_byte_size;
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_capture_set_crop(fpc1020_data_t *fpc1020,
- int first_column,
- int num_columns,
- int first_row,
- int num_rows)
- {
- fpc1020_reg_access_t reg;
- u32 temp_u32;
- temp_u32 = first_row;
- temp_u32 <<= 8;
- temp_u32 |= num_rows;
- temp_u32 <<= 8;
- temp_u32 |= (first_column * fpc1020->chip.adc_group_size);
- temp_u32 <<= 8;
- temp_u32 |= (num_columns * fpc1020->chip.adc_group_size);
- FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMG_CAPT_SIZE, &temp_u32);
- return fpc1020_reg_access(fpc1020, ®);
- }
- /* -------------------------------------------------------------------- */
- int fpc1020_capture_buffer(fpc1020_data_t *fpc1020,
- u8 *data,
- size_t offset,
- size_t image_size_bytes)
- {
- int error = 0;
- dev_dbg(&fpc1020->spi->dev, "%s\n", __func__);
- error = fpc1020_cmd(fpc1020,
- FPC1020_CMD_CAPTURE_IMAGE,
- FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA);
- if (error < 0)
- goto out_error;
- error = fpc1020_fetch_image(fpc1020,
- data,
- offset,
- image_size_bytes,
- (size_t)fpc1020->huge_buffer_size);
- if (error < 0)
- goto out_error;
- return 0;
- out_error:
- dev_dbg(&fpc1020->spi->dev, "%s FAILED %d\n", __func__, error);
- return error;
- }
- /* -------------------------------------------------------------------- */
- extern int fpc1020_capture_deferred_task(fpc1020_data_t *fpc1020)
- {
- int error = 0;
- dev_dbg(&fpc1020->spi->dev, "%s\n", __func__);
- error = (fpc1020->capture.deferred_finger_up) ?
- fpc1020_capture_wait_finger_up(fpc1020) : 0;
- if (error >= 0)
- fpc1020->capture.deferred_finger_up = false;
- return error;
- }
- /* -------------------------------------------------------------------- */
|