summaryrefslogtreecommitdiff
path: root/driver/fingerprint/fpc/bep/fpc_private.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/fingerprint/fpc/bep/fpc_private.c')
-rw-r--r--driver/fingerprint/fpc/bep/fpc_private.c260
1 files changed, 260 insertions, 0 deletions
diff --git a/driver/fingerprint/fpc/bep/fpc_private.c b/driver/fingerprint/fpc/bep/fpc_private.c
new file mode 100644
index 0000000000..f69cffb0ce
--- /dev/null
+++ b/driver/fingerprint/fpc/bep/fpc_private.c
@@ -0,0 +1,260 @@
+/* Copyright 2019 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 <stdint.h>
+#include <stddef.h>
+
+#include "fpc_bio_algorithm.h"
+#include "fpsensor.h"
+#include "spi.h"
+#include "system.h"
+#include "util.h"
+
+#include STRINGIFY(FP_SENSOR_PRIVATE)
+
+/* Console output macros */
+#define CPRINTF(format, args...) cprintf(CC_FP, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_FP, format, ## args)
+
+static uint8_t enroll_ctx[FP_ALGORITHM_ENROLLMENT_SIZE] = {0};
+
+/* Recorded error flags */
+static uint16_t errors;
+
+/* FPC specific initialization and de-initialization functions */
+int fp_sensor_open(void);
+int fp_sensor_close(void);
+
+/* Get FPC library version code.*/
+const char *fp_sensor_get_version(void);
+
+/* Get FPC library build info.*/
+const char *fp_sensor_get_build_info(void);
+
+/* Sensor description */
+static struct ec_response_fp_info ec_fp_sensor_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,
+};
+
+typedef struct fpc_bep_sensor fpc_bep_sensor_t;
+
+typedef struct {
+ const fpc_bep_sensor_t *sensor;
+ uint32_t image_buffer_size;
+} fpc_sensor_info_t;
+
+#if defined(FP_SENSOR_CONFIG_FPC1025)
+
+extern const fpc_bep_sensor_t fpc_bep_sensor_1025;
+extern const fpc_bep_algorithm_t fpc_bep_algorithm_pfe_1025;
+
+const fpc_sensor_info_t fpc_sensor_info = {
+ .sensor = &fpc_bep_sensor_1025,
+ .image_buffer_size = FP_SENSOR_IMAGE_SIZE,
+};
+
+const fpc_bio_info_t fpc_bio_info = {
+ .algorithm = &fpc_bep_algorithm_pfe_1025,
+ .template_size = FP_ALGORITHM_TEMPLATE_SIZE,
+};
+
+#elif defined(FP_SENSOR_CONFIG_FPC1035)
+
+extern const fpc_bep_sensor_t fpc_bep_sensor_1035;
+extern const fpc_bep_algorithm_t fpc_bep_algorithm_pfe_1035;
+
+const fpc_sensor_info_t fpc_sensor_info = {
+ .sensor = &fpc_bep_sensor_1035,
+ .image_buffer_size = FP_SENSOR_IMAGE_SIZE,
+};
+
+const fpc_bio_info_t fpc_bio_info = {
+ .algorithm = &fpc_bep_algorithm_pfe_1035,
+ .template_size = FP_ALGORITHM_TEMPLATE_SIZE,
+};
+#else
+#error "Sensor type not defined!"
+#endif
+
+/* Sensor IC commands */
+enum fpc_cmd {
+ FPC_CMD_DEEPSLEEP = 0x2C,
+ FPC_CMD_HW_ID = 0xFC,
+};
+
+/* Maximum size of a sensor command SPI transfer */
+#define MAX_CMD_SPI_TRANSFER_SIZE 3
+
+/* Memory for the SPI transfer buffer */
+static uint8_t spi_buf[MAX_CMD_SPI_TRANSFER_SIZE];
+
+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)
+{
+ fpc_send_cmd(FPC_CMD_DEEPSLEEP);
+}
+
+static int fpc_check_hwid(void)
+{
+ uint16_t id;
+ int rc;
+
+ 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 HW ID read failed %d", rc);
+ return FP_ERROR_SPI_COMM;
+ }
+
+ id = (spi_buf[1] << 8) | spi_buf[2];
+ if ((id >> 4) != FP_SENSOR_HWID) {
+ CPRINTS("FPC unknown silicon 0x%04x", id);
+ return FP_ERROR_BAD_HWID;
+ }
+ CPRINTS(FP_SENSOR_NAME " id 0x%04x", id);
+
+ return EC_SUCCESS;
+}
+
+/* Reset and initialize the sensor IC */
+int fp_sensor_init(void)
+{
+ int rc;
+
+ /* Print the binary libfpbep.a library version */
+ CPRINTS("FPC libfpbep.a %s", fp_sensor_get_version());
+
+ /* Print the BEP version and build time of the library */
+ CPRINTS("Build information - %s", fp_sensor_get_build_info());
+
+ rc = fp_sensor_open();
+ if (rc) {
+ errors |= FP_ERROR_INIT_FAIL;
+ CPRINTS("Error: fp_sensor_open() failed, result=%d", rc);
+ }
+
+ errors |= fpc_check_hwid();
+
+ rc = bio_algorithm_init();
+ if (rc < 0) {
+ errors |= FP_ERROR_INIT_FAIL;
+ CPRINTS("Error: bio_algorithm_init() failed, result=%d", rc);
+ }
+
+ /* Go back to low power */
+ fp_sensor_low_power();
+
+ return EC_SUCCESS;
+}
+
+/* Deinitialize the sensor IC */
+int fp_sensor_deinit(void)
+{
+ int rc;
+
+ rc = bio_algorithm_exit();
+ if (rc < 0)
+ CPRINTS("Error: bio_algorithm_exit() failed, result=%d", rc);
+
+ rc = fp_sensor_close();
+ if (rc < 0)
+ CPRINTS("Error: fp_sensor_close() failed, result=%d", rc);
+
+ return rc;
+}
+
+int fp_sensor_get_info(struct ec_response_fp_info *resp)
+{
+ int rc;
+
+ spi_buf[0] = FPC_CMD_HW_ID;
+
+ memcpy(resp, &ec_fp_sensor_info, sizeof(struct ec_response_fp_info));
+
+ 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)
+{
+ int rc;
+
+ rc = bio_template_image_match_list(templ, templ_count, image,
+ match_index, update_bitmap);
+ if (rc < 0)
+ CPRINTS("Error: bio_template_image_match_list() failed, result=%d",
+ rc);
+
+ return rc;
+}
+
+int fp_enrollment_begin(void)
+{
+ int rc;
+ bio_enrollment_t bio_enroll = enroll_ctx;
+
+ rc = bio_enrollment_begin(&bio_enroll);
+ if (rc < 0)
+ CPRINTS("Error: bio_enrollment_begin() failed, result=%d", rc);
+
+ return rc;
+}
+
+int fp_enrollment_finish(void *templ)
+{
+ int rc;
+ bio_enrollment_t bio_enroll = enroll_ctx;
+ bio_template_t bio_templ = templ;
+
+ rc = bio_enrollment_finish(bio_enroll, templ ? &bio_templ : NULL);
+ if (rc < 0)
+ CPRINTS("Error: bio_enrollment_finish() failed, result=%d", rc);
+
+ return rc;
+}
+
+int fp_finger_enroll(uint8_t *image, int *completion)
+{
+ int rc;
+ bio_enrollment_t bio_enroll = enroll_ctx;
+
+ rc = bio_enrollment_add_image(bio_enroll, image);
+ if (rc < 0) {
+ CPRINTS("Error: bio_enrollment_add_image() failed, result=%d",
+ rc);
+ return rc;
+ }
+
+ *completion = bio_enrollment_get_percent_complete(bio_enroll);
+
+ return rc;
+}