Initial GXFP5130 userspace prototype

This commit is contained in:
2026-08-03 11:43:42 +03:00
commit 088d8ef75c
30 changed files with 5318 additions and 0 deletions

48
include/gxfp/config.h Normal file
View File

@@ -0,0 +1,48 @@
// SPDX-License-Identifier: GPL-2.0-only
#ifndef GXFP_CONFIG_H
#define GXFP_CONFIG_H
#include <stddef.h>
#include <stdint.h>
#define GXFP_CONFIG_SIZE 0xE0u
#define GXFP_CONFIG_SECTION_COUNT 8u
enum gxfp_config_write_mode {
GXFP_CONFIG_WRITE_WORD = 0,
GXFP_CONFIG_WRITE_LOW_BYTE = 1,
GXFP_CONFIG_WRITE_HIGH_BYTE = 2,
};
struct gxfp_dac_info;
struct gxfp_chicagohu_config_info {
uint8_t tcode_diff;
uint16_t tcode;
uint8_t fdt_delta;
uint8_t fdt_offset;
uint16_t checksum;
};
uint16_t gxfp_config_checksum(const uint8_t config[GXFP_CONFIG_SIZE]);
int gxfp_config_update_checksum(uint8_t config[GXFP_CONFIG_SIZE]);
int gxfp_config_modify_register(uint8_t config[GXFP_CONFIG_SIZE],
uint16_t reg,
uint16_t value,
unsigned int section,
enum gxfp_config_write_mode mode,
uint16_t *old_value);
int gxfp_config_patch_dac(uint8_t config[GXFP_CONFIG_SIZE],
const uint16_t register_values[4]);
int gxfp_config_build_chicagohu_2504(
uint8_t config[GXFP_CONFIG_SIZE],
const void *otp,
size_t otp_len,
const struct gxfp_dac_info *dac,
struct gxfp_chicagohu_config_info *info);
#endif

32
include/gxfp/device.h Normal file
View File

@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0-only
#ifndef GXFP_DEVICE_H
#define GXFP_DEVICE_H
#include <stddef.h>
#include <stdint.h>
struct gxfp_device {
int fd;
};
struct gxfp_rx_record {
uint32_t mp_type;
uint64_t timestamp_ns;
uint8_t *payload;
size_t payload_len;
};
int gxfp_device_open(struct gxfp_device *device, const char *path);
void gxfp_device_close(struct gxfp_device *device);
int gxfp_device_flush_rx(struct gxfp_device *device);
int gxfp_device_send_mp(struct gxfp_device *device, uint8_t mp_flags,
const void *payload, size_t payload_len);
int gxfp_device_receive(struct gxfp_device *device,
struct gxfp_rx_record *record,
int timeout_ms);
void gxfp_rx_record_release(struct gxfp_rx_record *record);
#endif

34
include/gxfp/fdt.h Normal file
View File

@@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-2.0-only
#ifndef GXFP_FDT_H
#define GXFP_FDT_H
#include <stdbool.h>
#include <stdint.h>
struct gxfp_device;
struct gxfp_frame_view;
enum gxfp_fdt_event {
GXFP_FDT_EVENT_NONE = 0,
GXFP_FDT_EVENT_READY,
GXFP_FDT_EVENT_FINGER_DOWN,
GXFP_FDT_EVENT_FINGER_UP,
GXFP_FDT_EVENT_REVERSE,
};
struct gxfp_fdt {
bool waiting_for_up;
};
void gxfp_fdt_init(struct gxfp_fdt *fdt);
int gxfp_fdt_arm_down(struct gxfp_device *device);
int gxfp_fdt_arm_up(struct gxfp_device *device);
enum gxfp_fdt_event
gxfp_fdt_decode(const struct gxfp_frame_view *frame, uint16_t *status);
int gxfp_fdt_handle_event(struct gxfp_fdt *fdt,
struct gxfp_device *device,
enum gxfp_fdt_event event);
#endif

View File

@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _UAPI_GOODIX_EC_H_
#define _UAPI_GOODIX_EC_H_
#include <linux/ioctl.h>
#include <linux/types.h>
#define GOODIX_EC_UAPI_MAGIC 'G'
#define GOODIX_EC_UAPI_TX_MAX 500u
#define GOODIX_EC_UAPI_RX_MAX (128u * 1024u)
/*
* read(2) returns one record:
* struct goodix_ec_record_header
* followed by len bytes of MP payload (normally one Goodix frame).
*/
struct goodix_ec_record_header {
__u32 len;
__u32 mp_type;
__u64 timestamp_ns;
};
/*
* write(2) accepts:
* struct goodix_ec_tx_header
* followed by payload_len bytes used as the MP payload.
*/
struct goodix_ec_tx_header {
__u8 mp_flags;
__u8 reserved;
__u16 payload_len;
__u32 flags;
};
#define GOODIX_EC_IOCTL_FLUSH_RX _IO(GOODIX_EC_UAPI_MAGIC, 0x11)
#endif /* _UAPI_GOODIX_EC_H_ */

29
include/gxfp/protocol.h Normal file
View File

@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0-only
#ifndef GXFP_PROTOCOL_H
#define GXFP_PROTOCOL_H
#include <stddef.h>
#include <stdint.h>
#define GXFP_MP_COMMAND 0xA0
#define GXFP_MP_RX_COMMAND 0x0A
#define GXFP_GOODIX_CHECKSUM_TARGET 0xAA
#define GXFP_GOODIX_ACK 0xB0
#define GXFP_CMD_IMAGE_CAPTURE 0x20
struct gxfp_frame_view {
uint8_t command;
const uint8_t *payload;
size_t payload_len;
uint8_t checksum;
};
int gxfp_frame_build(uint8_t command,
const void *payload, size_t payload_len,
uint8_t *output, size_t output_capacity,
size_t *output_len);
int gxfp_frame_parse(const void *frame, size_t frame_len,
struct gxfp_frame_view *view);
#endif

28
include/gxfp/request.h Normal file
View File

@@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-2.0-only
#ifndef GXFP_REQUEST_H
#define GXFP_REQUEST_H
#include <stddef.h>
#include <stdint.h>
struct gxfp_device;
struct gxfp_response {
uint8_t command;
uint8_t *payload;
size_t payload_len;
uint64_t timestamp_ns;
};
int gxfp_request(struct gxfp_device *device,
uint8_t command,
const void *payload,
size_t payload_len,
uint8_t expected_command,
unsigned int max_frames,
int timeout_ms,
struct gxfp_response *response);
void gxfp_response_release(struct gxfp_response *response);
#endif

92
include/gxfp/sensor.h Normal file
View File

@@ -0,0 +1,92 @@
// SPDX-License-Identifier: GPL-2.0-only
#ifndef GXFP_SENSOR_H
#define GXFP_SENSOR_H
#include <stddef.h>
#include <stdint.h>
struct gxfp_device;
struct gxfp_otp_crc_info {
int cp_valid;
int ft_valid;
int mt_valid;
uint8_t cp_calculated;
uint8_t ft_calculated;
uint8_t mt_calculated;
uint8_t cp_stored;
uint8_t ft_stored;
uint8_t mt_stored;
};
struct gxfp_dac_info {
uint16_t raw[4];
uint16_t register_value[4];
unsigned int match_count;
int used_ft;
int used_mt;
int used_fallback;
struct gxfp_otp_crc_info crc;
};
struct gxfp_mcu_state {
uint8_t version;
uint8_t flags;
int pov_image_valid;
int tls_connected;
int tls_used;
int locked;
uint8_t reserved[18];
};
int gxfp_sensor_read_version(struct gxfp_device *device,
char *version, size_t version_capacity);
int gxfp_sensor_query_mcu_state(struct gxfp_device *device,
struct gxfp_mcu_state *state);
int gxfp_sensor_recover(struct gxfp_device *device, int unstick_tls);
int gxfp_sensor_reset(struct gxfp_device *device);
int gxfp_sensor_start_tls(struct gxfp_device *device);
int gxfp_sensor_download_config(struct gxfp_device *device,
const void *config,
size_t config_len);
int gxfp_sensor_reset_and_download_config(
struct gxfp_device *device,
const void *config,
size_t config_len);
int gxfp_sensor_capture_oneframe(struct gxfp_device *device,
void *output,
size_t output_capacity,
size_t *output_len);
int gxfp_sensor_read_register(struct gxfp_device *device,
uint16_t address,
void *output,
uint16_t output_len);
int gxfp_sensor_read_chip_id(struct gxfp_device *device,
uint16_t *chip_id);
int gxfp_sensor_read_otp(struct gxfp_device *device,
void *output,
size_t output_capacity,
size_t *output_len);
int gxfp_sensor_check_chicagohu_otp_crc(
const void *otp,
size_t otp_len,
struct gxfp_otp_crc_info *info);
int gxfp_sensor_parse_dac(const void *otp,
size_t otp_len,
int force_ft,
int force_mt,
struct gxfp_dac_info *info);
#endif

58
include/gxfp/session.h Normal file
View File

@@ -0,0 +1,58 @@
// SPDX-License-Identifier: GPL-2.0-only
#ifndef GXFP_SESSION_H
#define GXFP_SESSION_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct gxfp_session;
enum gxfp_session_state {
GXFP_SESSION_OPEN = 0,
GXFP_SESSION_ACTIVE,
GXFP_SESSION_WAITING_FINGER_DOWN,
GXFP_SESSION_FINGER_PRESENT,
GXFP_SESSION_CAPTURING,
GXFP_SESSION_WAITING_FINGER_UP,
GXFP_SESSION_ERROR,
};
struct gxfp_image12 {
uint16_t *pixels;
size_t width;
size_t height;
uint8_t header[5];
uint8_t trailer;
uint32_t crc_stored;
uint32_t crc_calculated;
};
int gxfp_session_open(struct gxfp_session **out, const char *device_path);
int gxfp_session_activate(struct gxfp_session *session, int timeout_ms);
int gxfp_session_deactivate(struct gxfp_session *session);
int gxfp_session_arm_finger_down(struct gxfp_session *session);
int gxfp_session_wait_finger_down(struct gxfp_session *session, int timeout_ms);
int gxfp_session_capture(struct gxfp_session *session,
struct gxfp_image12 *image, int timeout_ms);
int gxfp_session_arm_finger_up(struct gxfp_session *session);
int gxfp_session_wait_finger_up(struct gxfp_session *session, int timeout_ms);
int gxfp_image12_to_u8(const struct gxfp_image12 *source,
uint8_t *destination, size_t destination_size);
void gxfp_image12_clear(struct gxfp_image12 *image);
void gxfp_session_cancel(struct gxfp_session *session);
enum gxfp_session_state
gxfp_session_get_state(const struct gxfp_session *session);
void gxfp_session_close(struct gxfp_session *session);
#ifdef __cplusplus
}
#endif
#endif

36
include/gxfp/tls.h Normal file
View File

@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-2.0-only
#ifndef GXFP_TLS_H
#define GXFP_TLS_H
#include <stddef.h>
#include <stdint.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ssl.h>
#include "gxfp/device.h"
struct gxfp_tls {
struct gxfp_device *device;
mbedtls_ssl_context ssl;
mbedtls_ssl_config config;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
unsigned char *rx_buffer;
size_t rx_length;
size_t rx_offset;
int initialized;
};
int gxfp_tls_init(struct gxfp_tls *tls, struct gxfp_device *device);
int gxfp_tls_handshake(struct gxfp_tls *tls);
int gxfp_tls_handshake_timeout(struct gxfp_tls *tls, int timeout_ms);
int gxfp_tls_write_all(struct gxfp_tls *tls, const void *data, size_t len);
int gxfp_tls_read(struct gxfp_tls *tls, void *data, size_t capacity,
size_t *data_len);
int gxfp_tls_read_timeout(struct gxfp_tls *tls, void *data, size_t capacity,
size_t *data_len, int timeout_ms);
void gxfp_tls_close(struct gxfp_tls *tls);
#endif