diff options
Diffstat (limited to 'driver/fingerprint/fpc/libfp/fpc_private.c')
-rw-r--r-- | driver/fingerprint/fpc/libfp/fpc_private.c | 320 |
1 files changed, 0 insertions, 320 deletions
diff --git a/driver/fingerprint/fpc/libfp/fpc_private.c b/driver/fingerprint/fpc/libfp/fpc_private.c deleted file mode 100644 index 34fc61f66c..0000000000 --- a/driver/fingerprint/fpc/libfp/fpc_private.c +++ /dev/null @@ -1,320 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <stddef.h> -#include "common.h" -#include "console.h" -#include "endian.h" -#include "fpc_bio_algorithm.h" -#include "fpc_private.h" -#include "fpsensor.h" -#include "gpio.h" -#include "link_defs.h" -#include "spi.h" -#include "system.h" -#include "timer.h" -#include "util.h" - -#include "driver/fingerprint/fpc/fpc_sensor.h" - -#define CPRINTF(format, args...) cprintf(CC_FP, format, ## args) -#define CPRINTS(format, args...) cprints(CC_FP, format, ## args) - -/* Minimum reset duration */ -#define FP_SENSOR_RESET_DURATION_US (10 * MSEC) -/* Maximum delay for the interrupt to be asserted after the sensor is reset */ -#define FP_SENSOR_IRQ_MAX_DELAY_US (5 * MSEC) -/* Maximum number of attempts to initialise the sensor */ -#define FP_SENSOR_MAX_INIT_ATTEMPTS 10 -/* Delay between failed attempts of fp_sensor_open() */ -#define FP_SENSOR_OPEN_DELAY_US (500 * MSEC) - -/* Decode internal error codes from FPC's sensor library */ -#define FPC_GET_INTERNAL_CODE(res) (((res) & 0x000fc000) >> 14) -/* There was a finger on the sensor when calibrating finger detect */ -#define FPC_INTERNAL_FINGER_DFD FPC_ERROR_INTERNAL_38 - -/* - * The sensor context is uncached as it contains the SPI buffers, - * the binary library assumes that it is aligned. - */ -static uint8_t ctx[FP_SENSOR_CONTEXT_SIZE] __uncached __aligned(4); -static bio_sensor_t bio_sensor; -static uint8_t enroll_ctx[FP_ALGORITHM_ENROLLMENT_SIZE] __aligned(4); - -/* recorded error flags */ -static uint16_t errors; - -/* Sensor description */ -static struct ec_response_fp_info fpc1145_info = { - /* Sensor identification */ - .vendor_id = FOURCC('F', 'P', 'C', ' '), - .product_id = 9, - .model_id = 1, - .version = 1, - /* Image frame characteristics */ - .frame_size = FP_SENSOR_IMAGE_SIZE, - .pixel_format = V4L2_PIX_FMT_GREY, - .width = FP_SENSOR_RES_X, - .height = FP_SENSOR_RES_Y, - .bpp = FP_SENSOR_RES_BPP, -}; - -/* Sensor IC commands */ -enum fpc_cmd { - FPC_CMD_STATUS = 0x14, - FPC_CMD_INT_STS = 0x18, - FPC_CMD_INT_CLR = 0x1C, - FPC_CMD_FINGER_QUERY = 0x20, - FPC_CMD_SLEEP = 0x28, - FPC_CMD_DEEPSLEEP = 0x2C, - FPC_CMD_SOFT_RESET = 0xF8, - FPC_CMD_HW_ID = 0xFC, -}; - -/* Maximum size of a sensor command SPI transfer */ -#define MAX_CMD_SPI_TRANSFER_SIZE 3 - -/* Uncached memory for the SPI transfer buffer */ -static uint8_t spi_buf[MAX_CMD_SPI_TRANSFER_SIZE] __uncached; - -static int fpc_send_cmd(const uint8_t cmd) -{ - spi_buf[0] = cmd; - return spi_transaction(SPI_FP_DEVICE, spi_buf, 1, spi_buf, - SPI_READBACK_ALL); -} - -void fp_sensor_low_power(void) -{ - /* - * TODO(b/117620462): verify that sleep mode is WAI (no increased - * latency, expected power consumption). - */ - if (0) - fpc_send_cmd(FPC_CMD_SLEEP); -} - -int fpc_check_hwid(void) -{ - uint16_t id; - int rc; - - /* Clear previous occurences of relevant |errors| flags. */ - errors &= (~FP_ERROR_SPI_COMM & ~FP_ERROR_BAD_HWID); - - spi_buf[0] = FPC_CMD_HW_ID; - rc = spi_transaction(SPI_FP_DEVICE, spi_buf, 3, spi_buf, - SPI_READBACK_ALL); - if (rc) { - CPRINTS("FPC ID read failed %d", rc); - errors |= FP_ERROR_SPI_COMM; - return EC_ERROR_HW_INTERNAL; - } - id = (spi_buf[1] << 8) | spi_buf[2]; - if ((id >> 4) != FP_SENSOR_HWID) { - CPRINTS("FPC unknown silicon 0x%04x", id); - errors |= FP_ERROR_BAD_HWID; - return EC_ERROR_HW_INTERNAL; - } - CPRINTS(FP_SENSOR_NAME " id 0x%04x", id); - - return EC_SUCCESS; -} - -static uint8_t fpc_read_clear_int(void) -{ - spi_buf[0] = FPC_CMD_INT_CLR; - spi_buf[1] = 0xff; - if (spi_transaction(SPI_FP_DEVICE, spi_buf, 2, spi_buf, - SPI_READBACK_ALL)) - return 0xff; - return spi_buf[1]; -} - -/* - * Toggle the h/w reset pins and clear any pending IRQs before initializing the - * sensor contexts. - * Returns: - * - EC_SUCCESS on success. - * - EC_ERROR_HW_INTERNAL on failure (and |errors| variable is updated where - * appropriate). - */ -static int fpc_pulse_hw_reset(void) -{ - int ret; - int rc = EC_SUCCESS; - /* Clear previous occurrence of possible error flags. */ - errors &= ~FP_ERROR_NO_IRQ; - - /* Ensure we pulse reset low to initiate the startup */ - gpio_set_level(GPIO_FP_RST_ODL, 0); - usleep(FP_SENSOR_RESET_DURATION_US); - gpio_set_level(GPIO_FP_RST_ODL, 1); - /* the IRQ line should be set high by the sensor */ - usleep(FP_SENSOR_IRQ_MAX_DELAY_US); - if (!gpio_get_level(GPIO_FPS_INT)) { - CPRINTS("Sensor IRQ not ready"); - errors |= FP_ERROR_NO_IRQ; - rc = EC_ERROR_HW_INTERNAL; - } - - /* Check the Hardware ID */ - ret = fpc_check_hwid(); - if (ret != EC_SUCCESS) { - CPRINTS("Failed to verify HW ID"); - rc = EC_ERROR_HW_INTERNAL; - } - - /* clear the pending 'ready' IRQ before enabling interrupts */ - fpc_read_clear_int(); - - return rc; -} - -/* Reset and initialize the sensor IC */ -int fp_sensor_init(void) -{ - int res; - int attempt; - - errors = FP_ERROR_DEAD_PIXELS_UNKNOWN; - - /* Release any previously held resources from earlier iterations */ - res = bio_sensor_destroy(bio_sensor); - if (res) - CPRINTS("FPC Sensor resources release failed: %d", res); - bio_sensor = NULL; - - res = bio_algorithm_exit(); - if (res) - CPRINTS("FPC Algorithm resources release failed: %d", res); - - /* Print the binary libfpsensor.a library version */ - CPRINTF("FPC libfpsensor.a v%s\n", fp_sensor_get_version()); - cflush(); - - attempt = 0; - do { - attempt++; - - res = fpc_pulse_hw_reset(); - if (res != EC_SUCCESS) { - /* In case of failure, retry after a delay. */ - CPRINTS("H/W sensor reset failed, error flags: 0x%x", - errors); - cflush(); - usleep(FP_SENSOR_OPEN_DELAY_US); - continue; - } - - /* - * Ensure that any previous context data is obliterated in case - * of a sensor reset. - */ - memset(ctx, 0, FP_SENSOR_CONTEXT_SIZE); - - res = fp_sensor_open(ctx, FP_SENSOR_CONTEXT_SIZE); - /* Flush messages from the PAL if any */ - cflush(); - CPRINTS("Sensor init (attempt %d): 0x%x", attempt, res); - /* - * Retry on failure. This typically happens if the user has left - * their finger on the sensor after powering up the device, DFD - * will fail in that case. We've seen other error modes in the - * field, retry in all cases to be more resilient. - */ - if (!res) - break; - usleep(FP_SENSOR_OPEN_DELAY_US); - } while (attempt < FP_SENSOR_MAX_INIT_ATTEMPTS); - if (res) - errors |= FP_ERROR_INIT_FAIL; - - res = bio_algorithm_init(); - /* the PAL might have spewed a lot of traces, ensure they are visible */ - cflush(); - CPRINTS("Algorithm init: 0x%x", res); - if (res < 0) - errors |= FP_ERROR_INIT_FAIL; - res = bio_sensor_create(&bio_sensor); - CPRINTS("Sensor create: 0x%x", res); - if (res < 0) - errors |= FP_ERROR_INIT_FAIL; - - /* Go back to low power */ - fp_sensor_low_power(); - - return EC_SUCCESS; -} - -/* Deinitialize the sensor IC */ -int fp_sensor_deinit(void) -{ - /* - * TODO(tomhughes): libfp doesn't have fp_sensor_close like BEP does. - * We'll need FPC to either add it or verify that we don't have the same - * problem with the libfp library as described in: - * b/124773209#comment46 - */ - return EC_SUCCESS; -} - -int fp_sensor_get_info(struct ec_response_fp_info *resp) -{ - int rc; - - memcpy(resp, &fpc1145_info, sizeof(*resp)); - - spi_buf[0] = FPC_CMD_HW_ID; - rc = spi_transaction(SPI_FP_DEVICE, spi_buf, 3, spi_buf, - SPI_READBACK_ALL); - if (rc) - return EC_RES_ERROR; - resp->model_id = (spi_buf[1] << 8) | spi_buf[2]; - resp->errors = errors; - - return EC_SUCCESS; -} - -int fp_finger_match(void *templ, uint32_t templ_count, uint8_t *image, - int32_t *match_index, uint32_t *update_bitmap) -{ - return bio_template_image_match_list(templ, templ_count, image, - match_index, update_bitmap); -} - -int fp_enrollment_begin(void) -{ - int rc; - bio_enrollment_t p = enroll_ctx; - - rc = bio_enrollment_begin(bio_sensor, &p); - if (rc < 0) - CPRINTS("begin failed %d", rc); - return rc; -} - -int fp_enrollment_finish(void *templ) -{ - bio_template_t pt = templ; - - return bio_enrollment_finish(enroll_ctx, templ ? &pt : NULL); -} - -int fp_finger_enroll(uint8_t *image, int *completion) -{ - int rc = bio_enrollment_add_image(enroll_ctx, image); - - if (rc < 0) - return rc; - *completion = bio_enrollment_get_percent_complete(enroll_ctx); - return rc; -} - -int fp_maintenance(void) -{ - return fpc_fp_maintenance(&errors); -} |