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 | |
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
...
68 files changed, 2517 insertions, 1139 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio_keys.txt b/Documentation/devicetree/bindings/input/gpio-keys.txt index 5c2c02140a62..5c2c02140a62 100644 --- a/Documentation/devicetree/bindings/gpio/gpio_keys.txt +++ b/Documentation/devicetree/bindings/input/gpio-keys.txt | |||
diff --git a/Documentation/devicetree/bindings/input/st-keyscan.txt b/Documentation/devicetree/bindings/input/st-keyscan.txt new file mode 100644 index 000000000000..51eb428e5c85 --- /dev/null +++ b/Documentation/devicetree/bindings/input/st-keyscan.txt | |||
@@ -0,0 +1,60 @@ | |||
1 | * ST Keyscan controller Device Tree bindings | ||
2 | |||
3 | The ST keyscan controller Device Tree binding is based on the | ||
4 | matrix-keymap. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "st,sti-keyscan" | ||
8 | |||
9 | - reg: Register base address and size of st-keyscan controller. | ||
10 | |||
11 | - interrupts: Interrupt number for the st-keyscan controller. | ||
12 | |||
13 | - clocks: Must contain one entry, for the module clock. | ||
14 | See ../clocks/clock-bindings.txt for details. | ||
15 | |||
16 | - pinctrl: Should specify pin control groups used for this controller. | ||
17 | See ../pinctrl/pinctrl-bindings.txt for details. | ||
18 | |||
19 | - linux,keymap: The keymap for keys as described in the binding document | ||
20 | devicetree/bindings/input/matrix-keymap.txt. | ||
21 | |||
22 | - keypad,num-rows: Number of row lines connected to the keypad controller. | ||
23 | |||
24 | - keypad,num-columns: Number of column lines connected to the keypad | ||
25 | controller. | ||
26 | |||
27 | Optional property: | ||
28 | - st,debounce_us: Debouncing interval time in microseconds | ||
29 | |||
30 | Example: | ||
31 | |||
32 | keyscan: keyscan@fe4b0000 { | ||
33 | compatible = "st,sti-keyscan"; | ||
34 | reg = <0xfe4b0000 0x2000>; | ||
35 | interrupts = <GIC_SPI 212 IRQ_TYPE_NONE>; | ||
36 | clocks = <&CLK_SYSIN>; | ||
37 | pinctrl-names = "default"; | ||
38 | pinctrl-0 = <&pinctrl_keyscan>; | ||
39 | |||
40 | keypad,num-rows = <4>; | ||
41 | keypad,num-columns = <4>; | ||
42 | st,debounce_us = <5000>; | ||
43 | |||
44 | linux,keymap = < MATRIX_KEY(0x00, 0x00, KEY_F13) | ||
45 | MATRIX_KEY(0x00, 0x01, KEY_F9) | ||
46 | MATRIX_KEY(0x00, 0x02, KEY_F5) | ||
47 | MATRIX_KEY(0x00, 0x03, KEY_F1) | ||
48 | MATRIX_KEY(0x01, 0x00, KEY_F14) | ||
49 | MATRIX_KEY(0x01, 0x01, KEY_F10) | ||
50 | MATRIX_KEY(0x01, 0x02, KEY_F6) | ||
51 | MATRIX_KEY(0x01, 0x03, KEY_F2) | ||
52 | MATRIX_KEY(0x02, 0x00, KEY_F15) | ||
53 | MATRIX_KEY(0x02, 0x01, KEY_F11) | ||
54 | MATRIX_KEY(0x02, 0x02, KEY_F7) | ||
55 | MATRIX_KEY(0x02, 0x03, KEY_F3) | ||
56 | MATRIX_KEY(0x03, 0x00, KEY_F16) | ||
57 | MATRIX_KEY(0x03, 0x01, KEY_F12) | ||
58 | MATRIX_KEY(0x03, 0x02, KEY_F8) | ||
59 | MATRIX_KEY(0x03, 0x03, KEY_F4) >; | ||
60 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt new file mode 100644 index 000000000000..aef57791f40b --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | sun4i resistive touchscreen controller | ||
2 | -------------------------------------- | ||
3 | |||
4 | Required properties: | ||
5 | - compatible: "allwinner,sun4i-a10-ts" | ||
6 | - reg: mmio address range of the chip | ||
7 | - interrupts: interrupt to which the chip is connected | ||
8 | |||
9 | Optional properties: | ||
10 | - allwinner,ts-attached: boolean indicating that an actual touchscreen is | ||
11 | attached to the controller | ||
12 | |||
13 | Example: | ||
14 | |||
15 | rtp: rtp@01c25000 { | ||
16 | compatible = "allwinner,sun4i-a10-ts"; | ||
17 | reg = <0x01c25000 0x100>; | ||
18 | interrupts = <29>; | ||
19 | allwinner,ts-attached; | ||
20 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt new file mode 100644 index 000000000000..d8e06163c54e --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | General Touchscreen Properties: | ||
2 | |||
3 | Optional properties for Touchscreens: | ||
4 | - touchscreen-size-x : horizontal resolution of touchscreen | ||
5 | (in pixels) | ||
6 | - touchscreen-size-y : vertical resolution of touchscreen | ||
7 | (in pixels) | ||
8 | - touchscreen-max-pressure : maximum reported pressure (arbitrary range | ||
9 | dependent on the controller) | ||
10 | - touchscreen-fuzz-x : horizontal noise value of the absolute input | ||
11 | device (in pixels) | ||
12 | - touchscreen-fuzz-y : vertical noise value of the absolute input | ||
13 | device (in pixels) | ||
14 | - touchscreen-fuzz-pressure : pressure noise value of the absolute input | ||
15 | device (arbitrary range dependent on the | ||
16 | controller) | ||
17 | - touchscreen-inverted-x : X axis is inverted (boolean) | ||
18 | - touchscreen-inverted-y : Y axis is inverted (boolean) | ||
19 | |||
20 | Deprecated properties for Touchscreens: | ||
21 | - x-size : deprecated name for touchscreen-size-x | ||
22 | - y-size : deprecated name for touchscreen-size-y | ||
23 | - moving-threshold : deprecated name for a combination of | ||
24 | touchscreen-fuzz-x and touchscreen-fuzz-y | ||
25 | - contact-threshold : deprecated name for touchscreen-fuzz-pressure | ||
26 | - x-invert : deprecated name for touchscreen-inverted-x | ||
27 | - y-invert : deprecated name for touchscreen-inverted-y | ||
diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt new file mode 100644 index 000000000000..4b641c7bf1c2 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | * Texas Instruments tsc2005 touchscreen controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "ti,tsc2005" | ||
5 | - reg : SPI device address | ||
6 | - spi-max-frequency : Maximal SPI speed | ||
7 | - interrupts : IRQ specifier | ||
8 | - reset-gpios : GPIO specifier | ||
9 | - vio-supply : Regulator specifier | ||
10 | |||
11 | Optional properties: | ||
12 | - ti,x-plate-ohms : integer, resistance of the touchscreen's X plates | ||
13 | in ohm (defaults to 280) | ||
14 | - ti,esd-recovery-timeout-ms : integer, if the touchscreen does not respond after | ||
15 | the configured time (in milli seconds), the driver | ||
16 | will reset it. This is disabled by default. | ||
17 | - properties defined in touchscreen.txt | ||
18 | |||
19 | Example: | ||
20 | |||
21 | &mcspi1 { | ||
22 | tsc2005@0 { | ||
23 | compatible = "ti,tsc2005"; | ||
24 | spi-max-frequency = <6000000>; | ||
25 | reg = <0>; | ||
26 | |||
27 | vio-supply = <&vio>; | ||
28 | |||
29 | reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */ | ||
30 | interrupts-extended = <&gpio4 4 IRQ_TYPE_EDGE_RISING>; /* 100 */ | ||
31 | |||
32 | touchscreen-fuzz-x = <4>; | ||
33 | touchscreen-fuzz-y = <7>; | ||
34 | touchscreen-fuzz-pressure = <2>; | ||
35 | touchscreen-max-x = <4096>; | ||
36 | touchscreen-max-y = <4096>; | ||
37 | touchscreen-max-pressure = <2048>; | ||
38 | |||
39 | ti,x-plate-ohms = <280>; | ||
40 | ti,esd-recovery-timeout-ms = <8000>; | ||
41 | }; | ||
42 | } | ||
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 059a8ff1e6ac..ae8ae3f4f9bf 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts | |||
@@ -651,9 +651,24 @@ | |||
651 | * Also... order in the device tree actually matters here. | 651 | * Also... order in the device tree actually matters here. |
652 | */ | 652 | */ |
653 | tsc2005@0 { | 653 | tsc2005@0 { |
654 | compatible = "tsc2005"; | 654 | compatible = "ti,tsc2005"; |
655 | spi-max-frequency = <6000000>; | 655 | spi-max-frequency = <6000000>; |
656 | reg = <0>; | 656 | reg = <0>; |
657 | |||
658 | vio-supply = <&vio>; | ||
659 | |||
660 | reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */ | ||
661 | interrupts-extended = <&gpio4 4 IRQ_TYPE_EDGE_RISING>; /* 100 */ | ||
662 | |||
663 | touchscreen-fuzz-x = <4>; | ||
664 | touchscreen-fuzz-y = <7>; | ||
665 | touchscreen-fuzz-pressure = <2>; | ||
666 | touchscreen-max-x = <4096>; | ||
667 | touchscreen-max-y = <4096>; | ||
668 | touchscreen-max-pressure = <2048>; | ||
669 | |||
670 | ti,x-plate-ohms = <280>; | ||
671 | ti,esd-recovery-timeout-ms = <8000>; | ||
657 | }; | 672 | }; |
658 | 673 | ||
659 | acx565akm@2 { | 674 | acx565akm@2 { |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index e58609b312c7..592ba0a0ecf3 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/pinctrl/machine.h> | 20 | #include <linux/pinctrl/machine.h> |
21 | #include <linux/platform_data/omap4-keypad.h> | ||
22 | #include <linux/platform_data/mailbox-omap.h> | 21 | #include <linux/platform_data/mailbox-omap.h> |
23 | 22 | ||
24 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
@@ -29,7 +28,6 @@ | |||
29 | #include "iomap.h" | 28 | #include "iomap.h" |
30 | #include "omap_hwmod.h" | 29 | #include "omap_hwmod.h" |
31 | #include "omap_device.h" | 30 | #include "omap_device.h" |
32 | #include "omap4-keypad.h" | ||
33 | 31 | ||
34 | #include "soc.h" | 32 | #include "soc.h" |
35 | #include "common.h" | 33 | #include "common.h" |
@@ -255,37 +253,6 @@ static inline void omap_init_camera(void) | |||
255 | #endif | 253 | #endif |
256 | } | 254 | } |
257 | 255 | ||
258 | int __init omap4_keyboard_init(struct omap4_keypad_platform_data | ||
259 | *sdp4430_keypad_data, struct omap_board_data *bdata) | ||
260 | { | ||
261 | struct platform_device *pdev; | ||
262 | struct omap_hwmod *oh; | ||
263 | struct omap4_keypad_platform_data *keypad_data; | ||
264 | unsigned int id = -1; | ||
265 | char *oh_name = "kbd"; | ||
266 | char *name = "omap4-keypad"; | ||
267 | |||
268 | oh = omap_hwmod_lookup(oh_name); | ||
269 | if (!oh) { | ||
270 | pr_err("Could not look up %s\n", oh_name); | ||
271 | return -ENODEV; | ||
272 | } | ||
273 | |||
274 | keypad_data = sdp4430_keypad_data; | ||
275 | |||
276 | pdev = omap_device_build(name, id, oh, keypad_data, | ||
277 | sizeof(struct omap4_keypad_platform_data)); | ||
278 | |||
279 | if (IS_ERR(pdev)) { | ||
280 | WARN(1, "Can't build omap_device for %s:%s.\n", | ||
281 | name, oh->name); | ||
282 | return PTR_ERR(pdev); | ||
283 | } | ||
284 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) | 256 | #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) |
290 | static inline void __init omap_init_mbox(void) | 257 | static inline void __init omap_init_mbox(void) |
291 | { | 258 | { |
diff --git a/arch/arm/mach-omap2/omap4-keypad.h b/arch/arm/mach-omap2/omap4-keypad.h deleted file mode 100644 index 20de0d5a7e77..000000000000 --- a/arch/arm/mach-omap2/omap4-keypad.h +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | #ifndef ARCH_ARM_PLAT_OMAP4_KEYPAD_H | ||
2 | #define ARCH_ARM_PLAT_OMAP4_KEYPAD_H | ||
3 | |||
4 | struct omap_board_data; | ||
5 | |||
6 | extern int omap4_keyboard_init(struct omap4_keypad_platform_data *, | ||
7 | struct omap_board_data *); | ||
8 | #endif | ||
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index 6c719eccb94e..c1ce921c4088 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c | |||
@@ -234,14 +234,6 @@ static void __init goni_radio_init(void) | |||
234 | 234 | ||
235 | /* TSP */ | 235 | /* TSP */ |
236 | static struct mxt_platform_data qt602240_platform_data = { | 236 | static struct mxt_platform_data qt602240_platform_data = { |
237 | .x_line = 17, | ||
238 | .y_line = 11, | ||
239 | .x_size = 800, | ||
240 | .y_size = 480, | ||
241 | .blen = 0x21, | ||
242 | .threshold = 0x28, | ||
243 | .voltage = 2800000, /* 2.8V */ | ||
244 | .orient = MXT_DIAGONAL, | ||
245 | .irqflags = IRQF_TRIGGER_FALLING, | 237 | .irqflags = IRQF_TRIGGER_FALLING, |
246 | }; | 238 | }; |
247 | 239 | ||
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index ce953d895f5b..fd325ec9f064 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -629,12 +629,10 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) | |||
629 | return copy_to_user(p, str, len) ? -EFAULT : len; | 629 | return copy_to_user(p, str, len) ? -EFAULT : len; |
630 | } | 630 | } |
631 | 631 | ||
632 | #define OLD_KEY_MAX 0x1ff | ||
633 | static int handle_eviocgbit(struct input_dev *dev, | 632 | static int handle_eviocgbit(struct input_dev *dev, |
634 | unsigned int type, unsigned int size, | 633 | unsigned int type, unsigned int size, |
635 | void __user *p, int compat_mode) | 634 | void __user *p, int compat_mode) |
636 | { | 635 | { |
637 | static unsigned long keymax_warn_time; | ||
638 | unsigned long *bits; | 636 | unsigned long *bits; |
639 | int len; | 637 | int len; |
640 | 638 | ||
@@ -652,24 +650,8 @@ static int handle_eviocgbit(struct input_dev *dev, | |||
652 | default: return -EINVAL; | 650 | default: return -EINVAL; |
653 | } | 651 | } |
654 | 652 | ||
655 | /* | ||
656 | * Work around bugs in userspace programs that like to do | ||
657 | * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len' | ||
658 | * should be in bytes, not in bits. | ||
659 | */ | ||
660 | if (type == EV_KEY && size == OLD_KEY_MAX) { | ||
661 | len = OLD_KEY_MAX; | ||
662 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) | ||
663 | pr_warning("(EVIOCGBIT): Suspicious buffer size %u, " | ||
664 | "limiting output to %zu bytes. See " | ||
665 | "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n", | ||
666 | OLD_KEY_MAX, | ||
667 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); | ||
668 | } | ||
669 | |||
670 | return bits_to_user(bits, len, size, p, compat_mode); | 653 | return bits_to_user(bits, len, size, p, compat_mode); |
671 | } | 654 | } |
672 | #undef OLD_KEY_MAX | ||
673 | 655 | ||
674 | static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p) | 656 | static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p) |
675 | { | 657 | { |
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 7f161d93203c..3664f81655ca 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c | |||
@@ -147,6 +147,11 @@ static struct attribute_group input_polldev_attribute_group = { | |||
147 | .attrs = sysfs_attrs | 147 | .attrs = sysfs_attrs |
148 | }; | 148 | }; |
149 | 149 | ||
150 | static const struct attribute_group *input_polldev_attribute_groups[] = { | ||
151 | &input_polldev_attribute_group, | ||
152 | NULL | ||
153 | }; | ||
154 | |||
150 | /** | 155 | /** |
151 | * input_allocate_polled_device - allocate memory for polled device | 156 | * input_allocate_polled_device - allocate memory for polled device |
152 | * | 157 | * |
@@ -171,6 +176,91 @@ struct input_polled_dev *input_allocate_polled_device(void) | |||
171 | } | 176 | } |
172 | EXPORT_SYMBOL(input_allocate_polled_device); | 177 | EXPORT_SYMBOL(input_allocate_polled_device); |
173 | 178 | ||
179 | struct input_polled_devres { | ||
180 | struct input_polled_dev *polldev; | ||
181 | }; | ||
182 | |||
183 | static int devm_input_polldev_match(struct device *dev, void *res, void *data) | ||
184 | { | ||
185 | struct input_polled_devres *devres = res; | ||
186 | |||
187 | return devres->polldev == data; | ||
188 | } | ||
189 | |||
190 | static void devm_input_polldev_release(struct device *dev, void *res) | ||
191 | { | ||
192 | struct input_polled_devres *devres = res; | ||
193 | struct input_polled_dev *polldev = devres->polldev; | ||
194 | |||
195 | dev_dbg(dev, "%s: dropping reference/freeing %s\n", | ||
196 | __func__, dev_name(&polldev->input->dev)); | ||
197 | |||
198 | input_put_device(polldev->input); | ||
199 | kfree(polldev); | ||
200 | } | ||
201 | |||
202 | static void devm_input_polldev_unregister(struct device *dev, void *res) | ||
203 | { | ||
204 | struct input_polled_devres *devres = res; | ||
205 | struct input_polled_dev *polldev = devres->polldev; | ||
206 | |||
207 | dev_dbg(dev, "%s: unregistering device %s\n", | ||
208 | __func__, dev_name(&polldev->input->dev)); | ||
209 | input_unregister_device(polldev->input); | ||
210 | |||
211 | /* | ||
212 | * Note that we are still holding extra reference to the input | ||
213 | * device so it will stick around until devm_input_polldev_release() | ||
214 | * is called. | ||
215 | */ | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * devm_input_allocate_polled_device - allocate managed polled device | ||
220 | * @dev: device owning the polled device being created | ||
221 | * | ||
222 | * Returns prepared &struct input_polled_dev or %NULL. | ||
223 | * | ||
224 | * Managed polled input devices do not need to be explicitly unregistered | ||
225 | * or freed as it will be done automatically when owner device unbinds | ||
226 | * from * its driver (or binding fails). Once such managed polled device | ||
227 | * is allocated, it is ready to be set up and registered in the same | ||
228 | * fashion as regular polled input devices (using | ||
229 | * input_register_polled_device() function). | ||
230 | * | ||
231 | * If you want to manually unregister and free such managed polled devices, | ||
232 | * it can be still done by calling input_unregister_polled_device() and | ||
233 | * input_free_polled_device(), although it is rarely needed. | ||
234 | * | ||
235 | * NOTE: the owner device is set up as parent of input device and users | ||
236 | * should not override it. | ||
237 | */ | ||
238 | struct input_polled_dev *devm_input_allocate_polled_device(struct device *dev) | ||
239 | { | ||
240 | struct input_polled_dev *polldev; | ||
241 | struct input_polled_devres *devres; | ||
242 | |||
243 | devres = devres_alloc(devm_input_polldev_release, sizeof(*devres), | ||
244 | GFP_KERNEL); | ||
245 | if (!devres) | ||
246 | return NULL; | ||
247 | |||
248 | polldev = input_allocate_polled_device(); | ||
249 | if (!polldev) { | ||
250 | devres_free(devres); | ||
251 | return NULL; | ||
252 | } | ||
253 | |||
254 | polldev->input->dev.parent = dev; | ||
255 | polldev->devres_managed = true; | ||
256 | |||
257 | devres->polldev = polldev; | ||
258 | devres_add(dev, devres); | ||
259 | |||
260 | return polldev; | ||
261 | } | ||
262 | EXPORT_SYMBOL(devm_input_allocate_polled_device); | ||
263 | |||
174 | /** | 264 | /** |
175 | * input_free_polled_device - free memory allocated for polled device | 265 | * input_free_polled_device - free memory allocated for polled device |
176 | * @dev: device to free | 266 | * @dev: device to free |
@@ -181,7 +271,12 @@ EXPORT_SYMBOL(input_allocate_polled_device); | |||
181 | void input_free_polled_device(struct input_polled_dev *dev) | 271 | void input_free_polled_device(struct input_polled_dev *dev) |
182 | { | 272 | { |
183 | if (dev) { | 273 | if (dev) { |
184 | input_free_device(dev->input); | 274 | if (dev->devres_managed) |
275 | WARN_ON(devres_destroy(dev->input->dev.parent, | ||
276 | devm_input_polldev_release, | ||
277 | devm_input_polldev_match, | ||
278 | dev)); | ||
279 | input_put_device(dev->input); | ||
185 | kfree(dev); | 280 | kfree(dev); |
186 | } | 281 | } |
187 | } | 282 | } |
@@ -199,26 +294,35 @@ EXPORT_SYMBOL(input_free_polled_device); | |||
199 | */ | 294 | */ |
200 | int input_register_polled_device(struct input_polled_dev *dev) | 295 | int input_register_polled_device(struct input_polled_dev *dev) |
201 | { | 296 | { |
297 | struct input_polled_devres *devres = NULL; | ||
202 | struct input_dev *input = dev->input; | 298 | struct input_dev *input = dev->input; |
203 | int error; | 299 | int error; |
204 | 300 | ||
301 | if (dev->devres_managed) { | ||
302 | devres = devres_alloc(devm_input_polldev_unregister, | ||
303 | sizeof(*devres), GFP_KERNEL); | ||
304 | if (!devres) | ||
305 | return -ENOMEM; | ||
306 | |||
307 | devres->polldev = dev; | ||
308 | } | ||
309 | |||
205 | input_set_drvdata(input, dev); | 310 | input_set_drvdata(input, dev); |
206 | INIT_DELAYED_WORK(&dev->work, input_polled_device_work); | 311 | INIT_DELAYED_WORK(&dev->work, input_polled_device_work); |
312 | |||
207 | if (!dev->poll_interval) | 313 | if (!dev->poll_interval) |
208 | dev->poll_interval = 500; | 314 | dev->poll_interval = 500; |
209 | if (!dev->poll_interval_max) | 315 | if (!dev->poll_interval_max) |
210 | dev->poll_interval_max = dev->poll_interval; | 316 | dev->poll_interval_max = dev->poll_interval; |
317 | |||
211 | input->open = input_open_polled_device; | 318 | input->open = input_open_polled_device; |
212 | input->close = input_close_polled_device; | 319 | input->close = input_close_polled_device; |
213 | 320 | ||
214 | error = input_register_device(input); | 321 | input->dev.groups = input_polldev_attribute_groups; |
215 | if (error) | ||
216 | return error; | ||
217 | 322 | ||
218 | error = sysfs_create_group(&input->dev.kobj, | 323 | error = input_register_device(input); |
219 | &input_polldev_attribute_group); | ||
220 | if (error) { | 324 | if (error) { |
221 | input_unregister_device(input); | 325 | devres_free(devres); |
222 | return error; | 326 | return error; |
223 | } | 327 | } |
224 | 328 | ||
@@ -231,6 +335,12 @@ int input_register_polled_device(struct input_polled_dev *dev) | |||
231 | */ | 335 | */ |
232 | input_get_device(input); | 336 | input_get_device(input); |
233 | 337 | ||
338 | if (dev->devres_managed) { | ||
339 | dev_dbg(input->dev.parent, "%s: registering %s with devres.\n", | ||
340 | __func__, dev_name(&input->dev)); | ||
341 | devres_add(input->dev.parent, devres); | ||
342 | } | ||
343 | |||
234 | return 0; | 344 | return 0; |
235 | } | 345 | } |
236 | EXPORT_SYMBOL(input_register_polled_device); | 346 | EXPORT_SYMBOL(input_register_polled_device); |
@@ -245,8 +355,11 @@ EXPORT_SYMBOL(input_register_polled_device); | |||
245 | */ | 355 | */ |
246 | void input_unregister_polled_device(struct input_polled_dev *dev) | 356 | void input_unregister_polled_device(struct input_polled_dev *dev) |
247 | { | 357 | { |
248 | sysfs_remove_group(&dev->input->dev.kobj, | 358 | if (dev->devres_managed) |
249 | &input_polldev_attribute_group); | 359 | WARN_ON(devres_destroy(dev->input->dev.parent, |
360 | devm_input_polldev_unregister, | ||
361 | devm_input_polldev_match, | ||
362 | dev)); | ||
250 | 363 | ||
251 | input_unregister_device(dev->input); | 364 | input_unregister_device(dev->input); |
252 | } | 365 | } |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index ffc7ad3a2c88..f7e79b481349 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -524,6 +524,17 @@ config KEYBOARD_STOWAWAY | |||
524 | To compile this driver as a module, choose M here: the | 524 | To compile this driver as a module, choose M here: the |
525 | module will be called stowaway. | 525 | module will be called stowaway. |
526 | 526 | ||
527 | config KEYBOARD_ST_KEYSCAN | ||
528 | tristate "STMicroelectronics keyscan support" | ||
529 | depends on ARCH_STI || COMPILE_TEST | ||
530 | select INPUT_MATRIXKMAP | ||
531 | help | ||
532 | Say Y here if you want to use a keypad attached to the keyscan block | ||
533 | on some STMicroelectronics SoC devices. | ||
534 | |||
535 | To compile this driver as a module, choose M here: the | ||
536 | module will be called st-keyscan. | ||
537 | |||
527 | config KEYBOARD_SUNKBD | 538 | config KEYBOARD_SUNKBD |
528 | tristate "Sun Type 4 and Type 5 keyboard" | 539 | tristate "Sun Type 4 and Type 5 keyboard" |
529 | select SERIO | 540 | select SERIO |
@@ -578,7 +589,7 @@ config KEYBOARD_OMAP | |||
578 | 589 | ||
579 | config KEYBOARD_OMAP4 | 590 | config KEYBOARD_OMAP4 |
580 | tristate "TI OMAP4+ keypad support" | 591 | tristate "TI OMAP4+ keypad support" |
581 | depends on ARCH_OMAP2PLUS | 592 | depends on OF || ARCH_OMAP2PLUS |
582 | select INPUT_MATRIXKMAP | 593 | select INPUT_MATRIXKMAP |
583 | help | 594 | help |
584 | Say Y here if you want to use the OMAP4+ keypad. | 595 | Say Y here if you want to use the OMAP4+ keypad. |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 11cff7b84b47..7504ae19049d 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -51,6 +51,7 @@ obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | |||
51 | obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o | 51 | obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o |
52 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o | 52 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o |
53 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | 53 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o |
54 | obj-$(CONFIG_KEYBOARD_ST_KEYSCAN) += st-keyscan.o | ||
54 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | 55 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o |
55 | obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o | 56 | obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o |
56 | obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o | 57 | obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o |
diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index 4cc14c2fa7d5..7f4a8b58efc1 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/input.h> | 12 | #include <linux/input.h> |
13 | #include <linux/mfd/adp5520.h> | 13 | #include <linux/mfd/adp5520.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/device.h> | ||
15 | 16 | ||
16 | struct adp5520_keys { | 17 | struct adp5520_keys { |
17 | struct input_dev *input; | 18 | struct input_dev *input; |
@@ -81,7 +82,7 @@ static int adp5520_keys_probe(struct platform_device *pdev) | |||
81 | return -EINVAL; | 82 | return -EINVAL; |
82 | } | 83 | } |
83 | 84 | ||
84 | if (pdata == NULL) { | 85 | if (!pdata) { |
85 | dev_err(&pdev->dev, "missing platform data\n"); | 86 | dev_err(&pdev->dev, "missing platform data\n"); |
86 | return -EINVAL; | 87 | return -EINVAL; |
87 | } | 88 | } |
@@ -89,17 +90,15 @@ static int adp5520_keys_probe(struct platform_device *pdev) | |||
89 | if (!(pdata->rows_en_mask && pdata->cols_en_mask)) | 90 | if (!(pdata->rows_en_mask && pdata->cols_en_mask)) |
90 | return -EINVAL; | 91 | return -EINVAL; |
91 | 92 | ||
92 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 93 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); |
93 | if (dev == NULL) { | 94 | if (!dev) { |
94 | dev_err(&pdev->dev, "failed to alloc memory\n"); | 95 | dev_err(&pdev->dev, "failed to alloc memory\n"); |
95 | return -ENOMEM; | 96 | return -ENOMEM; |
96 | } | 97 | } |
97 | 98 | ||
98 | input = input_allocate_device(); | 99 | input = devm_input_allocate_device(&pdev->dev); |
99 | if (!input) { | 100 | if (!input) |
100 | ret = -ENOMEM; | 101 | return -ENOMEM; |
101 | goto err; | ||
102 | } | ||
103 | 102 | ||
104 | dev->master = pdev->dev.parent; | 103 | dev->master = pdev->dev.parent; |
105 | dev->input = input; | 104 | dev->input = input; |
@@ -135,7 +134,7 @@ static int adp5520_keys_probe(struct platform_device *pdev) | |||
135 | ret = input_register_device(input); | 134 | ret = input_register_device(input); |
136 | if (ret) { | 135 | if (ret) { |
137 | dev_err(&pdev->dev, "unable to register input device\n"); | 136 | dev_err(&pdev->dev, "unable to register input device\n"); |
138 | goto err; | 137 | return ret; |
139 | } | 138 | } |
140 | 139 | ||
141 | en_mask = pdata->rows_en_mask | pdata->cols_en_mask; | 140 | en_mask = pdata->rows_en_mask | pdata->cols_en_mask; |
@@ -157,8 +156,7 @@ static int adp5520_keys_probe(struct platform_device *pdev) | |||
157 | 156 | ||
158 | if (ret) { | 157 | if (ret) { |
159 | dev_err(&pdev->dev, "failed to write\n"); | 158 | dev_err(&pdev->dev, "failed to write\n"); |
160 | ret = -EIO; | 159 | return -EIO; |
161 | goto err1; | ||
162 | } | 160 | } |
163 | 161 | ||
164 | dev->notifier.notifier_call = adp5520_keys_notifier; | 162 | dev->notifier.notifier_call = adp5520_keys_notifier; |
@@ -166,19 +164,11 @@ static int adp5520_keys_probe(struct platform_device *pdev) | |||
166 | ADP5520_KP_IEN | ADP5520_KR_IEN); | 164 | ADP5520_KP_IEN | ADP5520_KR_IEN); |
167 | if (ret) { | 165 | if (ret) { |
168 | dev_err(&pdev->dev, "failed to register notifier\n"); | 166 | dev_err(&pdev->dev, "failed to register notifier\n"); |
169 | goto err1; | 167 | return ret; |
170 | } | 168 | } |
171 | 169 | ||
172 | platform_set_drvdata(pdev, dev); | 170 | platform_set_drvdata(pdev, dev); |
173 | return 0; | 171 | return 0; |
174 | |||
175 | err1: | ||
176 | input_unregister_device(input); | ||
177 | input = NULL; | ||
178 | err: | ||
179 | input_free_device(input); | ||
180 | kfree(dev); | ||
181 | return ret; | ||
182 | } | 172 | } |
183 | 173 | ||
184 | static int adp5520_keys_remove(struct platform_device *pdev) | 174 | static int adp5520_keys_remove(struct platform_device *pdev) |
@@ -188,8 +178,6 @@ static int adp5520_keys_remove(struct platform_device *pdev) | |||
188 | adp5520_unregister_notifier(dev->master, &dev->notifier, | 178 | adp5520_unregister_notifier(dev->master, &dev->notifier, |
189 | ADP5520_KP_IEN | ADP5520_KR_IEN); | 179 | ADP5520_KP_IEN | ADP5520_KR_IEN); |
190 | 180 | ||
191 | input_unregister_device(dev->input); | ||
192 | kfree(dev); | ||
193 | return 0; | 181 | return 0; |
194 | } | 182 | } |
195 | 183 | ||
diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index 3955aecee44b..552b65c6e6b0 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c | |||
@@ -185,7 +185,7 @@ static int clps711x_keypad_remove(struct platform_device *pdev) | |||
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
187 | 187 | ||
188 | static struct of_device_id clps711x_keypad_of_match[] = { | 188 | static const struct of_device_id clps711x_keypad_of_match[] = { |
189 | { .compatible = "cirrus,clps711x-keypad", }, | 189 | { .compatible = "cirrus,clps711x-keypad", }, |
190 | { } | 190 | { } |
191 | }; | 191 | }; |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 2db13246eb8e..8c98e97f8e41 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -424,6 +424,16 @@ out: | |||
424 | return IRQ_HANDLED; | 424 | return IRQ_HANDLED; |
425 | } | 425 | } |
426 | 426 | ||
427 | static void gpio_keys_quiesce_key(void *data) | ||
428 | { | ||
429 | struct gpio_button_data *bdata = data; | ||
430 | |||
431 | if (bdata->timer_debounce) | ||
432 | del_timer_sync(&bdata->timer); | ||
433 | |||
434 | cancel_work_sync(&bdata->work); | ||
435 | } | ||
436 | |||
427 | static int gpio_keys_setup_key(struct platform_device *pdev, | 437 | static int gpio_keys_setup_key(struct platform_device *pdev, |
428 | struct input_dev *input, | 438 | struct input_dev *input, |
429 | struct gpio_button_data *bdata, | 439 | struct gpio_button_data *bdata, |
@@ -433,7 +443,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
433 | struct device *dev = &pdev->dev; | 443 | struct device *dev = &pdev->dev; |
434 | irq_handler_t isr; | 444 | irq_handler_t isr; |
435 | unsigned long irqflags; | 445 | unsigned long irqflags; |
436 | int irq, error; | 446 | int irq; |
447 | int error; | ||
437 | 448 | ||
438 | bdata->input = input; | 449 | bdata->input = input; |
439 | bdata->button = button; | 450 | bdata->button = button; |
@@ -441,7 +452,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
441 | 452 | ||
442 | if (gpio_is_valid(button->gpio)) { | 453 | if (gpio_is_valid(button->gpio)) { |
443 | 454 | ||
444 | error = gpio_request_one(button->gpio, GPIOF_IN, desc); | 455 | error = devm_gpio_request_one(&pdev->dev, button->gpio, |
456 | GPIOF_IN, desc); | ||
445 | if (error < 0) { | 457 | if (error < 0) { |
446 | dev_err(dev, "Failed to request GPIO %d, error %d\n", | 458 | dev_err(dev, "Failed to request GPIO %d, error %d\n", |
447 | button->gpio, error); | 459 | button->gpio, error); |
@@ -463,7 +475,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
463 | dev_err(dev, | 475 | dev_err(dev, |
464 | "Unable to get irq number for GPIO %d, error %d\n", | 476 | "Unable to get irq number for GPIO %d, error %d\n", |
465 | button->gpio, error); | 477 | button->gpio, error); |
466 | goto fail; | 478 | return error; |
467 | } | 479 | } |
468 | bdata->irq = irq; | 480 | bdata->irq = irq; |
469 | 481 | ||
@@ -497,26 +509,33 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
497 | input_set_capability(input, button->type ?: EV_KEY, button->code); | 509 | input_set_capability(input, button->type ?: EV_KEY, button->code); |
498 | 510 | ||
499 | /* | 511 | /* |
512 | * Install custom action to cancel debounce timer and | ||
513 | * workqueue item. | ||
514 | */ | ||
515 | error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata); | ||
516 | if (error) { | ||
517 | dev_err(&pdev->dev, | ||
518 | "failed to register quiesce action, error: %d\n", | ||
519 | error); | ||
520 | return error; | ||
521 | } | ||
522 | |||
523 | /* | ||
500 | * If platform has specified that the button can be disabled, | 524 | * If platform has specified that the button can be disabled, |
501 | * we don't want it to share the interrupt line. | 525 | * we don't want it to share the interrupt line. |
502 | */ | 526 | */ |
503 | if (!button->can_disable) | 527 | if (!button->can_disable) |
504 | irqflags |= IRQF_SHARED; | 528 | irqflags |= IRQF_SHARED; |
505 | 529 | ||
506 | error = request_any_context_irq(bdata->irq, isr, irqflags, desc, bdata); | 530 | error = devm_request_any_context_irq(&pdev->dev, bdata->irq, |
531 | isr, irqflags, desc, bdata); | ||
507 | if (error < 0) { | 532 | if (error < 0) { |
508 | dev_err(dev, "Unable to claim irq %d; error %d\n", | 533 | dev_err(dev, "Unable to claim irq %d; error %d\n", |
509 | bdata->irq, error); | 534 | bdata->irq, error); |
510 | goto fail; | 535 | return error; |
511 | } | 536 | } |
512 | 537 | ||
513 | return 0; | 538 | return 0; |
514 | |||
515 | fail: | ||
516 | if (gpio_is_valid(button->gpio)) | ||
517 | gpio_free(button->gpio); | ||
518 | |||
519 | return error; | ||
520 | } | 539 | } |
521 | 540 | ||
522 | static void gpio_keys_report_state(struct gpio_keys_drvdata *ddata) | 541 | static void gpio_keys_report_state(struct gpio_keys_drvdata *ddata) |
@@ -578,23 +597,18 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
578 | int i; | 597 | int i; |
579 | 598 | ||
580 | node = dev->of_node; | 599 | node = dev->of_node; |
581 | if (!node) { | 600 | if (!node) |
582 | error = -ENODEV; | 601 | return ERR_PTR(-ENODEV); |
583 | goto err_out; | ||
584 | } | ||
585 | 602 | ||
586 | nbuttons = of_get_child_count(node); | 603 | nbuttons = of_get_child_count(node); |
587 | if (nbuttons == 0) { | 604 | if (nbuttons == 0) |
588 | error = -ENODEV; | 605 | return ERR_PTR(-ENODEV); |
589 | goto err_out; | ||
590 | } | ||
591 | 606 | ||
592 | pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), | 607 | pdata = devm_kzalloc(dev, |
593 | GFP_KERNEL); | 608 | sizeof(*pdata) + nbuttons * sizeof(*button), |
594 | if (!pdata) { | 609 | GFP_KERNEL); |
595 | error = -ENOMEM; | 610 | if (!pdata) |
596 | goto err_out; | 611 | return ERR_PTR(-ENOMEM); |
597 | } | ||
598 | 612 | ||
599 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); | 613 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); |
600 | pdata->nbuttons = nbuttons; | 614 | pdata->nbuttons = nbuttons; |
@@ -619,7 +633,7 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
619 | dev_err(dev, | 633 | dev_err(dev, |
620 | "Failed to get gpio flags, error: %d\n", | 634 | "Failed to get gpio flags, error: %d\n", |
621 | error); | 635 | error); |
622 | goto err_free_pdata; | 636 | return ERR_PTR(error); |
623 | } | 637 | } |
624 | 638 | ||
625 | button = &pdata->buttons[i++]; | 639 | button = &pdata->buttons[i++]; |
@@ -630,8 +644,7 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
630 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | 644 | if (of_property_read_u32(pp, "linux,code", &button->code)) { |
631 | dev_err(dev, "Button without keycode: 0x%x\n", | 645 | dev_err(dev, "Button without keycode: 0x%x\n", |
632 | button->gpio); | 646 | button->gpio); |
633 | error = -EINVAL; | 647 | return ERR_PTR(-EINVAL); |
634 | goto err_free_pdata; | ||
635 | } | 648 | } |
636 | 649 | ||
637 | button->desc = of_get_property(pp, "label", NULL); | 650 | button->desc = of_get_property(pp, "label", NULL); |
@@ -646,20 +659,13 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
646 | button->debounce_interval = 5; | 659 | button->debounce_interval = 5; |
647 | } | 660 | } |
648 | 661 | ||
649 | if (pdata->nbuttons == 0) { | 662 | if (pdata->nbuttons == 0) |
650 | error = -EINVAL; | 663 | return ERR_PTR(-EINVAL); |
651 | goto err_free_pdata; | ||
652 | } | ||
653 | 664 | ||
654 | return pdata; | 665 | return pdata; |
655 | |||
656 | err_free_pdata: | ||
657 | kfree(pdata); | ||
658 | err_out: | ||
659 | return ERR_PTR(error); | ||
660 | } | 666 | } |
661 | 667 | ||
662 | static struct of_device_id gpio_keys_of_match[] = { | 668 | static const struct of_device_id gpio_keys_of_match[] = { |
663 | { .compatible = "gpio-keys", }, | 669 | { .compatible = "gpio-keys", }, |
664 | { }, | 670 | { }, |
665 | }; | 671 | }; |
@@ -675,22 +681,13 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
675 | 681 | ||
676 | #endif | 682 | #endif |
677 | 683 | ||
678 | static void gpio_remove_key(struct gpio_button_data *bdata) | ||
679 | { | ||
680 | free_irq(bdata->irq, bdata); | ||
681 | if (bdata->timer_debounce) | ||
682 | del_timer_sync(&bdata->timer); | ||
683 | cancel_work_sync(&bdata->work); | ||
684 | if (gpio_is_valid(bdata->button->gpio)) | ||
685 | gpio_free(bdata->button->gpio); | ||
686 | } | ||
687 | |||
688 | static int gpio_keys_probe(struct platform_device *pdev) | 684 | static int gpio_keys_probe(struct platform_device *pdev) |
689 | { | 685 | { |
690 | struct device *dev = &pdev->dev; | 686 | struct device *dev = &pdev->dev; |
691 | const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); | 687 | const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); |
692 | struct gpio_keys_drvdata *ddata; | 688 | struct gpio_keys_drvdata *ddata; |
693 | struct input_dev *input; | 689 | struct input_dev *input; |
690 | size_t size; | ||
694 | int i, error; | 691 | int i, error; |
695 | int wakeup = 0; | 692 | int wakeup = 0; |
696 | 693 | ||
@@ -700,14 +697,18 @@ static int gpio_keys_probe(struct platform_device *pdev) | |||
700 | return PTR_ERR(pdata); | 697 | return PTR_ERR(pdata); |
701 | } | 698 | } |
702 | 699 | ||
703 | ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + | 700 | size = sizeof(struct gpio_keys_drvdata) + |
704 | pdata->nbuttons * sizeof(struct gpio_button_data), | 701 | pdata->nbuttons * sizeof(struct gpio_button_data); |
705 | GFP_KERNEL); | 702 | ddata = devm_kzalloc(dev, size, GFP_KERNEL); |
706 | input = input_allocate_device(); | 703 | if (!ddata) { |
707 | if (!ddata || !input) { | ||
708 | dev_err(dev, "failed to allocate state\n"); | 704 | dev_err(dev, "failed to allocate state\n"); |
709 | error = -ENOMEM; | 705 | return -ENOMEM; |
710 | goto fail1; | 706 | } |
707 | |||
708 | input = devm_input_allocate_device(dev); | ||
709 | if (!input) { | ||
710 | dev_err(dev, "failed to allocate input device\n"); | ||
711 | return -ENOMEM; | ||
711 | } | 712 | } |
712 | 713 | ||
713 | ddata->pdata = pdata; | 714 | ddata->pdata = pdata; |
@@ -738,7 +739,7 @@ static int gpio_keys_probe(struct platform_device *pdev) | |||
738 | 739 | ||
739 | error = gpio_keys_setup_key(pdev, input, bdata, button); | 740 | error = gpio_keys_setup_key(pdev, input, bdata, button); |
740 | if (error) | 741 | if (error) |
741 | goto fail2; | 742 | return error; |
742 | 743 | ||
743 | if (button->wakeup) | 744 | if (button->wakeup) |
744 | wakeup = 1; | 745 | wakeup = 1; |
@@ -748,57 +749,31 @@ static int gpio_keys_probe(struct platform_device *pdev) | |||
748 | if (error) { | 749 | if (error) { |
749 | dev_err(dev, "Unable to export keys/switches, error: %d\n", | 750 | dev_err(dev, "Unable to export keys/switches, error: %d\n", |
750 | error); | 751 | error); |
751 | goto fail2; | 752 | return error; |
752 | } | 753 | } |
753 | 754 | ||
754 | error = input_register_device(input); | 755 | error = input_register_device(input); |
755 | if (error) { | 756 | if (error) { |
756 | dev_err(dev, "Unable to register input device, error: %d\n", | 757 | dev_err(dev, "Unable to register input device, error: %d\n", |
757 | error); | 758 | error); |
758 | goto fail3; | 759 | goto err_remove_group; |
759 | } | 760 | } |
760 | 761 | ||
761 | device_init_wakeup(&pdev->dev, wakeup); | 762 | device_init_wakeup(&pdev->dev, wakeup); |
762 | 763 | ||
763 | return 0; | 764 | return 0; |
764 | 765 | ||
765 | fail3: | 766 | err_remove_group: |
766 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | 767 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); |
767 | fail2: | ||
768 | while (--i >= 0) | ||
769 | gpio_remove_key(&ddata->data[i]); | ||
770 | |||
771 | fail1: | ||
772 | input_free_device(input); | ||
773 | kfree(ddata); | ||
774 | /* If we have no platform data, we allocated pdata dynamically. */ | ||
775 | if (!dev_get_platdata(&pdev->dev)) | ||
776 | kfree(pdata); | ||
777 | |||
778 | return error; | 768 | return error; |
779 | } | 769 | } |
780 | 770 | ||
781 | static int gpio_keys_remove(struct platform_device *pdev) | 771 | static int gpio_keys_remove(struct platform_device *pdev) |
782 | { | 772 | { |
783 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); | ||
784 | struct input_dev *input = ddata->input; | ||
785 | int i; | ||
786 | |||
787 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | 773 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); |
788 | 774 | ||
789 | device_init_wakeup(&pdev->dev, 0); | 775 | device_init_wakeup(&pdev->dev, 0); |
790 | 776 | ||
791 | for (i = 0; i < ddata->pdata->nbuttons; i++) | ||
792 | gpio_remove_key(&ddata->data[i]); | ||
793 | |||
794 | input_unregister_device(input); | ||
795 | |||
796 | /* If we have no platform data, we allocated pdata dynamically. */ | ||
797 | if (!dev_get_platdata(&pdev->dev)) | ||
798 | kfree(ddata->pdata); | ||
799 | |||
800 | kfree(ddata); | ||
801 | |||
802 | return 0; | 777 | return 0; |
803 | } | 778 | } |
804 | 779 | ||
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index e571e194ff84..432d36395f35 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
@@ -120,12 +120,10 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct | |||
120 | if (nbuttons == 0) | 120 | if (nbuttons == 0) |
121 | return NULL; | 121 | return NULL; |
122 | 122 | ||
123 | pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), | 123 | pdata = devm_kzalloc(dev, sizeof(*pdata) + nbuttons * sizeof(*button), |
124 | GFP_KERNEL); | 124 | GFP_KERNEL); |
125 | if (!pdata) { | 125 | if (!pdata) |
126 | error = -ENOMEM; | 126 | return ERR_PTR(-ENOMEM); |
127 | goto err_out; | ||
128 | } | ||
129 | 127 | ||
130 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); | 128 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); |
131 | pdata->nbuttons = nbuttons; | 129 | pdata->nbuttons = nbuttons; |
@@ -151,7 +149,7 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct | |||
151 | dev_err(dev, | 149 | dev_err(dev, |
152 | "Failed to get gpio flags, error: %d\n", | 150 | "Failed to get gpio flags, error: %d\n", |
153 | error); | 151 | error); |
154 | goto err_free_pdata; | 152 | return ERR_PTR(error); |
155 | } | 153 | } |
156 | 154 | ||
157 | button = &pdata->buttons[i++]; | 155 | button = &pdata->buttons[i++]; |
@@ -162,8 +160,7 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct | |||
162 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | 160 | if (of_property_read_u32(pp, "linux,code", &button->code)) { |
163 | dev_err(dev, "Button without keycode: 0x%x\n", | 161 | dev_err(dev, "Button without keycode: 0x%x\n", |
164 | button->gpio); | 162 | button->gpio); |
165 | error = -EINVAL; | 163 | return ERR_PTR(-EINVAL); |
166 | goto err_free_pdata; | ||
167 | } | 164 | } |
168 | 165 | ||
169 | button->desc = of_get_property(pp, "label", NULL); | 166 | button->desc = of_get_property(pp, "label", NULL); |
@@ -178,20 +175,13 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct | |||
178 | button->debounce_interval = 5; | 175 | button->debounce_interval = 5; |
179 | } | 176 | } |
180 | 177 | ||
181 | if (pdata->nbuttons == 0) { | 178 | if (pdata->nbuttons == 0) |
182 | error = -EINVAL; | 179 | return ERR_PTR(-EINVAL); |
183 | goto err_free_pdata; | ||
184 | } | ||
185 | 180 | ||
186 | return pdata; | 181 | return pdata; |
187 | |||
188 | err_free_pdata: | ||
189 | kfree(pdata); | ||
190 | err_out: | ||
191 | return ERR_PTR(error); | ||
192 | } | 182 | } |
193 | 183 | ||
194 | static struct of_device_id gpio_keys_polled_of_match[] = { | 184 | static const struct of_device_id gpio_keys_polled_of_match[] = { |
195 | { .compatible = "gpio-keys-polled", }, | 185 | { .compatible = "gpio-keys-polled", }, |
196 | { }, | 186 | { }, |
197 | }; | 187 | }; |
@@ -213,6 +203,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
213 | struct gpio_keys_polled_dev *bdev; | 203 | struct gpio_keys_polled_dev *bdev; |
214 | struct input_polled_dev *poll_dev; | 204 | struct input_polled_dev *poll_dev; |
215 | struct input_dev *input; | 205 | struct input_dev *input; |
206 | size_t size; | ||
216 | int error; | 207 | int error; |
217 | int i; | 208 | int i; |
218 | 209 | ||
@@ -228,24 +219,21 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
228 | 219 | ||
229 | if (!pdata->poll_interval) { | 220 | if (!pdata->poll_interval) { |
230 | dev_err(dev, "missing poll_interval value\n"); | 221 | dev_err(dev, "missing poll_interval value\n"); |
231 | error = -EINVAL; | 222 | return -EINVAL; |
232 | goto err_free_pdata; | ||
233 | } | 223 | } |
234 | 224 | ||
235 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + | 225 | size = sizeof(struct gpio_keys_polled_dev) + |
236 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), | 226 | pdata->nbuttons * sizeof(struct gpio_keys_button_data); |
237 | GFP_KERNEL); | 227 | bdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
238 | if (!bdev) { | 228 | if (!bdev) { |
239 | dev_err(dev, "no memory for private data\n"); | 229 | dev_err(dev, "no memory for private data\n"); |
240 | error = -ENOMEM; | 230 | return -ENOMEM; |
241 | goto err_free_pdata; | ||
242 | } | 231 | } |
243 | 232 | ||
244 | poll_dev = input_allocate_polled_device(); | 233 | poll_dev = devm_input_allocate_polled_device(&pdev->dev); |
245 | if (!poll_dev) { | 234 | if (!poll_dev) { |
246 | dev_err(dev, "no memory for polled device\n"); | 235 | dev_err(dev, "no memory for polled device\n"); |
247 | error = -ENOMEM; | 236 | return -ENOMEM; |
248 | goto err_free_bdev; | ||
249 | } | 237 | } |
250 | 238 | ||
251 | poll_dev->private = bdev; | 239 | poll_dev->private = bdev; |
@@ -258,7 +246,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
258 | 246 | ||
259 | input->name = pdev->name; | 247 | input->name = pdev->name; |
260 | input->phys = DRV_NAME"/input0"; | 248 | input->phys = DRV_NAME"/input0"; |
261 | input->dev.parent = &pdev->dev; | ||
262 | 249 | ||
263 | input->id.bustype = BUS_HOST; | 250 | input->id.bustype = BUS_HOST; |
264 | input->id.vendor = 0x0001; | 251 | input->id.vendor = 0x0001; |
@@ -277,16 +264,15 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
277 | 264 | ||
278 | if (button->wakeup) { | 265 | if (button->wakeup) { |
279 | dev_err(dev, DRV_NAME " does not support wakeup\n"); | 266 | dev_err(dev, DRV_NAME " does not support wakeup\n"); |
280 | error = -EINVAL; | 267 | return -EINVAL; |
281 | goto err_free_gpio; | ||
282 | } | 268 | } |
283 | 269 | ||
284 | error = gpio_request_one(gpio, GPIOF_IN, | 270 | error = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_IN, |
285 | button->desc ?: DRV_NAME); | 271 | button->desc ? : DRV_NAME); |
286 | if (error) { | 272 | if (error) { |
287 | dev_err(dev, "unable to claim gpio %u, err=%d\n", | 273 | dev_err(dev, "unable to claim gpio %u, err=%d\n", |
288 | gpio, error); | 274 | gpio, error); |
289 | goto err_free_gpio; | 275 | return error; |
290 | } | 276 | } |
291 | 277 | ||
292 | bdata->can_sleep = gpio_cansleep(gpio); | 278 | bdata->can_sleep = gpio_cansleep(gpio); |
@@ -306,7 +292,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
306 | if (error) { | 292 | if (error) { |
307 | dev_err(dev, "unable to register polled device, err=%d\n", | 293 | dev_err(dev, "unable to register polled device, err=%d\n", |
308 | error); | 294 | error); |
309 | goto err_free_gpio; | 295 | return error; |
310 | } | 296 | } |
311 | 297 | ||
312 | /* report initial state of the buttons */ | 298 | /* report initial state of the buttons */ |
@@ -315,52 +301,10 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
315 | &bdev->data[i]); | 301 | &bdev->data[i]); |
316 | 302 | ||
317 | return 0; | 303 | return 0; |
318 | |||
319 | err_free_gpio: | ||
320 | while (--i >= 0) | ||
321 | gpio_free(pdata->buttons[i].gpio); | ||
322 | |||
323 | input_free_polled_device(poll_dev); | ||
324 | |||
325 | err_free_bdev: | ||
326 | kfree(bdev); | ||
327 | |||
328 | err_free_pdata: | ||
329 | /* If we have no platform_data, we allocated pdata dynamically. */ | ||
330 | if (!dev_get_platdata(&pdev->dev)) | ||
331 | kfree(pdata); | ||
332 | |||
333 | return error; | ||
334 | } | ||
335 | |||
336 | static int gpio_keys_polled_remove(struct platform_device *pdev) | ||
337 | { | ||
338 | struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); | ||
339 | const struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
340 | int i; | ||
341 | |||
342 | input_unregister_polled_device(bdev->poll_dev); | ||
343 | |||
344 | for (i = 0; i < pdata->nbuttons; i++) | ||
345 | gpio_free(pdata->buttons[i].gpio); | ||
346 | |||
347 | input_free_polled_device(bdev->poll_dev); | ||
348 | |||
349 | /* | ||
350 | * If we had no platform_data, we allocated pdata dynamically and | ||
351 | * must free it here. | ||
352 | */ | ||
353 | if (!dev_get_platdata(&pdev->dev)) | ||
354 | kfree(pdata); | ||
355 | |||
356 | kfree(bdev); | ||
357 | |||
358 | return 0; | ||
359 | } | 304 | } |
360 | 305 | ||
361 | static struct platform_driver gpio_keys_polled_driver = { | 306 | static struct platform_driver gpio_keys_polled_driver = { |
362 | .probe = gpio_keys_polled_probe, | 307 | .probe = gpio_keys_polled_probe, |
363 | .remove = gpio_keys_polled_remove, | ||
364 | .driver = { | 308 | .driver = { |
365 | .name = DRV_NAME, | 309 | .name = DRV_NAME, |
366 | .owner = THIS_MODULE, | 310 | .owner = THIS_MODULE, |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 97ec33572e56..8280cb16260b 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -415,7 +415,7 @@ open_err: | |||
415 | } | 415 | } |
416 | 416 | ||
417 | #ifdef CONFIG_OF | 417 | #ifdef CONFIG_OF |
418 | static struct of_device_id imx_keypad_of_match[] = { | 418 | static const struct of_device_id imx_keypad_of_match[] = { |
419 | { .compatible = "fsl,imx21-kpp", }, | 419 | { .compatible = "fsl,imx21-kpp", }, |
420 | { /* sentinel */ } | 420 | { /* sentinel */ } |
421 | }; | 421 | }; |
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 69b1f002ff52..0ba4428da24a 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | ||
19 | #include <linux/input.h> | 20 | #include <linux/input.h> |
20 | #include <linux/input-polldev.h> | 21 | #include <linux/input-polldev.h> |
21 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
@@ -185,14 +186,15 @@ static int jornada680kbd_probe(struct platform_device *pdev) | |||
185 | struct input_dev *input_dev; | 186 | struct input_dev *input_dev; |
186 | int i, error; | 187 | int i, error; |
187 | 188 | ||
188 | jornadakbd = kzalloc(sizeof(struct jornadakbd), GFP_KERNEL); | 189 | jornadakbd = devm_kzalloc(&pdev->dev, sizeof(struct jornadakbd), |
190 | GFP_KERNEL); | ||
189 | if (!jornadakbd) | 191 | if (!jornadakbd) |
190 | return -ENOMEM; | 192 | return -ENOMEM; |
191 | 193 | ||
192 | poll_dev = input_allocate_polled_device(); | 194 | poll_dev = devm_input_allocate_polled_device(&pdev->dev); |
193 | if (!poll_dev) { | 195 | if (!poll_dev) { |
194 | error = -ENOMEM; | 196 | dev_err(&pdev->dev, "failed to allocate polled input device\n"); |
195 | goto failed; | 197 | return -ENOMEM; |
196 | } | 198 | } |
197 | 199 | ||
198 | platform_set_drvdata(pdev, jornadakbd); | 200 | platform_set_drvdata(pdev, jornadakbd); |
@@ -224,27 +226,10 @@ static int jornada680kbd_probe(struct platform_device *pdev) | |||
224 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 226 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
225 | 227 | ||
226 | error = input_register_polled_device(jornadakbd->poll_dev); | 228 | error = input_register_polled_device(jornadakbd->poll_dev); |
227 | if (error) | 229 | if (error) { |
228 | goto failed; | 230 | dev_err(&pdev->dev, "failed to register polled input device\n"); |
229 | 231 | return error; | |
230 | return 0; | 232 | } |
231 | |||
232 | failed: | ||
233 | printk(KERN_ERR "Jornadakbd: failed to register driver, error: %d\n", | ||
234 | error); | ||
235 | input_free_polled_device(poll_dev); | ||
236 | kfree(jornadakbd); | ||
237 | return error; | ||
238 | |||
239 | } | ||
240 | |||
241 | static int jornada680kbd_remove(struct platform_device *pdev) | ||
242 | { | ||
243 | struct jornadakbd *jornadakbd = platform_get_drvdata(pdev); | ||
244 | |||
245 | input_unregister_polled_device(jornadakbd->poll_dev); | ||
246 | input_free_polled_device(jornadakbd->poll_dev); | ||
247 | kfree(jornadakbd); | ||
248 | 233 | ||
249 | return 0; | 234 | return 0; |
250 | } | 235 | } |
@@ -255,7 +240,6 @@ static struct platform_driver jornada680kbd_driver = { | |||
255 | .owner = THIS_MODULE, | 240 | .owner = THIS_MODULE, |
256 | }, | 241 | }, |
257 | .probe = jornada680kbd_probe, | 242 | .probe = jornada680kbd_probe, |
258 | .remove = jornada680kbd_remove, | ||
259 | }; | 243 | }; |
260 | module_platform_driver(jornada680kbd_driver); | 244 | module_platform_driver(jornada680kbd_driver); |
261 | 245 | ||
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 1da8e0b44b56..375b05ca8e2a 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c | |||
@@ -147,7 +147,7 @@ static int mcs_touchkey_probe(struct i2c_client *client, | |||
147 | } | 147 | } |
148 | dev_info(&client->dev, "Firmware version: %d\n", fw_ver); | 148 | dev_info(&client->dev, "Firmware version: %d\n", fw_ver); |
149 | 149 | ||
150 | input_dev->name = "MELPAS MCS Touchkey"; | 150 | input_dev->name = "MELFAS MCS Touchkey"; |
151 | input_dev->id.bustype = BUS_I2C; | 151 | input_dev->id.bustype = BUS_I2C; |
152 | input_dev->dev.parent = &client->dev; | 152 | input_dev->dev.parent = &client->dev; |
153 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | 153 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 0400b3f2b4b9..024b7bdffe5b 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c | |||
@@ -28,11 +28,10 @@ | |||
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/of.h> | 29 | #include <linux/of.h> |
30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
31 | #include <linux/input/matrix_keypad.h> | ||
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
32 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
33 | 34 | ||
34 | #include <linux/platform_data/omap4-keypad.h> | ||
35 | |||
36 | /* OMAP4 registers */ | 35 | /* OMAP4 registers */ |
37 | #define OMAP4_KBD_REVISION 0x00 | 36 | #define OMAP4_KBD_REVISION 0x00 |
38 | #define OMAP4_KBD_SYSCONFIG 0x10 | 37 | #define OMAP4_KBD_SYSCONFIG 0x10 |
@@ -218,7 +217,6 @@ static void omap4_keypad_close(struct input_dev *input) | |||
218 | pm_runtime_put_sync(input->dev.parent); | 217 | pm_runtime_put_sync(input->dev.parent); |
219 | } | 218 | } |
220 | 219 | ||
221 | #ifdef CONFIG_OF | ||
222 | static int omap4_keypad_parse_dt(struct device *dev, | 220 | static int omap4_keypad_parse_dt(struct device *dev, |
223 | struct omap4_keypad *keypad_data) | 221 | struct omap4_keypad *keypad_data) |
224 | { | 222 | { |
@@ -235,20 +233,9 @@ static int omap4_keypad_parse_dt(struct device *dev, | |||
235 | 233 | ||
236 | return 0; | 234 | return 0; |
237 | } | 235 | } |
238 | #else | ||
239 | static inline int omap4_keypad_parse_dt(struct device *dev, | ||
240 | struct omap4_keypad *keypad_data) | ||
241 | { | ||
242 | return -ENOSYS; | ||
243 | } | ||
244 | #endif | ||
245 | 236 | ||
246 | static int omap4_keypad_probe(struct platform_device *pdev) | 237 | static int omap4_keypad_probe(struct platform_device *pdev) |
247 | { | 238 | { |
248 | const struct omap4_keypad_platform_data *pdata = | ||
249 | dev_get_platdata(&pdev->dev); | ||
250 | const struct matrix_keymap_data *keymap_data = | ||
251 | pdata ? pdata->keymap_data : NULL; | ||
252 | struct omap4_keypad *keypad_data; | 239 | struct omap4_keypad *keypad_data; |
253 | struct input_dev *input_dev; | 240 | struct input_dev *input_dev; |
254 | struct resource *res; | 241 | struct resource *res; |
@@ -277,14 +264,9 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
277 | 264 | ||
278 | keypad_data->irq = irq; | 265 | keypad_data->irq = irq; |
279 | 266 | ||
280 | if (pdata) { | 267 | error = omap4_keypad_parse_dt(&pdev->dev, keypad_data); |
281 | keypad_data->rows = pdata->rows; | 268 | if (error) |
282 | keypad_data->cols = pdata->cols; | 269 | return error; |
283 | } else { | ||
284 | error = omap4_keypad_parse_dt(&pdev->dev, keypad_data); | ||
285 | if (error) | ||
286 | return error; | ||
287 | } | ||
288 | 270 | ||
289 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 271 | res = request_mem_region(res->start, resource_size(res), pdev->name); |
290 | if (!res) { | 272 | if (!res) { |
@@ -363,7 +345,7 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
363 | goto err_free_input; | 345 | goto err_free_input; |
364 | } | 346 | } |
365 | 347 | ||
366 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 348 | error = matrix_keypad_build_keymap(NULL, NULL, |
367 | keypad_data->rows, keypad_data->cols, | 349 | keypad_data->rows, keypad_data->cols, |
368 | keypad_data->keymap, input_dev); | 350 | keypad_data->keymap, input_dev); |
369 | if (error) { | 351 | if (error) { |
@@ -434,13 +416,11 @@ static int omap4_keypad_remove(struct platform_device *pdev) | |||
434 | return 0; | 416 | return 0; |
435 | } | 417 | } |
436 | 418 | ||
437 | #ifdef CONFIG_OF | ||
438 | static const struct of_device_id omap_keypad_dt_match[] = { | 419 | static const struct of_device_id omap_keypad_dt_match[] = { |
439 | { .compatible = "ti,omap4-keypad" }, | 420 | { .compatible = "ti,omap4-keypad" }, |
440 | {}, | 421 | {}, |
441 | }; | 422 | }; |
442 | MODULE_DEVICE_TABLE(of, omap_keypad_dt_match); | 423 | MODULE_DEVICE_TABLE(of, omap_keypad_dt_match); |
443 | #endif | ||
444 | 424 | ||
445 | #ifdef CONFIG_PM_SLEEP | 425 | #ifdef CONFIG_PM_SLEEP |
446 | static int omap4_keypad_suspend(struct device *dev) | 426 | static int omap4_keypad_suspend(struct device *dev) |
@@ -482,7 +462,7 @@ static struct platform_driver omap4_keypad_driver = { | |||
482 | .name = "omap4-keypad", | 462 | .name = "omap4-keypad", |
483 | .owner = THIS_MODULE, | 463 | .owner = THIS_MODULE, |
484 | .pm = &omap4_keypad_pm_ops, | 464 | .pm = &omap4_keypad_pm_ops, |
485 | .of_match_table = of_match_ptr(omap_keypad_dt_match), | 465 | .of_match_table = omap_keypad_dt_match, |
486 | }, | 466 | }, |
487 | }; | 467 | }; |
488 | module_platform_driver(omap4_keypad_driver); | 468 | module_platform_driver(omap4_keypad_driver); |
diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c new file mode 100644 index 000000000000..758b48731415 --- /dev/null +++ b/drivers/input/keyboard/st-keyscan.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * STMicroelectronics Key Scanning driver | ||
3 | * | ||
4 | * Copyright (c) 2014 STMicroelectonics Ltd. | ||
5 | * Author: Stuart Menefy <stuart.menefy@st.com> | ||
6 | * | ||
7 | * Based on sh_keysc.c, copyright 2008 Magnus Damm | ||
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 version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/input/matrix_keypad.h> | ||
20 | |||
21 | #define ST_KEYSCAN_MAXKEYS 16 | ||
22 | |||
23 | #define KEYSCAN_CONFIG_OFF 0x0 | ||
24 | #define KEYSCAN_CONFIG_ENABLE 0x1 | ||
25 | #define KEYSCAN_DEBOUNCE_TIME_OFF 0x4 | ||
26 | #define KEYSCAN_MATRIX_STATE_OFF 0x8 | ||
27 | #define KEYSCAN_MATRIX_DIM_OFF 0xc | ||
28 | #define KEYSCAN_MATRIX_DIM_X_SHIFT 0x0 | ||
29 | #define KEYSCAN_MATRIX_DIM_Y_SHIFT 0x2 | ||
30 | |||
31 | struct st_keyscan { | ||
32 | void __iomem *base; | ||
33 | int irq; | ||
34 | struct clk *clk; | ||
35 | struct input_dev *input_dev; | ||
36 | unsigned long last_state; | ||
37 | unsigned int n_rows; | ||
38 | unsigned int n_cols; | ||
39 | unsigned int debounce_us; | ||
40 | }; | ||
41 | |||
42 | static irqreturn_t keyscan_isr(int irq, void *dev_id) | ||
43 | { | ||
44 | struct st_keyscan *keypad = dev_id; | ||
45 | unsigned short *keycode = keypad->input_dev->keycode; | ||
46 | unsigned long state, change; | ||
47 | int bit_nr; | ||
48 | |||
49 | state = readl(keypad->base + KEYSCAN_MATRIX_STATE_OFF) & 0xffff; | ||
50 | change = keypad->last_state ^ state; | ||
51 | keypad->last_state = state; | ||
52 | |||
53 | for_each_set_bit(bit_nr, &change, BITS_PER_LONG) | ||
54 | input_report_key(keypad->input_dev, | ||
55 | keycode[bit_nr], state & BIT(bit_nr)); | ||
56 | |||
57 | input_sync(keypad->input_dev); | ||
58 | |||
59 | return IRQ_HANDLED; | ||
60 | } | ||
61 | |||
62 | static int keyscan_start(struct st_keyscan *keypad) | ||
63 | { | ||
64 | int error; | ||
65 | |||
66 | error = clk_enable(keypad->clk); | ||
67 | if (error) | ||
68 | return error; | ||
69 | |||
70 | writel(keypad->debounce_us * (clk_get_rate(keypad->clk) / 1000000), | ||
71 | keypad->base + KEYSCAN_DEBOUNCE_TIME_OFF); | ||
72 | |||
73 | writel(((keypad->n_cols - 1) << KEYSCAN_MATRIX_DIM_X_SHIFT) | | ||
74 | ((keypad->n_rows - 1) << KEYSCAN_MATRIX_DIM_Y_SHIFT), | ||
75 | keypad->base + KEYSCAN_MATRIX_DIM_OFF); | ||
76 | |||
77 | writel(KEYSCAN_CONFIG_ENABLE, keypad->base + KEYSCAN_CONFIG_OFF); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static void keyscan_stop(struct st_keyscan *keypad) | ||
83 | { | ||
84 | writel(0, keypad->base + KEYSCAN_CONFIG_OFF); | ||
85 | |||
86 | clk_disable(keypad->clk); | ||
87 | } | ||
88 | |||
89 | static int keyscan_open(struct input_dev *dev) | ||
90 | { | ||
91 | struct st_keyscan *keypad = input_get_drvdata(dev); | ||
92 | |||
93 | return keyscan_start(keypad); | ||
94 | } | ||
95 | |||
96 | static void keyscan_close(struct input_dev *dev) | ||
97 | { | ||
98 | struct st_keyscan *keypad = input_get_drvdata(dev); | ||
99 | |||
100 | keyscan_stop(keypad); | ||
101 | } | ||
102 | |||
103 | static int keypad_matrix_key_parse_dt(struct st_keyscan *keypad_data) | ||
104 | { | ||
105 | struct device *dev = keypad_data->input_dev->dev.parent; | ||
106 | struct device_node *np = dev->of_node; | ||
107 | int error; | ||
108 | |||
109 | error = matrix_keypad_parse_of_params(dev, &keypad_data->n_rows, | ||
110 | &keypad_data->n_cols); | ||
111 | if (error) { | ||
112 | dev_err(dev, "failed to parse keypad params\n"); | ||
113 | return error; | ||
114 | } | ||
115 | |||
116 | of_property_read_u32(np, "st,debounce-us", &keypad_data->debounce_us); | ||
117 | |||
118 | dev_dbg(dev, "n_rows=%d n_col=%d debounce=%d\n", | ||
119 | keypad_data->n_rows, keypad_data->n_cols, | ||
120 | keypad_data->debounce_us); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int keyscan_probe(struct platform_device *pdev) | ||
126 | { | ||
127 | struct st_keyscan *keypad_data; | ||
128 | struct input_dev *input_dev; | ||
129 | struct resource *res; | ||
130 | int error; | ||
131 | |||
132 | if (!pdev->dev.of_node) { | ||
133 | dev_err(&pdev->dev, "no DT data present\n"); | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | keypad_data = devm_kzalloc(&pdev->dev, sizeof(*keypad_data), | ||
138 | GFP_KERNEL); | ||
139 | if (!keypad_data) | ||
140 | return -ENOMEM; | ||
141 | |||
142 | input_dev = devm_input_allocate_device(&pdev->dev); | ||
143 | if (!input_dev) { | ||
144 | dev_err(&pdev->dev, "failed to allocate the input device\n"); | ||
145 | return -ENOMEM; | ||
146 | } | ||
147 | |||
148 | input_dev->name = pdev->name; | ||
149 | input_dev->phys = "keyscan-keys/input0"; | ||
150 | input_dev->dev.parent = &pdev->dev; | ||
151 | input_dev->open = keyscan_open; | ||
152 | input_dev->close = keyscan_close; | ||
153 | |||
154 | input_dev->id.bustype = BUS_HOST; | ||
155 | |||
156 | error = keypad_matrix_key_parse_dt(keypad_data); | ||
157 | if (error) | ||
158 | return error; | ||
159 | |||
160 | error = matrix_keypad_build_keymap(NULL, NULL, | ||
161 | keypad_data->n_rows, | ||
162 | keypad_data->n_cols, | ||
163 | NULL, input_dev); | ||
164 | if (error) { | ||
165 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
166 | return error; | ||
167 | } | ||
168 | |||
169 | input_set_drvdata(input_dev, keypad_data); | ||
170 | |||
171 | keypad_data->input_dev = input_dev; | ||
172 | |||
173 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
174 | keypad_data->base = devm_ioremap_resource(&pdev->dev, res); | ||
175 | if (IS_ERR(keypad_data->base)) | ||
176 | return PTR_ERR(keypad_data->base); | ||
177 | |||
178 | keypad_data->clk = devm_clk_get(&pdev->dev, NULL); | ||
179 | if (IS_ERR(keypad_data->clk)) { | ||
180 | dev_err(&pdev->dev, "cannot get clock\n"); | ||
181 | return PTR_ERR(keypad_data->clk); | ||
182 | } | ||
183 | |||
184 | error = clk_enable(keypad_data->clk); | ||
185 | if (error) { | ||
186 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
187 | return error; | ||
188 | } | ||
189 | |||
190 | keyscan_stop(keypad_data); | ||
191 | |||
192 | keypad_data->irq = platform_get_irq(pdev, 0); | ||
193 | if (keypad_data->irq < 0) { | ||
194 | dev_err(&pdev->dev, "no IRQ specified\n"); | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | |||
198 | error = devm_request_irq(&pdev->dev, keypad_data->irq, keyscan_isr, 0, | ||
199 | pdev->name, keypad_data); | ||
200 | if (error) { | ||
201 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
202 | return error; | ||
203 | } | ||
204 | |||
205 | error = input_register_device(input_dev); | ||
206 | if (error) { | ||
207 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
208 | return error; | ||
209 | } | ||
210 | |||
211 | platform_set_drvdata(pdev, keypad_data); | ||
212 | |||
213 | device_set_wakeup_capable(&pdev->dev, 1); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static int keyscan_suspend(struct device *dev) | ||
219 | { | ||
220 | struct platform_device *pdev = to_platform_device(dev); | ||
221 | struct st_keyscan *keypad = platform_get_drvdata(pdev); | ||
222 | struct input_dev *input = keypad->input_dev; | ||
223 | |||
224 | mutex_lock(&input->mutex); | ||
225 | |||
226 | if (device_may_wakeup(dev)) | ||
227 | enable_irq_wake(keypad->irq); | ||
228 | else if (input->users) | ||
229 | keyscan_stop(keypad); | ||
230 | |||
231 | mutex_unlock(&input->mutex); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int keyscan_resume(struct device *dev) | ||
236 | { | ||
237 | struct platform_device *pdev = to_platform_device(dev); | ||
238 | struct st_keyscan *keypad = platform_get_drvdata(pdev); | ||
239 | struct input_dev *input = keypad->input_dev; | ||
240 | int retval = 0; | ||
241 | |||
242 | mutex_lock(&input->mutex); | ||
243 | |||
244 | if (device_may_wakeup(dev)) | ||
245 | disable_irq_wake(keypad->irq); | ||
246 | else if (input->users) | ||
247 | retval = keyscan_start(keypad); | ||
248 | |||
249 | mutex_unlock(&input->mutex); | ||
250 | return retval; | ||
251 | } | ||
252 | |||
253 | static SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops, keyscan_suspend, keyscan_resume); | ||
254 | |||
255 | static const struct of_device_id keyscan_of_match[] = { | ||
256 | { .compatible = "st,sti-keyscan" }, | ||
257 | { }, | ||
258 | }; | ||
259 | MODULE_DEVICE_TABLE(of, keyscan_of_match); | ||
260 | |||
261 | static struct platform_driver keyscan_device_driver = { | ||
262 | .probe = keyscan_probe, | ||
263 | .driver = { | ||
264 | .name = "st-keyscan", | ||
265 | .pm = &keyscan_dev_pm_ops, | ||
266 | .of_match_table = of_match_ptr(keyscan_of_match), | ||
267 | } | ||
268 | }; | ||
269 | |||
270 | module_platform_driver(keyscan_device_driver); | ||
271 | |||
272 | MODULE_AUTHOR("Stuart Menefy <stuart.menefy@st.com>"); | ||
273 | MODULE_DESCRIPTION("STMicroelectronics keyscan device driver"); | ||
274 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index 74494a357522..ad7abae69078 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c | |||
@@ -296,6 +296,65 @@ static void tc3589x_keypad_close(struct input_dev *input) | |||
296 | tc3589x_keypad_disable(keypad); | 296 | tc3589x_keypad_disable(keypad); |
297 | } | 297 | } |
298 | 298 | ||
299 | #ifdef CONFIG_OF | ||
300 | static const struct tc3589x_keypad_platform_data * | ||
301 | tc3589x_keypad_of_probe(struct device *dev) | ||
302 | { | ||
303 | struct device_node *np = dev->of_node; | ||
304 | struct tc3589x_keypad_platform_data *plat; | ||
305 | u32 cols, rows; | ||
306 | u32 debounce_ms; | ||
307 | int proplen; | ||
308 | |||
309 | if (!np) | ||
310 | return ERR_PTR(-ENODEV); | ||
311 | |||
312 | plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL); | ||
313 | if (!plat) | ||
314 | return ERR_PTR(-ENOMEM); | ||
315 | |||
316 | of_property_read_u32(np, "keypad,num-columns", &cols); | ||
317 | of_property_read_u32(np, "keypad,num-rows", &rows); | ||
318 | plat->kcol = (u8) cols; | ||
319 | plat->krow = (u8) rows; | ||
320 | if (!plat->krow || !plat->kcol || | ||
321 | plat->krow > TC_KPD_ROWS || plat->kcol > TC_KPD_COLUMNS) { | ||
322 | dev_err(dev, | ||
323 | "keypad columns/rows not properly specified (%ux%u)\n", | ||
324 | plat->kcol, plat->krow); | ||
325 | return ERR_PTR(-EINVAL); | ||
326 | } | ||
327 | |||
328 | if (!of_get_property(np, "linux,keymap", &proplen)) { | ||
329 | dev_err(dev, "property linux,keymap not found\n"); | ||
330 | return ERR_PTR(-ENOENT); | ||
331 | } | ||
332 | |||
333 | plat->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat"); | ||
334 | plat->enable_wakeup = of_property_read_bool(np, "linux,wakeup"); | ||
335 | |||
336 | /* The custom delay format is ms/16 */ | ||
337 | of_property_read_u32(np, "debounce-delay-ms", &debounce_ms); | ||
338 | if (debounce_ms) | ||
339 | plat->debounce_period = debounce_ms * 16; | ||
340 | else | ||
341 | plat->debounce_period = TC_KPD_DEBOUNCE_PERIOD; | ||
342 | |||
343 | plat->settle_time = TC_KPD_SETTLE_TIME; | ||
344 | /* FIXME: should be property of the IRQ resource? */ | ||
345 | plat->irqtype = IRQF_TRIGGER_FALLING; | ||
346 | |||
347 | return plat; | ||
348 | } | ||
349 | #else | ||
350 | static inline const struct tc3589x_keypad_platform_data * | ||
351 | tc3589x_keypad_of_probe(struct device *dev) | ||
352 | { | ||
353 | return ERR_PTR(-ENODEV); | ||
354 | } | ||
355 | #endif | ||
356 | |||
357 | |||
299 | static int tc3589x_keypad_probe(struct platform_device *pdev) | 358 | static int tc3589x_keypad_probe(struct platform_device *pdev) |
300 | { | 359 | { |
301 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); | 360 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); |
@@ -306,8 +365,11 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) | |||
306 | 365 | ||
307 | plat = tc3589x->pdata->keypad; | 366 | plat = tc3589x->pdata->keypad; |
308 | if (!plat) { | 367 | if (!plat) { |
309 | dev_err(&pdev->dev, "invalid keypad platform data\n"); | 368 | plat = tc3589x_keypad_of_probe(&pdev->dev); |
310 | return -EINVAL; | 369 | if (IS_ERR(plat)) { |
370 | dev_err(&pdev->dev, "invalid keypad platform data\n"); | ||
371 | return PTR_ERR(plat); | ||
372 | } | ||
311 | } | 373 | } |
312 | 374 | ||
313 | irq = platform_get_irq(pdev, 0); | 375 | irq = platform_get_irq(pdev, 0); |
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c index abd8453e5212..220ce0fa15d9 100644 --- a/drivers/input/misc/88pm860x_onkey.c +++ b/drivers/input/misc/88pm860x_onkey.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/mfd/88pm860x.h> | 27 | #include <linux/mfd/88pm860x.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/device.h> | ||
29 | 30 | ||
30 | #define PM8607_WAKEUP 0x0b | 31 | #define PM8607_WAKEUP 0x0b |
31 | 32 | ||
@@ -68,7 +69,8 @@ static int pm860x_onkey_probe(struct platform_device *pdev) | |||
68 | return -EINVAL; | 69 | return -EINVAL; |
69 | } | 70 | } |
70 | 71 | ||
71 | info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL); | 72 | info = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_onkey_info), |
73 | GFP_KERNEL); | ||
72 | if (!info) | 74 | if (!info) |
73 | return -ENOMEM; | 75 | return -ENOMEM; |
74 | info->chip = chip; | 76 | info->chip = chip; |
@@ -76,11 +78,10 @@ static int pm860x_onkey_probe(struct platform_device *pdev) | |||
76 | info->dev = &pdev->dev; | 78 | info->dev = &pdev->dev; |
77 | info->irq = irq; | 79 | info->irq = irq; |
78 | 80 | ||
79 | info->idev = input_allocate_device(); | 81 | info->idev = devm_input_allocate_device(&pdev->dev); |
80 | if (!info->idev) { | 82 | if (!info->idev) { |
81 | dev_err(chip->dev, "Failed to allocate input dev\n"); | 83 | dev_err(chip->dev, "Failed to allocate input dev\n"); |
82 | ret = -ENOMEM; | 84 | return -ENOMEM; |
83 | goto out; | ||
84 | } | 85 | } |
85 | 86 | ||
86 | info->idev->name = "88pm860x_on"; | 87 | info->idev->name = "88pm860x_on"; |
@@ -93,42 +94,22 @@ static int pm860x_onkey_probe(struct platform_device *pdev) | |||
93 | ret = input_register_device(info->idev); | 94 | ret = input_register_device(info->idev); |
94 | if (ret) { | 95 | if (ret) { |
95 | dev_err(chip->dev, "Can't register input device: %d\n", ret); | 96 | dev_err(chip->dev, "Can't register input device: %d\n", ret); |
96 | goto out_reg; | 97 | return ret; |
97 | } | 98 | } |
98 | 99 | ||
99 | ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler, | 100 | ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, |
100 | IRQF_ONESHOT, "onkey", info); | 101 | pm860x_onkey_handler, IRQF_ONESHOT, |
102 | "onkey", info); | ||
101 | if (ret < 0) { | 103 | if (ret < 0) { |
102 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | 104 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", |
103 | info->irq, ret); | 105 | info->irq, ret); |
104 | goto out_irq; | 106 | return ret; |
105 | } | 107 | } |
106 | 108 | ||
107 | platform_set_drvdata(pdev, info); | 109 | platform_set_drvdata(pdev, info); |
108 | device_init_wakeup(&pdev->dev, 1); | 110 | device_init_wakeup(&pdev->dev, 1); |
109 | 111 | ||
110 | return 0; | 112 | return 0; |
111 | |||
112 | out_irq: | ||
113 | input_unregister_device(info->idev); | ||
114 | kfree(info); | ||
115 | return ret; | ||
116 | |||
117 | out_reg: | ||
118 | input_free_device(info->idev); | ||
119 | out: | ||
120 | kfree(info); | ||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | static int pm860x_onkey_remove(struct platform_device *pdev) | ||
125 | { | ||
126 | struct pm860x_onkey_info *info = platform_get_drvdata(pdev); | ||
127 | |||
128 | free_irq(info->irq, info); | ||
129 | input_unregister_device(info->idev); | ||
130 | kfree(info); | ||
131 | return 0; | ||
132 | } | 113 | } |
133 | 114 | ||
134 | #ifdef CONFIG_PM_SLEEP | 115 | #ifdef CONFIG_PM_SLEEP |
@@ -161,7 +142,6 @@ static struct platform_driver pm860x_onkey_driver = { | |||
161 | .pm = &pm860x_onkey_pm_ops, | 142 | .pm = &pm860x_onkey_pm_ops, |
162 | }, | 143 | }, |
163 | .probe = pm860x_onkey_probe, | 144 | .probe = pm860x_onkey_probe, |
164 | .remove = pm860x_onkey_remove, | ||
165 | }; | 145 | }; |
166 | module_platform_driver(pm860x_onkey_driver); | 146 | module_platform_driver(pm860x_onkey_driver); |
167 | 147 | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 5928ea71dd69..2ff4425a893b 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -224,7 +224,7 @@ config INPUT_GP2A | |||
224 | 224 | ||
225 | config INPUT_GPIO_BEEPER | 225 | config INPUT_GPIO_BEEPER |
226 | tristate "Generic GPIO Beeper support" | 226 | tristate "Generic GPIO Beeper support" |
227 | depends on OF_GPIO | 227 | depends on GPIOLIB |
228 | help | 228 | help |
229 | Say Y here if you have a beeper connected to a GPIO pin. | 229 | Say Y here if you have a beeper connected to a GPIO pin. |
230 | 230 | ||
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index f2fbdd88ed20..95ef7dd6442d 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * AB8500 Power-On Key handler | 7 | * AB8500 Power-On Key handler |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/device.h> | ||
10 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
11 | #include <linux/module.h> | 12 | #include <linux/module.h> |
12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
@@ -65,12 +66,14 @@ static int ab8500_ponkey_probe(struct platform_device *pdev) | |||
65 | return irq_dbr; | 66 | return irq_dbr; |
66 | } | 67 | } |
67 | 68 | ||
68 | ponkey = kzalloc(sizeof(struct ab8500_ponkey), GFP_KERNEL); | 69 | ponkey = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_ponkey), |
69 | input = input_allocate_device(); | 70 | GFP_KERNEL); |
70 | if (!ponkey || !input) { | 71 | if (!ponkey) |
71 | error = -ENOMEM; | 72 | return -ENOMEM; |
72 | goto err_free_mem; | 73 | |
73 | } | 74 | input = devm_input_allocate_device(&pdev->dev); |
75 | if (!input) | ||
76 | return -ENOMEM; | ||
74 | 77 | ||
75 | ponkey->idev = input; | 78 | ponkey->idev = input; |
76 | ponkey->ab8500 = ab8500; | 79 | ponkey->ab8500 = ab8500; |
@@ -82,52 +85,32 @@ static int ab8500_ponkey_probe(struct platform_device *pdev) | |||
82 | 85 | ||
83 | input_set_capability(input, EV_KEY, KEY_POWER); | 86 | input_set_capability(input, EV_KEY, KEY_POWER); |
84 | 87 | ||
85 | error = request_any_context_irq(ponkey->irq_dbf, ab8500_ponkey_handler, | 88 | error = devm_request_any_context_irq(&pdev->dev, ponkey->irq_dbf, |
86 | 0, "ab8500-ponkey-dbf", ponkey); | 89 | ab8500_ponkey_handler, 0, |
90 | "ab8500-ponkey-dbf", ponkey); | ||
87 | if (error < 0) { | 91 | if (error < 0) { |
88 | dev_err(ab8500->dev, "Failed to request dbf IRQ#%d: %d\n", | 92 | dev_err(ab8500->dev, "Failed to request dbf IRQ#%d: %d\n", |
89 | ponkey->irq_dbf, error); | 93 | ponkey->irq_dbf, error); |
90 | goto err_free_mem; | 94 | return error; |
91 | } | 95 | } |
92 | 96 | ||
93 | error = request_any_context_irq(ponkey->irq_dbr, ab8500_ponkey_handler, | 97 | error = devm_request_any_context_irq(&pdev->dev, ponkey->irq_dbr, |
94 | 0, "ab8500-ponkey-dbr", ponkey); | 98 | ab8500_ponkey_handler, 0, |
99 | "ab8500-ponkey-dbr", ponkey); | ||
95 | if (error < 0) { | 100 | if (error < 0) { |
96 | dev_err(ab8500->dev, "Failed to request dbr IRQ#%d: %d\n", | 101 | dev_err(ab8500->dev, "Failed to request dbr IRQ#%d: %d\n", |
97 | ponkey->irq_dbr, error); | 102 | ponkey->irq_dbr, error); |
98 | goto err_free_dbf_irq; | 103 | return error; |
99 | } | 104 | } |
100 | 105 | ||
101 | error = input_register_device(ponkey->idev); | 106 | error = input_register_device(ponkey->idev); |
102 | if (error) { | 107 | if (error) { |
103 | dev_err(ab8500->dev, "Can't register input device: %d\n", error); | 108 | dev_err(ab8500->dev, "Can't register input device: %d\n", error); |
104 | goto err_free_dbr_irq; | 109 | return error; |
105 | } | 110 | } |
106 | 111 | ||
107 | platform_set_drvdata(pdev, ponkey); | 112 | platform_set_drvdata(pdev, ponkey); |
108 | return 0; | 113 | return 0; |
109 | |||
110 | err_free_dbr_irq: | ||
111 | free_irq(ponkey->irq_dbr, ponkey); | ||
112 | err_free_dbf_irq: | ||
113 | free_irq(ponkey->irq_dbf, ponkey); | ||
114 | err_free_mem: | ||
115 | input_free_device(input); | ||
116 | kfree(ponkey); | ||
117 | |||
118 | return error; | ||
119 | } | ||
120 | |||
121 | static int ab8500_ponkey_remove(struct platform_device *pdev) | ||
122 | { | ||
123 | struct ab8500_ponkey *ponkey = platform_get_drvdata(pdev); | ||
124 | |||
125 | free_irq(ponkey->irq_dbf, ponkey); | ||
126 | free_irq(ponkey->irq_dbr, ponkey); | ||
127 | input_unregister_device(ponkey->idev); | ||
128 | kfree(ponkey); | ||
129 | |||
130 | return 0; | ||
131 | } | 114 | } |
132 | 115 | ||
133 | #ifdef CONFIG_OF | 116 | #ifdef CONFIG_OF |
@@ -144,7 +127,6 @@ static struct platform_driver ab8500_ponkey_driver = { | |||
144 | .of_match_table = of_match_ptr(ab8500_ponkey_match), | 127 | .of_match_table = of_match_ptr(ab8500_ponkey_match), |
145 | }, | 128 | }, |
146 | .probe = ab8500_ponkey_probe, | 129 | .probe = ab8500_ponkey_probe, |
147 | .remove = ab8500_ponkey_remove, | ||
148 | }; | 130 | }; |
149 | module_platform_driver(ab8500_ponkey_driver); | 131 | module_platform_driver(ab8500_ponkey_driver); |
150 | 132 | ||
diff --git a/drivers/input/misc/gpio-beeper.c b/drivers/input/misc/gpio-beeper.c index b757435e2b3d..8886af63eae3 100644 --- a/drivers/input/misc/gpio-beeper.c +++ b/drivers/input/misc/gpio-beeper.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Generic GPIO beeper driver | 2 | * Generic GPIO beeper driver |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru> | 4 | * Copyright (C) 2013-2014 Alexander Shiyan <shc_work@mail.ru> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -11,7 +11,8 @@ | |||
11 | 11 | ||
12 | #include <linux/input.h> | 12 | #include <linux/input.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/of_gpio.h> | 14 | #include <linux/gpio/consumer.h> |
15 | #include <linux/of.h> | ||
15 | #include <linux/workqueue.h> | 16 | #include <linux/workqueue.h> |
16 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
17 | 18 | ||
@@ -19,14 +20,13 @@ | |||
19 | 20 | ||
20 | struct gpio_beeper { | 21 | struct gpio_beeper { |
21 | struct work_struct work; | 22 | struct work_struct work; |
22 | int gpio; | 23 | struct gpio_desc *desc; |
23 | bool active_low; | ||
24 | bool beeping; | 24 | bool beeping; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static void gpio_beeper_toggle(struct gpio_beeper *beep, bool on) | 27 | static void gpio_beeper_toggle(struct gpio_beeper *beep, bool on) |
28 | { | 28 | { |
29 | gpio_set_value_cansleep(beep->gpio, on ^ beep->active_low); | 29 | gpiod_set_value_cansleep(beep->desc, on); |
30 | } | 30 | } |
31 | 31 | ||
32 | static void gpio_beeper_work(struct work_struct *work) | 32 | static void gpio_beeper_work(struct work_struct *work) |
@@ -65,18 +65,16 @@ static void gpio_beeper_close(struct input_dev *input) | |||
65 | static int gpio_beeper_probe(struct platform_device *pdev) | 65 | static int gpio_beeper_probe(struct platform_device *pdev) |
66 | { | 66 | { |
67 | struct gpio_beeper *beep; | 67 | struct gpio_beeper *beep; |
68 | enum of_gpio_flags flags; | ||
69 | struct input_dev *input; | 68 | struct input_dev *input; |
70 | unsigned long gflags; | ||
71 | int err; | 69 | int err; |
72 | 70 | ||
73 | beep = devm_kzalloc(&pdev->dev, sizeof(*beep), GFP_KERNEL); | 71 | beep = devm_kzalloc(&pdev->dev, sizeof(*beep), GFP_KERNEL); |
74 | if (!beep) | 72 | if (!beep) |
75 | return -ENOMEM; | 73 | return -ENOMEM; |
76 | 74 | ||
77 | beep->gpio = of_get_gpio_flags(pdev->dev.of_node, 0, &flags); | 75 | beep->desc = devm_gpiod_get(&pdev->dev, NULL); |
78 | if (!gpio_is_valid(beep->gpio)) | 76 | if (IS_ERR(beep->desc)) |
79 | return beep->gpio; | 77 | return PTR_ERR(beep->desc); |
80 | 78 | ||
81 | input = devm_input_allocate_device(&pdev->dev); | 79 | input = devm_input_allocate_device(&pdev->dev); |
82 | if (!input) | 80 | if (!input) |
@@ -94,10 +92,7 @@ static int gpio_beeper_probe(struct platform_device *pdev) | |||
94 | 92 | ||
95 | input_set_capability(input, EV_SND, SND_BELL); | 93 | input_set_capability(input, EV_SND, SND_BELL); |
96 | 94 | ||
97 | beep->active_low = flags & OF_GPIO_ACTIVE_LOW; | 95 | err = gpiod_direction_output(beep->desc, 0); |
98 | gflags = beep->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; | ||
99 | |||
100 | err = devm_gpio_request_one(&pdev->dev, beep->gpio, gflags, pdev->name); | ||
101 | if (err) | 96 | if (err) |
102 | return err; | 97 | return err; |
103 | 98 | ||
@@ -106,17 +101,19 @@ static int gpio_beeper_probe(struct platform_device *pdev) | |||
106 | return input_register_device(input); | 101 | return input_register_device(input); |
107 | } | 102 | } |
108 | 103 | ||
109 | static struct of_device_id gpio_beeper_of_match[] = { | 104 | #ifdef CONFIG_OF |
105 | static const struct of_device_id gpio_beeper_of_match[] = { | ||
110 | { .compatible = BEEPER_MODNAME, }, | 106 | { .compatible = BEEPER_MODNAME, }, |
111 | { } | 107 | { } |
112 | }; | 108 | }; |
113 | MODULE_DEVICE_TABLE(of, gpio_beeper_of_match); | 109 | MODULE_DEVICE_TABLE(of, gpio_beeper_of_match); |
110 | #endif | ||
114 | 111 | ||
115 | static struct platform_driver gpio_beeper_platform_driver = { | 112 | static struct platform_driver gpio_beeper_platform_driver = { |
116 | .driver = { | 113 | .driver = { |
117 | .name = BEEPER_MODNAME, | 114 | .name = BEEPER_MODNAME, |
118 | .owner = THIS_MODULE, | 115 | .owner = THIS_MODULE, |
119 | .of_match_table = gpio_beeper_of_match, | 116 | .of_match_table = of_match_ptr(gpio_beeper_of_match), |
120 | }, | 117 | }, |
121 | .probe = gpio_beeper_probe, | 118 | .probe = gpio_beeper_probe, |
122 | }; | 119 | }; |
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 5a736397d9c8..719410feb84b 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c | |||
@@ -1566,6 +1566,7 @@ static int ims_pcu_buffers_alloc(struct ims_pcu *pcu) | |||
1566 | if (!pcu->urb_ctrl_buf) { | 1566 | if (!pcu->urb_ctrl_buf) { |
1567 | dev_err(pcu->dev, | 1567 | dev_err(pcu->dev, |
1568 | "Failed to allocate memory for read buffer\n"); | 1568 | "Failed to allocate memory for read buffer\n"); |
1569 | error = -ENOMEM; | ||
1569 | goto err_free_urb_out_buf; | 1570 | goto err_free_urb_out_buf; |
1570 | } | 1571 | } |
1571 | 1572 | ||
diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c index eef41cfc054d..3809618e6a5d 100644 --- a/drivers/input/misc/max8925_onkey.c +++ b/drivers/input/misc/max8925_onkey.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/mfd/max8925.h> | 27 | #include <linux/mfd/max8925.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/device.h> | ||
29 | 30 | ||
30 | #define SW_INPUT (1 << 7) /* 0/1 -- up/down */ | 31 | #define SW_INPUT (1 << 7) /* 0/1 -- up/down */ |
31 | #define HARDRESET_EN (1 << 7) | 32 | #define HARDRESET_EN (1 << 7) |
@@ -81,12 +82,14 @@ static int max8925_onkey_probe(struct platform_device *pdev) | |||
81 | return -EINVAL; | 82 | return -EINVAL; |
82 | } | 83 | } |
83 | 84 | ||
84 | info = kzalloc(sizeof(struct max8925_onkey_info), GFP_KERNEL); | 85 | info = devm_kzalloc(&pdev->dev, sizeof(struct max8925_onkey_info), |
85 | input = input_allocate_device(); | 86 | GFP_KERNEL); |
86 | if (!info || !input) { | 87 | if (!info) |
87 | error = -ENOMEM; | 88 | return -ENOMEM; |
88 | goto err_free_mem; | 89 | |
89 | } | 90 | input = devm_input_allocate_device(&pdev->dev); |
91 | if (!input) | ||
92 | return -ENOMEM; | ||
90 | 93 | ||
91 | info->idev = input; | 94 | info->idev = input; |
92 | info->i2c = chip->i2c; | 95 | info->i2c = chip->i2c; |
@@ -100,55 +103,34 @@ static int max8925_onkey_probe(struct platform_device *pdev) | |||
100 | input->dev.parent = &pdev->dev; | 103 | input->dev.parent = &pdev->dev; |
101 | input_set_capability(input, EV_KEY, KEY_POWER); | 104 | input_set_capability(input, EV_KEY, KEY_POWER); |
102 | 105 | ||
103 | error = request_threaded_irq(irq[0], NULL, max8925_onkey_handler, | 106 | error = devm_request_threaded_irq(&pdev->dev, irq[0], NULL, |
104 | IRQF_ONESHOT, "onkey-down", info); | 107 | max8925_onkey_handler, IRQF_ONESHOT, |
108 | "onkey-down", info); | ||
105 | if (error < 0) { | 109 | if (error < 0) { |
106 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | 110 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", |
107 | irq[0], error); | 111 | irq[0], error); |
108 | goto err_free_mem; | 112 | return error; |
109 | } | 113 | } |
110 | 114 | ||
111 | error = request_threaded_irq(irq[1], NULL, max8925_onkey_handler, | 115 | error = devm_request_threaded_irq(&pdev->dev, irq[1], NULL, |
112 | IRQF_ONESHOT, "onkey-up", info); | 116 | max8925_onkey_handler, IRQF_ONESHOT, |
117 | "onkey-up", info); | ||
113 | if (error < 0) { | 118 | if (error < 0) { |
114 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | 119 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", |
115 | irq[1], error); | 120 | irq[1], error); |
116 | goto err_free_irq0; | 121 | return error; |
117 | } | 122 | } |
118 | 123 | ||
119 | error = input_register_device(info->idev); | 124 | error = input_register_device(info->idev); |
120 | if (error) { | 125 | if (error) { |
121 | dev_err(chip->dev, "Can't register input device: %d\n", error); | 126 | dev_err(chip->dev, "Can't register input device: %d\n", error); |
122 | goto err_free_irq1; | 127 | return error; |
123 | } | 128 | } |
124 | 129 | ||
125 | platform_set_drvdata(pdev, info); | 130 | platform_set_drvdata(pdev, info); |
126 | device_init_wakeup(&pdev->dev, 1); | 131 | device_init_wakeup(&pdev->dev, 1); |
127 | 132 | ||
128 | return 0; | 133 | return 0; |
129 | |||
130 | err_free_irq1: | ||
131 | free_irq(irq[1], info); | ||
132 | err_free_irq0: | ||
133 | free_irq(irq[0], info); | ||
134 | err_free_mem: | ||
135 | input_free_device(input); | ||
136 | kfree(info); | ||
137 | |||
138 | return error; | ||
139 | } | ||
140 | |||
141 | static int max8925_onkey_remove(struct platform_device *pdev) | ||
142 | { | ||
143 | struct max8925_onkey_info *info = platform_get_drvdata(pdev); | ||
144 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
145 | |||
146 | free_irq(info->irq[0] + chip->irq_base, info); | ||
147 | free_irq(info->irq[1] + chip->irq_base, info); | ||
148 | input_unregister_device(info->idev); | ||
149 | kfree(info); | ||
150 | |||
151 | return 0; | ||
152 | } | 134 | } |
153 | 135 | ||
154 | #ifdef CONFIG_PM_SLEEP | 136 | #ifdef CONFIG_PM_SLEEP |
@@ -190,7 +172,6 @@ static struct platform_driver max8925_onkey_driver = { | |||
190 | .pm = &max8925_onkey_pm_ops, | 172 | .pm = &max8925_onkey_pm_ops, |
191 | }, | 173 | }, |
192 | .probe = max8925_onkey_probe, | 174 | .probe = max8925_onkey_probe, |
193 | .remove = max8925_onkey_remove, | ||
194 | }; | 175 | }; |
195 | module_platform_driver(max8925_onkey_driver); | 176 | module_platform_driver(max8925_onkey_driver); |
196 | 177 | ||
diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c index 1fea5484941f..a363ebbd9cc0 100644 --- a/drivers/input/misc/max8997_haptic.c +++ b/drivers/input/misc/max8997_haptic.c | |||
@@ -181,11 +181,21 @@ static void max8997_haptic_enable(struct max8997_haptic *chip) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | if (!chip->enabled) { | 183 | if (!chip->enabled) { |
184 | chip->enabled = true; | 184 | error = regulator_enable(chip->regulator); |
185 | regulator_enable(chip->regulator); | 185 | if (error) { |
186 | dev_err(chip->dev, "Failed to enable regulator\n"); | ||
187 | goto out; | ||
188 | } | ||
186 | max8997_haptic_configure(chip); | 189 | max8997_haptic_configure(chip); |
187 | if (chip->mode == MAX8997_EXTERNAL_MODE) | 190 | if (chip->mode == MAX8997_EXTERNAL_MODE) { |
188 | pwm_enable(chip->pwm); | 191 | error = pwm_enable(chip->pwm); |
192 | if (error) { | ||
193 | dev_err(chip->dev, "Failed to enable PWM\n"); | ||
194 | regulator_disable(chip->regulator); | ||
195 | goto out; | ||
196 | } | ||
197 | } | ||
198 | chip->enabled = true; | ||
189 | } | 199 | } |
190 | 200 | ||
191 | out: | 201 | out: |
diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index 1cb8fda7a166..c91e3d33aea9 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c | |||
@@ -92,15 +92,15 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev) | |||
92 | bool pull_up; | 92 | bool pull_up; |
93 | 93 | ||
94 | if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay)) | 94 | if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay)) |
95 | kpd_delay = 0; | 95 | kpd_delay = 15625; |
96 | 96 | ||
97 | pull_up = of_property_read_bool(pdev->dev.of_node, "pull-up"); | 97 | if (kpd_delay > 62500 || kpd_delay == 0) { |
98 | |||
99 | if (kpd_delay > 62500) { | ||
100 | dev_err(&pdev->dev, "invalid power key trigger delay\n"); | 98 | dev_err(&pdev->dev, "invalid power key trigger delay\n"); |
101 | return -EINVAL; | 99 | return -EINVAL; |
102 | } | 100 | } |
103 | 101 | ||
102 | pull_up = of_property_read_bool(pdev->dev.of_node, "pull-up"); | ||
103 | |||
104 | regmap = dev_get_regmap(pdev->dev.parent, NULL); | 104 | regmap = dev_get_regmap(pdev->dev.parent, NULL); |
105 | if (!regmap) { | 105 | if (!regmap) { |
106 | dev_err(&pdev->dev, "failed to locate regmap for the device\n"); | 106 | dev_err(&pdev->dev, "failed to locate regmap for the device\n"); |
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 99b9e42aa748..93558a1c7f70 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
@@ -143,7 +143,7 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) | |||
143 | } | 143 | } |
144 | 144 | ||
145 | #ifdef CONFIG_OF | 145 | #ifdef CONFIG_OF |
146 | static struct of_device_id rotary_encoder_of_match[] = { | 146 | static const struct of_device_id rotary_encoder_of_match[] = { |
147 | { .compatible = "rotary-encoder", }, | 147 | { .compatible = "rotary-encoder", }, |
148 | { }, | 148 | { }, |
149 | }; | 149 | }; |
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index 20c80f543d5e..5a6334be30b8 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/acpi.h> | 17 | #include <linux/acpi.h> |
18 | #include <linux/gpio/consumer.h> | 18 | #include <linux/gpio/consumer.h> |
19 | #include <linux/gpio_keys.h> | 19 | #include <linux/gpio_keys.h> |
20 | #include <linux/input.h> | ||
21 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
22 | #include <linux/pnp.h> | 21 | #include <linux/pnp.h> |
23 | 22 | ||
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 77dc23b94eb1..6d26eecc278c 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c | |||
@@ -262,7 +262,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
262 | struct vibra_info *info; | 262 | struct vibra_info *info; |
263 | int vddvibl_uV = 0; | 263 | int vddvibl_uV = 0; |
264 | int vddvibr_uV = 0; | 264 | int vddvibr_uV = 0; |
265 | int ret; | 265 | int error; |
266 | 266 | ||
267 | twl6040_core_node = of_find_node_by_name(twl6040_core_dev->of_node, | 267 | twl6040_core_node = of_find_node_by_name(twl6040_core_dev->of_node, |
268 | "vibra"); | 268 | "vibra"); |
@@ -309,12 +309,12 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
309 | 309 | ||
310 | mutex_init(&info->mutex); | 310 | mutex_init(&info->mutex); |
311 | 311 | ||
312 | ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, | 312 | error = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, |
313 | twl6040_vib_irq_handler, 0, | 313 | twl6040_vib_irq_handler, 0, |
314 | "twl6040_irq_vib", info); | 314 | "twl6040_irq_vib", info); |
315 | if (ret) { | 315 | if (error) { |
316 | dev_err(info->dev, "VIB IRQ request failed: %d\n", ret); | 316 | dev_err(info->dev, "VIB IRQ request failed: %d\n", error); |
317 | return ret; | 317 | return error; |
318 | } | 318 | } |
319 | 319 | ||
320 | info->supplies[0].supply = "vddvibl"; | 320 | info->supplies[0].supply = "vddvibl"; |
@@ -323,40 +323,40 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
323 | * When booted with Device tree the regulators are attached to the | 323 | * When booted with Device tree the regulators are attached to the |
324 | * parent device (twl6040 MFD core) | 324 | * parent device (twl6040 MFD core) |
325 | */ | 325 | */ |
326 | ret = regulator_bulk_get(twl6040_core_dev, ARRAY_SIZE(info->supplies), | 326 | error = devm_regulator_bulk_get(twl6040_core_dev, |
327 | info->supplies); | 327 | ARRAY_SIZE(info->supplies), |
328 | if (ret) { | 328 | info->supplies); |
329 | dev_err(info->dev, "couldn't get regulators %d\n", ret); | 329 | if (error) { |
330 | return ret; | 330 | dev_err(info->dev, "couldn't get regulators %d\n", error); |
331 | return error; | ||
331 | } | 332 | } |
332 | 333 | ||
333 | if (vddvibl_uV) { | 334 | if (vddvibl_uV) { |
334 | ret = regulator_set_voltage(info->supplies[0].consumer, | 335 | error = regulator_set_voltage(info->supplies[0].consumer, |
335 | vddvibl_uV, vddvibl_uV); | 336 | vddvibl_uV, vddvibl_uV); |
336 | if (ret) { | 337 | if (error) { |
337 | dev_err(info->dev, "failed to set VDDVIBL volt %d\n", | 338 | dev_err(info->dev, "failed to set VDDVIBL volt %d\n", |
338 | ret); | 339 | error); |
339 | goto err_regulator; | 340 | return error; |
340 | } | 341 | } |
341 | } | 342 | } |
342 | 343 | ||
343 | if (vddvibr_uV) { | 344 | if (vddvibr_uV) { |
344 | ret = regulator_set_voltage(info->supplies[1].consumer, | 345 | error = regulator_set_voltage(info->supplies[1].consumer, |
345 | vddvibr_uV, vddvibr_uV); | 346 | vddvibr_uV, vddvibr_uV); |
346 | if (ret) { | 347 | if (error) { |
347 | dev_err(info->dev, "failed to set VDDVIBR volt %d\n", | 348 | dev_err(info->dev, "failed to set VDDVIBR volt %d\n", |
348 | ret); | 349 | error); |
349 | goto err_regulator; | 350 | return error; |
350 | } | 351 | } |
351 | } | 352 | } |
352 | 353 | ||
353 | INIT_WORK(&info->play_work, vibra_play_work); | 354 | INIT_WORK(&info->play_work, vibra_play_work); |
354 | 355 | ||
355 | info->input_dev = input_allocate_device(); | 356 | info->input_dev = devm_input_allocate_device(&pdev->dev); |
356 | if (info->input_dev == NULL) { | 357 | if (!info->input_dev) { |
357 | dev_err(info->dev, "couldn't allocate input device\n"); | 358 | dev_err(info->dev, "couldn't allocate input device\n"); |
358 | ret = -ENOMEM; | 359 | return -ENOMEM; |
359 | goto err_regulator; | ||
360 | } | 360 | } |
361 | 361 | ||
362 | input_set_drvdata(info->input_dev, info); | 362 | input_set_drvdata(info->input_dev, info); |
@@ -367,44 +367,25 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
367 | info->input_dev->close = twl6040_vibra_close; | 367 | info->input_dev->close = twl6040_vibra_close; |
368 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); | 368 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); |
369 | 369 | ||
370 | ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); | 370 | error = input_ff_create_memless(info->input_dev, NULL, vibra_play); |
371 | if (ret < 0) { | 371 | if (error) { |
372 | dev_err(info->dev, "couldn't register vibrator to FF\n"); | 372 | dev_err(info->dev, "couldn't register vibrator to FF\n"); |
373 | goto err_ialloc; | 373 | return error; |
374 | } | 374 | } |
375 | 375 | ||
376 | ret = input_register_device(info->input_dev); | 376 | error = input_register_device(info->input_dev); |
377 | if (ret < 0) { | 377 | if (error) { |
378 | dev_err(info->dev, "couldn't register input device\n"); | 378 | dev_err(info->dev, "couldn't register input device\n"); |
379 | goto err_iff; | 379 | return error; |
380 | } | 380 | } |
381 | 381 | ||
382 | platform_set_drvdata(pdev, info); | 382 | platform_set_drvdata(pdev, info); |
383 | 383 | ||
384 | return 0; | 384 | return 0; |
385 | |||
386 | err_iff: | ||
387 | input_ff_destroy(info->input_dev); | ||
388 | err_ialloc: | ||
389 | input_free_device(info->input_dev); | ||
390 | err_regulator: | ||
391 | regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies); | ||
392 | return ret; | ||
393 | } | ||
394 | |||
395 | static int twl6040_vibra_remove(struct platform_device *pdev) | ||
396 | { | ||
397 | struct vibra_info *info = platform_get_drvdata(pdev); | ||
398 | |||
399 | input_unregister_device(info->input_dev); | ||
400 | regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies); | ||
401 | |||
402 | return 0; | ||
403 | } | 385 | } |
404 | 386 | ||
405 | static struct platform_driver twl6040_vibra_driver = { | 387 | static struct platform_driver twl6040_vibra_driver = { |
406 | .probe = twl6040_vibra_probe, | 388 | .probe = twl6040_vibra_probe, |
407 | .remove = twl6040_vibra_remove, | ||
408 | .driver = { | 389 | .driver = { |
409 | .name = "twl6040-vibra", | 390 | .name = "twl6040-vibra", |
410 | .owner = THIS_MODULE, | 391 | .owner = THIS_MODULE, |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 6b8441f7bc32..366fc7ad5eb6 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -53,7 +53,7 @@ config MOUSE_PS2_LOGIPS2PP | |||
53 | default y | 53 | default y |
54 | depends on MOUSE_PS2 | 54 | depends on MOUSE_PS2 |
55 | help | 55 | help |
56 | Say Y here if you have a Logictech PS/2++ mouse connected to | 56 | Say Y here if you have a Logitech PS/2++ mouse connected to |
57 | your system. | 57 | your system. |
58 | 58 | ||
59 | If unsure, say Y. | 59 | If unsure, say Y. |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b96e978a37b7..ee2a04d90d20 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -473,8 +473,15 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse, | |||
473 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 473 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
474 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | 474 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); |
475 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | 475 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); |
476 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 476 | |
477 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 477 | /* For clickpads map both buttons to BTN_LEFT */ |
478 | if (etd->fw_version & 0x001000) { | ||
479 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); | ||
480 | } else { | ||
481 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | ||
482 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
483 | } | ||
484 | |||
478 | input_report_abs(dev, ABS_PRESSURE, pres); | 485 | input_report_abs(dev, ABS_PRESSURE, pres); |
479 | input_report_abs(dev, ABS_TOOL_WIDTH, width); | 486 | input_report_abs(dev, ABS_TOOL_WIDTH, width); |
480 | 487 | ||
@@ -484,10 +491,17 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse, | |||
484 | static void elantech_input_sync_v4(struct psmouse *psmouse) | 491 | static void elantech_input_sync_v4(struct psmouse *psmouse) |
485 | { | 492 | { |
486 | struct input_dev *dev = psmouse->dev; | 493 | struct input_dev *dev = psmouse->dev; |
494 | struct elantech_data *etd = psmouse->private; | ||
487 | unsigned char *packet = psmouse->packet; | 495 | unsigned char *packet = psmouse->packet; |
488 | 496 | ||
489 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 497 | /* For clickpads map both buttons to BTN_LEFT */ |
490 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 498 | if (etd->fw_version & 0x001000) { |
499 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); | ||
500 | } else { | ||
501 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | ||
502 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
503 | } | ||
504 | |||
491 | input_mt_report_pointer_emulation(dev, true); | 505 | input_mt_report_pointer_emulation(dev, true); |
492 | input_sync(dev); | 506 | input_sync(dev); |
493 | } | 507 | } |
@@ -835,7 +849,7 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
835 | if (etd->set_hw_resolution) | 849 | if (etd->set_hw_resolution) |
836 | etd->reg_10 = 0x0b; | 850 | etd->reg_10 = 0x0b; |
837 | else | 851 | else |
838 | etd->reg_10 = 0x03; | 852 | etd->reg_10 = 0x01; |
839 | 853 | ||
840 | if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) | 854 | if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) |
841 | rc = -1; | 855 | rc = -1; |
@@ -1336,7 +1350,8 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
1336 | } | 1350 | } |
1337 | 1351 | ||
1338 | /* | 1352 | /* |
1339 | * Some hw_version 3 models go into error state when we try to set bit 3 of r10 | 1353 | * Some hw_version 3 models go into error state when we try to set |
1354 | * bit 3 and/or bit 1 of r10. | ||
1340 | */ | 1355 | */ |
1341 | static const struct dmi_system_id no_hw_res_dmi_table[] = { | 1356 | static const struct dmi_system_id no_hw_res_dmi_table[] = { |
1342 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | 1357 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index c5ec703c727e..ec772d962f06 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -347,15 +347,6 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
347 | unsigned char resp[3]; | 347 | unsigned char resp[3]; |
348 | int i; | 348 | int i; |
349 | 349 | ||
350 | for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) | ||
351 | if (matches_pnp_id(psmouse, min_max_pnpid_table[i].pnp_ids)) { | ||
352 | priv->x_min = min_max_pnpid_table[i].x_min; | ||
353 | priv->x_max = min_max_pnpid_table[i].x_max; | ||
354 | priv->y_min = min_max_pnpid_table[i].y_min; | ||
355 | priv->y_max = min_max_pnpid_table[i].y_max; | ||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | if (SYN_ID_MAJOR(priv->identity) < 4) | 350 | if (SYN_ID_MAJOR(priv->identity) < 4) |
360 | return 0; | 351 | return 0; |
361 | 352 | ||
@@ -366,6 +357,16 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
366 | } | 357 | } |
367 | } | 358 | } |
368 | 359 | ||
360 | for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { | ||
361 | if (matches_pnp_id(psmouse, min_max_pnpid_table[i].pnp_ids)) { | ||
362 | priv->x_min = min_max_pnpid_table[i].x_min; | ||
363 | priv->x_max = min_max_pnpid_table[i].x_max; | ||
364 | priv->y_min = min_max_pnpid_table[i].y_min; | ||
365 | priv->y_max = min_max_pnpid_table[i].y_max; | ||
366 | return 0; | ||
367 | } | ||
368 | } | ||
369 | |||
369 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && | 370 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
370 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { | 371 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
371 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { | 372 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { |
diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c index 17e01a807ddc..98be824544a5 100644 --- a/drivers/input/serio/apbps2.c +++ b/drivers/input/serio/apbps2.c | |||
@@ -203,7 +203,7 @@ static int apbps2_of_remove(struct platform_device *of_dev) | |||
203 | return 0; | 203 | return 0; |
204 | } | 204 | } |
205 | 205 | ||
206 | static struct of_device_id apbps2_of_match[] = { | 206 | static const struct of_device_id apbps2_of_match[] = { |
207 | { .name = "GAISLER_APBPS2", }, | 207 | { .name = "GAISLER_APBPS2", }, |
208 | { .name = "01_060", }, | 208 | { .name = "01_060", }, |
209 | {} | 209 | {} |
diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c index 5d2fe7ece7ca..d906f3ebc8c8 100644 --- a/drivers/input/serio/olpc_apsp.c +++ b/drivers/input/serio/olpc_apsp.c | |||
@@ -262,7 +262,7 @@ static int olpc_apsp_remove(struct platform_device *pdev) | |||
262 | return 0; | 262 | return 0; |
263 | } | 263 | } |
264 | 264 | ||
265 | static struct of_device_id olpc_apsp_dt_ids[] = { | 265 | static const struct of_device_id olpc_apsp_dt_ids[] = { |
266 | { .compatible = "olpc,ap-sp", }, | 266 | { .compatible = "olpc,ap-sp", }, |
267 | {} | 267 | {} |
268 | }; | 268 | }; |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 611fc3905d00..2c613cd41dd6 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -349,6 +349,7 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
349 | break; | 349 | break; |
350 | 350 | ||
351 | case MTTPC: | 351 | case MTTPC: |
352 | case MTTPC_B: | ||
352 | features->pktlen = WACOM_PKGLEN_MTTPC; | 353 | features->pktlen = WACOM_PKGLEN_MTTPC; |
353 | break; | 354 | break; |
354 | 355 | ||
@@ -380,6 +381,16 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
380 | i += 12; | 381 | i += 12; |
381 | break; | 382 | break; |
382 | 383 | ||
384 | case MTTPC_B: | ||
385 | features->x_max = | ||
386 | get_unaligned_le16(&report[i + 3]); | ||
387 | features->x_phy = | ||
388 | get_unaligned_le16(&report[i + 6]); | ||
389 | features->unit = report[i - 5]; | ||
390 | features->unitExpo = report[i - 3]; | ||
391 | i += 9; | ||
392 | break; | ||
393 | |||
383 | default: | 394 | default: |
384 | features->x_max = | 395 | features->x_max = |
385 | get_unaligned_le16(&report[i + 3]); | 396 | get_unaligned_le16(&report[i + 3]); |
@@ -430,6 +441,14 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
430 | i += 12; | 441 | i += 12; |
431 | break; | 442 | break; |
432 | 443 | ||
444 | case MTTPC_B: | ||
445 | features->y_max = | ||
446 | get_unaligned_le16(&report[i + 3]); | ||
447 | features->y_phy = | ||
448 | get_unaligned_le16(&report[i + 6]); | ||
449 | i += 9; | ||
450 | break; | ||
451 | |||
433 | default: | 452 | default: |
434 | features->y_max = | 453 | features->y_max = |
435 | features->x_max; | 454 | features->x_max; |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 4822c57a3756..977d05cd9e2e 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -484,6 +484,8 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
484 | input_report_key(input, BTN_TOUCH, 0); | 484 | input_report_key(input, BTN_TOUCH, 0); |
485 | input_report_abs(input, ABS_PRESSURE, 0); | 485 | input_report_abs(input, ABS_PRESSURE, 0); |
486 | input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max); | 486 | input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max); |
487 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) | ||
488 | wacom->shared->stylus_in_proximity = true; | ||
487 | } | 489 | } |
488 | 490 | ||
489 | /* Exit report */ | 491 | /* Exit report */ |
@@ -928,12 +930,12 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
928 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | 930 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
929 | 931 | ||
930 | if (touch) { | 932 | if (touch) { |
931 | int t_x = le16_to_cpup((__le16 *)&data[offset + 2]); | 933 | int t_x = get_unaligned_le16(&data[offset + 2]); |
932 | int c_x = le16_to_cpup((__le16 *)&data[offset + 4]); | 934 | int c_x = get_unaligned_le16(&data[offset + 4]); |
933 | int t_y = le16_to_cpup((__le16 *)&data[offset + 6]); | 935 | int t_y = get_unaligned_le16(&data[offset + 6]); |
934 | int c_y = le16_to_cpup((__le16 *)&data[offset + 8]); | 936 | int c_y = get_unaligned_le16(&data[offset + 8]); |
935 | int w = le16_to_cpup((__le16 *)&data[offset + 10]); | 937 | int w = get_unaligned_le16(&data[offset + 10]); |
936 | int h = le16_to_cpup((__le16 *)&data[offset + 12]); | 938 | int h = get_unaligned_le16(&data[offset + 12]); |
937 | 939 | ||
938 | input_report_abs(input, ABS_MT_POSITION_X, t_x); | 940 | input_report_abs(input, ABS_MT_POSITION_X, t_x); |
939 | input_report_abs(input, ABS_MT_POSITION_Y, t_y); | 941 | input_report_abs(input, ABS_MT_POSITION_Y, t_y); |
@@ -962,7 +964,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
962 | int x_offset = 0; | 964 | int x_offset = 0; |
963 | 965 | ||
964 | /* MTTPC does not support Height and Width */ | 966 | /* MTTPC does not support Height and Width */ |
965 | if (wacom->features.type == MTTPC) | 967 | if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B) |
966 | x_offset = -4; | 968 | x_offset = -4; |
967 | 969 | ||
968 | /* | 970 | /* |
@@ -978,7 +980,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
978 | for (i = 0; i < contacts_to_send; i++) { | 980 | for (i = 0; i < contacts_to_send; i++) { |
979 | int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; | 981 | int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; |
980 | bool touch = data[offset] & 0x1; | 982 | bool touch = data[offset] & 0x1; |
981 | int id = le16_to_cpup((__le16 *)&data[offset + 1]); | 983 | int id = get_unaligned_le16(&data[offset + 1]); |
982 | int slot = input_mt_get_slot_by_key(input, id); | 984 | int slot = input_mt_get_slot_by_key(input, id); |
983 | 985 | ||
984 | if (slot < 0) | 986 | if (slot < 0) |
@@ -987,8 +989,8 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
987 | input_mt_slot(input, slot); | 989 | input_mt_slot(input, slot); |
988 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | 990 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
989 | if (touch) { | 991 | if (touch) { |
990 | int x = le16_to_cpup((__le16 *)&data[offset + x_offset + 7]); | 992 | int x = get_unaligned_le16(&data[offset + x_offset + 7]); |
991 | int y = le16_to_cpup((__le16 *)&data[offset + x_offset + 9]); | 993 | int y = get_unaligned_le16(&data[offset + x_offset + 9]); |
992 | input_report_abs(input, ABS_MT_POSITION_X, x); | 994 | input_report_abs(input, ABS_MT_POSITION_X, x); |
993 | input_report_abs(input, ABS_MT_POSITION_Y, y); | 995 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
994 | } | 996 | } |
@@ -1047,6 +1049,10 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) | |||
1047 | prox = data[0] & 0x01; | 1049 | prox = data[0] & 0x01; |
1048 | x = get_unaligned_le16(&data[1]); | 1050 | x = get_unaligned_le16(&data[1]); |
1049 | y = get_unaligned_le16(&data[3]); | 1051 | y = get_unaligned_le16(&data[3]); |
1052 | } else if (len == WACOM_PKGLEN_TPC1FG_B) { | ||
1053 | prox = data[2] & 0x01; | ||
1054 | x = get_unaligned_le16(&data[3]); | ||
1055 | y = get_unaligned_le16(&data[5]); | ||
1050 | } else { | 1056 | } else { |
1051 | prox = data[1] & 0x01; | 1057 | prox = data[1] & 0x01; |
1052 | x = le16_to_cpup((__le16 *)&data[2]); | 1058 | x = le16_to_cpup((__le16 *)&data[2]); |
@@ -1110,6 +1116,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
1110 | case WACOM_PKGLEN_TPC2FG: | 1116 | case WACOM_PKGLEN_TPC2FG: |
1111 | return wacom_tpc_mt_touch(wacom); | 1117 | return wacom_tpc_mt_touch(wacom); |
1112 | 1118 | ||
1119 | case WACOM_PKGLEN_PENABLED: | ||
1120 | return wacom_tpc_pen(wacom); | ||
1121 | |||
1113 | default: | 1122 | default: |
1114 | switch (data[0]) { | 1123 | switch (data[0]) { |
1115 | case WACOM_REPORT_TPC1FG: | 1124 | case WACOM_REPORT_TPC1FG: |
@@ -1119,6 +1128,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
1119 | return wacom_tpc_single_touch(wacom, len); | 1128 | return wacom_tpc_single_touch(wacom, len); |
1120 | 1129 | ||
1121 | case WACOM_REPORT_TPCMT: | 1130 | case WACOM_REPORT_TPCMT: |
1131 | case WACOM_REPORT_TPCMT2: | ||
1122 | return wacom_mt_touch(wacom); | 1132 | return wacom_mt_touch(wacom); |
1123 | 1133 | ||
1124 | case WACOM_REPORT_PENABLED: | 1134 | case WACOM_REPORT_PENABLED: |
@@ -1461,6 +1471,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1461 | case TABLETPC2FG: | 1471 | case TABLETPC2FG: |
1462 | case MTSCREEN: | 1472 | case MTSCREEN: |
1463 | case MTTPC: | 1473 | case MTTPC: |
1474 | case MTTPC_B: | ||
1464 | sync = wacom_tpc_irq(wacom_wac, len); | 1475 | sync = wacom_tpc_irq(wacom_wac, len); |
1465 | break; | 1476 | break; |
1466 | 1477 | ||
@@ -1565,10 +1576,10 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, | |||
1565 | struct wacom_features *features = &wacom_wac->features; | 1576 | struct wacom_features *features = &wacom_wac->features; |
1566 | 1577 | ||
1567 | if (features->device_type == BTN_TOOL_PEN) { | 1578 | if (features->device_type == BTN_TOOL_PEN) { |
1568 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, | 1579 | input_set_abs_params(input_dev, ABS_X, features->x_min, |
1569 | features->x_fuzz, 0); | 1580 | features->x_max, features->x_fuzz, 0); |
1570 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, | 1581 | input_set_abs_params(input_dev, ABS_Y, features->y_min, |
1571 | features->y_fuzz, 0); | 1582 | features->y_max, features->y_fuzz, 0); |
1572 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, | 1583 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, |
1573 | features->pressure_max, features->pressure_fuzz, 0); | 1584 | features->pressure_max, features->pressure_fuzz, 0); |
1574 | 1585 | ||
@@ -1802,6 +1813,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1802 | 1813 | ||
1803 | case MTSCREEN: | 1814 | case MTSCREEN: |
1804 | case MTTPC: | 1815 | case MTTPC: |
1816 | case MTTPC_B: | ||
1805 | case TABLETPC2FG: | 1817 | case TABLETPC2FG: |
1806 | if (features->device_type == BTN_TOOL_FINGER) { | 1818 | if (features->device_type == BTN_TOOL_FINGER) { |
1807 | unsigned int flags = INPUT_MT_DIRECT; | 1819 | unsigned int flags = INPUT_MT_DIRECT; |
@@ -2123,11 +2135,11 @@ static const struct wacom_features wacom_features_0x317 = | |||
2123 | 63, INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 2135 | 63, INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, |
2124 | .touch_max = 16 }; | 2136 | .touch_max = 16 }; |
2125 | static const struct wacom_features wacom_features_0xF4 = | 2137 | static const struct wacom_features wacom_features_0xF4 = |
2126 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | 2138 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104280, 65400, 2047, |
2127 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2139 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; |
2128 | static const struct wacom_features wacom_features_0xF8 = | 2140 | static const struct wacom_features wacom_features_0xF8 = |
2129 | { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */ | 2141 | { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104280, 65400, 2047, /* Pen */ |
2130 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 2142 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, |
2131 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; | 2143 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; |
2132 | static const struct wacom_features wacom_features_0xF6 = | 2144 | static const struct wacom_features wacom_features_0xF6 = |
2133 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ | 2145 | { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ |
@@ -2142,8 +2154,8 @@ static const struct wacom_features wacom_features_0xC6 = | |||
2142 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, | 2154 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, |
2143 | 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2155 | 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
2144 | static const struct wacom_features wacom_features_0x304 = | 2156 | static const struct wacom_features wacom_features_0x304 = |
2145 | { "Wacom Cintiq 13HD", WACOM_PKGLEN_INTUOS, 59552, 33848, 1023, | 2157 | { "Wacom Cintiq 13HD", WACOM_PKGLEN_INTUOS, 59352, 33648, 1023, |
2146 | 63, WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2158 | 63, WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; |
2147 | static const struct wacom_features wacom_features_0xC7 = | 2159 | static const struct wacom_features wacom_features_0xC7 = |
2148 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, | 2160 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, |
2149 | 0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2161 | 0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -2157,24 +2169,24 @@ static const struct wacom_features wacom_features_0xFB = | |||
2157 | { "Wacom DTU1031", WACOM_PKGLEN_DTUS, 22096, 13960, 511, | 2169 | { "Wacom DTU1031", WACOM_PKGLEN_DTUS, 22096, 13960, 511, |
2158 | 0, DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2170 | 0, DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2159 | static const struct wacom_features wacom_features_0x57 = | 2171 | static const struct wacom_features wacom_features_0x57 = |
2160 | { "Wacom DTK2241", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, | 2172 | { "Wacom DTK2241", WACOM_PKGLEN_INTUOS, 95640, 54060, 2047, |
2161 | 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES}; | 2173 | 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; |
2162 | static const struct wacom_features wacom_features_0x59 = /* Pen */ | 2174 | static const struct wacom_features wacom_features_0x59 = /* Pen */ |
2163 | { "Wacom DTH2242", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, | 2175 | { "Wacom DTH2242", WACOM_PKGLEN_INTUOS, 95640, 54060, 2047, |
2164 | 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 2176 | 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, |
2165 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D }; | 2177 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D }; |
2166 | static const struct wacom_features wacom_features_0x5D = /* Touch */ | 2178 | static const struct wacom_features wacom_features_0x5D = /* Touch */ |
2167 | { "Wacom DTH2242", .type = WACOM_24HDT, | 2179 | { "Wacom DTH2242", .type = WACOM_24HDT, |
2168 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10 }; | 2180 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10 }; |
2169 | static const struct wacom_features wacom_features_0xCC = | 2181 | static const struct wacom_features wacom_features_0xCC = |
2170 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, | 2182 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87000, 65400, 2047, |
2171 | 63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2183 | 63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; |
2172 | static const struct wacom_features wacom_features_0xFA = | 2184 | static const struct wacom_features wacom_features_0xFA = |
2173 | { "Wacom Cintiq 22HD", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, | 2185 | { "Wacom Cintiq 22HD", WACOM_PKGLEN_INTUOS, 95640, 54060, 2047, |
2174 | 63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2186 | 63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; |
2175 | static const struct wacom_features wacom_features_0x5B = | 2187 | static const struct wacom_features wacom_features_0x5B = |
2176 | { "Wacom Cintiq 22HDT", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, | 2188 | { "Wacom Cintiq 22HDT", WACOM_PKGLEN_INTUOS, 95640, 54060, 2047, |
2177 | 63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 2189 | 63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, |
2178 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; | 2190 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; |
2179 | static const struct wacom_features wacom_features_0x5E = | 2191 | static const struct wacom_features wacom_features_0x5E = |
2180 | { "Wacom Cintiq 22HDT", .type = WACOM_24HDT, | 2192 | { "Wacom Cintiq 22HDT", .type = WACOM_24HDT, |
@@ -2233,9 +2245,21 @@ static const struct wacom_features wacom_features_0x10E = | |||
2233 | static const struct wacom_features wacom_features_0x10F = | 2245 | static const struct wacom_features wacom_features_0x10F = |
2234 | { "Wacom ISDv4 10F", WACOM_PKGLEN_MTTPC, 27760, 15694, 255, | 2246 | { "Wacom ISDv4 10F", WACOM_PKGLEN_MTTPC, 27760, 15694, 255, |
2235 | 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2247 | 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2248 | static const struct wacom_features wacom_features_0x116 = | ||
2249 | { "Wacom ISDv4 116", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, | ||
2250 | 0, TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
2236 | static const struct wacom_features wacom_features_0x4001 = | 2251 | static const struct wacom_features wacom_features_0x4001 = |
2237 | { "Wacom ISDv4 4001", WACOM_PKGLEN_MTTPC, 26202, 16325, 255, | 2252 | { "Wacom ISDv4 4001", WACOM_PKGLEN_MTTPC, 26202, 16325, 255, |
2238 | 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2253 | 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2254 | static const struct wacom_features wacom_features_0x4004 = | ||
2255 | { "Wacom ISDv4 4004", WACOM_PKGLEN_MTTPC, 11060, 6220, 255, | ||
2256 | 0, MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
2257 | static const struct wacom_features wacom_features_0x5000 = | ||
2258 | { "Wacom ISDv4 5000", WACOM_PKGLEN_MTTPC, 27848, 15752, 1023, | ||
2259 | 0, MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
2260 | static const struct wacom_features wacom_features_0x5002 = | ||
2261 | { "Wacom ISDv4 5002", WACOM_PKGLEN_MTTPC, 29576, 16724, 1023, | ||
2262 | 0, MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
2239 | static const struct wacom_features wacom_features_0x47 = | 2263 | static const struct wacom_features wacom_features_0x47 = |
2240 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, | 2264 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
2241 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2265 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -2316,8 +2340,8 @@ static const struct wacom_features wacom_features_0x6004 = | |||
2316 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, | 2340 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, |
2317 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2341 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2318 | static const struct wacom_features wacom_features_0x0307 = | 2342 | static const struct wacom_features wacom_features_0x0307 = |
2319 | { "Wacom ISDv5 307", WACOM_PKGLEN_INTUOS, 59552, 33848, 2047, | 2343 | { "Wacom ISDv5 307", WACOM_PKGLEN_INTUOS, 59352, 33648, 2047, |
2320 | 63, CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | 2344 | 63, CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, |
2321 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 }; | 2345 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 }; |
2322 | static const struct wacom_features wacom_features_0x0309 = | 2346 | static const struct wacom_features wacom_features_0x0309 = |
2323 | { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ | 2347 | { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ |
@@ -2447,6 +2471,7 @@ const struct usb_device_id wacom_ids[] = { | |||
2447 | { USB_DEVICE_WACOM(0x10D) }, | 2471 | { USB_DEVICE_WACOM(0x10D) }, |
2448 | { USB_DEVICE_WACOM(0x10E) }, | 2472 | { USB_DEVICE_WACOM(0x10E) }, |
2449 | { USB_DEVICE_WACOM(0x10F) }, | 2473 | { USB_DEVICE_WACOM(0x10F) }, |
2474 | { USB_DEVICE_WACOM(0x116) }, | ||
2450 | { USB_DEVICE_WACOM(0x300) }, | 2475 | { USB_DEVICE_WACOM(0x300) }, |
2451 | { USB_DEVICE_WACOM(0x301) }, | 2476 | { USB_DEVICE_WACOM(0x301) }, |
2452 | { USB_DEVICE_DETAILED(0x302, USB_CLASS_HID, 0, 0) }, | 2477 | { USB_DEVICE_DETAILED(0x302, USB_CLASS_HID, 0, 0) }, |
@@ -2457,6 +2482,9 @@ const struct usb_device_id wacom_ids[] = { | |||
2457 | { USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) }, | 2482 | { USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) }, |
2458 | { USB_DEVICE_DETAILED(0x317, USB_CLASS_HID, 0, 0) }, | 2483 | { USB_DEVICE_DETAILED(0x317, USB_CLASS_HID, 0, 0) }, |
2459 | { USB_DEVICE_WACOM(0x4001) }, | 2484 | { USB_DEVICE_WACOM(0x4001) }, |
2485 | { USB_DEVICE_WACOM(0x4004) }, | ||
2486 | { USB_DEVICE_WACOM(0x5000) }, | ||
2487 | { USB_DEVICE_WACOM(0x5002) }, | ||
2460 | { USB_DEVICE_WACOM(0x47) }, | 2488 | { USB_DEVICE_WACOM(0x47) }, |
2461 | { USB_DEVICE_WACOM(0xF4) }, | 2489 | { USB_DEVICE_WACOM(0xF4) }, |
2462 | { USB_DEVICE_WACOM(0xF8) }, | 2490 | { USB_DEVICE_WACOM(0xF8) }, |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index f69c0ebe7fa9..b2c9a9c1b551 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define WACOM_PKGLEN_BBFUN 9 | 22 | #define WACOM_PKGLEN_BBFUN 9 |
23 | #define WACOM_PKGLEN_INTUOS 10 | 23 | #define WACOM_PKGLEN_INTUOS 10 |
24 | #define WACOM_PKGLEN_TPC1FG 5 | 24 | #define WACOM_PKGLEN_TPC1FG 5 |
25 | #define WACOM_PKGLEN_TPC1FG_B 10 | ||
25 | #define WACOM_PKGLEN_TPC2FG 14 | 26 | #define WACOM_PKGLEN_TPC2FG 14 |
26 | #define WACOM_PKGLEN_BBTOUCH 20 | 27 | #define WACOM_PKGLEN_BBTOUCH 20 |
27 | #define WACOM_PKGLEN_BBTOUCH3 64 | 28 | #define WACOM_PKGLEN_BBTOUCH3 64 |
@@ -30,6 +31,7 @@ | |||
30 | #define WACOM_PKGLEN_MTOUCH 62 | 31 | #define WACOM_PKGLEN_MTOUCH 62 |
31 | #define WACOM_PKGLEN_MTTPC 40 | 32 | #define WACOM_PKGLEN_MTTPC 40 |
32 | #define WACOM_PKGLEN_DTUS 68 | 33 | #define WACOM_PKGLEN_DTUS 68 |
34 | #define WACOM_PKGLEN_PENABLED 8 | ||
33 | 35 | ||
34 | /* wacom data size per MT contact */ | 36 | /* wacom data size per MT contact */ |
35 | #define WACOM_BYTES_PER_MT_PACKET 11 | 37 | #define WACOM_BYTES_PER_MT_PACKET 11 |
@@ -52,6 +54,7 @@ | |||
52 | #define WACOM_REPORT_TPC1FG 6 | 54 | #define WACOM_REPORT_TPC1FG 6 |
53 | #define WACOM_REPORT_TPC2FG 13 | 55 | #define WACOM_REPORT_TPC2FG 13 |
54 | #define WACOM_REPORT_TPCMT 13 | 56 | #define WACOM_REPORT_TPCMT 13 |
57 | #define WACOM_REPORT_TPCMT2 3 | ||
55 | #define WACOM_REPORT_TPCHID 15 | 58 | #define WACOM_REPORT_TPCHID 15 |
56 | #define WACOM_REPORT_TPCST 16 | 59 | #define WACOM_REPORT_TPCST 16 |
57 | #define WACOM_REPORT_DTUS 17 | 60 | #define WACOM_REPORT_DTUS 17 |
@@ -105,6 +108,7 @@ enum { | |||
105 | TABLETPC2FG, | 108 | TABLETPC2FG, |
106 | MTSCREEN, | 109 | MTSCREEN, |
107 | MTTPC, | 110 | MTTPC, |
111 | MTTPC_B, | ||
108 | MAX_TYPE | 112 | MAX_TYPE |
109 | }; | 113 | }; |
110 | 114 | ||
@@ -118,6 +122,8 @@ struct wacom_features { | |||
118 | int type; | 122 | int type; |
119 | int x_resolution; | 123 | int x_resolution; |
120 | int y_resolution; | 124 | int y_resolution; |
125 | int x_min; | ||
126 | int y_min; | ||
121 | int device_type; | 127 | int device_type; |
122 | int x_phy; | 128 | int x_phy; |
123 | int y_phy; | 129 | int y_phy; |
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 | }; |
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 7f3aad0e115c..7f1a2e2711bd 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c | |||
@@ -84,21 +84,19 @@ static struct i2c_board_info tsl2563_als_device = { | |||
84 | I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), | 84 | I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), |
85 | }; | 85 | }; |
86 | 86 | ||
87 | static int mxt_t19_keys[] = { | ||
88 | KEY_RESERVED, | ||
89 | KEY_RESERVED, | ||
90 | KEY_RESERVED, | ||
91 | KEY_RESERVED, | ||
92 | KEY_RESERVED, | ||
93 | BTN_LEFT | ||
94 | }; | ||
95 | |||
87 | static struct mxt_platform_data atmel_224s_tp_platform_data = { | 96 | static struct mxt_platform_data atmel_224s_tp_platform_data = { |
88 | .x_line = 18, | ||
89 | .y_line = 12, | ||
90 | .x_size = 102*20, | ||
91 | .y_size = 68*20, | ||
92 | .blen = 0x80, /* Gain setting is in upper 4 bits */ | ||
93 | .threshold = 0x32, | ||
94 | .voltage = 0, /* 3.3V */ | ||
95 | .orient = MXT_VERTICAL_FLIP, | ||
96 | .irqflags = IRQF_TRIGGER_FALLING, | 97 | .irqflags = IRQF_TRIGGER_FALLING, |
97 | .is_tp = true, | 98 | .t19_num_keys = ARRAY_SIZE(mxt_t19_keys), |
98 | .key_map = { KEY_RESERVED, | 99 | .t19_keymap = mxt_t19_keys, |
99 | KEY_RESERVED, | ||
100 | KEY_RESERVED, | ||
101 | BTN_LEFT }, | ||
102 | .config = NULL, | 100 | .config = NULL, |
103 | .config_length = 0, | 101 | .config_length = 0, |
104 | }; | 102 | }; |
@@ -110,16 +108,7 @@ static struct i2c_board_info atmel_224s_tp_device = { | |||
110 | }; | 108 | }; |
111 | 109 | ||
112 | static struct mxt_platform_data atmel_1664s_platform_data = { | 110 | static struct mxt_platform_data atmel_1664s_platform_data = { |
113 | .x_line = 32, | ||
114 | .y_line = 50, | ||
115 | .x_size = 1700, | ||
116 | .y_size = 2560, | ||
117 | .blen = 0x89, /* Gain setting is in upper 4 bits */ | ||
118 | .threshold = 0x28, | ||
119 | .voltage = 0, /* 3.3V */ | ||
120 | .orient = MXT_ROTATED_90_COUNTER, | ||
121 | .irqflags = IRQF_TRIGGER_FALLING, | 111 | .irqflags = IRQF_TRIGGER_FALLING, |
122 | .is_tp = false, | ||
123 | .config = NULL, | 112 | .config = NULL, |
124 | .config_length = 0, | 113 | .config_length = 0, |
125 | }; | 114 | }; |
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index a7e977ff4abf..8b622468952c 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h | |||
@@ -3,29 +3,53 @@ | |||
3 | 3 | ||
4 | struct device; | 4 | struct device; |
5 | 5 | ||
6 | /** | ||
7 | * struct gpio_keys_button - configuration parameters | ||
8 | * @code: input event code (KEY_*, SW_*) | ||
9 | * @gpio: %-1 if this key does not support gpio | ||
10 | * @active_low: %true indicates that button is considered | ||
11 | * depressed when gpio is low | ||
12 | * @desc: label that will be attached to button's gpio | ||
13 | * @type: input event type (%EV_KEY, %EV_SW, %EV_ABS) | ||
14 | * @wakeup: configure the button as a wake-up source | ||
15 | * @debounce_interval: debounce ticks interval in msecs | ||
16 | * @can_disable: %true indicates that userspace is allowed to | ||
17 | * disable button via sysfs | ||
18 | * @value: axis value for %EV_ABS | ||
19 | * @irq: Irq number in case of interrupt keys | ||
20 | */ | ||
6 | struct gpio_keys_button { | 21 | struct gpio_keys_button { |
7 | /* Configuration parameters */ | 22 | unsigned int code; |
8 | unsigned int code; /* input event code (KEY_*, SW_*) */ | 23 | int gpio; |
9 | int gpio; /* -1 if this key does not support gpio */ | ||
10 | int active_low; | 24 | int active_low; |
11 | const char *desc; | 25 | const char *desc; |
12 | unsigned int type; /* input event type (EV_KEY, EV_SW, EV_ABS) */ | 26 | unsigned int type; |
13 | int wakeup; /* configure the button as a wake-up source */ | 27 | int wakeup; |
14 | int debounce_interval; /* debounce ticks interval in msecs */ | 28 | int debounce_interval; |
15 | bool can_disable; | 29 | bool can_disable; |
16 | int value; /* axis value for EV_ABS */ | 30 | int value; |
17 | unsigned int irq; /* Irq number in case of interrupt keys */ | 31 | unsigned int irq; |
18 | }; | 32 | }; |
19 | 33 | ||
34 | /** | ||
35 | * struct gpio_keys_platform_data - platform data for gpio_keys driver | ||
36 | * @buttons: pointer to array of &gpio_keys_button structures | ||
37 | * describing buttons attached to the device | ||
38 | * @nbuttons: number of elements in @buttons array | ||
39 | * @poll_interval: polling interval in msecs - for polling driver only | ||
40 | * @rep: enable input subsystem auto repeat | ||
41 | * @enable: platform hook for enabling the device | ||
42 | * @disable: platform hook for disabling the device | ||
43 | * @name: input device name | ||
44 | */ | ||
20 | struct gpio_keys_platform_data { | 45 | struct gpio_keys_platform_data { |
21 | struct gpio_keys_button *buttons; | 46 | struct gpio_keys_button *buttons; |
22 | int nbuttons; | 47 | int nbuttons; |
23 | unsigned int poll_interval; /* polling interval in msecs - | 48 | unsigned int poll_interval; |
24 | for polling driver only */ | 49 | unsigned int rep:1; |
25 | unsigned int rep:1; /* enable input subsystem auto repeat */ | ||
26 | int (*enable)(struct device *dev); | 50 | int (*enable)(struct device *dev); |
27 | void (*disable)(struct device *dev); | 51 | void (*disable)(struct device *dev); |
28 | const char *name; /* input device name */ | 52 | const char *name; |
29 | }; | 53 | }; |
30 | 54 | ||
31 | #endif | 55 | #endif |
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h index 99e379b74398..3891dc1de21c 100644 --- a/include/linux/i2c/atmel_mxt_ts.h +++ b/include/linux/i2c/atmel_mxt_ts.h | |||
@@ -15,35 +15,14 @@ | |||
15 | 15 | ||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | 17 | ||
18 | /* For key_map array */ | ||
19 | #define MXT_NUM_GPIO 4 | ||
20 | |||
21 | /* Orient */ | ||
22 | #define MXT_NORMAL 0x0 | ||
23 | #define MXT_DIAGONAL 0x1 | ||
24 | #define MXT_HORIZONTAL_FLIP 0x2 | ||
25 | #define MXT_ROTATED_90_COUNTER 0x3 | ||
26 | #define MXT_VERTICAL_FLIP 0x4 | ||
27 | #define MXT_ROTATED_90 0x5 | ||
28 | #define MXT_ROTATED_180 0x6 | ||
29 | #define MXT_DIAGONAL_COUNTER 0x7 | ||
30 | |||
31 | /* The platform data for the Atmel maXTouch touchscreen driver */ | 18 | /* The platform data for the Atmel maXTouch touchscreen driver */ |
32 | struct mxt_platform_data { | 19 | struct mxt_platform_data { |
33 | const u8 *config; | 20 | const u8 *config; |
34 | size_t config_length; | 21 | size_t config_length; |
35 | 22 | u32 config_crc; | |
36 | unsigned int x_line; | ||
37 | unsigned int y_line; | ||
38 | unsigned int x_size; | ||
39 | unsigned int y_size; | ||
40 | unsigned int blen; | ||
41 | unsigned int threshold; | ||
42 | unsigned int voltage; | ||
43 | unsigned char orient; | ||
44 | unsigned long irqflags; | 23 | unsigned long irqflags; |
45 | bool is_tp; | 24 | u8 t19_num_keys; |
46 | const unsigned int key_map[MXT_NUM_GPIO]; | 25 | const unsigned int *t19_keymap; |
47 | }; | 26 | }; |
48 | 27 | ||
49 | #endif /* __LINUX_ATMEL_MXT_TS_H */ | 28 | #endif /* __LINUX_ATMEL_MXT_TS_H */ |
diff --git a/include/linux/input-polldev.h b/include/linux/input-polldev.h index ce0b72464eb8..2465182670db 100644 --- a/include/linux/input-polldev.h +++ b/include/linux/input-polldev.h | |||
@@ -48,9 +48,12 @@ struct input_polled_dev { | |||
48 | 48 | ||
49 | /* private: */ | 49 | /* private: */ |
50 | struct delayed_work work; | 50 | struct delayed_work work; |
51 | |||
52 | bool devres_managed; | ||
51 | }; | 53 | }; |
52 | 54 | ||
53 | struct input_polled_dev *input_allocate_polled_device(void); | 55 | struct input_polled_dev *input_allocate_polled_device(void); |
56 | struct input_polled_dev *devm_input_allocate_polled_device(struct device *dev); | ||
54 | void input_free_polled_device(struct input_polled_dev *dev); | 57 | void input_free_polled_device(struct input_polled_dev *dev); |
55 | int input_register_polled_device(struct input_polled_dev *dev); | 58 | int input_register_polled_device(struct input_polled_dev *dev); |
56 | void input_unregister_polled_device(struct input_polled_dev *dev); | 59 | void input_unregister_polled_device(struct input_polled_dev *dev); |
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h index 7163d91c0373..160cf353aa39 100644 --- a/include/linux/input/pixcir_ts.h +++ b/include/linux/input/pixcir_ts.h | |||
@@ -1,10 +1,52 @@ | |||
1 | #ifndef _PIXCIR_I2C_TS_H | 1 | #ifndef _PIXCIR_I2C_TS_H |
2 | #define _PIXCIR_I2C_TS_H | 2 | #define _PIXCIR_I2C_TS_H |
3 | 3 | ||
4 | /* | ||
5 | * Register map | ||
6 | */ | ||
7 | #define PIXCIR_REG_POWER_MODE 51 | ||
8 | #define PIXCIR_REG_INT_MODE 52 | ||
9 | |||
10 | /* | ||
11 | * Power modes: | ||
12 | * active: max scan speed | ||
13 | * idle: lower scan speed with automatic transition to active on touch | ||
14 | * halt: datasheet says sleep but this is more like halt as the chip | ||
15 | * clocks are cut and it can only be brought out of this mode | ||
16 | * using the RESET pin. | ||
17 | */ | ||
18 | enum pixcir_power_mode { | ||
19 | PIXCIR_POWER_ACTIVE, | ||
20 | PIXCIR_POWER_IDLE, | ||
21 | PIXCIR_POWER_HALT, | ||
22 | }; | ||
23 | |||
24 | #define PIXCIR_POWER_MODE_MASK 0x03 | ||
25 | #define PIXCIR_POWER_ALLOW_IDLE (1UL << 2) | ||
26 | |||
27 | /* | ||
28 | * Interrupt modes: | ||
29 | * periodical: interrupt is asserted periodicaly | ||
30 | * diff coordinates: interrupt is asserted when coordinates change | ||
31 | * level on touch: interrupt level asserted during touch | ||
32 | * pulse on touch: interrupt pulse asserted druing touch | ||
33 | * | ||
34 | */ | ||
35 | enum pixcir_int_mode { | ||
36 | PIXCIR_INT_PERIODICAL, | ||
37 | PIXCIR_INT_DIFF_COORD, | ||
38 | PIXCIR_INT_LEVEL_TOUCH, | ||
39 | PIXCIR_INT_PULSE_TOUCH, | ||
40 | }; | ||
41 | |||
42 | #define PIXCIR_INT_MODE_MASK 0x03 | ||
43 | #define PIXCIR_INT_ENABLE (1UL << 3) | ||
44 | #define PIXCIR_INT_POL_HIGH (1UL << 2) | ||
45 | |||
4 | struct pixcir_ts_platform_data { | 46 | struct pixcir_ts_platform_data { |
5 | int (*attb_read_val)(void); | ||
6 | int x_max; | 47 | int x_max; |
7 | int y_max; | 48 | int y_max; |
49 | int gpio_attb; /* GPIO connected to ATTB line */ | ||
8 | }; | 50 | }; |
9 | 51 | ||
10 | #endif | 52 | #endif |
diff --git a/include/linux/input/touchscreen.h b/include/linux/input/touchscreen.h new file mode 100644 index 000000000000..08a5ef6e8f25 --- /dev/null +++ b/include/linux/input/touchscreen.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Sebastian Reichel <sre@kernel.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License version 2 as published by | ||
6 | * the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef _TOUCHSCREEN_H | ||
10 | #define _TOUCHSCREEN_H | ||
11 | |||
12 | #include <linux/input.h> | ||
13 | |||
14 | #ifdef CONFIG_OF | ||
15 | void touchscreen_parse_of_params(struct input_dev *dev); | ||
16 | #else | ||
17 | static inline void touchscreen_parse_of_params(struct input_dev *dev) | ||
18 | { | ||
19 | } | ||
20 | #endif | ||
21 | |||
22 | #endif | ||
diff --git a/include/linux/platform_data/omap4-keypad.h b/include/linux/platform_data/omap4-keypad.h deleted file mode 100644 index 4eef5fb05a17..000000000000 --- a/include/linux/platform_data/omap4-keypad.h +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | #ifndef __LINUX_INPUT_OMAP4_KEYPAD_H | ||
2 | #define __LINUX_INPUT_OMAP4_KEYPAD_H | ||
3 | |||
4 | #include <linux/input/matrix_keypad.h> | ||
5 | |||
6 | struct omap4_keypad_platform_data { | ||
7 | const struct matrix_keymap_data *keymap_data; | ||
8 | |||
9 | u8 rows; | ||
10 | u8 cols; | ||
11 | }; | ||
12 | |||
13 | #endif /* __LINUX_INPUT_OMAP4_KEYPAD_H */ | ||