aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkateswara Rao Mandela <venkat.mandela@ti.com>2017-05-08 15:41:03 +0530
committerVishal Mahaveer <vishalm@ti.com>2017-05-08 11:51:15 -0400
commit5d6f2e55cea31158a3ec79dc569722b0b44049ac (patch)
treef403b05223af0dd95da105fed8f6d04b1ef44e0c
parentd99e36011a802b83f5dec004d4b718dbe40148d0 (diff)
downloadjacinto6evm-6AM.1.3-lcard.tar.gz
dra71x: lcard: Touch screen functional6AM.1.3-lcard
Enable goodix touchscreen with polling mode. Change-Id: I0a23d2cb3a185e3c2d2ff142eb37be738c10c557 Signed-off-by: Venkateswara Rao Mandela <venkat.mandela@ti.com> Signed-off-by: Vishal Mahaveer <vishalm@ti.com>
-rw-r--r--drivers/input/touchscreen/Kconfig1
-rw-r--r--drivers/input/touchscreen/goodix.c97
2 files changed, 86 insertions, 12 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 8364d84fd696..97f1eacdda0e 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -325,6 +325,7 @@ config TOUCHSCREEN_GOODIX
tristate "Goodix I2C touchscreen"
depends on I2C
depends on GPIOLIB
+ select INPUT_POLLDEV
help
Say Y here if you have the Goodix touchscreen (such as one
installed in Onda v975w tablets) connected to your
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index a27f0d7107af..f553bea645d7 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
+#include <linux/input-polldev.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/irq.h>
@@ -34,6 +35,7 @@
struct goodix_ts_data {
struct i2c_client *client;
struct input_dev *input_dev;
+ struct input_polled_dev *poll_dev;
int abs_x_max;
int abs_y_max;
bool swapped_x_y;
@@ -77,6 +79,8 @@ struct goodix_ts_data {
#define MAX_CONTACTS_LOC 5
#define TRIGGER_LOC 6
+#define TSC_DEFAULT_POLL_PERIOD 30 /* ms */
+
static const unsigned long goodix_irq_flags[] = {
IRQ_TYPE_EDGE_RISING,
IRQ_TYPE_EDGE_FALLING,
@@ -281,6 +285,19 @@ static void goodix_process_events(struct goodix_ts_data *ts)
input_sync(ts->input_dev);
}
+static void _goodix_process_events(struct goodix_ts_data *ts)
+{
+ goodix_process_events(ts);
+
+ if (goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0) < 0)
+ dev_err(&ts->client->dev, "I2C write end_cmd error\n");
+
+}
+static void goodix_poll(struct input_polled_dev *poll_dev)
+{
+ struct goodix_ts_data *ts = poll_dev->private;
+ _goodix_process_events(ts);
+}
/**
* goodix_ts_irq_handler - The IRQ handler
*
@@ -291,10 +308,7 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
{
struct goodix_ts_data *ts = dev_id;
- goodix_process_events(ts);
-
- if (goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0) < 0)
- dev_err(&ts->client->dev, "I2C write end_cmd error\n");
+ _goodix_process_events(ts);
return IRQ_HANDLED;
}
@@ -614,6 +628,58 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts)
return 0;
}
+static int goodix_request_input_polled_dev(struct goodix_ts_data *ts)
+{
+ int error;
+ struct input_polled_dev *poll_dev;
+
+ dev_err(&ts->client->dev, "Setting up polling.\n");
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev) {
+ dev_err(&ts->client->dev, "Failed to allocate polled input device.\n");
+ error = -ENOMEM;
+ return error;
+ }
+
+ ts->poll_dev = poll_dev;
+
+ poll_dev->private = ts;
+ poll_dev->poll = goodix_poll;
+ poll_dev->poll_interval = TSC_DEFAULT_POLL_PERIOD;
+
+ ts->input_dev = poll_dev->input;
+ if (!ts->input_dev) {
+ dev_err(&ts->client->dev, "Failed to allocate input device.");
+ return -ENOMEM;
+ }
+
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
+ 0, ts->abs_x_max, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
+ 0, ts->abs_y_max, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+
+ input_mt_init_slots(ts->input_dev, ts->max_touch_num,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+
+ ts->input_dev->name = "Goodix Capacitive TouchScreen";
+ ts->input_dev->phys = "input/ts";
+ ts->input_dev->id.bustype = BUS_I2C;
+ ts->input_dev->id.vendor = 0x0416;
+ ts->input_dev->id.product = ts->id;
+ ts->input_dev->id.version = ts->version;
+
+ error = input_register_polled_device(poll_dev);
+ if (error) {
+ dev_err(&ts->client->dev,
+ "Failed to register input device: %d", error);
+ return error;
+ }
+
+ return 0;
+}
+
/**
* goodix_configure_dev - Finish device initialization
*
@@ -637,15 +703,22 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
goodix_read_config(ts);
- error = goodix_request_input_dev(ts);
- if (error)
- return error;
- ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
- error = goodix_request_irq(ts);
- if (error) {
- dev_err(&ts->client->dev, "request IRQ failed: %d\n", error);
- return error;
+ if (ts->client->irq) {
+ error = goodix_request_input_dev(ts);
+ if (error)
+ return error;
+ ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
+ error = goodix_request_irq(ts);
+ if (error) {
+ dev_err(&ts->client->dev, "request IRQ failed: %d\n", error);
+ return error;
+ }
+ } else {
+ /* setup polling if IRQ is not defined */
+
+ error = goodix_request_input_polled_dev(ts);
+
}
return 0;