Add CLI touch feature of single tap to wakeup device

TP:
Add CLI touch feature of single tap to wakeup device.

Change-Id: I228a3b485ce96ab6a58b2f17f42e48fe576302de
Signed-off-by: zhuwg1 <zhuwg1@motorola.com>
Reviewed-on: https://gerrit.mot.com/2221785
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: litong <litong20@motorola.com>
Reviewed-by: Jianqi Yang <yangj@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
zhuwg1 2022-03-21 18:28:31 +08:00
commit 98d5634729
6 changed files with 215 additions and 24 deletions

View file

@ -42,6 +42,15 @@ ifeq ($(GTP_LIMIT_USE_SUPPLIER),true)
KBUILD_OPTIONS += CONFIG_GTP_LIMIT_USE_SUPPLIER=y
endif
ifneq ($(BOARD_USES_DOUBLE_TAP),)
KBUILD_OPTIONS += CONFIG_INPUT_CYTTSP5_MMI_ENABLE_DOUBLE_TAP=y
endif
include $(CLEAR_VARS)
ifneq ($(BOARD_USES_DOUBLE_TAP),)
LOCAL_ADDITIONAL_DEPENDENCIES += $(KERNEL_MODULES_OUT)/sensors_class.ko
endif
include $(CLEAR_VARS)
LOCAL_MODULE := parade_tma5xx_mmi_core.ko
LOCAL_MODULE_TAGS := optional

View file

@ -77,4 +77,9 @@ ifneq ($(filter m y,$(CONFIG_GTP_LIMIT_USE_SUPPLIER)),)
EXTRA_CFLAGS += -DCONFIG_GTP_LIMIT_USE_SUPPLIER
endif
ifneq ($(filter m y,$(CONFIG_INPUT_CYTTSP5_MMI_ENABLE_DOUBLE_TAP)),)
EXTRA_CFLAGS += -DCYTTSP5_SENSOR_EN
KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../../../sensors/$(GKI_OBJ_MODULE_DIR)/Module.symvers
endif
KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../touchscreen_mmi/$(GKI_OBJ_MODULE_DIR)/Module.symvers

View file

@ -13,4 +13,5 @@ clean:
rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers
rm -rf .tmp_versions
KBUILD_EXTRA_SYMBOLS += $(M)/../../../sensors/Module.symvers
KBUILD_EXTRA_SYMBOLS += $(M)/../touchscreen_mmi/$(GKI_OBJ_MODULE_DIR)/Module.symvers

View file

@ -118,6 +118,28 @@ struct cyttsp5_hid_output {
u16 timeout_ms;
};
#if defined (CYTTSP5_SENSOR_EN)
static struct sensors_classdev __maybe_unused sensors_touch_cdev = {
.name = "s-dt-gesture",
.vendor = "Parade",
.version = 1,
.type = SENSOR_TYPE_MOTO_DOUBLE_TAP,
.max_range = "5.0",
.resolution = "5.0",
.sensor_power = "1",
.min_delay = 0,
.max_delay = 0,
/* WAKE_UP & SPECIAL_REPORT */
.flags = 1 | 6,
.fifo_reserved_event_count = 0,
.fifo_max_event_count = 0,
.enabled = 0,
.delay_msec = 200,
.sensors_enable = NULL,
.sensors_poll_delay = NULL,
};
#endif
#define SET_CMD_OPCODE(byte, opcode) SET_CMD_LOW(byte, opcode)
#define SET_CMD_REPORT_TYPE(byte, type) SET_CMD_HIGH(byte, ((type) << 4))
#define SET_CMD_REPORT_ID(byte, id) SET_CMD_LOW(byte, id)
@ -3840,6 +3862,8 @@ static int cyttsp5_put_device_into_easy_wakeup_(struct cyttsp5_core_data *cd)
int rc;
u8 status = 0;
dev_info(cd->dev, "%s: put device into easy wakeup state\n", __func__);
mutex_lock(&cd->system_lock);
cd->wait_until_wake = 0;
mutex_unlock(&cd->system_lock);
@ -3908,7 +3932,10 @@ static int cyttsp5_core_sleep_(struct cyttsp5_core_data *cd)
cancel_work_sync(&cd->startup_work);
cyttsp5_stop_wd_timer(cd);
if (cd->cpdata->flags & CY_CORE_FLAG_POWEROFF_ON_SLEEP)
if (!IS_DEEP_SLEEP_CONFIGURED(cd->easy_wakeup_gesture) &&
(cd->should_enable_gesture ==1)) {
rc = cyttsp5_put_device_into_sleep_(cd);
} else if (cd->cpdata->flags & CY_CORE_FLAG_POWEROFF_ON_SLEEP)
rc = cyttsp5_core_poweroff_device_(cd);
else
rc = cyttsp5_put_device_into_sleep_(cd);
@ -3979,7 +4006,9 @@ exit:
if (cd->input_buf[2] != 4)
rc = -EINVAL;
#if 0
cd->wake_initiated_by_device = 1;
#endif
parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: rc=%d\n", __func__, rc);
@ -4514,6 +4543,8 @@ static int cyttsp5_core_wake_device_from_deep_sleep_(
{
int rc;
dev_info(cd->dev, "%s: wake device from deep sleep state\n", __func__);
rc = cyttsp5_hid_cmd_set_power_(cd, HID_POWER_ON);
if (rc)
rc = -EAGAIN;
@ -4533,10 +4564,12 @@ static int cyttsp5_core_wake_device_(struct cyttsp5_core_data *cd)
wake_up(&cd->wait_q);
msleep(20);
#if 0
if (cd->wake_initiated_by_device) {
cd->wake_initiated_by_device = 0;
return 0;
}
#endif
}
return cyttsp5_core_wake_device_from_deep_sleep_(cd);
@ -4663,7 +4696,10 @@ static int cyttsp5_core_wake_(struct cyttsp5_core_data *cd)
}
mutex_unlock(&cd->system_lock);
if (cd->cpdata->flags & CY_CORE_FLAG_POWEROFF_ON_SLEEP)
if (!IS_DEEP_SLEEP_CONFIGURED(cd->easy_wakeup_gesture) &&
(cd->should_enable_gesture ==1)) {
rc = cyttsp5_core_wake_device_(cd);
} else if (cd->cpdata->flags & CY_CORE_FLAG_POWEROFF_ON_SLEEP)
rc = cyttsp5_core_poweron_device_(cd);
else
rc = cyttsp5_core_wake_device_(cd);
@ -5059,17 +5095,19 @@ int cyttsp5_core_suspend(struct device *dev)
* This will not prevent resume
* Required to prevent interrupts before i2c awake
*/
disable_irq(cd->irq);
cd->irq_disabled = 1;
if (device_may_wakeup(dev)) {
parade_debug(dev, DEBUG_LEVEL_2, "%s Device MAY wakeup\n",
__func__);
if (!enable_irq_wake(cd->irq))
cd->irq_wake = 1;
if (!cd->should_enable_gesture) {
disable_irq(cd->irq);
cd->irq_disabled = 1;
} else {
parade_debug(dev, DEBUG_LEVEL_1, "%s Device MAY NOT wakeup\n",
__func__);
if (device_may_wakeup(dev)) {
parade_debug(dev, DEBUG_LEVEL_2, "%s Device MAY wakeup\n",
__func__);
if (!enable_irq_wake(cd->irq))
cd->irq_wake = 1;
} else {
parade_debug(dev, DEBUG_LEVEL_1, "%s Device MAY NOT wakeup\n",
__func__);
}
}
return 0;
@ -5091,18 +5129,19 @@ int cyttsp5_core_resume(struct device *dev)
cd->irq_disabled = 0;
}
if (device_may_wakeup(dev)) {
parade_debug(dev, DEBUG_LEVEL_2, "%s Device MAY wakeup\n",
__func__);
if (cd->irq_wake) {
disable_irq_wake(cd->irq);
cd->irq_wake = 0;
if (cd->should_enable_gesture) {
if (device_may_wakeup(dev)) {
parade_debug(dev, DEBUG_LEVEL_2, "%s Device MAY wakeup\n",
__func__);
if (cd->irq_wake) {
disable_irq_wake(cd->irq);
cd->irq_wake = 0;
}
} else {
parade_debug(dev, DEBUG_LEVEL_1, "%s Device MAY NOT wakeup\n",
__func__);
}
} else {
parade_debug(dev, DEBUG_LEVEL_1, "%s Device MAY NOT wakeup\n",
__func__);
}
exit:
cyttsp5_core_wake(cd);
@ -6562,6 +6601,95 @@ static int cyttsp5_setup_irq_gpio(struct cyttsp5_core_data *cd)
return rc;
}
#ifdef CYTTSP5_SENSOR_EN
static int cyttsp5_sensor_set_enable(struct sensors_classdev *sensors_cdev,
unsigned int enable)
{
struct cyttsp5_sensor_platform_data *sensor_pdata = container_of(
sensors_cdev, struct cyttsp5_sensor_platform_data, ps_cdev);
struct cyttsp5_core_data *cd = sensor_pdata->data;
pr_info("%s: Gesture set enable %d!", __func__, enable);
mutex_lock(&cd->state_mutex);
if (enable == 1) {
cd->should_enable_gesture = true;
} else if (enable == 0) {
cd->should_enable_gesture = false;
} else {
pr_info("%s: unknown enable symbol\n", __func__);
}
mutex_unlock(&cd->state_mutex);
return 0;
}
static int cyttsp5_sensor_init(struct cyttsp5_core_data *data)
{
struct cyttsp5_sensor_platform_data *sensor_pdata;
struct input_dev *sensor_input_dev;
int err;
sensor_input_dev = input_allocate_device();
if (!sensor_input_dev) {
pr_err("%s: Failed to allocate device", __func__);
goto exit;
}
sensor_pdata = devm_kzalloc(&sensor_input_dev->dev,
sizeof(struct cyttsp5_sensor_platform_data),
GFP_KERNEL);
if (!sensor_pdata) {
pr_err("%s: Failed to allocate memory", __func__);
goto free_sensor_pdata;
}
data->sensor_pdata = sensor_pdata;
__set_bit(EV_KEY, sensor_input_dev->evbit);
__set_bit(KEY_F1, sensor_input_dev->keybit);
__set_bit(EV_SYN, sensor_input_dev->evbit);
sensor_input_dev->name = "s-double-tap";
data->sensor_pdata->input_sensor_dev = sensor_input_dev;
err = input_register_device(sensor_input_dev);
if (err) {
pr_err("%s: Unable to register device, err=%d", __func__, err);
goto free_sensor_input_dev;
}
sensor_pdata->ps_cdev = sensors_touch_cdev;
sensor_pdata->ps_cdev.sensors_enable = cyttsp5_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 cyttsp5_sensor_remove(struct cyttsp5_core_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->should_enable_gesture = false;
return 0;
}
#endif
int cyttsp5_probe(const struct cyttsp5_bus_ops *ops, struct device *dev,
u16 irq, size_t xfer_buf_size)
{
@ -6569,6 +6697,9 @@ int cyttsp5_probe(const struct cyttsp5_bus_ops *ops, struct device *dev,
struct cyttsp5_platform_data *pdata = dev_get_platdata(dev);
enum cyttsp5_atten_type type;
int rc = 0;
#ifdef CYTTSP5_SENSOR_EN
static bool initialized_sensor;
#endif
/* Set default values on first probe */
if (cyttsp5_first_probe) {
@ -6773,6 +6904,15 @@ int cyttsp5_probe(const struct cyttsp5_bus_ops *ops, struct device *dev,
}
#endif
#if defined (CYTTSP5_SENSOR_EN)
if (!initialized_sensor) {
if (!cyttsp5_sensor_init(cd))
initialized_sensor = true;
else
dev_err(dev, "%s: cyttsp5 init sensor fail.\n", __func__);
}
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
cyttsp5_setup_early_suspend(cd);
#elif defined(CONFIG_FB)

View file

@ -364,7 +364,7 @@ static void cyttsp5_mt_send_dummy_event(struct cyttsp5_core_data *cd,
#else
/* TSG6 FW1.3 and above only. TSG6 FW1.0 - 1.2 does not */
/* support EasyWake, and this function will not be called */
u8 key_value;
u8 key_value = 0;
switch (cd->gesture_id) {
case GESTURE_DOUBLE_TAP:
@ -374,7 +374,11 @@ static void cyttsp5_mt_send_dummy_event(struct cyttsp5_core_data *cd,
key_value = KEY_F2;
break;
case GESTURE_TOUCH_DETECTED:
#ifdef CYTTSP5_SENSOR_EN
key_value = KEY_F1;
#else
key_value = KEY_F3;
#endif
break;
case GESTURE_PUSH_BUTTON:
key_value = KEY_F4;
@ -395,11 +399,24 @@ static void cyttsp5_mt_send_dummy_event(struct cyttsp5_core_data *cd,
break;
}
#ifdef CYTTSP5_SENSOR_EN
if (!(cd->easy_wakeup_gesture && cd->should_enable_gesture)) {
dev_info(cd->dev, "Gesture got but wakeable not set. Skip this gesture.");
return;
}
input_report_key(cd->sensor_pdata->input_sensor_dev, key_value, 1);
input_sync(cd->sensor_pdata->input_sensor_dev);
input_report_key(cd->sensor_pdata->input_sensor_dev, key_value, 0);
input_sync(cd->sensor_pdata->input_sensor_dev);
dev_info(cd->dev, "%s: report single tap, cd->gesture_id = %d, key_value = %d\n",
__func__, cd->gesture_id, key_value);
#else
input_report_key(md->input, key_value, 1);
mdelay(10);
input_report_key(md->input, key_value, 0);
input_sync(md->input);
#endif
#endif
}
static int cyttsp5_mt_attention(struct device *dev)

View file

@ -66,9 +66,13 @@
#include <linux/rtc.h>
#include <linux/regulator/consumer.h>
#ifdef CYTTSP5_SENSOR_EN
#include <linux/sensors.h>
#endif
//#define PT_PANEL_ID_FROM_MFG
/* #define EASYWAKE_TSG6 */
#define EASYWAKE_TSG6
#define PT_PIP2_MAX_FILE_SIZE 0x18000
#define CY_FW_FILE_PREFIX "cyttsp5_fw"
#define CY_FW_FILE_SUFFIX ".bin"
@ -942,6 +946,16 @@ struct cyttsp5_module {
void (*release)(struct device *dev, void *data);
};
#ifdef CYTTSP5_SENSOR_EN
struct cyttsp5_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 cyttsp5_core_data *data;
};
#endif
struct cyttsp5_core_data {
struct list_head node;
struct list_head module_list; /* List of probed modules */
@ -1022,6 +1036,11 @@ struct cyttsp5_core_data {
struct mutex tthe_lock;
u8 tthe_exit;
#endif
#ifdef CYTTSP5_SENSOR_EN
bool should_enable_gesture;
struct mutex state_mutex;
struct cyttsp5_sensor_platform_data *sensor_pdata;
#endif
u8 pr_buf[CY_MAX_PRBUF_SIZE];
u8 debug_level;
u32 watchdog_interval;