diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-24 13:34:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-24 13:34:29 -0400 |
commit | 2c01e7bc46f10e9190818437e564f7e0db875ae9 (patch) | |
tree | 8b06c85d69754f7df27f7fb42520f6e2ceaea907 | |
parent | ab11ca34eea8fda7a1a9302d86f6ef6108ffd68f (diff) | |
parent | e644dae645e167d154c0526358940986682a72b0 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input layer updates from Dmitry Torokhov:
- a bunch of new drivers (DA9052/53 touchscreenn controller, Synaptics
Navpoint, LM8333 keypads, Wacom I2C touhscreen);
- updates to existing touchpad drivers (ALPS, Sntelic);
- Wacom driver now supports Intuos5;
- device-tree bindings in numerous drivers;
- other cleanups and fixes.
Fix annoying conflict in drivers/input/tablet/wacom_wac.c that I think
implies that the input layer device naming is broken, but let's see. I
brough it up with Dmitry.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (57 commits)
Input: matrix-keymap - fix building keymaps
Input: spear-keyboard - document DT bindings
Input: spear-keyboard - add device tree bindings
Input: matrix-keymap - wire up device tree support
Input: matrix-keymap - uninline and prepare for device tree support
Input: adp5588 - add support for gpio names
Input: omap-keypad - dynamically handle register offsets
Input: synaptics - fix compile warning
MAINTAINERS: adjust input-related patterns
Input: ALPS - switch to using input_mt_report_finger_count
Input: ALPS - add semi-MT support for v4 protocol
Input: Add Synaptics NavPoint (PXA27x SSP/SPI) driver
Input: atmel_mxt_ts - dump each message on just 1 line
Input: atmel_mxt_ts - do not read extra (checksum) byte
Input: atmel_mxt_ts - verify object size in mxt_write_object
Input: atmel_mxt_ts - only allow root to update firmware
Input: atmel_mxt_ts - use CONFIG_PM_SLEEP
Input: sentelic - report device's production serial number
Input: tl6040-vibra - Device Tree support
Input: evdev - properly handle read/write with count 0
...
106 files changed, 2845 insertions, 1305 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-wacom b/Documentation/ABI/testing/sysfs-driver-wacom index 56c54558c8a4..8d55a83d6921 100644 --- a/Documentation/ABI/testing/sysfs-driver-wacom +++ b/Documentation/ABI/testing/sysfs-driver-wacom | |||
@@ -23,9 +23,10 @@ Contact: linux-input@vger.kernel.org | |||
23 | Description: | 23 | Description: |
24 | Attribute group for control of the status LEDs and the OLEDs. | 24 | Attribute group for control of the status LEDs and the OLEDs. |
25 | This attribute group is only available for Intuos 4 M, L, | 25 | This attribute group is only available for Intuos 4 M, L, |
26 | and XL (with LEDs and OLEDs) and Cintiq 21UX2 and Cintiq 24HD | 26 | and XL (with LEDs and OLEDs), Intuos 5 (LEDs only), and Cintiq |
27 | (LEDs only). Therefore its presence implicitly signifies the | 27 | 21UX2 and Cintiq 24HD (LEDs only). Therefore its presence |
28 | presence of said LEDs and OLEDs on the tablet device. | 28 | implicitly signifies the presence of said LEDs and OLEDs on the |
29 | tablet device. | ||
29 | 30 | ||
30 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status0_luminance | 31 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status0_luminance |
31 | Date: August 2011 | 32 | Date: August 2011 |
@@ -48,10 +49,10 @@ What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status_led0 | |||
48 | Date: August 2011 | 49 | Date: August 2011 |
49 | Contact: linux-input@vger.kernel.org | 50 | Contact: linux-input@vger.kernel.org |
50 | Description: | 51 | Description: |
51 | Writing to this file sets which one of the four (for Intuos 4) | 52 | Writing to this file sets which one of the four (for Intuos 4 |
52 | or of the right four (for Cintiq 21UX2 and Cintiq 24HD) status | 53 | and Intuos 5) or of the right four (for Cintiq 21UX2 and Cintiq |
53 | LEDs is active (0..3). The other three LEDs on the same side are | 54 | 24HD) status LEDs is active (0..3). The other three LEDs on the |
54 | always inactive. | 55 | same side are always inactive. |
55 | 56 | ||
56 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status_led1_select | 57 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status_led1_select |
57 | Date: September 2011 | 58 | Date: September 2011 |
diff --git a/Documentation/devicetree/bindings/input/spear-keyboard.txt b/Documentation/devicetree/bindings/input/spear-keyboard.txt new file mode 100644 index 000000000000..4a846d26da23 --- /dev/null +++ b/Documentation/devicetree/bindings/input/spear-keyboard.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | * SPEAr keyboard controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "st,spear300-kbd" | ||
5 | |||
6 | Optional properties, in addition to those specified by the shared | ||
7 | matrix-keyboard bindings: | ||
8 | - autorepeat: bool: enables key autorepeat | ||
9 | - st,mode: keyboard mode: 0 - 9x9, 1 - 6x6, 2 - 2x2 | ||
10 | |||
11 | Example: | ||
12 | |||
13 | kbd@fc400000 { | ||
14 | compatible = "st,spear300-kbd"; | ||
15 | reg = <0xfc400000 0x100>; | ||
16 | linux,keymap = < 0x00030012 | ||
17 | 0x0102003a >; | ||
18 | autorepeat; | ||
19 | st,mode = <0>; | ||
20 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/touchscreen/lpc32xx-tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/lpc32xx-tsc.txt new file mode 100644 index 000000000000..41cbf4b7a670 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/lpc32xx-tsc.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | * NXP LPC32xx SoC Touchscreen Controller (TSC) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: must be "nxp,lpc3220-tsc" | ||
5 | - reg: physical base address of the controller and length of memory mapped | ||
6 | region. | ||
7 | - interrupts: The TSC/ADC interrupt | ||
8 | |||
9 | Example: | ||
10 | |||
11 | tsc@40048000 { | ||
12 | compatible = "nxp,lpc3220-tsc"; | ||
13 | reg = <0x40048000 0x1000>; | ||
14 | interrupt-parent = <&mic>; | ||
15 | interrupts = <39 0>; | ||
16 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/twl6040-vibra.txt b/Documentation/devicetree/bindings/input/twl6040-vibra.txt new file mode 100644 index 000000000000..5b1918b818fb --- /dev/null +++ b/Documentation/devicetree/bindings/input/twl6040-vibra.txt | |||
@@ -0,0 +1,37 @@ | |||
1 | Vibra driver for the twl6040 family | ||
2 | |||
3 | The vibra driver is a child of the twl6040 MFD dirver. | ||
4 | Documentation/devicetree/bindings/mfd/twl6040.txt | ||
5 | |||
6 | Required properties: | ||
7 | - compatible : Must be "ti,twl6040-vibra"; | ||
8 | - interrupts: 4, Vibra overcurrent interrupt | ||
9 | - vddvibl-supply: Regulator supplying the left vibra motor | ||
10 | - vddvibr-supply: Regulator supplying the right vibra motor | ||
11 | - vibldrv_res: Board specific left driver resistance | ||
12 | - vibrdrv_res: Board specific right driver resistance | ||
13 | - viblmotor_res: Board specific left motor resistance | ||
14 | - vibrmotor_res: Board specific right motor resistance | ||
15 | |||
16 | Optional properties: | ||
17 | - vddvibl_uV: If the vddvibl default voltage need to be changed | ||
18 | - vddvibr_uV: If the vddvibr default voltage need to be changed | ||
19 | |||
20 | Example: | ||
21 | /* | ||
22 | * 8-channel high quality low-power audio codec | ||
23 | * http://www.ti.com/lit/ds/symlink/twl6040.pdf | ||
24 | */ | ||
25 | twl6040: twl6040@4b { | ||
26 | ... | ||
27 | twl6040_vibra: twl6040@1 { | ||
28 | compatible = "ti,twl6040-vibra"; | ||
29 | interrupts = <4>; | ||
30 | vddvibl-supply = <&vbat>; | ||
31 | vddvibr-supply = <&vbat>; | ||
32 | vibldrv_res = <8>; | ||
33 | vibrdrv_res = <3>; | ||
34 | viblmotor_res = <10>; | ||
35 | vibrmotor_res = <10>; | ||
36 | }; | ||
37 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 54c984e9d058..62b0cf496ebd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3465,6 +3465,8 @@ Q: http://patchwork.kernel.org/project/linux-input/list/ | |||
3465 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git | 3465 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git |
3466 | S: Maintained | 3466 | S: Maintained |
3467 | F: drivers/input/ | 3467 | F: drivers/input/ |
3468 | F: include/linux/input.h | ||
3469 | F: include/linux/input/ | ||
3468 | 3470 | ||
3469 | INPUT MULTITOUCH (MT) PROTOCOL | 3471 | INPUT MULTITOUCH (MT) PROTOCOL |
3470 | M: Henrik Rydberg <rydberg@euromail.se> | 3472 | M: Henrik Rydberg <rydberg@euromail.se> |
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 332597980817..55f7e57d4e42 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig | |||
@@ -25,10 +25,6 @@ config INPUT | |||
25 | 25 | ||
26 | if INPUT | 26 | if INPUT |
27 | 27 | ||
28 | config INPUT_OF_MATRIX_KEYMAP | ||
29 | depends on USE_OF | ||
30 | bool | ||
31 | |||
32 | config INPUT_FF_MEMLESS | 28 | config INPUT_FF_MEMLESS |
33 | tristate "Support for memoryless force-feedback devices" | 29 | tristate "Support for memoryless force-feedback devices" |
34 | help | 30 | help |
@@ -68,6 +64,19 @@ config INPUT_SPARSEKMAP | |||
68 | To compile this driver as a module, choose M here: the | 64 | To compile this driver as a module, choose M here: the |
69 | module will be called sparse-keymap. | 65 | module will be called sparse-keymap. |
70 | 66 | ||
67 | config INPUT_MATRIXKMAP | ||
68 | tristate "Matrix keymap support library" | ||
69 | help | ||
70 | Say Y here if you are using a driver for an input | ||
71 | device that uses matrix keymap. This option is only | ||
72 | useful for out-of-tree drivers since in-tree drivers | ||
73 | select it automatically. | ||
74 | |||
75 | If unsure, say N. | ||
76 | |||
77 | To compile this driver as a module, choose M here: the | ||
78 | module will be called matrix-keymap. | ||
79 | |||
71 | comment "Userland interfaces" | 80 | comment "Userland interfaces" |
72 | 81 | ||
73 | config INPUT_MOUSEDEV | 82 | config INPUT_MOUSEDEV |
diff --git a/drivers/input/Makefile b/drivers/input/Makefile index b173a13a73ca..5ca3f631497f 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile | |||
@@ -10,6 +10,7 @@ input-core-y := input.o input-compat.o input-mt.o ff-core.o | |||
10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o | 10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o |
11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o | 11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o |
12 | obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o | 12 | obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o |
13 | obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o | ||
13 | 14 | ||
14 | obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o | 15 | obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o |
15 | obj-$(CONFIG_INPUT_JOYDEV) += joydev.o | 16 | obj-$(CONFIG_INPUT_JOYDEV) += joydev.o |
@@ -24,4 +25,3 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ | |||
24 | obj-$(CONFIG_INPUT_MISC) += misc/ | 25 | obj-$(CONFIG_INPUT_MISC) += misc/ |
25 | 26 | ||
26 | obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o | 27 | obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o |
27 | obj-$(CONFIG_INPUT_OF_MATRIX_KEYMAP) += of_keymap.o | ||
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 4b2e10d5d641..6c58bfff01a3 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -180,7 +180,10 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client) | |||
180 | 180 | ||
181 | static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client) | 181 | static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client) |
182 | { | 182 | { |
183 | if (evdev->grab != client) | 183 | struct evdev_client *grab = rcu_dereference_protected(evdev->grab, |
184 | lockdep_is_held(&evdev->mutex)); | ||
185 | |||
186 | if (grab != client) | ||
184 | return -EINVAL; | 187 | return -EINVAL; |
185 | 188 | ||
186 | rcu_assign_pointer(evdev->grab, NULL); | 189 | rcu_assign_pointer(evdev->grab, NULL); |
@@ -259,8 +262,7 @@ static int evdev_release(struct inode *inode, struct file *file) | |||
259 | struct evdev *evdev = client->evdev; | 262 | struct evdev *evdev = client->evdev; |
260 | 263 | ||
261 | mutex_lock(&evdev->mutex); | 264 | mutex_lock(&evdev->mutex); |
262 | if (evdev->grab == client) | 265 | evdev_ungrab(evdev, client); |
263 | evdev_ungrab(evdev, client); | ||
264 | mutex_unlock(&evdev->mutex); | 266 | mutex_unlock(&evdev->mutex); |
265 | 267 | ||
266 | evdev_detach_client(evdev, client); | 268 | evdev_detach_client(evdev, client); |
@@ -343,7 +345,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, | |||
343 | struct input_event event; | 345 | struct input_event event; |
344 | int retval = 0; | 346 | int retval = 0; |
345 | 347 | ||
346 | if (count < input_event_size()) | 348 | if (count != 0 && count < input_event_size()) |
347 | return -EINVAL; | 349 | return -EINVAL; |
348 | 350 | ||
349 | retval = mutex_lock_interruptible(&evdev->mutex); | 351 | retval = mutex_lock_interruptible(&evdev->mutex); |
@@ -355,7 +357,8 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, | |||
355 | goto out; | 357 | goto out; |
356 | } | 358 | } |
357 | 359 | ||
358 | do { | 360 | while (retval + input_event_size() <= count) { |
361 | |||
359 | if (input_event_from_user(buffer + retval, &event)) { | 362 | if (input_event_from_user(buffer + retval, &event)) { |
360 | retval = -EFAULT; | 363 | retval = -EFAULT; |
361 | goto out; | 364 | goto out; |
@@ -364,7 +367,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, | |||
364 | 367 | ||
365 | input_inject_event(&evdev->handle, | 368 | input_inject_event(&evdev->handle, |
366 | event.type, event.code, event.value); | 369 | event.type, event.code, event.value); |
367 | } while (retval + input_event_size() <= count); | 370 | } |
368 | 371 | ||
369 | out: | 372 | out: |
370 | mutex_unlock(&evdev->mutex); | 373 | mutex_unlock(&evdev->mutex); |
@@ -395,35 +398,49 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, | |||
395 | struct evdev_client *client = file->private_data; | 398 | struct evdev_client *client = file->private_data; |
396 | struct evdev *evdev = client->evdev; | 399 | struct evdev *evdev = client->evdev; |
397 | struct input_event event; | 400 | struct input_event event; |
398 | int retval = 0; | 401 | size_t read = 0; |
402 | int error; | ||
399 | 403 | ||
400 | if (count < input_event_size()) | 404 | if (count != 0 && count < input_event_size()) |
401 | return -EINVAL; | 405 | return -EINVAL; |
402 | 406 | ||
403 | if (!(file->f_flags & O_NONBLOCK)) { | 407 | for (;;) { |
404 | retval = wait_event_interruptible(evdev->wait, | 408 | if (!evdev->exist) |
405 | client->packet_head != client->tail || | 409 | return -ENODEV; |
406 | !evdev->exist); | ||
407 | if (retval) | ||
408 | return retval; | ||
409 | } | ||
410 | 410 | ||
411 | if (!evdev->exist) | 411 | if (client->packet_head == client->tail && |
412 | return -ENODEV; | 412 | (file->f_flags & O_NONBLOCK)) |
413 | return -EAGAIN; | ||
413 | 414 | ||
414 | while (retval + input_event_size() <= count && | 415 | /* |
415 | evdev_fetch_next_event(client, &event)) { | 416 | * count == 0 is special - no IO is done but we check |
417 | * for error conditions (see above). | ||
418 | */ | ||
419 | if (count == 0) | ||
420 | break; | ||
416 | 421 | ||
417 | if (input_event_to_user(buffer + retval, &event)) | 422 | while (read + input_event_size() <= count && |
418 | return -EFAULT; | 423 | evdev_fetch_next_event(client, &event)) { |
419 | 424 | ||
420 | retval += input_event_size(); | 425 | if (input_event_to_user(buffer + read, &event)) |
421 | } | 426 | return -EFAULT; |
422 | 427 | ||
423 | if (retval == 0 && (file->f_flags & O_NONBLOCK)) | 428 | read += input_event_size(); |
424 | return -EAGAIN; | 429 | } |
425 | 430 | ||
426 | return retval; | 431 | if (read) |
432 | break; | ||
433 | |||
434 | if (!(file->f_flags & O_NONBLOCK)) { | ||
435 | error = wait_event_interruptible(evdev->wait, | ||
436 | client->packet_head != client->tail || | ||
437 | !evdev->exist); | ||
438 | if (error) | ||
439 | return error; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | return read; | ||
427 | } | 444 | } |
428 | 445 | ||
429 | /* No kernel lock - fine */ | 446 | /* No kernel lock - fine */ |
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index 422aa0a6b77f..daceafe7ee7d 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c | |||
@@ -125,15 +125,4 @@ static struct pci_driver emu_driver = { | |||
125 | .remove = __devexit_p(emu_remove), | 125 | .remove = __devexit_p(emu_remove), |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static int __init emu_init(void) | 128 | module_pci_driver(emu_driver); |
129 | { | ||
130 | return pci_register_driver(&emu_driver); | ||
131 | } | ||
132 | |||
133 | static void __exit emu_exit(void) | ||
134 | { | ||
135 | pci_unregister_driver(&emu_driver); | ||
136 | } | ||
137 | |||
138 | module_init(emu_init); | ||
139 | module_exit(emu_exit); | ||
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index a3b70ff21018..48ad3829ff20 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
@@ -144,6 +144,7 @@ static const struct pci_device_id fm801_gp_id_table[] = { | |||
144 | { PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 144 | { PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
145 | { 0 } | 145 | { 0 } |
146 | }; | 146 | }; |
147 | MODULE_DEVICE_TABLE(pci, fm801_gp_id_table); | ||
147 | 148 | ||
148 | static struct pci_driver fm801_gp_driver = { | 149 | static struct pci_driver fm801_gp_driver = { |
149 | .name = "FM801_gameport", | 150 | .name = "FM801_gameport", |
@@ -152,20 +153,7 @@ static struct pci_driver fm801_gp_driver = { | |||
152 | .remove = __devexit_p(fm801_gp_remove), | 153 | .remove = __devexit_p(fm801_gp_remove), |
153 | }; | 154 | }; |
154 | 155 | ||
155 | static int __init fm801_gp_init(void) | 156 | module_pci_driver(fm801_gp_driver); |
156 | { | ||
157 | return pci_register_driver(&fm801_gp_driver); | ||
158 | } | ||
159 | |||
160 | static void __exit fm801_gp_exit(void) | ||
161 | { | ||
162 | pci_unregister_driver(&fm801_gp_driver); | ||
163 | } | ||
164 | |||
165 | module_init(fm801_gp_init); | ||
166 | module_exit(fm801_gp_exit); | ||
167 | |||
168 | MODULE_DEVICE_TABLE(pci, fm801_gp_id_table); | ||
169 | 157 | ||
170 | MODULE_DESCRIPTION("FM801 gameport driver"); | 158 | MODULE_DESCRIPTION("FM801 gameport driver"); |
171 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | 159 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 1639ab2b94b7..85bc8dc07cfc 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c | |||
@@ -413,15 +413,4 @@ static struct gameport_driver a3d_drv = { | |||
413 | .disconnect = a3d_disconnect, | 413 | .disconnect = a3d_disconnect, |
414 | }; | 414 | }; |
415 | 415 | ||
416 | static int __init a3d_init(void) | 416 | module_gameport_driver(a3d_drv); |
417 | { | ||
418 | return gameport_register_driver(&a3d_drv); | ||
419 | } | ||
420 | |||
421 | static void __exit a3d_exit(void) | ||
422 | { | ||
423 | gameport_unregister_driver(&a3d_drv); | ||
424 | } | ||
425 | |||
426 | module_init(a3d_init); | ||
427 | module_exit(a3d_exit); | ||
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index b992fbf91f2f..0cbfd2dfabf4 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c | |||
@@ -557,10 +557,6 @@ static void adi_disconnect(struct gameport *gameport) | |||
557 | kfree(port); | 557 | kfree(port); |
558 | } | 558 | } |
559 | 559 | ||
560 | /* | ||
561 | * The gameport device structure. | ||
562 | */ | ||
563 | |||
564 | static struct gameport_driver adi_drv = { | 560 | static struct gameport_driver adi_drv = { |
565 | .driver = { | 561 | .driver = { |
566 | .name = "adi", | 562 | .name = "adi", |
@@ -570,15 +566,4 @@ static struct gameport_driver adi_drv = { | |||
570 | .disconnect = adi_disconnect, | 566 | .disconnect = adi_disconnect, |
571 | }; | 567 | }; |
572 | 568 | ||
573 | static int __init adi_init(void) | 569 | module_gameport_driver(adi_drv); |
574 | { | ||
575 | return gameport_register_driver(&adi_drv); | ||
576 | } | ||
577 | |||
578 | static void __exit adi_exit(void) | ||
579 | { | ||
580 | gameport_unregister_driver(&adi_drv); | ||
581 | } | ||
582 | |||
583 | module_init(adi_init); | ||
584 | module_exit(adi_exit); | ||
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 3497b87c3d05..65367e44d715 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c | |||
@@ -261,15 +261,4 @@ static struct gameport_driver cobra_drv = { | |||
261 | .disconnect = cobra_disconnect, | 261 | .disconnect = cobra_disconnect, |
262 | }; | 262 | }; |
263 | 263 | ||
264 | static int __init cobra_init(void) | 264 | module_gameport_driver(cobra_drv); |
265 | { | ||
266 | return gameport_register_driver(&cobra_drv); | ||
267 | } | ||
268 | |||
269 | static void __exit cobra_exit(void) | ||
270 | { | ||
271 | gameport_unregister_driver(&cobra_drv); | ||
272 | } | ||
273 | |||
274 | module_init(cobra_init); | ||
275 | module_exit(cobra_exit); | ||
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 0536b1b2f018..ab1cf2882004 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c | |||
@@ -373,15 +373,4 @@ static struct gameport_driver gf2k_drv = { | |||
373 | .disconnect = gf2k_disconnect, | 373 | .disconnect = gf2k_disconnect, |
374 | }; | 374 | }; |
375 | 375 | ||
376 | static int __init gf2k_init(void) | 376 | module_gameport_driver(gf2k_drv); |
377 | { | ||
378 | return gameport_register_driver(&gf2k_drv); | ||
379 | } | ||
380 | |||
381 | static void __exit gf2k_exit(void) | ||
382 | { | ||
383 | gameport_unregister_driver(&gf2k_drv); | ||
384 | } | ||
385 | |||
386 | module_init(gf2k_init); | ||
387 | module_exit(gf2k_exit); | ||
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index fc55899ba6c5..9e1beff57c33 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c | |||
@@ -424,15 +424,4 @@ static struct gameport_driver grip_drv = { | |||
424 | .disconnect = grip_disconnect, | 424 | .disconnect = grip_disconnect, |
425 | }; | 425 | }; |
426 | 426 | ||
427 | static int __init grip_init(void) | 427 | module_gameport_driver(grip_drv); |
428 | { | ||
429 | return gameport_register_driver(&grip_drv); | ||
430 | } | ||
431 | |||
432 | static void __exit grip_exit(void) | ||
433 | { | ||
434 | gameport_unregister_driver(&grip_drv); | ||
435 | } | ||
436 | |||
437 | module_init(grip_init); | ||
438 | module_exit(grip_exit); | ||
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 2d47baf47769..c0f9c7b7eb4e 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c | |||
@@ -687,15 +687,4 @@ static struct gameport_driver grip_drv = { | |||
687 | .disconnect = grip_disconnect, | 687 | .disconnect = grip_disconnect, |
688 | }; | 688 | }; |
689 | 689 | ||
690 | static int __init grip_init(void) | 690 | module_gameport_driver(grip_drv); |
691 | { | ||
692 | return gameport_register_driver(&grip_drv); | ||
693 | } | ||
694 | |||
695 | static void __exit grip_exit(void) | ||
696 | { | ||
697 | gameport_unregister_driver(&grip_drv); | ||
698 | } | ||
699 | |||
700 | module_init(grip_init); | ||
701 | module_exit(grip_exit); | ||
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 4058d4b272fe..55196f730af6 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c | |||
@@ -281,15 +281,4 @@ static struct gameport_driver guillemot_drv = { | |||
281 | .disconnect = guillemot_disconnect, | 281 | .disconnect = guillemot_disconnect, |
282 | }; | 282 | }; |
283 | 283 | ||
284 | static int __init guillemot_init(void) | 284 | module_gameport_driver(guillemot_drv); |
285 | { | ||
286 | return gameport_register_driver(&guillemot_drv); | ||
287 | } | ||
288 | |||
289 | static void __exit guillemot_exit(void) | ||
290 | { | ||
291 | gameport_unregister_driver(&guillemot_drv); | ||
292 | } | ||
293 | |||
294 | module_init(guillemot_init); | ||
295 | module_exit(guillemot_exit); | ||
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index 16fb19d1ca25..88c22623a2e8 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c | |||
@@ -311,15 +311,4 @@ static struct gameport_driver interact_drv = { | |||
311 | .disconnect = interact_disconnect, | 311 | .disconnect = interact_disconnect, |
312 | }; | 312 | }; |
313 | 313 | ||
314 | static int __init interact_init(void) | 314 | module_gameport_driver(interact_drv); |
315 | { | ||
316 | return gameport_register_driver(&interact_drv); | ||
317 | } | ||
318 | |||
319 | static void __exit interact_exit(void) | ||
320 | { | ||
321 | gameport_unregister_driver(&interact_drv); | ||
322 | } | ||
323 | |||
324 | module_init(interact_init); | ||
325 | module_exit(interact_exit); | ||
diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c index cd894a0564a2..7eb878bab968 100644 --- a/drivers/input/joystick/joydump.c +++ b/drivers/input/joystick/joydump.c | |||
@@ -159,15 +159,4 @@ static struct gameport_driver joydump_drv = { | |||
159 | .disconnect = joydump_disconnect, | 159 | .disconnect = joydump_disconnect, |
160 | }; | 160 | }; |
161 | 161 | ||
162 | static int __init joydump_init(void) | 162 | module_gameport_driver(joydump_drv); |
163 | { | ||
164 | return gameport_register_driver(&joydump_drv); | ||
165 | } | ||
166 | |||
167 | static void __exit joydump_exit(void) | ||
168 | { | ||
169 | gameport_unregister_driver(&joydump_drv); | ||
170 | } | ||
171 | |||
172 | module_init(joydump_init); | ||
173 | module_exit(joydump_exit); | ||
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 40e40780747d..9fb153eef2fc 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c | |||
@@ -222,19 +222,4 @@ static struct serio_driver magellan_drv = { | |||
222 | .disconnect = magellan_disconnect, | 222 | .disconnect = magellan_disconnect, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | /* | 225 | module_serio_driver(magellan_drv); |
226 | * The functions for inserting/removing us as a module. | ||
227 | */ | ||
228 | |||
229 | static int __init magellan_init(void) | ||
230 | { | ||
231 | return serio_register_driver(&magellan_drv); | ||
232 | } | ||
233 | |||
234 | static void __exit magellan_exit(void) | ||
235 | { | ||
236 | serio_unregister_driver(&magellan_drv); | ||
237 | } | ||
238 | |||
239 | module_init(magellan_init); | ||
240 | module_exit(magellan_exit); | ||
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index b8d86115644b..04c69af37148 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c | |||
@@ -820,15 +820,4 @@ static struct gameport_driver sw_drv = { | |||
820 | .disconnect = sw_disconnect, | 820 | .disconnect = sw_disconnect, |
821 | }; | 821 | }; |
822 | 822 | ||
823 | static int __init sw_init(void) | 823 | module_gameport_driver(sw_drv); |
824 | { | ||
825 | return gameport_register_driver(&sw_drv); | ||
826 | } | ||
827 | |||
828 | static void __exit sw_exit(void) | ||
829 | { | ||
830 | gameport_unregister_driver(&sw_drv); | ||
831 | } | ||
832 | |||
833 | module_init(sw_init); | ||
834 | module_exit(sw_exit); | ||
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 0cd9b29356a8..80a7b27a457a 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c | |||
@@ -296,19 +296,4 @@ static struct serio_driver spaceball_drv = { | |||
296 | .disconnect = spaceball_disconnect, | 296 | .disconnect = spaceball_disconnect, |
297 | }; | 297 | }; |
298 | 298 | ||
299 | /* | 299 | module_serio_driver(spaceball_drv); |
300 | * The functions for inserting/removing us as a module. | ||
301 | */ | ||
302 | |||
303 | static int __init spaceball_init(void) | ||
304 | { | ||
305 | return serio_register_driver(&spaceball_drv); | ||
306 | } | ||
307 | |||
308 | static void __exit spaceball_exit(void) | ||
309 | { | ||
310 | serio_unregister_driver(&spaceball_drv); | ||
311 | } | ||
312 | |||
313 | module_init(spaceball_init); | ||
314 | module_exit(spaceball_exit); | ||
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index a694bf8e557b..a41f291652e6 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c | |||
@@ -237,19 +237,4 @@ static struct serio_driver spaceorb_drv = { | |||
237 | .disconnect = spaceorb_disconnect, | 237 | .disconnect = spaceorb_disconnect, |
238 | }; | 238 | }; |
239 | 239 | ||
240 | /* | 240 | module_serio_driver(spaceorb_drv); |
241 | * The functions for inserting/removing us as a module. | ||
242 | */ | ||
243 | |||
244 | static int __init spaceorb_init(void) | ||
245 | { | ||
246 | return serio_register_driver(&spaceorb_drv); | ||
247 | } | ||
248 | |||
249 | static void __exit spaceorb_exit(void) | ||
250 | { | ||
251 | serio_unregister_driver(&spaceorb_drv); | ||
252 | } | ||
253 | |||
254 | module_init(spaceorb_init); | ||
255 | module_exit(spaceorb_exit); | ||
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index e0db9f5e4b41..0f51a60e14a7 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c | |||
@@ -208,19 +208,4 @@ static struct serio_driver stinger_drv = { | |||
208 | .disconnect = stinger_disconnect, | 208 | .disconnect = stinger_disconnect, |
209 | }; | 209 | }; |
210 | 210 | ||
211 | /* | 211 | module_serio_driver(stinger_drv); |
212 | * The functions for inserting/removing us as a module. | ||
213 | */ | ||
214 | |||
215 | static int __init stinger_init(void) | ||
216 | { | ||
217 | return serio_register_driver(&stinger_drv); | ||
218 | } | ||
219 | |||
220 | static void __exit stinger_exit(void) | ||
221 | { | ||
222 | serio_unregister_driver(&stinger_drv); | ||
223 | } | ||
224 | |||
225 | module_init(stinger_init); | ||
226 | module_exit(stinger_exit); | ||
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index d6c609807115..5ef9bcdb0345 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c | |||
@@ -436,15 +436,4 @@ static struct gameport_driver tmdc_drv = { | |||
436 | .disconnect = tmdc_disconnect, | 436 | .disconnect = tmdc_disconnect, |
437 | }; | 437 | }; |
438 | 438 | ||
439 | static int __init tmdc_init(void) | 439 | module_gameport_driver(tmdc_drv); |
440 | { | ||
441 | return gameport_register_driver(&tmdc_drv); | ||
442 | } | ||
443 | |||
444 | static void __exit tmdc_exit(void) | ||
445 | { | ||
446 | gameport_unregister_driver(&tmdc_drv); | ||
447 | } | ||
448 | |||
449 | module_init(tmdc_init); | ||
450 | module_exit(tmdc_exit); | ||
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 3f4ec73c9553..2556a8193579 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c | |||
@@ -257,19 +257,4 @@ static struct serio_driver twidjoy_drv = { | |||
257 | .disconnect = twidjoy_disconnect, | 257 | .disconnect = twidjoy_disconnect, |
258 | }; | 258 | }; |
259 | 259 | ||
260 | /* | 260 | module_serio_driver(twidjoy_drv); |
261 | * The functions for inserting/removing us as a module. | ||
262 | */ | ||
263 | |||
264 | static int __init twidjoy_init(void) | ||
265 | { | ||
266 | return serio_register_driver(&twidjoy_drv); | ||
267 | } | ||
268 | |||
269 | static void __exit twidjoy_exit(void) | ||
270 | { | ||
271 | serio_unregister_driver(&twidjoy_drv); | ||
272 | } | ||
273 | |||
274 | module_init(twidjoy_init); | ||
275 | module_exit(twidjoy_exit); | ||
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index f72c83e15e60..23b3071abb6e 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c | |||
@@ -217,19 +217,4 @@ static struct serio_driver warrior_drv = { | |||
217 | .disconnect = warrior_disconnect, | 217 | .disconnect = warrior_disconnect, |
218 | }; | 218 | }; |
219 | 219 | ||
220 | /* | 220 | module_serio_driver(warrior_drv); |
221 | * The functions for inserting/removing us as a module. | ||
222 | */ | ||
223 | |||
224 | static int __init warrior_init(void) | ||
225 | { | ||
226 | return serio_register_driver(&warrior_drv); | ||
227 | } | ||
228 | |||
229 | static void __exit warrior_exit(void) | ||
230 | { | ||
231 | serio_unregister_driver(&warrior_drv); | ||
232 | } | ||
233 | |||
234 | module_init(warrior_init); | ||
235 | module_exit(warrior_exit); | ||
diff --git a/drivers/input/joystick/zhenhua.c b/drivers/input/joystick/zhenhua.c index b5853125c898..c4de4388fd7f 100644 --- a/drivers/input/joystick/zhenhua.c +++ b/drivers/input/joystick/zhenhua.c | |||
@@ -225,19 +225,4 @@ static struct serio_driver zhenhua_drv = { | |||
225 | .disconnect = zhenhua_disconnect, | 225 | .disconnect = zhenhua_disconnect, |
226 | }; | 226 | }; |
227 | 227 | ||
228 | /* | 228 | module_serio_driver(zhenhua_drv); |
229 | * The functions for inserting/removing us as a module. | ||
230 | */ | ||
231 | |||
232 | static int __init zhenhua_init(void) | ||
233 | { | ||
234 | return serio_register_driver(&zhenhua_drv); | ||
235 | } | ||
236 | |||
237 | static void __exit zhenhua_exit(void) | ||
238 | { | ||
239 | serio_unregister_driver(&zhenhua_drv); | ||
240 | } | ||
241 | |||
242 | module_init(zhenhua_init); | ||
243 | module_exit(zhenhua_exit); | ||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index f354813a13e8..c0e11ecc646f 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -166,6 +166,7 @@ config KEYBOARD_LKKBD | |||
166 | config KEYBOARD_EP93XX | 166 | config KEYBOARD_EP93XX |
167 | tristate "EP93xx Matrix Keypad support" | 167 | tristate "EP93xx Matrix Keypad support" |
168 | depends on ARCH_EP93XX | 168 | depends on ARCH_EP93XX |
169 | select INPUT_MATRIXKMAP | ||
169 | help | 170 | help |
170 | Say Y here to enable the matrix keypad on the Cirrus EP93XX. | 171 | Say Y here to enable the matrix keypad on the Cirrus EP93XX. |
171 | 172 | ||
@@ -224,6 +225,7 @@ config KEYBOARD_TCA6416 | |||
224 | config KEYBOARD_TCA8418 | 225 | config KEYBOARD_TCA8418 |
225 | tristate "TCA8418 Keypad Support" | 226 | tristate "TCA8418 Keypad Support" |
226 | depends on I2C | 227 | depends on I2C |
228 | select INPUT_MATRIXKMAP | ||
227 | help | 229 | help |
228 | This driver implements basic keypad functionality | 230 | This driver implements basic keypad functionality |
229 | for keys connected through TCA8418 keypad decoder. | 231 | for keys connected through TCA8418 keypad decoder. |
@@ -240,6 +242,7 @@ config KEYBOARD_TCA8418 | |||
240 | config KEYBOARD_MATRIX | 242 | config KEYBOARD_MATRIX |
241 | tristate "GPIO driven matrix keypad support" | 243 | tristate "GPIO driven matrix keypad support" |
242 | depends on GENERIC_GPIO | 244 | depends on GENERIC_GPIO |
245 | select INPUT_MATRIXKMAP | ||
243 | help | 246 | help |
244 | Enable support for GPIO driven matrix keypad. | 247 | Enable support for GPIO driven matrix keypad. |
245 | 248 | ||
@@ -309,6 +312,17 @@ config KEYBOARD_LM8323 | |||
309 | To compile this driver as a module, choose M here: the | 312 | To compile this driver as a module, choose M here: the |
310 | module will be called lm8323. | 313 | module will be called lm8323. |
311 | 314 | ||
315 | config KEYBOARD_LM8333 | ||
316 | tristate "LM8333 keypad chip" | ||
317 | depends on I2C | ||
318 | select INPUT_MATRIXKMAP | ||
319 | help | ||
320 | If you say yes here you get support for the National Semiconductor | ||
321 | LM8333 keypad controller. | ||
322 | |||
323 | To compile this driver as a module, choose M here: the | ||
324 | module will be called lm8333. | ||
325 | |||
312 | config KEYBOARD_LOCOMO | 326 | config KEYBOARD_LOCOMO |
313 | tristate "LoCoMo Keyboard Support" | 327 | tristate "LoCoMo Keyboard Support" |
314 | depends on SHARP_LOCOMO | 328 | depends on SHARP_LOCOMO |
@@ -366,6 +380,7 @@ config KEYBOARD_MPR121 | |||
366 | config KEYBOARD_IMX | 380 | config KEYBOARD_IMX |
367 | tristate "IMX keypad support" | 381 | tristate "IMX keypad support" |
368 | depends on ARCH_MXC | 382 | depends on ARCH_MXC |
383 | select INPUT_MATRIXKMAP | ||
369 | help | 384 | help |
370 | Enable support for IMX keypad port. | 385 | Enable support for IMX keypad port. |
371 | 386 | ||
@@ -384,6 +399,7 @@ config KEYBOARD_NEWTON | |||
384 | config KEYBOARD_NOMADIK | 399 | config KEYBOARD_NOMADIK |
385 | tristate "ST-Ericsson Nomadik SKE keyboard" | 400 | tristate "ST-Ericsson Nomadik SKE keyboard" |
386 | depends on PLAT_NOMADIK | 401 | depends on PLAT_NOMADIK |
402 | select INPUT_MATRIXKMAP | ||
387 | help | 403 | help |
388 | Say Y here if you want to use a keypad provided on the SKE controller | 404 | Say Y here if you want to use a keypad provided on the SKE controller |
389 | used on the Ux500 and Nomadik platforms | 405 | used on the Ux500 and Nomadik platforms |
@@ -394,7 +410,7 @@ config KEYBOARD_NOMADIK | |||
394 | config KEYBOARD_TEGRA | 410 | config KEYBOARD_TEGRA |
395 | tristate "NVIDIA Tegra internal matrix keyboard controller support" | 411 | tristate "NVIDIA Tegra internal matrix keyboard controller support" |
396 | depends on ARCH_TEGRA | 412 | depends on ARCH_TEGRA |
397 | select INPUT_OF_MATRIX_KEYMAP if USE_OF | 413 | select INPUT_MATRIXKMAP |
398 | help | 414 | help |
399 | Say Y here if you want to use a matrix keyboard connected directly | 415 | Say Y here if you want to use a matrix keyboard connected directly |
400 | to the internal keyboard controller on Tegra SoCs. | 416 | to the internal keyboard controller on Tegra SoCs. |
@@ -432,6 +448,7 @@ config KEYBOARD_PXA930_ROTARY | |||
432 | config KEYBOARD_PMIC8XXX | 448 | config KEYBOARD_PMIC8XXX |
433 | tristate "Qualcomm PMIC8XXX keypad support" | 449 | tristate "Qualcomm PMIC8XXX keypad support" |
434 | depends on MFD_PM8XXX | 450 | depends on MFD_PM8XXX |
451 | select INPUT_MATRIXKMAP | ||
435 | help | 452 | help |
436 | Say Y here if you want to enable the driver for the PMIC8XXX | 453 | Say Y here if you want to enable the driver for the PMIC8XXX |
437 | keypad provided as a reference design from Qualcomm. This is intended | 454 | keypad provided as a reference design from Qualcomm. This is intended |
@@ -443,6 +460,7 @@ config KEYBOARD_PMIC8XXX | |||
443 | config KEYBOARD_SAMSUNG | 460 | config KEYBOARD_SAMSUNG |
444 | tristate "Samsung keypad support" | 461 | tristate "Samsung keypad support" |
445 | depends on HAVE_CLK | 462 | depends on HAVE_CLK |
463 | select INPUT_MATRIXKMAP | ||
446 | help | 464 | help |
447 | Say Y here if you want to use the keypad on your Samsung mobile | 465 | Say Y here if you want to use the keypad on your Samsung mobile |
448 | device. | 466 | device. |
@@ -485,6 +503,7 @@ config KEYBOARD_SH_KEYSC | |||
485 | config KEYBOARD_STMPE | 503 | config KEYBOARD_STMPE |
486 | tristate "STMPE keypad support" | 504 | tristate "STMPE keypad support" |
487 | depends on MFD_STMPE | 505 | depends on MFD_STMPE |
506 | select INPUT_MATRIXKMAP | ||
488 | help | 507 | help |
489 | Say Y here if you want to use the keypad controller on STMPE I/O | 508 | Say Y here if you want to use the keypad controller on STMPE I/O |
490 | expanders. | 509 | expanders. |
@@ -505,6 +524,7 @@ config KEYBOARD_DAVINCI | |||
505 | config KEYBOARD_OMAP | 524 | config KEYBOARD_OMAP |
506 | tristate "TI OMAP keypad support" | 525 | tristate "TI OMAP keypad support" |
507 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 526 | depends on (ARCH_OMAP1 || ARCH_OMAP2) |
527 | select INPUT_MATRIXKMAP | ||
508 | help | 528 | help |
509 | Say Y here if you want to use the OMAP keypad. | 529 | Say Y here if you want to use the OMAP keypad. |
510 | 530 | ||
@@ -512,9 +532,10 @@ config KEYBOARD_OMAP | |||
512 | module will be called omap-keypad. | 532 | module will be called omap-keypad. |
513 | 533 | ||
514 | config KEYBOARD_OMAP4 | 534 | config KEYBOARD_OMAP4 |
515 | tristate "TI OMAP4 keypad support" | 535 | tristate "TI OMAP4+ keypad support" |
536 | select INPUT_MATRIXKMAP | ||
516 | help | 537 | help |
517 | Say Y here if you want to use the OMAP4 keypad. | 538 | Say Y here if you want to use the OMAP4+ keypad. |
518 | 539 | ||
519 | To compile this driver as a module, choose M here: the | 540 | To compile this driver as a module, choose M here: the |
520 | module will be called omap4-keypad. | 541 | module will be called omap4-keypad. |
@@ -522,6 +543,7 @@ config KEYBOARD_OMAP4 | |||
522 | config KEYBOARD_SPEAR | 543 | config KEYBOARD_SPEAR |
523 | tristate "ST SPEAR keyboard support" | 544 | tristate "ST SPEAR keyboard support" |
524 | depends on PLAT_SPEAR | 545 | depends on PLAT_SPEAR |
546 | select INPUT_MATRIXKMAP | ||
525 | help | 547 | help |
526 | Say Y here if you want to use the SPEAR keyboard. | 548 | Say Y here if you want to use the SPEAR keyboard. |
527 | 549 | ||
@@ -531,6 +553,7 @@ config KEYBOARD_SPEAR | |||
531 | config KEYBOARD_TC3589X | 553 | config KEYBOARD_TC3589X |
532 | tristate "TC3589X Keypad support" | 554 | tristate "TC3589X Keypad support" |
533 | depends on MFD_TC3589X | 555 | depends on MFD_TC3589X |
556 | select INPUT_MATRIXKMAP | ||
534 | help | 557 | help |
535 | Say Y here if you want to use the keypad controller on | 558 | Say Y here if you want to use the keypad controller on |
536 | TC35892/3 I/O expander. | 559 | TC35892/3 I/O expander. |
@@ -541,6 +564,7 @@ config KEYBOARD_TC3589X | |||
541 | config KEYBOARD_TNETV107X | 564 | config KEYBOARD_TNETV107X |
542 | tristate "TI TNETV107X keypad support" | 565 | tristate "TI TNETV107X keypad support" |
543 | depends on ARCH_DAVINCI_TNETV107X | 566 | depends on ARCH_DAVINCI_TNETV107X |
567 | select INPUT_MATRIXKMAP | ||
544 | help | 568 | help |
545 | Say Y here if you want to use the TNETV107X keypad. | 569 | Say Y here if you want to use the TNETV107X keypad. |
546 | 570 | ||
@@ -550,6 +574,7 @@ config KEYBOARD_TNETV107X | |||
550 | config KEYBOARD_TWL4030 | 574 | config KEYBOARD_TWL4030 |
551 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" | 575 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" |
552 | depends on TWL4030_CORE | 576 | depends on TWL4030_CORE |
577 | select INPUT_MATRIXKMAP | ||
553 | help | 578 | help |
554 | Say Y here if your board use the keypad controller on | 579 | Say Y here if your board use the keypad controller on |
555 | TWL4030 family chips. It's safe to say enable this | 580 | TWL4030 family chips. It's safe to say enable this |
@@ -573,6 +598,7 @@ config KEYBOARD_XTKBD | |||
573 | config KEYBOARD_W90P910 | 598 | config KEYBOARD_W90P910 |
574 | tristate "W90P910 Matrix Keypad support" | 599 | tristate "W90P910 Matrix Keypad support" |
575 | depends on ARCH_W90X900 | 600 | depends on ARCH_W90X900 |
601 | select INPUT_MATRIXKMAP | ||
576 | help | 602 | help |
577 | Say Y here to enable the matrix keypad on evaluation board | 603 | Say Y here to enable the matrix keypad on evaluation board |
578 | based on W90P910. | 604 | based on W90P910. |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index df7061f12918..b03b02456a82 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -24,6 +24,7 @@ obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | |||
24 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | 24 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o |
25 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | 25 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o |
26 | obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o | 26 | obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o |
27 | obj-$(CONFIG_KEYBOARD_LM8333) += lm8333.o | ||
27 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o | 28 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o |
28 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | 29 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o |
29 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o | 30 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 39ebffac207e..b083bf10f139 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -197,6 +197,7 @@ static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad) | |||
197 | kpad->gc.base = gpio_data->gpio_start; | 197 | kpad->gc.base = gpio_data->gpio_start; |
198 | kpad->gc.label = kpad->client->name; | 198 | kpad->gc.label = kpad->client->name; |
199 | kpad->gc.owner = THIS_MODULE; | 199 | kpad->gc.owner = THIS_MODULE; |
200 | kpad->gc.names = gpio_data->names; | ||
200 | 201 | ||
201 | mutex_init(&kpad->gpio_lock); | 202 | mutex_init(&kpad->gpio_lock); |
202 | 203 | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index e05a2e7073c6..add5ffd9fe26 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -433,7 +433,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
433 | if (printk_ratelimit()) | 433 | if (printk_ratelimit()) |
434 | dev_warn(&serio->dev, | 434 | dev_warn(&serio->dev, |
435 | "Spurious %s on %s. " | 435 | "Spurious %s on %s. " |
436 | "Some program might be trying access hardware directly.\n", | 436 | "Some program might be trying to access hardware directly.\n", |
437 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); | 437 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); |
438 | goto out; | 438 | goto out; |
439 | case ATKBD_RET_ERR: | 439 | case ATKBD_RET_ERR: |
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index 0ba69f3fcb52..c46fc8185469 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
@@ -182,16 +182,10 @@ static void ep93xx_keypad_close(struct input_dev *pdev) | |||
182 | } | 182 | } |
183 | 183 | ||
184 | 184 | ||
185 | #ifdef CONFIG_PM | 185 | #ifdef CONFIG_PM_SLEEP |
186 | /* | 186 | static int ep93xx_keypad_suspend(struct device *dev) |
187 | * NOTE: I don't know if this is correct, or will work on the ep93xx. | ||
188 | * | ||
189 | * None of the existing ep93xx drivers have power management support. | ||
190 | * But, this is basically what the pxa27x_keypad driver does. | ||
191 | */ | ||
192 | static int ep93xx_keypad_suspend(struct platform_device *pdev, | ||
193 | pm_message_t state) | ||
194 | { | 187 | { |
188 | struct platform_device *pdev = to_platform_device(dev); | ||
195 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | 189 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); |
196 | struct input_dev *input_dev = keypad->input_dev; | 190 | struct input_dev *input_dev = keypad->input_dev; |
197 | 191 | ||
@@ -210,8 +204,9 @@ static int ep93xx_keypad_suspend(struct platform_device *pdev, | |||
210 | return 0; | 204 | return 0; |
211 | } | 205 | } |
212 | 206 | ||
213 | static int ep93xx_keypad_resume(struct platform_device *pdev) | 207 | static int ep93xx_keypad_resume(struct device *dev) |
214 | { | 208 | { |
209 | struct platform_device *pdev = to_platform_device(dev); | ||
215 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | 210 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); |
216 | struct input_dev *input_dev = keypad->input_dev; | 211 | struct input_dev *input_dev = keypad->input_dev; |
217 | 212 | ||
@@ -232,10 +227,10 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) | |||
232 | 227 | ||
233 | return 0; | 228 | return 0; |
234 | } | 229 | } |
235 | #else /* !CONFIG_PM */ | 230 | #endif |
236 | #define ep93xx_keypad_suspend NULL | 231 | |
237 | #define ep93xx_keypad_resume NULL | 232 | static SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops, |
238 | #endif /* !CONFIG_PM */ | 233 | ep93xx_keypad_suspend, ep93xx_keypad_resume); |
239 | 234 | ||
240 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | 235 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) |
241 | { | 236 | { |
@@ -308,19 +303,16 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
308 | input_dev->open = ep93xx_keypad_open; | 303 | input_dev->open = ep93xx_keypad_open; |
309 | input_dev->close = ep93xx_keypad_close; | 304 | input_dev->close = ep93xx_keypad_close; |
310 | input_dev->dev.parent = &pdev->dev; | 305 | input_dev->dev.parent = &pdev->dev; |
311 | input_dev->keycode = keypad->keycodes; | ||
312 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
313 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
314 | 306 | ||
315 | input_set_drvdata(input_dev, keypad); | 307 | err = matrix_keypad_build_keymap(keymap_data, NULL, |
308 | EP93XX_MATRIX_ROWS, EP93XX_MATRIX_COLS, | ||
309 | keypad->keycodes, input_dev); | ||
310 | if (err) | ||
311 | goto failed_free_dev; | ||
316 | 312 | ||
317 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
318 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) | 313 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) |
319 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | 314 | __set_bit(EV_REP, input_dev->evbit); |
320 | 315 | input_set_drvdata(input_dev, keypad); | |
321 | matrix_keypad_build_keymap(keymap_data, 3, | ||
322 | input_dev->keycode, input_dev->keybit); | ||
323 | platform_set_drvdata(pdev, keypad); | ||
324 | 316 | ||
325 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, | 317 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, |
326 | 0, pdev->name, keypad); | 318 | 0, pdev->name, keypad); |
@@ -331,6 +323,7 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
331 | if (err) | 323 | if (err) |
332 | goto failed_free_irq; | 324 | goto failed_free_irq; |
333 | 325 | ||
326 | platform_set_drvdata(pdev, keypad); | ||
334 | device_init_wakeup(&pdev->dev, 1); | 327 | device_init_wakeup(&pdev->dev, 1); |
335 | 328 | ||
336 | return 0; | 329 | return 0; |
@@ -384,11 +377,10 @@ static struct platform_driver ep93xx_keypad_driver = { | |||
384 | .driver = { | 377 | .driver = { |
385 | .name = "ep93xx-keypad", | 378 | .name = "ep93xx-keypad", |
386 | .owner = THIS_MODULE, | 379 | .owner = THIS_MODULE, |
380 | .pm = &ep93xx_keypad_pm_ops, | ||
387 | }, | 381 | }, |
388 | .probe = ep93xx_keypad_probe, | 382 | .probe = ep93xx_keypad_probe, |
389 | .remove = __devexit_p(ep93xx_keypad_remove), | 383 | .remove = __devexit_p(ep93xx_keypad_remove), |
390 | .suspend = ep93xx_keypad_suspend, | ||
391 | .resume = ep93xx_keypad_resume, | ||
392 | }; | 384 | }; |
393 | module_platform_driver(ep93xx_keypad_driver); | 385 | module_platform_driver(ep93xx_keypad_driver); |
394 | 386 | ||
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index fed31e0947a1..589e3c258f3f 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -583,15 +583,4 @@ static struct serio_driver hil_serio_drv = { | |||
583 | .interrupt = hil_dev_interrupt | 583 | .interrupt = hil_dev_interrupt |
584 | }; | 584 | }; |
585 | 585 | ||
586 | static int __init hil_dev_init(void) | 586 | module_serio_driver(hil_serio_drv); |
587 | { | ||
588 | return serio_register_driver(&hil_serio_drv); | ||
589 | } | ||
590 | |||
591 | static void __exit hil_dev_exit(void) | ||
592 | { | ||
593 | serio_unregister_driver(&hil_serio_drv); | ||
594 | } | ||
595 | |||
596 | module_init(hil_dev_init); | ||
597 | module_exit(hil_dev_exit); | ||
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index fb87b3bcadb9..6ee7421e2321 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -481,7 +481,7 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev) | |||
481 | } | 481 | } |
482 | 482 | ||
483 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || | 483 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || |
484 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { | 484 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { |
485 | dev_err(&pdev->dev, | 485 | dev_err(&pdev->dev, |
486 | "invalid key data (too many rows or colums)\n"); | 486 | "invalid key data (too many rows or colums)\n"); |
487 | error = -EINVAL; | 487 | error = -EINVAL; |
@@ -496,14 +496,17 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev) | |||
496 | input_dev->dev.parent = &pdev->dev; | 496 | input_dev->dev.parent = &pdev->dev; |
497 | input_dev->open = imx_keypad_open; | 497 | input_dev->open = imx_keypad_open; |
498 | input_dev->close = imx_keypad_close; | 498 | input_dev->close = imx_keypad_close; |
499 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
500 | input_dev->keycode = keypad->keycodes; | ||
501 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
502 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
503 | 499 | ||
504 | matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, | 500 | error = matrix_keypad_build_keymap(keymap_data, NULL, |
505 | keypad->keycodes, input_dev->keybit); | 501 | MAX_MATRIX_KEY_ROWS, |
502 | MAX_MATRIX_KEY_COLS, | ||
503 | keypad->keycodes, input_dev); | ||
504 | if (error) { | ||
505 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
506 | goto failed_clock_put; | ||
507 | } | ||
506 | 508 | ||
509 | __set_bit(EV_REP, input_dev->evbit); | ||
507 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 510 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
508 | input_set_drvdata(input_dev, keypad); | 511 | input_set_drvdata(input_dev, keypad); |
509 | 512 | ||
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index fa9bb6d235e2..fc0a63c2f278 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -731,19 +731,4 @@ static struct serio_driver lkkbd_drv = { | |||
731 | .interrupt = lkkbd_interrupt, | 731 | .interrupt = lkkbd_interrupt, |
732 | }; | 732 | }; |
733 | 733 | ||
734 | /* | 734 | module_serio_driver(lkkbd_drv); |
735 | * The functions for insering/removing us as a module. | ||
736 | */ | ||
737 | static int __init lkkbd_init(void) | ||
738 | { | ||
739 | return serio_register_driver(&lkkbd_drv); | ||
740 | } | ||
741 | |||
742 | static void __exit lkkbd_exit(void) | ||
743 | { | ||
744 | serio_unregister_driver(&lkkbd_drv); | ||
745 | } | ||
746 | |||
747 | module_init(lkkbd_init); | ||
748 | module_exit(lkkbd_exit); | ||
749 | |||
diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c new file mode 100644 index 000000000000..ca168a6679de --- /dev/null +++ b/drivers/input/keyboard/lm8333.c | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * LM8333 keypad driver | ||
3 | * Copyright (C) 2012 Wolfram Sang, Pengutronix <w.sang@pengutronix.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/input/matrix_keypad.h> | ||
16 | #include <linux/input/lm8333.h> | ||
17 | |||
18 | #define LM8333_FIFO_READ 0x20 | ||
19 | #define LM8333_DEBOUNCE 0x22 | ||
20 | #define LM8333_READ_INT 0xD0 | ||
21 | #define LM8333_ACTIVE 0xE4 | ||
22 | #define LM8333_READ_ERROR 0xF0 | ||
23 | |||
24 | #define LM8333_KEYPAD_IRQ (1 << 0) | ||
25 | #define LM8333_ERROR_IRQ (1 << 3) | ||
26 | |||
27 | #define LM8333_ERROR_KEYOVR 0x04 | ||
28 | #define LM8333_ERROR_FIFOOVR 0x40 | ||
29 | |||
30 | #define LM8333_FIFO_TRANSFER_SIZE 16 | ||
31 | |||
32 | #define LM8333_NUM_ROWS 8 | ||
33 | #define LM8333_NUM_COLS 16 | ||
34 | #define LM8333_ROW_SHIFT 4 | ||
35 | |||
36 | struct lm8333 { | ||
37 | struct i2c_client *client; | ||
38 | struct input_dev *input; | ||
39 | unsigned short keycodes[LM8333_NUM_ROWS << LM8333_ROW_SHIFT]; | ||
40 | }; | ||
41 | |||
42 | /* The accessors try twice because the first access may be needed for wakeup */ | ||
43 | #define LM8333_READ_RETRIES 2 | ||
44 | |||
45 | int lm8333_read8(struct lm8333 *lm8333, u8 cmd) | ||
46 | { | ||
47 | int retries = 0, ret; | ||
48 | |||
49 | do { | ||
50 | ret = i2c_smbus_read_byte_data(lm8333->client, cmd); | ||
51 | } while (ret < 0 && retries++ < LM8333_READ_RETRIES); | ||
52 | |||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | int lm8333_write8(struct lm8333 *lm8333, u8 cmd, u8 val) | ||
57 | { | ||
58 | int retries = 0, ret; | ||
59 | |||
60 | do { | ||
61 | ret = i2c_smbus_write_byte_data(lm8333->client, cmd, val); | ||
62 | } while (ret < 0 && retries++ < LM8333_READ_RETRIES); | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | int lm8333_read_block(struct lm8333 *lm8333, u8 cmd, u8 len, u8 *buf) | ||
68 | { | ||
69 | int retries = 0, ret; | ||
70 | |||
71 | do { | ||
72 | ret = i2c_smbus_read_i2c_block_data(lm8333->client, | ||
73 | cmd, len, buf); | ||
74 | } while (ret < 0 && retries++ < LM8333_READ_RETRIES); | ||
75 | |||
76 | return ret; | ||
77 | } | ||
78 | |||
79 | static void lm8333_key_handler(struct lm8333 *lm8333) | ||
80 | { | ||
81 | struct input_dev *input = lm8333->input; | ||
82 | u8 keys[LM8333_FIFO_TRANSFER_SIZE]; | ||
83 | u8 code, pressed; | ||
84 | int i, ret; | ||
85 | |||
86 | ret = lm8333_read_block(lm8333, LM8333_FIFO_READ, | ||
87 | LM8333_FIFO_TRANSFER_SIZE, keys); | ||
88 | if (ret != LM8333_FIFO_TRANSFER_SIZE) { | ||
89 | dev_err(&lm8333->client->dev, | ||
90 | "Error %d while reading FIFO\n", ret); | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | for (i = 0; keys[i] && i < LM8333_FIFO_TRANSFER_SIZE; i++) { | ||
95 | pressed = keys[i] & 0x80; | ||
96 | code = keys[i] & 0x7f; | ||
97 | |||
98 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
99 | input_report_key(input, lm8333->keycodes[code], pressed); | ||
100 | } | ||
101 | |||
102 | input_sync(input); | ||
103 | } | ||
104 | |||
105 | static irqreturn_t lm8333_irq_thread(int irq, void *data) | ||
106 | { | ||
107 | struct lm8333 *lm8333 = data; | ||
108 | u8 status = lm8333_read8(lm8333, LM8333_READ_INT); | ||
109 | |||
110 | if (!status) | ||
111 | return IRQ_NONE; | ||
112 | |||
113 | if (status & LM8333_ERROR_IRQ) { | ||
114 | u8 err = lm8333_read8(lm8333, LM8333_READ_ERROR); | ||
115 | |||
116 | if (err & (LM8333_ERROR_KEYOVR | LM8333_ERROR_FIFOOVR)) { | ||
117 | u8 dummy[LM8333_FIFO_TRANSFER_SIZE]; | ||
118 | |||
119 | lm8333_read_block(lm8333, LM8333_FIFO_READ, | ||
120 | LM8333_FIFO_TRANSFER_SIZE, dummy); | ||
121 | } | ||
122 | dev_err(&lm8333->client->dev, "Got error %02x\n", err); | ||
123 | } | ||
124 | |||
125 | if (status & LM8333_KEYPAD_IRQ) | ||
126 | lm8333_key_handler(lm8333); | ||
127 | |||
128 | return IRQ_HANDLED; | ||
129 | } | ||
130 | |||
131 | static int __devinit lm8333_probe(struct i2c_client *client, | ||
132 | const struct i2c_device_id *id) | ||
133 | { | ||
134 | const struct lm8333_platform_data *pdata = client->dev.platform_data; | ||
135 | struct lm8333 *lm8333; | ||
136 | struct input_dev *input; | ||
137 | int err, active_time; | ||
138 | |||
139 | if (!pdata) | ||
140 | return -EINVAL; | ||
141 | |||
142 | active_time = pdata->active_time ?: 500; | ||
143 | if (active_time / 3 <= pdata->debounce_time / 3) { | ||
144 | dev_err(&client->dev, "Active time not big enough!\n"); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | |||
148 | lm8333 = kzalloc(sizeof(*lm8333), GFP_KERNEL); | ||
149 | input = input_allocate_device(); | ||
150 | if (!lm8333 || !input) { | ||
151 | err = -ENOMEM; | ||
152 | goto free_mem; | ||
153 | } | ||
154 | |||
155 | lm8333->client = client; | ||
156 | lm8333->input = input; | ||
157 | |||
158 | input->name = client->name; | ||
159 | input->dev.parent = &client->dev; | ||
160 | input->id.bustype = BUS_I2C; | ||
161 | |||
162 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
163 | |||
164 | err = matrix_keypad_build_keymap(pdata->matrix_data, NULL, | ||
165 | LM8333_NUM_ROWS, LM8333_NUM_COLS, | ||
166 | lm8333->keycodes, input); | ||
167 | if (err) | ||
168 | goto free_mem; | ||
169 | |||
170 | if (pdata->debounce_time) { | ||
171 | err = lm8333_write8(lm8333, LM8333_DEBOUNCE, | ||
172 | pdata->debounce_time / 3); | ||
173 | if (err) | ||
174 | dev_warn(&client->dev, "Unable to set debounce time\n"); | ||
175 | } | ||
176 | |||
177 | if (pdata->active_time) { | ||
178 | err = lm8333_write8(lm8333, LM8333_ACTIVE, | ||
179 | pdata->active_time / 3); | ||
180 | if (err) | ||
181 | dev_warn(&client->dev, "Unable to set active time\n"); | ||
182 | } | ||
183 | |||
184 | err = request_threaded_irq(client->irq, NULL, lm8333_irq_thread, | ||
185 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
186 | "lm8333", lm8333); | ||
187 | if (err) | ||
188 | goto free_mem; | ||
189 | |||
190 | err = input_register_device(input); | ||
191 | if (err) | ||
192 | goto free_irq; | ||
193 | |||
194 | i2c_set_clientdata(client, lm8333); | ||
195 | return 0; | ||
196 | |||
197 | free_irq: | ||
198 | free_irq(client->irq, lm8333); | ||
199 | free_mem: | ||
200 | input_free_device(input); | ||
201 | kfree(lm8333); | ||
202 | return err; | ||
203 | } | ||
204 | |||
205 | static int __devexit lm8333_remove(struct i2c_client *client) | ||
206 | { | ||
207 | struct lm8333 *lm8333 = i2c_get_clientdata(client); | ||
208 | |||
209 | free_irq(client->irq, lm8333); | ||
210 | input_unregister_device(lm8333->input); | ||
211 | kfree(lm8333); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static const struct i2c_device_id lm8333_id[] = { | ||
217 | { "lm8333", 0 }, | ||
218 | { } | ||
219 | }; | ||
220 | MODULE_DEVICE_TABLE(i2c, lm8333_id); | ||
221 | |||
222 | static struct i2c_driver lm8333_driver = { | ||
223 | .driver = { | ||
224 | .name = "lm8333", | ||
225 | .owner = THIS_MODULE, | ||
226 | }, | ||
227 | .probe = lm8333_probe, | ||
228 | .remove = __devexit_p(lm8333_remove), | ||
229 | .id_table = lm8333_id, | ||
230 | }; | ||
231 | module_i2c_driver(lm8333_driver); | ||
232 | |||
233 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); | ||
234 | MODULE_DESCRIPTION("LM8333 keyboard driver"); | ||
235 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 9b223d73de32..18b72372028a 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -27,7 +27,6 @@ | |||
27 | struct matrix_keypad { | 27 | struct matrix_keypad { |
28 | const struct matrix_keypad_platform_data *pdata; | 28 | const struct matrix_keypad_platform_data *pdata; |
29 | struct input_dev *input_dev; | 29 | struct input_dev *input_dev; |
30 | unsigned short *keycodes; | ||
31 | unsigned int row_shift; | 30 | unsigned int row_shift; |
32 | 31 | ||
33 | DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); | 32 | DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); |
@@ -38,6 +37,8 @@ struct matrix_keypad { | |||
38 | bool scan_pending; | 37 | bool scan_pending; |
39 | bool stopped; | 38 | bool stopped; |
40 | bool gpio_all_disabled; | 39 | bool gpio_all_disabled; |
40 | |||
41 | unsigned short keycodes[]; | ||
41 | }; | 42 | }; |
42 | 43 | ||
43 | /* | 44 | /* |
@@ -224,7 +225,7 @@ static void matrix_keypad_stop(struct input_dev *dev) | |||
224 | disable_row_irqs(keypad); | 225 | disable_row_irqs(keypad); |
225 | } | 226 | } |
226 | 227 | ||
227 | #ifdef CONFIG_PM | 228 | #ifdef CONFIG_PM_SLEEP |
228 | static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) | 229 | static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) |
229 | { | 230 | { |
230 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 231 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
@@ -293,16 +294,16 @@ static int matrix_keypad_resume(struct device *dev) | |||
293 | 294 | ||
294 | return 0; | 295 | return 0; |
295 | } | 296 | } |
296 | |||
297 | static const SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, | ||
298 | matrix_keypad_suspend, matrix_keypad_resume); | ||
299 | #endif | 297 | #endif |
300 | 298 | ||
301 | static int __devinit init_matrix_gpio(struct platform_device *pdev, | 299 | static SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, |
302 | struct matrix_keypad *keypad) | 300 | matrix_keypad_suspend, matrix_keypad_resume); |
301 | |||
302 | static int __devinit matrix_keypad_init_gpio(struct platform_device *pdev, | ||
303 | struct matrix_keypad *keypad) | ||
303 | { | 304 | { |
304 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 305 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
305 | int i, err = -EINVAL; | 306 | int i, err; |
306 | 307 | ||
307 | /* initialized strobe lines as outputs, activated */ | 308 | /* initialized strobe lines as outputs, activated */ |
308 | for (i = 0; i < pdata->num_col_gpios; i++) { | 309 | for (i = 0; i < pdata->num_col_gpios; i++) { |
@@ -348,8 +349,7 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev, | |||
348 | "matrix-keypad", keypad); | 349 | "matrix-keypad", keypad); |
349 | if (err) { | 350 | if (err) { |
350 | dev_err(&pdev->dev, | 351 | dev_err(&pdev->dev, |
351 | "Unable to acquire interrupt " | 352 | "Unable to acquire interrupt for GPIO line %i\n", |
352 | "for GPIO line %i\n", | ||
353 | pdata->row_gpios[i]); | 353 | pdata->row_gpios[i]); |
354 | goto err_free_irqs; | 354 | goto err_free_irqs; |
355 | } | 355 | } |
@@ -375,14 +375,33 @@ err_free_cols: | |||
375 | return err; | 375 | return err; |
376 | } | 376 | } |
377 | 377 | ||
378 | static void matrix_keypad_free_gpio(struct matrix_keypad *keypad) | ||
379 | { | ||
380 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
381 | int i; | ||
382 | |||
383 | if (pdata->clustered_irq > 0) { | ||
384 | free_irq(pdata->clustered_irq, keypad); | ||
385 | } else { | ||
386 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
387 | free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); | ||
388 | } | ||
389 | |||
390 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
391 | gpio_free(pdata->row_gpios[i]); | ||
392 | |||
393 | for (i = 0; i < pdata->num_col_gpios; i++) | ||
394 | gpio_free(pdata->col_gpios[i]); | ||
395 | } | ||
396 | |||
378 | static int __devinit matrix_keypad_probe(struct platform_device *pdev) | 397 | static int __devinit matrix_keypad_probe(struct platform_device *pdev) |
379 | { | 398 | { |
380 | const struct matrix_keypad_platform_data *pdata; | 399 | const struct matrix_keypad_platform_data *pdata; |
381 | const struct matrix_keymap_data *keymap_data; | 400 | const struct matrix_keymap_data *keymap_data; |
382 | struct matrix_keypad *keypad; | 401 | struct matrix_keypad *keypad; |
383 | struct input_dev *input_dev; | 402 | struct input_dev *input_dev; |
384 | unsigned short *keycodes; | ||
385 | unsigned int row_shift; | 403 | unsigned int row_shift; |
404 | size_t keymap_size; | ||
386 | int err; | 405 | int err; |
387 | 406 | ||
388 | pdata = pdev->dev.platform_data; | 407 | pdata = pdev->dev.platform_data; |
@@ -398,20 +417,18 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) | |||
398 | } | 417 | } |
399 | 418 | ||
400 | row_shift = get_count_order(pdata->num_col_gpios); | 419 | row_shift = get_count_order(pdata->num_col_gpios); |
401 | 420 | keymap_size = (pdata->num_row_gpios << row_shift) * | |
402 | keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); | 421 | sizeof(keypad->keycodes[0]); |
403 | keycodes = kzalloc((pdata->num_row_gpios << row_shift) * | 422 | keypad = kzalloc(sizeof(struct matrix_keypad) + keymap_size, |
404 | sizeof(*keycodes), | 423 | GFP_KERNEL); |
405 | GFP_KERNEL); | ||
406 | input_dev = input_allocate_device(); | 424 | input_dev = input_allocate_device(); |
407 | if (!keypad || !keycodes || !input_dev) { | 425 | if (!keypad || !input_dev) { |
408 | err = -ENOMEM; | 426 | err = -ENOMEM; |
409 | goto err_free_mem; | 427 | goto err_free_mem; |
410 | } | 428 | } |
411 | 429 | ||
412 | keypad->input_dev = input_dev; | 430 | keypad->input_dev = input_dev; |
413 | keypad->pdata = pdata; | 431 | keypad->pdata = pdata; |
414 | keypad->keycodes = keycodes; | ||
415 | keypad->row_shift = row_shift; | 432 | keypad->row_shift = row_shift; |
416 | keypad->stopped = true; | 433 | keypad->stopped = true; |
417 | INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); | 434 | INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); |
@@ -420,38 +437,38 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) | |||
420 | input_dev->name = pdev->name; | 437 | input_dev->name = pdev->name; |
421 | input_dev->id.bustype = BUS_HOST; | 438 | input_dev->id.bustype = BUS_HOST; |
422 | input_dev->dev.parent = &pdev->dev; | 439 | input_dev->dev.parent = &pdev->dev; |
423 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
424 | if (!pdata->no_autorepeat) | ||
425 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
426 | input_dev->open = matrix_keypad_start; | 440 | input_dev->open = matrix_keypad_start; |
427 | input_dev->close = matrix_keypad_stop; | 441 | input_dev->close = matrix_keypad_stop; |
428 | 442 | ||
429 | input_dev->keycode = keycodes; | 443 | err = matrix_keypad_build_keymap(keymap_data, NULL, |
430 | input_dev->keycodesize = sizeof(*keycodes); | 444 | pdata->num_row_gpios, |
431 | input_dev->keycodemax = pdata->num_row_gpios << row_shift; | 445 | pdata->num_col_gpios, |
432 | 446 | keypad->keycodes, input_dev); | |
433 | matrix_keypad_build_keymap(keymap_data, row_shift, | 447 | if (err) |
434 | input_dev->keycode, input_dev->keybit); | 448 | goto err_free_mem; |
435 | 449 | ||
450 | if (!pdata->no_autorepeat) | ||
451 | __set_bit(EV_REP, input_dev->evbit); | ||
436 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 452 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
437 | input_set_drvdata(input_dev, keypad); | 453 | input_set_drvdata(input_dev, keypad); |
438 | 454 | ||
439 | err = init_matrix_gpio(pdev, keypad); | 455 | err = matrix_keypad_init_gpio(pdev, keypad); |
440 | if (err) | 456 | if (err) |
441 | goto err_free_mem; | 457 | goto err_free_mem; |
442 | 458 | ||
443 | err = input_register_device(keypad->input_dev); | 459 | err = input_register_device(keypad->input_dev); |
444 | if (err) | 460 | if (err) |
445 | goto err_free_mem; | 461 | goto err_free_gpio; |
446 | 462 | ||
447 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 463 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
448 | platform_set_drvdata(pdev, keypad); | 464 | platform_set_drvdata(pdev, keypad); |
449 | 465 | ||
450 | return 0; | 466 | return 0; |
451 | 467 | ||
468 | err_free_gpio: | ||
469 | matrix_keypad_free_gpio(keypad); | ||
452 | err_free_mem: | 470 | err_free_mem: |
453 | input_free_device(input_dev); | 471 | input_free_device(input_dev); |
454 | kfree(keycodes); | ||
455 | kfree(keypad); | 472 | kfree(keypad); |
456 | return err; | 473 | return err; |
457 | } | 474 | } |
@@ -459,29 +476,15 @@ err_free_mem: | |||
459 | static int __devexit matrix_keypad_remove(struct platform_device *pdev) | 476 | static int __devexit matrix_keypad_remove(struct platform_device *pdev) |
460 | { | 477 | { |
461 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 478 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
462 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | ||
463 | int i; | ||
464 | 479 | ||
465 | device_init_wakeup(&pdev->dev, 0); | 480 | device_init_wakeup(&pdev->dev, 0); |
466 | 481 | ||
467 | if (pdata->clustered_irq > 0) { | 482 | matrix_keypad_free_gpio(keypad); |
468 | free_irq(pdata->clustered_irq, keypad); | ||
469 | } else { | ||
470 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
471 | free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); | ||
472 | } | ||
473 | |||
474 | for (i = 0; i < pdata->num_row_gpios; i++) | ||
475 | gpio_free(pdata->row_gpios[i]); | ||
476 | |||
477 | for (i = 0; i < pdata->num_col_gpios; i++) | ||
478 | gpio_free(pdata->col_gpios[i]); | ||
479 | |||
480 | input_unregister_device(keypad->input_dev); | 483 | input_unregister_device(keypad->input_dev); |
481 | platform_set_drvdata(pdev, NULL); | ||
482 | kfree(keypad->keycodes); | ||
483 | kfree(keypad); | 484 | kfree(keypad); |
484 | 485 | ||
486 | platform_set_drvdata(pdev, NULL); | ||
487 | |||
485 | return 0; | 488 | return 0; |
486 | } | 489 | } |
487 | 490 | ||
@@ -491,9 +494,7 @@ static struct platform_driver matrix_keypad_driver = { | |||
491 | .driver = { | 494 | .driver = { |
492 | .name = "matrix-keypad", | 495 | .name = "matrix-keypad", |
493 | .owner = THIS_MODULE, | 496 | .owner = THIS_MODULE, |
494 | #ifdef CONFIG_PM | ||
495 | .pm = &matrix_keypad_pm_ops, | 497 | .pm = &matrix_keypad_pm_ops, |
496 | #endif | ||
497 | }, | 498 | }, |
498 | }; | 499 | }; |
499 | module_platform_driver(matrix_keypad_driver); | 500 | module_platform_driver(matrix_keypad_driver); |
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index 48d1cab0aa1c..f971898ad591 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c | |||
@@ -166,15 +166,4 @@ static struct serio_driver nkbd_drv = { | |||
166 | .disconnect = nkbd_disconnect, | 166 | .disconnect = nkbd_disconnect, |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static int __init nkbd_init(void) | 169 | module_serio_driver(nkbd_drv); |
170 | { | ||
171 | return serio_register_driver(&nkbd_drv); | ||
172 | } | ||
173 | |||
174 | static void __exit nkbd_exit(void) | ||
175 | { | ||
176 | serio_unregister_driver(&nkbd_drv); | ||
177 | } | ||
178 | |||
179 | module_init(nkbd_init); | ||
180 | module_exit(nkbd_exit); | ||
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 101e245944e7..4ea4341a68c5 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
@@ -39,7 +39,8 @@ | |||
39 | #define SKE_KPRISA (0x1 << 2) | 39 | #define SKE_KPRISA (0x1 << 2) |
40 | 40 | ||
41 | #define SKE_KEYPAD_ROW_SHIFT 3 | 41 | #define SKE_KEYPAD_ROW_SHIFT 3 |
42 | #define SKE_KPD_KEYMAP_SIZE (8 * 8) | 42 | #define SKE_KPD_NUM_ROWS 8 |
43 | #define SKE_KPD_NUM_COLS 8 | ||
43 | 44 | ||
44 | /* keypad auto scan registers */ | 45 | /* keypad auto scan registers */ |
45 | #define SKE_ASR0 0x20 | 46 | #define SKE_ASR0 0x20 |
@@ -63,7 +64,7 @@ struct ske_keypad { | |||
63 | void __iomem *reg_base; | 64 | void __iomem *reg_base; |
64 | struct input_dev *input; | 65 | struct input_dev *input; |
65 | const struct ske_keypad_platform_data *board; | 66 | const struct ske_keypad_platform_data *board; |
66 | unsigned short keymap[SKE_KPD_KEYMAP_SIZE]; | 67 | unsigned short keymap[SKE_KPD_NUM_ROWS * SKE_KPD_NUM_COLS]; |
67 | struct clk *clk; | 68 | struct clk *clk; |
68 | spinlock_t ske_keypad_lock; | 69 | spinlock_t ske_keypad_lock; |
69 | }; | 70 | }; |
@@ -261,19 +262,18 @@ static int __init ske_keypad_probe(struct platform_device *pdev) | |||
261 | input->name = "ux500-ske-keypad"; | 262 | input->name = "ux500-ske-keypad"; |
262 | input->dev.parent = &pdev->dev; | 263 | input->dev.parent = &pdev->dev; |
263 | 264 | ||
264 | input->keycode = keypad->keymap; | 265 | error = matrix_keypad_build_keymap(plat->keymap_data, NULL, |
265 | input->keycodesize = sizeof(keypad->keymap[0]); | 266 | SKE_KPD_NUM_ROWS, SKE_KPD_NUM_COLS, |
266 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | 267 | keypad->keymap, input); |
268 | if (error) { | ||
269 | dev_err(&pdev->dev, "Failed to build keymap\n"); | ||
270 | goto err_iounmap; | ||
271 | } | ||
267 | 272 | ||
268 | input_set_capability(input, EV_MSC, MSC_SCAN); | 273 | input_set_capability(input, EV_MSC, MSC_SCAN); |
269 | |||
270 | __set_bit(EV_KEY, input->evbit); | ||
271 | if (!plat->no_autorepeat) | 274 | if (!plat->no_autorepeat) |
272 | __set_bit(EV_REP, input->evbit); | 275 | __set_bit(EV_REP, input->evbit); |
273 | 276 | ||
274 | matrix_keypad_build_keymap(plat->keymap_data, SKE_KEYPAD_ROW_SHIFT, | ||
275 | input->keycode, input->keybit); | ||
276 | |||
277 | clk_enable(keypad->clk); | 277 | clk_enable(keypad->clk); |
278 | 278 | ||
279 | /* go through board initialization helpers */ | 279 | /* go through board initialization helpers */ |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 6b630d9d3dff..a0222db4dc86 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -61,6 +61,7 @@ struct omap_kp { | |||
61 | unsigned int cols; | 61 | unsigned int cols; |
62 | unsigned long delay; | 62 | unsigned long delay; |
63 | unsigned int debounce; | 63 | unsigned int debounce; |
64 | unsigned short keymap[]; | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); | 67 | static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); |
@@ -316,13 +317,6 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
316 | if (!cpu_is_omap24xx()) | 317 | if (!cpu_is_omap24xx()) |
317 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | 318 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
318 | 319 | ||
319 | input_dev->keycode = &omap_kp[1]; | ||
320 | input_dev->keycodesize = sizeof(unsigned short); | ||
321 | input_dev->keycodemax = keycodemax; | ||
322 | |||
323 | if (pdata->rep) | ||
324 | __set_bit(EV_REP, input_dev->evbit); | ||
325 | |||
326 | if (pdata->delay) | 320 | if (pdata->delay) |
327 | omap_kp->delay = pdata->delay; | 321 | omap_kp->delay = pdata->delay; |
328 | 322 | ||
@@ -371,9 +365,6 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
371 | goto err2; | 365 | goto err2; |
372 | 366 | ||
373 | /* setup input device */ | 367 | /* setup input device */ |
374 | __set_bit(EV_KEY, input_dev->evbit); | ||
375 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, | ||
376 | input_dev->keycode, input_dev->keybit); | ||
377 | input_dev->name = "omap-keypad"; | 368 | input_dev->name = "omap-keypad"; |
378 | input_dev->phys = "omap-keypad/input0"; | 369 | input_dev->phys = "omap-keypad/input0"; |
379 | input_dev->dev.parent = &pdev->dev; | 370 | input_dev->dev.parent = &pdev->dev; |
@@ -383,6 +374,15 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
383 | input_dev->id.product = 0x0001; | 374 | input_dev->id.product = 0x0001; |
384 | input_dev->id.version = 0x0100; | 375 | input_dev->id.version = 0x0100; |
385 | 376 | ||
377 | if (pdata->rep) | ||
378 | __set_bit(EV_REP, input_dev->evbit); | ||
379 | |||
380 | ret = matrix_keypad_build_keymap(pdata->keymap_data, NULL, | ||
381 | pdata->rows, pdata->cols, | ||
382 | omap_kp->keymap, input_dev); | ||
383 | if (ret < 0) | ||
384 | goto err3; | ||
385 | |||
386 | ret = input_register_device(omap_kp->input); | 386 | ret = input_register_device(omap_kp->input); |
387 | if (ret < 0) { | 387 | if (ret < 0) { |
388 | printk(KERN_ERR "Unable to register omap-keypad input device\n"); | 388 | printk(KERN_ERR "Unable to register omap-keypad input device\n"); |
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index e809ac095a38..aed5f6999ce2 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c | |||
@@ -68,19 +68,52 @@ | |||
68 | 68 | ||
69 | #define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF | 69 | #define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF |
70 | 70 | ||
71 | enum { | ||
72 | KBD_REVISION_OMAP4 = 0, | ||
73 | KBD_REVISION_OMAP5, | ||
74 | }; | ||
75 | |||
71 | struct omap4_keypad { | 76 | struct omap4_keypad { |
72 | struct input_dev *input; | 77 | struct input_dev *input; |
73 | 78 | ||
74 | void __iomem *base; | 79 | void __iomem *base; |
75 | int irq; | 80 | unsigned int irq; |
76 | 81 | ||
77 | unsigned int rows; | 82 | unsigned int rows; |
78 | unsigned int cols; | 83 | unsigned int cols; |
84 | u32 reg_offset; | ||
85 | u32 irqreg_offset; | ||
79 | unsigned int row_shift; | 86 | unsigned int row_shift; |
80 | unsigned char key_state[8]; | 87 | unsigned char key_state[8]; |
81 | unsigned short keymap[]; | 88 | unsigned short keymap[]; |
82 | }; | 89 | }; |
83 | 90 | ||
91 | static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset) | ||
92 | { | ||
93 | return __raw_readl(keypad_data->base + | ||
94 | keypad_data->reg_offset + offset); | ||
95 | } | ||
96 | |||
97 | static void kbd_writel(struct omap4_keypad *keypad_data, u32 offset, u32 value) | ||
98 | { | ||
99 | __raw_writel(value, | ||
100 | keypad_data->base + keypad_data->reg_offset + offset); | ||
101 | } | ||
102 | |||
103 | static int kbd_read_irqreg(struct omap4_keypad *keypad_data, u32 offset) | ||
104 | { | ||
105 | return __raw_readl(keypad_data->base + | ||
106 | keypad_data->irqreg_offset + offset); | ||
107 | } | ||
108 | |||
109 | static void kbd_write_irqreg(struct omap4_keypad *keypad_data, | ||
110 | u32 offset, u32 value) | ||
111 | { | ||
112 | __raw_writel(value, | ||
113 | keypad_data->base + keypad_data->irqreg_offset + offset); | ||
114 | } | ||
115 | |||
116 | |||
84 | /* Interrupt handler */ | 117 | /* Interrupt handler */ |
85 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | 118 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) |
86 | { | 119 | { |
@@ -91,12 +124,11 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | |||
91 | u32 *new_state = (u32 *) key_state; | 124 | u32 *new_state = (u32 *) key_state; |
92 | 125 | ||
93 | /* Disable interrupts */ | 126 | /* Disable interrupts */ |
94 | __raw_writel(OMAP4_VAL_IRQDISABLE, | 127 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, |
95 | keypad_data->base + OMAP4_KBD_IRQENABLE); | 128 | OMAP4_VAL_IRQDISABLE); |
96 | 129 | ||
97 | *new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0); | 130 | *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0); |
98 | *(new_state + 1) = __raw_readl(keypad_data->base | 131 | *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32); |
99 | + OMAP4_KBD_FULLCODE63_32); | ||
100 | 132 | ||
101 | for (row = 0; row < keypad_data->rows; row++) { | 133 | for (row = 0; row < keypad_data->rows; row++) { |
102 | changed = key_state[row] ^ keypad_data->key_state[row]; | 134 | changed = key_state[row] ^ keypad_data->key_state[row]; |
@@ -121,12 +153,13 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | |||
121 | sizeof(keypad_data->key_state)); | 153 | sizeof(keypad_data->key_state)); |
122 | 154 | ||
123 | /* clear pending interrupts */ | 155 | /* clear pending interrupts */ |
124 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), | 156 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, |
125 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | 157 | kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); |
126 | 158 | ||
127 | /* enable interrupts */ | 159 | /* enable interrupts */ |
128 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | 160 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, |
129 | keypad_data->base + OMAP4_KBD_IRQENABLE); | 161 | OMAP4_DEF_IRQENABLE_EVENTEN | |
162 | OMAP4_DEF_IRQENABLE_LONGKEY); | ||
130 | 163 | ||
131 | return IRQ_HANDLED; | 164 | return IRQ_HANDLED; |
132 | } | 165 | } |
@@ -139,16 +172,17 @@ static int omap4_keypad_open(struct input_dev *input) | |||
139 | 172 | ||
140 | disable_irq(keypad_data->irq); | 173 | disable_irq(keypad_data->irq); |
141 | 174 | ||
142 | __raw_writel(OMAP4_VAL_FUNCTIONALCFG, | 175 | kbd_writel(keypad_data, OMAP4_KBD_CTRL, |
143 | keypad_data->base + OMAP4_KBD_CTRL); | 176 | OMAP4_VAL_FUNCTIONALCFG); |
144 | __raw_writel(OMAP4_VAL_DEBOUNCINGTIME, | 177 | kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME, |
145 | keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME); | 178 | OMAP4_VAL_DEBOUNCINGTIME); |
146 | __raw_writel(OMAP4_VAL_IRQDISABLE, | 179 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, |
147 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | 180 | OMAP4_VAL_IRQDISABLE); |
148 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | 181 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, |
149 | keypad_data->base + OMAP4_KBD_IRQENABLE); | 182 | OMAP4_DEF_IRQENABLE_EVENTEN | |
150 | __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA, | 183 | OMAP4_DEF_IRQENABLE_LONGKEY); |
151 | keypad_data->base + OMAP4_KBD_WAKEUPENABLE); | 184 | kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE, |
185 | OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA); | ||
152 | 186 | ||
153 | enable_irq(keypad_data->irq); | 187 | enable_irq(keypad_data->irq); |
154 | 188 | ||
@@ -162,12 +196,12 @@ static void omap4_keypad_close(struct input_dev *input) | |||
162 | disable_irq(keypad_data->irq); | 196 | disable_irq(keypad_data->irq); |
163 | 197 | ||
164 | /* Disable interrupts */ | 198 | /* Disable interrupts */ |
165 | __raw_writel(OMAP4_VAL_IRQDISABLE, | 199 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, |
166 | keypad_data->base + OMAP4_KBD_IRQENABLE); | 200 | OMAP4_VAL_IRQDISABLE); |
167 | 201 | ||
168 | /* clear pending interrupts */ | 202 | /* clear pending interrupts */ |
169 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), | 203 | kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, |
170 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | 204 | kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); |
171 | 205 | ||
172 | enable_irq(keypad_data->irq); | 206 | enable_irq(keypad_data->irq); |
173 | 207 | ||
@@ -182,6 +216,7 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) | |||
182 | struct resource *res; | 216 | struct resource *res; |
183 | resource_size_t size; | 217 | resource_size_t size; |
184 | unsigned int row_shift, max_keys; | 218 | unsigned int row_shift, max_keys; |
219 | int rev; | ||
185 | int irq; | 220 | int irq; |
186 | int error; | 221 | int error; |
187 | 222 | ||
@@ -241,11 +276,40 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) | |||
241 | keypad_data->rows = pdata->rows; | 276 | keypad_data->rows = pdata->rows; |
242 | keypad_data->cols = pdata->cols; | 277 | keypad_data->cols = pdata->cols; |
243 | 278 | ||
279 | /* | ||
280 | * Enable clocks for the keypad module so that we can read | ||
281 | * revision register. | ||
282 | */ | ||
283 | pm_runtime_enable(&pdev->dev); | ||
284 | error = pm_runtime_get_sync(&pdev->dev); | ||
285 | if (error) { | ||
286 | dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); | ||
287 | goto err_unmap; | ||
288 | } | ||
289 | rev = __raw_readl(keypad_data->base + OMAP4_KBD_REVISION); | ||
290 | rev &= 0x03 << 30; | ||
291 | rev >>= 30; | ||
292 | switch (rev) { | ||
293 | case KBD_REVISION_OMAP4: | ||
294 | keypad_data->reg_offset = 0x00; | ||
295 | keypad_data->irqreg_offset = 0x00; | ||
296 | break; | ||
297 | case KBD_REVISION_OMAP5: | ||
298 | keypad_data->reg_offset = 0x10; | ||
299 | keypad_data->irqreg_offset = 0x0c; | ||
300 | break; | ||
301 | default: | ||
302 | dev_err(&pdev->dev, | ||
303 | "Keypad reports unsupported revision %d", rev); | ||
304 | error = -EINVAL; | ||
305 | goto err_pm_put_sync; | ||
306 | } | ||
307 | |||
244 | /* input device allocation */ | 308 | /* input device allocation */ |
245 | keypad_data->input = input_dev = input_allocate_device(); | 309 | keypad_data->input = input_dev = input_allocate_device(); |
246 | if (!input_dev) { | 310 | if (!input_dev) { |
247 | error = -ENOMEM; | 311 | error = -ENOMEM; |
248 | goto err_unmap; | 312 | goto err_pm_put_sync; |
249 | } | 313 | } |
250 | 314 | ||
251 | input_dev->name = pdev->name; | 315 | input_dev->name = pdev->name; |
@@ -258,20 +322,19 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) | |||
258 | input_dev->open = omap4_keypad_open; | 322 | input_dev->open = omap4_keypad_open; |
259 | input_dev->close = omap4_keypad_close; | 323 | input_dev->close = omap4_keypad_close; |
260 | 324 | ||
261 | input_dev->keycode = keypad_data->keymap; | 325 | error = matrix_keypad_build_keymap(pdata->keymap_data, NULL, |
262 | input_dev->keycodesize = sizeof(keypad_data->keymap[0]); | 326 | pdata->rows, pdata->cols, |
263 | input_dev->keycodemax = max_keys; | 327 | keypad_data->keymap, input_dev); |
328 | if (error) { | ||
329 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
330 | goto err_free_input; | ||
331 | } | ||
264 | 332 | ||
265 | __set_bit(EV_KEY, input_dev->evbit); | ||
266 | __set_bit(EV_REP, input_dev->evbit); | 333 | __set_bit(EV_REP, input_dev->evbit); |
267 | |||
268 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 334 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
269 | 335 | ||
270 | input_set_drvdata(input_dev, keypad_data); | 336 | input_set_drvdata(input_dev, keypad_data); |
271 | 337 | ||
272 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, | ||
273 | input_dev->keycode, input_dev->keybit); | ||
274 | |||
275 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, | 338 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, |
276 | IRQF_TRIGGER_RISING, | 339 | IRQF_TRIGGER_RISING, |
277 | "omap4-keypad", keypad_data); | 340 | "omap4-keypad", keypad_data); |
@@ -280,7 +343,7 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) | |||
280 | goto err_free_input; | 343 | goto err_free_input; |
281 | } | 344 | } |
282 | 345 | ||
283 | pm_runtime_enable(&pdev->dev); | 346 | pm_runtime_put_sync(&pdev->dev); |
284 | 347 | ||
285 | error = input_register_device(keypad_data->input); | 348 | error = input_register_device(keypad_data->input); |
286 | if (error < 0) { | 349 | if (error < 0) { |
@@ -296,6 +359,8 @@ err_pm_disable: | |||
296 | free_irq(keypad_data->irq, keypad_data); | 359 | free_irq(keypad_data->irq, keypad_data); |
297 | err_free_input: | 360 | err_free_input: |
298 | input_free_device(input_dev); | 361 | input_free_device(input_dev); |
362 | err_pm_put_sync: | ||
363 | pm_runtime_put_sync(&pdev->dev); | ||
299 | err_unmap: | 364 | err_unmap: |
300 | iounmap(keypad_data->base); | 365 | iounmap(keypad_data->base); |
301 | err_release_mem: | 366 | err_release_mem: |
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 01a1c9f8a383..52c34657d301 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c | |||
@@ -626,21 +626,21 @@ static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) | |||
626 | kp->input->id.product = 0x0001; | 626 | kp->input->id.product = 0x0001; |
627 | kp->input->id.vendor = 0x0001; | 627 | kp->input->id.vendor = 0x0001; |
628 | 628 | ||
629 | kp->input->evbit[0] = BIT_MASK(EV_KEY); | ||
630 | |||
631 | if (pdata->rep) | ||
632 | __set_bit(EV_REP, kp->input->evbit); | ||
633 | |||
634 | kp->input->keycode = kp->keycodes; | ||
635 | kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; | ||
636 | kp->input->keycodesize = sizeof(kp->keycodes); | ||
637 | kp->input->open = pmic8xxx_kp_open; | 629 | kp->input->open = pmic8xxx_kp_open; |
638 | kp->input->close = pmic8xxx_kp_close; | 630 | kp->input->close = pmic8xxx_kp_close; |
639 | 631 | ||
640 | matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, | 632 | rc = matrix_keypad_build_keymap(keymap_data, NULL, |
641 | kp->input->keycode, kp->input->keybit); | 633 | PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, |
634 | kp->keycodes, kp->input); | ||
635 | if (rc) { | ||
636 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
637 | goto err_get_irq; | ||
638 | } | ||
642 | 639 | ||
640 | if (pdata->rep) | ||
641 | __set_bit(EV_REP, kp->input->evbit); | ||
643 | input_set_capability(kp->input, EV_MSC, MSC_SCAN); | 642 | input_set_capability(kp->input, EV_MSC, MSC_SCAN); |
643 | |||
644 | input_set_drvdata(kp->input, kp); | 644 | input_set_drvdata(kp->input, kp); |
645 | 645 | ||
646 | /* initialize keypad state */ | 646 | /* initialize keypad state */ |
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 2391ae884fee..a061ba603a29 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c | |||
@@ -454,23 +454,23 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) | |||
454 | input_dev->name = pdev->name; | 454 | input_dev->name = pdev->name; |
455 | input_dev->id.bustype = BUS_HOST; | 455 | input_dev->id.bustype = BUS_HOST; |
456 | input_dev->dev.parent = &pdev->dev; | 456 | input_dev->dev.parent = &pdev->dev; |
457 | input_set_drvdata(input_dev, keypad); | ||
458 | 457 | ||
459 | input_dev->open = samsung_keypad_open; | 458 | input_dev->open = samsung_keypad_open; |
460 | input_dev->close = samsung_keypad_close; | 459 | input_dev->close = samsung_keypad_close; |
461 | 460 | ||
462 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | 461 | error = matrix_keypad_build_keymap(keymap_data, NULL, |
463 | if (!pdata->no_autorepeat) | 462 | pdata->rows, pdata->cols, |
464 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | 463 | keypad->keycodes, input_dev); |
464 | if (error) { | ||
465 | dev_err(&pdev->dev, "failed to build keymap\n"); | ||
466 | goto err_put_clk; | ||
467 | } | ||
465 | 468 | ||
466 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 469 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
470 | if (!pdata->no_autorepeat) | ||
471 | __set_bit(EV_REP, input_dev->evbit); | ||
467 | 472 | ||
468 | input_dev->keycode = keypad->keycodes; | 473 | input_set_drvdata(input_dev, keypad); |
469 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
470 | input_dev->keycodemax = pdata->rows << row_shift; | ||
471 | |||
472 | matrix_keypad_build_keymap(keymap_data, row_shift, | ||
473 | input_dev->keycode, input_dev->keybit); | ||
474 | 474 | ||
475 | keypad->irq = platform_get_irq(pdev, 0); | 475 | keypad->irq = platform_get_irq(pdev, 0); |
476 | if (keypad->irq < 0) { | 476 | if (keypad->irq < 0) { |
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 3b6b528f02fd..6f287f7e1538 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/of.h> | ||
22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
23 | #include <linux/pm_wakeup.h> | 24 | #include <linux/pm_wakeup.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
@@ -49,7 +50,9 @@ | |||
49 | #define KEY_VALUE 0x00FFFFFF | 50 | #define KEY_VALUE 0x00FFFFFF |
50 | #define ROW_MASK 0xF0 | 51 | #define ROW_MASK 0xF0 |
51 | #define COLUMN_MASK 0x0F | 52 | #define COLUMN_MASK 0x0F |
52 | #define ROW_SHIFT 4 | 53 | #define NUM_ROWS 16 |
54 | #define NUM_COLS 16 | ||
55 | |||
53 | #define KEY_MATRIX_SHIFT 6 | 56 | #define KEY_MATRIX_SHIFT 6 |
54 | 57 | ||
55 | struct spear_kbd { | 58 | struct spear_kbd { |
@@ -60,7 +63,8 @@ struct spear_kbd { | |||
60 | unsigned int irq; | 63 | unsigned int irq; |
61 | unsigned int mode; | 64 | unsigned int mode; |
62 | unsigned short last_key; | 65 | unsigned short last_key; |
63 | unsigned short keycodes[256]; | 66 | unsigned short keycodes[NUM_ROWS * NUM_COLS]; |
67 | bool rep; | ||
64 | }; | 68 | }; |
65 | 69 | ||
66 | static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) | 70 | static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) |
@@ -136,27 +140,49 @@ static void spear_kbd_close(struct input_dev *dev) | |||
136 | kbd->last_key = KEY_RESERVED; | 140 | kbd->last_key = KEY_RESERVED; |
137 | } | 141 | } |
138 | 142 | ||
139 | static int __devinit spear_kbd_probe(struct platform_device *pdev) | 143 | #ifdef CONFIG_OF |
144 | static int __devinit spear_kbd_parse_dt(struct platform_device *pdev, | ||
145 | struct spear_kbd *kbd) | ||
140 | { | 146 | { |
141 | const struct kbd_platform_data *pdata = pdev->dev.platform_data; | 147 | struct device_node *np = pdev->dev.of_node; |
142 | const struct matrix_keymap_data *keymap; | ||
143 | struct spear_kbd *kbd; | ||
144 | struct input_dev *input_dev; | ||
145 | struct resource *res; | ||
146 | int irq; | ||
147 | int error; | 148 | int error; |
149 | u32 val; | ||
148 | 150 | ||
149 | if (!pdata) { | 151 | if (!np) { |
150 | dev_err(&pdev->dev, "Invalid platform data\n"); | 152 | dev_err(&pdev->dev, "Missing DT data\n"); |
151 | return -EINVAL; | 153 | return -EINVAL; |
152 | } | 154 | } |
153 | 155 | ||
154 | keymap = pdata->keymap; | 156 | if (of_property_read_bool(np, "autorepeat")) |
155 | if (!keymap) { | 157 | kbd->rep = true; |
156 | dev_err(&pdev->dev, "no keymap defined\n"); | 158 | |
157 | return -EINVAL; | 159 | error = of_property_read_u32(np, "st,mode", &val); |
160 | if (error) { | ||
161 | dev_err(&pdev->dev, "DT: Invalid or missing mode\n"); | ||
162 | return error; | ||
158 | } | 163 | } |
159 | 164 | ||
165 | kbd->mode = val; | ||
166 | return 0; | ||
167 | } | ||
168 | #else | ||
169 | static inline int spear_kbd_parse_dt(struct platform_device *pdev, | ||
170 | struct spear_kbd *kbd) | ||
171 | { | ||
172 | return -ENOSYS; | ||
173 | } | ||
174 | #endif | ||
175 | |||
176 | static int __devinit spear_kbd_probe(struct platform_device *pdev) | ||
177 | { | ||
178 | struct kbd_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
179 | const struct matrix_keymap_data *keymap = pdata ? pdata->keymap : NULL; | ||
180 | struct spear_kbd *kbd; | ||
181 | struct input_dev *input_dev; | ||
182 | struct resource *res; | ||
183 | int irq; | ||
184 | int error; | ||
185 | |||
160 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 186 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
161 | if (!res) { | 187 | if (!res) { |
162 | dev_err(&pdev->dev, "no keyboard resource defined\n"); | 188 | dev_err(&pdev->dev, "no keyboard resource defined\n"); |
@@ -179,7 +205,15 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev) | |||
179 | 205 | ||
180 | kbd->input = input_dev; | 206 | kbd->input = input_dev; |
181 | kbd->irq = irq; | 207 | kbd->irq = irq; |
182 | kbd->mode = pdata->mode; | 208 | |
209 | if (!pdata) { | ||
210 | error = spear_kbd_parse_dt(pdev, kbd); | ||
211 | if (error) | ||
212 | goto err_free_mem; | ||
213 | } else { | ||
214 | kbd->mode = pdata->mode; | ||
215 | kbd->rep = pdata->rep; | ||
216 | } | ||
183 | 217 | ||
184 | kbd->res = request_mem_region(res->start, resource_size(res), | 218 | kbd->res = request_mem_region(res->start, resource_size(res), |
185 | pdev->name); | 219 | pdev->name); |
@@ -212,18 +246,17 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev) | |||
212 | input_dev->open = spear_kbd_open; | 246 | input_dev->open = spear_kbd_open; |
213 | input_dev->close = spear_kbd_close; | 247 | input_dev->close = spear_kbd_close; |
214 | 248 | ||
215 | __set_bit(EV_KEY, input_dev->evbit); | 249 | error = matrix_keypad_build_keymap(keymap, NULL, NUM_ROWS, NUM_COLS, |
216 | if (pdata->rep) | 250 | kbd->keycodes, input_dev); |
251 | if (error) { | ||
252 | dev_err(&pdev->dev, "Failed to build keymap\n"); | ||
253 | goto err_put_clk; | ||
254 | } | ||
255 | |||
256 | if (kbd->rep) | ||
217 | __set_bit(EV_REP, input_dev->evbit); | 257 | __set_bit(EV_REP, input_dev->evbit); |
218 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 258 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
219 | 259 | ||
220 | input_dev->keycode = kbd->keycodes; | ||
221 | input_dev->keycodesize = sizeof(kbd->keycodes[0]); | ||
222 | input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes); | ||
223 | |||
224 | matrix_keypad_build_keymap(keymap, ROW_SHIFT, | ||
225 | input_dev->keycode, input_dev->keybit); | ||
226 | |||
227 | input_set_drvdata(input_dev, kbd); | 260 | input_set_drvdata(input_dev, kbd); |
228 | 261 | ||
229 | error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd); | 262 | error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd); |
@@ -317,6 +350,14 @@ static int spear_kbd_resume(struct device *dev) | |||
317 | 350 | ||
318 | static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume); | 351 | static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume); |
319 | 352 | ||
353 | #ifdef CONFIG_OF | ||
354 | static const struct of_device_id spear_kbd_id_table[] = { | ||
355 | { .compatible = "st,spear300-kbd" }, | ||
356 | {} | ||
357 | }; | ||
358 | MODULE_DEVICE_TABLE(of, spear_kbd_id_table); | ||
359 | #endif | ||
360 | |||
320 | static struct platform_driver spear_kbd_driver = { | 361 | static struct platform_driver spear_kbd_driver = { |
321 | .probe = spear_kbd_probe, | 362 | .probe = spear_kbd_probe, |
322 | .remove = __devexit_p(spear_kbd_remove), | 363 | .remove = __devexit_p(spear_kbd_remove), |
@@ -324,6 +365,7 @@ static struct platform_driver spear_kbd_driver = { | |||
324 | .name = "keyboard", | 365 | .name = "keyboard", |
325 | .owner = THIS_MODULE, | 366 | .owner = THIS_MODULE, |
326 | .pm = &spear_kbd_pm_ops, | 367 | .pm = &spear_kbd_pm_ops, |
368 | .of_match_table = of_match_ptr(spear_kbd_id_table), | ||
327 | }, | 369 | }, |
328 | }; | 370 | }; |
329 | module_platform_driver(spear_kbd_driver); | 371 | module_platform_driver(spear_kbd_driver); |
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index 9397cf9c625c..470a8778dec1 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c | |||
@@ -289,19 +289,17 @@ static int __devinit stmpe_keypad_probe(struct platform_device *pdev) | |||
289 | input->id.bustype = BUS_I2C; | 289 | input->id.bustype = BUS_I2C; |
290 | input->dev.parent = &pdev->dev; | 290 | input->dev.parent = &pdev->dev; |
291 | 291 | ||
292 | input_set_capability(input, EV_MSC, MSC_SCAN); | 292 | ret = matrix_keypad_build_keymap(plat->keymap_data, NULL, |
293 | STMPE_KEYPAD_MAX_ROWS, | ||
294 | STMPE_KEYPAD_MAX_COLS, | ||
295 | keypad->keymap, input); | ||
296 | if (ret) | ||
297 | goto out_freeinput; | ||
293 | 298 | ||
294 | __set_bit(EV_KEY, input->evbit); | 299 | input_set_capability(input, EV_MSC, MSC_SCAN); |
295 | if (!plat->no_autorepeat) | 300 | if (!plat->no_autorepeat) |
296 | __set_bit(EV_REP, input->evbit); | 301 | __set_bit(EV_REP, input->evbit); |
297 | 302 | ||
298 | input->keycode = keypad->keymap; | ||
299 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
300 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
301 | |||
302 | matrix_keypad_build_keymap(plat->keymap_data, STMPE_KEYPAD_ROW_SHIFT, | ||
303 | input->keycode, input->keybit); | ||
304 | |||
305 | for (i = 0; i < plat->keymap_data->keymap_size; i++) { | 303 | for (i = 0; i < plat->keymap_data->keymap_size; i++) { |
306 | unsigned int key = plat->keymap_data->keymap[i]; | 304 | unsigned int key = plat->keymap_data->keymap[i]; |
307 | 305 | ||
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index 7437219370b1..cc612c5d5427 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c | |||
@@ -170,15 +170,4 @@ static struct serio_driver skbd_drv = { | |||
170 | .disconnect = skbd_disconnect, | 170 | .disconnect = skbd_disconnect, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static int __init skbd_init(void) | 173 | module_serio_driver(skbd_drv); |
174 | { | ||
175 | return serio_register_driver(&skbd_drv); | ||
176 | } | ||
177 | |||
178 | static void __exit skbd_exit(void) | ||
179 | { | ||
180 | serio_unregister_driver(&skbd_drv); | ||
181 | } | ||
182 | |||
183 | module_init(skbd_init); | ||
184 | module_exit(skbd_exit); | ||
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index a99a04b03ee4..5f836b1638c1 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c | |||
@@ -369,19 +369,4 @@ static struct serio_driver sunkbd_drv = { | |||
369 | .disconnect = sunkbd_disconnect, | 369 | .disconnect = sunkbd_disconnect, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | /* | 372 | module_serio_driver(sunkbd_drv); |
373 | * The functions for insering/removing us as a module. | ||
374 | */ | ||
375 | |||
376 | static int __init sunkbd_init(void) | ||
377 | { | ||
378 | return serio_register_driver(&sunkbd_drv); | ||
379 | } | ||
380 | |||
381 | static void __exit sunkbd_exit(void) | ||
382 | { | ||
383 | serio_unregister_driver(&sunkbd_drv); | ||
384 | } | ||
385 | |||
386 | module_init(sunkbd_init); | ||
387 | module_exit(sunkbd_exit); | ||
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index 2dee3e4e7c6f..7d498e698508 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c | |||
@@ -78,7 +78,7 @@ | |||
78 | * @input: pointer to input device object | 78 | * @input: pointer to input device object |
79 | * @board: keypad platform device | 79 | * @board: keypad platform device |
80 | * @krow: number of rows | 80 | * @krow: number of rows |
81 | * @kcol: number of coloumns | 81 | * @kcol: number of columns |
82 | * @keymap: matrix scan code table for keycodes | 82 | * @keymap: matrix scan code table for keycodes |
83 | * @keypad_stopped: holds keypad status | 83 | * @keypad_stopped: holds keypad status |
84 | */ | 84 | */ |
@@ -96,21 +96,15 @@ static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) | |||
96 | { | 96 | { |
97 | int ret; | 97 | int ret; |
98 | struct tc3589x *tc3589x = keypad->tc3589x; | 98 | struct tc3589x *tc3589x = keypad->tc3589x; |
99 | u8 settle_time = keypad->board->settle_time; | 99 | const struct tc3589x_keypad_platform_data *board = keypad->board; |
100 | u8 dbounce_period = keypad->board->debounce_period; | 100 | |
101 | u8 rows = keypad->board->krow & 0xf; /* mask out the nibble */ | 101 | /* validate platform configuration */ |
102 | u8 column = keypad->board->kcol & 0xf; /* mask out the nibble */ | 102 | if (board->kcol > TC3589x_MAX_KPCOL || board->krow > TC3589x_MAX_KPROW) |
103 | |||
104 | /* validate platform configurations */ | ||
105 | if (keypad->board->kcol > TC3589x_MAX_KPCOL || | ||
106 | keypad->board->krow > TC3589x_MAX_KPROW || | ||
107 | keypad->board->debounce_period > TC3589x_MAX_DEBOUNCE_SETTLE || | ||
108 | keypad->board->settle_time > TC3589x_MAX_DEBOUNCE_SETTLE) | ||
109 | return -EINVAL; | 103 | return -EINVAL; |
110 | 104 | ||
111 | /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */ | 105 | /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */ |
112 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE, | 106 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE, |
113 | (rows << KP_ROW_SHIFT) | column); | 107 | (board->krow << KP_ROW_SHIFT) | board->kcol); |
114 | if (ret < 0) | 108 | if (ret < 0) |
115 | return ret; | 109 | return ret; |
116 | 110 | ||
@@ -124,12 +118,14 @@ static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) | |||
124 | return ret; | 118 | return ret; |
125 | 119 | ||
126 | /* Configure settle time */ | 120 | /* Configure settle time */ |
127 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, settle_time); | 121 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, |
122 | board->settle_time); | ||
128 | if (ret < 0) | 123 | if (ret < 0) |
129 | return ret; | 124 | return ret; |
130 | 125 | ||
131 | /* Configure debounce time */ | 126 | /* Configure debounce time */ |
132 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, dbounce_period); | 127 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, |
128 | board->debounce_period); | ||
133 | if (ret < 0) | 129 | if (ret < 0) |
134 | return ret; | 130 | return ret; |
135 | 131 | ||
@@ -337,23 +333,22 @@ static int __devinit tc3589x_keypad_probe(struct platform_device *pdev) | |||
337 | input->name = pdev->name; | 333 | input->name = pdev->name; |
338 | input->dev.parent = &pdev->dev; | 334 | input->dev.parent = &pdev->dev; |
339 | 335 | ||
340 | input->keycode = keypad->keymap; | ||
341 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
342 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
343 | |||
344 | input->open = tc3589x_keypad_open; | 336 | input->open = tc3589x_keypad_open; |
345 | input->close = tc3589x_keypad_close; | 337 | input->close = tc3589x_keypad_close; |
346 | 338 | ||
347 | input_set_drvdata(input, keypad); | 339 | error = matrix_keypad_build_keymap(plat->keymap_data, NULL, |
340 | TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL, | ||
341 | keypad->keymap, input); | ||
342 | if (error) { | ||
343 | dev_err(&pdev->dev, "Failed to build keymap\n"); | ||
344 | goto err_free_mem; | ||
345 | } | ||
348 | 346 | ||
349 | input_set_capability(input, EV_MSC, MSC_SCAN); | 347 | input_set_capability(input, EV_MSC, MSC_SCAN); |
350 | |||
351 | __set_bit(EV_KEY, input->evbit); | ||
352 | if (!plat->no_autorepeat) | 348 | if (!plat->no_autorepeat) |
353 | __set_bit(EV_REP, input->evbit); | 349 | __set_bit(EV_REP, input->evbit); |
354 | 350 | ||
355 | matrix_keypad_build_keymap(plat->keymap_data, 0x3, | 351 | input_set_drvdata(input, keypad); |
356 | input->keycode, input->keybit); | ||
357 | 352 | ||
358 | error = request_threaded_irq(irq, NULL, | 353 | error = request_threaded_irq(irq, NULL, |
359 | tc3589x_keypad_irq, plat->irqtype, | 354 | tc3589x_keypad_irq, plat->irqtype, |
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 958ec107bfbc..5f87b28b3192 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c | |||
@@ -342,21 +342,20 @@ static int __devinit tca8418_keypad_probe(struct i2c_client *client, | |||
342 | input->id.product = 0x001; | 342 | input->id.product = 0x001; |
343 | input->id.version = 0x0001; | 343 | input->id.version = 0x0001; |
344 | 344 | ||
345 | input->keycode = keypad_data->keymap; | 345 | error = matrix_keypad_build_keymap(pdata->keymap_data, NULL, |
346 | input->keycodesize = sizeof(keypad_data->keymap[0]); | 346 | pdata->rows, pdata->cols, |
347 | input->keycodemax = max_keys; | 347 | keypad_data->keymap, input); |
348 | if (error) { | ||
349 | dev_dbg(&client->dev, "Failed to build keymap\n"); | ||
350 | goto fail2; | ||
351 | } | ||
348 | 352 | ||
349 | __set_bit(EV_KEY, input->evbit); | ||
350 | if (pdata->rep) | 353 | if (pdata->rep) |
351 | __set_bit(EV_REP, input->evbit); | 354 | __set_bit(EV_REP, input->evbit); |
352 | |||
353 | input_set_capability(input, EV_MSC, MSC_SCAN); | 355 | input_set_capability(input, EV_MSC, MSC_SCAN); |
354 | 356 | ||
355 | input_set_drvdata(input, keypad_data); | 357 | input_set_drvdata(input, keypad_data); |
356 | 358 | ||
357 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, | ||
358 | input->keycode, input->keybit); | ||
359 | |||
360 | if (pdata->irq_is_gpio) | 359 | if (pdata->irq_is_gpio) |
361 | client->irq = gpio_to_irq(client->irq); | 360 | client->irq = gpio_to_irq(client->irq); |
362 | 361 | ||
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index fe4ac95ca6c8..4ffe64d53107 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -619,8 +619,8 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | |||
619 | } | 619 | } |
620 | 620 | ||
621 | #ifdef CONFIG_OF | 621 | #ifdef CONFIG_OF |
622 | static struct tegra_kbc_platform_data * __devinit | 622 | static struct tegra_kbc_platform_data * __devinit tegra_kbc_dt_parse_pdata( |
623 | tegra_kbc_dt_parse_pdata(struct platform_device *pdev) | 623 | struct platform_device *pdev) |
624 | { | 624 | { |
625 | struct tegra_kbc_platform_data *pdata; | 625 | struct tegra_kbc_platform_data *pdata; |
626 | struct device_node *np = pdev->dev.of_node; | 626 | struct device_node *np = pdev->dev.of_node; |
@@ -660,10 +660,6 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev) | |||
660 | pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; | 660 | pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; |
661 | } | 661 | } |
662 | 662 | ||
663 | pdata->keymap_data = matrix_keyboard_of_fill_keymap(np, "linux,keymap"); | ||
664 | |||
665 | /* FIXME: Add handling of linux,fn-keymap here */ | ||
666 | |||
667 | return pdata; | 663 | return pdata; |
668 | } | 664 | } |
669 | #else | 665 | #else |
@@ -674,10 +670,36 @@ static inline struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata( | |||
674 | } | 670 | } |
675 | #endif | 671 | #endif |
676 | 672 | ||
673 | static int __devinit tegra_kbd_setup_keymap(struct tegra_kbc *kbc) | ||
674 | { | ||
675 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | ||
676 | const struct matrix_keymap_data *keymap_data = pdata->keymap_data; | ||
677 | unsigned int keymap_rows = KBC_MAX_KEY; | ||
678 | int retval; | ||
679 | |||
680 | if (keymap_data && pdata->use_fn_map) | ||
681 | keymap_rows *= 2; | ||
682 | |||
683 | retval = matrix_keypad_build_keymap(keymap_data, NULL, | ||
684 | keymap_rows, KBC_MAX_COL, | ||
685 | kbc->keycode, kbc->idev); | ||
686 | if (retval == -ENOSYS || retval == -ENOENT) { | ||
687 | /* | ||
688 | * If there is no OF support in kernel or keymap | ||
689 | * property is missing, use default keymap. | ||
690 | */ | ||
691 | retval = matrix_keypad_build_keymap( | ||
692 | &tegra_kbc_default_keymap_data, NULL, | ||
693 | keymap_rows, KBC_MAX_COL, | ||
694 | kbc->keycode, kbc->idev); | ||
695 | } | ||
696 | |||
697 | return retval; | ||
698 | } | ||
699 | |||
677 | static int __devinit tegra_kbc_probe(struct platform_device *pdev) | 700 | static int __devinit tegra_kbc_probe(struct platform_device *pdev) |
678 | { | 701 | { |
679 | const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data; | 702 | const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data; |
680 | const struct matrix_keymap_data *keymap_data; | ||
681 | struct tegra_kbc *kbc; | 703 | struct tegra_kbc *kbc; |
682 | struct input_dev *input_dev; | 704 | struct input_dev *input_dev; |
683 | struct resource *res; | 705 | struct resource *res; |
@@ -757,29 +779,26 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) | |||
757 | kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt; | 779 | kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt; |
758 | kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); | 780 | kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); |
759 | 781 | ||
782 | kbc->wakeup_key = pdata->wakeup_key; | ||
783 | kbc->use_fn_map = pdata->use_fn_map; | ||
784 | kbc->use_ghost_filter = pdata->use_ghost_filter; | ||
785 | |||
760 | input_dev->name = pdev->name; | 786 | input_dev->name = pdev->name; |
761 | input_dev->id.bustype = BUS_HOST; | 787 | input_dev->id.bustype = BUS_HOST; |
762 | input_dev->dev.parent = &pdev->dev; | 788 | input_dev->dev.parent = &pdev->dev; |
763 | input_dev->open = tegra_kbc_open; | 789 | input_dev->open = tegra_kbc_open; |
764 | input_dev->close = tegra_kbc_close; | 790 | input_dev->close = tegra_kbc_close; |
765 | 791 | ||
766 | input_set_drvdata(input_dev, kbc); | 792 | err = tegra_kbd_setup_keymap(kbc); |
793 | if (err) { | ||
794 | dev_err(&pdev->dev, "failed to setup keymap\n"); | ||
795 | goto err_put_clk; | ||
796 | } | ||
767 | 797 | ||
768 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 798 | __set_bit(EV_REP, input_dev->evbit); |
769 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 799 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
770 | 800 | ||
771 | input_dev->keycode = kbc->keycode; | 801 | input_set_drvdata(input_dev, kbc); |
772 | input_dev->keycodesize = sizeof(kbc->keycode[0]); | ||
773 | input_dev->keycodemax = KBC_MAX_KEY; | ||
774 | if (pdata->use_fn_map) | ||
775 | input_dev->keycodemax *= 2; | ||
776 | |||
777 | kbc->use_fn_map = pdata->use_fn_map; | ||
778 | kbc->use_ghost_filter = pdata->use_ghost_filter; | ||
779 | keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data; | ||
780 | matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT, | ||
781 | input_dev->keycode, input_dev->keybit); | ||
782 | kbc->wakeup_key = pdata->wakeup_key; | ||
783 | 802 | ||
784 | err = request_irq(kbc->irq, tegra_kbc_isr, | 803 | err = request_irq(kbc->irq, tegra_kbc_isr, |
785 | IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH, pdev->name, kbc); | 804 | IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH, pdev->name, kbc); |
@@ -799,9 +818,6 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) | |||
799 | platform_set_drvdata(pdev, kbc); | 818 | platform_set_drvdata(pdev, kbc); |
800 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 819 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
801 | 820 | ||
802 | if (!pdev->dev.platform_data) | ||
803 | matrix_keyboard_of_free_keymap(pdata->keymap_data); | ||
804 | |||
805 | return 0; | 821 | return 0; |
806 | 822 | ||
807 | err_free_irq: | 823 | err_free_irq: |
@@ -816,10 +832,8 @@ err_free_mem: | |||
816 | input_free_device(input_dev); | 832 | input_free_device(input_dev); |
817 | kfree(kbc); | 833 | kfree(kbc); |
818 | err_free_pdata: | 834 | err_free_pdata: |
819 | if (!pdev->dev.platform_data) { | 835 | if (!pdev->dev.platform_data) |
820 | matrix_keyboard_of_free_keymap(pdata->keymap_data); | ||
821 | kfree(pdata); | 836 | kfree(pdata); |
822 | } | ||
823 | 837 | ||
824 | return err; | 838 | return err; |
825 | } | 839 | } |
diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c index fb39c94b6fdd..a4a445fb7020 100644 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ b/drivers/input/keyboard/tnetv107x-keypad.c | |||
@@ -247,15 +247,11 @@ static int __devinit keypad_probe(struct platform_device *pdev) | |||
247 | error = -ENOMEM; | 247 | error = -ENOMEM; |
248 | goto error_input; | 248 | goto error_input; |
249 | } | 249 | } |
250 | input_set_drvdata(kp->input_dev, kp); | ||
251 | 250 | ||
252 | kp->input_dev->name = pdev->name; | 251 | kp->input_dev->name = pdev->name; |
253 | kp->input_dev->dev.parent = &pdev->dev; | 252 | kp->input_dev->dev.parent = &pdev->dev; |
254 | kp->input_dev->open = keypad_start; | 253 | kp->input_dev->open = keypad_start; |
255 | kp->input_dev->close = keypad_stop; | 254 | kp->input_dev->close = keypad_stop; |
256 | kp->input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
257 | if (!pdata->no_autorepeat) | ||
258 | kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
259 | 255 | ||
260 | clk_enable(kp->clk); | 256 | clk_enable(kp->clk); |
261 | rev = keypad_read(kp, rev); | 257 | rev = keypad_read(kp, rev); |
@@ -264,15 +260,20 @@ static int __devinit keypad_probe(struct platform_device *pdev) | |||
264 | kp->input_dev->id.version = ((rev >> 16) & 0xfff); | 260 | kp->input_dev->id.version = ((rev >> 16) & 0xfff); |
265 | clk_disable(kp->clk); | 261 | clk_disable(kp->clk); |
266 | 262 | ||
267 | kp->input_dev->keycode = kp->keycodes; | 263 | error = matrix_keypad_build_keymap(keymap_data, NULL, |
268 | kp->input_dev->keycodesize = sizeof(kp->keycodes[0]); | 264 | kp->rows, kp->cols, |
269 | kp->input_dev->keycodemax = kp->rows << kp->row_shift; | 265 | kp->keycodes, kp->input_dev); |
270 | 266 | if (error) { | |
271 | matrix_keypad_build_keymap(keymap_data, kp->row_shift, kp->keycodes, | 267 | dev_err(dev, "Failed to build keymap\n"); |
272 | kp->input_dev->keybit); | 268 | goto error_reg; |
269 | } | ||
273 | 270 | ||
271 | if (!pdata->no_autorepeat) | ||
272 | kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
274 | input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); | 273 | input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); |
275 | 274 | ||
275 | input_set_drvdata(kp->input_dev, kp); | ||
276 | |||
276 | error = input_register_device(kp->input_dev); | 277 | error = input_register_device(kp->input_dev); |
277 | if (error < 0) { | 278 | if (error < 0) { |
278 | dev_err(dev, "Could not register input device\n"); | 279 | dev_err(dev, "Could not register input device\n"); |
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 67bec14e8b96..a2c6f79aa101 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -361,14 +361,6 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) | |||
361 | kp->irq = platform_get_irq(pdev, 0); | 361 | kp->irq = platform_get_irq(pdev, 0); |
362 | 362 | ||
363 | /* setup input device */ | 363 | /* setup input device */ |
364 | __set_bit(EV_KEY, input->evbit); | ||
365 | |||
366 | /* Enable auto repeat feature of Linux input subsystem */ | ||
367 | if (pdata->rep) | ||
368 | __set_bit(EV_REP, input->evbit); | ||
369 | |||
370 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
371 | |||
372 | input->name = "TWL4030 Keypad"; | 364 | input->name = "TWL4030 Keypad"; |
373 | input->phys = "twl4030_keypad/input0"; | 365 | input->phys = "twl4030_keypad/input0"; |
374 | input->dev.parent = &pdev->dev; | 366 | input->dev.parent = &pdev->dev; |
@@ -378,12 +370,19 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) | |||
378 | input->id.product = 0x0001; | 370 | input->id.product = 0x0001; |
379 | input->id.version = 0x0003; | 371 | input->id.version = 0x0003; |
380 | 372 | ||
381 | input->keycode = kp->keymap; | 373 | error = matrix_keypad_build_keymap(keymap_data, NULL, |
382 | input->keycodesize = sizeof(kp->keymap[0]); | 374 | TWL4030_MAX_ROWS, |
383 | input->keycodemax = ARRAY_SIZE(kp->keymap); | 375 | 1 << TWL4030_ROW_SHIFT, |
376 | kp->keymap, input); | ||
377 | if (error) { | ||
378 | dev_err(kp->dbg_dev, "Failed to build keymap\n"); | ||
379 | goto err1; | ||
380 | } | ||
384 | 381 | ||
385 | matrix_keypad_build_keymap(keymap_data, TWL4030_ROW_SHIFT, | 382 | input_set_capability(input, EV_MSC, MSC_SCAN); |
386 | input->keycode, input->keybit); | 383 | /* Enable auto repeat feature of Linux input subsystem */ |
384 | if (pdata->rep) | ||
385 | __set_bit(EV_REP, input->evbit); | ||
387 | 386 | ||
388 | error = input_register_device(input); | 387 | error = input_register_device(input); |
389 | if (error) { | 388 | if (error) { |
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 99bbb7e775ae..085ede4d972d 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c | |||
@@ -42,7 +42,8 @@ | |||
42 | #define KGET_RAW(n) (((n) & KEY0R) >> 3) | 42 | #define KGET_RAW(n) (((n) & KEY0R) >> 3) |
43 | #define KGET_COLUMN(n) ((n) & KEY0C) | 43 | #define KGET_COLUMN(n) ((n) & KEY0C) |
44 | 44 | ||
45 | #define W90P910_MAX_KEY_NUM (8 * 8) | 45 | #define W90P910_NUM_ROWS 8 |
46 | #define W90P910_NUM_COLS 8 | ||
46 | #define W90P910_ROW_SHIFT 3 | 47 | #define W90P910_ROW_SHIFT 3 |
47 | 48 | ||
48 | struct w90p910_keypad { | 49 | struct w90p910_keypad { |
@@ -51,7 +52,7 @@ struct w90p910_keypad { | |||
51 | struct input_dev *input_dev; | 52 | struct input_dev *input_dev; |
52 | void __iomem *mmio_base; | 53 | void __iomem *mmio_base; |
53 | int irq; | 54 | int irq; |
54 | unsigned short keymap[W90P910_MAX_KEY_NUM]; | 55 | unsigned short keymap[W90P910_NUM_ROWS * W90P910_NUM_COLS]; |
55 | }; | 56 | }; |
56 | 57 | ||
57 | static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, | 58 | static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, |
@@ -190,17 +191,13 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev) | |||
190 | input_dev->close = w90p910_keypad_close; | 191 | input_dev->close = w90p910_keypad_close; |
191 | input_dev->dev.parent = &pdev->dev; | 192 | input_dev->dev.parent = &pdev->dev; |
192 | 193 | ||
193 | input_dev->keycode = keypad->keymap; | 194 | error = matrix_keypad_build_keymap(keymap_data, NULL, |
194 | input_dev->keycodesize = sizeof(keypad->keymap[0]); | 195 | W90P910_NUM_ROWS, W90P910_NUM_COLS, |
195 | input_dev->keycodemax = ARRAY_SIZE(keypad->keymap); | 196 | keypad->keymap, input_dev); |
196 | 197 | if (error) { | |
197 | input_set_drvdata(input_dev, keypad); | 198 | dev_err(&pdev->dev, "failed to build keymap\n"); |
198 | 199 | goto failed_put_clk; | |
199 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 200 | } |
200 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
201 | |||
202 | matrix_keypad_build_keymap(keymap_data, W90P910_ROW_SHIFT, | ||
203 | input_dev->keycode, input_dev->keybit); | ||
204 | 201 | ||
205 | error = request_irq(keypad->irq, w90p910_keypad_irq_handler, | 202 | error = request_irq(keypad->irq, w90p910_keypad_irq_handler, |
206 | 0, pdev->name, keypad); | 203 | 0, pdev->name, keypad); |
@@ -209,6 +206,10 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev) | |||
209 | goto failed_put_clk; | 206 | goto failed_put_clk; |
210 | } | 207 | } |
211 | 208 | ||
209 | __set_bit(EV_REP, input_dev->evbit); | ||
210 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
211 | input_set_drvdata(input_dev, keypad); | ||
212 | |||
212 | /* Register the input device */ | 213 | /* Register the input device */ |
213 | error = input_register_device(input_dev); | 214 | error = input_register_device(input_dev); |
214 | if (error) { | 215 | if (error) { |
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index 37b01d777a4a..d050d9d0011b 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c | |||
@@ -169,15 +169,4 @@ static struct serio_driver xtkbd_drv = { | |||
169 | .disconnect = xtkbd_disconnect, | 169 | .disconnect = xtkbd_disconnect, |
170 | }; | 170 | }; |
171 | 171 | ||
172 | static int __init xtkbd_init(void) | 172 | module_serio_driver(xtkbd_drv); |
173 | { | ||
174 | return serio_register_driver(&xtkbd_drv); | ||
175 | } | ||
176 | |||
177 | static void __exit xtkbd_exit(void) | ||
178 | { | ||
179 | serio_unregister_driver(&xtkbd_drv); | ||
180 | } | ||
181 | |||
182 | module_init(xtkbd_init); | ||
183 | module_exit(xtkbd_exit); | ||
diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c new file mode 100644 index 000000000000..443ad64b7f2a --- /dev/null +++ b/drivers/input/matrix-keymap.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Helpers for matrix keyboard bindings | ||
3 | * | ||
4 | * Copyright (C) 2012 Google, Inc | ||
5 | * | ||
6 | * Author: | ||
7 | * Olof Johansson <olof@lixom.net> | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/device.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/of.h> | ||
25 | #include <linux/export.h> | ||
26 | #include <linux/input/matrix_keypad.h> | ||
27 | |||
28 | static bool matrix_keypad_map_key(struct input_dev *input_dev, | ||
29 | unsigned int rows, unsigned int cols, | ||
30 | unsigned int row_shift, unsigned int key) | ||
31 | { | ||
32 | unsigned short *keymap = input_dev->keycode; | ||
33 | unsigned int row = KEY_ROW(key); | ||
34 | unsigned int col = KEY_COL(key); | ||
35 | unsigned short code = KEY_VAL(key); | ||
36 | |||
37 | if (row >= rows || col >= cols) { | ||
38 | dev_err(input_dev->dev.parent, | ||
39 | "%s: invalid keymap entry 0x%x (row: %d, col: %d, rows: %d, cols: %d)\n", | ||
40 | __func__, key, row, col, rows, cols); | ||
41 | return false; | ||
42 | } | ||
43 | |||
44 | keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code; | ||
45 | __set_bit(code, input_dev->keybit); | ||
46 | |||
47 | return true; | ||
48 | } | ||
49 | |||
50 | #ifdef CONFIG_OF | ||
51 | static int matrix_keypad_parse_of_keymap(const char *propname, | ||
52 | unsigned int rows, unsigned int cols, | ||
53 | struct input_dev *input_dev) | ||
54 | { | ||
55 | struct device *dev = input_dev->dev.parent; | ||
56 | struct device_node *np = dev->of_node; | ||
57 | unsigned int row_shift = get_count_order(cols); | ||
58 | unsigned int max_keys = rows << row_shift; | ||
59 | unsigned int proplen, i, size; | ||
60 | const __be32 *prop; | ||
61 | |||
62 | if (!np) | ||
63 | return -ENOENT; | ||
64 | |||
65 | if (!propname) | ||
66 | propname = "linux,keymap"; | ||
67 | |||
68 | prop = of_get_property(np, propname, &proplen); | ||
69 | if (!prop) { | ||
70 | dev_err(dev, "OF: %s property not defined in %s\n", | ||
71 | propname, np->full_name); | ||
72 | return -ENOENT; | ||
73 | } | ||
74 | |||
75 | if (proplen % sizeof(u32)) { | ||
76 | dev_err(dev, "OF: Malformed keycode property %s in %s\n", | ||
77 | propname, np->full_name); | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | |||
81 | size = proplen / sizeof(u32); | ||
82 | if (size > max_keys) { | ||
83 | dev_err(dev, "OF: %s size overflow\n", propname); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | for (i = 0; i < size; i++) { | ||
88 | unsigned int key = be32_to_cpup(prop + i); | ||
89 | |||
90 | if (!matrix_keypad_map_key(input_dev, rows, cols, | ||
91 | row_shift, key)) | ||
92 | return -EINVAL; | ||
93 | } | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | #else | ||
98 | static int matrix_keypad_parse_of_keymap(const char *propname, | ||
99 | unsigned int rows, unsigned int cols, | ||
100 | struct input_dev *input_dev) | ||
101 | { | ||
102 | return -ENOSYS; | ||
103 | } | ||
104 | #endif | ||
105 | |||
106 | /** | ||
107 | * matrix_keypad_build_keymap - convert platform keymap into matrix keymap | ||
108 | * @keymap_data: keymap supplied by the platform code | ||
109 | * @keymap_name: name of device tree property containing keymap (if device | ||
110 | * tree support is enabled). | ||
111 | * @rows: number of rows in target keymap array | ||
112 | * @cols: number of cols in target keymap array | ||
113 | * @keymap: expanded version of keymap that is suitable for use by | ||
114 | * matrix keyboard driver | ||
115 | * @input_dev: input devices for which we are setting up the keymap | ||
116 | * | ||
117 | * This function converts platform keymap (encoded with KEY() macro) into | ||
118 | * an array of keycodes that is suitable for using in a standard matrix | ||
119 | * keyboard driver that uses row and col as indices. | ||
120 | * | ||
121 | * If @keymap_data is not supplied and device tree support is enabled | ||
122 | * it will attempt load the keymap from property specified by @keymap_name | ||
123 | * argument (or "linux,keymap" if @keymap_name is %NULL). | ||
124 | * | ||
125 | * Callers are expected to set up input_dev->dev.parent before calling this | ||
126 | * function. | ||
127 | */ | ||
128 | int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, | ||
129 | const char *keymap_name, | ||
130 | unsigned int rows, unsigned int cols, | ||
131 | unsigned short *keymap, | ||
132 | struct input_dev *input_dev) | ||
133 | { | ||
134 | unsigned int row_shift = get_count_order(cols); | ||
135 | int i; | ||
136 | int error; | ||
137 | |||
138 | input_dev->keycode = keymap; | ||
139 | input_dev->keycodesize = sizeof(*keymap); | ||
140 | input_dev->keycodemax = rows << row_shift; | ||
141 | |||
142 | __set_bit(EV_KEY, input_dev->evbit); | ||
143 | |||
144 | if (keymap_data) { | ||
145 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
146 | unsigned int key = keymap_data->keymap[i]; | ||
147 | |||
148 | if (!matrix_keypad_map_key(input_dev, rows, cols, | ||
149 | row_shift, key)) | ||
150 | return -EINVAL; | ||
151 | } | ||
152 | } else { | ||
153 | error = matrix_keypad_parse_of_keymap(keymap_name, rows, cols, | ||
154 | input_dev); | ||
155 | if (error) | ||
156 | return error; | ||
157 | } | ||
158 | |||
159 | __clear_bit(KEY_RESERVED, input_dev->keybit); | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | EXPORT_SYMBOL(matrix_keypad_build_keymap); | ||
diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c index 06517e60e50c..a3735a01e9fd 100644 --- a/drivers/input/misc/cma3000_d0x.c +++ b/drivers/input/misc/cma3000_d0x.c | |||
@@ -318,7 +318,7 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, | |||
318 | mutex_init(&data->mutex); | 318 | mutex_init(&data->mutex); |
319 | 319 | ||
320 | data->mode = pdata->mode; | 320 | data->mode = pdata->mode; |
321 | if (data->mode < CMAMODE_DEFAULT || data->mode > CMAMODE_POFF) { | 321 | if (data->mode > CMAMODE_POFF) { |
322 | data->mode = CMAMODE_MOTDET; | 322 | data->mode = CMAMODE_MOTDET; |
323 | dev_warn(dev, | 323 | dev_warn(dev, |
324 | "Invalid mode specified, assuming Motion Detect\n"); | 324 | "Invalid mode specified, assuming Motion Detect\n"); |
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c index 5403c571b6a5..306f84c2d8fb 100644 --- a/drivers/input/misc/mpu3050.c +++ b/drivers/input/misc/mpu3050.c | |||
@@ -367,7 +367,7 @@ static int __devinit mpu3050_probe(struct i2c_client *client, | |||
367 | 367 | ||
368 | error = request_threaded_irq(client->irq, | 368 | error = request_threaded_irq(client->irq, |
369 | NULL, mpu3050_interrupt_thread, | 369 | NULL, mpu3050_interrupt_thread, |
370 | IRQF_TRIGGER_RISING, | 370 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
371 | "mpu3050", sensor); | 371 | "mpu3050", sensor); |
372 | if (error) { | 372 | if (error) { |
373 | dev_err(&client->dev, | 373 | dev_err(&client->dev, |
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 14e94f56cb7d..c34f6c0371c4 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c | |||
@@ -27,6 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/of.h> | ||
30 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
31 | #include <linux/input.h> | 32 | #include <linux/input.h> |
32 | #include <linux/mfd/twl6040.h> | 33 | #include <linux/mfd/twl6040.h> |
@@ -258,10 +259,13 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); | |||
258 | static int __devinit twl6040_vibra_probe(struct platform_device *pdev) | 259 | static int __devinit twl6040_vibra_probe(struct platform_device *pdev) |
259 | { | 260 | { |
260 | struct twl6040_vibra_data *pdata = pdev->dev.platform_data; | 261 | struct twl6040_vibra_data *pdata = pdev->dev.platform_data; |
262 | struct device_node *node = pdev->dev.of_node; | ||
261 | struct vibra_info *info; | 263 | struct vibra_info *info; |
264 | int vddvibl_uV = 0; | ||
265 | int vddvibr_uV = 0; | ||
262 | int ret; | 266 | int ret; |
263 | 267 | ||
264 | if (!pdata) { | 268 | if (!pdata && !node) { |
265 | dev_err(&pdev->dev, "platform_data not available\n"); | 269 | dev_err(&pdev->dev, "platform_data not available\n"); |
266 | return -EINVAL; | 270 | return -EINVAL; |
267 | } | 271 | } |
@@ -273,11 +277,26 @@ static int __devinit twl6040_vibra_probe(struct platform_device *pdev) | |||
273 | } | 277 | } |
274 | 278 | ||
275 | info->dev = &pdev->dev; | 279 | info->dev = &pdev->dev; |
280 | |||
276 | info->twl6040 = dev_get_drvdata(pdev->dev.parent); | 281 | info->twl6040 = dev_get_drvdata(pdev->dev.parent); |
277 | info->vibldrv_res = pdata->vibldrv_res; | 282 | if (pdata) { |
278 | info->vibrdrv_res = pdata->vibrdrv_res; | 283 | info->vibldrv_res = pdata->vibldrv_res; |
279 | info->viblmotor_res = pdata->viblmotor_res; | 284 | info->vibrdrv_res = pdata->vibrdrv_res; |
280 | info->vibrmotor_res = pdata->vibrmotor_res; | 285 | info->viblmotor_res = pdata->viblmotor_res; |
286 | info->vibrmotor_res = pdata->vibrmotor_res; | ||
287 | vddvibl_uV = pdata->vddvibl_uV; | ||
288 | vddvibr_uV = pdata->vddvibr_uV; | ||
289 | } else { | ||
290 | of_property_read_u32(node, "vibldrv_res", &info->vibldrv_res); | ||
291 | of_property_read_u32(node, "vibrdrv_res", &info->vibrdrv_res); | ||
292 | of_property_read_u32(node, "viblmotor_res", | ||
293 | &info->viblmotor_res); | ||
294 | of_property_read_u32(node, "vibrmotor_res", | ||
295 | &info->vibrmotor_res); | ||
296 | of_property_read_u32(node, "vddvibl_uV", &vddvibl_uV); | ||
297 | of_property_read_u32(node, "vddvibr_uV", &vddvibr_uV); | ||
298 | } | ||
299 | |||
281 | if ((!info->vibldrv_res && !info->viblmotor_res) || | 300 | if ((!info->vibldrv_res && !info->viblmotor_res) || |
282 | (!info->vibrdrv_res && !info->vibrmotor_res)) { | 301 | (!info->vibrdrv_res && !info->vibrmotor_res)) { |
283 | dev_err(info->dev, "invalid vibra driver/motor resistance\n"); | 302 | dev_err(info->dev, "invalid vibra driver/motor resistance\n"); |
@@ -339,10 +358,9 @@ static int __devinit twl6040_vibra_probe(struct platform_device *pdev) | |||
339 | goto err_regulator; | 358 | goto err_regulator; |
340 | } | 359 | } |
341 | 360 | ||
342 | if (pdata->vddvibl_uV) { | 361 | if (vddvibl_uV) { |
343 | ret = regulator_set_voltage(info->supplies[0].consumer, | 362 | ret = regulator_set_voltage(info->supplies[0].consumer, |
344 | pdata->vddvibl_uV, | 363 | vddvibl_uV, vddvibl_uV); |
345 | pdata->vddvibl_uV); | ||
346 | if (ret) { | 364 | if (ret) { |
347 | dev_err(info->dev, "failed to set VDDVIBL volt %d\n", | 365 | dev_err(info->dev, "failed to set VDDVIBL volt %d\n", |
348 | ret); | 366 | ret); |
@@ -350,10 +368,9 @@ static int __devinit twl6040_vibra_probe(struct platform_device *pdev) | |||
350 | } | 368 | } |
351 | } | 369 | } |
352 | 370 | ||
353 | if (pdata->vddvibr_uV) { | 371 | if (vddvibr_uV) { |
354 | ret = regulator_set_voltage(info->supplies[1].consumer, | 372 | ret = regulator_set_voltage(info->supplies[1].consumer, |
355 | pdata->vddvibr_uV, | 373 | vddvibr_uV, vddvibr_uV); |
356 | pdata->vddvibr_uV); | ||
357 | if (ret) { | 374 | if (ret) { |
358 | dev_err(info->dev, "failed to set VDDVIBR volt %d\n", | 375 | dev_err(info->dev, "failed to set VDDVIBR volt %d\n", |
359 | ret); | 376 | ret); |
@@ -401,6 +418,12 @@ static int __devexit twl6040_vibra_remove(struct platform_device *pdev) | |||
401 | return 0; | 418 | return 0; |
402 | } | 419 | } |
403 | 420 | ||
421 | static const struct of_device_id twl6040_vibra_of_match[] = { | ||
422 | {.compatible = "ti,twl6040-vibra", }, | ||
423 | { }, | ||
424 | }; | ||
425 | MODULE_DEVICE_TABLE(of, twl6040_vibra_of_match); | ||
426 | |||
404 | static struct platform_driver twl6040_vibra_driver = { | 427 | static struct platform_driver twl6040_vibra_driver = { |
405 | .probe = twl6040_vibra_probe, | 428 | .probe = twl6040_vibra_probe, |
406 | .remove = __devexit_p(twl6040_vibra_remove), | 429 | .remove = __devexit_p(twl6040_vibra_remove), |
@@ -408,6 +431,7 @@ static struct platform_driver twl6040_vibra_driver = { | |||
408 | .name = "twl6040-vibra", | 431 | .name = "twl6040-vibra", |
409 | .owner = THIS_MODULE, | 432 | .owner = THIS_MODULE, |
410 | .pm = &twl6040_vibra_pm_ops, | 433 | .pm = &twl6040_vibra_pm_ops, |
434 | .of_match_table = twl6040_vibra_of_match, | ||
411 | }, | 435 | }, |
412 | }; | 436 | }; |
413 | module_platform_driver(twl6040_vibra_driver); | 437 | module_platform_driver(twl6040_vibra_driver); |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 9b8db821d5f0..cd6268cf7cd5 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -339,4 +339,16 @@ config MOUSE_SYNAPTICS_USB | |||
339 | To compile this driver as a module, choose M here: the | 339 | To compile this driver as a module, choose M here: the |
340 | module will be called synaptics_usb. | 340 | module will be called synaptics_usb. |
341 | 341 | ||
342 | config MOUSE_NAVPOINT_PXA27x | ||
343 | tristate "Synaptics NavPoint (PXA27x SSP/SPI)" | ||
344 | depends on PXA27x && PXA_SSP | ||
345 | help | ||
346 | This driver adds support for the Synaptics NavPoint touchpad connected | ||
347 | to a PXA27x SSP port in SPI slave mode. The device emulates a mouse; | ||
348 | a tap or tap-and-a-half drag gesture emulates the left mouse button. | ||
349 | For example, use the xf86-input-evdev driver for an X pointing device. | ||
350 | |||
351 | To compile this driver as a module, choose M here: the | ||
352 | module will be called navpoint. | ||
353 | |||
342 | endif | 354 | endif |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 4718effeb8d9..46ba7556fd4f 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o | |||
12 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 12 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
13 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o | 13 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o |
14 | obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o | 14 | obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o |
15 | obj-$(CONFIG_MOUSE_NAVPOINT_PXA27x) += navpoint.o | ||
15 | obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o | 16 | obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o |
16 | obj-$(CONFIG_MOUSE_PS2) += psmouse.o | 17 | obj-$(CONFIG_MOUSE_PS2) += psmouse.o |
17 | obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o | 18 | obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4c6a72d3d48c..4a1347e91bdc 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -553,10 +553,7 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | |||
553 | 553 | ||
554 | alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | 554 | alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); |
555 | 555 | ||
556 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 556 | input_mt_report_finger_count(dev, fingers); |
557 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | ||
558 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | ||
559 | input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); | ||
560 | 557 | ||
561 | input_report_key(dev, BTN_LEFT, left); | 558 | input_report_key(dev, BTN_LEFT, left); |
562 | input_report_key(dev, BTN_RIGHT, right); | 559 | input_report_key(dev, BTN_RIGHT, right); |
@@ -604,10 +601,54 @@ static void alps_process_packet_v3(struct psmouse *psmouse) | |||
604 | 601 | ||
605 | static void alps_process_packet_v4(struct psmouse *psmouse) | 602 | static void alps_process_packet_v4(struct psmouse *psmouse) |
606 | { | 603 | { |
604 | struct alps_data *priv = psmouse->private; | ||
607 | unsigned char *packet = psmouse->packet; | 605 | unsigned char *packet = psmouse->packet; |
608 | struct input_dev *dev = psmouse->dev; | 606 | struct input_dev *dev = psmouse->dev; |
607 | int offset; | ||
609 | int x, y, z; | 608 | int x, y, z; |
610 | int left, right; | 609 | int left, right; |
610 | int x1, y1, x2, y2; | ||
611 | int fingers = 0; | ||
612 | unsigned int x_bitmap, y_bitmap; | ||
613 | |||
614 | /* | ||
615 | * v4 has a 6-byte encoding for bitmap data, but this data is | ||
616 | * broken up between 3 normal packets. Use priv->multi_packet to | ||
617 | * track our position in the bitmap packet. | ||
618 | */ | ||
619 | if (packet[6] & 0x40) { | ||
620 | /* sync, reset position */ | ||
621 | priv->multi_packet = 0; | ||
622 | } | ||
623 | |||
624 | if (WARN_ON_ONCE(priv->multi_packet > 2)) | ||
625 | return; | ||
626 | |||
627 | offset = 2 * priv->multi_packet; | ||
628 | priv->multi_data[offset] = packet[6]; | ||
629 | priv->multi_data[offset + 1] = packet[7]; | ||
630 | |||
631 | if (++priv->multi_packet > 2) { | ||
632 | priv->multi_packet = 0; | ||
633 | |||
634 | x_bitmap = ((priv->multi_data[2] & 0x1f) << 10) | | ||
635 | ((priv->multi_data[3] & 0x60) << 3) | | ||
636 | ((priv->multi_data[0] & 0x3f) << 2) | | ||
637 | ((priv->multi_data[1] & 0x60) >> 5); | ||
638 | y_bitmap = ((priv->multi_data[5] & 0x01) << 10) | | ||
639 | ((priv->multi_data[3] & 0x1f) << 5) | | ||
640 | (priv->multi_data[1] & 0x1f); | ||
641 | |||
642 | fingers = alps_process_bitmap(x_bitmap, y_bitmap, | ||
643 | &x1, &y1, &x2, &y2); | ||
644 | |||
645 | /* Store MT data.*/ | ||
646 | priv->fingers = fingers; | ||
647 | priv->x1 = x1; | ||
648 | priv->x2 = x2; | ||
649 | priv->y1 = y1; | ||
650 | priv->y2 = y2; | ||
651 | } | ||
611 | 652 | ||
612 | left = packet[4] & 0x01; | 653 | left = packet[4] & 0x01; |
613 | right = packet[4] & 0x02; | 654 | right = packet[4] & 0x02; |
@@ -617,21 +658,41 @@ static void alps_process_packet_v4(struct psmouse *psmouse) | |||
617 | y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f); | 658 | y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f); |
618 | z = packet[5] & 0x7f; | 659 | z = packet[5] & 0x7f; |
619 | 660 | ||
661 | /* | ||
662 | * If there were no contacts in the bitmap, use ST | ||
663 | * points in MT reports. | ||
664 | * If there were two contacts or more, report MT data. | ||
665 | */ | ||
666 | if (priv->fingers < 2) { | ||
667 | x1 = x; | ||
668 | y1 = y; | ||
669 | fingers = z > 0 ? 1 : 0; | ||
670 | } else { | ||
671 | fingers = priv->fingers; | ||
672 | x1 = priv->x1; | ||
673 | x2 = priv->x2; | ||
674 | y1 = priv->y1; | ||
675 | y2 = priv->y2; | ||
676 | } | ||
677 | |||
620 | if (z >= 64) | 678 | if (z >= 64) |
621 | input_report_key(dev, BTN_TOUCH, 1); | 679 | input_report_key(dev, BTN_TOUCH, 1); |
622 | else | 680 | else |
623 | input_report_key(dev, BTN_TOUCH, 0); | 681 | input_report_key(dev, BTN_TOUCH, 0); |
624 | 682 | ||
683 | alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | ||
684 | |||
685 | input_mt_report_finger_count(dev, fingers); | ||
686 | |||
687 | input_report_key(dev, BTN_LEFT, left); | ||
688 | input_report_key(dev, BTN_RIGHT, right); | ||
689 | |||
625 | if (z > 0) { | 690 | if (z > 0) { |
626 | input_report_abs(dev, ABS_X, x); | 691 | input_report_abs(dev, ABS_X, x); |
627 | input_report_abs(dev, ABS_Y, y); | 692 | input_report_abs(dev, ABS_Y, y); |
628 | } | 693 | } |
629 | input_report_abs(dev, ABS_PRESSURE, z); | 694 | input_report_abs(dev, ABS_PRESSURE, z); |
630 | 695 | ||
631 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); | ||
632 | input_report_key(dev, BTN_LEFT, left); | ||
633 | input_report_key(dev, BTN_RIGHT, right); | ||
634 | |||
635 | input_sync(dev); | 696 | input_sync(dev); |
636 | } | 697 | } |
637 | 698 | ||
@@ -1557,6 +1618,7 @@ int alps_init(struct psmouse *psmouse) | |||
1557 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); | 1618 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); |
1558 | break; | 1619 | break; |
1559 | case ALPS_PROTO_V3: | 1620 | case ALPS_PROTO_V3: |
1621 | case ALPS_PROTO_V4: | ||
1560 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); | 1622 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); |
1561 | input_mt_init_slots(dev1, 2); | 1623 | input_mt_init_slots(dev1, 2); |
1562 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); | 1624 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); |
@@ -1565,8 +1627,7 @@ int alps_init(struct psmouse *psmouse) | |||
1565 | set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit); | 1627 | set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit); |
1566 | set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit); | 1628 | set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit); |
1567 | set_bit(BTN_TOOL_QUADTAP, dev1->keybit); | 1629 | set_bit(BTN_TOOL_QUADTAP, dev1->keybit); |
1568 | /* fall through */ | 1630 | |
1569 | case ALPS_PROTO_V4: | ||
1570 | input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0); | 1631 | input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0); |
1571 | input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0); | 1632 | input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0); |
1572 | break; | 1633 | break; |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index a00a4ab92a0f..ae1ac354c778 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
@@ -39,6 +39,8 @@ struct alps_data { | |||
39 | int prev_fin; /* Finger bit from previous packet */ | 39 | int prev_fin; /* Finger bit from previous packet */ |
40 | int multi_packet; /* Multi-packet data in progress */ | 40 | int multi_packet; /* Multi-packet data in progress */ |
41 | unsigned char multi_data[6]; /* Saved multi-packet data */ | 41 | unsigned char multi_data[6]; /* Saved multi-packet data */ |
42 | int x1, x2, y1, y2; /* Coordinates from last MT report */ | ||
43 | int fingers; /* Number of fingers from MT report */ | ||
42 | u8 quirks; | 44 | u8 quirks; |
43 | struct timer_list timer; | 45 | struct timer_list timer; |
44 | }; | 46 | }; |
diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c new file mode 100644 index 000000000000..c29ae7654d5e --- /dev/null +++ b/drivers/input/mouse/navpoint.c | |||
@@ -0,0 +1,369 @@ | |||
1 | /* | ||
2 | * Synaptics NavPoint (PXA27x SSP/SPI) driver. | ||
3 | * | ||
4 | * Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com> | ||
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 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/input/navpoint.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/pxa2xx_ssp.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | /* | ||
26 | * Synaptics Modular Embedded Protocol: Module Packet Format. | ||
27 | * Module header byte 2:0 = Length (# bytes that follow) | ||
28 | * Module header byte 4:3 = Control | ||
29 | * Module header byte 7:5 = Module Address | ||
30 | */ | ||
31 | #define HEADER_LENGTH(byte) ((byte) & 0x07) | ||
32 | #define HEADER_CONTROL(byte) (((byte) >> 3) & 0x03) | ||
33 | #define HEADER_ADDRESS(byte) ((byte) >> 5) | ||
34 | |||
35 | struct navpoint { | ||
36 | struct ssp_device *ssp; | ||
37 | struct input_dev *input; | ||
38 | struct device *dev; | ||
39 | int gpio; | ||
40 | int index; | ||
41 | u8 data[1 + HEADER_LENGTH(0xff)]; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * Initialization values for SSCR0_x, SSCR1_x, SSSR_x. | ||
46 | */ | ||
47 | static const u32 sscr0 = 0 | ||
48 | | SSCR0_TUM /* TIM = 1; No TUR interrupts */ | ||
49 | | SSCR0_RIM /* RIM = 1; No ROR interrupts */ | ||
50 | | SSCR0_SSE /* SSE = 1; SSP enabled */ | ||
51 | | SSCR0_Motorola /* FRF = 0; Motorola SPI */ | ||
52 | | SSCR0_DataSize(16) /* DSS = 15; Data size = 16-bit */ | ||
53 | ; | ||
54 | static const u32 sscr1 = 0 | ||
55 | | SSCR1_SCFR /* SCFR = 1; SSPSCLK only during transfers */ | ||
56 | | SSCR1_SCLKDIR /* SCLKDIR = 1; Slave mode */ | ||
57 | | SSCR1_SFRMDIR /* SFRMDIR = 1; Slave mode */ | ||
58 | | SSCR1_RWOT /* RWOT = 1; Receive without transmit mode */ | ||
59 | | SSCR1_RxTresh(1) /* RFT = 0; Receive FIFO threshold = 1 */ | ||
60 | | SSCR1_SPH /* SPH = 1; SSPSCLK inactive 0.5 + 1 cycles */ | ||
61 | | SSCR1_RIE /* RIE = 1; Receive FIFO interrupt enabled */ | ||
62 | ; | ||
63 | static const u32 sssr = 0 | ||
64 | | SSSR_BCE /* BCE = 1; Clear BCE */ | ||
65 | | SSSR_TUR /* TUR = 1; Clear TUR */ | ||
66 | | SSSR_EOC /* EOC = 1; Clear EOC */ | ||
67 | | SSSR_TINT /* TINT = 1; Clear TINT */ | ||
68 | | SSSR_PINT /* PINT = 1; Clear PINT */ | ||
69 | | SSSR_ROR /* ROR = 1; Clear ROR */ | ||
70 | ; | ||
71 | |||
72 | /* | ||
73 | * MEP Query $22: Touchpad Coordinate Range Query is not supported by | ||
74 | * the NavPoint module, so sampled values provide the default limits. | ||
75 | */ | ||
76 | #define NAVPOINT_X_MIN 1278 | ||
77 | #define NAVPOINT_X_MAX 5340 | ||
78 | #define NAVPOINT_Y_MIN 1572 | ||
79 | #define NAVPOINT_Y_MAX 4396 | ||
80 | #define NAVPOINT_PRESSURE_MIN 0 | ||
81 | #define NAVPOINT_PRESSURE_MAX 255 | ||
82 | |||
83 | static void navpoint_packet(struct navpoint *navpoint) | ||
84 | { | ||
85 | int finger; | ||
86 | int gesture; | ||
87 | int x, y, z; | ||
88 | |||
89 | switch (navpoint->data[0]) { | ||
90 | case 0xff: /* Garbage (packet?) between reset and Hello packet */ | ||
91 | case 0x00: /* Module 0, NULL packet */ | ||
92 | break; | ||
93 | |||
94 | case 0x0e: /* Module 0, Absolute packet */ | ||
95 | finger = (navpoint->data[1] & 0x01); | ||
96 | gesture = (navpoint->data[1] & 0x02); | ||
97 | x = ((navpoint->data[2] & 0x1f) << 8) | navpoint->data[3]; | ||
98 | y = ((navpoint->data[4] & 0x1f) << 8) | navpoint->data[5]; | ||
99 | z = navpoint->data[6]; | ||
100 | input_report_key(navpoint->input, BTN_TOUCH, finger); | ||
101 | input_report_abs(navpoint->input, ABS_X, x); | ||
102 | input_report_abs(navpoint->input, ABS_Y, y); | ||
103 | input_report_abs(navpoint->input, ABS_PRESSURE, z); | ||
104 | input_report_key(navpoint->input, BTN_TOOL_FINGER, finger); | ||
105 | input_report_key(navpoint->input, BTN_LEFT, gesture); | ||
106 | input_sync(navpoint->input); | ||
107 | break; | ||
108 | |||
109 | case 0x19: /* Module 0, Hello packet */ | ||
110 | if ((navpoint->data[1] & 0xf0) == 0x10) | ||
111 | break; | ||
112 | /* FALLTHROUGH */ | ||
113 | default: | ||
114 | dev_warn(navpoint->dev, | ||
115 | "spurious packet: data=0x%02x,0x%02x,...\n", | ||
116 | navpoint->data[0], navpoint->data[1]); | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static irqreturn_t navpoint_irq(int irq, void *dev_id) | ||
122 | { | ||
123 | struct navpoint *navpoint = dev_id; | ||
124 | struct ssp_device *ssp = navpoint->ssp; | ||
125 | irqreturn_t ret = IRQ_NONE; | ||
126 | u32 status; | ||
127 | |||
128 | status = pxa_ssp_read_reg(ssp, SSSR); | ||
129 | if (status & sssr) { | ||
130 | dev_warn(navpoint->dev, | ||
131 | "unexpected interrupt: status=0x%08x\n", status); | ||
132 | pxa_ssp_write_reg(ssp, SSSR, (status & sssr)); | ||
133 | ret = IRQ_HANDLED; | ||
134 | } | ||
135 | |||
136 | while (status & SSSR_RNE) { | ||
137 | u32 data; | ||
138 | |||
139 | data = pxa_ssp_read_reg(ssp, SSDR); | ||
140 | navpoint->data[navpoint->index + 0] = (data >> 8); | ||
141 | navpoint->data[navpoint->index + 1] = data; | ||
142 | navpoint->index += 2; | ||
143 | if (HEADER_LENGTH(navpoint->data[0]) < navpoint->index) { | ||
144 | navpoint_packet(navpoint); | ||
145 | navpoint->index = 0; | ||
146 | } | ||
147 | status = pxa_ssp_read_reg(ssp, SSSR); | ||
148 | ret = IRQ_HANDLED; | ||
149 | } | ||
150 | |||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | static void navpoint_up(struct navpoint *navpoint) | ||
155 | { | ||
156 | struct ssp_device *ssp = navpoint->ssp; | ||
157 | int timeout; | ||
158 | |||
159 | clk_prepare_enable(ssp->clk); | ||
160 | |||
161 | pxa_ssp_write_reg(ssp, SSCR1, sscr1); | ||
162 | pxa_ssp_write_reg(ssp, SSSR, sssr); | ||
163 | pxa_ssp_write_reg(ssp, SSTO, 0); | ||
164 | pxa_ssp_write_reg(ssp, SSCR0, sscr0); /* SSCR0_SSE written last */ | ||
165 | |||
166 | /* Wait until SSP port is ready for slave clock operations */ | ||
167 | for (timeout = 100; timeout != 0; --timeout) { | ||
168 | if (!(pxa_ssp_read_reg(ssp, SSSR) & SSSR_CSS)) | ||
169 | break; | ||
170 | msleep(1); | ||
171 | } | ||
172 | |||
173 | if (timeout == 0) | ||
174 | dev_err(navpoint->dev, | ||
175 | "timeout waiting for SSSR[CSS] to clear\n"); | ||
176 | |||
177 | if (gpio_is_valid(navpoint->gpio)) | ||
178 | gpio_set_value(navpoint->gpio, 1); | ||
179 | } | ||
180 | |||
181 | static void navpoint_down(struct navpoint *navpoint) | ||
182 | { | ||
183 | struct ssp_device *ssp = navpoint->ssp; | ||
184 | |||
185 | if (gpio_is_valid(navpoint->gpio)) | ||
186 | gpio_set_value(navpoint->gpio, 0); | ||
187 | |||
188 | pxa_ssp_write_reg(ssp, SSCR0, 0); | ||
189 | |||
190 | clk_disable_unprepare(ssp->clk); | ||
191 | } | ||
192 | |||
193 | static int navpoint_open(struct input_dev *input) | ||
194 | { | ||
195 | struct navpoint *navpoint = input_get_drvdata(input); | ||
196 | |||
197 | navpoint_up(navpoint); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static void navpoint_close(struct input_dev *input) | ||
203 | { | ||
204 | struct navpoint *navpoint = input_get_drvdata(input); | ||
205 | |||
206 | navpoint_down(navpoint); | ||
207 | } | ||
208 | |||
209 | static int __devinit navpoint_probe(struct platform_device *pdev) | ||
210 | { | ||
211 | const struct navpoint_platform_data *pdata = | ||
212 | dev_get_platdata(&pdev->dev); | ||
213 | struct ssp_device *ssp; | ||
214 | struct input_dev *input; | ||
215 | struct navpoint *navpoint; | ||
216 | int error; | ||
217 | |||
218 | if (!pdata) { | ||
219 | dev_err(&pdev->dev, "no platform data\n"); | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | |||
223 | if (gpio_is_valid(pdata->gpio)) { | ||
224 | error = gpio_request_one(pdata->gpio, GPIOF_OUT_INIT_LOW, | ||
225 | "SYNAPTICS_ON"); | ||
226 | if (error) | ||
227 | return error; | ||
228 | } | ||
229 | |||
230 | ssp = pxa_ssp_request(pdata->port, pdev->name); | ||
231 | if (!ssp) { | ||
232 | error = -ENODEV; | ||
233 | goto err_free_gpio; | ||
234 | } | ||
235 | |||
236 | /* HaRET does not disable devices before jumping into Linux */ | ||
237 | if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { | ||
238 | pxa_ssp_write_reg(ssp, SSCR0, 0); | ||
239 | dev_warn(&pdev->dev, "ssp%d already enabled\n", pdata->port); | ||
240 | } | ||
241 | |||
242 | navpoint = kzalloc(sizeof(*navpoint), GFP_KERNEL); | ||
243 | input = input_allocate_device(); | ||
244 | if (!navpoint || !input) { | ||
245 | error = -ENOMEM; | ||
246 | goto err_free_mem; | ||
247 | } | ||
248 | |||
249 | navpoint->ssp = ssp; | ||
250 | navpoint->input = input; | ||
251 | navpoint->dev = &pdev->dev; | ||
252 | navpoint->gpio = pdata->gpio; | ||
253 | |||
254 | input->name = pdev->name; | ||
255 | input->dev.parent = &pdev->dev; | ||
256 | |||
257 | __set_bit(EV_KEY, input->evbit); | ||
258 | __set_bit(EV_ABS, input->evbit); | ||
259 | __set_bit(BTN_LEFT, input->keybit); | ||
260 | __set_bit(BTN_TOUCH, input->keybit); | ||
261 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
262 | |||
263 | input_set_abs_params(input, ABS_X, | ||
264 | NAVPOINT_X_MIN, NAVPOINT_X_MAX, 0, 0); | ||
265 | input_set_abs_params(input, ABS_Y, | ||
266 | NAVPOINT_Y_MIN, NAVPOINT_Y_MAX, 0, 0); | ||
267 | input_set_abs_params(input, ABS_PRESSURE, | ||
268 | NAVPOINT_PRESSURE_MIN, NAVPOINT_PRESSURE_MAX, | ||
269 | 0, 0); | ||
270 | |||
271 | input->open = navpoint_open; | ||
272 | input->close = navpoint_close; | ||
273 | |||
274 | input_set_drvdata(input, navpoint); | ||
275 | |||
276 | error = request_irq(ssp->irq, navpoint_irq, 0, pdev->name, navpoint); | ||
277 | if (error) | ||
278 | goto err_free_mem; | ||
279 | |||
280 | error = input_register_device(input); | ||
281 | if (error) | ||
282 | goto err_free_irq; | ||
283 | |||
284 | platform_set_drvdata(pdev, navpoint); | ||
285 | dev_dbg(&pdev->dev, "ssp%d, irq %d\n", pdata->port, ssp->irq); | ||
286 | |||
287 | return 0; | ||
288 | |||
289 | err_free_irq: | ||
290 | free_irq(ssp->irq, &pdev->dev); | ||
291 | err_free_mem: | ||
292 | input_free_device(input); | ||
293 | kfree(navpoint); | ||
294 | pxa_ssp_free(ssp); | ||
295 | err_free_gpio: | ||
296 | if (gpio_is_valid(pdata->gpio)) | ||
297 | gpio_free(pdata->gpio); | ||
298 | |||
299 | return error; | ||
300 | } | ||
301 | |||
302 | static int __devexit navpoint_remove(struct platform_device *pdev) | ||
303 | { | ||
304 | const struct navpoint_platform_data *pdata = | ||
305 | dev_get_platdata(&pdev->dev); | ||
306 | struct navpoint *navpoint = platform_get_drvdata(pdev); | ||
307 | struct ssp_device *ssp = navpoint->ssp; | ||
308 | |||
309 | free_irq(ssp->irq, navpoint); | ||
310 | |||
311 | input_unregister_device(navpoint->input); | ||
312 | kfree(navpoint); | ||
313 | |||
314 | pxa_ssp_free(ssp); | ||
315 | |||
316 | if (gpio_is_valid(pdata->gpio)) | ||
317 | gpio_free(pdata->gpio); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | #ifdef CONFIG_PM_SLEEP | ||
323 | static int navpoint_suspend(struct device *dev) | ||
324 | { | ||
325 | struct platform_device *pdev = to_platform_device(dev); | ||
326 | struct navpoint *navpoint = platform_get_drvdata(pdev); | ||
327 | struct input_dev *input = navpoint->input; | ||
328 | |||
329 | mutex_lock(&input->mutex); | ||
330 | if (input->users) | ||
331 | navpoint_down(navpoint); | ||
332 | mutex_unlock(&input->mutex); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static int navpoint_resume(struct device *dev) | ||
338 | { | ||
339 | struct platform_device *pdev = to_platform_device(dev); | ||
340 | struct navpoint *navpoint = platform_get_drvdata(pdev); | ||
341 | struct input_dev *input = navpoint->input; | ||
342 | |||
343 | mutex_lock(&input->mutex); | ||
344 | if (input->users) | ||
345 | navpoint_up(navpoint); | ||
346 | mutex_unlock(&input->mutex); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | #endif | ||
351 | |||
352 | static SIMPLE_DEV_PM_OPS(navpoint_pm_ops, navpoint_suspend, navpoint_resume); | ||
353 | |||
354 | static struct platform_driver navpoint_driver = { | ||
355 | .probe = navpoint_probe, | ||
356 | .remove = __devexit_p(navpoint_remove), | ||
357 | .driver = { | ||
358 | .name = "navpoint", | ||
359 | .owner = THIS_MODULE, | ||
360 | .pm = &navpoint_pm_ops, | ||
361 | }, | ||
362 | }; | ||
363 | |||
364 | module_platform_driver(navpoint_driver); | ||
365 | |||
366 | MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>"); | ||
367 | MODULE_DESCRIPTION("Synaptics NavPoint (PXA27x SSP/SPI) driver"); | ||
368 | MODULE_LICENSE("GPL"); | ||
369 | MODULE_ALIAS("platform:navpoint"); | ||
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 661a0ca3b3d6..3f5649f19082 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #define GET_ABS_Y(packet) ((packet[2] << 2) | (packet[3] & 0x03)) | 41 | #define GET_ABS_Y(packet) ((packet[2] << 2) | (packet[3] & 0x03)) |
42 | 42 | ||
43 | /** Driver version. */ | 43 | /** Driver version. */ |
44 | static const char fsp_drv_ver[] = "1.0.0-K"; | 44 | static const char fsp_drv_ver[] = "1.1.0-K"; |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Make sure that the value being sent to FSP will not conflict with | 47 | * Make sure that the value being sent to FSP will not conflict with |
@@ -303,6 +303,27 @@ static int fsp_get_revision(struct psmouse *psmouse, int *rev) | |||
303 | return 0; | 303 | return 0; |
304 | } | 304 | } |
305 | 305 | ||
306 | static int fsp_get_sn(struct psmouse *psmouse, int *sn) | ||
307 | { | ||
308 | int v0, v1, v2; | ||
309 | int rc = -EIO; | ||
310 | |||
311 | /* production number since Cx is available at: 0x0b40 ~ 0x0b42 */ | ||
312 | if (fsp_page_reg_write(psmouse, FSP_PAGE_0B)) | ||
313 | goto out; | ||
314 | if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0)) | ||
315 | goto out; | ||
316 | if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1)) | ||
317 | goto out; | ||
318 | if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2)) | ||
319 | goto out; | ||
320 | *sn = (v0 << 16) | (v1 << 8) | v2; | ||
321 | rc = 0; | ||
322 | out: | ||
323 | fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT); | ||
324 | return rc; | ||
325 | } | ||
326 | |||
306 | static int fsp_get_buttons(struct psmouse *psmouse, int *btn) | 327 | static int fsp_get_buttons(struct psmouse *psmouse, int *btn) |
307 | { | 328 | { |
308 | static const int buttons[] = { | 329 | static const int buttons[] = { |
@@ -1000,16 +1021,21 @@ static int fsp_reconnect(struct psmouse *psmouse) | |||
1000 | int fsp_init(struct psmouse *psmouse) | 1021 | int fsp_init(struct psmouse *psmouse) |
1001 | { | 1022 | { |
1002 | struct fsp_data *priv; | 1023 | struct fsp_data *priv; |
1003 | int ver, rev; | 1024 | int ver, rev, sn = 0; |
1004 | int error; | 1025 | int error; |
1005 | 1026 | ||
1006 | if (fsp_get_version(psmouse, &ver) || | 1027 | if (fsp_get_version(psmouse, &ver) || |
1007 | fsp_get_revision(psmouse, &rev)) { | 1028 | fsp_get_revision(psmouse, &rev)) { |
1008 | return -ENODEV; | 1029 | return -ENODEV; |
1009 | } | 1030 | } |
1031 | if (ver >= FSP_VER_STL3888_C0) { | ||
1032 | /* firmware information is only available since C0 */ | ||
1033 | fsp_get_sn(psmouse, &sn); | ||
1034 | } | ||
1010 | 1035 | ||
1011 | psmouse_info(psmouse, "Finger Sensing Pad, hw: %d.%d.%d, sw: %s\n", | 1036 | psmouse_info(psmouse, |
1012 | ver >> 4, ver & 0x0F, rev, fsp_drv_ver); | 1037 | "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n", |
1038 | ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver); | ||
1013 | 1039 | ||
1014 | psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); | 1040 | psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); |
1015 | if (!priv) | 1041 | if (!priv) |
diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h index 334de19e5ddb..aa697ece405b 100644 --- a/drivers/input/mouse/sentelic.h +++ b/drivers/input/mouse/sentelic.h | |||
@@ -65,6 +65,14 @@ | |||
65 | #define FSP_BIT_SWC1_GST_GRP1 BIT(6) | 65 | #define FSP_BIT_SWC1_GST_GRP1 BIT(6) |
66 | #define FSP_BIT_SWC1_BX_COMPAT BIT(7) | 66 | #define FSP_BIT_SWC1_BX_COMPAT BIT(7) |
67 | 67 | ||
68 | #define FSP_PAGE_0B (0x0b) | ||
69 | #define FSP_PAGE_82 (0x82) | ||
70 | #define FSP_PAGE_DEFAULT FSP_PAGE_82 | ||
71 | |||
72 | #define FSP_REG_SN0 (0x40) | ||
73 | #define FSP_REG_SN1 (0x41) | ||
74 | #define FSP_REG_SN2 (0x42) | ||
75 | |||
68 | /* Finger-sensing Pad packet formating related definitions */ | 76 | /* Finger-sensing Pad packet formating related definitions */ |
69 | 77 | ||
70 | /* absolute packet type */ | 78 | /* absolute packet type */ |
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 17ff137b9bd5..d5928fd0c914 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c | |||
@@ -355,15 +355,4 @@ static struct serio_driver sermouse_drv = { | |||
355 | .disconnect = sermouse_disconnect, | 355 | .disconnect = sermouse_disconnect, |
356 | }; | 356 | }; |
357 | 357 | ||
358 | static int __init sermouse_init(void) | 358 | module_serio_driver(sermouse_drv); |
359 | { | ||
360 | return serio_register_driver(&sermouse_drv); | ||
361 | } | ||
362 | |||
363 | static void __exit sermouse_exit(void) | ||
364 | { | ||
365 | serio_unregister_driver(&sermouse_drv); | ||
366 | } | ||
367 | |||
368 | module_init(sermouse_init); | ||
369 | module_exit(sermouse_exit); | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index a4b14a41cbf4..c703d53be3a0 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -45,16 +45,6 @@ | |||
45 | #define YMIN_NOMINAL 1408 | 45 | #define YMIN_NOMINAL 1408 |
46 | #define YMAX_NOMINAL 4448 | 46 | #define YMAX_NOMINAL 4448 |
47 | 47 | ||
48 | /* | ||
49 | * Synaptics touchpads report the y coordinate from bottom to top, which is | ||
50 | * opposite from what userspace expects. | ||
51 | * This function is used to invert y before reporting. | ||
52 | */ | ||
53 | static int synaptics_invert_y(int y) | ||
54 | { | ||
55 | return YMAX_NOMINAL + YMIN_NOMINAL - y; | ||
56 | } | ||
57 | |||
58 | 48 | ||
59 | /***************************************************************************** | 49 | /***************************************************************************** |
60 | * Stuff we need even when we do not want native Synaptics support | 50 | * Stuff we need even when we do not want native Synaptics support |
@@ -112,6 +102,16 @@ void synaptics_reset(struct psmouse *psmouse) | |||
112 | ****************************************************************************/ | 102 | ****************************************************************************/ |
113 | 103 | ||
114 | /* | 104 | /* |
105 | * Synaptics touchpads report the y coordinate from bottom to top, which is | ||
106 | * opposite from what userspace expects. | ||
107 | * This function is used to invert y before reporting. | ||
108 | */ | ||
109 | static int synaptics_invert_y(int y) | ||
110 | { | ||
111 | return YMAX_NOMINAL + YMIN_NOMINAL - y; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * Send a command to the synpatics touchpad by special commands | 115 | * Send a command to the synpatics touchpad by special commands |
116 | */ | 116 | */ |
117 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) | 117 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) |
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index eb9a3cfbeefa..e900d465aaf6 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -548,16 +548,4 @@ static struct serio_driver vsxxxaa_drv = { | |||
548 | .disconnect = vsxxxaa_disconnect, | 548 | .disconnect = vsxxxaa_disconnect, |
549 | }; | 549 | }; |
550 | 550 | ||
551 | static int __init vsxxxaa_init(void) | 551 | module_serio_driver(vsxxxaa_drv); |
552 | { | ||
553 | return serio_register_driver(&vsxxxaa_drv); | ||
554 | } | ||
555 | |||
556 | static void __exit vsxxxaa_exit(void) | ||
557 | { | ||
558 | serio_unregister_driver(&vsxxxaa_drv); | ||
559 | } | ||
560 | |||
561 | module_init(vsxxxaa_init); | ||
562 | module_exit(vsxxxaa_exit); | ||
563 | |||
diff --git a/drivers/input/of_keymap.c b/drivers/input/of_keymap.c deleted file mode 100644 index 061493d57682..000000000000 --- a/drivers/input/of_keymap.c +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | /* | ||
2 | * Helpers for open firmware matrix keyboard bindings | ||
3 | * | ||
4 | * Copyright (C) 2012 Google, Inc | ||
5 | * | ||
6 | * Author: | ||
7 | * Olof Johansson <olof@lixom.net> | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/input/matrix_keypad.h> | ||
25 | #include <linux/export.h> | ||
26 | #include <linux/gfp.h> | ||
27 | #include <linux/slab.h> | ||
28 | |||
29 | struct matrix_keymap_data * | ||
30 | matrix_keyboard_of_fill_keymap(struct device_node *np, | ||
31 | const char *propname) | ||
32 | { | ||
33 | struct matrix_keymap_data *kd; | ||
34 | u32 *keymap; | ||
35 | int proplen, i; | ||
36 | const __be32 *prop; | ||
37 | |||
38 | if (!np) | ||
39 | return NULL; | ||
40 | |||
41 | if (!propname) | ||
42 | propname = "linux,keymap"; | ||
43 | |||
44 | prop = of_get_property(np, propname, &proplen); | ||
45 | if (!prop) | ||
46 | return NULL; | ||
47 | |||
48 | if (proplen % sizeof(u32)) { | ||
49 | pr_warn("Malformed keymap property %s in %s\n", | ||
50 | propname, np->full_name); | ||
51 | return NULL; | ||
52 | } | ||
53 | |||
54 | kd = kzalloc(sizeof(*kd), GFP_KERNEL); | ||
55 | if (!kd) | ||
56 | return NULL; | ||
57 | |||
58 | kd->keymap = keymap = kzalloc(proplen, GFP_KERNEL); | ||
59 | if (!kd->keymap) { | ||
60 | kfree(kd); | ||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | kd->keymap_size = proplen / sizeof(u32); | ||
65 | |||
66 | for (i = 0; i < kd->keymap_size; i++) { | ||
67 | u32 tmp = be32_to_cpup(prop + i); | ||
68 | int key_code, row, col; | ||
69 | |||
70 | row = (tmp >> 24) & 0xff; | ||
71 | col = (tmp >> 16) & 0xff; | ||
72 | key_code = tmp & 0xffff; | ||
73 | keymap[i] = KEY(row, col, key_code); | ||
74 | } | ||
75 | |||
76 | return kd; | ||
77 | } | ||
78 | EXPORT_SYMBOL_GPL(matrix_keyboard_of_fill_keymap); | ||
79 | |||
80 | void matrix_keyboard_of_free_keymap(const struct matrix_keymap_data *kd) | ||
81 | { | ||
82 | if (kd) { | ||
83 | kfree(kd->keymap); | ||
84 | kfree(kd); | ||
85 | } | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(matrix_keyboard_of_free_keymap); | ||
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 43494742541c..0c42497aaaf4 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c | |||
@@ -206,6 +206,7 @@ static const struct pci_device_id pcips2_ids[] = { | |||
206 | }, | 206 | }, |
207 | { 0, } | 207 | { 0, } |
208 | }; | 208 | }; |
209 | MODULE_DEVICE_TABLE(pci, pcips2_ids); | ||
209 | 210 | ||
210 | static struct pci_driver pcips2_driver = { | 211 | static struct pci_driver pcips2_driver = { |
211 | .name = "pcips2", | 212 | .name = "pcips2", |
@@ -214,20 +215,8 @@ static struct pci_driver pcips2_driver = { | |||
214 | .remove = __devexit_p(pcips2_remove), | 215 | .remove = __devexit_p(pcips2_remove), |
215 | }; | 216 | }; |
216 | 217 | ||
217 | static int __init pcips2_init(void) | 218 | module_pci_driver(pcips2_driver); |
218 | { | ||
219 | return pci_register_driver(&pcips2_driver); | ||
220 | } | ||
221 | |||
222 | static void __exit pcips2_exit(void) | ||
223 | { | ||
224 | pci_unregister_driver(&pcips2_driver); | ||
225 | } | ||
226 | |||
227 | module_init(pcips2_init); | ||
228 | module_exit(pcips2_exit); | ||
229 | 219 | ||
230 | MODULE_LICENSE("GPL"); | 220 | MODULE_LICENSE("GPL"); |
231 | MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); | 221 | MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); |
232 | MODULE_DESCRIPTION("PCI PS/2 keyboard/mouse driver"); | 222 | MODULE_DESCRIPTION("PCI PS/2 keyboard/mouse driver"); |
233 | MODULE_DEVICE_TABLE(pci, pcips2_ids); | ||
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c index 15aa81c9f1fb..a76fb64f03db 100644 --- a/drivers/input/serio/ps2mult.c +++ b/drivers/input/serio/ps2mult.c | |||
@@ -304,15 +304,4 @@ static struct serio_driver ps2mult_drv = { | |||
304 | .reconnect = ps2mult_reconnect, | 304 | .reconnect = ps2mult_reconnect, |
305 | }; | 305 | }; |
306 | 306 | ||
307 | static int __init ps2mult_init(void) | 307 | module_serio_driver(ps2mult_drv); |
308 | { | ||
309 | return serio_register_driver(&ps2mult_drv); | ||
310 | } | ||
311 | |||
312 | static void __exit ps2mult_exit(void) | ||
313 | { | ||
314 | serio_unregister_driver(&ps2mult_drv); | ||
315 | } | ||
316 | |||
317 | module_init(ps2mult_init); | ||
318 | module_exit(ps2mult_exit); | ||
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 4494233d331a..59df2e7317a3 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -165,31 +165,38 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, | |||
165 | struct serio_raw *serio_raw = client->serio_raw; | 165 | struct serio_raw *serio_raw = client->serio_raw; |
166 | char uninitialized_var(c); | 166 | char uninitialized_var(c); |
167 | ssize_t read = 0; | 167 | ssize_t read = 0; |
168 | int retval; | 168 | int error; |
169 | 169 | ||
170 | if (serio_raw->dead) | 170 | for (;;) { |
171 | return -ENODEV; | 171 | if (serio_raw->dead) |
172 | return -ENODEV; | ||
172 | 173 | ||
173 | if (serio_raw->head == serio_raw->tail && (file->f_flags & O_NONBLOCK)) | 174 | if (serio_raw->head == serio_raw->tail && |
174 | return -EAGAIN; | 175 | (file->f_flags & O_NONBLOCK)) |
176 | return -EAGAIN; | ||
175 | 177 | ||
176 | retval = wait_event_interruptible(serio_raw->wait, | 178 | if (count == 0) |
177 | serio_raw->head != serio_raw->tail || serio_raw->dead); | 179 | break; |
178 | if (retval) | ||
179 | return retval; | ||
180 | 180 | ||
181 | if (serio_raw->dead) | 181 | while (read < count && serio_raw_fetch_byte(serio_raw, &c)) { |
182 | return -ENODEV; | 182 | if (put_user(c, buffer++)) |
183 | return -EFAULT; | ||
184 | read++; | ||
185 | } | ||
183 | 186 | ||
184 | while (read < count && serio_raw_fetch_byte(serio_raw, &c)) { | 187 | if (read) |
185 | if (put_user(c, buffer++)) { | ||
186 | retval = -EFAULT; | ||
187 | break; | 188 | break; |
189 | |||
190 | if (!(file->f_flags & O_NONBLOCK)) { | ||
191 | error = wait_event_interruptible(serio_raw->wait, | ||
192 | serio_raw->head != serio_raw->tail || | ||
193 | serio_raw->dead); | ||
194 | if (error) | ||
195 | return error; | ||
188 | } | 196 | } |
189 | read++; | ||
190 | } | 197 | } |
191 | 198 | ||
192 | return read ?: retval; | 199 | return read; |
193 | } | 200 | } |
194 | 201 | ||
195 | static ssize_t serio_raw_write(struct file *file, const char __user *buffer, | 202 | static ssize_t serio_raw_write(struct file *file, const char __user *buffer, |
@@ -197,8 +204,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, | |||
197 | { | 204 | { |
198 | struct serio_raw_client *client = file->private_data; | 205 | struct serio_raw_client *client = file->private_data; |
199 | struct serio_raw *serio_raw = client->serio_raw; | 206 | struct serio_raw *serio_raw = client->serio_raw; |
200 | ssize_t written = 0; | 207 | int retval = 0; |
201 | int retval; | ||
202 | unsigned char c; | 208 | unsigned char c; |
203 | 209 | ||
204 | retval = mutex_lock_interruptible(&serio_raw_mutex); | 210 | retval = mutex_lock_interruptible(&serio_raw_mutex); |
@@ -218,16 +224,20 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer, | |||
218 | retval = -EFAULT; | 224 | retval = -EFAULT; |
219 | goto out; | 225 | goto out; |
220 | } | 226 | } |
227 | |||
221 | if (serio_write(serio_raw->serio, c)) { | 228 | if (serio_write(serio_raw->serio, c)) { |
222 | retval = -EIO; | 229 | /* Either signal error or partial write */ |
230 | if (retval == 0) | ||
231 | retval = -EIO; | ||
223 | goto out; | 232 | goto out; |
224 | } | 233 | } |
225 | written++; | 234 | |
235 | retval++; | ||
226 | } | 236 | } |
227 | 237 | ||
228 | out: | 238 | out: |
229 | mutex_unlock(&serio_raw_mutex); | 239 | mutex_unlock(&serio_raw_mutex); |
230 | return written ?: retval; | 240 | return retval; |
231 | } | 241 | } |
232 | 242 | ||
233 | static unsigned int serio_raw_poll(struct file *file, poll_table *wait) | 243 | static unsigned int serio_raw_poll(struct file *file, poll_table *wait) |
@@ -432,15 +442,4 @@ static struct serio_driver serio_raw_drv = { | |||
432 | .manual_bind = true, | 442 | .manual_bind = true, |
433 | }; | 443 | }; |
434 | 444 | ||
435 | static int __init serio_raw_init(void) | 445 | module_serio_driver(serio_raw_drv); |
436 | { | ||
437 | return serio_register_driver(&serio_raw_drv); | ||
438 | } | ||
439 | |||
440 | static void __exit serio_raw_exit(void) | ||
441 | { | ||
442 | serio_unregister_driver(&serio_raw_drv); | ||
443 | } | ||
444 | |||
445 | module_init(serio_raw_init); | ||
446 | module_exit(serio_raw_exit); | ||
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index d96d4c2a76a9..1e983bec7d86 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c | |||
@@ -73,7 +73,8 @@ struct xps2data { | |||
73 | spinlock_t lock; | 73 | spinlock_t lock; |
74 | void __iomem *base_address; /* virt. address of control registers */ | 74 | void __iomem *base_address; /* virt. address of control registers */ |
75 | unsigned int flags; | 75 | unsigned int flags; |
76 | struct serio serio; /* serio */ | 76 | struct serio *serio; /* serio */ |
77 | struct device *dev; | ||
77 | }; | 78 | }; |
78 | 79 | ||
79 | /************************************/ | 80 | /************************************/ |
@@ -119,7 +120,7 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id) | |||
119 | 120 | ||
120 | /* Check which interrupt is active */ | 121 | /* Check which interrupt is active */ |
121 | if (intr_sr & XPS2_IPIXR_RX_OVF) | 122 | if (intr_sr & XPS2_IPIXR_RX_OVF) |
122 | dev_warn(drvdata->serio.dev.parent, "receive overrun error\n"); | 123 | dev_warn(drvdata->dev, "receive overrun error\n"); |
123 | 124 | ||
124 | if (intr_sr & XPS2_IPIXR_RX_ERR) | 125 | if (intr_sr & XPS2_IPIXR_RX_ERR) |
125 | drvdata->flags |= SERIO_PARITY; | 126 | drvdata->flags |= SERIO_PARITY; |
@@ -132,10 +133,10 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id) | |||
132 | 133 | ||
133 | /* Error, if a byte is not received */ | 134 | /* Error, if a byte is not received */ |
134 | if (status) { | 135 | if (status) { |
135 | dev_err(drvdata->serio.dev.parent, | 136 | dev_err(drvdata->dev, |
136 | "wrong rcvd byte count (%d)\n", status); | 137 | "wrong rcvd byte count (%d)\n", status); |
137 | } else { | 138 | } else { |
138 | serio_interrupt(&drvdata->serio, c, drvdata->flags); | 139 | serio_interrupt(drvdata->serio, c, drvdata->flags); |
139 | drvdata->flags = 0; | 140 | drvdata->flags = 0; |
140 | } | 141 | } |
141 | } | 142 | } |
@@ -193,7 +194,7 @@ static int sxps2_open(struct serio *pserio) | |||
193 | error = request_irq(drvdata->irq, &xps2_interrupt, 0, | 194 | error = request_irq(drvdata->irq, &xps2_interrupt, 0, |
194 | DRIVER_NAME, drvdata); | 195 | DRIVER_NAME, drvdata); |
195 | if (error) { | 196 | if (error) { |
196 | dev_err(drvdata->serio.dev.parent, | 197 | dev_err(drvdata->dev, |
197 | "Couldn't allocate interrupt %d\n", drvdata->irq); | 198 | "Couldn't allocate interrupt %d\n", drvdata->irq); |
198 | return error; | 199 | return error; |
199 | } | 200 | } |
@@ -259,15 +260,16 @@ static int __devinit xps2_of_probe(struct platform_device *ofdev) | |||
259 | } | 260 | } |
260 | 261 | ||
261 | drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL); | 262 | drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL); |
262 | if (!drvdata) { | 263 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); |
263 | dev_err(dev, "Couldn't allocate device private record\n"); | 264 | if (!drvdata || !serio) { |
264 | return -ENOMEM; | 265 | error = -ENOMEM; |
266 | goto failed1; | ||
265 | } | 267 | } |
266 | 268 | ||
267 | dev_set_drvdata(dev, drvdata); | ||
268 | |||
269 | spin_lock_init(&drvdata->lock); | 269 | spin_lock_init(&drvdata->lock); |
270 | drvdata->irq = r_irq.start; | 270 | drvdata->irq = r_irq.start; |
271 | drvdata->serio = serio; | ||
272 | drvdata->dev = dev; | ||
271 | 273 | ||
272 | phys_addr = r_mem.start; | 274 | phys_addr = r_mem.start; |
273 | remap_size = resource_size(&r_mem); | 275 | remap_size = resource_size(&r_mem); |
@@ -298,7 +300,6 @@ static int __devinit xps2_of_probe(struct platform_device *ofdev) | |||
298 | (unsigned long long)phys_addr, drvdata->base_address, | 300 | (unsigned long long)phys_addr, drvdata->base_address, |
299 | drvdata->irq); | 301 | drvdata->irq); |
300 | 302 | ||
301 | serio = &drvdata->serio; | ||
302 | serio->id.type = SERIO_8042; | 303 | serio->id.type = SERIO_8042; |
303 | serio->write = sxps2_write; | 304 | serio->write = sxps2_write; |
304 | serio->open = sxps2_open; | 305 | serio->open = sxps2_open; |
@@ -312,13 +313,14 @@ static int __devinit xps2_of_probe(struct platform_device *ofdev) | |||
312 | 313 | ||
313 | serio_register_port(serio); | 314 | serio_register_port(serio); |
314 | 315 | ||
316 | platform_set_drvdata(ofdev, drvdata); | ||
315 | return 0; /* success */ | 317 | return 0; /* success */ |
316 | 318 | ||
317 | failed2: | 319 | failed2: |
318 | release_mem_region(phys_addr, remap_size); | 320 | release_mem_region(phys_addr, remap_size); |
319 | failed1: | 321 | failed1: |
322 | kfree(serio); | ||
320 | kfree(drvdata); | 323 | kfree(drvdata); |
321 | dev_set_drvdata(dev, NULL); | ||
322 | 324 | ||
323 | return error; | 325 | return error; |
324 | } | 326 | } |
@@ -333,22 +335,21 @@ failed1: | |||
333 | */ | 335 | */ |
334 | static int __devexit xps2_of_remove(struct platform_device *of_dev) | 336 | static int __devexit xps2_of_remove(struct platform_device *of_dev) |
335 | { | 337 | { |
336 | struct device *dev = &of_dev->dev; | 338 | struct xps2data *drvdata = platform_get_drvdata(of_dev); |
337 | struct xps2data *drvdata = dev_get_drvdata(dev); | ||
338 | struct resource r_mem; /* IO mem resources */ | 339 | struct resource r_mem; /* IO mem resources */ |
339 | 340 | ||
340 | serio_unregister_port(&drvdata->serio); | 341 | serio_unregister_port(drvdata->serio); |
341 | iounmap(drvdata->base_address); | 342 | iounmap(drvdata->base_address); |
342 | 343 | ||
343 | /* Get iospace of the device */ | 344 | /* Get iospace of the device */ |
344 | if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem)) | 345 | if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem)) |
345 | dev_err(dev, "invalid address\n"); | 346 | dev_err(drvdata->dev, "invalid address\n"); |
346 | else | 347 | else |
347 | release_mem_region(r_mem.start, resource_size(&r_mem)); | 348 | release_mem_region(r_mem.start, resource_size(&r_mem)); |
348 | 349 | ||
349 | kfree(drvdata); | 350 | kfree(drvdata); |
350 | 351 | ||
351 | dev_set_drvdata(dev, NULL); | 352 | platform_set_drvdata(of_dev, NULL); |
352 | 353 | ||
353 | return 0; | 354 | return 0; |
354 | } | 355 | } |
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 755a39e4c9e9..ee83c3904ee8 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
@@ -1862,7 +1862,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1862 | if (i == ARRAY_SIZE(speeds)) { | 1862 | if (i == ARRAY_SIZE(speeds)) { |
1863 | dev_info(&intf->dev, | 1863 | dev_info(&intf->dev, |
1864 | "Aiptek tried all speeds, no sane response\n"); | 1864 | "Aiptek tried all speeds, no sane response\n"); |
1865 | goto fail2; | 1865 | goto fail3; |
1866 | } | 1866 | } |
1867 | 1867 | ||
1868 | /* Associate this driver's struct with the usb interface. | 1868 | /* Associate this driver's struct with the usb interface. |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index b4842d0e61dd..b79d45198d82 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -135,6 +135,6 @@ extern const struct usb_device_id wacom_ids[]; | |||
135 | 135 | ||
136 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); | 136 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); |
137 | void wacom_setup_device_quirks(struct wacom_features *features); | 137 | void wacom_setup_device_quirks(struct wacom_features *features); |
138 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 138 | int wacom_setup_input_capabilities(struct input_dev *input_dev, |
139 | struct wacom_wac *wacom_wac); | 139 | struct wacom_wac *wacom_wac); |
140 | #endif | 140 | #endif |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 79a0509882d4..cad5602d3ce4 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #define HID_USAGE_Y_TILT 0x3e | 28 | #define HID_USAGE_Y_TILT 0x3e |
29 | #define HID_USAGE_FINGER 0x22 | 29 | #define HID_USAGE_FINGER 0x22 |
30 | #define HID_USAGE_STYLUS 0x20 | 30 | #define HID_USAGE_STYLUS 0x20 |
31 | #define HID_USAGE_CONTACTMAX 0x55 | ||
31 | #define HID_COLLECTION 0xa1 | 32 | #define HID_COLLECTION 0xa1 |
32 | #define HID_COLLECTION_LOGICAL 0x02 | 33 | #define HID_COLLECTION_LOGICAL 0x02 |
33 | #define HID_COLLECTION_END 0xc0 | 34 | #define HID_COLLECTION_END 0xc0 |
@@ -204,6 +205,27 @@ static int wacom_parse_logical_collection(unsigned char *report, | |||
204 | return length; | 205 | return length; |
205 | } | 206 | } |
206 | 207 | ||
208 | static void wacom_retrieve_report_data(struct usb_interface *intf, | ||
209 | struct wacom_features *features) | ||
210 | { | ||
211 | int result = 0; | ||
212 | unsigned char *rep_data; | ||
213 | |||
214 | rep_data = kmalloc(2, GFP_KERNEL); | ||
215 | if (rep_data) { | ||
216 | |||
217 | rep_data[0] = 12; | ||
218 | result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, | ||
219 | rep_data[0], &rep_data, 2, | ||
220 | WAC_MSG_RETRIES); | ||
221 | |||
222 | if (result >= 0 && rep_data[1] > 2) | ||
223 | features->touch_max = rep_data[1]; | ||
224 | |||
225 | kfree(rep_data); | ||
226 | } | ||
227 | } | ||
228 | |||
207 | /* | 229 | /* |
208 | * Interface Descriptor of wacom devices can be incomplete and | 230 | * Interface Descriptor of wacom devices can be incomplete and |
209 | * inconsistent so wacom_features table is used to store stylus | 231 | * inconsistent so wacom_features table is used to store stylus |
@@ -236,6 +258,9 @@ static int wacom_parse_logical_collection(unsigned char *report, | |||
236 | * 3rd gen Bamboo Touch no longer define a Digitizer-Finger Pysical | 258 | * 3rd gen Bamboo Touch no longer define a Digitizer-Finger Pysical |
237 | * Collection. Instead they define a Logical Collection with a single | 259 | * Collection. Instead they define a Logical Collection with a single |
238 | * Logical Maximum for both X and Y. | 260 | * Logical Maximum for both X and Y. |
261 | * | ||
262 | * Intuos5 touch interface does not contain useful data. We deal with | ||
263 | * this after returning from this function. | ||
239 | */ | 264 | */ |
240 | static int wacom_parse_hid(struct usb_interface *intf, | 265 | static int wacom_parse_hid(struct usb_interface *intf, |
241 | struct hid_descriptor *hid_desc, | 266 | struct hid_descriptor *hid_desc, |
@@ -295,6 +320,10 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
295 | /* need to reset back */ | 320 | /* need to reset back */ |
296 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 321 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
297 | } | 322 | } |
323 | |||
324 | if (features->type == MTSCREEN) | ||
325 | features->pktlen = WACOM_PKGLEN_MTOUCH; | ||
326 | |||
298 | if (features->type == BAMBOO_PT) { | 327 | if (features->type == BAMBOO_PT) { |
299 | /* need to reset back */ | 328 | /* need to reset back */ |
300 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | 329 | features->pktlen = WACOM_PKGLEN_BBTOUCH; |
@@ -327,18 +356,15 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
327 | case HID_USAGE_Y: | 356 | case HID_USAGE_Y: |
328 | if (usage == WCM_DESKTOP) { | 357 | if (usage == WCM_DESKTOP) { |
329 | if (finger) { | 358 | if (finger) { |
330 | features->device_type = BTN_TOOL_FINGER; | 359 | int type = features->type; |
331 | if (features->type == TABLETPC2FG) { | 360 | |
332 | /* need to reset back */ | 361 | if (type == TABLETPC2FG || type == MTSCREEN) { |
333 | features->pktlen = WACOM_PKGLEN_TPC2FG; | ||
334 | features->y_max = | 362 | features->y_max = |
335 | get_unaligned_le16(&report[i + 3]); | 363 | get_unaligned_le16(&report[i + 3]); |
336 | features->y_phy = | 364 | features->y_phy = |
337 | get_unaligned_le16(&report[i + 6]); | 365 | get_unaligned_le16(&report[i + 6]); |
338 | i += 7; | 366 | i += 7; |
339 | } else if (features->type == BAMBOO_PT) { | 367 | } else if (type == BAMBOO_PT) { |
340 | /* need to reset back */ | ||
341 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | ||
342 | features->y_phy = | 368 | features->y_phy = |
343 | get_unaligned_le16(&report[i + 3]); | 369 | get_unaligned_le16(&report[i + 3]); |
344 | features->y_max = | 370 | features->y_max = |
@@ -352,10 +378,6 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
352 | i += 4; | 378 | i += 4; |
353 | } | 379 | } |
354 | } else if (pen) { | 380 | } else if (pen) { |
355 | /* penabled only accepts exact bytes of data */ | ||
356 | if (features->type == TABLETPC2FG) | ||
357 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | ||
358 | features->device_type = BTN_TOOL_PEN; | ||
359 | features->y_max = | 381 | features->y_max = |
360 | get_unaligned_le16(&report[i + 3]); | 382 | get_unaligned_le16(&report[i + 3]); |
361 | i += 4; | 383 | i += 4; |
@@ -377,6 +399,11 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
377 | pen = 1; | 399 | pen = 1; |
378 | i++; | 400 | i++; |
379 | break; | 401 | break; |
402 | |||
403 | case HID_USAGE_CONTACTMAX: | ||
404 | wacom_retrieve_report_data(intf, features); | ||
405 | i++; | ||
406 | break; | ||
380 | } | 407 | } |
381 | break; | 408 | break; |
382 | 409 | ||
@@ -413,22 +440,29 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
413 | if (!rep_data) | 440 | if (!rep_data) |
414 | return error; | 441 | return error; |
415 | 442 | ||
416 | /* ask to report tablet data if it is MT Tablet PC or | 443 | /* ask to report Wacom data */ |
417 | * not a Tablet PC */ | 444 | if (features->device_type == BTN_TOOL_FINGER) { |
418 | if (features->type == TABLETPC2FG) { | 445 | /* if it is an MT Tablet PC touch */ |
419 | do { | 446 | if (features->type == TABLETPC2FG || |
420 | rep_data[0] = 3; | 447 | features->type == MTSCREEN) { |
421 | rep_data[1] = 4; | 448 | do { |
422 | rep_data[2] = 0; | 449 | rep_data[0] = 3; |
423 | rep_data[3] = 0; | 450 | rep_data[1] = 4; |
424 | report_id = 3; | 451 | rep_data[2] = 0; |
425 | error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, | 452 | rep_data[3] = 0; |
426 | report_id, rep_data, 4, 1); | 453 | report_id = 3; |
427 | if (error >= 0) | 454 | error = wacom_set_report(intf, |
428 | error = wacom_get_report(intf, | 455 | WAC_HID_FEATURE_REPORT, |
429 | WAC_HID_FEATURE_REPORT, | 456 | report_id, |
430 | report_id, rep_data, 4, 1); | 457 | rep_data, 4, 1); |
431 | } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES); | 458 | if (error >= 0) |
459 | error = wacom_get_report(intf, | ||
460 | WAC_HID_FEATURE_REPORT, | ||
461 | report_id, | ||
462 | rep_data, 4, 1); | ||
463 | } while ((error < 0 || rep_data[1] != 4) && | ||
464 | limit++ < WAC_MSG_RETRIES); | ||
465 | } | ||
432 | } else if (features->type != TABLETPC && | 466 | } else if (features->type != TABLETPC && |
433 | features->type != WIRELESS && | 467 | features->type != WIRELESS && |
434 | features->device_type == BTN_TOOL_PEN) { | 468 | features->device_type == BTN_TOOL_PEN) { |
@@ -450,7 +484,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
450 | } | 484 | } |
451 | 485 | ||
452 | static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | 486 | static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, |
453 | struct wacom_features *features) | 487 | struct wacom_features *features) |
454 | { | 488 | { |
455 | int error = 0; | 489 | int error = 0; |
456 | struct usb_host_interface *interface = intf->cur_altsetting; | 490 | struct usb_host_interface *interface = intf->cur_altsetting; |
@@ -478,16 +512,21 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
478 | } | 512 | } |
479 | } | 513 | } |
480 | 514 | ||
481 | /* only Tablet PCs and Bamboo P&T need to retrieve the info */ | 515 | /* only devices that support touch need to retrieve the info */ |
482 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && | 516 | if (features->type != TABLETPC && |
483 | (features->type != BAMBOO_PT)) | 517 | features->type != TABLETPC2FG && |
518 | features->type != BAMBOO_PT && | ||
519 | features->type != MTSCREEN) { | ||
484 | goto out; | 520 | goto out; |
521 | } | ||
485 | 522 | ||
486 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | 523 | error = usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc); |
487 | if (usb_get_extra_descriptor(&interface->endpoint[0], | 524 | if (error) { |
488 | HID_DEVICET_REPORT, &hid_desc)) { | 525 | error = usb_get_extra_descriptor(&interface->endpoint[0], |
489 | printk("wacom: can not retrieve extra class descriptor\n"); | 526 | HID_DEVICET_REPORT, &hid_desc); |
490 | error = 1; | 527 | if (error) { |
528 | dev_err(&intf->dev, | ||
529 | "can not retrieve extra class descriptor\n"); | ||
491 | goto out; | 530 | goto out; |
492 | } | 531 | } |
493 | } | 532 | } |
@@ -577,23 +616,39 @@ static void wacom_remove_shared_data(struct wacom_wac *wacom) | |||
577 | static int wacom_led_control(struct wacom *wacom) | 616 | static int wacom_led_control(struct wacom *wacom) |
578 | { | 617 | { |
579 | unsigned char *buf; | 618 | unsigned char *buf; |
580 | int retval, led = 0; | 619 | int retval; |
581 | 620 | ||
582 | buf = kzalloc(9, GFP_KERNEL); | 621 | buf = kzalloc(9, GFP_KERNEL); |
583 | if (!buf) | 622 | if (!buf) |
584 | return -ENOMEM; | 623 | return -ENOMEM; |
585 | 624 | ||
586 | if (wacom->wacom_wac.features.type == WACOM_21UX2 || | 625 | if (wacom->wacom_wac.features.type >= INTUOS5S && |
587 | wacom->wacom_wac.features.type == WACOM_24HD) | 626 | wacom->wacom_wac.features.type <= INTUOS5L) { |
588 | led = (wacom->led.select[1] << 4) | 0x40; | 627 | /* |
589 | 628 | * Touch Ring and crop mark LED luminance may take on | |
590 | led |= wacom->led.select[0] | 0x4; | 629 | * one of four values: |
591 | 630 | * 0 = Low; 1 = Medium; 2 = High; 3 = Off | |
592 | buf[0] = WAC_CMD_LED_CONTROL; | 631 | */ |
593 | buf[1] = led; | 632 | int ring_led = wacom->led.select[0] & 0x03; |
594 | buf[2] = wacom->led.llv; | 633 | int ring_lum = (((wacom->led.llv & 0x60) >> 5) - 1) & 0x03; |
595 | buf[3] = wacom->led.hlv; | 634 | int crop_lum = 0; |
596 | buf[4] = wacom->led.img_lum; | 635 | |
636 | buf[0] = WAC_CMD_LED_CONTROL; | ||
637 | buf[1] = (crop_lum << 4) | (ring_lum << 2) | (ring_led); | ||
638 | } | ||
639 | else { | ||
640 | int led = wacom->led.select[0] | 0x4; | ||
641 | |||
642 | if (wacom->wacom_wac.features.type == WACOM_21UX2 || | ||
643 | wacom->wacom_wac.features.type == WACOM_24HD) | ||
644 | led |= (wacom->led.select[1] << 4) | 0x40; | ||
645 | |||
646 | buf[0] = WAC_CMD_LED_CONTROL; | ||
647 | buf[1] = led; | ||
648 | buf[2] = wacom->led.llv; | ||
649 | buf[3] = wacom->led.hlv; | ||
650 | buf[4] = wacom->led.img_lum; | ||
651 | } | ||
597 | 652 | ||
598 | retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL, | 653 | retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL, |
599 | buf, 9, WAC_CMD_RETRIES); | 654 | buf, 9, WAC_CMD_RETRIES); |
@@ -786,6 +841,17 @@ static struct attribute_group intuos4_led_attr_group = { | |||
786 | .attrs = intuos4_led_attrs, | 841 | .attrs = intuos4_led_attrs, |
787 | }; | 842 | }; |
788 | 843 | ||
844 | static struct attribute *intuos5_led_attrs[] = { | ||
845 | &dev_attr_status0_luminance.attr, | ||
846 | &dev_attr_status_led0_select.attr, | ||
847 | NULL | ||
848 | }; | ||
849 | |||
850 | static struct attribute_group intuos5_led_attr_group = { | ||
851 | .name = "wacom_led", | ||
852 | .attrs = intuos5_led_attrs, | ||
853 | }; | ||
854 | |||
789 | static int wacom_initialize_leds(struct wacom *wacom) | 855 | static int wacom_initialize_leds(struct wacom *wacom) |
790 | { | 856 | { |
791 | int error; | 857 | int error; |
@@ -815,6 +881,19 @@ static int wacom_initialize_leds(struct wacom *wacom) | |||
815 | &cintiq_led_attr_group); | 881 | &cintiq_led_attr_group); |
816 | break; | 882 | break; |
817 | 883 | ||
884 | case INTUOS5S: | ||
885 | case INTUOS5: | ||
886 | case INTUOS5L: | ||
887 | wacom->led.select[0] = 0; | ||
888 | wacom->led.select[1] = 0; | ||
889 | wacom->led.llv = 32; | ||
890 | wacom->led.hlv = 0; | ||
891 | wacom->led.img_lum = 0; | ||
892 | |||
893 | error = sysfs_create_group(&wacom->intf->dev.kobj, | ||
894 | &intuos5_led_attr_group); | ||
895 | break; | ||
896 | |||
818 | default: | 897 | default: |
819 | return 0; | 898 | return 0; |
820 | } | 899 | } |
@@ -843,6 +922,13 @@ static void wacom_destroy_leds(struct wacom *wacom) | |||
843 | sysfs_remove_group(&wacom->intf->dev.kobj, | 922 | sysfs_remove_group(&wacom->intf->dev.kobj, |
844 | &cintiq_led_attr_group); | 923 | &cintiq_led_attr_group); |
845 | break; | 924 | break; |
925 | |||
926 | case INTUOS5S: | ||
927 | case INTUOS5: | ||
928 | case INTUOS5L: | ||
929 | sysfs_remove_group(&wacom->intf->dev.kobj, | ||
930 | &intuos5_led_attr_group); | ||
931 | break; | ||
846 | } | 932 | } |
847 | } | 933 | } |
848 | 934 | ||
@@ -904,8 +990,10 @@ static int wacom_register_input(struct wacom *wacom) | |||
904 | int error; | 990 | int error; |
905 | 991 | ||
906 | input_dev = input_allocate_device(); | 992 | input_dev = input_allocate_device(); |
907 | if (!input_dev) | 993 | if (!input_dev) { |
908 | return -ENOMEM; | 994 | error = -ENOMEM; |
995 | goto fail1; | ||
996 | } | ||
909 | 997 | ||
910 | input_dev->name = wacom_wac->name; | 998 | input_dev->name = wacom_wac->name; |
911 | input_dev->dev.parent = &intf->dev; | 999 | input_dev->dev.parent = &intf->dev; |
@@ -915,14 +1003,20 @@ static int wacom_register_input(struct wacom *wacom) | |||
915 | input_set_drvdata(input_dev, wacom); | 1003 | input_set_drvdata(input_dev, wacom); |
916 | 1004 | ||
917 | wacom_wac->input = input_dev; | 1005 | wacom_wac->input = input_dev; |
918 | wacom_setup_input_capabilities(input_dev, wacom_wac); | 1006 | error = wacom_setup_input_capabilities(input_dev, wacom_wac); |
1007 | if (error) | ||
1008 | goto fail1; | ||
919 | 1009 | ||
920 | error = input_register_device(input_dev); | 1010 | error = input_register_device(input_dev); |
921 | if (error) { | 1011 | if (error) |
922 | input_free_device(input_dev); | 1012 | goto fail2; |
923 | wacom_wac->input = NULL; | ||
924 | } | ||
925 | 1013 | ||
1014 | return 0; | ||
1015 | |||
1016 | fail2: | ||
1017 | input_free_device(input_dev); | ||
1018 | wacom_wac->input = NULL; | ||
1019 | fail1: | ||
926 | return error; | 1020 | return error; |
927 | } | 1021 | } |
928 | 1022 | ||
@@ -941,22 +1035,22 @@ static void wacom_wireless_work(struct work_struct *work) | |||
941 | wacom = usb_get_intfdata(usbdev->config->interface[1]); | 1035 | wacom = usb_get_intfdata(usbdev->config->interface[1]); |
942 | if (wacom->wacom_wac.input) | 1036 | if (wacom->wacom_wac.input) |
943 | input_unregister_device(wacom->wacom_wac.input); | 1037 | input_unregister_device(wacom->wacom_wac.input); |
944 | wacom->wacom_wac.input = 0; | 1038 | wacom->wacom_wac.input = NULL; |
945 | 1039 | ||
946 | /* Touch interface */ | 1040 | /* Touch interface */ |
947 | wacom = usb_get_intfdata(usbdev->config->interface[2]); | 1041 | wacom = usb_get_intfdata(usbdev->config->interface[2]); |
948 | if (wacom->wacom_wac.input) | 1042 | if (wacom->wacom_wac.input) |
949 | input_unregister_device(wacom->wacom_wac.input); | 1043 | input_unregister_device(wacom->wacom_wac.input); |
950 | wacom->wacom_wac.input = 0; | 1044 | wacom->wacom_wac.input = NULL; |
951 | 1045 | ||
952 | if (wacom_wac->pid == 0) { | 1046 | if (wacom_wac->pid == 0) { |
953 | printk(KERN_INFO "wacom: wireless tablet disconnected\n"); | 1047 | dev_info(&wacom->intf->dev, "wireless tablet disconnected\n"); |
954 | } else { | 1048 | } else { |
955 | const struct usb_device_id *id = wacom_ids; | 1049 | const struct usb_device_id *id = wacom_ids; |
956 | 1050 | ||
957 | printk(KERN_INFO | 1051 | dev_info(&wacom->intf->dev, |
958 | "wacom: wireless tablet connected with PID %x\n", | 1052 | "wireless tablet connected with PID %x\n", |
959 | wacom_wac->pid); | 1053 | wacom_wac->pid); |
960 | 1054 | ||
961 | while (id->match_flags) { | 1055 | while (id->match_flags) { |
962 | if (id->idVendor == USB_VENDOR_ID_WACOM && | 1056 | if (id->idVendor == USB_VENDOR_ID_WACOM && |
@@ -966,8 +1060,8 @@ static void wacom_wireless_work(struct work_struct *work) | |||
966 | } | 1060 | } |
967 | 1061 | ||
968 | if (!id->match_flags) { | 1062 | if (!id->match_flags) { |
969 | printk(KERN_INFO | 1063 | dev_info(&wacom->intf->dev, |
970 | "wacom: ignorning unknown PID.\n"); | 1064 | "ignoring unknown PID.\n"); |
971 | return; | 1065 | return; |
972 | } | 1066 | } |
973 | 1067 | ||
@@ -1038,11 +1132,33 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1038 | 1132 | ||
1039 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 1133 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
1040 | 1134 | ||
1041 | /* Retrieve the physical and logical size for OEM devices */ | 1135 | /* Retrieve the physical and logical size for touch devices */ |
1042 | error = wacom_retrieve_hid_descriptor(intf, features); | 1136 | error = wacom_retrieve_hid_descriptor(intf, features); |
1043 | if (error) | 1137 | if (error) |
1044 | goto fail3; | 1138 | goto fail3; |
1045 | 1139 | ||
1140 | /* | ||
1141 | * Intuos5 has no useful data about its touch interface in its | ||
1142 | * HID descriptor. If this is the touch interface (wMaxPacketSize | ||
1143 | * of WACOM_PKGLEN_BBTOUCH3), override the table values. | ||
1144 | */ | ||
1145 | if (features->type >= INTUOS5S && features->type <= INTUOS5L) { | ||
1146 | if (endpoint->wMaxPacketSize == WACOM_PKGLEN_BBTOUCH3) { | ||
1147 | features->device_type = BTN_TOOL_FINGER; | ||
1148 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; | ||
1149 | |||
1150 | features->x_phy = | ||
1151 | (features->x_max * 100) / features->x_resolution; | ||
1152 | features->y_phy = | ||
1153 | (features->y_max * 100) / features->y_resolution; | ||
1154 | |||
1155 | features->x_max = 4096; | ||
1156 | features->y_max = 4096; | ||
1157 | } else { | ||
1158 | features->device_type = BTN_TOOL_PEN; | ||
1159 | } | ||
1160 | } | ||
1161 | |||
1046 | wacom_setup_device_quirks(features); | 1162 | wacom_setup_device_quirks(features); |
1047 | 1163 | ||
1048 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); | 1164 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index b327790e9a0c..004bc1bb1544 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -61,7 +61,8 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom) | |||
61 | break; | 61 | break; |
62 | 62 | ||
63 | default: | 63 | default: |
64 | printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); | 64 | dev_dbg(input->dev.parent, |
65 | "%s: received unknown report #%d\n", __func__, data[0]); | ||
65 | return 0; | 66 | return 0; |
66 | } | 67 | } |
67 | 68 | ||
@@ -76,8 +77,8 @@ static int wacom_pl_irq(struct wacom_wac *wacom) | |||
76 | int prox, pressure; | 77 | int prox, pressure; |
77 | 78 | ||
78 | if (data[0] != WACOM_REPORT_PENABLED) { | 79 | if (data[0] != WACOM_REPORT_PENABLED) { |
79 | dev_dbg(&input->dev, | 80 | dev_dbg(input->dev.parent, |
80 | "wacom_pl_irq: received unknown report #%d\n", data[0]); | 81 | "%s: received unknown report #%d\n", __func__, data[0]); |
81 | return 0; | 82 | return 0; |
82 | } | 83 | } |
83 | 84 | ||
@@ -147,7 +148,8 @@ static int wacom_ptu_irq(struct wacom_wac *wacom) | |||
147 | struct input_dev *input = wacom->input; | 148 | struct input_dev *input = wacom->input; |
148 | 149 | ||
149 | if (data[0] != WACOM_REPORT_PENABLED) { | 150 | if (data[0] != WACOM_REPORT_PENABLED) { |
150 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); | 151 | dev_dbg(input->dev.parent, |
152 | "%s: received unknown report #%d\n", __func__, data[0]); | ||
151 | return 0; | 153 | return 0; |
152 | } | 154 | } |
153 | 155 | ||
@@ -176,7 +178,8 @@ static int wacom_dtu_irq(struct wacom_wac *wacom) | |||
176 | struct input_dev *input = wacom->input; | 178 | struct input_dev *input = wacom->input; |
177 | int prox = data[1] & 0x20, pressure; | 179 | int prox = data[1] & 0x20, pressure; |
178 | 180 | ||
179 | dev_dbg(&input->dev, "wacom_dtu_irq: received report #%d\n", data[0]); | 181 | dev_dbg(input->dev.parent, |
182 | "%s: received report #%d", __func__, data[0]); | ||
180 | 183 | ||
181 | if (prox) { | 184 | if (prox) { |
182 | /* Going into proximity select tool */ | 185 | /* Going into proximity select tool */ |
@@ -212,9 +215,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) | |||
212 | int retval = 0; | 215 | int retval = 0; |
213 | 216 | ||
214 | if (data[0] != WACOM_REPORT_PENABLED) { | 217 | if (data[0] != WACOM_REPORT_PENABLED) { |
215 | dev_dbg(&input->dev, | 218 | dev_dbg(input->dev.parent, |
216 | "wacom_graphire_irq: received unknown report #%d\n", | 219 | "%s: received unknown report #%d\n", __func__, data[0]); |
217 | data[0]); | ||
218 | goto exit; | 220 | goto exit; |
219 | } | 221 | } |
220 | 222 | ||
@@ -324,6 +326,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
324 | 326 | ||
325 | /* Enter report */ | 327 | /* Enter report */ |
326 | if ((data[1] & 0xfc) == 0xc0) { | 328 | if ((data[1] & 0xfc) == 0xc0) { |
329 | if (features->type >= INTUOS5S && features->type <= INTUOS5L) | ||
330 | wacom->shared->stylus_in_proximity = true; | ||
331 | |||
327 | /* serial number of the tool */ | 332 | /* serial number of the tool */ |
328 | wacom->serial[idx] = ((data[3] & 0x0f) << 28) + | 333 | wacom->serial[idx] = ((data[3] & 0x0f) << 28) + |
329 | (data[4] << 20) + (data[5] << 12) + | 334 | (data[4] << 20) + (data[5] << 12) + |
@@ -409,6 +414,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
409 | 414 | ||
410 | /* Exit report */ | 415 | /* Exit report */ |
411 | if ((data[1] & 0xfe) == 0x80) { | 416 | if ((data[1] & 0xfe) == 0x80) { |
417 | if (features->type >= INTUOS5S && features->type <= INTUOS5L) | ||
418 | wacom->shared->stylus_in_proximity = false; | ||
419 | |||
412 | /* | 420 | /* |
413 | * Reset all states otherwise we lose the initial states | 421 | * Reset all states otherwise we lose the initial states |
414 | * when in-prox next time | 422 | * when in-prox next time |
@@ -455,6 +463,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom) | |||
455 | if ((data[1] & 0xb8) == 0xa0) { | 463 | if ((data[1] & 0xb8) == 0xa0) { |
456 | t = (data[6] << 2) | ((data[7] >> 6) & 3); | 464 | t = (data[6] << 2) | ((data[7] >> 6) & 3); |
457 | if ((features->type >= INTUOS4S && features->type <= INTUOS4L) || | 465 | if ((features->type >= INTUOS4S && features->type <= INTUOS4L) || |
466 | (features->type >= INTUOS5S && features->type <= INTUOS5L) || | ||
458 | features->type == WACOM_21UX2 || features->type == WACOM_24HD) { | 467 | features->type == WACOM_21UX2 || features->type == WACOM_24HD) { |
459 | t = (t << 1) | (data[1] & 1); | 468 | t = (t << 1) | (data[1] & 1); |
460 | } | 469 | } |
@@ -485,11 +494,13 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
485 | unsigned int t; | 494 | unsigned int t; |
486 | int idx = 0, result; | 495 | int idx = 0, result; |
487 | 496 | ||
488 | if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_INTUOSREAD | 497 | if (data[0] != WACOM_REPORT_PENABLED && |
489 | && data[0] != WACOM_REPORT_INTUOSWRITE && data[0] != WACOM_REPORT_INTUOSPAD) { | 498 | data[0] != WACOM_REPORT_INTUOSREAD && |
490 | dev_dbg(&input->dev, | 499 | data[0] != WACOM_REPORT_INTUOSWRITE && |
491 | "wacom_intuos_irq: received unknown report #%d\n", | 500 | data[0] != WACOM_REPORT_INTUOSPAD && |
492 | data[0]); | 501 | data[0] != WACOM_REPORT_INTUOS5PAD) { |
502 | dev_dbg(input->dev.parent, | ||
503 | "%s: received unknown report #%d\n", __func__, data[0]); | ||
493 | return 0; | 504 | return 0; |
494 | } | 505 | } |
495 | 506 | ||
@@ -498,7 +509,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
498 | idx = data[1] & 0x01; | 509 | idx = data[1] & 0x01; |
499 | 510 | ||
500 | /* pad packets. Works as a second tool and is always in prox */ | 511 | /* pad packets. Works as a second tool and is always in prox */ |
501 | if (data[0] == WACOM_REPORT_INTUOSPAD) { | 512 | if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD) { |
502 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { | 513 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
503 | input_report_key(input, BTN_0, (data[2] & 0x01)); | 514 | input_report_key(input, BTN_0, (data[2] & 0x01)); |
504 | input_report_key(input, BTN_1, (data[3] & 0x01)); | 515 | input_report_key(input, BTN_1, (data[3] & 0x01)); |
@@ -574,6 +585,34 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
574 | input_report_key(input, wacom->tool[1], 0); | 585 | input_report_key(input, wacom->tool[1], 0); |
575 | input_report_abs(input, ABS_MISC, 0); | 586 | input_report_abs(input, ABS_MISC, 0); |
576 | } | 587 | } |
588 | } else if (features->type >= INTUOS5S && features->type <= INTUOS5L) { | ||
589 | int i; | ||
590 | |||
591 | /* Touch ring mode switch has no capacitive sensor */ | ||
592 | input_report_key(input, BTN_0, (data[3] & 0x01)); | ||
593 | |||
594 | /* | ||
595 | * ExpressKeys on Intuos5 have a capacitive sensor in | ||
596 | * addition to the mechanical switch. Switch data is | ||
597 | * stored in data[4], capacitive data in data[5]. | ||
598 | */ | ||
599 | for (i = 0; i < 8; i++) | ||
600 | input_report_key(input, BTN_1 + i, data[4] & (1 << i)); | ||
601 | |||
602 | if (data[2] & 0x80) { | ||
603 | input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f)); | ||
604 | } else { | ||
605 | /* Out of proximity, clear wheel value. */ | ||
606 | input_report_abs(input, ABS_WHEEL, 0); | ||
607 | } | ||
608 | |||
609 | if (data[2] | (data[3] & 0x01) | data[4]) { | ||
610 | input_report_key(input, wacom->tool[1], 1); | ||
611 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
612 | } else { | ||
613 | input_report_key(input, wacom->tool[1], 0); | ||
614 | input_report_abs(input, ABS_MISC, 0); | ||
615 | } | ||
577 | } else { | 616 | } else { |
578 | if (features->type == WACOM_21UX2) { | 617 | if (features->type == WACOM_21UX2) { |
579 | input_report_key(input, BTN_0, (data[5] & 0x01)); | 618 | input_report_key(input, BTN_0, (data[5] & 0x01)); |
@@ -637,7 +676,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
637 | (features->type == INTUOS3 || | 676 | (features->type == INTUOS3 || |
638 | features->type == INTUOS3S || | 677 | features->type == INTUOS3S || |
639 | features->type == INTUOS4 || | 678 | features->type == INTUOS4 || |
640 | features->type == INTUOS4S)) { | 679 | features->type == INTUOS4S || |
680 | features->type == INTUOS5 || | ||
681 | features->type == INTUOS5S)) { | ||
641 | 682 | ||
642 | return 0; | 683 | return 0; |
643 | } | 684 | } |
@@ -690,7 +731,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
690 | 731 | ||
691 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { | 732 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { |
692 | /* I4 mouse */ | 733 | /* I4 mouse */ |
693 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { | 734 | if ((features->type >= INTUOS4S && features->type <= INTUOS4L) || |
735 | (features->type >= INTUOS5S && features->type <= INTUOS5L)) { | ||
694 | input_report_key(input, BTN_LEFT, data[6] & 0x01); | 736 | input_report_key(input, BTN_LEFT, data[6] & 0x01); |
695 | input_report_key(input, BTN_MIDDLE, data[6] & 0x02); | 737 | input_report_key(input, BTN_MIDDLE, data[6] & 0x02); |
696 | input_report_key(input, BTN_RIGHT, data[6] & 0x04); | 738 | input_report_key(input, BTN_RIGHT, data[6] & 0x04); |
@@ -717,7 +759,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
717 | } | 759 | } |
718 | } | 760 | } |
719 | } else if ((features->type < INTUOS3S || features->type == INTUOS3L || | 761 | } else if ((features->type < INTUOS3S || features->type == INTUOS3L || |
720 | features->type == INTUOS4L) && | 762 | features->type == INTUOS4L || features->type == INTUOS5L) && |
721 | wacom->tool[idx] == BTN_TOOL_LENS) { | 763 | wacom->tool[idx] == BTN_TOOL_LENS) { |
722 | /* Lens cursor packets */ | 764 | /* Lens cursor packets */ |
723 | input_report_key(input, BTN_LEFT, data[8] & 0x01); | 765 | input_report_key(input, BTN_LEFT, data[8] & 0x01); |
@@ -734,6 +776,72 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
734 | return 1; | 776 | return 1; |
735 | } | 777 | } |
736 | 778 | ||
779 | static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid) | ||
780 | { | ||
781 | int touch_max = wacom->features.touch_max; | ||
782 | int i; | ||
783 | |||
784 | if (!wacom->slots) | ||
785 | return -1; | ||
786 | |||
787 | for (i = 0; i < touch_max; ++i) { | ||
788 | if (wacom->slots[i] == contactid) | ||
789 | return i; | ||
790 | } | ||
791 | for (i = 0; i < touch_max; ++i) { | ||
792 | if (wacom->slots[i] == -1) | ||
793 | return i; | ||
794 | } | ||
795 | return -1; | ||
796 | } | ||
797 | |||
798 | static int wacom_mt_touch(struct wacom_wac *wacom) | ||
799 | { | ||
800 | struct input_dev *input = wacom->input; | ||
801 | char *data = wacom->data; | ||
802 | int i; | ||
803 | int current_num_contacts = data[2]; | ||
804 | int contacts_to_send = 0; | ||
805 | |||
806 | /* | ||
807 | * First packet resets the counter since only the first | ||
808 | * packet in series will have non-zero current_num_contacts. | ||
809 | */ | ||
810 | if (current_num_contacts) | ||
811 | wacom->num_contacts_left = current_num_contacts; | ||
812 | |||
813 | /* There are at most 5 contacts per packet */ | ||
814 | contacts_to_send = min(5, wacom->num_contacts_left); | ||
815 | |||
816 | for (i = 0; i < contacts_to_send; i++) { | ||
817 | int offset = (WACOM_BYTES_PER_MT_PACKET * i) + 3; | ||
818 | bool touch = data[offset] & 0x1; | ||
819 | int id = le16_to_cpup((__le16 *)&data[offset + 1]); | ||
820 | int slot = find_slot_from_contactid(wacom, id); | ||
821 | |||
822 | if (slot < 0) | ||
823 | continue; | ||
824 | |||
825 | input_mt_slot(input, slot); | ||
826 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | ||
827 | if (touch) { | ||
828 | int x = le16_to_cpup((__le16 *)&data[offset + 7]); | ||
829 | int y = le16_to_cpup((__le16 *)&data[offset + 9]); | ||
830 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
831 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
832 | } | ||
833 | wacom->slots[slot] = touch ? id : -1; | ||
834 | } | ||
835 | |||
836 | input_mt_report_pointer_emulation(input, true); | ||
837 | |||
838 | wacom->num_contacts_left -= contacts_to_send; | ||
839 | if (wacom->num_contacts_left < 0) | ||
840 | wacom->num_contacts_left = 0; | ||
841 | |||
842 | return 1; | ||
843 | } | ||
844 | |||
737 | static int wacom_tpc_mt_touch(struct wacom_wac *wacom) | 845 | static int wacom_tpc_mt_touch(struct wacom_wac *wacom) |
738 | { | 846 | { |
739 | struct input_dev *input = wacom->input; | 847 | struct input_dev *input = wacom->input; |
@@ -772,6 +880,9 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) | |||
772 | bool prox; | 880 | bool prox; |
773 | int x = 0, y = 0; | 881 | int x = 0, y = 0; |
774 | 882 | ||
883 | if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG) | ||
884 | return 0; | ||
885 | |||
775 | if (!wacom->shared->stylus_in_proximity) { | 886 | if (!wacom->shared->stylus_in_proximity) { |
776 | if (len == WACOM_PKGLEN_TPC1FG) { | 887 | if (len == WACOM_PKGLEN_TPC1FG) { |
777 | prox = data[0] & 0x01; | 888 | prox = data[0] & 0x01; |
@@ -835,15 +946,15 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
835 | { | 946 | { |
836 | char *data = wacom->data; | 947 | char *data = wacom->data; |
837 | 948 | ||
838 | dev_dbg(&wacom->input->dev, "wacom_tpc_irq: received report #%d\n", | 949 | dev_dbg(wacom->input->dev.parent, |
839 | data[0]); | 950 | "%s: received report #%d\n", __func__, data[0]); |
840 | 951 | ||
841 | switch (len) { | 952 | switch (len) { |
842 | case WACOM_PKGLEN_TPC1FG: | 953 | case WACOM_PKGLEN_TPC1FG: |
843 | return wacom_tpc_single_touch(wacom, len); | 954 | return wacom_tpc_single_touch(wacom, len); |
844 | 955 | ||
845 | case WACOM_PKGLEN_TPC2FG: | 956 | case WACOM_PKGLEN_TPC2FG: |
846 | return wacom_tpc_mt_touch(wacom); | 957 | return wacom_tpc_mt_touch(wacom); |
847 | 958 | ||
848 | default: | 959 | default: |
849 | switch (data[0]) { | 960 | switch (data[0]) { |
@@ -852,6 +963,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
852 | case WACOM_REPORT_TPCST: | 963 | case WACOM_REPORT_TPCST: |
853 | return wacom_tpc_single_touch(wacom, len); | 964 | return wacom_tpc_single_touch(wacom, len); |
854 | 965 | ||
966 | case WACOM_REPORT_TPCMT: | ||
967 | return wacom_mt_touch(wacom); | ||
968 | |||
855 | case WACOM_REPORT_PENABLED: | 969 | case WACOM_REPORT_PENABLED: |
856 | return wacom_tpc_pen(wacom); | 970 | return wacom_tpc_pen(wacom); |
857 | } | 971 | } |
@@ -1120,8 +1234,18 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1120 | sync = wacom_intuos_irq(wacom_wac); | 1234 | sync = wacom_intuos_irq(wacom_wac); |
1121 | break; | 1235 | break; |
1122 | 1236 | ||
1237 | case INTUOS5S: | ||
1238 | case INTUOS5: | ||
1239 | case INTUOS5L: | ||
1240 | if (len == WACOM_PKGLEN_BBTOUCH3) | ||
1241 | sync = wacom_bpt3_touch(wacom_wac); | ||
1242 | else | ||
1243 | sync = wacom_intuos_irq(wacom_wac); | ||
1244 | break; | ||
1245 | |||
1123 | case TABLETPC: | 1246 | case TABLETPC: |
1124 | case TABLETPC2FG: | 1247 | case TABLETPC2FG: |
1248 | case MTSCREEN: | ||
1125 | sync = wacom_tpc_irq(wacom_wac, len); | 1249 | sync = wacom_tpc_irq(wacom_wac, len); |
1126 | break; | 1250 | break; |
1127 | 1251 | ||
@@ -1194,7 +1318,9 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
1194 | 1318 | ||
1195 | /* these device have multiple inputs */ | 1319 | /* these device have multiple inputs */ |
1196 | if (features->type == TABLETPC || features->type == TABLETPC2FG || | 1320 | if (features->type == TABLETPC || features->type == TABLETPC2FG || |
1197 | features->type == BAMBOO_PT || features->type == WIRELESS) | 1321 | features->type == BAMBOO_PT || features->type == WIRELESS || |
1322 | (features->type >= INTUOS5S && features->type <= INTUOS5L) || | ||
1323 | features->type == MTSCREEN) | ||
1198 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | 1324 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; |
1199 | 1325 | ||
1200 | /* quirk for bamboo touch with 2 low res touches */ | 1326 | /* quirk for bamboo touch with 2 low res touches */ |
@@ -1225,8 +1351,8 @@ static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | |||
1225 | return (logical_max * 100) / physical_max; | 1351 | return (logical_max * 100) / physical_max; |
1226 | } | 1352 | } |
1227 | 1353 | ||
1228 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 1354 | int wacom_setup_input_capabilities(struct input_dev *input_dev, |
1229 | struct wacom_wac *wacom_wac) | 1355 | struct wacom_wac *wacom_wac) |
1230 | { | 1356 | { |
1231 | struct wacom_features *features = &wacom_wac->features; | 1357 | struct wacom_features *features = &wacom_wac->features; |
1232 | int i; | 1358 | int i; |
@@ -1361,6 +1487,50 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1361 | wacom_setup_intuos(wacom_wac); | 1487 | wacom_setup_intuos(wacom_wac); |
1362 | break; | 1488 | break; |
1363 | 1489 | ||
1490 | case INTUOS5: | ||
1491 | case INTUOS5L: | ||
1492 | if (features->device_type == BTN_TOOL_PEN) { | ||
1493 | __set_bit(BTN_7, input_dev->keybit); | ||
1494 | __set_bit(BTN_8, input_dev->keybit); | ||
1495 | } | ||
1496 | /* fall through */ | ||
1497 | |||
1498 | case INTUOS5S: | ||
1499 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
1500 | |||
1501 | if (features->device_type == BTN_TOOL_PEN) { | ||
1502 | for (i = 0; i < 7; i++) | ||
1503 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
1504 | |||
1505 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, | ||
1506 | features->distance_max, | ||
1507 | 0, 0); | ||
1508 | |||
1509 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
1510 | |||
1511 | wacom_setup_intuos(wacom_wac); | ||
1512 | } else if (features->device_type == BTN_TOOL_FINGER) { | ||
1513 | __clear_bit(ABS_MISC, input_dev->absbit); | ||
1514 | |||
1515 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1516 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1517 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
1518 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | ||
1519 | |||
1520 | input_mt_init_slots(input_dev, features->touch_max); | ||
1521 | |||
1522 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
1523 | 0, 255, 0, 0); | ||
1524 | |||
1525 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1526 | 0, features->x_max, | ||
1527 | features->x_fuzz, 0); | ||
1528 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1529 | 0, features->y_max, | ||
1530 | features->y_fuzz, 0); | ||
1531 | } | ||
1532 | break; | ||
1533 | |||
1364 | case INTUOS4: | 1534 | case INTUOS4: |
1365 | case INTUOS4L: | 1535 | case INTUOS4L: |
1366 | __set_bit(BTN_7, input_dev->keybit); | 1536 | __set_bit(BTN_7, input_dev->keybit); |
@@ -1378,9 +1548,19 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1378 | break; | 1548 | break; |
1379 | 1549 | ||
1380 | case TABLETPC2FG: | 1550 | case TABLETPC2FG: |
1551 | case MTSCREEN: | ||
1381 | if (features->device_type == BTN_TOOL_FINGER) { | 1552 | if (features->device_type == BTN_TOOL_FINGER) { |
1382 | 1553 | ||
1383 | input_mt_init_slots(input_dev, 2); | 1554 | wacom_wac->slots = kmalloc(features->touch_max * |
1555 | sizeof(int), | ||
1556 | GFP_KERNEL); | ||
1557 | if (!wacom_wac->slots) | ||
1558 | return -ENOMEM; | ||
1559 | |||
1560 | for (i = 0; i < features->touch_max; i++) | ||
1561 | wacom_wac->slots[i] = -1; | ||
1562 | |||
1563 | input_mt_init_slots(input_dev, features->touch_max); | ||
1384 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, | 1564 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, |
1385 | 0, MT_TOOL_MAX, 0, 0); | 1565 | 0, MT_TOOL_MAX, 0, 0); |
1386 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1566 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
@@ -1435,6 +1615,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1435 | 1615 | ||
1436 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 1616 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
1437 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | 1617 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); |
1618 | input_mt_init_slots(input_dev, features->touch_max); | ||
1438 | 1619 | ||
1439 | if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { | 1620 | if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { |
1440 | __set_bit(BTN_TOOL_TRIPLETAP, | 1621 | __set_bit(BTN_TOOL_TRIPLETAP, |
@@ -1442,13 +1623,9 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1442 | __set_bit(BTN_TOOL_QUADTAP, | 1623 | __set_bit(BTN_TOOL_QUADTAP, |
1443 | input_dev->keybit); | 1624 | input_dev->keybit); |
1444 | 1625 | ||
1445 | input_mt_init_slots(input_dev, 16); | ||
1446 | |||
1447 | input_set_abs_params(input_dev, | 1626 | input_set_abs_params(input_dev, |
1448 | ABS_MT_TOUCH_MAJOR, | 1627 | ABS_MT_TOUCH_MAJOR, |
1449 | 0, 255, 0, 0); | 1628 | 0, 255, 0, 0); |
1450 | } else { | ||
1451 | input_mt_init_slots(input_dev, 2); | ||
1452 | } | 1629 | } |
1453 | 1630 | ||
1454 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1631 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
@@ -1468,6 +1645,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1468 | } | 1645 | } |
1469 | break; | 1646 | break; |
1470 | } | 1647 | } |
1648 | return 0; | ||
1471 | } | 1649 | } |
1472 | 1650 | ||
1473 | static const struct wacom_features wacom_features_0x00 = | 1651 | static const struct wacom_features wacom_features_0x00 = |
@@ -1635,6 +1813,24 @@ static const struct wacom_features wacom_features_0xBB = | |||
1635 | static const struct wacom_features wacom_features_0xBC = | 1813 | static const struct wacom_features wacom_features_0xBC = |
1636 | { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, | 1814 | { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, |
1637 | 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1815 | 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
1816 | static const struct wacom_features wacom_features_0x26 = | ||
1817 | { "Wacom Intuos5 touch S", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, | ||
1818 | 63, INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
1819 | .touch_max = 16 }; | ||
1820 | static const struct wacom_features wacom_features_0x27 = | ||
1821 | { "Wacom Intuos5 touch M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, | ||
1822 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
1823 | .touch_max = 16 }; | ||
1824 | static const struct wacom_features wacom_features_0x28 = | ||
1825 | { "Wacom Intuos5 touch L", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, | ||
1826 | 63, INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
1827 | .touch_max = 16 }; | ||
1828 | static const struct wacom_features wacom_features_0x29 = | ||
1829 | { "Wacom Intuos5 S", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, | ||
1830 | 63, INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1831 | static const struct wacom_features wacom_features_0x2A = | ||
1832 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, | ||
1833 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1638 | static const struct wacom_features wacom_features_0xF4 = | 1834 | static const struct wacom_features wacom_features_0xF4 = |
1639 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | 1835 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, |
1640 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1836 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
@@ -1676,13 +1872,19 @@ static const struct wacom_features wacom_features_0x9F = | |||
1676 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1872 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
1677 | static const struct wacom_features wacom_features_0xE2 = | 1873 | static const struct wacom_features wacom_features_0xE2 = |
1678 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, | 1874 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, |
1679 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1875 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1876 | .touch_max = 2 }; | ||
1680 | static const struct wacom_features wacom_features_0xE3 = | 1877 | static const struct wacom_features wacom_features_0xE3 = |
1681 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, | 1878 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, |
1682 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1879 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1880 | .touch_max = 2 }; | ||
1881 | static const struct wacom_features wacom_features_0xE5 = | ||
1882 | { "Wacom ISDv4 E5", WACOM_PKGLEN_MTOUCH, 26202, 16325, 255, | ||
1883 | 0, MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1683 | static const struct wacom_features wacom_features_0xE6 = | 1884 | static const struct wacom_features wacom_features_0xE6 = |
1684 | { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, | 1885 | { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, |
1685 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1886 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1887 | .touch_max = 2 }; | ||
1686 | static const struct wacom_features wacom_features_0xEC = | 1888 | static const struct wacom_features wacom_features_0xEC = |
1687 | { "Wacom ISDv4 EC", WACOM_PKGLEN_GRAPHIRE, 25710, 14500, 255, | 1889 | { "Wacom ISDv4 EC", WACOM_PKGLEN_GRAPHIRE, 25710, 14500, 255, |
1688 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1890 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -1691,19 +1893,22 @@ static const struct wacom_features wacom_features_0x47 = | |||
1691 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1893 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
1692 | static const struct wacom_features wacom_features_0x84 = | 1894 | static const struct wacom_features wacom_features_0x84 = |
1693 | { "Wacom Wireless Receiver", WACOM_PKGLEN_WIRELESS, 0, 0, 0, | 1895 | { "Wacom Wireless Receiver", WACOM_PKGLEN_WIRELESS, 0, 0, 0, |
1694 | 0, WIRELESS, 0, 0 }; | 1896 | 0, WIRELESS, 0, 0, .touch_max = 16 }; |
1695 | static const struct wacom_features wacom_features_0xD0 = | 1897 | static const struct wacom_features wacom_features_0xD0 = |
1696 | { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1898 | { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
1697 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1899 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1900 | .touch_max = 2 }; | ||
1698 | static const struct wacom_features wacom_features_0xD1 = | 1901 | static const struct wacom_features wacom_features_0xD1 = |
1699 | { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1902 | { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
1700 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1903 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1904 | .touch_max = 2 }; | ||
1701 | static const struct wacom_features wacom_features_0xD2 = | 1905 | static const struct wacom_features wacom_features_0xD2 = |
1702 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1906 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
1703 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1907 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
1704 | static const struct wacom_features wacom_features_0xD3 = | 1908 | static const struct wacom_features wacom_features_0xD3 = |
1705 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023, | 1909 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023, |
1706 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1910 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1911 | .touch_max = 2 }; | ||
1707 | static const struct wacom_features wacom_features_0xD4 = | 1912 | static const struct wacom_features wacom_features_0xD4 = |
1708 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1913 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
1709 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1914 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -1712,28 +1917,35 @@ static const struct wacom_features wacom_features_0xD5 = | |||
1712 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1917 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
1713 | static const struct wacom_features wacom_features_0xD6 = | 1918 | static const struct wacom_features wacom_features_0xD6 = |
1714 | { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1919 | { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
1715 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1920 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1921 | .touch_max = 2 }; | ||
1716 | static const struct wacom_features wacom_features_0xD7 = | 1922 | static const struct wacom_features wacom_features_0xD7 = |
1717 | { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1923 | { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
1718 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1924 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1925 | .touch_max = 2 }; | ||
1719 | static const struct wacom_features wacom_features_0xD8 = | 1926 | static const struct wacom_features wacom_features_0xD8 = |
1720 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023, | 1927 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023, |
1721 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1928 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1929 | .touch_max = 2 }; | ||
1722 | static const struct wacom_features wacom_features_0xDA = | 1930 | static const struct wacom_features wacom_features_0xDA = |
1723 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1931 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
1724 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1932 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1933 | .touch_max = 2 }; | ||
1725 | static struct wacom_features wacom_features_0xDB = | 1934 | static struct wacom_features wacom_features_0xDB = |
1726 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023, | 1935 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023, |
1727 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1936 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1937 | .touch_max = 2 }; | ||
1728 | static const struct wacom_features wacom_features_0xDD = | 1938 | static const struct wacom_features wacom_features_0xDD = |
1729 | { "Wacom Bamboo Connect", WACOM_PKGLEN_BBPEN, 14720, 9200, 1023, | 1939 | { "Wacom Bamboo Connect", WACOM_PKGLEN_BBPEN, 14720, 9200, 1023, |
1730 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1940 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
1731 | static const struct wacom_features wacom_features_0xDE = | 1941 | static const struct wacom_features wacom_features_0xDE = |
1732 | { "Wacom Bamboo 16FG 4x5", WACOM_PKGLEN_BBPEN, 14720, 9200, 1023, | 1942 | { "Wacom Bamboo 16FG 4x5", WACOM_PKGLEN_BBPEN, 14720, 9200, 1023, |
1733 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1943 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1944 | .touch_max = 16 }; | ||
1734 | static const struct wacom_features wacom_features_0xDF = | 1945 | static const struct wacom_features wacom_features_0xDF = |
1735 | { "Wacom Bamboo 16FG 6x8", WACOM_PKGLEN_BBPEN, 21648, 13700, 1023, | 1946 | { "Wacom Bamboo 16FG 6x8", WACOM_PKGLEN_BBPEN, 21648, 13700, 1023, |
1736 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1947 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
1948 | .touch_max = 16 }; | ||
1737 | static const struct wacom_features wacom_features_0x6004 = | 1949 | static const struct wacom_features wacom_features_0x6004 = |
1738 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, | 1950 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, |
1739 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1951 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -1807,6 +2019,11 @@ const struct usb_device_id wacom_ids[] = { | |||
1807 | { USB_DEVICE_WACOM(0xBA) }, | 2019 | { USB_DEVICE_WACOM(0xBA) }, |
1808 | { USB_DEVICE_WACOM(0xBB) }, | 2020 | { USB_DEVICE_WACOM(0xBB) }, |
1809 | { USB_DEVICE_WACOM(0xBC) }, | 2021 | { USB_DEVICE_WACOM(0xBC) }, |
2022 | { USB_DEVICE_WACOM(0x26) }, | ||
2023 | { USB_DEVICE_WACOM(0x27) }, | ||
2024 | { USB_DEVICE_WACOM(0x28) }, | ||
2025 | { USB_DEVICE_WACOM(0x29) }, | ||
2026 | { USB_DEVICE_WACOM(0x2A) }, | ||
1810 | { USB_DEVICE_WACOM(0x3F) }, | 2027 | { USB_DEVICE_WACOM(0x3F) }, |
1811 | { USB_DEVICE_WACOM(0xC5) }, | 2028 | { USB_DEVICE_WACOM(0xC5) }, |
1812 | { USB_DEVICE_WACOM(0xC6) }, | 2029 | { USB_DEVICE_WACOM(0xC6) }, |
@@ -1842,6 +2059,7 @@ const struct usb_device_id wacom_ids[] = { | |||
1842 | { USB_DEVICE_WACOM(0x9F) }, | 2059 | { USB_DEVICE_WACOM(0x9F) }, |
1843 | { USB_DEVICE_WACOM(0xE2) }, | 2060 | { USB_DEVICE_WACOM(0xE2) }, |
1844 | { USB_DEVICE_WACOM(0xE3) }, | 2061 | { USB_DEVICE_WACOM(0xE3) }, |
2062 | { USB_DEVICE_WACOM(0xE5) }, | ||
1845 | { USB_DEVICE_WACOM(0xE6) }, | 2063 | { USB_DEVICE_WACOM(0xE6) }, |
1846 | { USB_DEVICE_WACOM(0xEC) }, | 2064 | { USB_DEVICE_WACOM(0xEC) }, |
1847 | { USB_DEVICE_WACOM(0x47) }, | 2065 | { USB_DEVICE_WACOM(0x47) }, |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index ba5a334e54d6..78fbd3f42009 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -25,6 +25,10 @@ | |||
25 | #define WACOM_PKGLEN_BBTOUCH3 64 | 25 | #define WACOM_PKGLEN_BBTOUCH3 64 |
26 | #define WACOM_PKGLEN_BBPEN 10 | 26 | #define WACOM_PKGLEN_BBPEN 10 |
27 | #define WACOM_PKGLEN_WIRELESS 32 | 27 | #define WACOM_PKGLEN_WIRELESS 32 |
28 | #define WACOM_PKGLEN_MTOUCH 62 | ||
29 | |||
30 | /* wacom data size per MT contact */ | ||
31 | #define WACOM_BYTES_PER_MT_PACKET 11 | ||
28 | 32 | ||
29 | /* device IDs */ | 33 | /* device IDs */ |
30 | #define STYLUS_DEVICE_ID 0x02 | 34 | #define STYLUS_DEVICE_ID 0x02 |
@@ -38,8 +42,10 @@ | |||
38 | #define WACOM_REPORT_INTUOSREAD 5 | 42 | #define WACOM_REPORT_INTUOSREAD 5 |
39 | #define WACOM_REPORT_INTUOSWRITE 6 | 43 | #define WACOM_REPORT_INTUOSWRITE 6 |
40 | #define WACOM_REPORT_INTUOSPAD 12 | 44 | #define WACOM_REPORT_INTUOSPAD 12 |
45 | #define WACOM_REPORT_INTUOS5PAD 3 | ||
41 | #define WACOM_REPORT_TPC1FG 6 | 46 | #define WACOM_REPORT_TPC1FG 6 |
42 | #define WACOM_REPORT_TPC2FG 13 | 47 | #define WACOM_REPORT_TPC2FG 13 |
48 | #define WACOM_REPORT_TPCMT 13 | ||
43 | #define WACOM_REPORT_TPCHID 15 | 49 | #define WACOM_REPORT_TPCHID 15 |
44 | #define WACOM_REPORT_TPCST 16 | 50 | #define WACOM_REPORT_TPCST 16 |
45 | 51 | ||
@@ -65,6 +71,9 @@ enum { | |||
65 | INTUOS4S, | 71 | INTUOS4S, |
66 | INTUOS4, | 72 | INTUOS4, |
67 | INTUOS4L, | 73 | INTUOS4L, |
74 | INTUOS5S, | ||
75 | INTUOS5, | ||
76 | INTUOS5L, | ||
68 | WACOM_24HD, | 77 | WACOM_24HD, |
69 | WACOM_21UX2, | 78 | WACOM_21UX2, |
70 | CINTIQ, | 79 | CINTIQ, |
@@ -72,6 +81,7 @@ enum { | |||
72 | WACOM_MO, | 81 | WACOM_MO, |
73 | TABLETPC, | 82 | TABLETPC, |
74 | TABLETPC2FG, | 83 | TABLETPC2FG, |
84 | MTSCREEN, | ||
75 | MAX_TYPE | 85 | MAX_TYPE |
76 | }; | 86 | }; |
77 | 87 | ||
@@ -95,6 +105,7 @@ struct wacom_features { | |||
95 | int pressure_fuzz; | 105 | int pressure_fuzz; |
96 | int distance_fuzz; | 106 | int distance_fuzz; |
97 | unsigned quirks; | 107 | unsigned quirks; |
108 | unsigned touch_max; | ||
98 | }; | 109 | }; |
99 | 110 | ||
100 | struct wacom_shared { | 111 | struct wacom_shared { |
@@ -113,6 +124,8 @@ struct wacom_wac { | |||
113 | struct input_dev *input; | 124 | struct input_dev *input; |
114 | int pid; | 125 | int pid; |
115 | int battery_capacity; | 126 | int battery_capacity; |
127 | int num_contacts_left; | ||
128 | int *slots; | ||
116 | }; | 129 | }; |
117 | 130 | ||
118 | #endif | 131 | #endif |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 75838d7710ce..98d263504eea 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -187,6 +187,23 @@ config TOUCHSCREEN_DA9034 | |||
187 | Say Y here to enable the support for the touchscreen found | 187 | Say Y here to enable the support for the touchscreen found |
188 | on Dialog Semiconductor DA9034 PMIC. | 188 | on Dialog Semiconductor DA9034 PMIC. |
189 | 189 | ||
190 | If unsure, say N. | ||
191 | |||
192 | To compile this driver as a module, choose M here: the | ||
193 | module will be called da9034-ts. | ||
194 | |||
195 | config TOUCHSCREEN_DA9052 | ||
196 | tristate "Dialog DA9052/DA9053 TSI" | ||
197 | depends on PMIC_DA9052 | ||
198 | help | ||
199 | Say Y here to support the touchscreen found on Dialog Semiconductor | ||
200 | DA9052-BC and DA9053-AA/Bx PMICs. | ||
201 | |||
202 | If unsure, say N. | ||
203 | |||
204 | To compile this driver as a module, choose M here: the | ||
205 | module will be called da9052_tsi. | ||
206 | |||
190 | config TOUCHSCREEN_DYNAPRO | 207 | config TOUCHSCREEN_DYNAPRO |
191 | tristate "Dynapro serial touchscreen" | 208 | tristate "Dynapro serial touchscreen" |
192 | select SERIO | 209 | select SERIO |
@@ -306,6 +323,18 @@ config TOUCHSCREEN_WACOM_W8001 | |||
306 | To compile this driver as a module, choose M here: the | 323 | To compile this driver as a module, choose M here: the |
307 | module will be called wacom_w8001. | 324 | module will be called wacom_w8001. |
308 | 325 | ||
326 | config TOUCHSCREEN_WACOM_I2C | ||
327 | tristate "Wacom Tablet support (I2C)" | ||
328 | depends on I2C | ||
329 | help | ||
330 | Say Y here if you want to use the I2C version of the Wacom | ||
331 | Pen Tablet. | ||
332 | |||
333 | If unsure, say N. | ||
334 | |||
335 | To compile this driver as a module, choose M here: the module | ||
336 | will be called wacom_i2c. | ||
337 | |||
309 | config TOUCHSCREEN_LPC32XX | 338 | config TOUCHSCREEN_LPC32XX |
310 | tristate "LPC32XX touchscreen controller" | 339 | tristate "LPC32XX touchscreen controller" |
311 | depends on ARCH_LPC32XX | 340 | depends on ARCH_LPC32XX |
@@ -635,6 +664,7 @@ config TOUCHSCREEN_USB_COMPOSITE | |||
635 | - Zytronic controllers | 664 | - Zytronic controllers |
636 | - Elo TouchSystems 2700 IntelliTouch | 665 | - Elo TouchSystems 2700 IntelliTouch |
637 | - EasyTouch USB Touch Controller from Data Modul | 666 | - EasyTouch USB Touch Controller from Data Modul |
667 | - e2i (Mimo monitors) | ||
638 | 668 | ||
639 | Have a look at <http://linux.chapter7.ch/touchkit/> for | 669 | Have a look at <http://linux.chapter7.ch/touchkit/> for |
640 | a usage description and the required user-space stuff. | 670 | a usage description and the required user-space stuff. |
@@ -721,7 +751,7 @@ config TOUCHSCREEN_USB_ELO | |||
721 | 751 | ||
722 | config TOUCHSCREEN_USB_E2I | 752 | config TOUCHSCREEN_USB_E2I |
723 | default y | 753 | default y |
724 | bool "e2i Touchscreen controller (e.g. from Mimo 740)" | 754 | bool "e2i Touchscreen controller (e.g. from Mimo 740)" if EXPERT |
725 | depends on TOUCHSCREEN_USB_COMPOSITE | 755 | depends on TOUCHSCREEN_USB_COMPOSITE |
726 | 756 | ||
727 | config TOUCHSCREEN_USB_ZYTRONIC | 757 | config TOUCHSCREEN_USB_ZYTRONIC |
@@ -744,7 +774,7 @@ config TOUCHSCREEN_USB_EASYTOUCH | |||
744 | bool "EasyTouch USB Touch controller device support" if EMBEDDED | 774 | bool "EasyTouch USB Touch controller device support" if EMBEDDED |
745 | depends on TOUCHSCREEN_USB_COMPOSITE | 775 | depends on TOUCHSCREEN_USB_COMPOSITE |
746 | help | 776 | help |
747 | Say Y here if you have a EasyTouch USB Touch controller device support. | 777 | Say Y here if you have an EasyTouch USB Touch controller. |
748 | If unsure, say N. | 778 | If unsure, say N. |
749 | 779 | ||
750 | config TOUCHSCREEN_TOUCHIT213 | 780 | config TOUCHSCREEN_TOUCHIT213 |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 3d5cf8cbf89c..eb8bfe1c1a46 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o | |||
22 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o | 22 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o |
23 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o | 23 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o |
24 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o | 24 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o |
25 | obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o | ||
25 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o | 26 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o |
26 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o | 27 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o |
27 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 28 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
@@ -59,6 +60,7 @@ obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o | |||
59 | obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o | 60 | obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o |
60 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o | 61 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o |
61 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o | 62 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o |
63 | obj-$(CONFIG_TOUCHSCREEN_WACOM_I2C) += wacom_i2c.o | ||
62 | obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o | 64 | obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o |
63 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o | 65 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o |
64 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o | 66 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 19d4ea65ea01..42e645062c20 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -236,7 +236,6 @@ struct mxt_object { | |||
236 | struct mxt_message { | 236 | struct mxt_message { |
237 | u8 reportid; | 237 | u8 reportid; |
238 | u8 message[7]; | 238 | u8 message[7]; |
239 | u8 checksum; | ||
240 | }; | 239 | }; |
241 | 240 | ||
242 | struct mxt_finger { | 241 | struct mxt_finger { |
@@ -326,17 +325,12 @@ static bool mxt_object_writable(unsigned int type) | |||
326 | } | 325 | } |
327 | 326 | ||
328 | static void mxt_dump_message(struct device *dev, | 327 | static void mxt_dump_message(struct device *dev, |
329 | struct mxt_message *message) | 328 | struct mxt_message *message) |
330 | { | 329 | { |
331 | dev_dbg(dev, "reportid:\t0x%x\n", message->reportid); | 330 | dev_dbg(dev, "reportid: %u\tmessage: %02x %02x %02x %02x %02x %02x %02x\n", |
332 | dev_dbg(dev, "message1:\t0x%x\n", message->message[0]); | 331 | message->reportid, message->message[0], message->message[1], |
333 | dev_dbg(dev, "message2:\t0x%x\n", message->message[1]); | 332 | message->message[2], message->message[3], message->message[4], |
334 | dev_dbg(dev, "message3:\t0x%x\n", message->message[2]); | 333 | message->message[5], message->message[6]); |
335 | dev_dbg(dev, "message4:\t0x%x\n", message->message[3]); | ||
336 | dev_dbg(dev, "message5:\t0x%x\n", message->message[4]); | ||
337 | dev_dbg(dev, "message6:\t0x%x\n", message->message[5]); | ||
338 | dev_dbg(dev, "message7:\t0x%x\n", message->message[6]); | ||
339 | dev_dbg(dev, "checksum:\t0x%x\n", message->checksum); | ||
340 | } | 334 | } |
341 | 335 | ||
342 | static int mxt_check_bootloader(struct i2c_client *client, | 336 | static int mxt_check_bootloader(struct i2c_client *client, |
@@ -506,7 +500,7 @@ static int mxt_write_object(struct mxt_data *data, | |||
506 | u16 reg; | 500 | u16 reg; |
507 | 501 | ||
508 | object = mxt_get_object(data, type); | 502 | object = mxt_get_object(data, type); |
509 | if (!object) | 503 | if (!object || offset >= object->size + 1) |
510 | return -EINVAL; | 504 | return -EINVAL; |
511 | 505 | ||
512 | reg = object->start_address; | 506 | reg = object->start_address; |
@@ -1049,8 +1043,8 @@ static ssize_t mxt_update_fw_store(struct device *dev, | |||
1049 | return count; | 1043 | return count; |
1050 | } | 1044 | } |
1051 | 1045 | ||
1052 | static DEVICE_ATTR(object, 0444, mxt_object_show, NULL); | 1046 | static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); |
1053 | static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store); | 1047 | static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store); |
1054 | 1048 | ||
1055 | static struct attribute *mxt_attrs[] = { | 1049 | static struct attribute *mxt_attrs[] = { |
1056 | &dev_attr_object.attr, | 1050 | &dev_attr_object.attr, |
@@ -1201,7 +1195,7 @@ static int __devexit mxt_remove(struct i2c_client *client) | |||
1201 | return 0; | 1195 | return 0; |
1202 | } | 1196 | } |
1203 | 1197 | ||
1204 | #ifdef CONFIG_PM | 1198 | #ifdef CONFIG_PM_SLEEP |
1205 | static int mxt_suspend(struct device *dev) | 1199 | static int mxt_suspend(struct device *dev) |
1206 | { | 1200 | { |
1207 | struct i2c_client *client = to_i2c_client(dev); | 1201 | struct i2c_client *client = to_i2c_client(dev); |
@@ -1239,13 +1233,10 @@ static int mxt_resume(struct device *dev) | |||
1239 | 1233 | ||
1240 | return 0; | 1234 | return 0; |
1241 | } | 1235 | } |
1242 | |||
1243 | static const struct dev_pm_ops mxt_pm_ops = { | ||
1244 | .suspend = mxt_suspend, | ||
1245 | .resume = mxt_resume, | ||
1246 | }; | ||
1247 | #endif | 1236 | #endif |
1248 | 1237 | ||
1238 | static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); | ||
1239 | |||
1249 | static const struct i2c_device_id mxt_id[] = { | 1240 | static const struct i2c_device_id mxt_id[] = { |
1250 | { "qt602240_ts", 0 }, | 1241 | { "qt602240_ts", 0 }, |
1251 | { "atmel_mxt_ts", 0 }, | 1242 | { "atmel_mxt_ts", 0 }, |
@@ -1258,9 +1249,7 @@ static struct i2c_driver mxt_driver = { | |||
1258 | .driver = { | 1249 | .driver = { |
1259 | .name = "atmel_mxt_ts", | 1250 | .name = "atmel_mxt_ts", |
1260 | .owner = THIS_MODULE, | 1251 | .owner = THIS_MODULE, |
1261 | #ifdef CONFIG_PM | ||
1262 | .pm = &mxt_pm_ops, | 1252 | .pm = &mxt_pm_ops, |
1263 | #endif | ||
1264 | }, | 1253 | }, |
1265 | .probe = mxt_probe, | 1254 | .probe = mxt_probe, |
1266 | .remove = __devexit_p(mxt_remove), | 1255 | .remove = __devexit_p(mxt_remove), |
diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c new file mode 100644 index 000000000000..e8df341090c0 --- /dev/null +++ b/drivers/input/touchscreen/da9052_tsi.c | |||
@@ -0,0 +1,370 @@ | |||
1 | /* | ||
2 | * TSI driver for Dialog DA9052 | ||
3 | * | ||
4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: David Dajun Chen <dchen@diasemi.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | |||
20 | #include <linux/mfd/da9052/reg.h> | ||
21 | #include <linux/mfd/da9052/da9052.h> | ||
22 | |||
23 | #define TSI_PEN_DOWN_STATUS 0x40 | ||
24 | |||
25 | struct da9052_tsi { | ||
26 | struct da9052 *da9052; | ||
27 | struct input_dev *dev; | ||
28 | struct delayed_work ts_pen_work; | ||
29 | struct mutex mutex; | ||
30 | unsigned int irq_pendwn; | ||
31 | unsigned int irq_datardy; | ||
32 | bool stopped; | ||
33 | bool adc_on; | ||
34 | }; | ||
35 | |||
36 | static void da9052_ts_adc_toggle(struct da9052_tsi *tsi, bool on) | ||
37 | { | ||
38 | da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 0, on); | ||
39 | tsi->adc_on = on; | ||
40 | } | ||
41 | |||
42 | static irqreturn_t da9052_ts_pendwn_irq(int irq, void *data) | ||
43 | { | ||
44 | struct da9052_tsi *tsi = data; | ||
45 | |||
46 | if (!tsi->stopped) { | ||
47 | /* Mask PEN_DOWN event and unmask TSI_READY event */ | ||
48 | disable_irq_nosync(tsi->irq_pendwn); | ||
49 | enable_irq(tsi->irq_datardy); | ||
50 | |||
51 | da9052_ts_adc_toggle(tsi, true); | ||
52 | |||
53 | schedule_delayed_work(&tsi->ts_pen_work, HZ / 50); | ||
54 | } | ||
55 | |||
56 | return IRQ_HANDLED; | ||
57 | } | ||
58 | |||
59 | static void da9052_ts_read(struct da9052_tsi *tsi) | ||
60 | { | ||
61 | struct input_dev *input = tsi->dev; | ||
62 | int ret; | ||
63 | u16 x, y, z; | ||
64 | u8 v; | ||
65 | |||
66 | ret = da9052_reg_read(tsi->da9052, DA9052_TSI_X_MSB_REG); | ||
67 | if (ret < 0) | ||
68 | return; | ||
69 | |||
70 | x = (u16) ret; | ||
71 | |||
72 | ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Y_MSB_REG); | ||
73 | if (ret < 0) | ||
74 | return; | ||
75 | |||
76 | y = (u16) ret; | ||
77 | |||
78 | ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Z_MSB_REG); | ||
79 | if (ret < 0) | ||
80 | return; | ||
81 | |||
82 | z = (u16) ret; | ||
83 | |||
84 | ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG); | ||
85 | if (ret < 0) | ||
86 | return; | ||
87 | |||
88 | v = (u8) ret; | ||
89 | |||
90 | x = ((x << 2) & 0x3fc) | (v & 0x3); | ||
91 | y = ((y << 2) & 0x3fc) | ((v & 0xc) >> 2); | ||
92 | z = ((z << 2) & 0x3fc) | ((v & 0x30) >> 4); | ||
93 | |||
94 | input_report_key(input, BTN_TOUCH, 1); | ||
95 | input_report_abs(input, ABS_X, x); | ||
96 | input_report_abs(input, ABS_Y, y); | ||
97 | input_report_abs(input, ABS_PRESSURE, z); | ||
98 | input_sync(input); | ||
99 | } | ||
100 | |||
101 | static irqreturn_t da9052_ts_datardy_irq(int irq, void *data) | ||
102 | { | ||
103 | struct da9052_tsi *tsi = data; | ||
104 | |||
105 | da9052_ts_read(tsi); | ||
106 | |||
107 | return IRQ_HANDLED; | ||
108 | } | ||
109 | |||
110 | static void da9052_ts_pen_work(struct work_struct *work) | ||
111 | { | ||
112 | struct da9052_tsi *tsi = container_of(work, struct da9052_tsi, | ||
113 | ts_pen_work.work); | ||
114 | if (!tsi->stopped) { | ||
115 | int ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG); | ||
116 | if (ret < 0 || (ret & TSI_PEN_DOWN_STATUS)) { | ||
117 | /* Pen is still DOWN (or read error) */ | ||
118 | schedule_delayed_work(&tsi->ts_pen_work, HZ / 50); | ||
119 | } else { | ||
120 | struct input_dev *input = tsi->dev; | ||
121 | |||
122 | /* Pen UP */ | ||
123 | da9052_ts_adc_toggle(tsi, false); | ||
124 | |||
125 | /* Report Pen UP */ | ||
126 | input_report_key(input, BTN_TOUCH, 0); | ||
127 | input_report_abs(input, ABS_PRESSURE, 0); | ||
128 | input_sync(input); | ||
129 | |||
130 | /* | ||
131 | * FIXME: Fixes the unhandled irq issue when quick | ||
132 | * pen down and pen up events occurs | ||
133 | */ | ||
134 | ret = da9052_reg_update(tsi->da9052, | ||
135 | DA9052_EVENT_B_REG, 0xC0, 0xC0); | ||
136 | if (ret < 0) | ||
137 | return; | ||
138 | |||
139 | /* Mask TSI_READY event and unmask PEN_DOWN event */ | ||
140 | disable_irq(tsi->irq_datardy); | ||
141 | enable_irq(tsi->irq_pendwn); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static int __devinit da9052_ts_configure_gpio(struct da9052 *da9052) | ||
147 | { | ||
148 | int error; | ||
149 | |||
150 | error = da9052_reg_update(da9052, DA9052_GPIO_2_3_REG, 0x30, 0); | ||
151 | if (error < 0) | ||
152 | return error; | ||
153 | |||
154 | error = da9052_reg_update(da9052, DA9052_GPIO_4_5_REG, 0x33, 0); | ||
155 | if (error < 0) | ||
156 | return error; | ||
157 | |||
158 | error = da9052_reg_update(da9052, DA9052_GPIO_6_7_REG, 0x33, 0); | ||
159 | if (error < 0) | ||
160 | return error; | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int __devinit da9052_configure_tsi(struct da9052_tsi *tsi) | ||
166 | { | ||
167 | int error; | ||
168 | |||
169 | error = da9052_ts_configure_gpio(tsi->da9052); | ||
170 | if (error) | ||
171 | return error; | ||
172 | |||
173 | /* Measure TSI sample every 1ms */ | ||
174 | error = da9052_reg_update(tsi->da9052, DA9052_ADC_CONT_REG, | ||
175 | 1 << 6, 1 << 6); | ||
176 | if (error < 0) | ||
177 | return error; | ||
178 | |||
179 | /* TSI_DELAY: 3 slots, TSI_SKIP: 0 slots, TSI_MODE: XYZP */ | ||
180 | error = da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 0xFC, 0xC0); | ||
181 | if (error < 0) | ||
182 | return error; | ||
183 | |||
184 | /* Supply TSIRef through LD09 */ | ||
185 | error = da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x59); | ||
186 | if (error < 0) | ||
187 | return error; | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int da9052_ts_input_open(struct input_dev *input_dev) | ||
193 | { | ||
194 | struct da9052_tsi *tsi = input_get_drvdata(input_dev); | ||
195 | |||
196 | tsi->stopped = false; | ||
197 | mb(); | ||
198 | |||
199 | /* Unmask PEN_DOWN event */ | ||
200 | enable_irq(tsi->irq_pendwn); | ||
201 | |||
202 | /* Enable Pen Detect Circuit */ | ||
203 | return da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, | ||
204 | 1 << 1, 1 << 1); | ||
205 | } | ||
206 | |||
207 | static void da9052_ts_input_close(struct input_dev *input_dev) | ||
208 | { | ||
209 | struct da9052_tsi *tsi = input_get_drvdata(input_dev); | ||
210 | |||
211 | tsi->stopped = true; | ||
212 | mb(); | ||
213 | disable_irq(tsi->irq_pendwn); | ||
214 | cancel_delayed_work_sync(&tsi->ts_pen_work); | ||
215 | |||
216 | if (tsi->adc_on) { | ||
217 | disable_irq(tsi->irq_datardy); | ||
218 | da9052_ts_adc_toggle(tsi, false); | ||
219 | |||
220 | /* | ||
221 | * If ADC was on that means that pendwn IRQ was disabled | ||
222 | * twice and we need to enable it to keep enable/disable | ||
223 | * counter balanced. IRQ is still off though. | ||
224 | */ | ||
225 | enable_irq(tsi->irq_pendwn); | ||
226 | } | ||
227 | |||
228 | /* Disable Pen Detect Circuit */ | ||
229 | da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0); | ||
230 | } | ||
231 | |||
232 | static int __devinit da9052_ts_probe(struct platform_device *pdev) | ||
233 | { | ||
234 | struct da9052 *da9052; | ||
235 | struct da9052_tsi *tsi; | ||
236 | struct input_dev *input_dev; | ||
237 | int irq_pendwn; | ||
238 | int irq_datardy; | ||
239 | int error; | ||
240 | |||
241 | da9052 = dev_get_drvdata(pdev->dev.parent); | ||
242 | if (!da9052) | ||
243 | return -EINVAL; | ||
244 | |||
245 | irq_pendwn = platform_get_irq_byname(pdev, "PENDWN"); | ||
246 | irq_datardy = platform_get_irq_byname(pdev, "TSIRDY"); | ||
247 | if (irq_pendwn < 0 || irq_datardy < 0) { | ||
248 | dev_err(da9052->dev, "Unable to determine device interrupts\n"); | ||
249 | return -ENXIO; | ||
250 | } | ||
251 | |||
252 | tsi = kzalloc(sizeof(struct da9052_tsi), GFP_KERNEL); | ||
253 | input_dev = input_allocate_device(); | ||
254 | if (!tsi || !input_dev) { | ||
255 | error = -ENOMEM; | ||
256 | goto err_free_mem; | ||
257 | } | ||
258 | |||
259 | tsi->da9052 = da9052; | ||
260 | tsi->dev = input_dev; | ||
261 | tsi->irq_pendwn = da9052->irq_base + irq_pendwn; | ||
262 | tsi->irq_datardy = da9052->irq_base + irq_datardy; | ||
263 | tsi->stopped = true; | ||
264 | INIT_DELAYED_WORK(&tsi->ts_pen_work, da9052_ts_pen_work); | ||
265 | |||
266 | input_dev->id.version = 0x0101; | ||
267 | input_dev->id.vendor = 0x15B6; | ||
268 | input_dev->id.product = 0x9052; | ||
269 | input_dev->name = "Dialog DA9052 TouchScreen Driver"; | ||
270 | input_dev->dev.parent = &pdev->dev; | ||
271 | input_dev->open = da9052_ts_input_open; | ||
272 | input_dev->close = da9052_ts_input_close; | ||
273 | |||
274 | __set_bit(EV_ABS, input_dev->evbit); | ||
275 | __set_bit(EV_KEY, input_dev->evbit); | ||
276 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
277 | |||
278 | input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0); | ||
279 | input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0); | ||
280 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1023, 0, 0); | ||
281 | |||
282 | input_set_drvdata(input_dev, tsi); | ||
283 | |||
284 | /* Disable Pen Detect Circuit */ | ||
285 | da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0); | ||
286 | |||
287 | /* Disable ADC */ | ||
288 | da9052_ts_adc_toggle(tsi, false); | ||
289 | |||
290 | error = request_threaded_irq(tsi->irq_pendwn, | ||
291 | NULL, da9052_ts_pendwn_irq, | ||
292 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
293 | "PENDWN", tsi); | ||
294 | if (error) { | ||
295 | dev_err(tsi->da9052->dev, | ||
296 | "Failed to register PENDWN IRQ %d, error = %d\n", | ||
297 | tsi->irq_pendwn, error); | ||
298 | goto err_free_mem; | ||
299 | } | ||
300 | |||
301 | error = request_threaded_irq(tsi->irq_datardy, | ||
302 | NULL, da9052_ts_datardy_irq, | ||
303 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
304 | "TSIRDY", tsi); | ||
305 | if (error) { | ||
306 | dev_err(tsi->da9052->dev, | ||
307 | "Failed to register TSIRDY IRQ %d, error = %d\n", | ||
308 | tsi->irq_datardy, error); | ||
309 | goto err_free_pendwn_irq; | ||
310 | } | ||
311 | |||
312 | /* Mask PEN_DOWN and TSI_READY events */ | ||
313 | disable_irq(tsi->irq_pendwn); | ||
314 | disable_irq(tsi->irq_datardy); | ||
315 | |||
316 | error = da9052_configure_tsi(tsi); | ||
317 | if (error) | ||
318 | goto err_free_datardy_irq; | ||
319 | |||
320 | error = input_register_device(tsi->dev); | ||
321 | if (error) | ||
322 | goto err_free_datardy_irq; | ||
323 | |||
324 | platform_set_drvdata(pdev, tsi); | ||
325 | |||
326 | return 0; | ||
327 | |||
328 | err_free_datardy_irq: | ||
329 | free_irq(tsi->irq_datardy, tsi); | ||
330 | err_free_pendwn_irq: | ||
331 | free_irq(tsi->irq_pendwn, tsi); | ||
332 | err_free_mem: | ||
333 | kfree(tsi); | ||
334 | input_free_device(input_dev); | ||
335 | |||
336 | return error; | ||
337 | } | ||
338 | |||
339 | static int __devexit da9052_ts_remove(struct platform_device *pdev) | ||
340 | { | ||
341 | struct da9052_tsi *tsi = platform_get_drvdata(pdev); | ||
342 | |||
343 | da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19); | ||
344 | |||
345 | free_irq(tsi->irq_pendwn, tsi); | ||
346 | free_irq(tsi->irq_datardy, tsi); | ||
347 | |||
348 | input_unregister_device(tsi->dev); | ||
349 | kfree(tsi); | ||
350 | |||
351 | platform_set_drvdata(pdev, NULL); | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static struct platform_driver da9052_tsi_driver = { | ||
357 | .probe = da9052_ts_probe, | ||
358 | .remove = __devexit_p(da9052_ts_remove), | ||
359 | .driver = { | ||
360 | .name = "da9052-tsi", | ||
361 | .owner = THIS_MODULE, | ||
362 | }, | ||
363 | }; | ||
364 | |||
365 | module_platform_driver(da9052_tsi_driver); | ||
366 | |||
367 | MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9052"); | ||
368 | MODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>"); | ||
369 | MODULE_LICENSE("GPL"); | ||
370 | MODULE_ALIAS("platform:da9052-tsi"); | ||
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c index 455353908bdf..1809677a6513 100644 --- a/drivers/input/touchscreen/dynapro.c +++ b/drivers/input/touchscreen/dynapro.c | |||
@@ -188,19 +188,4 @@ static struct serio_driver dynapro_drv = { | |||
188 | .disconnect = dynapro_disconnect, | 188 | .disconnect = dynapro_disconnect, |
189 | }; | 189 | }; |
190 | 190 | ||
191 | /* | 191 | module_serio_driver(dynapro_drv); |
192 | * The functions for inserting/removing us as a module. | ||
193 | */ | ||
194 | |||
195 | static int __init dynapro_init(void) | ||
196 | { | ||
197 | return serio_register_driver(&dynapro_drv); | ||
198 | } | ||
199 | |||
200 | static void __exit dynapro_exit(void) | ||
201 | { | ||
202 | serio_unregister_driver(&dynapro_drv); | ||
203 | } | ||
204 | |||
205 | module_init(dynapro_init); | ||
206 | module_exit(dynapro_exit); | ||
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 486d31ba9c09..957423d1471d 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
@@ -405,19 +405,4 @@ static struct serio_driver elo_drv = { | |||
405 | .disconnect = elo_disconnect, | 405 | .disconnect = elo_disconnect, |
406 | }; | 406 | }; |
407 | 407 | ||
408 | /* | 408 | module_serio_driver(elo_drv); |
409 | * The functions for inserting/removing us as a module. | ||
410 | */ | ||
411 | |||
412 | static int __init elo_init(void) | ||
413 | { | ||
414 | return serio_register_driver(&elo_drv); | ||
415 | } | ||
416 | |||
417 | static void __exit elo_exit(void) | ||
418 | { | ||
419 | serio_unregister_driver(&elo_drv); | ||
420 | } | ||
421 | |||
422 | module_init(elo_init); | ||
423 | module_exit(elo_exit); | ||
diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c index 80b21800355f..10794ddbdf58 100644 --- a/drivers/input/touchscreen/fujitsu_ts.c +++ b/drivers/input/touchscreen/fujitsu_ts.c | |||
@@ -175,15 +175,4 @@ static struct serio_driver fujitsu_drv = { | |||
175 | .disconnect = fujitsu_disconnect, | 175 | .disconnect = fujitsu_disconnect, |
176 | }; | 176 | }; |
177 | 177 | ||
178 | static int __init fujitsu_init(void) | 178 | module_serio_driver(fujitsu_drv); |
179 | { | ||
180 | return serio_register_driver(&fujitsu_drv); | ||
181 | } | ||
182 | |||
183 | static void __exit fujitsu_exit(void) | ||
184 | { | ||
185 | serio_unregister_driver(&fujitsu_drv); | ||
186 | } | ||
187 | |||
188 | module_init(fujitsu_init); | ||
189 | module_exit(fujitsu_exit); | ||
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index a54f90e02ab6..41c71766bf18 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c | |||
@@ -186,19 +186,4 @@ static struct serio_driver gunze_drv = { | |||
186 | .disconnect = gunze_disconnect, | 186 | .disconnect = gunze_disconnect, |
187 | }; | 187 | }; |
188 | 188 | ||
189 | /* | 189 | module_serio_driver(gunze_drv); |
190 | * The functions for inserting/removing us as a module. | ||
191 | */ | ||
192 | |||
193 | static int __init gunze_init(void) | ||
194 | { | ||
195 | return serio_register_driver(&gunze_drv); | ||
196 | } | ||
197 | |||
198 | static void __exit gunze_exit(void) | ||
199 | { | ||
200 | serio_unregister_driver(&gunze_drv); | ||
201 | } | ||
202 | |||
203 | module_init(gunze_init); | ||
204 | module_exit(gunze_exit); | ||
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index 6107e563e681..b9e8686a6f1c 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -476,19 +476,4 @@ static struct serio_driver h3600ts_drv = { | |||
476 | .disconnect = h3600ts_disconnect, | 476 | .disconnect = h3600ts_disconnect, |
477 | }; | 477 | }; |
478 | 478 | ||
479 | /* | 479 | module_serio_driver(h3600ts_drv); |
480 | * The functions for inserting/removing us as a module. | ||
481 | */ | ||
482 | |||
483 | static int __init h3600ts_init(void) | ||
484 | { | ||
485 | return serio_register_driver(&h3600ts_drv); | ||
486 | } | ||
487 | |||
488 | static void __exit h3600ts_exit(void) | ||
489 | { | ||
490 | serio_unregister_driver(&h3600ts_drv); | ||
491 | } | ||
492 | |||
493 | module_init(h3600ts_init); | ||
494 | module_exit(h3600ts_exit); | ||
diff --git a/drivers/input/touchscreen/hampshire.c b/drivers/input/touchscreen/hampshire.c index 2da6cc31bb21..0cc47ea98acf 100644 --- a/drivers/input/touchscreen/hampshire.c +++ b/drivers/input/touchscreen/hampshire.c | |||
@@ -187,19 +187,4 @@ static struct serio_driver hampshire_drv = { | |||
187 | .disconnect = hampshire_disconnect, | 187 | .disconnect = hampshire_disconnect, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | /* | 190 | module_serio_driver(hampshire_drv); |
191 | * The functions for inserting/removing us as a module. | ||
192 | */ | ||
193 | |||
194 | static int __init hampshire_init(void) | ||
195 | { | ||
196 | return serio_register_driver(&hampshire_drv); | ||
197 | } | ||
198 | |||
199 | static void __exit hampshire_exit(void) | ||
200 | { | ||
201 | serio_unregister_driver(&hampshire_drv); | ||
202 | } | ||
203 | |||
204 | module_init(hampshire_init); | ||
205 | module_exit(hampshire_exit); | ||
diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c index 192ade0a0fb9..a29c99c32245 100644 --- a/drivers/input/touchscreen/inexio.c +++ b/drivers/input/touchscreen/inexio.c | |||
@@ -189,19 +189,4 @@ static struct serio_driver inexio_drv = { | |||
189 | .disconnect = inexio_disconnect, | 189 | .disconnect = inexio_disconnect, |
190 | }; | 190 | }; |
191 | 191 | ||
192 | /* | 192 | module_serio_driver(inexio_drv); |
193 | * The functions for inserting/removing us as a module. | ||
194 | */ | ||
195 | |||
196 | static int __init inexio_init(void) | ||
197 | { | ||
198 | return serio_register_driver(&inexio_drv); | ||
199 | } | ||
200 | |||
201 | static void __exit inexio_exit(void) | ||
202 | { | ||
203 | serio_unregister_driver(&inexio_drv); | ||
204 | } | ||
205 | |||
206 | module_init(inexio_init); | ||
207 | module_exit(inexio_exit); | ||
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c index afcd0691ec67..4c2b8ed3bf16 100644 --- a/drivers/input/touchscreen/lpc32xx_ts.c +++ b/drivers/input/touchscreen/lpc32xx_ts.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/of.h> | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Touchscreen controller register offsets | 28 | * Touchscreen controller register offsets |
@@ -383,6 +384,14 @@ static const struct dev_pm_ops lpc32xx_ts_pm_ops = { | |||
383 | #define LPC32XX_TS_PM_OPS NULL | 384 | #define LPC32XX_TS_PM_OPS NULL |
384 | #endif | 385 | #endif |
385 | 386 | ||
387 | #ifdef CONFIG_OF | ||
388 | static struct of_device_id lpc32xx_tsc_of_match[] = { | ||
389 | { .compatible = "nxp,lpc3220-tsc", }, | ||
390 | { }, | ||
391 | }; | ||
392 | MODULE_DEVICE_TABLE(of, lpc32xx_tsc_of_match); | ||
393 | #endif | ||
394 | |||
386 | static struct platform_driver lpc32xx_ts_driver = { | 395 | static struct platform_driver lpc32xx_ts_driver = { |
387 | .probe = lpc32xx_ts_probe, | 396 | .probe = lpc32xx_ts_probe, |
388 | .remove = __devexit_p(lpc32xx_ts_remove), | 397 | .remove = __devexit_p(lpc32xx_ts_remove), |
@@ -390,6 +399,7 @@ static struct platform_driver lpc32xx_ts_driver = { | |||
390 | .name = MOD_NAME, | 399 | .name = MOD_NAME, |
391 | .owner = THIS_MODULE, | 400 | .owner = THIS_MODULE, |
392 | .pm = LPC32XX_TS_PM_OPS, | 401 | .pm = LPC32XX_TS_PM_OPS, |
402 | .of_match_table = of_match_ptr(lpc32xx_tsc_of_match), | ||
393 | }, | 403 | }, |
394 | }; | 404 | }; |
395 | module_platform_driver(lpc32xx_ts_driver); | 405 | module_platform_driver(lpc32xx_ts_driver); |
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index 9077228418b7..eb66b7c37c2f 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c | |||
@@ -202,19 +202,4 @@ static struct serio_driver mtouch_drv = { | |||
202 | .disconnect = mtouch_disconnect, | 202 | .disconnect = mtouch_disconnect, |
203 | }; | 203 | }; |
204 | 204 | ||
205 | /* | 205 | module_serio_driver(mtouch_drv); |
206 | * The functions for inserting/removing us as a module. | ||
207 | */ | ||
208 | |||
209 | static int __init mtouch_init(void) | ||
210 | { | ||
211 | return serio_register_driver(&mtouch_drv); | ||
212 | } | ||
213 | |||
214 | static void __exit mtouch_exit(void) | ||
215 | { | ||
216 | serio_unregister_driver(&mtouch_drv); | ||
217 | } | ||
218 | |||
219 | module_init(mtouch_init); | ||
220 | module_exit(mtouch_exit); | ||
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index 4c012fb2b01e..4ccde45b9da2 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c | |||
@@ -317,19 +317,4 @@ static struct serio_driver pm_drv = { | |||
317 | .disconnect = pm_disconnect, | 317 | .disconnect = pm_disconnect, |
318 | }; | 318 | }; |
319 | 319 | ||
320 | /* | 320 | module_serio_driver(pm_drv); |
321 | * The functions for inserting/removing us as a module. | ||
322 | */ | ||
323 | |||
324 | static int __init pm_init(void) | ||
325 | { | ||
326 | return serio_register_driver(&pm_drv); | ||
327 | } | ||
328 | |||
329 | static void __exit pm_exit(void) | ||
330 | { | ||
331 | serio_unregister_driver(&pm_drv); | ||
332 | } | ||
333 | |||
334 | module_init(pm_init); | ||
335 | module_exit(pm_exit); | ||
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index cbbf71b22696..6cb68a1981bf 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c | |||
@@ -218,7 +218,7 @@ static int __devexit st1232_ts_remove(struct i2c_client *client) | |||
218 | return 0; | 218 | return 0; |
219 | } | 219 | } |
220 | 220 | ||
221 | #ifdef CONFIG_PM | 221 | #ifdef CONFIG_PM_SLEEP |
222 | static int st1232_ts_suspend(struct device *dev) | 222 | static int st1232_ts_suspend(struct device *dev) |
223 | { | 223 | { |
224 | struct i2c_client *client = to_i2c_client(dev); | 224 | struct i2c_client *client = to_i2c_client(dev); |
@@ -243,18 +243,25 @@ static int st1232_ts_resume(struct device *dev) | |||
243 | return 0; | 243 | return 0; |
244 | } | 244 | } |
245 | 245 | ||
246 | static const struct dev_pm_ops st1232_ts_pm_ops = { | ||
247 | .suspend = st1232_ts_suspend, | ||
248 | .resume = st1232_ts_resume, | ||
249 | }; | ||
250 | #endif | 246 | #endif |
251 | 247 | ||
248 | static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops, | ||
249 | st1232_ts_suspend, st1232_ts_resume); | ||
250 | |||
252 | static const struct i2c_device_id st1232_ts_id[] = { | 251 | static const struct i2c_device_id st1232_ts_id[] = { |
253 | { ST1232_TS_NAME, 0 }, | 252 | { ST1232_TS_NAME, 0 }, |
254 | { } | 253 | { } |
255 | }; | 254 | }; |
256 | MODULE_DEVICE_TABLE(i2c, st1232_ts_id); | 255 | MODULE_DEVICE_TABLE(i2c, st1232_ts_id); |
257 | 256 | ||
257 | #ifdef CONFIG_OF | ||
258 | static const struct of_device_id st1232_ts_dt_ids[] __devinitconst = { | ||
259 | { .compatible = "sitronix,st1232", }, | ||
260 | { } | ||
261 | }; | ||
262 | MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids); | ||
263 | #endif | ||
264 | |||
258 | static struct i2c_driver st1232_ts_driver = { | 265 | static struct i2c_driver st1232_ts_driver = { |
259 | .probe = st1232_ts_probe, | 266 | .probe = st1232_ts_probe, |
260 | .remove = __devexit_p(st1232_ts_remove), | 267 | .remove = __devexit_p(st1232_ts_remove), |
@@ -262,9 +269,8 @@ static struct i2c_driver st1232_ts_driver = { | |||
262 | .driver = { | 269 | .driver = { |
263 | .name = ST1232_TS_NAME, | 270 | .name = ST1232_TS_NAME, |
264 | .owner = THIS_MODULE, | 271 | .owner = THIS_MODULE, |
265 | #ifdef CONFIG_PM | 272 | .of_match_table = of_match_ptr(st1232_ts_dt_ids), |
266 | .pm = &st1232_ts_pm_ops, | 273 | .pm = &st1232_ts_pm_ops, |
267 | #endif | ||
268 | }, | 274 | }, |
269 | }; | 275 | }; |
270 | 276 | ||
diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c index d1297ba19daf..5f29e5b8e1c1 100644 --- a/drivers/input/touchscreen/touchit213.c +++ b/drivers/input/touchscreen/touchit213.c | |||
@@ -216,19 +216,4 @@ static struct serio_driver touchit213_drv = { | |||
216 | .disconnect = touchit213_disconnect, | 216 | .disconnect = touchit213_disconnect, |
217 | }; | 217 | }; |
218 | 218 | ||
219 | /* | 219 | module_serio_driver(touchit213_drv); |
220 | * The functions for inserting/removing us as a module. | ||
221 | */ | ||
222 | |||
223 | static int __init touchit213_init(void) | ||
224 | { | ||
225 | return serio_register_driver(&touchit213_drv); | ||
226 | } | ||
227 | |||
228 | static void __exit touchit213_exit(void) | ||
229 | { | ||
230 | serio_unregister_driver(&touchit213_drv); | ||
231 | } | ||
232 | |||
233 | module_init(touchit213_init); | ||
234 | module_exit(touchit213_exit); | ||
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c index 3a5c142c2a78..8a2887daf194 100644 --- a/drivers/input/touchscreen/touchright.c +++ b/drivers/input/touchscreen/touchright.c | |||
@@ -176,19 +176,4 @@ static struct serio_driver tr_drv = { | |||
176 | .disconnect = tr_disconnect, | 176 | .disconnect = tr_disconnect, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | /* | 179 | module_serio_driver(tr_drv); |
180 | * The functions for inserting/removing us as a module. | ||
181 | */ | ||
182 | |||
183 | static int __init tr_init(void) | ||
184 | { | ||
185 | return serio_register_driver(&tr_drv); | ||
186 | } | ||
187 | |||
188 | static void __exit tr_exit(void) | ||
189 | { | ||
190 | serio_unregister_driver(&tr_drv); | ||
191 | } | ||
192 | |||
193 | module_init(tr_init); | ||
194 | module_exit(tr_exit); | ||
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c index 763a656a59f8..588cdcb839dd 100644 --- a/drivers/input/touchscreen/touchwin.c +++ b/drivers/input/touchscreen/touchwin.c | |||
@@ -183,19 +183,4 @@ static struct serio_driver tw_drv = { | |||
183 | .disconnect = tw_disconnect, | 183 | .disconnect = tw_disconnect, |
184 | }; | 184 | }; |
185 | 185 | ||
186 | /* | 186 | module_serio_driver(tw_drv); |
187 | * The functions for inserting/removing us as a module. | ||
188 | */ | ||
189 | |||
190 | static int __init tw_init(void) | ||
191 | { | ||
192 | return serio_register_driver(&tw_drv); | ||
193 | } | ||
194 | |||
195 | static void __exit tw_exit(void) | ||
196 | { | ||
197 | serio_unregister_driver(&tw_drv); | ||
198 | } | ||
199 | |||
200 | module_init(tw_init); | ||
201 | module_exit(tw_exit); | ||
diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c index 29d5ed4dd31c..63209aaa55f0 100644 --- a/drivers/input/touchscreen/tsc40.c +++ b/drivers/input/touchscreen/tsc40.c | |||
@@ -167,17 +167,7 @@ static struct serio_driver tsc_drv = { | |||
167 | .disconnect = tsc_disconnect, | 167 | .disconnect = tsc_disconnect, |
168 | }; | 168 | }; |
169 | 169 | ||
170 | static int __init tsc_ser_init(void) | 170 | module_serio_driver(tsc_drv); |
171 | { | ||
172 | return serio_register_driver(&tsc_drv); | ||
173 | } | ||
174 | module_init(tsc_ser_init); | ||
175 | |||
176 | static void __exit tsc_exit(void) | ||
177 | { | ||
178 | serio_unregister_driver(&tsc_drv); | ||
179 | } | ||
180 | module_exit(tsc_exit); | ||
181 | 171 | ||
182 | MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); | 172 | MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); |
183 | MODULE_DESCRIPTION(DRIVER_DESC); | 173 | MODULE_DESCRIPTION(DRIVER_DESC); |
diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c new file mode 100644 index 000000000000..35572575d34a --- /dev/null +++ b/drivers/input/touchscreen/wacom_i2c.c | |||
@@ -0,0 +1,282 @@ | |||
1 | /* | ||
2 | * Wacom Penabled Driver for I2C | ||
3 | * | ||
4 | * Copyright (c) 2011 Tatsunosuke Tobita, Wacom. | ||
5 | * <tobita.tatsunosuke@wacom.co.jp> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it | ||
8 | * and/or modify it under the terms of the GNU General | ||
9 | * Public License as published by the Free Software | ||
10 | * Foundation; either version of 2 of the License, | ||
11 | * or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <asm/unaligned.h> | ||
22 | |||
23 | #define WACOM_CMD_QUERY0 0x04 | ||
24 | #define WACOM_CMD_QUERY1 0x00 | ||
25 | #define WACOM_CMD_QUERY2 0x33 | ||
26 | #define WACOM_CMD_QUERY3 0x02 | ||
27 | #define WACOM_CMD_THROW0 0x05 | ||
28 | #define WACOM_CMD_THROW1 0x00 | ||
29 | #define WACOM_QUERY_SIZE 19 | ||
30 | #define WACOM_RETRY_CNT 100 | ||
31 | |||
32 | struct wacom_features { | ||
33 | int x_max; | ||
34 | int y_max; | ||
35 | int pressure_max; | ||
36 | char fw_version; | ||
37 | }; | ||
38 | |||
39 | struct wacom_i2c { | ||
40 | struct i2c_client *client; | ||
41 | struct input_dev *input; | ||
42 | u8 data[WACOM_QUERY_SIZE]; | ||
43 | }; | ||
44 | |||
45 | static int wacom_query_device(struct i2c_client *client, | ||
46 | struct wacom_features *features) | ||
47 | { | ||
48 | int ret; | ||
49 | u8 cmd1[] = { WACOM_CMD_QUERY0, WACOM_CMD_QUERY1, | ||
50 | WACOM_CMD_QUERY2, WACOM_CMD_QUERY3 }; | ||
51 | u8 cmd2[] = { WACOM_CMD_THROW0, WACOM_CMD_THROW1 }; | ||
52 | u8 data[WACOM_QUERY_SIZE]; | ||
53 | struct i2c_msg msgs[] = { | ||
54 | { | ||
55 | .addr = client->addr, | ||
56 | .flags = 0, | ||
57 | .len = sizeof(cmd1), | ||
58 | .buf = cmd1, | ||
59 | }, | ||
60 | { | ||
61 | .addr = client->addr, | ||
62 | .flags = 0, | ||
63 | .len = sizeof(cmd2), | ||
64 | .buf = cmd2, | ||
65 | }, | ||
66 | { | ||
67 | .addr = client->addr, | ||
68 | .flags = I2C_M_RD, | ||
69 | .len = sizeof(data), | ||
70 | .buf = data, | ||
71 | }, | ||
72 | }; | ||
73 | |||
74 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
75 | if (ret < 0) | ||
76 | return ret; | ||
77 | if (ret != ARRAY_SIZE(msgs)) | ||
78 | return -EIO; | ||
79 | |||
80 | features->x_max = get_unaligned_le16(&data[3]); | ||
81 | features->y_max = get_unaligned_le16(&data[5]); | ||
82 | features->pressure_max = get_unaligned_le16(&data[11]); | ||
83 | features->fw_version = get_unaligned_le16(&data[13]); | ||
84 | |||
85 | dev_dbg(&client->dev, | ||
86 | "x_max:%d, y_max:%d, pressure:%d, fw:%d\n", | ||
87 | features->x_max, features->y_max, | ||
88 | features->pressure_max, features->fw_version); | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static irqreturn_t wacom_i2c_irq(int irq, void *dev_id) | ||
94 | { | ||
95 | struct wacom_i2c *wac_i2c = dev_id; | ||
96 | struct input_dev *input = wac_i2c->input; | ||
97 | u8 *data = wac_i2c->data; | ||
98 | unsigned int x, y, pressure; | ||
99 | unsigned char tsw, f1, f2, ers; | ||
100 | int error; | ||
101 | |||
102 | error = i2c_master_recv(wac_i2c->client, | ||
103 | wac_i2c->data, sizeof(wac_i2c->data)); | ||
104 | if (error < 0) | ||
105 | goto out; | ||
106 | |||
107 | tsw = data[3] & 0x01; | ||
108 | ers = data[3] & 0x04; | ||
109 | f1 = data[3] & 0x02; | ||
110 | f2 = data[3] & 0x10; | ||
111 | x = le16_to_cpup((__le16 *)&data[4]); | ||
112 | y = le16_to_cpup((__le16 *)&data[6]); | ||
113 | pressure = le16_to_cpup((__le16 *)&data[8]); | ||
114 | |||
115 | input_report_key(input, BTN_TOUCH, tsw || ers); | ||
116 | input_report_key(input, BTN_TOOL_PEN, tsw); | ||
117 | input_report_key(input, BTN_TOOL_RUBBER, ers); | ||
118 | input_report_key(input, BTN_STYLUS, f1); | ||
119 | input_report_key(input, BTN_STYLUS2, f2); | ||
120 | input_report_abs(input, ABS_X, x); | ||
121 | input_report_abs(input, ABS_Y, y); | ||
122 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
123 | input_sync(input); | ||
124 | |||
125 | out: | ||
126 | return IRQ_HANDLED; | ||
127 | } | ||
128 | |||
129 | static int wacom_i2c_open(struct input_dev *dev) | ||
130 | { | ||
131 | struct wacom_i2c *wac_i2c = input_get_drvdata(dev); | ||
132 | struct i2c_client *client = wac_i2c->client; | ||
133 | |||
134 | enable_irq(client->irq); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static void wacom_i2c_close(struct input_dev *dev) | ||
140 | { | ||
141 | struct wacom_i2c *wac_i2c = input_get_drvdata(dev); | ||
142 | struct i2c_client *client = wac_i2c->client; | ||
143 | |||
144 | disable_irq(client->irq); | ||
145 | } | ||
146 | |||
147 | static int __devinit wacom_i2c_probe(struct i2c_client *client, | ||
148 | const struct i2c_device_id *id) | ||
149 | { | ||
150 | struct wacom_i2c *wac_i2c; | ||
151 | struct input_dev *input; | ||
152 | struct wacom_features features; | ||
153 | int error; | ||
154 | |||
155 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
156 | dev_err(&client->dev, "i2c_check_functionality error\n"); | ||
157 | return -EIO; | ||
158 | } | ||
159 | |||
160 | error = wacom_query_device(client, &features); | ||
161 | if (error) | ||
162 | return error; | ||
163 | |||
164 | wac_i2c = kzalloc(sizeof(*wac_i2c), GFP_KERNEL); | ||
165 | input = input_allocate_device(); | ||
166 | if (!wac_i2c || !input) { | ||
167 | error = -ENOMEM; | ||
168 | goto err_free_mem; | ||
169 | } | ||
170 | |||
171 | wac_i2c->client = client; | ||
172 | wac_i2c->input = input; | ||
173 | |||
174 | input->name = "Wacom I2C Digitizer"; | ||
175 | input->id.bustype = BUS_I2C; | ||
176 | input->id.vendor = 0x56a; | ||
177 | input->id.version = features.fw_version; | ||
178 | input->dev.parent = &client->dev; | ||
179 | input->open = wacom_i2c_open; | ||
180 | input->close = wacom_i2c_close; | ||
181 | |||
182 | input->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
183 | |||
184 | __set_bit(BTN_TOOL_PEN, input->keybit); | ||
185 | __set_bit(BTN_TOOL_RUBBER, input->keybit); | ||
186 | __set_bit(BTN_STYLUS, input->keybit); | ||
187 | __set_bit(BTN_STYLUS2, input->keybit); | ||
188 | __set_bit(BTN_TOUCH, input->keybit); | ||
189 | |||
190 | input_set_abs_params(input, ABS_X, 0, features.x_max, 0, 0); | ||
191 | input_set_abs_params(input, ABS_Y, 0, features.y_max, 0, 0); | ||
192 | input_set_abs_params(input, ABS_PRESSURE, | ||
193 | 0, features.pressure_max, 0, 0); | ||
194 | |||
195 | input_set_drvdata(input, wac_i2c); | ||
196 | |||
197 | error = request_threaded_irq(client->irq, NULL, wacom_i2c_irq, | ||
198 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
199 | "wacom_i2c", wac_i2c); | ||
200 | if (error) { | ||
201 | dev_err(&client->dev, | ||
202 | "Failed to enable IRQ, error: %d\n", error); | ||
203 | goto err_free_mem; | ||
204 | } | ||
205 | |||
206 | /* Disable the IRQ, we'll enable it in wac_i2c_open() */ | ||
207 | disable_irq(client->irq); | ||
208 | |||
209 | error = input_register_device(wac_i2c->input); | ||
210 | if (error) { | ||
211 | dev_err(&client->dev, | ||
212 | "Failed to register input device, error: %d\n", error); | ||
213 | goto err_free_irq; | ||
214 | } | ||
215 | |||
216 | i2c_set_clientdata(client, wac_i2c); | ||
217 | return 0; | ||
218 | |||
219 | err_free_irq: | ||
220 | free_irq(client->irq, wac_i2c); | ||
221 | err_free_mem: | ||
222 | input_free_device(input); | ||
223 | kfree(wac_i2c); | ||
224 | |||
225 | return error; | ||
226 | } | ||
227 | |||
228 | static int __devexit wacom_i2c_remove(struct i2c_client *client) | ||
229 | { | ||
230 | struct wacom_i2c *wac_i2c = i2c_get_clientdata(client); | ||
231 | |||
232 | free_irq(client->irq, wac_i2c); | ||
233 | input_unregister_device(wac_i2c->input); | ||
234 | kfree(wac_i2c); | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | #ifdef CONFIG_PM_SLEEP | ||
240 | static int wacom_i2c_suspend(struct device *dev) | ||
241 | { | ||
242 | struct i2c_client *client = to_i2c_client(dev); | ||
243 | |||
244 | disable_irq(client->irq); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int wacom_i2c_resume(struct device *dev) | ||
250 | { | ||
251 | struct i2c_client *client = to_i2c_client(dev); | ||
252 | |||
253 | enable_irq(client->irq); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | #endif | ||
258 | |||
259 | static SIMPLE_DEV_PM_OPS(wacom_i2c_pm, wacom_i2c_suspend, wacom_i2c_resume); | ||
260 | |||
261 | static const struct i2c_device_id wacom_i2c_id[] = { | ||
262 | { "WAC_I2C_EMR", 0 }, | ||
263 | { }, | ||
264 | }; | ||
265 | MODULE_DEVICE_TABLE(i2c, wacom_i2c_id); | ||
266 | |||
267 | static struct i2c_driver wacom_i2c_driver = { | ||
268 | .driver = { | ||
269 | .name = "wacom_i2c", | ||
270 | .owner = THIS_MODULE, | ||
271 | .pm = &wacom_i2c_pm, | ||
272 | }, | ||
273 | |||
274 | .probe = wacom_i2c_probe, | ||
275 | .remove = __devexit_p(wacom_i2c_remove), | ||
276 | .id_table = wacom_i2c_id, | ||
277 | }; | ||
278 | module_i2c_driver(wacom_i2c_driver); | ||
279 | |||
280 | MODULE_AUTHOR("Tatsunosuke Tobita <tobita.tatsunosuke@wacom.co.jp>"); | ||
281 | MODULE_DESCRIPTION("WACOM EMR I2C Driver"); | ||
282 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 1569a3934ab2..8f9ad2f893b8 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
@@ -594,15 +594,4 @@ static struct serio_driver w8001_drv = { | |||
594 | .disconnect = w8001_disconnect, | 594 | .disconnect = w8001_disconnect, |
595 | }; | 595 | }; |
596 | 596 | ||
597 | static int __init w8001_init(void) | 597 | module_serio_driver(w8001_drv); |
598 | { | ||
599 | return serio_register_driver(&w8001_drv); | ||
600 | } | ||
601 | |||
602 | static void __exit w8001_exit(void) | ||
603 | { | ||
604 | serio_unregister_driver(&w8001_drv); | ||
605 | } | ||
606 | |||
607 | module_init(w8001_init); | ||
608 | module_exit(w8001_exit); | ||
diff --git a/include/linux/gameport.h b/include/linux/gameport.h index b456b08d70ed..b986be513406 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h | |||
@@ -153,6 +153,19 @@ int __must_check __gameport_register_driver(struct gameport_driver *drv, | |||
153 | 153 | ||
154 | void gameport_unregister_driver(struct gameport_driver *drv); | 154 | void gameport_unregister_driver(struct gameport_driver *drv); |
155 | 155 | ||
156 | /** | ||
157 | * module_gameport_driver() - Helper macro for registering a gameport driver | ||
158 | * @__gameport_driver: gameport_driver struct | ||
159 | * | ||
160 | * Helper macro for gameport drivers which do not do anything special in | ||
161 | * module init/exit. This eliminates a lot of boilerplate. Each module may | ||
162 | * only use this macro once, and calling it replaces module_init() and | ||
163 | * module_exit(). | ||
164 | */ | ||
165 | #define module_gameport_driver(__gameport_driver) \ | ||
166 | module_driver(__gameport_driver, gameport_register_driver, \ | ||
167 | gameport_unregister_driver) | ||
168 | |||
156 | #endif /* __KERNEL__ */ | 169 | #endif /* __KERNEL__ */ |
157 | 170 | ||
158 | #define GAMEPORT_MODE_DISABLED 0 | 171 | #define GAMEPORT_MODE_DISABLED 0 |
diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h index cec17cf6cac2..d8341cb47b60 100644 --- a/include/linux/i2c/adp5588.h +++ b/include/linux/i2c/adp5588.h | |||
@@ -157,6 +157,7 @@ struct i2c_client; /* forward declaration */ | |||
157 | 157 | ||
158 | struct adp5588_gpio_platform_data { | 158 | struct adp5588_gpio_platform_data { |
159 | int gpio_start; /* GPIO Chip base # */ | 159 | int gpio_start; /* GPIO Chip base # */ |
160 | const char *const *names; | ||
160 | unsigned irq_base; /* interrupt base # */ | 161 | unsigned irq_base; /* interrupt base # */ |
161 | unsigned pullup_dis_mask; /* Pull-Up Disable Mask */ | 162 | unsigned pullup_dis_mask; /* Pull-Up Disable Mask */ |
162 | int (*setup)(struct i2c_client *client, | 163 | int (*setup)(struct i2c_client *client, |
diff --git a/include/linux/input/lm8333.h b/include/linux/input/lm8333.h new file mode 100644 index 000000000000..79f918c6e8c5 --- /dev/null +++ b/include/linux/input/lm8333.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * public include for LM8333 keypad driver - same license as driver | ||
3 | * Copyright (C) 2012 Wolfram Sang, Pengutronix <w.sang@pengutronix.de> | ||
4 | */ | ||
5 | |||
6 | #ifndef _LM8333_H | ||
7 | #define _LM8333_H | ||
8 | |||
9 | struct lm8333; | ||
10 | |||
11 | struct lm8333_platform_data { | ||
12 | /* Keymap data */ | ||
13 | const struct matrix_keymap_data *matrix_data; | ||
14 | /* Active timeout before enter HALT mode in microseconds */ | ||
15 | unsigned active_time; | ||
16 | /* Debounce interval in microseconds */ | ||
17 | unsigned debounce_time; | ||
18 | }; | ||
19 | |||
20 | extern int lm8333_read8(struct lm8333 *lm8333, u8 cmd); | ||
21 | extern int lm8333_write8(struct lm8333 *lm8333, u8 cmd, u8 val); | ||
22 | extern int lm8333_read_block(struct lm8333 *lm8333, u8 cmd, u8 len, u8 *buf); | ||
23 | |||
24 | #endif /* _LM8333_H */ | ||
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 6c07ced0af81..5f3aa6b11bfa 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h | |||
@@ -75,54 +75,10 @@ struct matrix_keypad_platform_data { | |||
75 | bool no_autorepeat; | 75 | bool no_autorepeat; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | /** | 78 | int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, |
79 | * matrix_keypad_build_keymap - convert platform keymap into matrix keymap | 79 | const char *keymap_name, |
80 | * @keymap_data: keymap supplied by the platform code | 80 | unsigned int rows, unsigned int cols, |
81 | * @row_shift: number of bits to shift row value by to advance to the next | 81 | unsigned short *keymap, |
82 | * line in the keymap | 82 | struct input_dev *input_dev); |
83 | * @keymap: expanded version of keymap that is suitable for use by | ||
84 | * matrix keyboad driver | ||
85 | * @keybit: pointer to bitmap of keys supported by input device | ||
86 | * | ||
87 | * This function converts platform keymap (encoded with KEY() macro) into | ||
88 | * an array of keycodes that is suitable for using in a standard matrix | ||
89 | * keyboard driver that uses row and col as indices. | ||
90 | */ | ||
91 | static inline void | ||
92 | matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, | ||
93 | unsigned int row_shift, | ||
94 | unsigned short *keymap, unsigned long *keybit) | ||
95 | { | ||
96 | int i; | ||
97 | |||
98 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
99 | unsigned int key = keymap_data->keymap[i]; | ||
100 | unsigned int row = KEY_ROW(key); | ||
101 | unsigned int col = KEY_COL(key); | ||
102 | unsigned short code = KEY_VAL(key); | ||
103 | |||
104 | keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code; | ||
105 | __set_bit(code, keybit); | ||
106 | } | ||
107 | __clear_bit(KEY_RESERVED, keybit); | ||
108 | } | ||
109 | |||
110 | #ifdef CONFIG_INPUT_OF_MATRIX_KEYMAP | ||
111 | struct matrix_keymap_data * | ||
112 | matrix_keyboard_of_fill_keymap(struct device_node *np, const char *propname); | ||
113 | |||
114 | void matrix_keyboard_of_free_keymap(const struct matrix_keymap_data *kd); | ||
115 | #else | ||
116 | static inline struct matrix_keymap_data * | ||
117 | matrix_keyboard_of_fill_keymap(struct device_node *np, const char *propname) | ||
118 | { | ||
119 | return NULL; | ||
120 | } | ||
121 | |||
122 | static inline void | ||
123 | matrix_keyboard_of_free_keymap(const struct matrix_keymap_data *kd) | ||
124 | { | ||
125 | } | ||
126 | #endif | ||
127 | 83 | ||
128 | #endif /* _MATRIX_KEYPAD_H */ | 84 | #endif /* _MATRIX_KEYPAD_H */ |
diff --git a/include/linux/input/navpoint.h b/include/linux/input/navpoint.h new file mode 100644 index 000000000000..45050eb34de3 --- /dev/null +++ b/include/linux/input/navpoint.h | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | struct navpoint_platform_data { | ||
10 | int port; /* PXA SSP port for pxa_ssp_request() */ | ||
11 | int gpio; /* GPIO for power on/off */ | ||
12 | }; | ||
diff --git a/include/linux/serio.h b/include/linux/serio.h index ca82861b0e46..6d6cfd3e94a3 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h | |||
@@ -96,6 +96,19 @@ int __must_check __serio_register_driver(struct serio_driver *drv, | |||
96 | 96 | ||
97 | void serio_unregister_driver(struct serio_driver *drv); | 97 | void serio_unregister_driver(struct serio_driver *drv); |
98 | 98 | ||
99 | /** | ||
100 | * module_serio_driver() - Helper macro for registering a serio driver | ||
101 | * @__serio_driver: serio_driver struct | ||
102 | * | ||
103 | * Helper macro for serio drivers which do not do anything special in | ||
104 | * module init/exit. This eliminates a lot of boilerplate. Each module | ||
105 | * may only use this macro once, and calling it replaces module_init() | ||
106 | * and module_exit(). | ||
107 | */ | ||
108 | #define module_serio_driver(__serio_driver) \ | ||
109 | module_driver(__serio_driver, serio_register_driver, \ | ||
110 | serio_unregister_driver) | ||
111 | |||
99 | static inline int serio_write(struct serio *serio, unsigned char data) | 112 | static inline int serio_write(struct serio *serio, unsigned char data) |
100 | { | 113 | { |
101 | if (serio->write) | 114 | if (serio->write) |