input: touchscreen: cyttsp5: fix gesture wakeup issue
The gesture report size is not 4 bytes by default.
After fix this, touch gesture wakeup works.
Change-Id: I7a8d0b8cacd596ef69551cef75e9bdbcbf159245
Signed-off-by: Fei <feim1@codeaurora.org>
diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c
index a8f1df3..ef4bf38 100644
--- a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c
+++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c
@@ -3614,7 +3614,8 @@
struct cyttsp5_core_data *cd =
container_of(work, struct cyttsp5_core_data,
watchdog_work);
- int rc;
+ int rc = 0;
+
/*fix CDT207254
*if found the current sleep_state is SS_SLEEPING
*then no need to request_exclusive, directly return
@@ -3768,6 +3769,7 @@
mutex_lock(&cd->system_lock);
cd->sleep_state = SS_SLEEP_ON;
+ cd->large_power_state = 0;
mutex_unlock(&cd->system_lock);
return rc;
@@ -3801,13 +3803,11 @@
/* TSG5 EasyWake */
int rc = 0;
int event_id;
- int size = get_unaligned_le16(&cd->input_buf[0]);
/* Validate report */
- if (size != 4 || cd->input_buf[2] != 4)
+ if (cd->input_buf[2] != 4)
rc = -EINVAL;
- cd->wake_initiated_by_device = 1;
event_id = cd->input_buf[3];
parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: e=%d, rc=%d\n",
@@ -3818,6 +3818,21 @@
goto exit;
}
+ if (event_id != 3 && event_id != 0xAA) {
+ dev_err(cd->dev, "do not wake up by filter\n");
+ if (event_id == GESTURE_SINGLE_QUICK_CALL)
+ goto callcb;
+ else
+ goto exit;
+ }
+
+ if (cd->wake_initiated_by_device == 1) {
+ dev_dbg(cd->dev, "%s: try to re-send power key\n", __func__);
+ goto exit;
+ }
+ cd->wake_initiated_by_device = 1;
+
+callcb:
/* attention WAKE */
call_atten_cb(cd, CY_ATTEN_WAKE, 0);
exit:
@@ -4094,9 +4109,24 @@
read:
rc = cyttsp5_adap_read_default_nosize(cd, cd->input_buf, CY_MAX_INPUT);
if (rc) {
- dev_err(dev, "%s: Error getting report, r=%d\n",
- __func__, rc);
+ dev_err(dev, "%s: Error getting report, r=%d\n", __func__, rc);
+ #ifdef PATCH_WAKEUP_NACK_ISSUE
+ if (cd->sleep_state == SS_SLEEP_ON) {
+ cd->input_buf[0] = 0x07;
+ cd->input_buf[1] = 0x00;
+ cd->input_buf[2] = 0x04;
+ cd->input_buf[3] = 0xAA;
+ cd->input_buf[4] = 0x00;
+ cd->input_buf[5] = 0x00;
+ cd->input_buf[6] = 0x00;
+ dev_info(dev, "Self recover for I2C Bus err\n");
+ rc = 0;
+ } else
+ return rc;
+
+ #else
return rc;
+ #endif
}
parade_debug(dev, DEBUG_LEVEL_2, "%s: Read input successfully\n",
__func__);
@@ -4805,38 +4835,6 @@
__func__, rc);
}
-/*
- * CONFIG_PM_RUNTIME option is removed in 3.19.0.
- */
-
-static int cyttsp5_core_rt_suspend(struct device *dev)
-{
- struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
- int rc;
-
- rc = cyttsp5_core_sleep(cd);
- if (rc < 0) {
- dev_err(dev, "%s: Error on sleep\n", __func__);
- return -EAGAIN;
- }
- return 0;
-}
-
-static int cyttsp5_core_rt_resume(struct device *dev)
-{
- struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
- int rc;
-
- rc = cyttsp5_core_wake(cd);
- if (rc < 0) {
- dev_err(dev, "%s: Error on wake\n", __func__);
- return -EAGAIN;
- }
-
- return 0;
-}
-
-
#if defined(CONFIG_PM_SLEEP)
static int cyttsp5_core_suspend(struct device *dev)
{
@@ -4851,18 +4849,24 @@
* This will not prevent resume
* Required to prevent interrupts before i2c awake
*/
- disable_irq(cd->irq);
- cd->irq_disabled = 1;
+
+ /*
+ * 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))
+ if (!enable_irq_wake(cd->irq)) {
cd->irq_wake = 1;
+ dev_info(dev, "suspend irq - cd->irq_wake = 1\n");
+ }
} else
parade_debug(dev, DEBUG_LEVEL_1, "%s Device MAY NOT wakeup\n",
__func__);
+ cd->forbit_bigobject = 0;
return 0;
}
@@ -4877,10 +4881,13 @@
* I2C bus pm does not call suspend if device runtime suspended
* This flag is cover that case
*/
- if (cd->irq_disabled) {
- enable_irq(cd->irq);
- cd->irq_disabled = 0;
- }
+
+ /*
+ * if (cd->irq_disabled) {
+ * enable_irq(cd->irq);
+ * cd->irq_disabled = 0;
+ * }
+ */
if (device_may_wakeup(dev)) {
parade_debug(dev, DEBUG_LEVEL_2, "%s Device MAY wakeup\n",
@@ -4925,10 +4932,25 @@
}
#endif
+#ifdef USE_FB_SUSPEND_RESUME
+static int cyttsp5_temp_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int cyttsp5_temp_resume(struct device *dev)
+{
+ return 0;
+}
+#endif
+
const struct dev_pm_ops cyttsp5_pm_ops = {
+#ifdef USE_FB_SUSPEND_RESUME
+ //SET_SYSTEM_SLEEP_PM_OPS(cyttsp5_core_suspend, cyttsp5_core_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(cyttsp5_temp_suspend, cyttsp5_temp_resume)
+#else
SET_SYSTEM_SLEEP_PM_OPS(cyttsp5_core_suspend, cyttsp5_core_resume)
- SET_RUNTIME_PM_OPS(cyttsp5_core_rt_suspend, cyttsp5_core_rt_resume,
- NULL)
+#endif
};
EXPORT_SYMBOL_GPL(cyttsp5_pm_ops);
@@ -5461,7 +5483,7 @@
struct cyttsp5_platform_data *pdata = dev_get_platdata(dev);
ssize_t ret;
- ret = snprintf(buf, PAGE_SIZE,
+ ret = snprintf(buf, CY_MAX_PRBUF_SIZE,
"%s: %d\n"
"%s: %d\n"
"%s: %d\n"
@@ -5489,6 +5511,37 @@
return ret;
}
+static ssize_t cyttsp5_bigobjectoff_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned int data;
+ int error;
+ struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
+
+ error = kstrtoint(buf, 10, &data);
+ if (error < 0)
+ return error;
+
+ if (data != 0)
+ cd->forbit_bigobject = 1;
+ else
+ cd->forbit_bigobject = 0;
+
+ pr_info("cyttsp5_bigobjectoff_store forbitobject:%d\n",
+ cd->forbit_bigobject);
+ return count;
+}
+
+static ssize_t cyttsp5_bigobjectoff_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
+ ssize_t ret;
+
+ ret = snprintf(buf, CY_MAX_PRBUF_SIZE, "%d\n", cd->forbit_bigobject);
+ return ret;
+}
+
static struct device_attribute attributes[] = {
__ATTR(ic_ver, 0444, cyttsp5_ic_ver_show, NULL),
__ATTR(drv_ver, 0444, cyttsp5_drv_ver_show, NULL),
@@ -5509,6 +5562,9 @@
#endif
__ATTR(panel_id, 0444, cyttsp5_panel_id_show, NULL),
__ATTR(platform_data, 0444, cyttsp5_platform_data_show, NULL),
+ __ATTR(bigobject_off, 0600,
+ cyttsp5_bigobjectoff_show,
+ cyttsp5_bigobjectoff_store),
};
static int add_sysfs_interfaces(struct device *dev)
@@ -5563,15 +5619,14 @@
#endif
rc = cyttsp5_probe(cyttsp5_bus_ops_save, &client->dev, client->irq,
- 512);
+ 512);
if (!rc) {
is_cyttsp5_probe_success = true;
dev_err(dev, "%s restart successful\n", __func__);
} else {
is_cyttsp5_probe_success = false;
- dev_err(dev, "%s: ttdl restart failed r=%d\n",
- __func__, rc);
+ dev_err(dev, "%s: ttdl restart failed r=%d\n", __func__, rc);
}
#ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
index 2cdea6f..59bf31a 100644
--- a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
+++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
@@ -4885,7 +4885,7 @@
cyttsp5_get_device_access_data(dev);
if (!fw) {
- dev_info(dev, "%s: No builtin cmcp threshold file\n", __func__);
+ dev_dbg(dev, "%s: No builtin cmcp threshold file\n", __func__);
goto exit;
}
diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c
index 69fe997..62f92c3 100644
--- a/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c
+++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c
@@ -312,6 +312,7 @@
static int cyttsp5_xy_worker(struct cyttsp5_mt_data *md)
{
struct device *dev = md->dev;
+ struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
struct cyttsp5_sysinfo *si = md->si;
int max_tch = si->sensing_conf_data.max_tch;
struct cyttsp5_touch tch;
@@ -332,6 +333,19 @@
__func__);
if (md->pdata->flags & CY_MT_FLAG_NO_TOUCH_ON_LO)
num_cur_tch = 0;
+
+ if (tch.hdr[CY_TCH_LO] && cd->large_power_state != 1) {
+ dev_info(dev,
+ "%s: Large area detected forbitobject:%d\n",
+ __func__, cd->forbit_bigobject);
+ if (cd->forbit_bigobject != 1) {
+ input_report_key(md->input, KEY_POWER, 1);
+ input_sync(md->input);
+ input_report_key(md->input, KEY_POWER, 0);
+ input_sync(md->input);
+ cd->large_power_state = 1;
+ }
+ }
}
if (num_cur_tch == 0 && md->num_prv_rec == 0)
@@ -359,7 +373,7 @@
u8 key_value = 0;
- dev_err(cd->dev, "%s report_id:%X\n", __func__, cd->input_buf[2]);
+ dev_dbg(cd->dev, "%s report_id:%X\n", __func__, cd->input_buf[2]);
switch (cd->input_buf[3]) {
case GESTURE_DOUBLE_TAP:
diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h
index 933daae..4fb6ae3 100644
--- a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h
+++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h
@@ -67,6 +67,7 @@
/* #define EASYWAKE_TSG6 */
+#define CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_BINARY_FW_UPGRADE
#define CY_FW_FILE_PREFIX "cyttsp5_fw"
#define CY_FW_FILE_SUFFIX ".bin"
@@ -1025,6 +1026,7 @@
u8 debug_level;
u32 watchdog_interval;
u8 show_timestamp;
+ int forbit_bigobject;
};
struct gd_sensor {