From 56b5fe87c2ce9969084c2d0096f3a0c624e2ccd6 Mon Sep 17 00:00:00 2001 From: "makarand.karvekar" Date: Tue, 2 Nov 2010 11:18:19 -0500 Subject: [PATCH] qtouch: suspend/resume touch uC via wake-line wake-line gpio high puts touch uC in low-power mode. fixed inconsistent irq disable in suspend when irq_enable is skipped due to i2c failure. Change-Id: I6a9fe011abdffad599da0b2897f3a976db10fff5 Signed-off-by: makarand.karvekar --- drivers/input/touchscreen/qtouch_obp_ts.c | 19 +++++++++++++++---- include/linux/qtouch_obp_ts.h | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/qtouch_obp_ts.c b/drivers/input/touchscreen/qtouch_obp_ts.c index 7f110095b8a0..82279bc47f65 100644 --- a/drivers/input/touchscreen/qtouch_obp_ts.c +++ b/drivers/input/touchscreen/qtouch_obp_ts.c @@ -89,6 +89,7 @@ struct qtouch_ts_data { atomic_t irq_enabled; atomic_t process_open; + int enable_irq_flag; int status; uint8_t mode; @@ -1636,6 +1637,7 @@ static int qtouch_ts_probe(struct i2c_client *client, ts->y_delta = ts->pdata->y_delta; atomic_set(&ts->irq_enabled, 1); atomic_set(&ts->process_open, 1); + ts->enable_irq_flag = 1; ts->status = 0xfe; ts->touch_fw_size = 0; ts->touch_fw_image = NULL; @@ -1875,7 +1877,8 @@ static int qtouch_ts_suspend(struct i2c_client *client, pm_message_t mesg) if (ts->mode == 1) return -EBUSY; - disable_irq_nosync(ts->client->irq); + if (ts->enable_irq_flag) + disable_irq_nosync(ts->client->irq); ret = cancel_work_sync(&ts->work); if (ret) { /* if work was pending disable-count is now 2 */ pr_info("%s: Pending work item\n", __func__); @@ -1886,6 +1889,9 @@ static int qtouch_ts_suspend(struct i2c_client *client, pm_message_t mesg) if (ret < 0) pr_err("%s: Cannot write power config\n", __func__); + if (ts->pdata->hw_suspend) + ts->pdata->hw_suspend(1); + return 0; } @@ -1905,6 +1911,9 @@ static int qtouch_ts_resume(struct i2c_client *client) if (ts->mode == 1) return -EBUSY; + if (ts->pdata->hw_suspend) + ts->pdata->hw_suspend(0); + /* If we were suspended while a touch was happening we need to tell the upper layers so they do not hang waiting on the liftoff that will not come. */ @@ -1924,20 +1933,22 @@ static int qtouch_ts_resume(struct i2c_client *client) ret = qtouch_power_config(ts, 1); if (ret < 0) { pr_err("%s: Cannot write power config\n", __func__); + ts->enable_irq_flag = 0; return -EIO; } - /* HACK: temporary fix for IC wake issue - qtouch_force_reset(ts, 0); */ + /* Point the address pointer to the message processor. * Must do this before enabling interrupts */ obj = find_obj(ts, QTM_OBJ_GEN_MSG_PROC); ret = qtouch_set_addr(ts, obj->entry.addr); if (ret != 0) { pr_err("%s: Can't to set addr to msg processor\n", __func__); + ts->enable_irq_flag = 0; + return -EIO; } - /* end of HACK */ enable_irq(ts->client->irq); + ts->enable_irq_flag = 1; return 0; } diff --git a/include/linux/qtouch_obp_ts.h b/include/linux/qtouch_obp_ts.h index 7d79c3554495..022176259a89 100644 --- a/include/linux/qtouch_obp_ts.h +++ b/include/linux/qtouch_obp_ts.h @@ -511,6 +511,7 @@ struct qtouch_ts_platform_data { uint8_t boot_i2c_addr; int (*hw_reset)(void); + int (*hw_suspend)(int); /* TODO: allow multiple key arrays */ struct qtouch_key_array key_array; -- 2.34.1