/* * * FocalTech TouchScreen driver. * * Copyright (c) 2012-2020, Focaltech Ltd. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ /***************************************************************************** * * File Name: focaltech_core.h * Author: Focaltech Driver Team * * Created: 2016-08-08 * * Abstract: * * Reference: * *****************************************************************************/ #ifndef __LINUX_FOCALTECH_CORE_H__ #define __LINUX_FOCALTECH_CORE_H__ /***************************************************************************** * Included header files *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "focaltech_common.h" #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) #include #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_HEATMAP) #include #endif /***************************************************************************** * Private constant and macro definitions using #define *****************************************************************************/ #define FTS_MAX_POINTS_SUPPORT 10 /* constant value, can't be changed */ #define FTS_MAX_KEYS 4 #define FTS_KEY_DIM 10 #define FTS_ONE_TCH_LEN 6 #define FTS_TOUCH_DATA_LEN (FTS_MAX_POINTS_SUPPORT * FTS_ONE_TCH_LEN + 3) #define FTS_GESTURE_POINTS_MAX 1 #define FTS_GESTURE_DATA_LEN (FTS_GESTURE_POINTS_MAX * 4 + 4) #define FTS_MAX_ID 0x0A #define FTS_TOUCH_X_H_POS 3 #define FTS_TOUCH_X_L_POS 4 #define FTS_TOUCH_Y_H_POS 5 #define FTS_TOUCH_Y_L_POS 6 #define FTS_TOUCH_PRE_POS 7 #define FTS_TOUCH_AREA_POS 8 #define FTS_TOUCH_POINT_NUM 2 #define FTS_TOUCH_EVENT_POS 3 #define FTS_TOUCH_ID_POS 5 #define FTS_COORDS_ARR_SIZE 4 #define FTS_X_MIN_DISPLAY_DEFAULT 0 #define FTS_Y_MIN_DISPLAY_DEFAULT 0 #define FTS_X_MAX_DISPLAY_DEFAULT 720 #define FTS_Y_MAX_DISPLAY_DEFAULT 1280 #define FTS_TOUCH_DOWN 0 #define FTS_TOUCH_UP 1 #define FTS_TOUCH_CONTACT 2 #define EVENT_DOWN(flag) ((FTS_TOUCH_DOWN == flag) || (FTS_TOUCH_CONTACT == flag)) #define EVENT_UP(flag) (FTS_TOUCH_UP == flag) #define EVENT_NO_DOWN(data) (!data->point_num) #define FTS_MAX_COMPATIBLE_TYPE 4 #define FTS_MAX_COMMMAND_LENGTH 16 /***************************************************************************** * Alternative mode (When something goes wrong, the modules may be able to solve the problem.) *****************************************************************************/ /* * For commnication error in PM(deep sleep) state */ #define FTS_PATCH_COMERR_PM 0 #define FTS_TIMEOUT_COMERR_PM 700 #define FTS_HIGH_REPORT 0 #define FTS_SIZE_DEFAULT 15 /***************************************************************************** * Private enumerations, structures and unions using typedef *****************************************************************************/ struct ftxxxx_proc { struct proc_dir_entry *proc_entry; u8 opmode; u8 cmd_len; u8 cmd[FTS_MAX_COMMMAND_LENGTH]; }; struct fts_ts_platform_data { u32 irq_gpio; u32 irq_gpio_flags; u32 reset_gpio; u32 reset_gpio_flags; struct drm_panel *panel; u32 initial_panel_index; bool have_key; u32 key_number; u32 keys[FTS_MAX_KEYS]; u32 key_y_coords[FTS_MAX_KEYS]; u32 key_x_coords[FTS_MAX_KEYS]; u32 x_max; u32 y_max; u32 x_min; u32 y_min; u32 max_touch_number; #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) u32 offload_id; #endif u32 tx_ch_num; u32 rx_ch_num; /* convert mm to pixel for major and minor */ u8 mm2px; }; struct ts_event { int x; /*x coordinate */ int y; /*y coordinate */ int p; /* pressure */ int flag; /* touch event flag: 0 -- down; 1-- up; 2 -- contact */ int id; /*touch ID */ int area; int major; int minor; }; struct pen_event { int inrange; int tip; int x; /*x coordinate */ int y; /*y coordinate */ int p; /* pressure */ int flag; /* touch event flag: 0 -- down; 1-- up; 2 -- contact */ int id; /*touch ID */ int tilt_x; int tilt_y; int tool_type; }; /* Motion filter finite state machine (FSM) states * MF_FILTERED - default coordinate filtering * MF_UNFILTERED - unfiltered single-touch coordinates * MF_FILTERED_LOCKED - filtered coordinates. Locked until touch is lifted. */ typedef enum { MF_FILTERED, MF_UNFILTERED, MF_FILTERED_LOCKED, } motion_filter_state_t; /* Motion filter mode. * MF_OFF : 0 = Always unfilter. * MF_DYNAMIC: 1 = Dynamic change motion filter. * MF_ON : 2 = Always filter by touch FW. */ enum MF_MODE { MF_OFF, MF_DYNAMIC, MF_ON, }; struct fts_ts_data { struct i2c_client *client; struct spi_device *spi; struct device *dev; struct input_dev *input_dev; struct input_dev *pen_dev; struct fts_ts_platform_data *pdata; struct ts_ic_info ic_info; struct workqueue_struct *ts_workqueue; struct work_struct fwupg_work; struct delayed_work esdcheck_work; struct delayed_work prc_work; struct work_struct resume_work; struct work_struct suspend_work; struct pm_qos_request pm_qos_req; struct ftxxxx_proc proc; spinlock_t irq_lock; struct mutex report_mutex; struct mutex bus_lock; struct mutex device_mutex; struct completion bus_resumed; unsigned long intr_jiffies; int irq; int log_level; int fw_is_running; /* confirm fw is running when using spi:default 0 */ int dummy_byte; #if defined(CONFIG_PM) && FTS_PATCH_COMERR_PM struct completion pm_completion; bool pm_suspend; #endif bool suspended; bool fw_loading; bool irq_disabled; bool power_disabled; bool glove_mode; bool cover_mode; bool charger_mode; bool gesture_mode; /* gesture enable or disable, default: disable */ bool prc_mode; struct pen_event pevent; /* multi-touch */ struct ts_event *events; u8 *bus_tx_buf; u8 *bus_rx_buf; int bus_type; u8 *point_buf; int pnt_buf_size; int touchs; int key_state; int touch_point; int point_num; /* Motion filter mode. * MF_OFF : 0 = Always unfilter. * MF_DYNAMIC: 1 = Dynamic change motion filter. * MF_ON : 2 = Always filter by touch FW. */ u8 mf_mode; /* Payload for continuously report. */ u8 set_continuously_report; /* Motion filter finite state machine (FSM) state */ motion_filter_state_t mf_state; /* Time of initial single-finger touch down. This timestamp is used to * compute the duration a single finger is touched before it is lifted. */ ktime_t mf_downtime; ktime_t bugreport_ktime_start; u8 work_mode; #if IS_ENABLED(CONFIG_TOUCHSCREEN_HEATMAP) bool enable_fw_heatmap; #endif u8 enable_fw_grip; u8 enable_fw_palm; ktime_t isr_timestamp; /* Time that the event was first received from the * touch IC, acquired during hard interrupt, in * CLOCK_MONOTONIC */ ktime_t coords_timestamp; #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) || \ IS_ENABLED(CONFIG_TOUCHSCREEN_HEATMAP) u8 *heatmap_raw; u8 *trans_raw; u16 *heatmap_buff; #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) struct touch_offload_context offload; struct touch_offload_frame *reserved_frame; #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_HEATMAP) struct v4l2_heatmap v4l2; #endif struct proc_dir_entry *proc_touch_entry; struct regulator *avdd; struct regulator *dvdd; #if FTS_PINCTRL_EN struct pinctrl *pinctrl; struct pinctrl_state *pins_active; struct pinctrl_state *pins_suspend; #endif #if defined(CONFIG_FB) || defined(CONFIG_DRM) struct notifier_block fb_notif; #elif defined(CONFIG_HAS_EARLYSUSPEND) struct early_suspend early_suspend; #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_PANEL_BRIDGE) volatile int power_status; u16 bus_refmask; struct mutex bus_mutex; struct drm_bridge panel_bridge; struct drm_connector *connector; bool is_panel_lp_mode; int display_refresh_rate; #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_TBN) u32 tbn_register_mask; #endif }; enum FTS_BUS_TYPE { FTS_BUS_TYPE_NONE, FTS_BUS_TYPE_I2C, FTS_BUS_TYPE_SPI, FTS_BUS_TYPE_SPI_V2, }; #if GOOGLE_REPORT_MODE enum FTS_CUSTOMER_STATUS { STATUS_HOPPING = 0, STATUS_PALM = 2, STATUS_WATER, STATUS_GRIP, STATUS_GLOVE, STATUS_EDGE_PALM, STATUS_LPTW, STATUS_CNT_END, }; #endif enum FTS_SCAN_MODE { MODE_AUTO, MODE_NORMAL_ACTIVE, MODE_NORMAL_IDLE, MODE_LOW_POWER_ACTIVE, MODE_LOW_POWER_IDLE, MODE_CNT, }; /***************************************************************************** * Global variable or extern global variabls/functions *****************************************************************************/ extern struct fts_ts_data *fts_data; /* communication interface */ int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen); int fts_read_reg(u8 addr, u8 *value); int fts_write(u8 *writebuf, u32 writelen); int fts_write_reg(u8 addr, u8 value); void fts_hid2std(void); int fts_bus_init(struct fts_ts_data *ts_data); int fts_bus_exit(struct fts_ts_data *ts_data); int fts_spi_transfer_direct(u8 *writebuf, u32 writelen, u8 *readbuf, u32 readlen); /* Gesture functions */ int fts_gesture_init(struct fts_ts_data *ts_data); int fts_gesture_exit(struct fts_ts_data *ts_data); void fts_gesture_recovery(struct fts_ts_data *ts_data); int fts_gesture_readdata(struct fts_ts_data *ts_data, u8 *data); int fts_gesture_suspend(struct fts_ts_data *ts_data); int fts_gesture_resume(struct fts_ts_data *ts_data); /* Heatmap */ int fts_set_heatmap_mode(struct fts_ts_data *ts_data, bool en); int fts_set_grip_mode(struct fts_ts_data *ts_datam, u8 grip_mode); int fts_set_palm_mode(struct fts_ts_data *ts_data, u8 palm_mode); int fts_set_continuous_mode(struct fts_ts_data *ts_data, bool en); int fts_set_glove_mode(struct fts_ts_data *ts_data, bool en); /* Apk and functions */ int fts_create_apk_debug_channel(struct fts_ts_data *); void fts_release_apk_debug_channel(struct fts_ts_data *); /* ADB functions */ int fts_create_sysfs(struct fts_ts_data *ts_data); int fts_remove_sysfs(struct fts_ts_data *ts_data); /* ESD */ #if FTS_ESDCHECK_EN int fts_esdcheck_init(struct fts_ts_data *ts_data); int fts_esdcheck_exit(struct fts_ts_data *ts_data); int fts_esdcheck_switch(bool enable); int fts_esdcheck_proc_busy(bool proc_debug); int fts_esdcheck_set_intr(bool intr); int fts_esdcheck_suspend(void); int fts_esdcheck_resume(void); #endif /* Production test */ #if FTS_TEST_EN int fts_test_init(struct fts_ts_data *ts_data); int fts_test_exit(struct fts_ts_data *ts_data); #endif /* Point Report Check*/ #if FTS_POINT_REPORT_CHECK_EN int fts_point_report_check_init(struct fts_ts_data *ts_data); int fts_point_report_check_exit(struct fts_ts_data *ts_data); void fts_prc_queue_work(struct fts_ts_data *ts_data); #endif /* FW upgrade */ int fts_fwupg_init(struct fts_ts_data *ts_data); int fts_fwupg_exit(struct fts_ts_data *ts_data); int fts_upgrade_bin(char *fw_name, bool force); int fts_enter_test_environment(bool test_state); /* Other */ int fts_reset_proc(int hdelayms); int fts_check_cid(struct fts_ts_data *ts_data, u8 id_h); int fts_wait_tp_to_valid(void); void fts_release_all_finger(void); void fts_tp_state_recovery(struct fts_ts_data *ts_data); int fts_ex_mode_init(struct fts_ts_data *ts_data); int fts_ex_mode_exit(struct fts_ts_data *ts_data); int fts_ex_mode_recovery(struct fts_ts_data *ts_data); void fts_update_feature_setting(struct fts_ts_data *ts_data); void fts_irq_disable(void); void fts_irq_enable(void); #if IS_ENABLED(CONFIG_TOUCHSCREEN_PANEL_BRIDGE) /* Bus reference tracking */ int fts_ts_set_bus_ref(struct fts_ts_data *ts, u16 ref, bool enable); #endif #endif /* __LINUX_FOCALTECH_CORE_H__ */