From 5d6f2e55cea31158a3ec79dc569722b0b44049ac Mon Sep 17 00:00:00 2001 From: Venkateswara Rao Mandela Date: Mon, 8 May 2017 15:41:03 +0530 Subject: dra71x: lcard: Touch screen functional Enable goodix touchscreen with polling mode. Change-Id: I0a23d2cb3a185e3c2d2ff142eb37be738c10c557 Signed-off-by: Venkateswara Rao Mandela Signed-off-by: Vishal Mahaveer --- drivers/input/touchscreen/Kconfig | 1 + drivers/input/touchscreen/goodix.c | 97 +++++++++++++++++++++++++++++++++----- 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 #include #include +#include #include #include #include @@ -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; -- cgit v1.2.3-54-g00ecf