mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
projects/imx6/patches/linux: remove enhanced driver for st1232 touchscreen
because now everything is handled in userspace by touchscreen access library (tslib)
This commit is contained in:
parent
b85b9ea1c3
commit
65398da267
@ -1,640 +0,0 @@
|
||||
From 8a7ac9c15a3e6e25f8a3238c26a2584d84c6b38f Mon Sep 17 00:00:00 2001
|
||||
From: vpeter4 <peter.vicman@gmail.com>
|
||||
Date: Wed, 3 Jun 2015 18:15:31 +0200
|
||||
Subject: [PATCH] update driver for st1232 touchscreen controller
|
||||
|
||||
Original driver is multitouch only and Kodi doesnt understand
|
||||
this input events. Driver was modified to start as singletouch
|
||||
and also supports touch button in this mode.
|
||||
|
||||
---
|
||||
drivers/input/touchscreen/st1232.c | 554 ++++++++++++++++++++++---------------
|
||||
1 file changed, 331 insertions(+), 223 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
|
||||
index 5c342b3..e1254a1 100644
|
||||
--- a/drivers/input/touchscreen/st1232.c
|
||||
+++ b/drivers/input/touchscreen/st1232.c
|
||||
@@ -1,12 +1,13 @@
|
||||
/*
|
||||
- * ST1232 Touchscreen Controller Driver
|
||||
+ * ST1232/ST1332 Touchscreen Controller Driver
|
||||
*
|
||||
* Copyright (C) 2010 Renesas Solutions Corp.
|
||||
- * Tony SIM <chinyeow.sim.xt@renesas.com>
|
||||
+ * Tony SIM <chinyeow.sim.xt@renesas.com>
|
||||
+ * Copyright (C) 2015 Peter Vicman <peter.vicman@gmail.com>
|
||||
*
|
||||
* Using code from:
|
||||
* - android.git.kernel.org: projects/kernel/common.git: synaptics_i2c_rmi.c
|
||||
- * Copyright (C) 2007 Google, Inc.
|
||||
+ * Copyright (C) 2007 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
@@ -30,282 +31,383 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_data/st1232_pdata.h>
|
||||
-
|
||||
-#define ST1232_TS_NAME "st1232-ts"
|
||||
-
|
||||
-#define MIN_X 0x00
|
||||
-#define MIN_Y 0x00
|
||||
-#define MAX_X 0x31f /* (800 - 1) */
|
||||
-#define MAX_Y 0x1df /* (480 - 1) */
|
||||
-#define MAX_AREA 0xff
|
||||
-#define MAX_FINGERS 2
|
||||
+#include <linux/workqueue.h>
|
||||
+
|
||||
+#define ST1232_TS_NAME "st1232-ts"
|
||||
+#define MIN_X 0
|
||||
+#define MIN_Y 0
|
||||
+#define MAX_X (800 - 1)
|
||||
+#define MAX_Y (480 - 1)
|
||||
+#define MAX_AREA 0xff
|
||||
+#define MAX_FINGERS 2
|
||||
+#define SAMPLE_DELAY 20 /* msecs */
|
||||
+#define REVERSE_X(x) if (reverse_x == true) { x = MAX_X - (x); } else {}
|
||||
+#define REVERSE_Y(y) if (reverse_y == true) { y = MAX_Y - (y); } else {}
|
||||
|
||||
struct st1232_ts_finger {
|
||||
- u16 x;
|
||||
- u16 y;
|
||||
- u8 t;
|
||||
- bool is_valid;
|
||||
+ u16 x;
|
||||
+ u16 y;
|
||||
+ u8 t;
|
||||
+ bool is_valid;
|
||||
};
|
||||
|
||||
struct st1232_ts_data {
|
||||
- struct i2c_client *client;
|
||||
- struct input_dev *input_dev;
|
||||
- struct st1232_ts_finger finger[MAX_FINGERS];
|
||||
- struct dev_pm_qos_request low_latency_req;
|
||||
- int reset_gpio;
|
||||
+ struct i2c_client *client;
|
||||
+ struct input_dev *input_dev;
|
||||
+ struct st1232_ts_finger finger[MAX_FINGERS];
|
||||
+ struct dev_pm_qos_request low_latency_req;
|
||||
+ int reset_gpio;
|
||||
+ struct delayed_work work;
|
||||
};
|
||||
|
||||
+static bool multitouch = false;
|
||||
+module_param(multitouch, bool, 0);
|
||||
+MODULE_PARM_DESC(multitouch, " If multitouch is set to 1 ts acts as multitouch");
|
||||
+
|
||||
+static bool reverse_x = false;
|
||||
+module_param(reverse_x, bool, 0600);
|
||||
+MODULE_PARM_DESC(reverse_x, " If reverse_x is set to 1 x coordinates are reversed");
|
||||
+
|
||||
+static bool reverse_y = false;
|
||||
+module_param(reverse_y, bool, 0600);
|
||||
+MODULE_PARM_DESC(reverse_y, " If reverse_y is set to 1 y coordinates are reversed");
|
||||
+
|
||||
+static int offset_x = 0;
|
||||
+module_param(offset_x, int, 0600);
|
||||
+MODULE_PARM_DESC(offset_x, " Offset value for x axis");
|
||||
+
|
||||
+static int offset_y = 0;
|
||||
+module_param(offset_y, int, 0600);
|
||||
+MODULE_PARM_DESC(offset_y, " Offset value for y axis");
|
||||
+
|
||||
static int st1232_ts_read_data(struct st1232_ts_data *ts)
|
||||
{
|
||||
- struct st1232_ts_finger *finger = ts->finger;
|
||||
- struct i2c_client *client = ts->client;
|
||||
- struct i2c_msg msg[2];
|
||||
- int error;
|
||||
- u8 start_reg;
|
||||
- u8 buf[10];
|
||||
-
|
||||
- /* read touchscreen data from ST1232 */
|
||||
- msg[0].addr = client->addr;
|
||||
- msg[0].flags = 0;
|
||||
- msg[0].len = 1;
|
||||
- msg[0].buf = &start_reg;
|
||||
- start_reg = 0x10;
|
||||
-
|
||||
- msg[1].addr = ts->client->addr;
|
||||
- msg[1].flags = I2C_M_RD;
|
||||
- msg[1].len = sizeof(buf);
|
||||
- msg[1].buf = buf;
|
||||
-
|
||||
- error = i2c_transfer(client->adapter, msg, 2);
|
||||
- if (error < 0)
|
||||
- return error;
|
||||
-
|
||||
- /* get "valid" bits */
|
||||
- finger[0].is_valid = buf[2] >> 7;
|
||||
- finger[1].is_valid = buf[5] >> 7;
|
||||
-
|
||||
- /* get xy coordinate */
|
||||
- if (finger[0].is_valid) {
|
||||
- finger[0].x = ((buf[2] & 0x0070) << 4) | buf[3];
|
||||
- finger[0].y = ((buf[2] & 0x0007) << 8) | buf[4];
|
||||
- finger[0].t = buf[8];
|
||||
- }
|
||||
-
|
||||
- if (finger[1].is_valid) {
|
||||
- finger[1].x = ((buf[5] & 0x0070) << 4) | buf[6];
|
||||
- finger[1].y = ((buf[5] & 0x0007) << 8) | buf[7];
|
||||
- finger[1].t = buf[9];
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ struct st1232_ts_finger *finger = ts->finger;
|
||||
+ struct i2c_client *client = ts->client;
|
||||
+ struct i2c_msg msg[2];
|
||||
+ int error;
|
||||
+ u8 start_reg;
|
||||
+ u8 buf[10];
|
||||
+
|
||||
+ /* read touchscreen data from ST1232 */
|
||||
+ msg[0].addr = client->addr;
|
||||
+ msg[0].flags = 0;
|
||||
+ msg[0].len = 1;
|
||||
+ msg[0].buf = &start_reg;
|
||||
+ start_reg = 0x10;
|
||||
+
|
||||
+ msg[1].addr = ts->client->addr;
|
||||
+ msg[1].flags = I2C_M_RD;
|
||||
+ msg[1].len = sizeof(buf);
|
||||
+ msg[1].buf = buf;
|
||||
+
|
||||
+ error = i2c_transfer(client->adapter, msg, 2);
|
||||
+ if (error < 0)
|
||||
+ return error;
|
||||
+
|
||||
+ memset(finger, 0x0, sizeof(struct st1232_ts_finger) * MAX_FINGERS);
|
||||
+
|
||||
+ /* get "valid" bits from fingers
|
||||
+ and combine with "valid" bits from coordinates */
|
||||
+ finger[0].is_valid = (buf[0] & 0x07); /* only 3 bits on st1332 */
|
||||
+ finger[0].is_valid &= (buf[2] >> 7);
|
||||
+ finger[1].is_valid = (buf[0] & 0x07);
|
||||
+ finger[1].is_valid &= (buf[5] >> 7);
|
||||
+
|
||||
+ /* get xy coordinates and strength */
|
||||
+ if (finger[0].is_valid) {
|
||||
+ finger[0].x = ((buf[2] & 0x0070) << 4) | buf[3];
|
||||
+ finger[0].y = ((buf[2] & 0x0007) << 8) | buf[4];
|
||||
+ finger[0].t = buf[8];
|
||||
+
|
||||
+ REVERSE_X(finger[0].x)
|
||||
+ REVERSE_Y(finger[0].y)
|
||||
+
|
||||
+ finger[0].x += offset_x;
|
||||
+ finger[0].y += offset_y;
|
||||
+ }
|
||||
+
|
||||
+ if (finger[1].is_valid) {
|
||||
+ finger[1].x = ((buf[5] & 0x0070) << 4) | buf[6];
|
||||
+ finger[1].y = ((buf[5] & 0x0007) << 8) | buf[7];
|
||||
+ finger[1].t = buf[9];
|
||||
+
|
||||
+ REVERSE_X(finger[1].x)
|
||||
+ REVERSE_Y(finger[1].y)
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void st1232_ts_finger_released(struct work_struct *work)
|
||||
+{
|
||||
+ struct st1232_ts_data *ts = container_of(work, struct st1232_ts_data, work.work);
|
||||
+ struct st1232_ts_finger *finger = ts->finger;
|
||||
+ struct input_dev *input_dev = ts->input_dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = st1232_ts_read_data(ts);
|
||||
+ if (ret < 0)
|
||||
+ goto end;
|
||||
+
|
||||
+ /* finger is a pointer to finger[0] */
|
||||
+ if (finger->is_valid)
|
||||
+ goto end; /* finger (still) touched */
|
||||
+
|
||||
+ /* finger released */
|
||||
+ input_report_abs(input_dev, ABS_PRESSURE, 0);
|
||||
+ input_report_key(input_dev, BTN_TOUCH, 0);
|
||||
+ input_sync(input_dev);
|
||||
+
|
||||
+end:
|
||||
+ return;
|
||||
}
|
||||
|
||||
static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
- struct st1232_ts_data *ts = dev_id;
|
||||
- struct st1232_ts_finger *finger = ts->finger;
|
||||
- struct input_dev *input_dev = ts->input_dev;
|
||||
- int count = 0;
|
||||
- int i, ret;
|
||||
-
|
||||
- ret = st1232_ts_read_data(ts);
|
||||
- if (ret < 0)
|
||||
- goto end;
|
||||
-
|
||||
- /* multi touch protocol */
|
||||
- for (i = 0; i < MAX_FINGERS; i++) {
|
||||
- if (!finger[i].is_valid)
|
||||
- continue;
|
||||
-
|
||||
- input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t);
|
||||
- input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x);
|
||||
- input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y);
|
||||
- input_mt_sync(input_dev);
|
||||
- count++;
|
||||
- }
|
||||
-
|
||||
- /* SYN_MT_REPORT only if no contact */
|
||||
- if (!count) {
|
||||
- input_mt_sync(input_dev);
|
||||
- if (ts->low_latency_req.dev) {
|
||||
- dev_pm_qos_remove_request(&ts->low_latency_req);
|
||||
- ts->low_latency_req.dev = NULL;
|
||||
- }
|
||||
- } else if (!ts->low_latency_req.dev) {
|
||||
- /* First contact, request 100 us latency. */
|
||||
- dev_pm_qos_add_ancestor_request(&ts->client->dev,
|
||||
- &ts->low_latency_req, 100);
|
||||
- }
|
||||
-
|
||||
- /* SYN_REPORT */
|
||||
- input_sync(input_dev);
|
||||
+ struct st1232_ts_data *ts = dev_id;
|
||||
+ struct st1232_ts_finger *finger = ts->finger;
|
||||
+ struct input_dev *input_dev = ts->input_dev;
|
||||
+ int count = 0;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ if (multitouch == false) {
|
||||
+ /*
|
||||
+ * Cancel scheduled polling for release if we have new value
|
||||
+ * available. Wait if the polling is already running.
|
||||
+ */
|
||||
+ cancel_delayed_work_sync(&ts->work);
|
||||
+ }
|
||||
+
|
||||
+ ret = st1232_ts_read_data(ts);
|
||||
+ if (ret < 0)
|
||||
+ goto end;
|
||||
+
|
||||
+ if (multitouch == false) {
|
||||
+ if (finger->is_valid) {
|
||||
+ input_report_abs(input_dev, ABS_X, finger->x);
|
||||
+ input_report_abs(input_dev, ABS_Y, finger->y);
|
||||
+ input_report_abs(input_dev, ABS_PRESSURE, finger->t);
|
||||
+ input_report_key(input_dev, BTN_TOUCH, 1);
|
||||
+ input_sync(input_dev);
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* multi touch protocol */
|
||||
+ for (i = 0; i < MAX_FINGERS; i++) {
|
||||
+ if (!finger[i].is_valid)
|
||||
+ continue;
|
||||
+
|
||||
+ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t);
|
||||
+ input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x);
|
||||
+ input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y);
|
||||
+ input_mt_sync(input_dev);
|
||||
+ count++;
|
||||
+ }
|
||||
+
|
||||
+ /* SYN_MT_REPORT only if no contact */
|
||||
+ if (!count) {
|
||||
+ input_mt_sync(input_dev);
|
||||
+ if (ts->low_latency_req.dev) {
|
||||
+ dev_pm_qos_remove_request(&ts->low_latency_req);
|
||||
+ ts->low_latency_req.dev = NULL;
|
||||
+ }
|
||||
+ } else if (!ts->low_latency_req.dev) {
|
||||
+ /* First contact, request 100 us latency. */
|
||||
+ dev_pm_qos_add_ancestor_request(&ts->client->dev, &ts->low_latency_req, 100);
|
||||
+ }
|
||||
+
|
||||
+ /* SYN_REPORT */
|
||||
+ input_sync(input_dev);
|
||||
+ }
|
||||
|
||||
end:
|
||||
- return IRQ_HANDLED;
|
||||
+ if (multitouch == false) {
|
||||
+ /* start polling for st1232_ts_read_data to detect release */
|
||||
+ schedule_delayed_work(&ts->work, msecs_to_jiffies(SAMPLE_DELAY));
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void st1232_ts_power(struct st1232_ts_data *ts, bool poweron)
|
||||
{
|
||||
- if (gpio_is_valid(ts->reset_gpio))
|
||||
- gpio_direction_output(ts->reset_gpio, poweron);
|
||||
+ if (gpio_is_valid(ts->reset_gpio))
|
||||
+ gpio_direction_output(ts->reset_gpio, poweron);
|
||||
}
|
||||
|
||||
static int st1232_ts_probe(struct i2c_client *client,
|
||||
- const struct i2c_device_id *id)
|
||||
+ const struct i2c_device_id *id)
|
||||
{
|
||||
- struct st1232_ts_data *ts;
|
||||
- struct st1232_pdata *pdata = dev_get_platdata(&client->dev);
|
||||
- struct input_dev *input_dev;
|
||||
- int error;
|
||||
-
|
||||
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
- dev_err(&client->dev, "need I2C_FUNC_I2C\n");
|
||||
- return -EIO;
|
||||
- }
|
||||
-
|
||||
- if (!client->irq) {
|
||||
- dev_err(&client->dev, "no IRQ?\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
|
||||
- if (!ts)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- input_dev = devm_input_allocate_device(&client->dev);
|
||||
- if (!input_dev)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- ts->client = client;
|
||||
- ts->input_dev = input_dev;
|
||||
-
|
||||
- if (pdata)
|
||||
- ts->reset_gpio = pdata->reset_gpio;
|
||||
- else if (client->dev.of_node)
|
||||
- ts->reset_gpio = of_get_gpio(client->dev.of_node, 0);
|
||||
- else
|
||||
- ts->reset_gpio = -ENODEV;
|
||||
-
|
||||
- if (gpio_is_valid(ts->reset_gpio)) {
|
||||
- error = devm_gpio_request(&client->dev, ts->reset_gpio, NULL);
|
||||
- if (error) {
|
||||
- dev_err(&client->dev,
|
||||
- "Unable to request GPIO pin %d.\n",
|
||||
- ts->reset_gpio);
|
||||
- return error;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- st1232_ts_power(ts, true);
|
||||
-
|
||||
- input_dev->name = "st1232-touchscreen";
|
||||
- input_dev->id.bustype = BUS_I2C;
|
||||
- input_dev->dev.parent = &client->dev;
|
||||
-
|
||||
- __set_bit(EV_SYN, input_dev->evbit);
|
||||
- __set_bit(EV_KEY, input_dev->evbit);
|
||||
- __set_bit(EV_ABS, input_dev->evbit);
|
||||
-
|
||||
- input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0);
|
||||
- input_set_abs_params(input_dev, ABS_MT_POSITION_X, MIN_X, MAX_X, 0, 0);
|
||||
- input_set_abs_params(input_dev, ABS_MT_POSITION_Y, MIN_Y, MAX_Y, 0, 0);
|
||||
-
|
||||
- error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
- NULL, st1232_ts_irq_handler,
|
||||
- IRQF_ONESHOT,
|
||||
- client->name, ts);
|
||||
- if (error) {
|
||||
- dev_err(&client->dev, "Failed to register interrupt\n");
|
||||
- return error;
|
||||
- }
|
||||
-
|
||||
- error = input_register_device(ts->input_dev);
|
||||
- if (error) {
|
||||
- dev_err(&client->dev, "Unable to register %s input device\n",
|
||||
- input_dev->name);
|
||||
- return error;
|
||||
- }
|
||||
-
|
||||
- i2c_set_clientdata(client, ts);
|
||||
- device_init_wakeup(&client->dev, 1);
|
||||
-
|
||||
- return 0;
|
||||
+ struct st1232_ts_data *ts;
|
||||
+ struct st1232_pdata *pdata = dev_get_platdata(&client->dev);
|
||||
+ struct input_dev *input_dev;
|
||||
+ int error;
|
||||
+
|
||||
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
+ dev_err(&client->dev, "need I2C_FUNC_I2C\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ if (!client->irq) {
|
||||
+ dev_err(&client->dev, "no IRQ?\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
|
||||
+ if (!ts)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ input_dev = devm_input_allocate_device(&client->dev);
|
||||
+ if (!input_dev)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ts->client = client;
|
||||
+ ts->input_dev = input_dev;
|
||||
+
|
||||
+ if (pdata)
|
||||
+ ts->reset_gpio = pdata->reset_gpio;
|
||||
+ else if (client->dev.of_node)
|
||||
+ ts->reset_gpio = of_get_gpio(client->dev.of_node, 0);
|
||||
+ else
|
||||
+ ts->reset_gpio = -ENODEV;
|
||||
+
|
||||
+ if (gpio_is_valid(ts->reset_gpio)) {
|
||||
+ error = devm_gpio_request(&client->dev, ts->reset_gpio, NULL);
|
||||
+ if (error) {
|
||||
+ dev_err(&client->dev, "Unable to request GPIO pin %d.\n", ts->reset_gpio);
|
||||
+ return error;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ st1232_ts_power(ts, true);
|
||||
+
|
||||
+ input_dev->name = ST1232_TS_NAME;
|
||||
+ input_dev->id.bustype = BUS_I2C;
|
||||
+ input_dev->dev.parent = &client->dev;
|
||||
+
|
||||
+ if (multitouch == false) {
|
||||
+ input_dev->phys = ST1232_TS_NAME"/input0";
|
||||
+
|
||||
+ __set_bit(BTN_TOUCH, input_dev->keybit);
|
||||
+ __set_bit(EV_KEY, input_dev->evbit);
|
||||
+ __set_bit(EV_ABS, input_dev->evbit);
|
||||
+ __set_bit(ABS_X, input_dev->absbit);
|
||||
+ __set_bit(ABS_Y, input_dev->absbit);
|
||||
+ __set_bit(ABS_PRESSURE, input_dev->absbit);
|
||||
+
|
||||
+ input_set_abs_params(input_dev, ABS_X, MIN_X, MAX_X, 0, 0);
|
||||
+ input_set_abs_params(input_dev, ABS_Y, MIN_Y, MAX_Y, 0, 0);
|
||||
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0x0, 0xff, 0, 0);
|
||||
+
|
||||
+ INIT_DELAYED_WORK(&ts->work, st1232_ts_finger_released);
|
||||
+ } else {
|
||||
+ __set_bit(EV_SYN, input_dev->evbit);
|
||||
+ __set_bit(EV_KEY, input_dev->evbit);
|
||||
+ __set_bit(EV_ABS, input_dev->evbit);
|
||||
+
|
||||
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0);
|
||||
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, MIN_X, MAX_X, 0, 0);
|
||||
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, MIN_Y, MAX_Y, 0, 0);
|
||||
+ }
|
||||
+
|
||||
+ error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
+ NULL, st1232_ts_irq_handler,
|
||||
+ IRQF_ONESHOT,
|
||||
+ client->name, ts);
|
||||
+ if (error) {
|
||||
+ dev_err(&client->dev, "Failed to register interrupt\n");
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ error = input_register_device(ts->input_dev);
|
||||
+ if (error) {
|
||||
+ dev_err(&client->dev, "Unable to register %s input device\n",
|
||||
+ input_dev->name);
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ i2c_set_clientdata(client, ts);
|
||||
+ device_init_wakeup(&client->dev, 1);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int st1232_ts_remove(struct i2c_client *client)
|
||||
{
|
||||
- struct st1232_ts_data *ts = i2c_get_clientdata(client);
|
||||
+ struct st1232_ts_data *ts = i2c_get_clientdata(client);
|
||||
|
||||
- device_init_wakeup(&client->dev, 0);
|
||||
- st1232_ts_power(ts, false);
|
||||
+ device_init_wakeup(&client->dev, 0);
|
||||
+ st1232_ts_power(ts, false);
|
||||
+ cancel_delayed_work_sync(&ts->work);
|
||||
|
||||
- return 0;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int st1232_ts_suspend(struct device *dev)
|
||||
{
|
||||
- struct i2c_client *client = to_i2c_client(dev);
|
||||
- struct st1232_ts_data *ts = i2c_get_clientdata(client);
|
||||
-
|
||||
- if (device_may_wakeup(&client->dev)) {
|
||||
- enable_irq_wake(client->irq);
|
||||
- } else {
|
||||
- disable_irq(client->irq);
|
||||
- st1232_ts_power(ts, false);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ struct i2c_client *client = to_i2c_client(dev);
|
||||
+ struct st1232_ts_data *ts = i2c_get_clientdata(client);
|
||||
+
|
||||
+ if (device_may_wakeup(&client->dev)) {
|
||||
+ enable_irq_wake(client->irq);
|
||||
+ } else {
|
||||
+ disable_irq(client->irq);
|
||||
+ cancel_delayed_work_sync(&ts->work);
|
||||
+ st1232_ts_power(ts, false);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int st1232_ts_resume(struct device *dev)
|
||||
{
|
||||
- struct i2c_client *client = to_i2c_client(dev);
|
||||
- struct st1232_ts_data *ts = i2c_get_clientdata(client);
|
||||
-
|
||||
- if (device_may_wakeup(&client->dev)) {
|
||||
- disable_irq_wake(client->irq);
|
||||
- } else {
|
||||
- st1232_ts_power(ts, true);
|
||||
- enable_irq(client->irq);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ struct i2c_client *client = to_i2c_client(dev);
|
||||
+ struct st1232_ts_data *ts = i2c_get_clientdata(client);
|
||||
+
|
||||
+ if (device_may_wakeup(&client->dev)) {
|
||||
+ disable_irq_wake(client->irq);
|
||||
+ } else {
|
||||
+ st1232_ts_power(ts, true);
|
||||
+ schedule_delayed_work(&ts->work, HZ / 50);
|
||||
+ enable_irq(client->irq);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
-
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops,
|
||||
- st1232_ts_suspend, st1232_ts_resume);
|
||||
+ st1232_ts_suspend, st1232_ts_resume);
|
||||
|
||||
static const struct i2c_device_id st1232_ts_id[] = {
|
||||
- { ST1232_TS_NAME, 0 },
|
||||
- { }
|
||||
+ { ST1232_TS_NAME, 0 },
|
||||
+ { }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, st1232_ts_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id st1232_ts_dt_ids[] = {
|
||||
- { .compatible = "sitronix,st1232", },
|
||||
- { }
|
||||
+ { .compatible = "sitronix,st1232", },
|
||||
+ { }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver st1232_ts_driver = {
|
||||
- .probe = st1232_ts_probe,
|
||||
- .remove = st1232_ts_remove,
|
||||
- .id_table = st1232_ts_id,
|
||||
- .driver = {
|
||||
- .name = ST1232_TS_NAME,
|
||||
- .owner = THIS_MODULE,
|
||||
- .of_match_table = of_match_ptr(st1232_ts_dt_ids),
|
||||
- .pm = &st1232_ts_pm_ops,
|
||||
- },
|
||||
+ .probe = st1232_ts_probe,
|
||||
+ .remove = st1232_ts_remove,
|
||||
+ .id_table = st1232_ts_id,
|
||||
+ .driver = {
|
||||
+ .name = ST1232_TS_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(st1232_ts_dt_ids),
|
||||
+ .pm = &st1232_ts_pm_ops,
|
||||
+ },
|
||||
};
|
||||
|
||||
module_i2c_driver(st1232_ts_driver);
|
||||
|
||||
-MODULE_AUTHOR("Tony SIM <chinyeow.sim.xt@renesas.com>");
|
||||
-MODULE_DESCRIPTION("SITRONIX ST1232 Touchscreen Controller Driver");
|
||||
+MODULE_AUTHOR("Tony SIM <chinyeow.sim.xt@renesas.com>, Peter Vicman <peter.vicman@gmail.com>");
|
||||
+MODULE_DESCRIPTION("SITRONIX ST1232/ST1332 Touchscreen Controller Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
--
|
||||
1.8.1.2
|
Loading…
x
Reference in New Issue
Block a user