/* Copyright 2021 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 #include "common.h" #include "console.h" #include "endian.h" #include "gpio.h" #include "link_defs.h" #include "spi.h" #include "system.h" #include "timer.h" #include "util.h" #include "shared_mem.h" #include "math_util.h" #include "fpsensor.h" #include "cryptoc/util.h" #include "elan_sensor.h" #include "elan_setting.h" #include "elan_sensor_pal.h" static uint16_t errors; #define CPRINTF(format, args...) cprintf(CC_FP, format, ##args) /* Sensor description */ static struct ec_response_fp_info ec_fp_sensor_info = { /* Sensor identification */ .vendor_id = VID, .product_id = PID, .model_id = MID, .version = VERSION, /* Image frame characteristics */ .frame_size = FP_SENSOR_RES_X * FP_SENSOR_RES_Y, .pixel_format = V4L2_PIX_FMT_GREY, .width = FP_SENSOR_RES_X, .height = FP_SENSOR_RES_Y, .bpp = FP_SENSOR_RES_BPP, }; /** * set fingerprint sensor into power saving mode */ void fp_sensor_low_power(void) { elan_woe_mode(); } /** * Reset and initialize the sensor IC */ int fp_sensor_init(void) { CPRINTF("========%s=======\n", __func__); errors = 0; elan_execute_reset(); algorithm_parameter_setting(); if (elan_execute_calibration() < 0) errors |= FP_ERROR_INIT_FAIL; if (elan_woe_mode() != 0) errors |= FP_ERROR_SPI_COMM; return EC_SUCCESS; } /** * Deinitialize the sensor IC */ int fp_sensor_deinit(void) { CPRINTF("========%s=======\n", __func__); return elan_fp_deinit(); } /** * Fill the 'ec_response_fp_info' buffer with the sensor information * * @param[out] resp retrieve the version, sensor and template information * * @return EC_SUCCESS on success otherwise error. */ int fp_sensor_get_info(struct ec_response_fp_info *resp) { int ret = 0; CPRINTF("========%s=======\n", __func__); memcpy(resp, &ec_fp_sensor_info, sizeof(struct ec_response_fp_info)); elan_sensor_get_alg_info(resp); resp->errors |= errors; CPRINTF("##%s## FrameSize=%d, errors=0x%04x\n", __func__, resp->frame_size, resp->errors); return ret; } /** * Compares given finger image against enrolled templates. * * @param[in] templ a pointer to the array of template buffers. * @param[in] templ_count the number of buffers in the array of templates. * @param[in] image the buffer containing the finger image * @param[out] match_index index of the matched finger in the template * array if any. * @param[out] update_bitmap contains one bit per template, the bit is set if * the match has updated the given template. * * @return negative value on error, else one of the following code : * - EC_MKBP_FP_ERR_MATCH_NO on non-match * - EC_MKBP_FP_ERR_MATCH_YES for match when template was not updated with * new data * - EC_MKBP_FP_ERR_MATCH_YES_UPDATED for match when template was updated * - EC_MKBP_FP_ERR_MATCH_YES_UPDATE_FAILED match, but update failed (not saved) * - EC_MKBP_FP_ERR_MATCH_LOW_QUALITY when matching could not be performed due * to low image quality * - EC_MKBP_FP_ERR_MATCH_LOW_COVERAGE when matching could not be performed * due to finger covering too little area of the sensor */ int fp_finger_match(void *templ, uint32_t templ_count, uint8_t *image, int32_t *match_index, uint32_t *update_bitmap) { CPRINTF("========%s=======\n", __func__); return elan_match(templ, templ_count, image, match_index, update_bitmap); } /** * start a finger enrollment session and initialize enrollment data * * @return 0 on success. * */ int fp_enrollment_begin(void) { CPRINTF("========%s=======\n", __func__); return elan_enrollment_begin(); } /** * Generate a template from the finger whose enrollment has just being * completed. * * @param templ the buffer which will receive the template. * templ can be set to NULL to abort the current enrollment * process. * * @return 0 on success or a negative error code. */ int fp_enrollment_finish(void *templ) { CPRINTF("========%s=======\n", __func__); return elan_enrollment_finish(templ); } /** * Adds fingerprint image to the current enrollment session. * * @param[in] image fingerprint image data * @param[out] completion retrieve percentage of current enrollment * * @return a negative value on error or one of the following codes: * - EC_MKBP_FP_ERR_ENROLL_OK when image was successfully enrolled * - EC_MKBP_FP_ERR_ENROLL_IMMOBILE when image added, but user should be * advised to move finger * - EC_MKBP_FP_ERR_ENROLL_LOW_QUALITY when image could not be used due to * low image quality * - EC_MKBP_FP_ERR_ENROLL_LOW_COVERAGE when image could not be used due to * finger covering too little area of the sensor */ int fp_finger_enroll(uint8_t *image, int *completion) { CPRINTF("========%s=======\n", __func__); return elan_enroll(image, completion); } /** * Put the sensor in its lowest power state. * * fp_sensor_configure_detect needs to be called to restore finger detection * functionality. */ void fp_sensor_configure_detect(void) { CPRINTF("========%s=======\n", __func__); elan_woe_mode(); } /** * Acquires a fingerprint image with specific capture mode. * * @param[out] image_data Memory buffer to retrieve fingerprint image data * Image_data is allocated by the caller and the size * is FP_SENSOR_IMAGE_SIZE. * @param[in] mode one of the FP_CAPTURE_ constants to get a specific * image type * - FP_CAPTURE_VENDOR_FORMAT: Full blown vendor-defined capture * - FP_CAPTURE_SIMPLE_IMAGE: Simple raw image capture * - FP_CAPTURE_PATTERN0: Self test pattern * - FP_CAPTURE_PATTERN1: Self test pattern * - FP_CAPTURE_QUALITY_TEST * - FP_CAPTURE_RESET_TEST * - FP_CAPTURE_TYPE_MAX * * @return * - 0 on success * - negative value on error * - FP_SENSOR_LOW_IMAGE_QUALITY on image captured but quality is too low * - FP_SENSOR_TOO_FAST on finger removed before image was captured * - FP_SENSOR_LOW_SENSOR_COVERAGE on sensor not fully covered by finger */ int fp_sensor_acquire_image_with_mode(uint8_t *image_data, int mode) { CPRINTF("========%s=======\n", __func__); return elan_sensor_acquire_image_with_mode(image_data, mode); } /** * Returns the status of the finger on the sensor. * * @return one of the following codes: * - FINGER_NONE * - FINGER_PARTIAL * - FINGER_PRESENT */ enum finger_state fp_sensor_finger_status(void) { CPRINTF("========%s=======\n", __func__); return elan_sensor_finger_status(); } /** * Runs a test for defective pixels. * * Should be triggered periodically by the client. The maintenance command can * take several hundred milliseconds to run. * * @return EC_ERROR_HW_INTERNAL on error (such as finger on sensor) * @return EC_SUCCESS on success */ int fp_maintenance(void) { CPRINTF("========%s=======\n", __func__); return elan_fp_maintenance(&errors); }