focaltech_0flash_mmi: Add double tap function

TP:
If double tap option is enabled, create a virtual sensor for moto app.

Change-Id: I7e1f5119a3979419b58775f653622859341975e5
Signed-off-by: haojl2 <haojl2@motorola.com>
Reviewed-on: https://gerrit.mot.com/1401525
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Guobin Zhang <zhanggb@motorola.com>
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1405303
Reviewed-by: Jianqi Yang <yangj@motorola.com>
This commit is contained in:
haojl2 2019-08-16 11:45:56 +08:00 • committed by Jialei Hao
commit a4e60c194c
6 changed files with 266 additions and 7 deletions

View file

@ -7,6 +7,10 @@ else
KERNEL_CFLAGS += CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME=ft8719
endif
ifneq ($(BOARD_USES_DOUBLE_TAP),)
KERNEL_CFLAGS += CONFIG_INPUT_FOCALTECH_0FLASH_MMI_ENABLE_DOUBLE_TAP=y
endif
include $(CLEAR_VARS)
LOCAL_MODULE := focaltech_0flash_mmi.ko
LOCAL_MODULE_TAGS := optional

View file

@ -34,3 +34,6 @@ ifneq ($(filter ft8009,$(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME)),)
focaltech_0flash_mmi-objs += focaltech_flash_ft8756.o
focaltech_0flash_mmi-objs += focaltech_spi_v1_1_1.o
endif
ifneq ($(filter m y,$(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_ENABLE_DOUBLE_TAP)),)
EXTRA_CFLAGS += -DFOCALTECH_SENSOR_EN
endif

View file

@ -164,7 +164,11 @@
* Gesture function enable
* default: disable
*/
#ifdef FOCALTECH_SENSOR_EN
#define FTS_GESTURE_EN 1
#else
#define FTS_GESTURE_EN 0
#endif
/*
* ESD check & protection

View file

@ -1479,6 +1479,11 @@ static int fts_ts_probe_entry(struct fts_ts_data *ts_data)
spin_lock_init(&ts_data->irq_lock);
mutex_init(&ts_data->report_mutex);
mutex_init(&ts_data->bus_lock);
#ifdef FOCALTECH_SENSOR_EN
mutex_init(&ts_data->state_mutex);
//unknown screen state
ts_data->screen_state = SCREEN_UNKNOWN;
#endif
/* Init communication interface */
ret = fts_bus_init(ts_data);
@ -1732,13 +1737,23 @@ static int fts_ts_suspend(struct device *dev)
int ret = 0;
struct fts_ts_data *ts_data = fts_data;
#ifdef FOCALTECH_SENSOR_EN
mutex_lock(&ts_data->state_mutex);
#endif
FTS_FUNC_ENTER();
if (ts_data->suspended) {
#ifdef FOCALTECH_SENSOR_EN
mutex_unlock(&ts_data->state_mutex);
#endif
FTS_INFO("Already in suspend state");
return 0;
}
if (ts_data->fw_loading) {
#ifdef FOCALTECH_SENSOR_EN
mutex_unlock(&ts_data->state_mutex);
#endif
FTS_INFO("fw upgrade in process, can't suspend");
return 0;
}
@ -1748,12 +1763,23 @@ static int fts_ts_suspend(struct device *dev)
#endif
#if FTS_GESTURE_EN
if (fts_gesture_suspend(ts_data) == 0) {
/* Enter into gesture mode(suspend) */
ts_data->suspended = true;
return 0;
#ifdef FOCALTECH_SENSOR_EN
if (ts_data->should_enable_gesture) {
#endif
if (fts_gesture_suspend(ts_data) == 0) {
/* Enter into gesture mode(suspend) */
ts_data->suspended = true;
#ifdef FOCALTECH_SENSOR_EN
ts_data->screen_state = SCREEN_OFF;
mutex_unlock(&ts_data->state_mutex);
FTS_INFO("Enter gesture suspend mode.");
#endif
return 0;
}
#ifdef FOCALTECH_SENSOR_EN
}
#endif
#endif
/* TP enter sleep mode */
@ -1776,6 +1802,10 @@ static int fts_ts_suspend(struct device *dev)
fts_release_all_finger();
ts_data->suspended = true;
FTS_FUNC_EXIT();
#ifdef FOCALTECH_SENSOR_EN
ts_data->screen_state = SCREEN_OFF;
mutex_unlock(&ts_data->state_mutex);
#endif
return 0;
}
@ -1783,8 +1813,15 @@ static int fts_ts_resume(struct device *dev)
{
struct fts_ts_data *ts_data = fts_data;
#ifdef FOCALTECH_SENSOR_EN
mutex_lock(&ts_data->state_mutex);
#endif
FTS_FUNC_ENTER();
if (!ts_data->suspended) {
#ifdef FOCALTECH_SENSOR_EN
mutex_unlock(&ts_data->state_mutex);
#endif
FTS_DEBUG("Already in awake state");
return 0;
}
@ -1805,10 +1842,22 @@ static int fts_ts_resume(struct device *dev)
#endif
#if FTS_GESTURE_EN
if (fts_gesture_resume(ts_data) == 0) {
ts_data->suspended = false;
return 0;
#ifdef FOCALTECH_SENSOR_EN
if (ts_data->should_enable_gesture) {
#endif
if (fts_gesture_resume(ts_data) == 0) {
ts_data->suspended = false;
#ifdef FOCALTECH_SENSOR_EN
ts_data->screen_state = SCREEN_ON;
mutex_unlock(&ts_data->state_mutex);
FTS_INFO("Exit from gesture suspend mode.");
#endif
return 0;
}
#ifdef FOCALTECH_SENSOR_EN
}
#endif
#endif
ts_data->suspended = false;
@ -1818,6 +1867,10 @@ static int fts_ts_resume(struct device *dev)
#endif
FTS_FUNC_EXIT();
#ifdef FOCALTECH_SENSOR_EN
mutex_unlock(&ts_data->state_mutex);
ts_data->screen_state = SCREEN_ON;
#endif
return 0;
}

View file

@ -65,6 +65,9 @@
#ifdef FTS_USB_DETECT_EN
#include <linux/power_supply.h>
#endif
#ifdef FOCALTECH_SENSOR_EN
#include <linux/sensors.h>
#endif
/*****************************************************************************
* Private constant and macro definitions using #define
@ -111,6 +114,14 @@
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
#ifdef FOCALTECH_SENSOR_EN
/* display state */
enum display_state {
SCREEN_UNKNOWN,
SCREEN_OFF,
SCREEN_ON,
};
#endif
struct ftxxxx_proc {
struct proc_dir_entry *proc_entry;
u8 opmode;
@ -145,6 +156,16 @@ struct ts_event {
int area;
};
#ifdef FOCALTECH_SENSOR_EN
struct focaltech_sensor_platform_data {
struct input_dev *input_sensor_dev;
struct sensors_classdev ps_cdev;
int sensor_opened;
char sensor_data; /* 0 near, 1 far */
struct fts_ts_data *data;
};
#endif
struct fts_ts_data {
struct i2c_client *client;
struct spi_device *spi;
@ -203,6 +224,13 @@ struct fts_ts_data {
struct notifier_block charger_notif;
#endif
#ifdef FOCALTECH_SENSOR_EN
bool wakeable;
bool should_enable_gesture;
enum display_state screen_state;
struct mutex state_mutex;
struct focaltech_sensor_platform_data *sensor_pdata;
#endif
};
/*****************************************************************************

View file

@ -67,6 +67,10 @@
#define GESTURE_Z 0x41
#define GESTURE_C 0x34
#ifdef FOCALTECH_SENSOR_EN
#define REPORT_MAX_COUNT 10000
#endif
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
@ -93,6 +97,30 @@ struct fts_gesture_st {
* Static variables
*****************************************************************************/
static struct fts_gesture_st fts_gesture_data;
#ifdef FOCALTECH_SENSOR_EN
#ifdef CONFIG_HAS_WAKELOCK
static struct wake_lock gesture_wakelock;
#else
static struct wakeup_source gesture_wakelock;
#endif
static struct sensors_classdev __maybe_unused sensors_touch_cdev = {
.name = "dt-gesture",
.vendor = "Focaltech",
.version = 1,
.type = SENSOR_TYPE_MOTO_DOUBLE_TAP,
.max_range = "5.0",
.resolution = "5.0",
.sensor_power = "1",
.min_delay = -1,
.max_delay = 0,
.fifo_reserved_event_count = 0,
.fifo_max_event_count = 0,
.enabled = 0,
.delay_msec = 200,
.sensors_enable = NULL,
.sensors_poll_delay = NULL,
};
#endif
/*****************************************************************************
* Global variable or extern global variabls/functions
@ -211,6 +239,9 @@ int fts_create_gesture_sysfs(struct device *dev)
static void fts_gesture_report(struct input_dev *input_dev, int gesture_id)
{
int gesture;
#ifdef FOCALTECH_SENSOR_EN
static int report_cnt = 0;
#endif
FTS_DEBUG("gesture_id:0x%x", gesture_id);
switch (gesture_id) {
@ -263,13 +294,134 @@ static void fts_gesture_report(struct input_dev *input_dev, int gesture_id)
/* report event key */
if (gesture != -1) {
FTS_DEBUG("Gesture Code=%d", gesture);
#ifdef FOCALTECH_SENSOR_EN
if (!fts_data->wakeable) {
FTS_INFO("Predict enable failed.");
fts_data->should_enable_gesture = false;
fts_gesture_resume(fts_data);
return;
}
input_report_abs(fts_data->sensor_pdata->input_sensor_dev,
ABS_DISTANCE, ++report_cnt);
FTS_INFO("input report: %d", report_cnt);
if (report_cnt >= REPORT_MAX_COUNT)
report_cnt = 0;
input_sync(fts_data->sensor_pdata->input_sensor_dev);
#ifdef CONFIG_HAS_WAKELOCK
wake_lock_timeout(&gesture_wakelock, msecs_to_jiffies(5000));
#else
__pm_wakeup_event(&gesture_wakelock, msecs_to_jiffies(5000));
#endif
#else
input_report_key(input_dev, gesture, 1);
input_sync(input_dev);
input_report_key(input_dev, gesture, 0);
input_sync(input_dev);
#endif
}
}
#ifdef FOCALTECH_SENSOR_EN
static int fts_sensor_set_enable(struct sensors_classdev *sensors_cdev,
unsigned int enable)
{
FTS_INFO("Gesture set enable %d!", enable);
mutex_lock(&fts_data->state_mutex);
if (enable == 1) {
fts_data->wakeable = true;
if (!fts_data->suspended && fts_data->screen_state == SCREEN_ON) {
FTS_INFO("Touch still in normal mode, skip to set to gesture mode");
mutex_unlock(&fts_data->state_mutex);
return 0;
}
if (fts_gesture_data.active == ENABLE) {
FTS_INFO("already in gesture mode");
mutex_unlock(&fts_data->state_mutex);
return 0;
}
fts_data->should_enable_gesture = true;
fts_gesture_suspend(fts_data);
FTS_INFO("Set IC in doze mode");
} else if (enable == 0) {
fts_data->wakeable = false;
//fts_gesture_resume(fts_data);
} else {
FTS_INFO("unknown enable symbol\n");
}
mutex_unlock(&fts_data->state_mutex);
return 0;
}
static int fts_sensor_init(struct fts_ts_data *data)
{
struct focaltech_sensor_platform_data *sensor_pdata;
struct input_dev *sensor_input_dev;
int err;
sensor_input_dev = input_allocate_device();
if (!sensor_input_dev) {
FTS_ERROR("Failed to allocate device");
goto exit;
}
sensor_pdata = devm_kzalloc(&sensor_input_dev->dev,
sizeof(struct focaltech_sensor_platform_data),
GFP_KERNEL);
if (!sensor_pdata) {
FTS_ERROR("Failed to allocate memory");
goto free_sensor_pdata;
}
data->sensor_pdata = sensor_pdata;
__set_bit(EV_ABS, sensor_input_dev->evbit);
__set_bit(EV_SYN, sensor_input_dev->evbit);
input_set_abs_params(sensor_input_dev, ABS_DISTANCE,
0, REPORT_MAX_COUNT, 0, 0);
sensor_input_dev->name = "double-tap";
data->sensor_pdata->input_sensor_dev = sensor_input_dev;
err = input_register_device(sensor_input_dev);
if (err) {
FTS_ERROR("Unable to register device, err=%d", err);
goto free_sensor_input_dev;
}
sensor_pdata->ps_cdev = sensors_touch_cdev;
sensor_pdata->ps_cdev.sensors_enable = fts_sensor_set_enable;
sensor_pdata->data = data;
err = sensors_classdev_register(&sensor_input_dev->dev,
&sensor_pdata->ps_cdev);
if (err)
goto unregister_sensor_input_device;
return 0;
unregister_sensor_input_device:
input_unregister_device(data->sensor_pdata->input_sensor_dev);
free_sensor_input_dev:
input_free_device(data->sensor_pdata->input_sensor_dev);
free_sensor_pdata:
devm_kfree(&sensor_input_dev->dev, sensor_pdata);
data->sensor_pdata = NULL;
exit:
return 1;
}
int fts_sensor_remove(struct fts_ts_data *data)
{
sensors_classdev_unregister(&data->sensor_pdata->ps_cdev);
input_unregister_device(data->sensor_pdata->input_sensor_dev);
devm_kfree(&data->sensor_pdata->input_sensor_dev->dev,
data->sensor_pdata);
data->sensor_pdata = NULL;
data->wakeable = false;
data->should_enable_gesture = false;
return 0;
}
#endif
/*****************************************************************************
* Name: fts_gesture_readdata
* Brief: Read information about gesture: enable flag/gesture points..., if ges-
@ -433,6 +585,9 @@ int fts_gesture_resume(struct fts_ts_data *ts_data)
int fts_gesture_init(struct fts_ts_data *ts_data)
{
struct input_dev *input_dev = ts_data->input_dev;
#ifdef FOCALTECH_SENSOR_EN
static bool initialized_sensor;
#endif
FTS_FUNC_ENTER();
input_set_capability(input_dev, EV_KEY, KEY_POWER);
@ -466,6 +621,18 @@ int fts_gesture_init(struct fts_ts_data *ts_data)
__set_bit(KEY_GESTURE_C, input_dev->keybit);
__set_bit(KEY_GESTURE_Z, input_dev->keybit);
#ifdef FOCALTECH_SENSOR_EN
if (!initialized_sensor) {
#ifdef CONFIG_HAS_WAKELOCK
wake_lock_init(&gesture_wakelock, WAKE_LOCK_SUSPEND, "poll-wake-lock");
#else
wakeup_source_init(&gesture_wakelock, "ets_wake_lock");
#endif
if (!fts_sensor_init(ts_data))
initialized_sensor = true;
}
#endif
fts_create_gesture_sysfs(ts_data->dev);
memset(&fts_gesture_data, 0, sizeof(struct fts_gesture_st));