summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiGang <b41990@freescale.com>2012-09-14 13:31:24 +0800
committerLiGang <b41990@freescale.com>2012-09-14 13:31:24 +0800
commit0ccf1609f3d00d1f3d093a621969379e2fc46346 (patch)
treeae01636d9793c3f1ce497669e1e34ad6ce593cec
parent559073d213f793985151bec2b65c54b2613e489e (diff)
ENGR00224171 evk : Touch screen has no response after resumeimx-android-r13.5-beta
System is triggered by falling edge of touch interrupt pin, and the touch can't power off during suspend, so if touch the screen during suspend, the touch interrupt pin will changed to low status, but system can't response the falling edge interrupt for it's in suspend, then the touch interrupt pin will stay low status. After resume, the system will not accept any falling edge interrpt from touch, that leads the touch no response after resume. The solution here is: in later resume, read the touch data if the interrupt pin of touch is low status, then the interrupt pin of touch will return to high after reading the touch data. Signed-off-by: LiGang <b41990@freescale.com>
-rw-r--r--drivers/input/touchscreen/elan_ts.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/elan_ts.c b/drivers/input/touchscreen/elan_ts.c
index 7edd87d6cd1b..fd85c1b33b7c 100644
--- a/drivers/input/touchscreen/elan_ts.c
+++ b/drivers/input/touchscreen/elan_ts.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007-2008 HTC Corporation.
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
*
* This driver is adapted from elan8232_i2c.c written by Shan-Fu Chiou
* <sfchiou@gmail.com> and Jay Tu <jay_tu@htc.com>.
@@ -28,6 +29,8 @@
#include <linux/hrtimer.h>
#include <linux/gpio.h>
+#include <linux/earlysuspend.h>
+
static const char ELAN_TS_NAME[] = "elan-touch";
#define ELAN_TS_X_MAX 1088
@@ -55,6 +58,9 @@ static struct elan_data {
struct i2c_client *client;
struct input_dev *input;
wait_queue_head_t wait;
+#ifdef CONFIG_EARLYSUSPEND
+ struct early_suspend es_handler;
+#endif
} elan_touch_data;
/*--------------------------------------------------------------*/
@@ -267,6 +273,12 @@ static int elan_touch_register_interrupt(struct i2c_client *client)
return 0;
}
+#ifdef CONFIG_EARLYSUSPEND
+static void elan_early_suspend(struct early_suspend *h);
+static void elan_later_resume(struct early_suspend *h);
+#endif
+
+
static int elan_touch_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -328,6 +340,15 @@ static int elan_touch_probe(struct i2c_client *client,
goto fail;
}
+#ifdef CONFIG_EARLYSUSPEND
+ /* register this client's earlysuspend */
+ elan_touch_data.es_handler.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
+ elan_touch_data.es_handler.suspend = elan_early_suspend;
+ elan_touch_data.es_handler.resume = elan_later_resume;
+ elan_touch_data.es_handler.data = (void *)client;
+ register_early_suspend(&elan_touch_data.es_handler);
+#endif
+
elan_touch_register_interrupt(elan_touch_data.client);
return 0;
@@ -341,6 +362,10 @@ fail:
static int elan_touch_remove(struct i2c_client *client)
{
+#ifdef CONFIG_EARLYSUSPEND
+ unregister_early_suspend(&elan_touch_data.es_handler);
+#endif
+
if (elan_wq)
destroy_workqueue(elan_wq);
@@ -353,6 +378,28 @@ static int elan_touch_remove(struct i2c_client *client)
return 0;
}
+#ifdef CONFIG_EARLYSUSPEND
+static void elan_early_suspend(struct early_suspend *h)
+{
+}
+
+static void elan_later_resume(struct early_suspend *h)
+{
+ if (0 == elan_touch_detect_int_level()) {
+ pr_debug("elan_ts: got touch in suspend period\n");
+ if (h->data) {
+ /*if touch screen during suspend, recv and drop the
+ data, then touch interrupt pin will return high after
+ receving data.
+ */
+ uint8_t buf_recv[IDX_PACKET_SIZE];
+ elan_touch_recv_data((struct i2c_client *)(h->data),
+ buf_recv);
+ }
+ }
+}
+#endif
+
/* -------------------------------------------------------------------- */
static const struct i2c_device_id elan_touch_id[] = {
{"elan-touch", 0},