aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2016-10-03 19:42:21 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-10-03 19:42:21 -0400
commitc758f96a8c346ac5a6822b521ec92308c5774381 (patch)
tree377b72d74ee58b3e1eeb0528d0618e38645aaafc /drivers/input/touchscreen
parent9fb6de1b0bf4ec11573b76059da3c3b39ac7f2ff (diff)
parent265d426d7470d53e900379960eef5b4482125089 (diff)
Merge branch 'next' into for-linus
Prepare first round of input updates for 4.9 merge window.
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig25
-rw-r--r--drivers/input/touchscreen/Makefile2
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c8
-rw-r--r--drivers/input/touchscreen/ektf2127.c336
-rw-r--r--drivers/input/touchscreen/elants_i2c.c31
-rw-r--r--drivers/input/touchscreen/ft6236.c326
-rw-r--r--drivers/input/touchscreen/jornada720_ts.c21
-rw-r--r--drivers/input/touchscreen/mc13783_ts.c24
-rw-r--r--drivers/input/touchscreen/pixcir_i2c_ts.c13
-rw-r--r--drivers/input/touchscreen/wdt87xx_i2c.c5
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c2
11 files changed, 403 insertions, 390 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 2fb1f430a431..507981356921 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -305,19 +305,6 @@ config TOUCHSCREEN_EGALAX_SERIAL
305 To compile this driver as a module, choose M here: the 305 To compile this driver as a module, choose M here: the
306 module will be called egalax_ts_serial. 306 module will be called egalax_ts_serial.
307 307
308config TOUCHSCREEN_FT6236
309 tristate "FT6236 I2C touchscreen"
310 depends on I2C
311 depends on GPIOLIB || COMPILE_TEST
312 help
313 Say Y here to enable support for the I2C connected FT6x06 and
314 FT6x36 family of capacitive touchscreen drivers.
315
316 If unsure, say N.
317
318 To compile this driver as a module, choose M here: the
319 module will be called ft6236.
320
321config TOUCHSCREEN_FUJITSU 308config TOUCHSCREEN_FUJITSU
322 tristate "Fujitsu serial touchscreen" 309 tristate "Fujitsu serial touchscreen"
323 select SERIO 310 select SERIO
@@ -397,6 +384,18 @@ config TOUCHSCREEN_GUNZE
397 To compile this driver as a module, choose M here: the 384 To compile this driver as a module, choose M here: the
398 module will be called gunze. 385 module will be called gunze.
399 386
387config TOUCHSCREEN_EKTF2127
388 tristate "Elan eKTF2127 I2C touchscreen"
389 depends on I2C
390 help
391 Say Y here if you have an Elan eKTF2127 touchscreen
392 connected to your system.
393
394 If unsure, say N.
395
396 To compile this driver as a module, choose M here: the
397 module will be called ektf2127.
398
400config TOUCHSCREEN_ELAN 399config TOUCHSCREEN_ELAN
401 tristate "Elan eKTH I2C touchscreen" 400 tristate "Elan eKTH I2C touchscreen"
402 depends on I2C 401 depends on I2C
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index b4373d6be402..81b86451782d 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -32,11 +32,11 @@ obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o
32obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o 32obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o
33obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o 33obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
34obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o 34obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
35obj-$(CONFIG_TOUCHSCREEN_EKTF2127) += ektf2127.o
35obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o 36obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o
36obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o 37obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
37obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o 38obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o
38obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o 39obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
39obj-$(CONFIG_TOUCHSCREEN_FT6236) += ft6236.o
40obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o 40obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
41obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o 41obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
42obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o 42obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 703e295a37ed..28466e358fee 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -1063,9 +1063,15 @@ static const struct edt_i2c_chip_data edt_ft5506_data = {
1063 .max_support_points = 10, 1063 .max_support_points = 10,
1064}; 1064};
1065 1065
1066static const struct edt_i2c_chip_data edt_ft6236_data = {
1067 .max_support_points = 2,
1068};
1069
1066static const struct i2c_device_id edt_ft5x06_ts_id[] = { 1070static const struct i2c_device_id edt_ft5x06_ts_id[] = {
1067 { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data }, 1071 { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
1068 { .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data }, 1072 { .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data },
1073 /* Note no edt- prefix for compatibility with the ft6236.c driver */
1074 { .name = "ft6236", .driver_data = (long)&edt_ft6236_data },
1069 { /* sentinel */ } 1075 { /* sentinel */ }
1070}; 1076};
1071MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id); 1077MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
@@ -1076,6 +1082,8 @@ static const struct of_device_id edt_ft5x06_of_match[] = {
1076 { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data }, 1082 { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data },
1077 { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data }, 1083 { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data },
1078 { .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data }, 1084 { .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data },
1085 /* Note focaltech vendor prefix for compatibility with ft6236.c */
1086 { .compatible = "focaltech,ft6236", .data = &edt_ft6236_data },
1079 { /* sentinel */ } 1087 { /* sentinel */ }
1080}; 1088};
1081MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match); 1089MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
new file mode 100644
index 000000000000..0ed34ff787ce
--- /dev/null
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -0,0 +1,336 @@
1/*
2 * Driver for ELAN eKTF2127 i2c touchscreen controller
3 *
4 * For this driver the layout of the Chipone icn8318 i2c
5 * touchscreencontroller is used.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * Author:
13 * Michel Verlaan <michel.verl@gmail.com>
14 * Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>
15 *
16 * Original chipone_icn8318 driver:
17 * Hans de Goede <hdegoede@redhat.com>
18 */
19
20#include <linux/gpio/consumer.h>
21#include <linux/interrupt.h>
22#include <linux/i2c.h>
23#include <linux/input.h>
24#include <linux/input/mt.h>
25#include <linux/input/touchscreen.h>
26#include <linux/module.h>
27#include <linux/of.h>
28#include <linux/delay.h>
29
30/* Packet header defines (first byte of data send / received) */
31#define EKTF2127_NOISE 0x40
32#define EKTF2127_RESPONSE 0x52
33#define EKTF2127_REQUEST 0x53
34#define EKTF2127_HELLO 0x55
35#define EKTF2127_REPORT 0x5d
36#define EKTF2127_CALIB_DONE 0x66
37
38/* Register defines (second byte of data send / received) */
39#define EKTF2127_ENV_NOISY 0x41
40#define EKTF2127_HEIGHT 0x60
41#define EKTF2127_WIDTH 0x63
42
43/* 2 bytes header + 5 * 3 bytes coordinates + 3 bytes pressure info + footer */
44#define EKTF2127_TOUCH_REPORT_SIZE 21
45#define EKTF2127_MAX_TOUCHES 5
46
47struct ektf2127_ts {
48 struct i2c_client *client;
49 struct input_dev *input;
50 struct gpio_desc *power_gpios;
51 struct touchscreen_properties prop;
52};
53
54static void ektf2127_parse_coordinates(const u8* buf, unsigned int touch_count,
55 struct input_mt_pos *touches)
56{
57 int index = 0;
58 int i;
59
60 for (i = 0; i < touch_count; i++) {
61 index = 2 + i * 3;
62
63 touches[i].x = (buf[index] & 0x0f);
64 touches[i].x <<= 8;
65 touches[i].x |= buf[index + 2];
66
67 touches[i].y = (buf[index] & 0xf0);
68 touches[i].y <<= 4;
69 touches[i].y |= buf[index + 1];
70 }
71}
72
73static void ektf2127_report_event(struct ektf2127_ts *ts, const u8 *buf)
74{
75 struct input_mt_pos touches[EKTF2127_MAX_TOUCHES];
76 int slots[EKTF2127_MAX_TOUCHES];
77 unsigned int touch_count, i;
78
79 touch_count = buf[1] & 0x07;
80 if (touch_count > EKTF2127_MAX_TOUCHES) {
81 dev_err(&ts->client->dev,
82 "Too many touches %d > %d\n",
83 touch_count, EKTF2127_MAX_TOUCHES);
84 touch_count = EKTF2127_MAX_TOUCHES;
85 }
86
87 ektf2127_parse_coordinates(buf, touch_count, touches);
88 input_mt_assign_slots(ts->input, slots, touches,
89 touch_count, 0);
90
91 for (i = 0; i < touch_count; i++) {
92 input_mt_slot(ts->input, slots[i]);
93 input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
94 touchscreen_report_pos(ts->input, &ts->prop,
95 touches[i].x, touches[i].y, true);
96 }
97
98 input_mt_sync_frame(ts->input);
99 input_sync(ts->input);
100}
101
102static irqreturn_t ektf2127_irq(int irq, void *dev_id)
103{
104 struct ektf2127_ts *ts = dev_id;
105 struct device *dev = &ts->client->dev;
106 char buf[EKTF2127_TOUCH_REPORT_SIZE];
107 int ret;
108
109 ret = i2c_master_recv(ts->client, buf, EKTF2127_TOUCH_REPORT_SIZE);
110 if (ret != EKTF2127_TOUCH_REPORT_SIZE) {
111 dev_err(dev, "Error reading touch data: %d\n", ret);
112 goto out;
113 }
114
115 switch (buf[0]) {
116 case EKTF2127_REPORT:
117 ektf2127_report_event(ts, buf);
118 break;
119
120 case EKTF2127_NOISE:
121 if (buf[1] == EKTF2127_ENV_NOISY)
122 dev_dbg(dev, "Environment is electrically noisy\n");
123 break;
124
125 case EKTF2127_HELLO:
126 case EKTF2127_CALIB_DONE:
127 break;
128
129 default:
130 dev_err(dev, "Unexpected packet header byte %#02x\n", buf[0]);
131 break;
132 }
133
134out:
135 return IRQ_HANDLED;
136}
137
138static int ektf2127_start(struct input_dev *dev)
139{
140 struct ektf2127_ts *ts = input_get_drvdata(dev);
141
142 enable_irq(ts->client->irq);
143 gpiod_set_value_cansleep(ts->power_gpios, 1);
144
145 return 0;
146}
147
148static void ektf2127_stop(struct input_dev *dev)
149{
150 struct ektf2127_ts *ts = input_get_drvdata(dev);
151
152 disable_irq(ts->client->irq);
153 gpiod_set_value_cansleep(ts->power_gpios, 0);
154}
155
156static int __maybe_unused ektf2127_suspend(struct device *dev)
157{
158 struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
159
160 mutex_lock(&ts->input->mutex);
161 if (ts->input->users)
162 ektf2127_stop(ts->input);
163 mutex_unlock(&ts->input->mutex);
164
165 return 0;
166}
167
168static int __maybe_unused ektf2127_resume(struct device *dev)
169{
170 struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
171
172 mutex_lock(&ts->input->mutex);
173 if (ts->input->users)
174 ektf2127_start(ts->input);
175 mutex_unlock(&ts->input->mutex);
176
177 return 0;
178}
179
180static SIMPLE_DEV_PM_OPS(ektf2127_pm_ops, ektf2127_suspend,
181 ektf2127_resume);
182
183static int ektf2127_query_dimension(struct i2c_client *client, bool width)
184{
185 struct device *dev = &client->dev;
186 const char *what = width ? "width" : "height";
187 u8 what_code = width ? EKTF2127_WIDTH : EKTF2127_HEIGHT;
188 u8 buf[4];
189 int ret;
190 int error;
191
192 /* Request dimension */
193 buf[0] = EKTF2127_REQUEST;
194 buf[1] = width ? EKTF2127_WIDTH : EKTF2127_HEIGHT;
195 buf[2] = 0x00;
196 buf[3] = 0x00;
197 ret = i2c_master_send(client, buf, sizeof(buf));
198 if (ret != sizeof(buf)) {
199 error = ret < 0 ? ret : -EIO;
200 dev_err(dev, "Failed to request %s: %d\n", what, error);
201 return error;
202 }
203
204 msleep(20);
205
206 /* Read response */
207 ret = i2c_master_recv(client, buf, sizeof(buf));
208 if (ret != sizeof(buf)) {
209 error = ret < 0 ? ret : -EIO;
210 dev_err(dev, "Failed to receive %s data: %d\n", what, error);
211 return error;
212 }
213
214 if (buf[0] != EKTF2127_RESPONSE || buf[1] != what_code) {
215 dev_err(dev, "Unexpected %s data: %#02x %#02x\n",
216 what, buf[0], buf[1]);
217 return -EIO;
218 }
219
220 return (((buf[3] & 0xf0) << 4) | buf[2]) - 1;
221}
222
223static int ektf2127_probe(struct i2c_client *client,
224 const struct i2c_device_id *id)
225{
226 struct device *dev = &client->dev;
227 struct ektf2127_ts *ts;
228 struct input_dev *input;
229 u8 buf[4];
230 int max_x, max_y;
231 int error;
232
233 if (!client->irq) {
234 dev_err(dev, "Error no irq specified\n");
235 return -EINVAL;
236 }
237
238 ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
239 if (!ts)
240 return -ENOMEM;
241
242 /* This requests the gpio *and* turns on the touchscreen controller */
243 ts->power_gpios = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH);
244 if (IS_ERR(ts->power_gpios)) {
245 error = PTR_ERR(ts->power_gpios);
246 if (error != -EPROBE_DEFER)
247 dev_err(dev, "Error getting power gpio: %d\n", error);
248 return error;
249 }
250
251 input = devm_input_allocate_device(dev);
252 if (!input)
253 return -ENOMEM;
254
255 input->name = client->name;
256 input->id.bustype = BUS_I2C;
257 input->open = ektf2127_start;
258 input->close = ektf2127_stop;
259
260 ts->client = client;
261
262 /* Read hello (ignore result, depends on initial power state) */
263 msleep(20);
264 i2c_master_recv(ts->client, buf, sizeof(buf));
265
266 /* Read resolution from chip */
267 max_x = ektf2127_query_dimension(client, true);
268 if (max_x < 0)
269 return max_x;
270
271 max_y = ektf2127_query_dimension(client, false);
272 if (max_y < 0)
273 return max_y;
274
275 input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
276 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
277 touchscreen_parse_properties(input, true, &ts->prop);
278
279 error = input_mt_init_slots(input, EKTF2127_MAX_TOUCHES,
280 INPUT_MT_DIRECT |
281 INPUT_MT_DROP_UNUSED |
282 INPUT_MT_TRACK);
283 if (error)
284 return error;
285
286 ts->input = input;
287 input_set_drvdata(input, ts);
288
289 error = devm_request_threaded_irq(dev, client->irq,
290 NULL, ektf2127_irq,
291 IRQF_ONESHOT, client->name, ts);
292 if (error) {
293 dev_err(dev, "Error requesting irq: %d\n", error);
294 return error;
295 }
296
297 /* Stop device till opened */
298 ektf2127_stop(ts->input);
299
300 error = input_register_device(input);
301 if (error)
302 return error;
303
304 i2c_set_clientdata(client, ts);
305
306 return 0;
307}
308
309#ifdef CONFIG_OF
310static const struct of_device_id ektf2127_of_match[] = {
311 { .compatible = "elan,ektf2127" },
312 {}
313};
314MODULE_DEVICE_TABLE(of, ektf2127_of_match);
315#endif
316
317static const struct i2c_device_id ektf2127_i2c_id[] = {
318 { "ektf2127", 0 },
319 {}
320};
321MODULE_DEVICE_TABLE(i2c, ektf2127_i2c_id);
322
323static struct i2c_driver ektf2127_driver = {
324 .driver = {
325 .name = "elan_ektf2127",
326 .pm = &ektf2127_pm_ops,
327 .of_match_table = of_match_ptr(ektf2127_of_match),
328 },
329 .probe = ektf2127_probe,
330 .id_table = ektf2127_i2c_id,
331};
332module_i2c_driver(ektf2127_driver);
333
334MODULE_DESCRIPTION("ELAN eKTF2127 I2C Touchscreen Driver");
335MODULE_AUTHOR("Michel Verlaan, Siebren Vroegindeweij");
336MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index ac09855fa435..02aec284deca 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -298,7 +298,7 @@ static u16 elants_i2c_parse_version(u8 *buf)
298 return get_unaligned_be32(buf) >> 4; 298 return get_unaligned_be32(buf) >> 4;
299} 299}
300 300
301static int elants_i2c_query_fw_id(struct elants_data *ts) 301static int elants_i2c_query_hw_version(struct elants_data *ts)
302{ 302{
303 struct i2c_client *client = ts->client; 303 struct i2c_client *client = ts->client;
304 int error, retry_cnt; 304 int error, retry_cnt;
@@ -318,8 +318,13 @@ static int elants_i2c_query_fw_id(struct elants_data *ts)
318 error, (int)sizeof(resp), resp); 318 error, (int)sizeof(resp), resp);
319 } 319 }
320 320
321 dev_err(&client->dev, 321 if (error) {
322 "Failed to read fw id or fw id is invalid\n"); 322 dev_err(&client->dev,
323 "Failed to read fw id: %d\n", error);
324 return error;
325 }
326
327 dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
323 328
324 return -EINVAL; 329 return -EINVAL;
325} 330}
@@ -508,7 +513,7 @@ static int elants_i2c_fastboot(struct i2c_client *client)
508static int elants_i2c_initialize(struct elants_data *ts) 513static int elants_i2c_initialize(struct elants_data *ts)
509{ 514{
510 struct i2c_client *client = ts->client; 515 struct i2c_client *client = ts->client;
511 int error, retry_cnt; 516 int error, error2, retry_cnt;
512 const u8 hello_packet[] = { 0x55, 0x55, 0x55, 0x55 }; 517 const u8 hello_packet[] = { 0x55, 0x55, 0x55, 0x55 };
513 const u8 recov_packet[] = { 0x55, 0x55, 0x80, 0x80 }; 518 const u8 recov_packet[] = { 0x55, 0x55, 0x80, 0x80 };
514 u8 buf[HEADER_SIZE]; 519 u8 buf[HEADER_SIZE];
@@ -553,18 +558,22 @@ static int elants_i2c_initialize(struct elants_data *ts)
553 } 558 }
554 } 559 }
555 560
561 /* hw version is available even if device in recovery state */
562 error2 = elants_i2c_query_hw_version(ts);
556 if (!error) 563 if (!error)
557 error = elants_i2c_query_fw_id(ts); 564 error = error2;
565
558 if (!error) 566 if (!error)
559 error = elants_i2c_query_fw_version(ts); 567 error = elants_i2c_query_fw_version(ts);
568 if (!error)
569 error = elants_i2c_query_test_version(ts);
570 if (!error)
571 error = elants_i2c_query_bc_version(ts);
572 if (!error)
573 error = elants_i2c_query_ts_info(ts);
560 574
561 if (error) { 575 if (error)
562 ts->iap_mode = ELAN_IAP_RECOVERY; 576 ts->iap_mode = ELAN_IAP_RECOVERY;
563 } else {
564 elants_i2c_query_test_version(ts);
565 elants_i2c_query_bc_version(ts);
566 elants_i2c_query_ts_info(ts);
567 }
568 577
569 return 0; 578 return 0;
570} 579}
diff --git a/drivers/input/touchscreen/ft6236.c b/drivers/input/touchscreen/ft6236.c
deleted file mode 100644
index d240d2e212bd..000000000000
--- a/drivers/input/touchscreen/ft6236.c
+++ /dev/null
@@ -1,326 +0,0 @@
1/*
2 * FocalTech FT6236 TouchScreen driver.
3 *
4 * Copyright (c) 2010 Focal tech Ltd.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/delay.h>
17#include <linux/gpio/consumer.h>
18#include <linux/i2c.h>
19#include <linux/input.h>
20#include <linux/input/mt.h>
21#include <linux/interrupt.h>
22#include <linux/module.h>
23#include <linux/property.h>
24
25#define FT6236_MAX_TOUCH_POINTS 2
26
27#define FT6236_REG_TH_GROUP 0x80
28#define FT6236_REG_PERIODACTIVE 0x88
29#define FT6236_REG_LIB_VER_H 0xa1
30#define FT6236_REG_LIB_VER_L 0xa2
31#define FT6236_REG_CIPHER 0xa3
32#define FT6236_REG_FIRMID 0xa6
33#define FT6236_REG_FOCALTECH_ID 0xa8
34#define FT6236_REG_RELEASE_CODE_ID 0xaf
35
36#define FT6236_EVENT_PRESS_DOWN 0
37#define FT6236_EVENT_LIFT_UP 1
38#define FT6236_EVENT_CONTACT 2
39#define FT6236_EVENT_NO_EVENT 3
40
41struct ft6236_data {
42 struct i2c_client *client;
43 struct input_dev *input;
44 struct gpio_desc *reset_gpio;
45 u32 max_x;
46 u32 max_y;
47 bool invert_x;
48 bool invert_y;
49 bool swap_xy;
50};
51
52/*
53 * This struct is a touchpoint as stored in hardware. Note that the id,
54 * as well as the event, are stored in the upper nybble of the hi byte.
55 */
56struct ft6236_touchpoint {
57 union {
58 u8 xhi;
59 u8 event;
60 };
61 u8 xlo;
62 union {
63 u8 yhi;
64 u8 id;
65 };
66 u8 ylo;
67 u8 weight;
68 u8 misc;
69} __packed;
70
71/* This packet represents the register map as read from offset 0 */
72struct ft6236_packet {
73 u8 dev_mode;
74 u8 gest_id;
75 u8 touches;
76 struct ft6236_touchpoint points[FT6236_MAX_TOUCH_POINTS];
77} __packed;
78
79static int ft6236_read(struct i2c_client *client, u8 reg, u8 len, void *data)
80{
81 int error;
82
83 error = i2c_smbus_read_i2c_block_data(client, reg, len, data);
84 if (error < 0)
85 return error;
86
87 if (error != len)
88 return -EIO;
89
90 return 0;
91}
92
93static irqreturn_t ft6236_interrupt(int irq, void *dev_id)
94{
95 struct ft6236_data *ft6236 = dev_id;
96 struct device *dev = &ft6236->client->dev;
97 struct input_dev *input = ft6236->input;
98 struct ft6236_packet buf;
99 u8 touches;
100 int i, error;
101
102 error = ft6236_read(ft6236->client, 0, sizeof(buf), &buf);
103 if (error) {
104 dev_err(dev, "read touchdata failed %d\n", error);
105 return IRQ_HANDLED;
106 }
107
108 touches = buf.touches & 0xf;
109 if (touches > FT6236_MAX_TOUCH_POINTS) {
110 dev_dbg(dev,
111 "%d touch points reported, only %d are supported\n",
112 touches, FT6236_MAX_TOUCH_POINTS);
113 touches = FT6236_MAX_TOUCH_POINTS;
114 }
115
116 for (i = 0; i < touches; i++) {
117 struct ft6236_touchpoint *point = &buf.points[i];
118 u16 x = ((point->xhi & 0xf) << 8) | buf.points[i].xlo;
119 u16 y = ((point->yhi & 0xf) << 8) | buf.points[i].ylo;
120 u8 event = point->event >> 6;
121 u8 id = point->id >> 4;
122 bool act = (event == FT6236_EVENT_PRESS_DOWN ||
123 event == FT6236_EVENT_CONTACT);
124
125 input_mt_slot(input, id);
126 input_mt_report_slot_state(input, MT_TOOL_FINGER, act);
127 if (!act)
128 continue;
129
130 if (ft6236->invert_x)
131 x = ft6236->max_x - x;
132
133 if (ft6236->invert_y)
134 y = ft6236->max_y - y;
135
136 if (ft6236->swap_xy) {
137 input_report_abs(input, ABS_MT_POSITION_X, y);
138 input_report_abs(input, ABS_MT_POSITION_Y, x);
139 } else {
140 input_report_abs(input, ABS_MT_POSITION_X, x);
141 input_report_abs(input, ABS_MT_POSITION_Y, y);
142 }
143 }
144
145 input_mt_sync_frame(input);
146 input_sync(input);
147
148 return IRQ_HANDLED;
149}
150
151static u8 ft6236_debug_read_byte(struct ft6236_data *ft6236, u8 reg)
152{
153 struct i2c_client *client = ft6236->client;
154 u8 val = 0;
155 int error;
156
157 error = ft6236_read(client, reg, 1, &val);
158 if (error)
159 dev_dbg(&client->dev,
160 "error reading register 0x%02x: %d\n", reg, error);
161
162 return val;
163}
164
165static void ft6236_debug_info(struct ft6236_data *ft6236)
166{
167 struct device *dev = &ft6236->client->dev;
168
169 dev_dbg(dev, "Touch threshold is %d\n",
170 ft6236_debug_read_byte(ft6236, FT6236_REG_TH_GROUP) * 4);
171 dev_dbg(dev, "Report rate is %dHz\n",
172 ft6236_debug_read_byte(ft6236, FT6236_REG_PERIODACTIVE) * 10);
173 dev_dbg(dev, "Firmware library version 0x%02x%02x\n",
174 ft6236_debug_read_byte(ft6236, FT6236_REG_LIB_VER_H),
175 ft6236_debug_read_byte(ft6236, FT6236_REG_LIB_VER_L));
176 dev_dbg(dev, "Firmware version 0x%02x\n",
177 ft6236_debug_read_byte(ft6236, FT6236_REG_FIRMID));
178 dev_dbg(dev, "Chip vendor ID 0x%02x\n",
179 ft6236_debug_read_byte(ft6236, FT6236_REG_CIPHER));
180 dev_dbg(dev, "CTPM vendor ID 0x%02x\n",
181 ft6236_debug_read_byte(ft6236, FT6236_REG_FOCALTECH_ID));
182 dev_dbg(dev, "Release code version 0x%02x\n",
183 ft6236_debug_read_byte(ft6236, FT6236_REG_RELEASE_CODE_ID));
184}
185
186static void ft6236_reset(struct ft6236_data *ft6236)
187{
188 if (!ft6236->reset_gpio)
189 return;
190
191 gpiod_set_value_cansleep(ft6236->reset_gpio, 1);
192 usleep_range(5000, 20000);
193 gpiod_set_value_cansleep(ft6236->reset_gpio, 0);
194 msleep(300);
195}
196
197static int ft6236_probe(struct i2c_client *client,
198 const struct i2c_device_id *id)
199{
200 struct device *dev = &client->dev;
201 struct ft6236_data *ft6236;
202 struct input_dev *input;
203 u32 fuzz_x = 0, fuzz_y = 0;
204 u8 val;
205 int error;
206
207 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
208 return -ENXIO;
209
210 if (!client->irq) {
211 dev_err(dev, "irq is missing\n");
212 return -EINVAL;
213 }
214
215 ft6236 = devm_kzalloc(dev, sizeof(*ft6236), GFP_KERNEL);
216 if (!ft6236)
217 return -ENOMEM;
218
219 ft6236->client = client;
220 ft6236->reset_gpio = devm_gpiod_get_optional(dev, "reset",
221 GPIOD_OUT_LOW);
222 if (IS_ERR(ft6236->reset_gpio)) {
223 error = PTR_ERR(ft6236->reset_gpio);
224 if (error != -EPROBE_DEFER)
225 dev_err(dev, "error getting reset gpio: %d\n", error);
226 return error;
227 }
228
229 ft6236_reset(ft6236);
230
231 /* verify that the controller is present */
232 error = ft6236_read(client, 0x00, 1, &val);
233 if (error) {
234 dev_err(dev, "failed to read from controller: %d\n", error);
235 return error;
236 }
237
238 ft6236_debug_info(ft6236);
239
240 input = devm_input_allocate_device(dev);
241 if (!input)
242 return -ENOMEM;
243
244 ft6236->input = input;
245 input->name = client->name;
246 input->id.bustype = BUS_I2C;
247
248 if (device_property_read_u32(dev, "touchscreen-size-x",
249 &ft6236->max_x) ||
250 device_property_read_u32(dev, "touchscreen-size-y",
251 &ft6236->max_y)) {
252 dev_err(dev, "touchscreen-size-x and/or -y missing\n");
253 return -EINVAL;
254 }
255
256 device_property_read_u32(dev, "touchscreen-fuzz-x", &fuzz_x);
257 device_property_read_u32(dev, "touchscreen-fuzz-y", &fuzz_y);
258 ft6236->invert_x = device_property_read_bool(dev,
259 "touchscreen-inverted-x");
260 ft6236->invert_y = device_property_read_bool(dev,
261 "touchscreen-inverted-y");
262 ft6236->swap_xy = device_property_read_bool(dev,
263 "touchscreen-swapped-x-y");
264
265 if (ft6236->swap_xy) {
266 input_set_abs_params(input, ABS_MT_POSITION_X, 0,
267 ft6236->max_y, fuzz_y, 0);
268 input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
269 ft6236->max_x, fuzz_x, 0);
270 } else {
271 input_set_abs_params(input, ABS_MT_POSITION_X, 0,
272 ft6236->max_x, fuzz_x, 0);
273 input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
274 ft6236->max_y, fuzz_y, 0);
275 }
276
277 error = input_mt_init_slots(input, FT6236_MAX_TOUCH_POINTS,
278 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
279 if (error)
280 return error;
281
282 error = devm_request_threaded_irq(dev, client->irq, NULL,
283 ft6236_interrupt, IRQF_ONESHOT,
284 client->name, ft6236);
285 if (error) {
286 dev_err(dev, "request irq %d failed: %d\n", client->irq, error);
287 return error;
288 }
289
290 error = input_register_device(input);
291 if (error) {
292 dev_err(dev, "failed to register input device: %d\n", error);
293 return error;
294 }
295
296 return 0;
297}
298
299#ifdef CONFIG_OF
300static const struct of_device_id ft6236_of_match[] = {
301 { .compatible = "focaltech,ft6236", },
302 { }
303};
304MODULE_DEVICE_TABLE(of, ft6236_of_match);
305#endif
306
307static const struct i2c_device_id ft6236_id[] = {
308 { "ft6236", },
309 { }
310};
311MODULE_DEVICE_TABLE(i2c, ft6236_id);
312
313static struct i2c_driver ft6236_driver = {
314 .driver = {
315 .name = "ft6236",
316 .of_match_table = of_match_ptr(ft6236_of_match),
317 },
318 .probe = ft6236_probe,
319 .id_table = ft6236_id,
320};
321module_i2c_driver(ft6236_driver);
322
323MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>");
324MODULE_AUTHOR("Noralf Trønnes <noralf@tronnes.org>");
325MODULE_DESCRIPTION("FocalTech FT6236 TouchScreen driver");
326MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c
index ea3b6a5b83e6..729b3c89324c 100644
--- a/drivers/input/touchscreen/jornada720_ts.c
+++ b/drivers/input/touchscreen/jornada720_ts.c
@@ -13,6 +13,7 @@
13 * HP Jornada 710/720/729 Touchscreen Driver 13 * HP Jornada 710/720/729 Touchscreen Driver
14 */ 14 */
15 15
16#include <linux/gpio/consumer.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/input.h> 18#include <linux/input.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
@@ -20,9 +21,7 @@
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/io.h> 22#include <linux/io.h>
22 23
23#include <mach/hardware.h>
24#include <mach/jornada720.h> 24#include <mach/jornada720.h>
25#include <mach/irqs.h>
26 25
27MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); 26MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
28MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver"); 27MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver");
@@ -30,6 +29,7 @@ MODULE_LICENSE("GPL v2");
30 29
31struct jornada_ts { 30struct jornada_ts {
32 struct input_dev *dev; 31 struct input_dev *dev;
32 struct gpio_desc *gpio;
33 int x_data[4]; /* X sample values */ 33 int x_data[4]; /* X sample values */
34 int y_data[4]; /* Y sample values */ 34 int y_data[4]; /* Y sample values */
35}; 35};
@@ -71,8 +71,8 @@ static irqreturn_t jornada720_ts_interrupt(int irq, void *dev_id)
71 struct input_dev *input = jornada_ts->dev; 71 struct input_dev *input = jornada_ts->dev;
72 int x, y; 72 int x, y;
73 73
74 /* If GPIO_GPIO9 is set to high then report pen up */ 74 /* If gpio is high then report pen up */
75 if (GPLR & GPIO_GPIO(9)) { 75 if (gpiod_get_value(jornada_ts->gpio)) {
76 input_report_key(input, BTN_TOUCH, 0); 76 input_report_key(input, BTN_TOUCH, 0);
77 input_sync(input); 77 input_sync(input);
78 } else { 78 } else {
@@ -101,7 +101,7 @@ static int jornada720_ts_probe(struct platform_device *pdev)
101{ 101{
102 struct jornada_ts *jornada_ts; 102 struct jornada_ts *jornada_ts;
103 struct input_dev *input_dev; 103 struct input_dev *input_dev;
104 int error; 104 int error, irq;
105 105
106 jornada_ts = devm_kzalloc(&pdev->dev, sizeof(*jornada_ts), GFP_KERNEL); 106 jornada_ts = devm_kzalloc(&pdev->dev, sizeof(*jornada_ts), GFP_KERNEL);
107 if (!jornada_ts) 107 if (!jornada_ts)
@@ -113,6 +113,14 @@ static int jornada720_ts_probe(struct platform_device *pdev)
113 113
114 platform_set_drvdata(pdev, jornada_ts); 114 platform_set_drvdata(pdev, jornada_ts);
115 115
116 jornada_ts->gpio = devm_gpiod_get(&pdev->dev, "penup", GPIOD_IN);
117 if (IS_ERR(jornada_ts->gpio))
118 return PTR_ERR(jornada_ts->gpio);
119
120 irq = gpiod_to_irq(jornada_ts->gpio);
121 if (irq <= 0)
122 return irq < 0 ? irq : -EINVAL;
123
116 jornada_ts->dev = input_dev; 124 jornada_ts->dev = input_dev;
117 125
118 input_dev->name = "HP Jornada 7xx Touchscreen"; 126 input_dev->name = "HP Jornada 7xx Touchscreen";
@@ -125,8 +133,7 @@ static int jornada720_ts_probe(struct platform_device *pdev)
125 input_set_abs_params(input_dev, ABS_X, 270, 3900, 0, 0); 133 input_set_abs_params(input_dev, ABS_X, 270, 3900, 0, 0);
126 input_set_abs_params(input_dev, ABS_Y, 180, 3700, 0, 0); 134 input_set_abs_params(input_dev, ABS_Y, 180, 3700, 0, 0);
127 135
128 error = devm_request_irq(&pdev->dev, IRQ_GPIO9, 136 error = devm_request_irq(&pdev->dev, irq, jornada720_ts_interrupt,
129 jornada720_ts_interrupt,
130 IRQF_TRIGGER_RISING, 137 IRQF_TRIGGER_RISING,
131 "HP7XX Touchscreen driver", pdev); 138 "HP7XX Touchscreen driver", pdev);
132 if (error) { 139 if (error) {
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
index 913e25a994b4..ef64f36c5ffc 100644
--- a/drivers/input/touchscreen/mc13783_ts.c
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -37,7 +37,6 @@ struct mc13783_ts_priv {
37 struct input_dev *idev; 37 struct input_dev *idev;
38 struct mc13xxx *mc13xxx; 38 struct mc13xxx *mc13xxx;
39 struct delayed_work work; 39 struct delayed_work work;
40 struct workqueue_struct *workq;
41 unsigned int sample[4]; 40 unsigned int sample[4];
42 struct mc13xxx_ts_platform_data *touch; 41 struct mc13xxx_ts_platform_data *touch;
43}; 42};
@@ -54,7 +53,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data)
54 * be rescheduled for immediate execution here. However the rearm 53 * be rescheduled for immediate execution here. However the rearm
55 * delay is HZ / 50 which is acceptable. 54 * delay is HZ / 50 which is acceptable.
56 */ 55 */
57 queue_delayed_work(priv->workq, &priv->work, 0); 56 schedule_delayed_work(&priv->work, 0);
58 57
59 return IRQ_HANDLED; 58 return IRQ_HANDLED;
60} 59}
@@ -106,16 +105,18 @@ static void mc13783_ts_report_sample(struct mc13783_ts_priv *priv)
106 105
107 dev_dbg(&idev->dev, "report (%d, %d, %d)\n", 106 dev_dbg(&idev->dev, "report (%d, %d, %d)\n",
108 x1, y1, 0x1000 - cr0); 107 x1, y1, 0x1000 - cr0);
109 queue_delayed_work(priv->workq, &priv->work, HZ / 50); 108 schedule_delayed_work(&priv->work, HZ / 50);
110 } else 109 } else {
111 dev_dbg(&idev->dev, "report release\n"); 110 dev_dbg(&idev->dev, "report release\n");
111 }
112 112
113 input_report_abs(idev, ABS_PRESSURE, 113 input_report_abs(idev, ABS_PRESSURE,
114 cr0 ? 0x1000 - cr0 : cr0); 114 cr0 ? 0x1000 - cr0 : cr0);
115 input_report_key(idev, BTN_TOUCH, cr0); 115 input_report_key(idev, BTN_TOUCH, cr0);
116 input_sync(idev); 116 input_sync(idev);
117 } else 117 } else {
118 dev_dbg(&idev->dev, "discard event\n"); 118 dev_dbg(&idev->dev, "discard event\n");
119 }
119} 120}
120 121
121static void mc13783_ts_work(struct work_struct *work) 122static void mc13783_ts_work(struct work_struct *work)
@@ -189,14 +190,6 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
189 goto err_free_mem; 190 goto err_free_mem;
190 } 191 }
191 192
192 /*
193 * We need separate workqueue because mc13783_adc_do_conversion
194 * uses keventd and thus would deadlock.
195 */
196 priv->workq = create_singlethread_workqueue("mc13783_ts");
197 if (!priv->workq)
198 goto err_free_mem;
199
200 idev->name = MC13783_TS_NAME; 193 idev->name = MC13783_TS_NAME;
201 idev->dev.parent = &pdev->dev; 194 idev->dev.parent = &pdev->dev;
202 195
@@ -215,14 +208,12 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
215 if (ret) { 208 if (ret) {
216 dev_err(&pdev->dev, 209 dev_err(&pdev->dev,
217 "register input device failed with %d\n", ret); 210 "register input device failed with %d\n", ret);
218 goto err_destroy_wq; 211 goto err_free_mem;
219 } 212 }
220 213
221 platform_set_drvdata(pdev, priv); 214 platform_set_drvdata(pdev, priv);
222 return 0; 215 return 0;
223 216
224err_destroy_wq:
225 destroy_workqueue(priv->workq);
226err_free_mem: 217err_free_mem:
227 input_free_device(idev); 218 input_free_device(idev);
228 kfree(priv); 219 kfree(priv);
@@ -233,7 +224,6 @@ static int mc13783_ts_remove(struct platform_device *pdev)
233{ 224{
234 struct mc13783_ts_priv *priv = platform_get_drvdata(pdev); 225 struct mc13783_ts_priv *priv = platform_get_drvdata(pdev);
235 226
236 destroy_workqueue(priv->workq);
237 input_unregister_device(priv->idev); 227 input_unregister_device(priv->idev);
238 kfree(priv); 228 kfree(priv);
239 229
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index d159e14f4d20..3bb0637d832e 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -11,10 +11,6 @@
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 14 */
19 15
20#include <linux/delay.h> 16#include <linux/delay.h>
@@ -404,7 +400,6 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev)
404 mutex_lock(&input->mutex); 400 mutex_lock(&input->mutex);
405 401
406 if (device_may_wakeup(&client->dev)) { 402 if (device_may_wakeup(&client->dev)) {
407
408 if (!input->users) { 403 if (!input->users) {
409 ret = pixcir_stop(ts); 404 ret = pixcir_stop(ts);
410 if (ret) { 405 if (ret) {
@@ -431,13 +426,7 @@ static const struct of_device_id pixcir_of_match[];
431static int pixcir_parse_dt(struct device *dev, 426static int pixcir_parse_dt(struct device *dev,
432 struct pixcir_i2c_ts_data *tsdata) 427 struct pixcir_i2c_ts_data *tsdata)
433{ 428{
434 const struct of_device_id *match; 429 tsdata->chip = of_device_get_match_data(dev);
435
436 match = of_match_device(of_match_ptr(pixcir_of_match), dev);
437 if (!match)
438 return -EINVAL;
439
440 tsdata->chip = (const struct pixcir_i2c_chip_data *)match->data;
441 if (!tsdata->chip) 430 if (!tsdata->chip)
442 return -EINVAL; 431 return -EINVAL;
443 432
diff --git a/drivers/input/touchscreen/wdt87xx_i2c.c b/drivers/input/touchscreen/wdt87xx_i2c.c
index 73861ad22df4..a9132603ab34 100644
--- a/drivers/input/touchscreen/wdt87xx_i2c.c
+++ b/drivers/input/touchscreen/wdt87xx_i2c.c
@@ -23,7 +23,7 @@
23#include <asm/unaligned.h> 23#include <asm/unaligned.h>
24 24
25#define WDT87XX_NAME "wdt87xx_i2c" 25#define WDT87XX_NAME "wdt87xx_i2c"
26#define WDT87XX_DRV_VER "0.9.7" 26#define WDT87XX_DRV_VER "0.9.8"
27#define WDT87XX_FW_NAME "wdt87xx_fw.bin" 27#define WDT87XX_FW_NAME "wdt87xx_fw.bin"
28#define WDT87XX_CFG_NAME "wdt87xx_cfg.bin" 28#define WDT87XX_CFG_NAME "wdt87xx_cfg.bin"
29 29
@@ -157,6 +157,7 @@
157/* Controller requires minimum 300us between commands */ 157/* Controller requires minimum 300us between commands */
158#define WDT_COMMAND_DELAY_MS 2 158#define WDT_COMMAND_DELAY_MS 2
159#define WDT_FLASH_WRITE_DELAY_MS 4 159#define WDT_FLASH_WRITE_DELAY_MS 4
160#define WDT_FLASH_ERASE_DELAY_MS 200
160#define WDT_FW_RESET_TIME 2500 161#define WDT_FW_RESET_TIME 2500
161 162
162struct wdt87xx_sys_param { 163struct wdt87xx_sys_param {
@@ -726,7 +727,7 @@ static int wdt87xx_write_firmware(struct i2c_client *client, const void *chunk)
726 break; 727 break;
727 } 728 }
728 729
729 msleep(50); 730 msleep(WDT_FLASH_ERASE_DELAY_MS);
730 731
731 error = wdt87xx_write_data(client, data, start_addr, 732 error = wdt87xx_write_data(client, data, start_addr,
732 page_size); 733 page_size);
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index 1534e9b0788c..90d6be3c26cc 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -500,7 +500,7 @@ static int wm97xx_ts_input_open(struct input_dev *idev)
500{ 500{
501 struct wm97xx *wm = input_get_drvdata(idev); 501 struct wm97xx *wm = input_get_drvdata(idev);
502 502
503 wm->ts_workq = create_singlethread_workqueue("kwm97xx"); 503 wm->ts_workq = alloc_ordered_workqueue("kwm97xx", 0);
504 if (wm->ts_workq == NULL) { 504 if (wm->ts_workq == NULL) {
505 dev_err(wm->dev, 505 dev_err(wm->dev,
506 "Failed to create workqueue\n"); 506 "Failed to create workqueue\n");