summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2017-03-29 18:16:05 +0200
committerchrome-bot <chrome-bot@chromium.org>2017-05-23 05:57:14 -0700
commit4ce20f3f79d93f57f5c9974fdbe80316cb94f537 (patch)
tree8ed7420bb4ef240ab305cfa6939aa6269f8e34a2
parent563456c6582d785483c32cbf01d97c413b303324 (diff)
downloadchrome-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>
-rw-r--r--driver/fpc1140.c58
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 */;
}