summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-09-05 20:36:38 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:35:34 -0800
commit6766a82cac62b7b6ccffd91c9c1df74f10432e41 (patch)
treeaeda6b3e3af733796627e9ccd9695129b673cd4f /drivers/input/touchscreen
parent4b2c1f73b7f34dc7d383121310ad6b2efd006a97 (diff)
input: touchscreen: panjit_i2c: fix suspend
the panjit touchscreen needs to be reset when returning from deep sleep mode; add a platform data structure to specify the reset GPIO. perform the reset during _probe, since the code already needs to exist for _resume delete a bunch of unused preprocessor defines Change-Id: I71ae65dec45710b0eab4625036edf75064d4cc2b Signed-off-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/panjit_i2c.c99
1 files changed, 61 insertions, 38 deletions
diff --git a/drivers/input/touchscreen/panjit_i2c.c b/drivers/input/touchscreen/panjit_i2c.c
index f636315f263b..6d82cec45ed9 100644
--- a/drivers/input/touchscreen/panjit_i2c.c
+++ b/drivers/input/touchscreen/panjit_i2c.c
@@ -25,39 +25,23 @@
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/i2c.h>
+#include <linux/i2c/panjit_ts.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/slab.h>
-/* touch controller registers */
-#define CSR 0x00 /* Control and Status register */
-#define C_FLAG 0x01 /* Interrupt Clear flag */
-#define X1_H 0x03 /* High Byte of X1 Position */
-#define X1_L 0x04 /* Low Byte of X1 Position */
-#define Y1_H 0x05 /* High Byte of Y1 Position */
-#define Y1_L 0x06 /* Low Byte of Y1 Position */
-#define X2_H 0x07 /* High Byte of X2 Position */
-#define X2_L 0x08 /* Low Byte of X2 Position */
-#define Y2_H 0x09 /* High Byte of Y2 Position */
-#define Y2_L 0x0A /* Low Byte of Y2 Position */
-#define FINGERS 0x0B /* Detected finger number */
-#define GESTURE 0x0C /* Interpreted gesture */
-
-/* Control Status Register bit masks */
-#define CSR_SLEEP_EN (1 << 7)
-#define CSR_SCAN_EN (1 << 3)
-#define SLEEP_ENABLE 1
-
-/* Interrupt Clear register bit masks */
-#define C_FLAG_CLEAR 0x08
-#define INT_ASSERTED (1 << C_FLAG_CLEAR)
-
-#define DRIVER_NAME "panjit_touch"
+#define CSR 0x00
+ #define CSR_SCAN_EN (1 << 3)
+ #define CSR_SLEEP_EN (1 << 7)
+#define C_FLAG 0x01
+#define X1_H 0x03
+
+#define DRIVER_NAME "panjit_touch"
struct pj_data {
struct input_dev *input_dev;
struct i2c_client *client;
- int chipid;
+ int gpio_reset;
};
struct pj_event {
@@ -74,6 +58,17 @@ union pj_buff {
unsigned char buff[sizeof(struct pj_data)];
};
+static void pj_reset(struct pj_data *touch)
+{
+ if (touch->gpio_reset < 0)
+ return;
+
+ gpio_set_value(touch->gpio_reset, 1);
+ msleep(50);
+ gpio_set_value(touch->gpio_reset, 0);
+ msleep(50);
+}
+
static irqreturn_t pj_irq(int irq, void *dev_id)
{
struct pj_data *touch = dev_id;
@@ -87,12 +82,12 @@ static irqreturn_t pj_irq(int irq, void *dev_id)
sizeof(event.buff), event.buff);
if (WARN_ON(ret < 0)) {
dev_err(&client->dev, "error %d reading event data\n", ret);
- return IRQ_HANDLED;
+ return IRQ_NONE;
}
ret = i2c_smbus_write_byte_data(client, C_FLAG, 0);
if (WARN_ON(ret < 0)) {
dev_err(&client->dev, "error %d clearing interrupt\n", ret);
- return IRQ_HANDLED;
+ return IRQ_NONE;
}
input_report_key(touch->input_dev, BTN_TOUCH,
@@ -128,6 +123,7 @@ out:
static int pj_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct panjit_i2c_ts_platform_data *pdata = client->dev.platform_data;
struct pj_data *touch = NULL;
struct input_dev *input_dev = NULL;
int ret = 0;
@@ -138,6 +134,22 @@ static int pj_probe(struct i2c_client *client,
return -ENOMEM;
}
+ touch->gpio_reset = -EINVAL;
+
+ if (pdata) {
+ ret = gpio_request(pdata->gpio_reset, "panjit_reset");
+ if (!ret) {
+ ret = gpio_direction_output(pdata->gpio_reset, 1);
+ if (ret < 0)
+ gpio_free(pdata->gpio_reset);
+ }
+
+ if (!ret)
+ touch->gpio_reset = pdata->gpio_reset;
+ else
+ dev_warn(&client->dev, "unable to configure GPIO\n");
+ }
+
input_dev = input_allocate_device();
if (!input_dev) {
dev_err(&client->dev, "%s: no memory\n", __func__);
@@ -148,6 +160,8 @@ static int pj_probe(struct i2c_client *client,
touch->client = client;
i2c_set_clientdata(client, touch);
+ pj_reset(touch);
+
/* clear interrupt */
ret = i2c_smbus_write_byte_data(touch->client, C_FLAG, 0);
if (ret < 0) {
@@ -199,7 +213,8 @@ static int pj_probe(struct i2c_client *client,
/* get the irq */
ret = request_threaded_irq(touch->client->irq, NULL, pj_irq,
- IRQF_ONESHOT, DRIVER_NAME, touch);
+ IRQF_ONESHOT | IRQF_TRIGGER_LOW,
+ DRIVER_NAME, touch);
if (ret) {
dev_err(&client->dev, "%s: request_irq(%d) failed\n",
__func__, touch->client->irq);
@@ -213,6 +228,9 @@ fail_irq:
input_unregister_device(touch->input_dev);
fail_i2c_or_register:
+ if (touch->gpio_reset >= 0)
+ gpio_free(touch->gpio_reset);
+
input_free_device(input_dev);
kfree(touch);
return ret;
@@ -223,12 +241,10 @@ static int pj_suspend(struct i2c_client *client, pm_message_t state)
struct pj_data *touch = i2c_get_clientdata(client);
int ret;
- if (!touch) {
- WARN_ON(1);
+ if (WARN_ON(!touch))
return -EINVAL;
- }
- disable_irq(touch->client->irq);
+ disable_irq(client->irq);
/* disable scanning and enable deep sleep */
ret = i2c_smbus_write_byte_data(client, CSR, CSR_SLEEP_EN);
@@ -236,6 +252,7 @@ static int pj_suspend(struct i2c_client *client, pm_message_t state)
dev_err(&client->dev, "%s: sleep enable fail\n", __func__);
return ret;
}
+
return 0;
}
@@ -244,18 +261,22 @@ static int pj_resume(struct i2c_client *client)
struct pj_data *touch = i2c_get_clientdata(client);
int ret = 0;
- if (!touch) {
- WARN_ON(1);
+ if (WARN_ON(!touch))
return -EINVAL;
- }
+
+ pj_reset(touch);
+
/* enable scanning and disable deep sleep */
- ret = i2c_smbus_write_byte_data(client, CSR, CSR_SCAN_EN);
+ ret = i2c_smbus_write_byte_data(client, C_FLAG, 0);
+ if (ret >= 0)
+ ret = i2c_smbus_write_byte_data(client, CSR, CSR_SCAN_EN);
if (ret < 0) {
- dev_err(&client->dev, "%s: interrupt enable fail\n", __func__);
+ dev_err(&client->dev, "%s: scan enable fail\n", __func__);
return ret;
}
- enable_irq(touch->client->irq);
+ enable_irq(client->irq);
+
return 0;
}
@@ -267,6 +288,8 @@ static int pj_remove(struct i2c_client *client)
return -EINVAL;
free_irq(touch->client->irq, touch);
+ if (touch->gpio_reset >= 0)
+ gpio_free(touch->gpio_reset);
input_unregister_device(touch->input_dev);
input_free_device(touch->input_dev);
kfree(touch);