diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-09 21:46:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-09 21:46:02 -0400 |
commit | f4f9b8fc73f9aa93744f0e91e18f367d7766f523 (patch) | |
tree | 90d02c6722b0ffd8252ac438370600aaf8d814e7 /drivers/input/touchscreen | |
parent | 9894e6d9c020b754dd962960e9f7eac18282f69f (diff) | |
parent | a292241cccb7e20e8b997a9a44177e7c98141859 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
"A big update to the Atmel touchscreen driver, devm support for polled
input devices, several drivers have been converted to using managed
resources, and assorted driver fixes"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (87 commits)
Input: synaptics - fix resolution for manually provided min/max
Input: atmel_mxt_ts - fix invalid return from mxt_get_bootloader_version
Input: max8997_haptic - add error handling for regulator and pwm
Input: elantech - don't set bit 1 of reg_10 when the no_hw_res quirk is set
Input: elantech - deal with clickpads reporting right button events
Input: edt-ft5x06 - fix an i2c write for M09 support
Input: omap-keypad - remove platform data support
ARM: OMAP2+: remove unused omap4-keypad file and code
Input: ab8500-ponkey - switch to using managed resources
Input: max8925_onkey - switch to using managed resources
Input: 88pm860x-ts - switch to using managed resources
Input: 88pm860x_onkey - switch to using managed resources
Input: intel-mid-touch - switch to using managed resources
Input: wacom - process outbound for newer Cintiqs
Input: wacom - set stylus_in_proximity when pen is in range
DTS: ARM: OMAP3-N900: Add tsc2005 support
Input: tsc2005 - add DT support
Input: add common DT binding for touchscreens
Input: jornada680_kbd - switch top using managed resources
Input: adp5520-keys - switch to using managed resources
...
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r-- | drivers/input/touchscreen/88pm860x-ts.c | 41 | ||||
-rw-r--r-- | drivers/input/touchscreen/Kconfig | 18 | ||||
-rw-r--r-- | drivers/input/touchscreen/Makefile | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/ad7877.c | 5 | ||||
-rw-r--r-- | drivers/input/touchscreen/ads7846.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 862 | ||||
-rw-r--r-- | drivers/input/touchscreen/auo-pixcir-ts.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/da9034-ts.c | 39 | ||||
-rw-r--r-- | drivers/input/touchscreen/edt-ft5x06.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/egalax_ts.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/intel-mid-touch.c | 47 | ||||
-rw-r--r-- | drivers/input/touchscreen/lpc32xx_ts.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/mcs5000_ts.c | 83 | ||||
-rw-r--r-- | drivers/input/touchscreen/mms114.c | 4 | ||||
-rw-r--r-- | drivers/input/touchscreen/of_touchscreen.c | 45 | ||||
-rw-r--r-- | drivers/input/touchscreen/pixcir_i2c_ts.c | 281 | ||||
-rw-r--r-- | drivers/input/touchscreen/sun4i-ts.c | 339 | ||||
-rw-r--r-- | drivers/input/touchscreen/tsc2005.c | 157 | ||||
-rw-r--r-- | drivers/input/touchscreen/zforce_ts.c | 2 |
19 files changed, 1419 insertions, 516 deletions
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c index 544e20c551f8..0d4a9fad4a78 100644 --- a/drivers/input/touchscreen/88pm860x-ts.c +++ b/drivers/input/touchscreen/88pm860x-ts.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/input.h> | 16 | #include <linux/input.h> |
17 | #include <linux/mfd/88pm860x.h> | 17 | #include <linux/mfd/88pm860x.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/device.h> | ||
19 | 20 | ||
20 | #define MEAS_LEN (8) | 21 | #define MEAS_LEN (8) |
21 | #define ACCURATE_BIT (12) | 22 | #define ACCURATE_BIT (12) |
@@ -234,16 +235,17 @@ static int pm860x_touch_probe(struct platform_device *pdev) | |||
234 | if (ret) | 235 | if (ret) |
235 | return ret; | 236 | return ret; |
236 | 237 | ||
237 | touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); | 238 | touch = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_touch), |
238 | if (touch == NULL) | 239 | GFP_KERNEL); |
240 | if (!touch) | ||
239 | return -ENOMEM; | 241 | return -ENOMEM; |
242 | |||
240 | platform_set_drvdata(pdev, touch); | 243 | platform_set_drvdata(pdev, touch); |
241 | 244 | ||
242 | touch->idev = input_allocate_device(); | 245 | touch->idev = devm_input_allocate_device(&pdev->dev); |
243 | if (touch->idev == NULL) { | 246 | if (!touch->idev) { |
244 | dev_err(&pdev->dev, "Failed to allocate input device!\n"); | 247 | dev_err(&pdev->dev, "Failed to allocate input device!\n"); |
245 | ret = -ENOMEM; | 248 | return -ENOMEM; |
246 | goto out; | ||
247 | } | 249 | } |
248 | 250 | ||
249 | touch->idev->name = "88pm860x-touch"; | 251 | touch->idev->name = "88pm860x-touch"; |
@@ -258,10 +260,11 @@ static int pm860x_touch_probe(struct platform_device *pdev) | |||
258 | touch->res_x = res_x; | 260 | touch->res_x = res_x; |
259 | input_set_drvdata(touch->idev, touch); | 261 | input_set_drvdata(touch->idev, touch); |
260 | 262 | ||
261 | ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, | 263 | ret = devm_request_threaded_irq(&pdev->dev, touch->irq, NULL, |
262 | IRQF_ONESHOT, "touch", touch); | 264 | pm860x_touch_handler, IRQF_ONESHOT, |
265 | "touch", touch); | ||
263 | if (ret < 0) | 266 | if (ret < 0) |
264 | goto out_irq; | 267 | return ret; |
265 | 268 | ||
266 | __set_bit(EV_ABS, touch->idev->evbit); | 269 | __set_bit(EV_ABS, touch->idev->evbit); |
267 | __set_bit(ABS_X, touch->idev->absbit); | 270 | __set_bit(ABS_X, touch->idev->absbit); |
@@ -279,28 +282,11 @@ static int pm860x_touch_probe(struct platform_device *pdev) | |||
279 | ret = input_register_device(touch->idev); | 282 | ret = input_register_device(touch->idev); |
280 | if (ret < 0) { | 283 | if (ret < 0) { |
281 | dev_err(chip->dev, "Failed to register touch!\n"); | 284 | dev_err(chip->dev, "Failed to register touch!\n"); |
282 | goto out_rg; | 285 | return ret; |
283 | } | 286 | } |
284 | 287 | ||
285 | platform_set_drvdata(pdev, touch); | 288 | platform_set_drvdata(pdev, touch); |
286 | return 0; | 289 | return 0; |
287 | out_rg: | ||
288 | free_irq(touch->irq, touch); | ||
289 | out_irq: | ||
290 | input_free_device(touch->idev); | ||
291 | out: | ||
292 | kfree(touch); | ||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | static int pm860x_touch_remove(struct platform_device *pdev) | ||
297 | { | ||
298 | struct pm860x_touch *touch = platform_get_drvdata(pdev); | ||
299 | |||
300 | input_unregister_device(touch->idev); | ||
301 | free_irq(touch->irq, touch); | ||
302 | kfree(touch); | ||
303 | return 0; | ||
304 | } | 290 | } |
305 | 291 | ||
306 | static struct platform_driver pm860x_touch_driver = { | 292 | static struct platform_driver pm860x_touch_driver = { |
@@ -309,7 +295,6 @@ static struct platform_driver pm860x_touch_driver = { | |||
309 | .owner = THIS_MODULE, | 295 | .owner = THIS_MODULE, |
310 | }, | 296 | }, |
311 | .probe = pm860x_touch_probe, | 297 | .probe = pm860x_touch_probe, |
312 | .remove = pm860x_touch_remove, | ||
313 | }; | 298 | }; |
314 | module_platform_driver(pm860x_touch_driver); | 299 | module_platform_driver(pm860x_touch_driver); |
315 | 300 | ||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index d4e5ab57909f..a23a94bb4bcb 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -11,6 +11,10 @@ menuconfig INPUT_TOUCHSCREEN | |||
11 | 11 | ||
12 | if INPUT_TOUCHSCREEN | 12 | if INPUT_TOUCHSCREEN |
13 | 13 | ||
14 | config OF_TOUCHSCREEN | ||
15 | def_tristate INPUT | ||
16 | depends on INPUT && OF | ||
17 | |||
14 | config TOUCHSCREEN_88PM860X | 18 | config TOUCHSCREEN_88PM860X |
15 | tristate "Marvell 88PM860x touchscreen" | 19 | tristate "Marvell 88PM860x touchscreen" |
16 | depends on MFD_88PM860X | 20 | depends on MFD_88PM860X |
@@ -89,6 +93,7 @@ config TOUCHSCREEN_AD7879_SPI | |||
89 | config TOUCHSCREEN_ATMEL_MXT | 93 | config TOUCHSCREEN_ATMEL_MXT |
90 | tristate "Atmel mXT I2C Touchscreen" | 94 | tristate "Atmel mXT I2C Touchscreen" |
91 | depends on I2C | 95 | depends on I2C |
96 | select FW_LOADER | ||
92 | help | 97 | help |
93 | Say Y here if you have Atmel mXT series I2C touchscreen, | 98 | Say Y here if you have Atmel mXT series I2C touchscreen, |
94 | such as AT42QT602240/ATMXT224, connected to your system. | 99 | such as AT42QT602240/ATMXT224, connected to your system. |
@@ -846,7 +851,7 @@ config TOUCHSCREEN_TSC2007 | |||
846 | 851 | ||
847 | config TOUCHSCREEN_W90X900 | 852 | config TOUCHSCREEN_W90X900 |
848 | tristate "W90P910 touchscreen driver" | 853 | tristate "W90P910 touchscreen driver" |
849 | depends on HAVE_CLK | 854 | depends on ARCH_W90X900 |
850 | help | 855 | help |
851 | Say Y here if you have a W90P910 based touchscreen. | 856 | Say Y here if you have a W90P910 based touchscreen. |
852 | 857 | ||
@@ -885,6 +890,17 @@ config TOUCHSCREEN_STMPE | |||
885 | To compile this driver as a module, choose M here: the | 890 | To compile this driver as a module, choose M here: the |
886 | module will be called stmpe-ts. | 891 | module will be called stmpe-ts. |
887 | 892 | ||
893 | config TOUCHSCREEN_SUN4I | ||
894 | tristate "Allwinner sun4i resistive touchscreen controller support" | ||
895 | depends on ARCH_SUNXI || COMPILE_TEST | ||
896 | depends on HWMON | ||
897 | help | ||
898 | This selects support for the resistive touchscreen controller | ||
899 | found on Allwinner sunxi SoCs. | ||
900 | |||
901 | To compile this driver as a module, choose M here: the | ||
902 | module will be called sun4i-ts. | ||
903 | |||
888 | config TOUCHSCREEN_SUR40 | 904 | config TOUCHSCREEN_SUR40 |
889 | tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen" | 905 | tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen" |
890 | depends on USB | 906 | depends on USB |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 03f12a1f2218..126479d8c29a 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | wm97xx-ts-y := wm97xx-core.o | 7 | wm97xx-ts-y := wm97xx-core.o |
8 | 8 | ||
9 | obj-$(CONFIG_OF_TOUCHSCREEN) += of_touchscreen.o | ||
9 | obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o | 10 | obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o |
10 | obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o | 11 | obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o |
11 | obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o | 12 | obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o |
@@ -53,6 +54,7 @@ obj-$(CONFIG_TOUCHSCREEN_PIXCIR) += pixcir_i2c_ts.o | |||
53 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o | 54 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o |
54 | obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o | 55 | obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o |
55 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o | 56 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o |
57 | obj-$(CONFIG_TOUCHSCREEN_SUN4I) += sun4i-ts.o | ||
56 | obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o | 58 | obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o |
57 | obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o | 59 | obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o |
58 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o | 60 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o |
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 6793c85903ae..523865daa1d3 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -210,11 +210,6 @@ static bool gpio3; | |||
210 | module_param(gpio3, bool, 0); | 210 | module_param(gpio3, bool, 0); |
211 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); | 211 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); |
212 | 212 | ||
213 | /* | ||
214 | * ad7877_read/write are only used for initial setup and for sysfs controls. | ||
215 | * The main traffic is done using spi_async() in the interrupt handler. | ||
216 | */ | ||
217 | |||
218 | static int ad7877_read(struct spi_device *spi, u16 reg) | 213 | static int ad7877_read(struct spi_device *spi, u16 reg) |
219 | { | 214 | { |
220 | struct ser_req *req; | 215 | struct ser_req *req; |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 7f8aa981500d..da201b8e37dc 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -706,7 +706,7 @@ static void ads7846_read_state(struct ads7846 *ts) | |||
706 | m = &ts->msg[msg_idx]; | 706 | m = &ts->msg[msg_idx]; |
707 | error = spi_sync(ts->spi, m); | 707 | error = spi_sync(ts->spi, m); |
708 | if (error) { | 708 | if (error) { |
709 | dev_err(&ts->spi->dev, "spi_async --> %d\n", error); | 709 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", error); |
710 | packet->tc.ignore = true; | 710 | packet->tc.ignore = true; |
711 | return; | 711 | return; |
712 | } | 712 | } |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index a70400754e92..6e0b4a2120d3 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * Atmel maXTouch Touchscreen driver | 2 | * Atmel maXTouch Touchscreen driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | 4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd |
5 | * Copyright (C) 2012 Google, Inc. | ||
6 | * | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | 7 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> |
6 | * | 8 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
@@ -12,6 +14,8 @@ | |||
12 | */ | 14 | */ |
13 | 15 | ||
14 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | ||
18 | #include <linux/completion.h> | ||
15 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
16 | #include <linux/firmware.h> | 20 | #include <linux/firmware.h> |
17 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
@@ -25,12 +29,6 @@ | |||
25 | #define MXT_VER_21 21 | 29 | #define MXT_VER_21 21 |
26 | #define MXT_VER_22 22 | 30 | #define MXT_VER_22 22 |
27 | 31 | ||
28 | /* Slave addresses */ | ||
29 | #define MXT_APP_LOW 0x4a | ||
30 | #define MXT_APP_HIGH 0x4b | ||
31 | #define MXT_BOOT_LOW 0x24 | ||
32 | #define MXT_BOOT_HIGH 0x25 | ||
33 | |||
34 | /* Firmware */ | 32 | /* Firmware */ |
35 | #define MXT_FW_NAME "maxtouch.fw" | 33 | #define MXT_FW_NAME "maxtouch.fw" |
36 | 34 | ||
@@ -83,6 +81,9 @@ | |||
83 | #define MXT_COMMAND_REPORTALL 3 | 81 | #define MXT_COMMAND_REPORTALL 3 |
84 | #define MXT_COMMAND_DIAGNOSTIC 5 | 82 | #define MXT_COMMAND_DIAGNOSTIC 5 |
85 | 83 | ||
84 | /* Define for T6 status byte */ | ||
85 | #define MXT_T6_STATUS_RESET (1 << 7) | ||
86 | |||
86 | /* MXT_GEN_POWER_T7 field */ | 87 | /* MXT_GEN_POWER_T7 field */ |
87 | #define MXT_POWER_IDLEACQINT 0 | 88 | #define MXT_POWER_IDLEACQINT 0 |
88 | #define MXT_POWER_ACTVACQINT 1 | 89 | #define MXT_POWER_ACTVACQINT 1 |
@@ -99,33 +100,26 @@ | |||
99 | 100 | ||
100 | /* MXT_TOUCH_MULTI_T9 field */ | 101 | /* MXT_TOUCH_MULTI_T9 field */ |
101 | #define MXT_TOUCH_CTRL 0 | 102 | #define MXT_TOUCH_CTRL 0 |
102 | #define MXT_TOUCH_XORIGIN 1 | 103 | #define MXT_T9_ORIENT 9 |
103 | #define MXT_TOUCH_YORIGIN 2 | 104 | #define MXT_T9_RANGE 18 |
104 | #define MXT_TOUCH_XSIZE 3 | 105 | |
105 | #define MXT_TOUCH_YSIZE 4 | 106 | /* MXT_TOUCH_MULTI_T9 status */ |
106 | #define MXT_TOUCH_BLEN 6 | 107 | #define MXT_T9_UNGRIP (1 << 0) |
107 | #define MXT_TOUCH_TCHTHR 7 | 108 | #define MXT_T9_SUPPRESS (1 << 1) |
108 | #define MXT_TOUCH_TCHDI 8 | 109 | #define MXT_T9_AMP (1 << 2) |
109 | #define MXT_TOUCH_ORIENT 9 | 110 | #define MXT_T9_VECTOR (1 << 3) |
110 | #define MXT_TOUCH_MOVHYSTI 11 | 111 | #define MXT_T9_MOVE (1 << 4) |
111 | #define MXT_TOUCH_MOVHYSTN 12 | 112 | #define MXT_T9_RELEASE (1 << 5) |
112 | #define MXT_TOUCH_NUMTOUCH 14 | 113 | #define MXT_T9_PRESS (1 << 6) |
113 | #define MXT_TOUCH_MRGHYST 15 | 114 | #define MXT_T9_DETECT (1 << 7) |
114 | #define MXT_TOUCH_MRGTHR 16 | 115 | |
115 | #define MXT_TOUCH_AMPHYST 17 | 116 | struct t9_range { |
116 | #define MXT_TOUCH_XRANGE_LSB 18 | 117 | u16 x; |
117 | #define MXT_TOUCH_XRANGE_MSB 19 | 118 | u16 y; |
118 | #define MXT_TOUCH_YRANGE_LSB 20 | 119 | } __packed; |
119 | #define MXT_TOUCH_YRANGE_MSB 21 | 120 | |
120 | #define MXT_TOUCH_XLOCLIP 22 | 121 | /* MXT_TOUCH_MULTI_T9 orient */ |
121 | #define MXT_TOUCH_XHICLIP 23 | 122 | #define MXT_T9_ORIENT_SWITCH (1 << 0) |
122 | #define MXT_TOUCH_YLOCLIP 24 | ||
123 | #define MXT_TOUCH_YHICLIP 25 | ||
124 | #define MXT_TOUCH_XEDGECTRL 26 | ||
125 | #define MXT_TOUCH_XEDGEDIST 27 | ||
126 | #define MXT_TOUCH_YEDGECTRL 28 | ||
127 | #define MXT_TOUCH_YEDGEDIST 29 | ||
128 | #define MXT_TOUCH_JUMPLIMIT 30 | ||
129 | 123 | ||
130 | /* MXT_PROCI_GRIPFACE_T20 field */ | 124 | /* MXT_PROCI_GRIPFACE_T20 field */ |
131 | #define MXT_GRIPFACE_CTRL 0 | 125 | #define MXT_GRIPFACE_CTRL 0 |
@@ -174,17 +168,16 @@ | |||
174 | 168 | ||
175 | /* Define for MXT_GEN_COMMAND_T6 */ | 169 | /* Define for MXT_GEN_COMMAND_T6 */ |
176 | #define MXT_BOOT_VALUE 0xa5 | 170 | #define MXT_BOOT_VALUE 0xa5 |
171 | #define MXT_RESET_VALUE 0x01 | ||
177 | #define MXT_BACKUP_VALUE 0x55 | 172 | #define MXT_BACKUP_VALUE 0x55 |
173 | |||
174 | /* Delay times */ | ||
178 | #define MXT_BACKUP_TIME 50 /* msec */ | 175 | #define MXT_BACKUP_TIME 50 /* msec */ |
179 | #define MXT_RESET_TIME 200 /* msec */ | 176 | #define MXT_RESET_TIME 200 /* msec */ |
180 | 177 | #define MXT_RESET_TIMEOUT 3000 /* msec */ | |
181 | #define MXT_FWRESET_TIME 175 /* msec */ | 178 | #define MXT_CRC_TIMEOUT 1000 /* msec */ |
182 | 179 | #define MXT_FW_RESET_TIME 3000 /* msec */ | |
183 | /* MXT_SPT_GPIOPWM_T19 field */ | 180 | #define MXT_FW_CHG_TIMEOUT 300 /* msec */ |
184 | #define MXT_GPIO0_MASK 0x04 | ||
185 | #define MXT_GPIO1_MASK 0x08 | ||
186 | #define MXT_GPIO2_MASK 0x10 | ||
187 | #define MXT_GPIO3_MASK 0x20 | ||
188 | 181 | ||
189 | /* Command to unlock bootloader */ | 182 | /* Command to unlock bootloader */ |
190 | #define MXT_UNLOCK_CMD_MSB 0xaa | 183 | #define MXT_UNLOCK_CMD_MSB 0xaa |
@@ -198,21 +191,8 @@ | |||
198 | #define MXT_FRAME_CRC_PASS 0x04 | 191 | #define MXT_FRAME_CRC_PASS 0x04 |
199 | #define MXT_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */ | 192 | #define MXT_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */ |
200 | #define MXT_BOOT_STATUS_MASK 0x3f | 193 | #define MXT_BOOT_STATUS_MASK 0x3f |
201 | 194 | #define MXT_BOOT_EXTENDED_ID (1 << 5) | |
202 | /* Touch status */ | 195 | #define MXT_BOOT_ID_MASK 0x1f |
203 | #define MXT_UNGRIP (1 << 0) | ||
204 | #define MXT_SUPPRESS (1 << 1) | ||
205 | #define MXT_AMP (1 << 2) | ||
206 | #define MXT_VECTOR (1 << 3) | ||
207 | #define MXT_MOVE (1 << 4) | ||
208 | #define MXT_RELEASE (1 << 5) | ||
209 | #define MXT_PRESS (1 << 6) | ||
210 | #define MXT_DETECT (1 << 7) | ||
211 | |||
212 | /* Touch orient bits */ | ||
213 | #define MXT_XY_SWITCH (1 << 0) | ||
214 | #define MXT_X_INVERT (1 << 1) | ||
215 | #define MXT_Y_INVERT (1 << 2) | ||
216 | 196 | ||
217 | /* Touchscreen absolute values */ | 197 | /* Touchscreen absolute values */ |
218 | #define MXT_MAX_AREA 0xff | 198 | #define MXT_MAX_AREA 0xff |
@@ -232,8 +212,8 @@ struct mxt_info { | |||
232 | struct mxt_object { | 212 | struct mxt_object { |
233 | u8 type; | 213 | u8 type; |
234 | u16 start_address; | 214 | u16 start_address; |
235 | u8 size; /* Size of each instance - 1 */ | 215 | u8 size_minus_one; |
236 | u8 instances; /* Number of instances - 1 */ | 216 | u8 instances_minus_one; |
237 | u8 num_report_ids; | 217 | u8 num_report_ids; |
238 | } __packed; | 218 | } __packed; |
239 | 219 | ||
@@ -250,19 +230,40 @@ struct mxt_data { | |||
250 | const struct mxt_platform_data *pdata; | 230 | const struct mxt_platform_data *pdata; |
251 | struct mxt_object *object_table; | 231 | struct mxt_object *object_table; |
252 | struct mxt_info info; | 232 | struct mxt_info info; |
253 | bool is_tp; | ||
254 | |||
255 | unsigned int irq; | 233 | unsigned int irq; |
256 | unsigned int max_x; | 234 | unsigned int max_x; |
257 | unsigned int max_y; | 235 | unsigned int max_y; |
236 | bool in_bootloader; | ||
237 | u32 config_crc; | ||
238 | u8 bootloader_addr; | ||
258 | 239 | ||
259 | /* Cached parameters from object table */ | 240 | /* Cached parameters from object table */ |
260 | u8 T6_reportid; | 241 | u8 T6_reportid; |
242 | u16 T6_address; | ||
261 | u8 T9_reportid_min; | 243 | u8 T9_reportid_min; |
262 | u8 T9_reportid_max; | 244 | u8 T9_reportid_max; |
263 | u8 T19_reportid; | 245 | u8 T19_reportid; |
246 | |||
247 | /* for fw update in bootloader */ | ||
248 | struct completion bl_completion; | ||
249 | |||
250 | /* for reset handling */ | ||
251 | struct completion reset_completion; | ||
252 | |||
253 | /* for config update handling */ | ||
254 | struct completion crc_completion; | ||
264 | }; | 255 | }; |
265 | 256 | ||
257 | static size_t mxt_obj_size(const struct mxt_object *obj) | ||
258 | { | ||
259 | return obj->size_minus_one + 1; | ||
260 | } | ||
261 | |||
262 | static size_t mxt_obj_instances(const struct mxt_object *obj) | ||
263 | { | ||
264 | return obj->instances_minus_one + 1; | ||
265 | } | ||
266 | |||
266 | static bool mxt_object_readable(unsigned int type) | 267 | static bool mxt_object_readable(unsigned int type) |
267 | { | 268 | { |
268 | switch (type) { | 269 | switch (type) { |
@@ -334,60 +335,190 @@ static void mxt_dump_message(struct device *dev, | |||
334 | message->reportid, 7, message->message); | 335 | message->reportid, 7, message->message); |
335 | } | 336 | } |
336 | 337 | ||
337 | static int mxt_check_bootloader(struct i2c_client *client, | 338 | static int mxt_wait_for_completion(struct mxt_data *data, |
338 | unsigned int state) | 339 | struct completion *comp, |
340 | unsigned int timeout_ms) | ||
341 | { | ||
342 | struct device *dev = &data->client->dev; | ||
343 | unsigned long timeout = msecs_to_jiffies(timeout_ms); | ||
344 | long ret; | ||
345 | |||
346 | ret = wait_for_completion_interruptible_timeout(comp, timeout); | ||
347 | if (ret < 0) { | ||
348 | return ret; | ||
349 | } else if (ret == 0) { | ||
350 | dev_err(dev, "Wait for completion timed out.\n"); | ||
351 | return -ETIMEDOUT; | ||
352 | } | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static int mxt_bootloader_read(struct mxt_data *data, | ||
357 | u8 *val, unsigned int count) | ||
358 | { | ||
359 | int ret; | ||
360 | struct i2c_msg msg; | ||
361 | |||
362 | msg.addr = data->bootloader_addr; | ||
363 | msg.flags = data->client->flags & I2C_M_TEN; | ||
364 | msg.flags |= I2C_M_RD; | ||
365 | msg.len = count; | ||
366 | msg.buf = val; | ||
367 | |||
368 | ret = i2c_transfer(data->client->adapter, &msg, 1); | ||
369 | |||
370 | if (ret == 1) { | ||
371 | ret = 0; | ||
372 | } else { | ||
373 | ret = ret < 0 ? ret : -EIO; | ||
374 | dev_err(&data->client->dev, "%s: i2c recv failed (%d)\n", | ||
375 | __func__, ret); | ||
376 | } | ||
377 | |||
378 | return ret; | ||
379 | } | ||
380 | |||
381 | static int mxt_bootloader_write(struct mxt_data *data, | ||
382 | const u8 * const val, unsigned int count) | ||
383 | { | ||
384 | int ret; | ||
385 | struct i2c_msg msg; | ||
386 | |||
387 | msg.addr = data->bootloader_addr; | ||
388 | msg.flags = data->client->flags & I2C_M_TEN; | ||
389 | msg.len = count; | ||
390 | msg.buf = (u8 *)val; | ||
391 | |||
392 | ret = i2c_transfer(data->client->adapter, &msg, 1); | ||
393 | if (ret == 1) { | ||
394 | ret = 0; | ||
395 | } else { | ||
396 | ret = ret < 0 ? ret : -EIO; | ||
397 | dev_err(&data->client->dev, "%s: i2c send failed (%d)\n", | ||
398 | __func__, ret); | ||
399 | } | ||
400 | |||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | static int mxt_lookup_bootloader_address(struct mxt_data *data) | ||
405 | { | ||
406 | u8 appmode = data->client->addr; | ||
407 | u8 bootloader; | ||
408 | |||
409 | switch (appmode) { | ||
410 | case 0x4a: | ||
411 | case 0x4b: | ||
412 | case 0x4c: | ||
413 | case 0x4d: | ||
414 | case 0x5a: | ||
415 | case 0x5b: | ||
416 | bootloader = appmode - 0x26; | ||
417 | break; | ||
418 | default: | ||
419 | dev_err(&data->client->dev, | ||
420 | "Appmode i2c address 0x%02x not found\n", | ||
421 | appmode); | ||
422 | return -EINVAL; | ||
423 | } | ||
424 | |||
425 | data->bootloader_addr = bootloader; | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static u8 mxt_get_bootloader_version(struct mxt_data *data, u8 val) | ||
430 | { | ||
431 | struct device *dev = &data->client->dev; | ||
432 | u8 buf[3]; | ||
433 | |||
434 | if (val & MXT_BOOT_EXTENDED_ID) { | ||
435 | if (mxt_bootloader_read(data, &buf[0], 3) != 0) { | ||
436 | dev_err(dev, "%s: i2c failure\n", __func__); | ||
437 | return val; | ||
438 | } | ||
439 | |||
440 | dev_dbg(dev, "Bootloader ID:%d Version:%d\n", buf[1], buf[2]); | ||
441 | |||
442 | return buf[0]; | ||
443 | } else { | ||
444 | dev_dbg(dev, "Bootloader ID:%d\n", val & MXT_BOOT_ID_MASK); | ||
445 | |||
446 | return val; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | static int mxt_check_bootloader(struct mxt_data *data, unsigned int state) | ||
339 | { | 451 | { |
452 | struct device *dev = &data->client->dev; | ||
340 | u8 val; | 453 | u8 val; |
454 | int ret; | ||
341 | 455 | ||
342 | recheck: | 456 | recheck: |
343 | if (i2c_master_recv(client, &val, 1) != 1) { | 457 | if (state != MXT_WAITING_BOOTLOAD_CMD) { |
344 | dev_err(&client->dev, "%s: i2c recv failed\n", __func__); | 458 | /* |
345 | return -EIO; | 459 | * In application update mode, the interrupt |
460 | * line signals state transitions. We must wait for the | ||
461 | * CHG assertion before reading the status byte. | ||
462 | * Once the status byte has been read, the line is deasserted. | ||
463 | */ | ||
464 | ret = mxt_wait_for_completion(data, &data->bl_completion, | ||
465 | MXT_FW_CHG_TIMEOUT); | ||
466 | if (ret) { | ||
467 | /* | ||
468 | * TODO: handle -ERESTARTSYS better by terminating | ||
469 | * fw update process before returning to userspace | ||
470 | * by writing length 0x000 to device (iff we are in | ||
471 | * WAITING_FRAME_DATA state). | ||
472 | */ | ||
473 | dev_err(dev, "Update wait error %d\n", ret); | ||
474 | return ret; | ||
475 | } | ||
346 | } | 476 | } |
347 | 477 | ||
478 | ret = mxt_bootloader_read(data, &val, 1); | ||
479 | if (ret) | ||
480 | return ret; | ||
481 | |||
482 | if (state == MXT_WAITING_BOOTLOAD_CMD) | ||
483 | val = mxt_get_bootloader_version(data, val); | ||
484 | |||
348 | switch (state) { | 485 | switch (state) { |
349 | case MXT_WAITING_BOOTLOAD_CMD: | 486 | case MXT_WAITING_BOOTLOAD_CMD: |
350 | case MXT_WAITING_FRAME_DATA: | 487 | case MXT_WAITING_FRAME_DATA: |
351 | val &= ~MXT_BOOT_STATUS_MASK; | 488 | val &= ~MXT_BOOT_STATUS_MASK; |
352 | break; | 489 | break; |
353 | case MXT_FRAME_CRC_PASS: | 490 | case MXT_FRAME_CRC_PASS: |
354 | if (val == MXT_FRAME_CRC_CHECK) | 491 | if (val == MXT_FRAME_CRC_CHECK) { |
355 | goto recheck; | 492 | goto recheck; |
493 | } else if (val == MXT_FRAME_CRC_FAIL) { | ||
494 | dev_err(dev, "Bootloader CRC fail\n"); | ||
495 | return -EINVAL; | ||
496 | } | ||
356 | break; | 497 | break; |
357 | default: | 498 | default: |
358 | return -EINVAL; | 499 | return -EINVAL; |
359 | } | 500 | } |
360 | 501 | ||
361 | if (val != state) { | 502 | if (val != state) { |
362 | dev_err(&client->dev, "Unvalid bootloader mode state\n"); | 503 | dev_err(dev, "Invalid bootloader state %02X != %02X\n", |
504 | val, state); | ||
363 | return -EINVAL; | 505 | return -EINVAL; |
364 | } | 506 | } |
365 | 507 | ||
366 | return 0; | 508 | return 0; |
367 | } | 509 | } |
368 | 510 | ||
369 | static int mxt_unlock_bootloader(struct i2c_client *client) | 511 | static int mxt_unlock_bootloader(struct mxt_data *data) |
370 | { | 512 | { |
513 | int ret; | ||
371 | u8 buf[2]; | 514 | u8 buf[2]; |
372 | 515 | ||
373 | buf[0] = MXT_UNLOCK_CMD_LSB; | 516 | buf[0] = MXT_UNLOCK_CMD_LSB; |
374 | buf[1] = MXT_UNLOCK_CMD_MSB; | 517 | buf[1] = MXT_UNLOCK_CMD_MSB; |
375 | 518 | ||
376 | if (i2c_master_send(client, buf, 2) != 2) { | 519 | ret = mxt_bootloader_write(data, buf, 2); |
377 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | 520 | if (ret) |
378 | return -EIO; | 521 | return ret; |
379 | } | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static int mxt_fw_write(struct i2c_client *client, | ||
385 | const u8 *data, unsigned int frame_size) | ||
386 | { | ||
387 | if (i2c_master_send(client, data, frame_size) != frame_size) { | ||
388 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
389 | return -EIO; | ||
390 | } | ||
391 | 522 | ||
392 | return 0; | 523 | return 0; |
393 | } | 524 | } |
@@ -427,11 +558,6 @@ static int __mxt_read_reg(struct i2c_client *client, | |||
427 | return ret; | 558 | return ret; |
428 | } | 559 | } |
429 | 560 | ||
430 | static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val) | ||
431 | { | ||
432 | return __mxt_read_reg(client, reg, 1, val); | ||
433 | } | ||
434 | |||
435 | static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len, | 561 | static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len, |
436 | const void *val) | 562 | const void *val) |
437 | { | 563 | { |
@@ -479,7 +605,7 @@ mxt_get_object(struct mxt_data *data, u8 type) | |||
479 | return object; | 605 | return object; |
480 | } | 606 | } |
481 | 607 | ||
482 | dev_err(&data->client->dev, "Invalid object type\n"); | 608 | dev_err(&data->client->dev, "Invalid object type T%u\n", type); |
483 | return NULL; | 609 | return NULL; |
484 | } | 610 | } |
485 | 611 | ||
@@ -505,7 +631,7 @@ static int mxt_write_object(struct mxt_data *data, | |||
505 | u16 reg; | 631 | u16 reg; |
506 | 632 | ||
507 | object = mxt_get_object(data, type); | 633 | object = mxt_get_object(data, type); |
508 | if (!object || offset >= object->size + 1) | 634 | if (!object || offset >= mxt_obj_size(object)) |
509 | return -EINVAL; | 635 | return -EINVAL; |
510 | 636 | ||
511 | reg = object->start_address; | 637 | reg = object->start_address; |
@@ -515,18 +641,25 @@ static int mxt_write_object(struct mxt_data *data, | |||
515 | static void mxt_input_button(struct mxt_data *data, struct mxt_message *message) | 641 | static void mxt_input_button(struct mxt_data *data, struct mxt_message *message) |
516 | { | 642 | { |
517 | struct input_dev *input = data->input_dev; | 643 | struct input_dev *input = data->input_dev; |
644 | const struct mxt_platform_data *pdata = data->pdata; | ||
518 | bool button; | 645 | bool button; |
519 | int i; | 646 | int i; |
520 | 647 | ||
521 | /* Active-low switch */ | 648 | /* Active-low switch */ |
522 | for (i = 0; i < MXT_NUM_GPIO; i++) { | 649 | for (i = 0; i < pdata->t19_num_keys; i++) { |
523 | if (data->pdata->key_map[i] == KEY_RESERVED) | 650 | if (pdata->t19_keymap[i] == KEY_RESERVED) |
524 | continue; | 651 | continue; |
525 | button = !(message->message[0] & MXT_GPIO0_MASK << i); | 652 | button = !(message->message[0] & (1 << i)); |
526 | input_report_key(input, data->pdata->key_map[i], button); | 653 | input_report_key(input, pdata->t19_keymap[i], button); |
527 | } | 654 | } |
528 | } | 655 | } |
529 | 656 | ||
657 | static void mxt_input_sync(struct input_dev *input_dev) | ||
658 | { | ||
659 | input_mt_report_pointer_emulation(input_dev, false); | ||
660 | input_sync(input_dev); | ||
661 | } | ||
662 | |||
530 | static void mxt_input_touchevent(struct mxt_data *data, | 663 | static void mxt_input_touchevent(struct mxt_data *data, |
531 | struct mxt_message *message, int id) | 664 | struct mxt_message *message, int id) |
532 | { | 665 | { |
@@ -536,44 +669,60 @@ static void mxt_input_touchevent(struct mxt_data *data, | |||
536 | int x; | 669 | int x; |
537 | int y; | 670 | int y; |
538 | int area; | 671 | int area; |
539 | int pressure; | 672 | int amplitude; |
540 | 673 | ||
541 | x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf); | 674 | x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf); |
542 | y = (message->message[2] << 4) | ((message->message[3] & 0xf)); | 675 | y = (message->message[2] << 4) | ((message->message[3] & 0xf)); |
676 | |||
677 | /* Handle 10/12 bit switching */ | ||
543 | if (data->max_x < 1024) | 678 | if (data->max_x < 1024) |
544 | x = x >> 2; | 679 | x >>= 2; |
545 | if (data->max_y < 1024) | 680 | if (data->max_y < 1024) |
546 | y = y >> 2; | 681 | y >>= 2; |
547 | 682 | ||
548 | area = message->message[4]; | 683 | area = message->message[4]; |
549 | pressure = message->message[5]; | 684 | amplitude = message->message[5]; |
550 | 685 | ||
551 | dev_dbg(dev, | 686 | dev_dbg(dev, |
552 | "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n", | 687 | "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n", |
553 | id, | 688 | id, |
554 | (status & MXT_DETECT) ? 'D' : '.', | 689 | (status & MXT_T9_DETECT) ? 'D' : '.', |
555 | (status & MXT_PRESS) ? 'P' : '.', | 690 | (status & MXT_T9_PRESS) ? 'P' : '.', |
556 | (status & MXT_RELEASE) ? 'R' : '.', | 691 | (status & MXT_T9_RELEASE) ? 'R' : '.', |
557 | (status & MXT_MOVE) ? 'M' : '.', | 692 | (status & MXT_T9_MOVE) ? 'M' : '.', |
558 | (status & MXT_VECTOR) ? 'V' : '.', | 693 | (status & MXT_T9_VECTOR) ? 'V' : '.', |
559 | (status & MXT_AMP) ? 'A' : '.', | 694 | (status & MXT_T9_AMP) ? 'A' : '.', |
560 | (status & MXT_SUPPRESS) ? 'S' : '.', | 695 | (status & MXT_T9_SUPPRESS) ? 'S' : '.', |
561 | (status & MXT_UNGRIP) ? 'U' : '.', | 696 | (status & MXT_T9_UNGRIP) ? 'U' : '.', |
562 | x, y, area, pressure); | 697 | x, y, area, amplitude); |
563 | 698 | ||
564 | input_mt_slot(input_dev, id); | 699 | input_mt_slot(input_dev, id); |
565 | input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, | ||
566 | status & MXT_DETECT); | ||
567 | 700 | ||
568 | if (status & MXT_DETECT) { | 701 | if (status & MXT_T9_DETECT) { |
702 | /* | ||
703 | * Multiple bits may be set if the host is slow to read | ||
704 | * the status messages, indicating all the events that | ||
705 | * have happened. | ||
706 | */ | ||
707 | if (status & MXT_T9_RELEASE) { | ||
708 | input_mt_report_slot_state(input_dev, | ||
709 | MT_TOOL_FINGER, 0); | ||
710 | mxt_input_sync(input_dev); | ||
711 | } | ||
712 | |||
713 | /* Touch active */ | ||
714 | input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1); | ||
569 | input_report_abs(input_dev, ABS_MT_POSITION_X, x); | 715 | input_report_abs(input_dev, ABS_MT_POSITION_X, x); |
570 | input_report_abs(input_dev, ABS_MT_POSITION_Y, y); | 716 | input_report_abs(input_dev, ABS_MT_POSITION_Y, y); |
571 | input_report_abs(input_dev, ABS_MT_PRESSURE, pressure); | 717 | input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude); |
572 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area); | 718 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area); |
719 | } else { | ||
720 | /* Touch no longer active, close out slot */ | ||
721 | input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0); | ||
573 | } | 722 | } |
574 | } | 723 | } |
575 | 724 | ||
576 | static unsigned mxt_extract_T6_csum(const u8 *csum) | 725 | static u16 mxt_extract_T6_csum(const u8 *csum) |
577 | { | 726 | { |
578 | return csum[0] | (csum[1] << 8) | (csum[2] << 16); | 727 | return csum[0] | (csum[1] << 8) | (csum[2] << 16); |
579 | } | 728 | } |
@@ -584,28 +733,37 @@ static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg) | |||
584 | return (id >= data->T9_reportid_min && id <= data->T9_reportid_max); | 733 | return (id >= data->T9_reportid_min && id <= data->T9_reportid_max); |
585 | } | 734 | } |
586 | 735 | ||
587 | static irqreturn_t mxt_interrupt(int irq, void *dev_id) | 736 | static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data) |
588 | { | 737 | { |
589 | struct mxt_data *data = dev_id; | ||
590 | struct mxt_message message; | 738 | struct mxt_message message; |
591 | const u8 *payload = &message.message[0]; | 739 | const u8 *payload = &message.message[0]; |
592 | struct device *dev = &data->client->dev; | 740 | struct device *dev = &data->client->dev; |
593 | u8 reportid; | 741 | u8 reportid; |
594 | bool update_input = false; | 742 | bool update_input = false; |
743 | u32 crc; | ||
595 | 744 | ||
596 | do { | 745 | do { |
597 | if (mxt_read_message(data, &message)) { | 746 | if (mxt_read_message(data, &message)) { |
598 | dev_err(dev, "Failed to read message\n"); | 747 | dev_err(dev, "Failed to read message\n"); |
599 | goto end; | 748 | return IRQ_NONE; |
600 | } | 749 | } |
601 | 750 | ||
602 | reportid = message.reportid; | 751 | reportid = message.reportid; |
603 | 752 | ||
604 | if (reportid == data->T6_reportid) { | 753 | if (reportid == data->T6_reportid) { |
605 | u8 status = payload[0]; | 754 | u8 status = payload[0]; |
606 | unsigned csum = mxt_extract_T6_csum(&payload[1]); | 755 | |
756 | crc = mxt_extract_T6_csum(&payload[1]); | ||
757 | if (crc != data->config_crc) { | ||
758 | data->config_crc = crc; | ||
759 | complete(&data->crc_completion); | ||
760 | } | ||
761 | |||
607 | dev_dbg(dev, "Status: %02x Config Checksum: %06x\n", | 762 | dev_dbg(dev, "Status: %02x Config Checksum: %06x\n", |
608 | status, csum); | 763 | status, data->config_crc); |
764 | |||
765 | if (status & MXT_T6_STATUS_RESET) | ||
766 | complete(&data->reset_completion); | ||
609 | } else if (mxt_is_T9_message(data, &message)) { | 767 | } else if (mxt_is_T9_message(data, &message)) { |
610 | int id = reportid - data->T9_reportid_min; | 768 | int id = reportid - data->T9_reportid_min; |
611 | mxt_input_touchevent(data, &message, id); | 769 | mxt_input_touchevent(data, &message, id); |
@@ -618,15 +776,96 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) | |||
618 | } | 776 | } |
619 | } while (reportid != 0xff); | 777 | } while (reportid != 0xff); |
620 | 778 | ||
621 | if (update_input) { | 779 | if (update_input) |
622 | input_mt_report_pointer_emulation(data->input_dev, false); | 780 | mxt_input_sync(data->input_dev); |
623 | input_sync(data->input_dev); | ||
624 | } | ||
625 | 781 | ||
626 | end: | ||
627 | return IRQ_HANDLED; | 782 | return IRQ_HANDLED; |
628 | } | 783 | } |
629 | 784 | ||
785 | static irqreturn_t mxt_interrupt(int irq, void *dev_id) | ||
786 | { | ||
787 | struct mxt_data *data = dev_id; | ||
788 | |||
789 | if (data->in_bootloader) { | ||
790 | /* bootloader state transition completion */ | ||
791 | complete(&data->bl_completion); | ||
792 | return IRQ_HANDLED; | ||
793 | } | ||
794 | |||
795 | return mxt_process_messages_until_invalid(data); | ||
796 | } | ||
797 | |||
798 | static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset, | ||
799 | u8 value, bool wait) | ||
800 | { | ||
801 | u16 reg; | ||
802 | u8 command_register; | ||
803 | int timeout_counter = 0; | ||
804 | int ret; | ||
805 | |||
806 | reg = data->T6_address + cmd_offset; | ||
807 | |||
808 | ret = mxt_write_reg(data->client, reg, value); | ||
809 | if (ret) | ||
810 | return ret; | ||
811 | |||
812 | if (!wait) | ||
813 | return 0; | ||
814 | |||
815 | do { | ||
816 | msleep(20); | ||
817 | ret = __mxt_read_reg(data->client, reg, 1, &command_register); | ||
818 | if (ret) | ||
819 | return ret; | ||
820 | } while (command_register != 0 && timeout_counter++ <= 100); | ||
821 | |||
822 | if (timeout_counter > 100) { | ||
823 | dev_err(&data->client->dev, "Command failed!\n"); | ||
824 | return -EIO; | ||
825 | } | ||
826 | |||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | static int mxt_soft_reset(struct mxt_data *data) | ||
831 | { | ||
832 | struct device *dev = &data->client->dev; | ||
833 | int ret = 0; | ||
834 | |||
835 | dev_info(dev, "Resetting chip\n"); | ||
836 | |||
837 | reinit_completion(&data->reset_completion); | ||
838 | |||
839 | ret = mxt_t6_command(data, MXT_COMMAND_RESET, MXT_RESET_VALUE, false); | ||
840 | if (ret) | ||
841 | return ret; | ||
842 | |||
843 | ret = mxt_wait_for_completion(data, &data->reset_completion, | ||
844 | MXT_RESET_TIMEOUT); | ||
845 | if (ret) | ||
846 | return ret; | ||
847 | |||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | static void mxt_update_crc(struct mxt_data *data, u8 cmd, u8 value) | ||
852 | { | ||
853 | /* | ||
854 | * On failure, CRC is set to 0 and config will always be | ||
855 | * downloaded. | ||
856 | */ | ||
857 | data->config_crc = 0; | ||
858 | reinit_completion(&data->crc_completion); | ||
859 | |||
860 | mxt_t6_command(data, cmd, value, true); | ||
861 | |||
862 | /* | ||
863 | * Wait for crc message. On failure, CRC is set to 0 and config will | ||
864 | * always be downloaded. | ||
865 | */ | ||
866 | mxt_wait_for_completion(data, &data->crc_completion, MXT_CRC_TIMEOUT); | ||
867 | } | ||
868 | |||
630 | static int mxt_check_reg_init(struct mxt_data *data) | 869 | static int mxt_check_reg_init(struct mxt_data *data) |
631 | { | 870 | { |
632 | const struct mxt_platform_data *pdata = data->pdata; | 871 | const struct mxt_platform_data *pdata = data->pdata; |
@@ -641,13 +880,23 @@ static int mxt_check_reg_init(struct mxt_data *data) | |||
641 | return 0; | 880 | return 0; |
642 | } | 881 | } |
643 | 882 | ||
883 | mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); | ||
884 | |||
885 | if (data->config_crc == pdata->config_crc) { | ||
886 | dev_info(dev, "Config CRC 0x%06X: OK\n", data->config_crc); | ||
887 | return 0; | ||
888 | } | ||
889 | |||
890 | dev_info(dev, "Config CRC 0x%06X: does not match 0x%06X\n", | ||
891 | data->config_crc, pdata->config_crc); | ||
892 | |||
644 | for (i = 0; i < data->info.object_num; i++) { | 893 | for (i = 0; i < data->info.object_num; i++) { |
645 | object = data->object_table + i; | 894 | object = data->object_table + i; |
646 | 895 | ||
647 | if (!mxt_object_writable(object->type)) | 896 | if (!mxt_object_writable(object->type)) |
648 | continue; | 897 | continue; |
649 | 898 | ||
650 | size = (object->size + 1) * (object->instances + 1); | 899 | size = mxt_obj_size(object) * mxt_obj_instances(object); |
651 | if (index + size > pdata->config_length) { | 900 | if (index + size > pdata->config_length) { |
652 | dev_err(dev, "Not enough config data!\n"); | 901 | dev_err(dev, "Not enough config data!\n"); |
653 | return -EINVAL; | 902 | return -EINVAL; |
@@ -660,6 +909,14 @@ static int mxt_check_reg_init(struct mxt_data *data) | |||
660 | index += size; | 909 | index += size; |
661 | } | 910 | } |
662 | 911 | ||
912 | mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); | ||
913 | |||
914 | ret = mxt_soft_reset(data); | ||
915 | if (ret) | ||
916 | return ret; | ||
917 | |||
918 | dev_info(dev, "Config successfully updated\n"); | ||
919 | |||
663 | return 0; | 920 | return 0; |
664 | } | 921 | } |
665 | 922 | ||
@@ -685,54 +942,6 @@ static int mxt_make_highchg(struct mxt_data *data) | |||
685 | return 0; | 942 | return 0; |
686 | } | 943 | } |
687 | 944 | ||
688 | static void mxt_handle_pdata(struct mxt_data *data) | ||
689 | { | ||
690 | const struct mxt_platform_data *pdata = data->pdata; | ||
691 | u8 voltage; | ||
692 | |||
693 | /* Set touchscreen lines */ | ||
694 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_XSIZE, | ||
695 | pdata->x_line); | ||
696 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_YSIZE, | ||
697 | pdata->y_line); | ||
698 | |||
699 | /* Set touchscreen orient */ | ||
700 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_ORIENT, | ||
701 | pdata->orient); | ||
702 | |||
703 | /* Set touchscreen burst length */ | ||
704 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, | ||
705 | MXT_TOUCH_BLEN, pdata->blen); | ||
706 | |||
707 | /* Set touchscreen threshold */ | ||
708 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, | ||
709 | MXT_TOUCH_TCHTHR, pdata->threshold); | ||
710 | |||
711 | /* Set touchscreen resolution */ | ||
712 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, | ||
713 | MXT_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff); | ||
714 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, | ||
715 | MXT_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8); | ||
716 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, | ||
717 | MXT_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff); | ||
718 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, | ||
719 | MXT_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8); | ||
720 | |||
721 | /* Set touchscreen voltage */ | ||
722 | if (pdata->voltage) { | ||
723 | if (pdata->voltage < MXT_VOLTAGE_DEFAULT) { | ||
724 | voltage = (MXT_VOLTAGE_DEFAULT - pdata->voltage) / | ||
725 | MXT_VOLTAGE_STEP; | ||
726 | voltage = 0xff - voltage + 1; | ||
727 | } else | ||
728 | voltage = (pdata->voltage - MXT_VOLTAGE_DEFAULT) / | ||
729 | MXT_VOLTAGE_STEP; | ||
730 | |||
731 | mxt_write_object(data, MXT_SPT_CTECONFIG_T28, | ||
732 | MXT_CTE_VOLTAGE, voltage); | ||
733 | } | ||
734 | } | ||
735 | |||
736 | static int mxt_get_info(struct mxt_data *data) | 945 | static int mxt_get_info(struct mxt_data *data) |
737 | { | 946 | { |
738 | struct i2c_client *client = data->client; | 947 | struct i2c_client *client = data->client; |
@@ -772,7 +981,7 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
772 | if (object->num_report_ids) { | 981 | if (object->num_report_ids) { |
773 | min_id = reportid; | 982 | min_id = reportid; |
774 | reportid += object->num_report_ids * | 983 | reportid += object->num_report_ids * |
775 | (object->instances + 1); | 984 | mxt_obj_instances(object); |
776 | max_id = reportid - 1; | 985 | max_id = reportid - 1; |
777 | } else { | 986 | } else { |
778 | min_id = 0; | 987 | min_id = 0; |
@@ -780,13 +989,15 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
780 | } | 989 | } |
781 | 990 | ||
782 | dev_dbg(&data->client->dev, | 991 | dev_dbg(&data->client->dev, |
783 | "Type %2d Start %3d Size %3d Instances %2d ReportIDs %3u : %3u\n", | 992 | "T%u Start:%u Size:%zu Instances:%zu Report IDs:%u-%u\n", |
784 | object->type, object->start_address, object->size + 1, | 993 | object->type, object->start_address, |
785 | object->instances + 1, min_id, max_id); | 994 | mxt_obj_size(object), mxt_obj_instances(object), |
995 | min_id, max_id); | ||
786 | 996 | ||
787 | switch (object->type) { | 997 | switch (object->type) { |
788 | case MXT_GEN_COMMAND_T6: | 998 | case MXT_GEN_COMMAND_T6: |
789 | data->T6_reportid = min_id; | 999 | data->T6_reportid = min_id; |
1000 | data->T6_address = object->start_address; | ||
790 | break; | 1001 | break; |
791 | case MXT_TOUCH_MULTI_T9: | 1002 | case MXT_TOUCH_MULTI_T9: |
792 | data->T9_reportid_min = min_id; | 1003 | data->T9_reportid_min = min_id; |
@@ -811,12 +1022,59 @@ static void mxt_free_object_table(struct mxt_data *data) | |||
811 | data->T19_reportid = 0; | 1022 | data->T19_reportid = 0; |
812 | } | 1023 | } |
813 | 1024 | ||
1025 | static int mxt_read_t9_resolution(struct mxt_data *data) | ||
1026 | { | ||
1027 | struct i2c_client *client = data->client; | ||
1028 | int error; | ||
1029 | struct t9_range range; | ||
1030 | unsigned char orient; | ||
1031 | struct mxt_object *object; | ||
1032 | |||
1033 | object = mxt_get_object(data, MXT_TOUCH_MULTI_T9); | ||
1034 | if (!object) | ||
1035 | return -EINVAL; | ||
1036 | |||
1037 | error = __mxt_read_reg(client, | ||
1038 | object->start_address + MXT_T9_RANGE, | ||
1039 | sizeof(range), &range); | ||
1040 | if (error) | ||
1041 | return error; | ||
1042 | |||
1043 | le16_to_cpus(&range.x); | ||
1044 | le16_to_cpus(&range.y); | ||
1045 | |||
1046 | error = __mxt_read_reg(client, | ||
1047 | object->start_address + MXT_T9_ORIENT, | ||
1048 | 1, &orient); | ||
1049 | if (error) | ||
1050 | return error; | ||
1051 | |||
1052 | /* Handle default values */ | ||
1053 | if (range.x == 0) | ||
1054 | range.x = 1023; | ||
1055 | |||
1056 | if (range.y == 0) | ||
1057 | range.y = 1023; | ||
1058 | |||
1059 | if (orient & MXT_T9_ORIENT_SWITCH) { | ||
1060 | data->max_x = range.y; | ||
1061 | data->max_y = range.x; | ||
1062 | } else { | ||
1063 | data->max_x = range.x; | ||
1064 | data->max_y = range.y; | ||
1065 | } | ||
1066 | |||
1067 | dev_dbg(&client->dev, | ||
1068 | "Touchscreen size X%uY%u\n", data->max_x, data->max_y); | ||
1069 | |||
1070 | return 0; | ||
1071 | } | ||
1072 | |||
814 | static int mxt_initialize(struct mxt_data *data) | 1073 | static int mxt_initialize(struct mxt_data *data) |
815 | { | 1074 | { |
816 | struct i2c_client *client = data->client; | 1075 | struct i2c_client *client = data->client; |
817 | struct mxt_info *info = &data->info; | 1076 | struct mxt_info *info = &data->info; |
818 | int error; | 1077 | int error; |
819 | u8 val; | ||
820 | 1078 | ||
821 | error = mxt_get_info(data); | 1079 | error = mxt_get_info(data); |
822 | if (error) | 1080 | if (error) |
@@ -832,47 +1090,29 @@ static int mxt_initialize(struct mxt_data *data) | |||
832 | 1090 | ||
833 | /* Get object table information */ | 1091 | /* Get object table information */ |
834 | error = mxt_get_object_table(data); | 1092 | error = mxt_get_object_table(data); |
835 | if (error) | 1093 | if (error) { |
1094 | dev_err(&client->dev, "Error %d reading object table\n", error); | ||
836 | goto err_free_object_table; | 1095 | goto err_free_object_table; |
1096 | } | ||
837 | 1097 | ||
838 | /* Check register init values */ | 1098 | /* Check register init values */ |
839 | error = mxt_check_reg_init(data); | 1099 | error = mxt_check_reg_init(data); |
840 | if (error) | 1100 | if (error) { |
841 | goto err_free_object_table; | 1101 | dev_err(&client->dev, "Error %d initializing configuration\n", |
842 | 1102 | error); | |
843 | mxt_handle_pdata(data); | ||
844 | |||
845 | /* Backup to memory */ | ||
846 | mxt_write_object(data, MXT_GEN_COMMAND_T6, | ||
847 | MXT_COMMAND_BACKUPNV, | ||
848 | MXT_BACKUP_VALUE); | ||
849 | msleep(MXT_BACKUP_TIME); | ||
850 | |||
851 | /* Soft reset */ | ||
852 | mxt_write_object(data, MXT_GEN_COMMAND_T6, | ||
853 | MXT_COMMAND_RESET, 1); | ||
854 | msleep(MXT_RESET_TIME); | ||
855 | |||
856 | /* Update matrix size at info struct */ | ||
857 | error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val); | ||
858 | if (error) | ||
859 | goto err_free_object_table; | 1103 | goto err_free_object_table; |
860 | info->matrix_xsize = val; | 1104 | } |
861 | 1105 | ||
862 | error = mxt_read_reg(client, MXT_MATRIX_Y_SIZE, &val); | 1106 | error = mxt_read_t9_resolution(data); |
863 | if (error) | 1107 | if (error) { |
1108 | dev_err(&client->dev, "Failed to initialize T9 resolution\n"); | ||
864 | goto err_free_object_table; | 1109 | goto err_free_object_table; |
865 | info->matrix_ysize = val; | 1110 | } |
866 | |||
867 | dev_info(&client->dev, | ||
868 | "Family ID: %u Variant ID: %u Major.Minor.Build: %u.%u.%02X\n", | ||
869 | info->family_id, info->variant_id, info->version >> 4, | ||
870 | info->version & 0xf, info->build); | ||
871 | 1111 | ||
872 | dev_info(&client->dev, | 1112 | dev_info(&client->dev, |
873 | "Matrix X Size: %u Matrix Y Size: %u Object Num: %u\n", | 1113 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", |
874 | info->matrix_xsize, info->matrix_ysize, | 1114 | info->family_id, info->variant_id, info->version >> 4, |
875 | info->object_num); | 1115 | info->version & 0xf, info->build, info->object_num); |
876 | 1116 | ||
877 | return 0; | 1117 | return 0; |
878 | 1118 | ||
@@ -881,20 +1121,6 @@ err_free_object_table: | |||
881 | return error; | 1121 | return error; |
882 | } | 1122 | } |
883 | 1123 | ||
884 | static void mxt_calc_resolution(struct mxt_data *data) | ||
885 | { | ||
886 | unsigned int max_x = data->pdata->x_size - 1; | ||
887 | unsigned int max_y = data->pdata->y_size - 1; | ||
888 | |||
889 | if (data->pdata->orient & MXT_XY_SWITCH) { | ||
890 | data->max_x = max_y; | ||
891 | data->max_y = max_x; | ||
892 | } else { | ||
893 | data->max_x = max_x; | ||
894 | data->max_y = max_y; | ||
895 | } | ||
896 | } | ||
897 | |||
898 | /* Firmware Version is returned as Major.Minor.Build */ | 1124 | /* Firmware Version is returned as Major.Minor.Build */ |
899 | static ssize_t mxt_fw_version_show(struct device *dev, | 1125 | static ssize_t mxt_fw_version_show(struct device *dev, |
900 | struct device_attribute *attr, char *buf) | 1126 | struct device_attribute *attr, char *buf) |
@@ -921,11 +1147,11 @@ static ssize_t mxt_show_instance(char *buf, int count, | |||
921 | { | 1147 | { |
922 | int i; | 1148 | int i; |
923 | 1149 | ||
924 | if (object->instances > 0) | 1150 | if (mxt_obj_instances(object) > 1) |
925 | count += scnprintf(buf + count, PAGE_SIZE - count, | 1151 | count += scnprintf(buf + count, PAGE_SIZE - count, |
926 | "Instance %u\n", instance); | 1152 | "Instance %u\n", instance); |
927 | 1153 | ||
928 | for (i = 0; i < object->size + 1; i++) | 1154 | for (i = 0; i < mxt_obj_size(object); i++) |
929 | count += scnprintf(buf + count, PAGE_SIZE - count, | 1155 | count += scnprintf(buf + count, PAGE_SIZE - count, |
930 | "\t[%2u]: %02x (%d)\n", i, val[i], val[i]); | 1156 | "\t[%2u]: %02x (%d)\n", i, val[i], val[i]); |
931 | count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); | 1157 | count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); |
@@ -958,8 +1184,8 @@ static ssize_t mxt_object_show(struct device *dev, | |||
958 | count += scnprintf(buf + count, PAGE_SIZE - count, | 1184 | count += scnprintf(buf + count, PAGE_SIZE - count, |
959 | "T%u:\n", object->type); | 1185 | "T%u:\n", object->type); |
960 | 1186 | ||
961 | for (j = 0; j < object->instances + 1; j++) { | 1187 | for (j = 0; j < mxt_obj_instances(object); j++) { |
962 | u16 size = object->size + 1; | 1188 | u16 size = mxt_obj_size(object); |
963 | u16 addr = object->start_address + j * size; | 1189 | u16 addr = object->start_address + j * size; |
964 | 1190 | ||
965 | error = __mxt_read_reg(data->client, addr, size, obuf); | 1191 | error = __mxt_read_reg(data->client, addr, size, obuf); |
@@ -975,13 +1201,38 @@ done: | |||
975 | return error ?: count; | 1201 | return error ?: count; |
976 | } | 1202 | } |
977 | 1203 | ||
1204 | static int mxt_check_firmware_format(struct device *dev, | ||
1205 | const struct firmware *fw) | ||
1206 | { | ||
1207 | unsigned int pos = 0; | ||
1208 | char c; | ||
1209 | |||
1210 | while (pos < fw->size) { | ||
1211 | c = *(fw->data + pos); | ||
1212 | |||
1213 | if (c < '0' || (c > '9' && c < 'A') || c > 'F') | ||
1214 | return 0; | ||
1215 | |||
1216 | pos++; | ||
1217 | } | ||
1218 | |||
1219 | /* | ||
1220 | * To convert file try: | ||
1221 | * xxd -r -p mXTXXX__APP_VX-X-XX.enc > maxtouch.fw | ||
1222 | */ | ||
1223 | dev_err(dev, "Aborting: firmware file must be in binary format\n"); | ||
1224 | |||
1225 | return -EINVAL; | ||
1226 | } | ||
1227 | |||
978 | static int mxt_load_fw(struct device *dev, const char *fn) | 1228 | static int mxt_load_fw(struct device *dev, const char *fn) |
979 | { | 1229 | { |
980 | struct mxt_data *data = dev_get_drvdata(dev); | 1230 | struct mxt_data *data = dev_get_drvdata(dev); |
981 | struct i2c_client *client = data->client; | ||
982 | const struct firmware *fw = NULL; | 1231 | const struct firmware *fw = NULL; |
983 | unsigned int frame_size; | 1232 | unsigned int frame_size; |
984 | unsigned int pos = 0; | 1233 | unsigned int pos = 0; |
1234 | unsigned int retry = 0; | ||
1235 | unsigned int frame = 0; | ||
985 | int ret; | 1236 | int ret; |
986 | 1237 | ||
987 | ret = request_firmware(&fw, fn, dev); | 1238 | ret = request_firmware(&fw, fn, dev); |
@@ -990,59 +1241,91 @@ static int mxt_load_fw(struct device *dev, const char *fn) | |||
990 | return ret; | 1241 | return ret; |
991 | } | 1242 | } |
992 | 1243 | ||
1244 | /* Check for incorrect enc file */ | ||
1245 | ret = mxt_check_firmware_format(dev, fw); | ||
1246 | if (ret) | ||
1247 | goto release_firmware; | ||
1248 | |||
1249 | ret = mxt_lookup_bootloader_address(data); | ||
1250 | if (ret) | ||
1251 | goto release_firmware; | ||
1252 | |||
993 | /* Change to the bootloader mode */ | 1253 | /* Change to the bootloader mode */ |
994 | mxt_write_object(data, MXT_GEN_COMMAND_T6, | 1254 | data->in_bootloader = true; |
995 | MXT_COMMAND_RESET, MXT_BOOT_VALUE); | 1255 | |
1256 | ret = mxt_t6_command(data, MXT_COMMAND_RESET, MXT_BOOT_VALUE, false); | ||
1257 | if (ret) | ||
1258 | goto release_firmware; | ||
1259 | |||
996 | msleep(MXT_RESET_TIME); | 1260 | msleep(MXT_RESET_TIME); |
997 | 1261 | ||
998 | /* Change to slave address of bootloader */ | 1262 | reinit_completion(&data->bl_completion); |
999 | if (client->addr == MXT_APP_LOW) | ||
1000 | client->addr = MXT_BOOT_LOW; | ||
1001 | else | ||
1002 | client->addr = MXT_BOOT_HIGH; | ||
1003 | 1263 | ||
1004 | ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD); | 1264 | ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD); |
1005 | if (ret) | 1265 | if (ret) |
1006 | goto out; | 1266 | goto disable_irq; |
1007 | 1267 | ||
1008 | /* Unlock bootloader */ | 1268 | /* Unlock bootloader */ |
1009 | mxt_unlock_bootloader(client); | 1269 | mxt_unlock_bootloader(data); |
1010 | 1270 | ||
1011 | while (pos < fw->size) { | 1271 | while (pos < fw->size) { |
1012 | ret = mxt_check_bootloader(client, | 1272 | ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA); |
1013 | MXT_WAITING_FRAME_DATA); | ||
1014 | if (ret) | 1273 | if (ret) |
1015 | goto out; | 1274 | goto disable_irq; |
1016 | 1275 | ||
1017 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); | 1276 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); |
1018 | 1277 | ||
1019 | /* We should add 2 at frame size as the the firmware data is not | 1278 | /* Take account of CRC bytes */ |
1020 | * included the CRC bytes. | ||
1021 | */ | ||
1022 | frame_size += 2; | 1279 | frame_size += 2; |
1023 | 1280 | ||
1024 | /* Write one frame to device */ | 1281 | /* Write one frame to device */ |
1025 | mxt_fw_write(client, fw->data + pos, frame_size); | 1282 | ret = mxt_bootloader_write(data, fw->data + pos, frame_size); |
1026 | |||
1027 | ret = mxt_check_bootloader(client, | ||
1028 | MXT_FRAME_CRC_PASS); | ||
1029 | if (ret) | 1283 | if (ret) |
1030 | goto out; | 1284 | goto disable_irq; |
1031 | 1285 | ||
1032 | pos += frame_size; | 1286 | ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS); |
1287 | if (ret) { | ||
1288 | retry++; | ||
1033 | 1289 | ||
1034 | dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); | 1290 | /* Back off by 20ms per retry */ |
1291 | msleep(retry * 20); | ||
1292 | |||
1293 | if (retry > 20) { | ||
1294 | dev_err(dev, "Retry count exceeded\n"); | ||
1295 | goto disable_irq; | ||
1296 | } | ||
1297 | } else { | ||
1298 | retry = 0; | ||
1299 | pos += frame_size; | ||
1300 | frame++; | ||
1301 | } | ||
1302 | |||
1303 | if (frame % 50 == 0) | ||
1304 | dev_dbg(dev, "Sent %d frames, %d/%zd bytes\n", | ||
1305 | frame, pos, fw->size); | ||
1035 | } | 1306 | } |
1036 | 1307 | ||
1037 | out: | 1308 | /* Wait for flash. */ |
1038 | release_firmware(fw); | 1309 | ret = mxt_wait_for_completion(data, &data->bl_completion, |
1310 | MXT_FW_RESET_TIME); | ||
1311 | if (ret) | ||
1312 | goto disable_irq; | ||
1039 | 1313 | ||
1040 | /* Change to slave address of application */ | 1314 | dev_dbg(dev, "Sent %d frames, %d bytes\n", frame, pos); |
1041 | if (client->addr == MXT_BOOT_LOW) | ||
1042 | client->addr = MXT_APP_LOW; | ||
1043 | else | ||
1044 | client->addr = MXT_APP_HIGH; | ||
1045 | 1315 | ||
1316 | /* | ||
1317 | * Wait for device to reset. Some bootloader versions do not assert | ||
1318 | * the CHG line after bootloading has finished, so ignore potential | ||
1319 | * errors. | ||
1320 | */ | ||
1321 | mxt_wait_for_completion(data, &data->bl_completion, MXT_FW_RESET_TIME); | ||
1322 | |||
1323 | data->in_bootloader = false; | ||
1324 | |||
1325 | disable_irq: | ||
1326 | disable_irq(data->irq); | ||
1327 | release_firmware: | ||
1328 | release_firmware(fw); | ||
1046 | return ret; | 1329 | return ret; |
1047 | } | 1330 | } |
1048 | 1331 | ||
@@ -1053,28 +1336,23 @@ static ssize_t mxt_update_fw_store(struct device *dev, | |||
1053 | struct mxt_data *data = dev_get_drvdata(dev); | 1336 | struct mxt_data *data = dev_get_drvdata(dev); |
1054 | int error; | 1337 | int error; |
1055 | 1338 | ||
1056 | disable_irq(data->irq); | ||
1057 | |||
1058 | error = mxt_load_fw(dev, MXT_FW_NAME); | 1339 | error = mxt_load_fw(dev, MXT_FW_NAME); |
1059 | if (error) { | 1340 | if (error) { |
1060 | dev_err(dev, "The firmware update failed(%d)\n", error); | 1341 | dev_err(dev, "The firmware update failed(%d)\n", error); |
1061 | count = error; | 1342 | count = error; |
1062 | } else { | 1343 | } else { |
1063 | dev_dbg(dev, "The firmware update succeeded\n"); | 1344 | dev_info(dev, "The firmware update succeeded\n"); |
1064 | |||
1065 | /* Wait for reset */ | ||
1066 | msleep(MXT_FWRESET_TIME); | ||
1067 | 1345 | ||
1068 | mxt_free_object_table(data); | 1346 | mxt_free_object_table(data); |
1069 | 1347 | ||
1070 | mxt_initialize(data); | 1348 | mxt_initialize(data); |
1071 | } | ||
1072 | 1349 | ||
1073 | enable_irq(data->irq); | 1350 | enable_irq(data->irq); |
1074 | 1351 | ||
1075 | error = mxt_make_highchg(data); | 1352 | error = mxt_make_highchg(data); |
1076 | if (error) | 1353 | if (error) |
1077 | return error; | 1354 | return error; |
1355 | } | ||
1078 | 1356 | ||
1079 | return count; | 1357 | return count; |
1080 | } | 1358 | } |
@@ -1134,6 +1412,8 @@ static int mxt_probe(struct i2c_client *client, | |||
1134 | struct input_dev *input_dev; | 1412 | struct input_dev *input_dev; |
1135 | int error; | 1413 | int error; |
1136 | unsigned int num_mt_slots; | 1414 | unsigned int num_mt_slots; |
1415 | unsigned int mt_flags = 0; | ||
1416 | int i; | ||
1137 | 1417 | ||
1138 | if (!pdata) | 1418 | if (!pdata) |
1139 | return -EINVAL; | 1419 | return -EINVAL; |
@@ -1146,10 +1426,7 @@ static int mxt_probe(struct i2c_client *client, | |||
1146 | goto err_free_mem; | 1426 | goto err_free_mem; |
1147 | } | 1427 | } |
1148 | 1428 | ||
1149 | data->is_tp = pdata && pdata->is_tp; | 1429 | input_dev->name = "Atmel maXTouch Touchscreen"; |
1150 | |||
1151 | input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" : | ||
1152 | "Atmel maXTouch Touchscreen"; | ||
1153 | snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", | 1430 | snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", |
1154 | client->adapter->nr, client->addr); | 1431 | client->adapter->nr, client->addr); |
1155 | 1432 | ||
@@ -1165,7 +1442,9 @@ static int mxt_probe(struct i2c_client *client, | |||
1165 | data->pdata = pdata; | 1442 | data->pdata = pdata; |
1166 | data->irq = client->irq; | 1443 | data->irq = client->irq; |
1167 | 1444 | ||
1168 | mxt_calc_resolution(data); | 1445 | init_completion(&data->bl_completion); |
1446 | init_completion(&data->reset_completion); | ||
1447 | init_completion(&data->crc_completion); | ||
1169 | 1448 | ||
1170 | error = mxt_initialize(data); | 1449 | error = mxt_initialize(data); |
1171 | if (error) | 1450 | if (error) |
@@ -1175,20 +1454,15 @@ static int mxt_probe(struct i2c_client *client, | |||
1175 | __set_bit(EV_KEY, input_dev->evbit); | 1454 | __set_bit(EV_KEY, input_dev->evbit); |
1176 | __set_bit(BTN_TOUCH, input_dev->keybit); | 1455 | __set_bit(BTN_TOUCH, input_dev->keybit); |
1177 | 1456 | ||
1178 | if (data->is_tp) { | 1457 | if (pdata->t19_num_keys) { |
1179 | int i; | ||
1180 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
1181 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); | 1458 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); |
1182 | 1459 | ||
1183 | for (i = 0; i < MXT_NUM_GPIO; i++) | 1460 | for (i = 0; i < pdata->t19_num_keys; i++) |
1184 | if (pdata->key_map[i] != KEY_RESERVED) | 1461 | if (pdata->t19_keymap[i] != KEY_RESERVED) |
1185 | __set_bit(pdata->key_map[i], input_dev->keybit); | 1462 | input_set_capability(input_dev, EV_KEY, |
1463 | pdata->t19_keymap[i]); | ||
1186 | 1464 | ||
1187 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 1465 | mt_flags |= INPUT_MT_POINTER; |
1188 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1189 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
1190 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | ||
1191 | __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit); | ||
1192 | 1466 | ||
1193 | input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM); | 1467 | input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM); |
1194 | input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM); | 1468 | input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM); |
@@ -1196,6 +1470,8 @@ static int mxt_probe(struct i2c_client *client, | |||
1196 | MXT_PIXELS_PER_MM); | 1470 | MXT_PIXELS_PER_MM); |
1197 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, | 1471 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, |
1198 | MXT_PIXELS_PER_MM); | 1472 | MXT_PIXELS_PER_MM); |
1473 | |||
1474 | input_dev->name = "Atmel maXTouch Touchpad"; | ||
1199 | } | 1475 | } |
1200 | 1476 | ||
1201 | /* For single touch */ | 1477 | /* For single touch */ |
@@ -1208,7 +1484,7 @@ static int mxt_probe(struct i2c_client *client, | |||
1208 | 1484 | ||
1209 | /* For multi touch */ | 1485 | /* For multi touch */ |
1210 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; | 1486 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; |
1211 | error = input_mt_init_slots(input_dev, num_mt_slots, 0); | 1487 | error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags); |
1212 | if (error) | 1488 | if (error) |
1213 | goto err_free_object; | 1489 | goto err_free_object; |
1214 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 1490 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
@@ -1236,12 +1512,18 @@ static int mxt_probe(struct i2c_client *client, | |||
1236 | goto err_free_irq; | 1512 | goto err_free_irq; |
1237 | 1513 | ||
1238 | error = input_register_device(input_dev); | 1514 | error = input_register_device(input_dev); |
1239 | if (error) | 1515 | if (error) { |
1516 | dev_err(&client->dev, "Error %d registering input device\n", | ||
1517 | error); | ||
1240 | goto err_free_irq; | 1518 | goto err_free_irq; |
1519 | } | ||
1241 | 1520 | ||
1242 | error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); | 1521 | error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); |
1243 | if (error) | 1522 | if (error) { |
1523 | dev_err(&client->dev, "Failure %d creating sysfs group\n", | ||
1524 | error); | ||
1244 | goto err_unregister_device; | 1525 | goto err_unregister_device; |
1526 | } | ||
1245 | 1527 | ||
1246 | return 0; | 1528 | return 0; |
1247 | 1529 | ||
@@ -1294,11 +1576,7 @@ static int mxt_resume(struct device *dev) | |||
1294 | struct mxt_data *data = i2c_get_clientdata(client); | 1576 | struct mxt_data *data = i2c_get_clientdata(client); |
1295 | struct input_dev *input_dev = data->input_dev; | 1577 | struct input_dev *input_dev = data->input_dev; |
1296 | 1578 | ||
1297 | /* Soft reset */ | 1579 | mxt_soft_reset(data); |
1298 | mxt_write_object(data, MXT_GEN_COMMAND_T6, | ||
1299 | MXT_COMMAND_RESET, 1); | ||
1300 | |||
1301 | msleep(MXT_RESET_TIME); | ||
1302 | 1580 | ||
1303 | mutex_lock(&input_dev->mutex); | 1581 | mutex_lock(&input_dev->mutex); |
1304 | 1582 | ||
diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index d3f9f6b0f9b7..7f3c94787787 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c | |||
@@ -679,7 +679,7 @@ static const struct i2c_device_id auo_pixcir_idtable[] = { | |||
679 | MODULE_DEVICE_TABLE(i2c, auo_pixcir_idtable); | 679 | MODULE_DEVICE_TABLE(i2c, auo_pixcir_idtable); |
680 | 680 | ||
681 | #ifdef CONFIG_OF | 681 | #ifdef CONFIG_OF |
682 | static struct of_device_id auo_pixcir_ts_dt_idtable[] = { | 682 | static const struct of_device_id auo_pixcir_ts_dt_idtable[] = { |
683 | { .compatible = "auo,auo_pixcir_ts" }, | 683 | { .compatible = "auo,auo_pixcir_ts" }, |
684 | {}, | 684 | {}, |
685 | }; | 685 | }; |
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c index 8ccf7bb4028a..cf6f4b31db4d 100644 --- a/drivers/input/touchscreen/da9034-ts.c +++ b/drivers/input/touchscreen/da9034-ts.c | |||
@@ -301,10 +301,11 @@ static int da9034_touch_probe(struct platform_device *pdev) | |||
301 | struct da9034_touch_pdata *pdata = dev_get_platdata(&pdev->dev); | 301 | struct da9034_touch_pdata *pdata = dev_get_platdata(&pdev->dev); |
302 | struct da9034_touch *touch; | 302 | struct da9034_touch *touch; |
303 | struct input_dev *input_dev; | 303 | struct input_dev *input_dev; |
304 | int ret; | 304 | int error; |
305 | 305 | ||
306 | touch = kzalloc(sizeof(struct da9034_touch), GFP_KERNEL); | 306 | touch = devm_kzalloc(&pdev->dev, sizeof(struct da9034_touch), |
307 | if (touch == NULL) { | 307 | GFP_KERNEL); |
308 | if (!touch) { | ||
308 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | 309 | dev_err(&pdev->dev, "failed to allocate driver data\n"); |
309 | return -ENOMEM; | 310 | return -ENOMEM; |
310 | } | 311 | } |
@@ -315,18 +316,18 @@ static int da9034_touch_probe(struct platform_device *pdev) | |||
315 | touch->interval_ms = pdata->interval_ms; | 316 | touch->interval_ms = pdata->interval_ms; |
316 | touch->x_inverted = pdata->x_inverted; | 317 | touch->x_inverted = pdata->x_inverted; |
317 | touch->y_inverted = pdata->y_inverted; | 318 | touch->y_inverted = pdata->y_inverted; |
318 | } else | 319 | } else { |
319 | /* fallback into default */ | 320 | /* fallback into default */ |
320 | touch->interval_ms = 10; | 321 | touch->interval_ms = 10; |
322 | } | ||
321 | 323 | ||
322 | INIT_DELAYED_WORK(&touch->tsi_work, da9034_tsi_work); | 324 | INIT_DELAYED_WORK(&touch->tsi_work, da9034_tsi_work); |
323 | touch->notifier.notifier_call = da9034_touch_notifier; | 325 | touch->notifier.notifier_call = da9034_touch_notifier; |
324 | 326 | ||
325 | input_dev = input_allocate_device(); | 327 | input_dev = devm_input_allocate_device(&pdev->dev); |
326 | if (!input_dev) { | 328 | if (!input_dev) { |
327 | dev_err(&pdev->dev, "failed to allocate input device\n"); | 329 | dev_err(&pdev->dev, "failed to allocate input device\n"); |
328 | ret = -ENOMEM; | 330 | return -ENOMEM; |
329 | goto err_free_touch; | ||
330 | } | 331 | } |
331 | 332 | ||
332 | input_dev->name = pdev->name; | 333 | input_dev->name = pdev->name; |
@@ -346,26 +347,9 @@ static int da9034_touch_probe(struct platform_device *pdev) | |||
346 | touch->input_dev = input_dev; | 347 | touch->input_dev = input_dev; |
347 | input_set_drvdata(input_dev, touch); | 348 | input_set_drvdata(input_dev, touch); |
348 | 349 | ||
349 | ret = input_register_device(input_dev); | 350 | error = input_register_device(input_dev); |
350 | if (ret) | 351 | if (error) |
351 | goto err_free_input; | 352 | return error; |
352 | |||
353 | platform_set_drvdata(pdev, touch); | ||
354 | return 0; | ||
355 | |||
356 | err_free_input: | ||
357 | input_free_device(input_dev); | ||
358 | err_free_touch: | ||
359 | kfree(touch); | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | static int da9034_touch_remove(struct platform_device *pdev) | ||
364 | { | ||
365 | struct da9034_touch *touch = platform_get_drvdata(pdev); | ||
366 | |||
367 | input_unregister_device(touch->input_dev); | ||
368 | kfree(touch); | ||
369 | 353 | ||
370 | return 0; | 354 | return 0; |
371 | } | 355 | } |
@@ -376,7 +360,6 @@ static struct platform_driver da9034_touch_driver = { | |||
376 | .owner = THIS_MODULE, | 360 | .owner = THIS_MODULE, |
377 | }, | 361 | }, |
378 | .probe = da9034_touch_probe, | 362 | .probe = da9034_touch_probe, |
379 | .remove = da9034_touch_remove, | ||
380 | }; | 363 | }; |
381 | module_platform_driver(da9034_touch_driver); | 364 | module_platform_driver(da9034_touch_driver); |
382 | 365 | ||
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index f8815bebc9ef..d4f33992ad8c 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -271,7 +271,7 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata, | |||
271 | wrbuf[0] = addr; | 271 | wrbuf[0] = addr; |
272 | wrbuf[1] = value; | 272 | wrbuf[1] = value; |
273 | 273 | ||
274 | return edt_ft5x06_ts_readwrite(tsdata->client, 3, | 274 | return edt_ft5x06_ts_readwrite(tsdata->client, 2, |
275 | wrbuf, 0, NULL); | 275 | wrbuf, 0, NULL); |
276 | 276 | ||
277 | default: | 277 | default: |
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index e6bcb13680b2..c8057847d71d 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c | |||
@@ -262,7 +262,7 @@ static int egalax_ts_resume(struct device *dev) | |||
262 | 262 | ||
263 | static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); | 263 | static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); |
264 | 264 | ||
265 | static struct of_device_id egalax_ts_dt_ids[] = { | 265 | static const struct of_device_id egalax_ts_dt_ids[] = { |
266 | { .compatible = "eeti,egalax_ts" }, | 266 | { .compatible = "eeti,egalax_ts" }, |
267 | { /* sentinel */ } | 267 | { /* sentinel */ } |
268 | }; | 268 | }; |
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c index 4f6b156144e9..c38ca4a7e386 100644 --- a/drivers/input/touchscreen/intel-mid-touch.c +++ b/drivers/input/touchscreen/intel-mid-touch.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <asm/intel_scu_ipc.h> | 38 | #include <asm/intel_scu_ipc.h> |
39 | #include <linux/device.h> | ||
39 | 40 | ||
40 | /* PMIC Interrupt registers */ | 41 | /* PMIC Interrupt registers */ |
41 | #define PMIC_REG_ID1 0x00 /* PMIC ID1 register */ | 42 | #define PMIC_REG_ID1 0x00 /* PMIC ID1 register */ |
@@ -580,12 +581,17 @@ static int mrstouch_probe(struct platform_device *pdev) | |||
580 | return -EINVAL; | 581 | return -EINVAL; |
581 | } | 582 | } |
582 | 583 | ||
583 | tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL); | 584 | tsdev = devm_kzalloc(&pdev->dev, sizeof(struct mrstouch_dev), |
584 | input = input_allocate_device(); | 585 | GFP_KERNEL); |
585 | if (!tsdev || !input) { | 586 | if (!tsdev) { |
586 | dev_err(&pdev->dev, "unable to allocate memory\n"); | 587 | dev_err(&pdev->dev, "unable to allocate memory\n"); |
587 | err = -ENOMEM; | 588 | return -ENOMEM; |
588 | goto err_free_mem; | 589 | } |
590 | |||
591 | input = devm_input_allocate_device(&pdev->dev); | ||
592 | if (!input) { | ||
593 | dev_err(&pdev->dev, "unable to allocate input device\n"); | ||
594 | return -ENOMEM; | ||
589 | } | 595 | } |
590 | 596 | ||
591 | tsdev->dev = &pdev->dev; | 597 | tsdev->dev = &pdev->dev; |
@@ -598,7 +604,7 @@ static int mrstouch_probe(struct platform_device *pdev) | |||
598 | err = mrstouch_adc_init(tsdev); | 604 | err = mrstouch_adc_init(tsdev); |
599 | if (err) { | 605 | if (err) { |
600 | dev_err(&pdev->dev, "ADC initialization failed\n"); | 606 | dev_err(&pdev->dev, "ADC initialization failed\n"); |
601 | goto err_free_mem; | 607 | return err; |
602 | } | 608 | } |
603 | 609 | ||
604 | input->name = "mrst_touchscreen"; | 610 | input->name = "mrst_touchscreen"; |
@@ -618,38 +624,20 @@ static int mrstouch_probe(struct platform_device *pdev) | |||
618 | input_set_abs_params(tsdev->input, ABS_PRESSURE, | 624 | input_set_abs_params(tsdev->input, ABS_PRESSURE, |
619 | MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); | 625 | MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); |
620 | 626 | ||
621 | err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq, | 627 | err = devm_request_threaded_irq(&pdev->dev, tsdev->irq, NULL, |
622 | IRQF_ONESHOT, "mrstouch", tsdev); | 628 | mrstouch_pendet_irq, IRQF_ONESHOT, |
629 | "mrstouch", tsdev); | ||
623 | if (err) { | 630 | if (err) { |
624 | dev_err(tsdev->dev, "unable to allocate irq\n"); | 631 | dev_err(tsdev->dev, "unable to allocate irq\n"); |
625 | goto err_free_mem; | 632 | return err; |
626 | } | 633 | } |
627 | 634 | ||
628 | err = input_register_device(tsdev->input); | 635 | err = input_register_device(tsdev->input); |
629 | if (err) { | 636 | if (err) { |
630 | dev_err(tsdev->dev, "unable to register input device\n"); | 637 | dev_err(tsdev->dev, "unable to register input device\n"); |
631 | goto err_free_irq; | 638 | return err; |
632 | } | 639 | } |
633 | 640 | ||
634 | platform_set_drvdata(pdev, tsdev); | ||
635 | return 0; | ||
636 | |||
637 | err_free_irq: | ||
638 | free_irq(tsdev->irq, tsdev); | ||
639 | err_free_mem: | ||
640 | input_free_device(input); | ||
641 | kfree(tsdev); | ||
642 | return err; | ||
643 | } | ||
644 | |||
645 | static int mrstouch_remove(struct platform_device *pdev) | ||
646 | { | ||
647 | struct mrstouch_dev *tsdev = platform_get_drvdata(pdev); | ||
648 | |||
649 | free_irq(tsdev->irq, tsdev); | ||
650 | input_unregister_device(tsdev->input); | ||
651 | kfree(tsdev); | ||
652 | |||
653 | return 0; | 641 | return 0; |
654 | } | 642 | } |
655 | 643 | ||
@@ -659,7 +647,6 @@ static struct platform_driver mrstouch_driver = { | |||
659 | .owner = THIS_MODULE, | 647 | .owner = THIS_MODULE, |
660 | }, | 648 | }, |
661 | .probe = mrstouch_probe, | 649 | .probe = mrstouch_probe, |
662 | .remove = mrstouch_remove, | ||
663 | }; | 650 | }; |
664 | module_platform_driver(mrstouch_driver); | 651 | module_platform_driver(mrstouch_driver); |
665 | 652 | ||
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c index 2058253b55d9..bb47d3442a35 100644 --- a/drivers/input/touchscreen/lpc32xx_ts.c +++ b/drivers/input/touchscreen/lpc32xx_ts.c | |||
@@ -384,7 +384,7 @@ static const struct dev_pm_ops lpc32xx_ts_pm_ops = { | |||
384 | #endif | 384 | #endif |
385 | 385 | ||
386 | #ifdef CONFIG_OF | 386 | #ifdef CONFIG_OF |
387 | static struct of_device_id lpc32xx_tsc_of_match[] = { | 387 | static const struct of_device_id lpc32xx_tsc_of_match[] = { |
388 | { .compatible = "nxp,lpc3220-tsc", }, | 388 | { .compatible = "nxp,lpc3220-tsc", }, |
389 | { }, | 389 | { }, |
390 | }; | 390 | }; |
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 647e36f5930e..00510a9836b3 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c | |||
@@ -161,10 +161,9 @@ static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id) | |||
161 | return IRQ_HANDLED; | 161 | return IRQ_HANDLED; |
162 | } | 162 | } |
163 | 163 | ||
164 | static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) | 164 | static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data, |
165 | const struct mcs_platform_data *platform_data) | ||
165 | { | 166 | { |
166 | const struct mcs_platform_data *platform_data = | ||
167 | data->platform_data; | ||
168 | struct i2c_client *client = data->client; | 167 | struct i2c_client *client = data->client; |
169 | 168 | ||
170 | /* Touch reset & sleep mode */ | 169 | /* Touch reset & sleep mode */ |
@@ -187,28 +186,32 @@ static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) | |||
187 | } | 186 | } |
188 | 187 | ||
189 | static int mcs5000_ts_probe(struct i2c_client *client, | 188 | static int mcs5000_ts_probe(struct i2c_client *client, |
190 | const struct i2c_device_id *id) | 189 | const struct i2c_device_id *id) |
191 | { | 190 | { |
191 | const struct mcs_platform_data *pdata; | ||
192 | struct mcs5000_ts_data *data; | 192 | struct mcs5000_ts_data *data; |
193 | struct input_dev *input_dev; | 193 | struct input_dev *input_dev; |
194 | int ret; | 194 | int error; |
195 | 195 | ||
196 | if (!dev_get_platdata(&client->dev)) | 196 | pdata = dev_get_platdata(&client->dev); |
197 | if (!pdata) | ||
197 | return -EINVAL; | 198 | return -EINVAL; |
198 | 199 | ||
199 | data = kzalloc(sizeof(struct mcs5000_ts_data), GFP_KERNEL); | 200 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); |
200 | input_dev = input_allocate_device(); | 201 | if (!data) { |
201 | if (!data || !input_dev) { | ||
202 | dev_err(&client->dev, "Failed to allocate memory\n"); | 202 | dev_err(&client->dev, "Failed to allocate memory\n"); |
203 | ret = -ENOMEM; | 203 | return -ENOMEM; |
204 | goto err_free_mem; | ||
205 | } | 204 | } |
206 | 205 | ||
207 | data->client = client; | 206 | data->client = client; |
208 | data->input_dev = input_dev; | ||
209 | data->platform_data = dev_get_platdata(&client->dev); | ||
210 | 207 | ||
211 | input_dev->name = "MELPAS MCS-5000 Touchscreen"; | 208 | input_dev = devm_input_allocate_device(&client->dev); |
209 | if (!input_dev) { | ||
210 | dev_err(&client->dev, "Failed to allocate input device\n"); | ||
211 | return -ENOMEM; | ||
212 | } | ||
213 | |||
214 | input_dev->name = "MELFAS MCS-5000 Touchscreen"; | ||
212 | input_dev->id.bustype = BUS_I2C; | 215 | input_dev->id.bustype = BUS_I2C; |
213 | input_dev->dev.parent = &client->dev; | 216 | input_dev->dev.parent = &client->dev; |
214 | 217 | ||
@@ -219,44 +222,30 @@ static int mcs5000_ts_probe(struct i2c_client *client, | |||
219 | input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0); | 222 | input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0); |
220 | 223 | ||
221 | input_set_drvdata(input_dev, data); | 224 | input_set_drvdata(input_dev, data); |
225 | data->input_dev = input_dev; | ||
222 | 226 | ||
223 | if (data->platform_data->cfg_pin) | 227 | if (pdata->cfg_pin) |
224 | data->platform_data->cfg_pin(); | 228 | pdata->cfg_pin(); |
225 | |||
226 | ret = request_threaded_irq(client->irq, NULL, mcs5000_ts_interrupt, | ||
227 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, "mcs5000_ts", data); | ||
228 | 229 | ||
229 | if (ret < 0) { | 230 | error = devm_request_threaded_irq(&client->dev, client->irq, |
231 | NULL, mcs5000_ts_interrupt, | ||
232 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
233 | "mcs5000_ts", data); | ||
234 | if (error) { | ||
230 | dev_err(&client->dev, "Failed to register interrupt\n"); | 235 | dev_err(&client->dev, "Failed to register interrupt\n"); |
231 | goto err_free_mem; | 236 | return error; |
232 | } | 237 | } |
233 | 238 | ||
234 | ret = input_register_device(data->input_dev); | 239 | error = input_register_device(data->input_dev); |
235 | if (ret < 0) | 240 | if (error) { |
236 | goto err_free_irq; | 241 | dev_err(&client->dev, "Failed to register input device\n"); |
242 | return error; | ||
243 | } | ||
237 | 244 | ||
238 | mcs5000_ts_phys_init(data); | 245 | mcs5000_ts_phys_init(data, pdata); |
239 | i2c_set_clientdata(client, data); | 246 | i2c_set_clientdata(client, data); |
240 | 247 | ||
241 | return 0; | 248 | return 0; |
242 | |||
243 | err_free_irq: | ||
244 | free_irq(client->irq, data); | ||
245 | err_free_mem: | ||
246 | input_free_device(input_dev); | ||
247 | kfree(data); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static int mcs5000_ts_remove(struct i2c_client *client) | ||
252 | { | ||
253 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | ||
254 | |||
255 | free_irq(client->irq, data); | ||
256 | input_unregister_device(data->input_dev); | ||
257 | kfree(data); | ||
258 | |||
259 | return 0; | ||
260 | } | 249 | } |
261 | 250 | ||
262 | #ifdef CONFIG_PM | 251 | #ifdef CONFIG_PM |
@@ -274,14 +263,15 @@ static int mcs5000_ts_resume(struct device *dev) | |||
274 | { | 263 | { |
275 | struct i2c_client *client = to_i2c_client(dev); | 264 | struct i2c_client *client = to_i2c_client(dev); |
276 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | 265 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); |
266 | const struct mcs_platform_data *pdata = dev_get_platdata(dev); | ||
277 | 267 | ||
278 | mcs5000_ts_phys_init(data); | 268 | mcs5000_ts_phys_init(data, pdata); |
279 | 269 | ||
280 | return 0; | 270 | return 0; |
281 | } | 271 | } |
272 | #endif | ||
282 | 273 | ||
283 | static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume); | 274 | static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume); |
284 | #endif | ||
285 | 275 | ||
286 | static const struct i2c_device_id mcs5000_ts_id[] = { | 276 | static const struct i2c_device_id mcs5000_ts_id[] = { |
287 | { "mcs5000_ts", 0 }, | 277 | { "mcs5000_ts", 0 }, |
@@ -291,12 +281,9 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); | |||
291 | 281 | ||
292 | static struct i2c_driver mcs5000_ts_driver = { | 282 | static struct i2c_driver mcs5000_ts_driver = { |
293 | .probe = mcs5000_ts_probe, | 283 | .probe = mcs5000_ts_probe, |
294 | .remove = mcs5000_ts_remove, | ||
295 | .driver = { | 284 | .driver = { |
296 | .name = "mcs5000_ts", | 285 | .name = "mcs5000_ts", |
297 | #ifdef CONFIG_PM | ||
298 | .pm = &mcs5000_ts_pm, | 286 | .pm = &mcs5000_ts_pm, |
299 | #endif | ||
300 | }, | 287 | }, |
301 | .id_table = mcs5000_ts_id, | 288 | .id_table = mcs5000_ts_id, |
302 | }; | 289 | }; |
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 8a598c065391..372bbf7658fe 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c | |||
@@ -456,7 +456,7 @@ static int mms114_probe(struct i2c_client *client, | |||
456 | data->input_dev = input_dev; | 456 | data->input_dev = input_dev; |
457 | data->pdata = pdata; | 457 | data->pdata = pdata; |
458 | 458 | ||
459 | input_dev->name = "MELPAS MMS114 Touchscreen"; | 459 | input_dev->name = "MELFAS MMS114 Touchscreen"; |
460 | input_dev->id.bustype = BUS_I2C; | 460 | input_dev->id.bustype = BUS_I2C; |
461 | input_dev->dev.parent = &client->dev; | 461 | input_dev->dev.parent = &client->dev; |
462 | input_dev->open = mms114_input_open; | 462 | input_dev->open = mms114_input_open; |
@@ -570,7 +570,7 @@ static const struct i2c_device_id mms114_id[] = { | |||
570 | MODULE_DEVICE_TABLE(i2c, mms114_id); | 570 | MODULE_DEVICE_TABLE(i2c, mms114_id); |
571 | 571 | ||
572 | #ifdef CONFIG_OF | 572 | #ifdef CONFIG_OF |
573 | static struct of_device_id mms114_dt_match[] = { | 573 | static const struct of_device_id mms114_dt_match[] = { |
574 | { .compatible = "melfas,mms114" }, | 574 | { .compatible = "melfas,mms114" }, |
575 | { } | 575 | { } |
576 | }; | 576 | }; |
diff --git a/drivers/input/touchscreen/of_touchscreen.c b/drivers/input/touchscreen/of_touchscreen.c new file mode 100644 index 000000000000..f8f9b84230b1 --- /dev/null +++ b/drivers/input/touchscreen/of_touchscreen.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Generic DT helper functions for touchscreen devices | ||
3 | * | ||
4 | * Copyright (c) 2014 Sebastian Reichel <sre@kernel.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/of.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <linux/input/touchscreen.h> | ||
15 | |||
16 | /** | ||
17 | * touchscreen_parse_of_params - parse common touchscreen DT properties | ||
18 | * @dev: device that should be parsed | ||
19 | * | ||
20 | * This function parses common DT properties for touchscreens and setups the | ||
21 | * input device accordingly. The function keeps previously setuped default | ||
22 | * values if no value is specified via DT. | ||
23 | */ | ||
24 | void touchscreen_parse_of_params(struct input_dev *dev) | ||
25 | { | ||
26 | struct device_node *np = dev->dev.parent->of_node; | ||
27 | struct input_absinfo *absinfo; | ||
28 | |||
29 | input_alloc_absinfo(dev); | ||
30 | if (!dev->absinfo) | ||
31 | return; | ||
32 | |||
33 | absinfo = &dev->absinfo[ABS_X]; | ||
34 | of_property_read_u32(np, "touchscreen-size-x", &absinfo->maximum); | ||
35 | of_property_read_u32(np, "touchscreen-fuzz-x", &absinfo->fuzz); | ||
36 | |||
37 | absinfo = &dev->absinfo[ABS_Y]; | ||
38 | of_property_read_u32(np, "touchscreen-size-y", &absinfo->maximum); | ||
39 | of_property_read_u32(np, "touchscreen-fuzz-y", &absinfo->fuzz); | ||
40 | |||
41 | absinfo = &dev->absinfo[ABS_PRESSURE]; | ||
42 | of_property_read_u32(np, "touchscreen-max-pressure", &absinfo->maximum); | ||
43 | of_property_read_u32(np, "touchscreen-fuzz-pressure", &absinfo->fuzz); | ||
44 | } | ||
45 | EXPORT_SYMBOL(touchscreen_parse_of_params); | ||
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 02392d2061d6..19c6c0fdc94b 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c | |||
@@ -24,12 +24,13 @@ | |||
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
26 | #include <linux/input/pixcir_ts.h> | 26 | #include <linux/input/pixcir_ts.h> |
27 | #include <linux/gpio.h> | ||
27 | 28 | ||
28 | struct pixcir_i2c_ts_data { | 29 | struct pixcir_i2c_ts_data { |
29 | struct i2c_client *client; | 30 | struct i2c_client *client; |
30 | struct input_dev *input; | 31 | struct input_dev *input; |
31 | const struct pixcir_ts_platform_data *chip; | 32 | const struct pixcir_ts_platform_data *chip; |
32 | bool exiting; | 33 | bool running; |
33 | }; | 34 | }; |
34 | 35 | ||
35 | static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data) | 36 | static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data) |
@@ -87,11 +88,12 @@ static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data) | |||
87 | static irqreturn_t pixcir_ts_isr(int irq, void *dev_id) | 88 | static irqreturn_t pixcir_ts_isr(int irq, void *dev_id) |
88 | { | 89 | { |
89 | struct pixcir_i2c_ts_data *tsdata = dev_id; | 90 | struct pixcir_i2c_ts_data *tsdata = dev_id; |
91 | const struct pixcir_ts_platform_data *pdata = tsdata->chip; | ||
90 | 92 | ||
91 | while (!tsdata->exiting) { | 93 | while (tsdata->running) { |
92 | pixcir_ts_poscheck(tsdata); | 94 | pixcir_ts_poscheck(tsdata); |
93 | 95 | ||
94 | if (tsdata->chip->attb_read_val()) | 96 | if (gpio_get_value(pdata->gpio_attb)) |
95 | break; | 97 | break; |
96 | 98 | ||
97 | msleep(20); | 99 | msleep(20); |
@@ -100,25 +102,221 @@ static irqreturn_t pixcir_ts_isr(int irq, void *dev_id) | |||
100 | return IRQ_HANDLED; | 102 | return IRQ_HANDLED; |
101 | } | 103 | } |
102 | 104 | ||
105 | static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, | ||
106 | enum pixcir_power_mode mode) | ||
107 | { | ||
108 | struct device *dev = &ts->client->dev; | ||
109 | int ret; | ||
110 | |||
111 | ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE); | ||
112 | if (ret < 0) { | ||
113 | dev_err(dev, "%s: can't read reg 0x%x : %d\n", | ||
114 | __func__, PIXCIR_REG_POWER_MODE, ret); | ||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | ret &= ~PIXCIR_POWER_MODE_MASK; | ||
119 | ret |= mode; | ||
120 | |||
121 | /* Always AUTO_IDLE */ | ||
122 | ret |= PIXCIR_POWER_ALLOW_IDLE; | ||
123 | |||
124 | ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret); | ||
125 | if (ret < 0) { | ||
126 | dev_err(dev, "%s: can't write reg 0x%x : %d\n", | ||
127 | __func__, PIXCIR_REG_POWER_MODE, ret); | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * Set the interrupt mode for the device i.e. ATTB line behaviour | ||
136 | * | ||
137 | * @polarity : 1 for active high, 0 for active low. | ||
138 | */ | ||
139 | static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts, | ||
140 | enum pixcir_int_mode mode, bool polarity) | ||
141 | { | ||
142 | struct device *dev = &ts->client->dev; | ||
143 | int ret; | ||
144 | |||
145 | ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); | ||
146 | if (ret < 0) { | ||
147 | dev_err(dev, "%s: can't read reg 0x%x : %d\n", | ||
148 | __func__, PIXCIR_REG_INT_MODE, ret); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | ret &= ~PIXCIR_INT_MODE_MASK; | ||
153 | ret |= mode; | ||
154 | |||
155 | if (polarity) | ||
156 | ret |= PIXCIR_INT_POL_HIGH; | ||
157 | else | ||
158 | ret &= ~PIXCIR_INT_POL_HIGH; | ||
159 | |||
160 | ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); | ||
161 | if (ret < 0) { | ||
162 | dev_err(dev, "%s: can't write reg 0x%x : %d\n", | ||
163 | __func__, PIXCIR_REG_INT_MODE, ret); | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * Enable/disable interrupt generation | ||
172 | */ | ||
173 | static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable) | ||
174 | { | ||
175 | struct device *dev = &ts->client->dev; | ||
176 | int ret; | ||
177 | |||
178 | ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); | ||
179 | if (ret < 0) { | ||
180 | dev_err(dev, "%s: can't read reg 0x%x : %d\n", | ||
181 | __func__, PIXCIR_REG_INT_MODE, ret); | ||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | if (enable) | ||
186 | ret |= PIXCIR_INT_ENABLE; | ||
187 | else | ||
188 | ret &= ~PIXCIR_INT_ENABLE; | ||
189 | |||
190 | ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); | ||
191 | if (ret < 0) { | ||
192 | dev_err(dev, "%s: can't write reg 0x%x : %d\n", | ||
193 | __func__, PIXCIR_REG_INT_MODE, ret); | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static int pixcir_start(struct pixcir_i2c_ts_data *ts) | ||
201 | { | ||
202 | struct device *dev = &ts->client->dev; | ||
203 | int error; | ||
204 | |||
205 | /* LEVEL_TOUCH interrupt with active low polarity */ | ||
206 | error = pixcir_set_int_mode(ts, PIXCIR_INT_LEVEL_TOUCH, 0); | ||
207 | if (error) { | ||
208 | dev_err(dev, "Failed to set interrupt mode: %d\n", error); | ||
209 | return error; | ||
210 | } | ||
211 | |||
212 | ts->running = true; | ||
213 | mb(); /* Update status before IRQ can fire */ | ||
214 | |||
215 | /* enable interrupt generation */ | ||
216 | error = pixcir_int_enable(ts, true); | ||
217 | if (error) { | ||
218 | dev_err(dev, "Failed to enable interrupt generation: %d\n", | ||
219 | error); | ||
220 | return error; | ||
221 | } | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int pixcir_stop(struct pixcir_i2c_ts_data *ts) | ||
227 | { | ||
228 | int error; | ||
229 | |||
230 | /* Disable interrupt generation */ | ||
231 | error = pixcir_int_enable(ts, false); | ||
232 | if (error) { | ||
233 | dev_err(&ts->client->dev, | ||
234 | "Failed to disable interrupt generation: %d\n", | ||
235 | error); | ||
236 | return error; | ||
237 | } | ||
238 | |||
239 | /* Exit ISR if running, no more report parsing */ | ||
240 | ts->running = false; | ||
241 | mb(); /* update status before we synchronize irq */ | ||
242 | |||
243 | /* Wait till running ISR is complete */ | ||
244 | synchronize_irq(ts->client->irq); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int pixcir_input_open(struct input_dev *dev) | ||
250 | { | ||
251 | struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev); | ||
252 | |||
253 | return pixcir_start(ts); | ||
254 | } | ||
255 | |||
256 | static void pixcir_input_close(struct input_dev *dev) | ||
257 | { | ||
258 | struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev); | ||
259 | |||
260 | pixcir_stop(ts); | ||
261 | } | ||
262 | |||
103 | #ifdef CONFIG_PM_SLEEP | 263 | #ifdef CONFIG_PM_SLEEP |
104 | static int pixcir_i2c_ts_suspend(struct device *dev) | 264 | static int pixcir_i2c_ts_suspend(struct device *dev) |
105 | { | 265 | { |
106 | struct i2c_client *client = to_i2c_client(dev); | 266 | struct i2c_client *client = to_i2c_client(dev); |
267 | struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); | ||
268 | struct input_dev *input = ts->input; | ||
269 | int ret = 0; | ||
270 | |||
271 | mutex_lock(&input->mutex); | ||
272 | |||
273 | if (device_may_wakeup(&client->dev)) { | ||
274 | if (!input->users) { | ||
275 | ret = pixcir_start(ts); | ||
276 | if (ret) { | ||
277 | dev_err(dev, "Failed to start\n"); | ||
278 | goto unlock; | ||
279 | } | ||
280 | } | ||
107 | 281 | ||
108 | if (device_may_wakeup(&client->dev)) | ||
109 | enable_irq_wake(client->irq); | 282 | enable_irq_wake(client->irq); |
283 | } else if (input->users) { | ||
284 | ret = pixcir_stop(ts); | ||
285 | } | ||
110 | 286 | ||
111 | return 0; | 287 | unlock: |
288 | mutex_unlock(&input->mutex); | ||
289 | |||
290 | return ret; | ||
112 | } | 291 | } |
113 | 292 | ||
114 | static int pixcir_i2c_ts_resume(struct device *dev) | 293 | static int pixcir_i2c_ts_resume(struct device *dev) |
115 | { | 294 | { |
116 | struct i2c_client *client = to_i2c_client(dev); | 295 | struct i2c_client *client = to_i2c_client(dev); |
296 | struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); | ||
297 | struct input_dev *input = ts->input; | ||
298 | int ret = 0; | ||
299 | |||
300 | mutex_lock(&input->mutex); | ||
117 | 301 | ||
118 | if (device_may_wakeup(&client->dev)) | 302 | if (device_may_wakeup(&client->dev)) { |
119 | disable_irq_wake(client->irq); | 303 | disable_irq_wake(client->irq); |
120 | 304 | ||
121 | return 0; | 305 | if (!input->users) { |
306 | ret = pixcir_stop(ts); | ||
307 | if (ret) { | ||
308 | dev_err(dev, "Failed to stop\n"); | ||
309 | goto unlock; | ||
310 | } | ||
311 | } | ||
312 | } else if (input->users) { | ||
313 | ret = pixcir_start(ts); | ||
314 | } | ||
315 | |||
316 | unlock: | ||
317 | mutex_unlock(&input->mutex); | ||
318 | |||
319 | return ret; | ||
122 | } | 320 | } |
123 | #endif | 321 | #endif |
124 | 322 | ||
@@ -130,6 +328,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, | |||
130 | { | 328 | { |
131 | const struct pixcir_ts_platform_data *pdata = | 329 | const struct pixcir_ts_platform_data *pdata = |
132 | dev_get_platdata(&client->dev); | 330 | dev_get_platdata(&client->dev); |
331 | struct device *dev = &client->dev; | ||
133 | struct pixcir_i2c_ts_data *tsdata; | 332 | struct pixcir_i2c_ts_data *tsdata; |
134 | struct input_dev *input; | 333 | struct input_dev *input; |
135 | int error; | 334 | int error; |
@@ -139,12 +338,19 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, | |||
139 | return -EINVAL; | 338 | return -EINVAL; |
140 | } | 339 | } |
141 | 340 | ||
142 | tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL); | 341 | if (!gpio_is_valid(pdata->gpio_attb)) { |
143 | input = input_allocate_device(); | 342 | dev_err(dev, "Invalid gpio_attb in pdata\n"); |
144 | if (!tsdata || !input) { | 343 | return -EINVAL; |
145 | dev_err(&client->dev, "Failed to allocate driver data!\n"); | 344 | } |
146 | error = -ENOMEM; | 345 | |
147 | goto err_free_mem; | 346 | tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL); |
347 | if (!tsdata) | ||
348 | return -ENOMEM; | ||
349 | |||
350 | input = devm_input_allocate_device(dev); | ||
351 | if (!input) { | ||
352 | dev_err(dev, "Failed to allocate input device\n"); | ||
353 | return -ENOMEM; | ||
148 | } | 354 | } |
149 | 355 | ||
150 | tsdata->client = client; | 356 | tsdata->client = client; |
@@ -153,6 +359,8 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, | |||
153 | 359 | ||
154 | input->name = client->name; | 360 | input->name = client->name; |
155 | input->id.bustype = BUS_I2C; | 361 | input->id.bustype = BUS_I2C; |
362 | input->open = pixcir_input_open; | ||
363 | input->close = pixcir_input_close; | ||
156 | input->dev.parent = &client->dev; | 364 | input->dev.parent = &client->dev; |
157 | 365 | ||
158 | __set_bit(EV_KEY, input->evbit); | 366 | __set_bit(EV_KEY, input->evbit); |
@@ -165,44 +373,47 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, | |||
165 | 373 | ||
166 | input_set_drvdata(input, tsdata); | 374 | input_set_drvdata(input, tsdata); |
167 | 375 | ||
168 | error = request_threaded_irq(client->irq, NULL, pixcir_ts_isr, | 376 | error = devm_gpio_request_one(dev, pdata->gpio_attb, |
169 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 377 | GPIOF_DIR_IN, "pixcir_i2c_attb"); |
170 | client->name, tsdata); | ||
171 | if (error) { | 378 | if (error) { |
172 | dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); | 379 | dev_err(dev, "Failed to request ATTB gpio\n"); |
173 | goto err_free_mem; | 380 | return error; |
174 | } | 381 | } |
175 | 382 | ||
383 | error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr, | ||
384 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
385 | client->name, tsdata); | ||
386 | if (error) { | ||
387 | dev_err(dev, "failed to request irq %d\n", client->irq); | ||
388 | return error; | ||
389 | } | ||
390 | |||
391 | /* Always be in IDLE mode to save power, device supports auto wake */ | ||
392 | error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE); | ||
393 | if (error) { | ||
394 | dev_err(dev, "Failed to set IDLE mode\n"); | ||
395 | return error; | ||
396 | } | ||
397 | |||
398 | /* Stop device till opened */ | ||
399 | error = pixcir_stop(tsdata); | ||
400 | if (error) | ||
401 | return error; | ||
402 | |||
176 | error = input_register_device(input); | 403 | error = input_register_device(input); |
177 | if (error) | 404 | if (error) |
178 | goto err_free_irq; | 405 | return error; |
179 | 406 | ||
180 | i2c_set_clientdata(client, tsdata); | 407 | i2c_set_clientdata(client, tsdata); |
181 | device_init_wakeup(&client->dev, 1); | 408 | device_init_wakeup(&client->dev, 1); |
182 | 409 | ||
183 | return 0; | 410 | return 0; |
184 | |||
185 | err_free_irq: | ||
186 | free_irq(client->irq, tsdata); | ||
187 | err_free_mem: | ||
188 | input_free_device(input); | ||
189 | kfree(tsdata); | ||
190 | return error; | ||
191 | } | 411 | } |
192 | 412 | ||
193 | static int pixcir_i2c_ts_remove(struct i2c_client *client) | 413 | static int pixcir_i2c_ts_remove(struct i2c_client *client) |
194 | { | 414 | { |
195 | struct pixcir_i2c_ts_data *tsdata = i2c_get_clientdata(client); | ||
196 | |||
197 | device_init_wakeup(&client->dev, 0); | 415 | device_init_wakeup(&client->dev, 0); |
198 | 416 | ||
199 | tsdata->exiting = true; | ||
200 | mb(); | ||
201 | free_irq(client->irq, tsdata); | ||
202 | |||
203 | input_unregister_device(tsdata->input); | ||
204 | kfree(tsdata); | ||
205 | |||
206 | return 0; | 417 | return 0; |
207 | } | 418 | } |
208 | 419 | ||
diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c new file mode 100644 index 000000000000..2ba826024954 --- /dev/null +++ b/drivers/input/touchscreen/sun4i-ts.c | |||
@@ -0,0 +1,339 @@ | |||
1 | /* | ||
2 | * Allwinner sunxi resistive touchscreen controller driver | ||
3 | * | ||
4 | * Copyright (C) 2013 - 2014 Hans de Goede <hdegoede@redhat.com> | ||
5 | * | ||
6 | * The hwmon parts are based on work by Corentin LABBE which is: | ||
7 | * Copyright (C) 2013 Corentin LABBE <clabbe.montjoie@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * The sun4i-ts controller is capable of detecting a second touch, but when a | ||
22 | * second touch is present then the accuracy becomes so bad the reported touch | ||
23 | * location is not useable. | ||
24 | * | ||
25 | * The original android driver contains some complicated heuristics using the | ||
26 | * aprox. distance between the 2 touches to see if the user is making a pinch | ||
27 | * open / close movement, and then reports emulated multi-touch events around | ||
28 | * the last touch coordinate (as the dual-touch coordinates are worthless). | ||
29 | * | ||
30 | * These kinds of heuristics are just asking for trouble (and don't belong | ||
31 | * in the kernel). So this driver offers straight forward, reliable single | ||
32 | * touch functionality only. | ||
33 | */ | ||
34 | |||
35 | #include <linux/err.h> | ||
36 | #include <linux/hwmon.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/input.h> | ||
39 | #include <linux/interrupt.h> | ||
40 | #include <linux/io.h> | ||
41 | #include <linux/module.h> | ||
42 | #include <linux/of_platform.h> | ||
43 | #include <linux/platform_device.h> | ||
44 | #include <linux/slab.h> | ||
45 | |||
46 | #define TP_CTRL0 0x00 | ||
47 | #define TP_CTRL1 0x04 | ||
48 | #define TP_CTRL2 0x08 | ||
49 | #define TP_CTRL3 0x0c | ||
50 | #define TP_INT_FIFOC 0x10 | ||
51 | #define TP_INT_FIFOS 0x14 | ||
52 | #define TP_TPR 0x18 | ||
53 | #define TP_CDAT 0x1c | ||
54 | #define TEMP_DATA 0x20 | ||
55 | #define TP_DATA 0x24 | ||
56 | |||
57 | /* TP_CTRL0 bits */ | ||
58 | #define ADC_FIRST_DLY(x) ((x) << 24) /* 8 bits */ | ||
59 | #define ADC_FIRST_DLY_MODE(x) ((x) << 23) | ||
60 | #define ADC_CLK_SEL(x) ((x) << 22) | ||
61 | #define ADC_CLK_DIV(x) ((x) << 20) /* 3 bits */ | ||
62 | #define FS_DIV(x) ((x) << 16) /* 4 bits */ | ||
63 | #define T_ACQ(x) ((x) << 0) /* 16 bits */ | ||
64 | |||
65 | /* TP_CTRL1 bits */ | ||
66 | #define STYLUS_UP_DEBOUN(x) ((x) << 12) /* 8 bits */ | ||
67 | #define STYLUS_UP_DEBOUN_EN(x) ((x) << 9) | ||
68 | #define TOUCH_PAN_CALI_EN(x) ((x) << 6) | ||
69 | #define TP_DUAL_EN(x) ((x) << 5) | ||
70 | #define TP_MODE_EN(x) ((x) << 4) | ||
71 | #define TP_ADC_SELECT(x) ((x) << 3) | ||
72 | #define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */ | ||
73 | |||
74 | /* TP_CTRL2 bits */ | ||
75 | #define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */ | ||
76 | #define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */ | ||
77 | #define PRE_MEA_EN(x) ((x) << 24) | ||
78 | #define PRE_MEA_THRE_CNT(x) ((x) << 0) /* 24 bits */ | ||
79 | |||
80 | /* TP_CTRL3 bits */ | ||
81 | #define FILTER_EN(x) ((x) << 2) | ||
82 | #define FILTER_TYPE(x) ((x) << 0) /* 2 bits */ | ||
83 | |||
84 | /* TP_INT_FIFOC irq and fifo mask / control bits */ | ||
85 | #define TEMP_IRQ_EN(x) ((x) << 18) | ||
86 | #define OVERRUN_IRQ_EN(x) ((x) << 17) | ||
87 | #define DATA_IRQ_EN(x) ((x) << 16) | ||
88 | #define TP_DATA_XY_CHANGE(x) ((x) << 13) | ||
89 | #define FIFO_TRIG(x) ((x) << 8) /* 5 bits */ | ||
90 | #define DATA_DRQ_EN(x) ((x) << 7) | ||
91 | #define FIFO_FLUSH(x) ((x) << 4) | ||
92 | #define TP_UP_IRQ_EN(x) ((x) << 1) | ||
93 | #define TP_DOWN_IRQ_EN(x) ((x) << 0) | ||
94 | |||
95 | /* TP_INT_FIFOS irq and fifo status bits */ | ||
96 | #define TEMP_DATA_PENDING BIT(18) | ||
97 | #define FIFO_OVERRUN_PENDING BIT(17) | ||
98 | #define FIFO_DATA_PENDING BIT(16) | ||
99 | #define TP_IDLE_FLG BIT(2) | ||
100 | #define TP_UP_PENDING BIT(1) | ||
101 | #define TP_DOWN_PENDING BIT(0) | ||
102 | |||
103 | /* TP_TPR bits */ | ||
104 | #define TEMP_ENABLE(x) ((x) << 16) | ||
105 | #define TEMP_PERIOD(x) ((x) << 0) /* t = x * 256 * 16 / clkin */ | ||
106 | |||
107 | struct sun4i_ts_data { | ||
108 | struct device *dev; | ||
109 | struct input_dev *input; | ||
110 | void __iomem *base; | ||
111 | unsigned int irq; | ||
112 | bool ignore_fifo_data; | ||
113 | int temp_data; | ||
114 | }; | ||
115 | |||
116 | static void sun4i_ts_irq_handle_input(struct sun4i_ts_data *ts, u32 reg_val) | ||
117 | { | ||
118 | u32 x, y; | ||
119 | |||
120 | if (reg_val & FIFO_DATA_PENDING) { | ||
121 | x = readl(ts->base + TP_DATA); | ||
122 | y = readl(ts->base + TP_DATA); | ||
123 | /* The 1st location reported after an up event is unreliable */ | ||
124 | if (!ts->ignore_fifo_data) { | ||
125 | input_report_abs(ts->input, ABS_X, x); | ||
126 | input_report_abs(ts->input, ABS_Y, y); | ||
127 | /* | ||
128 | * The hardware has a separate down status bit, but | ||
129 | * that gets set before we get the first location, | ||
130 | * resulting in reporting a click on the old location. | ||
131 | */ | ||
132 | input_report_key(ts->input, BTN_TOUCH, 1); | ||
133 | input_sync(ts->input); | ||
134 | } else { | ||
135 | ts->ignore_fifo_data = false; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | if (reg_val & TP_UP_PENDING) { | ||
140 | ts->ignore_fifo_data = true; | ||
141 | input_report_key(ts->input, BTN_TOUCH, 0); | ||
142 | input_sync(ts->input); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static irqreturn_t sun4i_ts_irq(int irq, void *dev_id) | ||
147 | { | ||
148 | struct sun4i_ts_data *ts = dev_id; | ||
149 | u32 reg_val; | ||
150 | |||
151 | reg_val = readl(ts->base + TP_INT_FIFOS); | ||
152 | |||
153 | if (reg_val & TEMP_DATA_PENDING) | ||
154 | ts->temp_data = readl(ts->base + TEMP_DATA); | ||
155 | |||
156 | if (ts->input) | ||
157 | sun4i_ts_irq_handle_input(ts, reg_val); | ||
158 | |||
159 | writel(reg_val, ts->base + TP_INT_FIFOS); | ||
160 | |||
161 | return IRQ_HANDLED; | ||
162 | } | ||
163 | |||
164 | static int sun4i_ts_open(struct input_dev *dev) | ||
165 | { | ||
166 | struct sun4i_ts_data *ts = input_get_drvdata(dev); | ||
167 | |||
168 | /* Flush, set trig level to 1, enable temp, data and up irqs */ | ||
169 | writel(TEMP_IRQ_EN(1) | DATA_IRQ_EN(1) | FIFO_TRIG(1) | FIFO_FLUSH(1) | | ||
170 | TP_UP_IRQ_EN(1), ts->base + TP_INT_FIFOC); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static void sun4i_ts_close(struct input_dev *dev) | ||
176 | { | ||
177 | struct sun4i_ts_data *ts = input_get_drvdata(dev); | ||
178 | |||
179 | /* Deactivate all input IRQs */ | ||
180 | writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); | ||
181 | } | ||
182 | |||
183 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
184 | char *buf) | ||
185 | { | ||
186 | struct sun4i_ts_data *ts = dev_get_drvdata(dev); | ||
187 | |||
188 | /* No temp_data until the first irq */ | ||
189 | if (ts->temp_data == -1) | ||
190 | return -EAGAIN; | ||
191 | |||
192 | return sprintf(buf, "%d\n", (ts->temp_data - 1447) * 100); | ||
193 | } | ||
194 | |||
195 | static ssize_t show_temp_label(struct device *dev, | ||
196 | struct device_attribute *devattr, char *buf) | ||
197 | { | ||
198 | return sprintf(buf, "SoC temperature\n"); | ||
199 | } | ||
200 | |||
201 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); | ||
202 | static DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL); | ||
203 | |||
204 | static struct attribute *sun4i_ts_attrs[] = { | ||
205 | &dev_attr_temp1_input.attr, | ||
206 | &dev_attr_temp1_label.attr, | ||
207 | NULL | ||
208 | }; | ||
209 | ATTRIBUTE_GROUPS(sun4i_ts); | ||
210 | |||
211 | static int sun4i_ts_probe(struct platform_device *pdev) | ||
212 | { | ||
213 | struct sun4i_ts_data *ts; | ||
214 | struct device *dev = &pdev->dev; | ||
215 | struct device_node *np = dev->of_node; | ||
216 | struct device *hwmon; | ||
217 | int error; | ||
218 | bool ts_attached; | ||
219 | |||
220 | ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); | ||
221 | if (!ts) | ||
222 | return -ENOMEM; | ||
223 | |||
224 | ts->dev = dev; | ||
225 | ts->ignore_fifo_data = true; | ||
226 | ts->temp_data = -1; | ||
227 | |||
228 | ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); | ||
229 | if (ts_attached) { | ||
230 | ts->input = devm_input_allocate_device(dev); | ||
231 | if (!ts->input) | ||
232 | return -ENOMEM; | ||
233 | |||
234 | ts->input->name = pdev->name; | ||
235 | ts->input->phys = "sun4i_ts/input0"; | ||
236 | ts->input->open = sun4i_ts_open; | ||
237 | ts->input->close = sun4i_ts_close; | ||
238 | ts->input->id.bustype = BUS_HOST; | ||
239 | ts->input->id.vendor = 0x0001; | ||
240 | ts->input->id.product = 0x0001; | ||
241 | ts->input->id.version = 0x0100; | ||
242 | ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); | ||
243 | __set_bit(BTN_TOUCH, ts->input->keybit); | ||
244 | input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); | ||
245 | input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); | ||
246 | input_set_drvdata(ts->input, ts); | ||
247 | } | ||
248 | |||
249 | ts->base = devm_ioremap_resource(dev, | ||
250 | platform_get_resource(pdev, IORESOURCE_MEM, 0)); | ||
251 | if (IS_ERR(ts->base)) | ||
252 | return PTR_ERR(ts->base); | ||
253 | |||
254 | ts->irq = platform_get_irq(pdev, 0); | ||
255 | error = devm_request_irq(dev, ts->irq, sun4i_ts_irq, 0, "sun4i-ts", ts); | ||
256 | if (error) | ||
257 | return error; | ||
258 | |||
259 | /* | ||
260 | * Select HOSC clk, clkin = clk / 6, adc samplefreq = clkin / 8192, | ||
261 | * t_acq = clkin / (16 * 64) | ||
262 | */ | ||
263 | writel(ADC_CLK_SEL(0) | ADC_CLK_DIV(2) | FS_DIV(7) | T_ACQ(63), | ||
264 | ts->base + TP_CTRL0); | ||
265 | |||
266 | /* | ||
267 | * sensitive_adjust = 15 : max, which is not all that sensitive, | ||
268 | * tp_mode = 0 : only x and y coordinates, as we don't use dual touch | ||
269 | */ | ||
270 | writel(TP_SENSITIVE_ADJUST(15) | TP_MODE_SELECT(0), | ||
271 | ts->base + TP_CTRL2); | ||
272 | |||
273 | /* Enable median filter, type 1 : 5/3 */ | ||
274 | writel(FILTER_EN(1) | FILTER_TYPE(1), ts->base + TP_CTRL3); | ||
275 | |||
276 | /* Enable temperature measurement, period 1953 (2 seconds) */ | ||
277 | writel(TEMP_ENABLE(1) | TEMP_PERIOD(1953), ts->base + TP_TPR); | ||
278 | |||
279 | /* | ||
280 | * Set stylus up debounce to aprox 10 ms, enable debounce, and | ||
281 | * finally enable tp mode. | ||
282 | */ | ||
283 | writel(STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1) | TP_MODE_EN(1), | ||
284 | ts->base + TP_CTRL1); | ||
285 | |||
286 | hwmon = devm_hwmon_device_register_with_groups(ts->dev, "sun4i_ts", | ||
287 | ts, sun4i_ts_groups); | ||
288 | if (IS_ERR(hwmon)) | ||
289 | return PTR_ERR(hwmon); | ||
290 | |||
291 | writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); | ||
292 | |||
293 | if (ts_attached) { | ||
294 | error = input_register_device(ts->input); | ||
295 | if (error) { | ||
296 | writel(0, ts->base + TP_INT_FIFOC); | ||
297 | return error; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | platform_set_drvdata(pdev, ts); | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static int sun4i_ts_remove(struct platform_device *pdev) | ||
306 | { | ||
307 | struct sun4i_ts_data *ts = platform_get_drvdata(pdev); | ||
308 | |||
309 | /* Explicit unregister to avoid open/close changing the imask later */ | ||
310 | if (ts->input) | ||
311 | input_unregister_device(ts->input); | ||
312 | |||
313 | /* Deactivate all IRQs */ | ||
314 | writel(0, ts->base + TP_INT_FIFOC); | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static const struct of_device_id sun4i_ts_of_match[] = { | ||
320 | { .compatible = "allwinner,sun4i-a10-ts", }, | ||
321 | { /* sentinel */ } | ||
322 | }; | ||
323 | MODULE_DEVICE_TABLE(of, sun4i_ts_of_match); | ||
324 | |||
325 | static struct platform_driver sun4i_ts_driver = { | ||
326 | .driver = { | ||
327 | .owner = THIS_MODULE, | ||
328 | .name = "sun4i-ts", | ||
329 | .of_match_table = of_match_ptr(sun4i_ts_of_match), | ||
330 | }, | ||
331 | .probe = sun4i_ts_probe, | ||
332 | .remove = sun4i_ts_remove, | ||
333 | }; | ||
334 | |||
335 | module_platform_driver(sun4i_ts_driver); | ||
336 | |||
337 | MODULE_DESCRIPTION("Allwinner sun4i resistive touchscreen controller driver"); | ||
338 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | ||
339 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 550adcbbfc23..52380b68ebdf 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c | |||
@@ -25,11 +25,15 @@ | |||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/input.h> | 27 | #include <linux/input.h> |
28 | #include <linux/input/touchscreen.h> | ||
28 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/pm.h> | 31 | #include <linux/pm.h> |
32 | #include <linux/of.h> | ||
33 | #include <linux/of_gpio.h> | ||
31 | #include <linux/spi/spi.h> | 34 | #include <linux/spi/spi.h> |
32 | #include <linux/spi/tsc2005.h> | 35 | #include <linux/spi/tsc2005.h> |
36 | #include <linux/regulator/consumer.h> | ||
33 | 37 | ||
34 | /* | 38 | /* |
35 | * The touchscreen interface operates as follows: | 39 | * The touchscreen interface operates as follows: |
@@ -100,6 +104,11 @@ | |||
100 | TSC2005_CFR2_AVG_7) | 104 | TSC2005_CFR2_AVG_7) |
101 | 105 | ||
102 | #define MAX_12BIT 0xfff | 106 | #define MAX_12BIT 0xfff |
107 | #define TSC2005_DEF_X_FUZZ 4 | ||
108 | #define TSC2005_DEF_Y_FUZZ 8 | ||
109 | #define TSC2005_DEF_P_FUZZ 2 | ||
110 | #define TSC2005_DEF_RESISTOR 280 | ||
111 | |||
103 | #define TSC2005_SPI_MAX_SPEED_HZ 10000000 | 112 | #define TSC2005_SPI_MAX_SPEED_HZ 10000000 |
104 | #define TSC2005_PENUP_TIME_MS 40 | 113 | #define TSC2005_PENUP_TIME_MS 40 |
105 | 114 | ||
@@ -143,6 +152,9 @@ struct tsc2005 { | |||
143 | 152 | ||
144 | bool pen_down; | 153 | bool pen_down; |
145 | 154 | ||
155 | struct regulator *vio; | ||
156 | |||
157 | int reset_gpio; | ||
146 | void (*set_reset)(bool enable); | 158 | void (*set_reset)(bool enable); |
147 | }; | 159 | }; |
148 | 160 | ||
@@ -337,6 +349,14 @@ static void tsc2005_stop_scan(struct tsc2005 *ts) | |||
337 | tsc2005_cmd(ts, TSC2005_CMD_STOP); | 349 | tsc2005_cmd(ts, TSC2005_CMD_STOP); |
338 | } | 350 | } |
339 | 351 | ||
352 | static void tsc2005_set_reset(struct tsc2005 *ts, bool enable) | ||
353 | { | ||
354 | if (ts->reset_gpio >= 0) | ||
355 | gpio_set_value(ts->reset_gpio, enable); | ||
356 | else if (ts->set_reset) | ||
357 | ts->set_reset(enable); | ||
358 | } | ||
359 | |||
340 | /* must be called with ts->mutex held */ | 360 | /* must be called with ts->mutex held */ |
341 | static void __tsc2005_disable(struct tsc2005 *ts) | 361 | static void __tsc2005_disable(struct tsc2005 *ts) |
342 | { | 362 | { |
@@ -355,7 +375,7 @@ static void __tsc2005_enable(struct tsc2005 *ts) | |||
355 | { | 375 | { |
356 | tsc2005_start_scan(ts); | 376 | tsc2005_start_scan(ts); |
357 | 377 | ||
358 | if (ts->esd_timeout && ts->set_reset) { | 378 | if (ts->esd_timeout && (ts->set_reset || ts->reset_gpio)) { |
359 | ts->last_valid_interrupt = jiffies; | 379 | ts->last_valid_interrupt = jiffies; |
360 | schedule_delayed_work(&ts->esd_work, | 380 | schedule_delayed_work(&ts->esd_work, |
361 | round_jiffies_relative( | 381 | round_jiffies_relative( |
@@ -414,9 +434,9 @@ static ssize_t tsc2005_selftest_show(struct device *dev, | |||
414 | } | 434 | } |
415 | 435 | ||
416 | /* hardware reset */ | 436 | /* hardware reset */ |
417 | ts->set_reset(false); | 437 | tsc2005_set_reset(ts, false); |
418 | usleep_range(100, 500); /* only 10us required */ | 438 | usleep_range(100, 500); /* only 10us required */ |
419 | ts->set_reset(true); | 439 | tsc2005_set_reset(ts, true); |
420 | 440 | ||
421 | if (!success) | 441 | if (!success) |
422 | goto out; | 442 | goto out; |
@@ -459,7 +479,7 @@ static umode_t tsc2005_attr_is_visible(struct kobject *kobj, | |||
459 | umode_t mode = attr->mode; | 479 | umode_t mode = attr->mode; |
460 | 480 | ||
461 | if (attr == &dev_attr_selftest.attr) { | 481 | if (attr == &dev_attr_selftest.attr) { |
462 | if (!ts->set_reset) | 482 | if (!ts->set_reset && !ts->reset_gpio) |
463 | mode = 0; | 483 | mode = 0; |
464 | } | 484 | } |
465 | 485 | ||
@@ -509,9 +529,9 @@ static void tsc2005_esd_work(struct work_struct *work) | |||
509 | 529 | ||
510 | tsc2005_update_pen_state(ts, 0, 0, 0); | 530 | tsc2005_update_pen_state(ts, 0, 0, 0); |
511 | 531 | ||
512 | ts->set_reset(false); | 532 | tsc2005_set_reset(ts, false); |
513 | usleep_range(100, 500); /* only 10us required */ | 533 | usleep_range(100, 500); /* only 10us required */ |
514 | ts->set_reset(true); | 534 | tsc2005_set_reset(ts, true); |
515 | 535 | ||
516 | enable_irq(ts->spi->irq); | 536 | enable_irq(ts->spi->irq); |
517 | tsc2005_start_scan(ts); | 537 | tsc2005_start_scan(ts); |
@@ -572,29 +592,47 @@ static void tsc2005_setup_spi_xfer(struct tsc2005 *ts) | |||
572 | static int tsc2005_probe(struct spi_device *spi) | 592 | static int tsc2005_probe(struct spi_device *spi) |
573 | { | 593 | { |
574 | const struct tsc2005_platform_data *pdata = dev_get_platdata(&spi->dev); | 594 | const struct tsc2005_platform_data *pdata = dev_get_platdata(&spi->dev); |
595 | struct device_node *np = spi->dev.of_node; | ||
596 | |||
575 | struct tsc2005 *ts; | 597 | struct tsc2005 *ts; |
576 | struct input_dev *input_dev; | 598 | struct input_dev *input_dev; |
577 | unsigned int max_x, max_y, max_p; | 599 | unsigned int max_x = MAX_12BIT; |
578 | unsigned int fudge_x, fudge_y, fudge_p; | 600 | unsigned int max_y = MAX_12BIT; |
601 | unsigned int max_p = MAX_12BIT; | ||
602 | unsigned int fudge_x = TSC2005_DEF_X_FUZZ; | ||
603 | unsigned int fudge_y = TSC2005_DEF_Y_FUZZ; | ||
604 | unsigned int fudge_p = TSC2005_DEF_P_FUZZ; | ||
605 | unsigned int x_plate_ohm = TSC2005_DEF_RESISTOR; | ||
606 | unsigned int esd_timeout; | ||
579 | int error; | 607 | int error; |
580 | 608 | ||
581 | if (!pdata) { | 609 | if (!np && !pdata) { |
582 | dev_dbg(&spi->dev, "no platform data\n"); | 610 | dev_err(&spi->dev, "no platform data\n"); |
583 | return -ENODEV; | 611 | return -ENODEV; |
584 | } | 612 | } |
585 | 613 | ||
586 | fudge_x = pdata->ts_x_fudge ? : 4; | ||
587 | fudge_y = pdata->ts_y_fudge ? : 8; | ||
588 | fudge_p = pdata->ts_pressure_fudge ? : 2; | ||
589 | max_x = pdata->ts_x_max ? : MAX_12BIT; | ||
590 | max_y = pdata->ts_y_max ? : MAX_12BIT; | ||
591 | max_p = pdata->ts_pressure_max ? : MAX_12BIT; | ||
592 | |||
593 | if (spi->irq <= 0) { | 614 | if (spi->irq <= 0) { |
594 | dev_dbg(&spi->dev, "no irq\n"); | 615 | dev_err(&spi->dev, "no irq\n"); |
595 | return -ENODEV; | 616 | return -ENODEV; |
596 | } | 617 | } |
597 | 618 | ||
619 | if (pdata) { | ||
620 | fudge_x = pdata->ts_x_fudge; | ||
621 | fudge_y = pdata->ts_y_fudge; | ||
622 | fudge_p = pdata->ts_pressure_fudge; | ||
623 | max_x = pdata->ts_x_max; | ||
624 | max_y = pdata->ts_y_max; | ||
625 | max_p = pdata->ts_pressure_max; | ||
626 | x_plate_ohm = pdata->ts_x_plate_ohm; | ||
627 | esd_timeout = pdata->esd_timeout_ms; | ||
628 | } else { | ||
629 | x_plate_ohm = TSC2005_DEF_RESISTOR; | ||
630 | of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm); | ||
631 | esd_timeout = 0; | ||
632 | of_property_read_u32(np, "ti,esd-recovery-timeout-ms", | ||
633 | &esd_timeout); | ||
634 | } | ||
635 | |||
598 | spi->mode = SPI_MODE_0; | 636 | spi->mode = SPI_MODE_0; |
599 | spi->bits_per_word = 8; | 637 | spi->bits_per_word = 8; |
600 | if (!spi->max_speed_hz) | 638 | if (!spi->max_speed_hz) |
@@ -604,19 +642,48 @@ static int tsc2005_probe(struct spi_device *spi) | |||
604 | if (error) | 642 | if (error) |
605 | return error; | 643 | return error; |
606 | 644 | ||
607 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | 645 | ts = devm_kzalloc(&spi->dev, sizeof(*ts), GFP_KERNEL); |
608 | input_dev = input_allocate_device(); | 646 | if (!ts) |
609 | if (!ts || !input_dev) { | 647 | return -ENOMEM; |
610 | error = -ENOMEM; | 648 | |
611 | goto err_free_mem; | 649 | input_dev = devm_input_allocate_device(&spi->dev); |
612 | } | 650 | if (!input_dev) |
651 | return -ENOMEM; | ||
613 | 652 | ||
614 | ts->spi = spi; | 653 | ts->spi = spi; |
615 | ts->idev = input_dev; | 654 | ts->idev = input_dev; |
616 | 655 | ||
617 | ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; | 656 | ts->x_plate_ohm = x_plate_ohm; |
618 | ts->esd_timeout = pdata->esd_timeout_ms; | 657 | ts->esd_timeout = esd_timeout; |
619 | ts->set_reset = pdata->set_reset; | 658 | |
659 | if (np) { | ||
660 | ts->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); | ||
661 | if (ts->reset_gpio == -EPROBE_DEFER) | ||
662 | return ts->reset_gpio; | ||
663 | if (ts->reset_gpio < 0) { | ||
664 | dev_err(&spi->dev, "error acquiring reset gpio: %d\n", | ||
665 | ts->reset_gpio); | ||
666 | return ts->reset_gpio; | ||
667 | } | ||
668 | |||
669 | error = devm_gpio_request_one(&spi->dev, ts->reset_gpio, 0, | ||
670 | "reset-gpios"); | ||
671 | if (error) { | ||
672 | dev_err(&spi->dev, "error requesting reset gpio: %d\n", | ||
673 | error); | ||
674 | return error; | ||
675 | } | ||
676 | |||
677 | ts->vio = devm_regulator_get(&spi->dev, "vio"); | ||
678 | if (IS_ERR(ts->vio)) { | ||
679 | error = PTR_ERR(ts->vio); | ||
680 | dev_err(&spi->dev, "vio regulator missing (%d)", error); | ||
681 | return error; | ||
682 | } | ||
683 | } else { | ||
684 | ts->reset_gpio = -1; | ||
685 | ts->set_reset = pdata->set_reset; | ||
686 | } | ||
620 | 687 | ||
621 | mutex_init(&ts->mutex); | 688 | mutex_init(&ts->mutex); |
622 | 689 | ||
@@ -641,6 +708,9 @@ static int tsc2005_probe(struct spi_device *spi) | |||
641 | input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0); | 708 | input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0); |
642 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); | 709 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); |
643 | 710 | ||
711 | if (np) | ||
712 | touchscreen_parse_of_params(input_dev); | ||
713 | |||
644 | input_dev->open = tsc2005_open; | 714 | input_dev->open = tsc2005_open; |
645 | input_dev->close = tsc2005_close; | 715 | input_dev->close = tsc2005_close; |
646 | 716 | ||
@@ -649,12 +719,20 @@ static int tsc2005_probe(struct spi_device *spi) | |||
649 | /* Ensure the touchscreen is off */ | 719 | /* Ensure the touchscreen is off */ |
650 | tsc2005_stop_scan(ts); | 720 | tsc2005_stop_scan(ts); |
651 | 721 | ||
652 | error = request_threaded_irq(spi->irq, NULL, tsc2005_irq_thread, | 722 | error = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, |
653 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | 723 | tsc2005_irq_thread, |
654 | "tsc2005", ts); | 724 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
725 | "tsc2005", ts); | ||
655 | if (error) { | 726 | if (error) { |
656 | dev_err(&spi->dev, "Failed to request irq, err: %d\n", error); | 727 | dev_err(&spi->dev, "Failed to request irq, err: %d\n", error); |
657 | goto err_free_mem; | 728 | return error; |
729 | } | ||
730 | |||
731 | /* enable regulator for DT */ | ||
732 | if (ts->vio) { | ||
733 | error = regulator_enable(ts->vio); | ||
734 | if (error) | ||
735 | return error; | ||
658 | } | 736 | } |
659 | 737 | ||
660 | spi_set_drvdata(spi, ts); | 738 | spi_set_drvdata(spi, ts); |
@@ -662,7 +740,7 @@ static int tsc2005_probe(struct spi_device *spi) | |||
662 | if (error) { | 740 | if (error) { |
663 | dev_err(&spi->dev, | 741 | dev_err(&spi->dev, |
664 | "Failed to create sysfs attributes, err: %d\n", error); | 742 | "Failed to create sysfs attributes, err: %d\n", error); |
665 | goto err_clear_drvdata; | 743 | goto disable_regulator; |
666 | } | 744 | } |
667 | 745 | ||
668 | error = input_register_device(ts->idev); | 746 | error = input_register_device(ts->idev); |
@@ -677,11 +755,9 @@ static int tsc2005_probe(struct spi_device *spi) | |||
677 | 755 | ||
678 | err_remove_sysfs: | 756 | err_remove_sysfs: |
679 | sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); | 757 | sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); |
680 | err_clear_drvdata: | 758 | disable_regulator: |
681 | free_irq(spi->irq, ts); | 759 | if (ts->vio) |
682 | err_free_mem: | 760 | regulator_disable(ts->vio); |
683 | input_free_device(input_dev); | ||
684 | kfree(ts); | ||
685 | return error; | 761 | return error; |
686 | } | 762 | } |
687 | 763 | ||
@@ -689,11 +765,10 @@ static int tsc2005_remove(struct spi_device *spi) | |||
689 | { | 765 | { |
690 | struct tsc2005 *ts = spi_get_drvdata(spi); | 766 | struct tsc2005 *ts = spi_get_drvdata(spi); |
691 | 767 | ||
692 | sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group); | 768 | sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); |
693 | 769 | ||
694 | free_irq(ts->spi->irq, ts); | 770 | if (ts->vio) |
695 | input_unregister_device(ts->idev); | 771 | regulator_disable(ts->vio); |
696 | kfree(ts); | ||
697 | 772 | ||
698 | return 0; | 773 | return 0; |
699 | } | 774 | } |
diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index 01d30cedde46..feea85b52fa8 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c | |||
@@ -880,7 +880,7 @@ static struct i2c_device_id zforce_idtable[] = { | |||
880 | MODULE_DEVICE_TABLE(i2c, zforce_idtable); | 880 | MODULE_DEVICE_TABLE(i2c, zforce_idtable); |
881 | 881 | ||
882 | #ifdef CONFIG_OF | 882 | #ifdef CONFIG_OF |
883 | static struct of_device_id zforce_dt_idtable[] = { | 883 | static const struct of_device_id zforce_dt_idtable[] = { |
884 | { .compatible = "neonode,zforce" }, | 884 | { .compatible = "neonode,zforce" }, |
885 | {}, | 885 | {}, |
886 | }; | 886 | }; |