diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2017-03-29 18:16:05 +0200 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-05-23 05:57:14 -0700 |
commit | 4ce20f3f79d93f57f5c9974fdbe80316cb94f537 (patch) | |
tree | 8ed7420bb4ef240ab305cfa6939aa6269f8e34a2 /driver | |
parent | 563456c6582d785483c32cbf01d97c413b303324 (diff) | |
download | chrome-ec-4ce20f3f79d93f57f5c9974fdbe80316cb94f537.tar.gz |
fpc1140: add the finger capture init sequence
Allow to configure the sensor to detect autonomously finger touch event
similar to what is done in the suspend() routine of the kernel fpc1020
driver.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=b:35648259
TEST=make BOARD=eve_fp
Change-Id: I8b78bd6bdeecd8658850383417c950d9025fdf40
Reviewed-on: https://chromium-review.googlesource.com/491072
Commit-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Todd Broch <tbroch@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/fpc1140.c | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/driver/fpc1140.c b/driver/fpc1140.c index 05094eb713..7b48158887 100644 --- a/driver/fpc1140.c +++ b/driver/fpc1140.c @@ -32,10 +32,13 @@ enum fpc_cmd { FPC_CMD_INT_CLR = 0x1C, FPC_CMD_FINGER_QUERY = 0x20, FPC_CMD_SLEEP = 0x28, + FPC_CMD_DEEPSLEEP = 0x2B, FPC_CMD_SOFT_RESET = 0xF8, FPC_CMD_HW_ID = 0xFC, }; +#define FPC_IDLE_MASK 0x1E + #define FPC_INT_FINGER_DOWN (1 << 0) #ifndef SPI_FPC_DEVICE @@ -97,6 +100,29 @@ static uint8_t fpc_read_int(void) return val; } +static uint8_t fpc_read_status(void) +{ + const uint8_t cmd = FPC_CMD_STATUS; + uint8_t val[2]; + + if (spi_transaction(SPI_FPC_DEVICE, &cmd, 1, val, 2)) + return 0xff; + return val[1]; +} + +static int fpc_wait_for_idle(void) +{ + uint8_t sts; + int retries = 100; + + do { + fpc_read_clear_int(); + sts = fpc_read_status(); + } while (sts != FPC_IDLE_MASK && retries--); + + return sts != FPC_IDLE_MASK; +} + /* Reset and initialize the sensor IC */ static int fpc_init(void) { @@ -126,11 +152,37 @@ static int fpc_init(void) fpc_read_clear_int(); gpio_enable_interrupt(GPIO_FPS_INT); - fpc_send_cmd(FPC_CMD_SLEEP); + fpc_send_cmd(FPC_CMD_DEEPSLEEP); return EC_SUCCESS; } +static void fp_configure_sensor(void) +{ + int i, index; + + for (i = 0, index = 0; i < u.sensor_config.count; i++) { + uint8_t *data = u.sensor_config.data + index; + int len = u.sensor_config.len[i]; + int rc = spi_transaction(&spi_devices[0], data, len, NULL, 0); + + if (rc) + CPRINTS("Config %d failed with %d for 0x%02x", + i, rc, data[0]); + index += len; + } +} + +static void fp_prepare_capture(void) +{ + /* wake it from deep-sleep by doing a soft-reset */ + fpc_send_cmd(FPC_CMD_SOFT_RESET); + fpc_wait_for_idle(); + fp_configure_sensor(); + /* sleep until the finger down is detected */ + fpc_send_cmd(FPC_CMD_SLEEP); +} + /* Interrupt line from the fingerprint sensor */ void fps_event(enum gpio_signal signal) { @@ -231,10 +283,10 @@ static int fp_command_mode(struct host_cmd_handler_args *args) if (!(p->mode & FP_MODE_DONT_CHANGE)) { sensor_mode = p->mode; if (p->mode & FP_MODE_DEEPSLEEP) { - /* TBD fpc_send_cmd(FPC_CMD_DEEPSLEEP) */; + fpc_send_cmd(FPC_CMD_DEEPSLEEP); } else { if (p->mode & FP_MODE_FINGER_DOWN) - /* TBD: fp_prepare_capture()*/; + fp_prepare_capture(); if (p->mode & FP_MODE_FINGER_UP) /* TBD */; } |