aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/Makefile2
-rw-r--r--drivers/input/evbug.c6
-rw-r--r--drivers/input/evdev.c199
-rw-r--r--drivers/input/gameport/gameport.c3
-rw-r--r--drivers/input/gameport/ns558.c2
-rw-r--r--drivers/input/input-compat.c135
-rw-r--r--drivers/input/input-compat.h94
-rw-r--r--drivers/input/input.c4
-rw-r--r--drivers/input/joydev.c2
-rw-r--r--drivers/input/joystick/Kconfig24
-rw-r--r--drivers/input/joystick/Makefile2
-rw-r--r--drivers/input/joystick/maplecontrol.c193
-rw-r--r--drivers/input/joystick/walkera0701.c292
-rw-r--r--drivers/input/keyboard/Kconfig9
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/atkbd.c60
-rw-r--r--drivers/input/keyboard/gpio_keys.c4
-rw-r--r--drivers/input/keyboard/hil_kbd.c1
-rw-r--r--drivers/input/keyboard/omap-keypad.c6
-rw-r--r--drivers/input/keyboard/pxa930_rotary.c212
-rw-r--r--drivers/input/misc/pcspkr.c4
-rw-r--r--drivers/input/misc/uinput.c172
-rw-r--r--drivers/input/mouse/Kconfig6
-rw-r--r--drivers/input/mouse/Makefile27
-rw-r--r--drivers/input/mouse/appletouch.c274
-rw-r--r--drivers/input/mouse/gpio_mouse.c2
-rw-r--r--drivers/input/mouse/hgpk.c32
-rw-r--r--drivers/input/mouse/hil_ptr.c2
-rw-r--r--drivers/input/mouse/pxa930_trkball.c269
-rw-r--r--drivers/input/mouse/synaptics.c16
-rw-r--r--drivers/input/mousedev.c3
-rw-r--r--drivers/input/serio/hil_mlc.c1
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h15
-rw-r--r--drivers/input/serio/libps2.c20
-rw-r--r--drivers/input/serio/pcips2.c2
-rw-r--r--drivers/input/serio/serio.c4
-rw-r--r--drivers/input/serio/xilinx_ps2.c220
-rw-r--r--drivers/input/tablet/gtco.c2
-rw-r--r--drivers/input/tablet/wacom_wac.c2
-rw-r--r--drivers/input/touchscreen/Kconfig32
-rw-r--r--drivers/input/touchscreen/Makefile3
-rw-r--r--drivers/input/touchscreen/ads7846.c6
-rw-r--r--drivers/input/touchscreen/da9034-ts.c389
-rw-r--r--drivers/input/touchscreen/tsc2007.c381
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c5
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c325
46 files changed, 2944 insertions, 521 deletions
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 98c4f9a77876..4c9c745a7020 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -5,7 +5,7 @@
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_INPUT) += input-core.o 7obj-$(CONFIG_INPUT) += input-core.o
8input-core-objs := input.o ff-core.o 8input-core-objs := input.o input-compat.o ff-core.o
9 9
10obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o 10obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
11obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o 11obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c
index 0353601ac3b5..f7c5c14ec12a 100644
--- a/drivers/input/evbug.c
+++ b/drivers/input/evbug.c
@@ -39,7 +39,7 @@ MODULE_LICENSE("GPL");
39static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) 39static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
40{ 40{
41 printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", 41 printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
42 handle->dev->dev.bus_id, type, code, value); 42 dev_name(&handle->dev->dev), type, code, value);
43} 43}
44 44
45static int evbug_connect(struct input_handler *handler, struct input_dev *dev, 45static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
@@ -65,7 +65,7 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
65 goto err_unregister_handle; 65 goto err_unregister_handle;
66 66
67 printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n", 67 printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n",
68 dev->dev.bus_id, 68 dev_name(&dev->dev),
69 dev->name ?: "unknown", 69 dev->name ?: "unknown",
70 dev->phys ?: "unknown"); 70 dev->phys ?: "unknown");
71 71
@@ -81,7 +81,7 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
81static void evbug_disconnect(struct input_handle *handle) 81static void evbug_disconnect(struct input_handle *handle)
82{ 82{
83 printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", 83 printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n",
84 handle->dev->dev.bus_id); 84 dev_name(&handle->dev->dev));
85 85
86 input_close_device(handle); 86 input_close_device(handle);
87 input_unregister_handle(handle); 87 input_unregister_handle(handle);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1070db330d35..ed8baa0aec3c 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -19,7 +19,7 @@
19#include <linux/input.h> 19#include <linux/input.h>
20#include <linux/major.h> 20#include <linux/major.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/compat.h> 22#include "input-compat.h"
23 23
24struct evdev { 24struct evdev {
25 int exist; 25 int exist;
@@ -290,187 +290,6 @@ static int evdev_open(struct inode *inode, struct file *file)
290 return error; 290 return error;
291} 291}
292 292
293#ifdef CONFIG_COMPAT
294
295struct input_event_compat {
296 struct compat_timeval time;
297 __u16 type;
298 __u16 code;
299 __s32 value;
300};
301
302struct ff_periodic_effect_compat {
303 __u16 waveform;
304 __u16 period;
305 __s16 magnitude;
306 __s16 offset;
307 __u16 phase;
308
309 struct ff_envelope envelope;
310
311 __u32 custom_len;
312 compat_uptr_t custom_data;
313};
314
315struct ff_effect_compat {
316 __u16 type;
317 __s16 id;
318 __u16 direction;
319 struct ff_trigger trigger;
320 struct ff_replay replay;
321
322 union {
323 struct ff_constant_effect constant;
324 struct ff_ramp_effect ramp;
325 struct ff_periodic_effect_compat periodic;
326 struct ff_condition_effect condition[2]; /* One for each axis */
327 struct ff_rumble_effect rumble;
328 } u;
329};
330
331/* Note to the author of this code: did it ever occur to
332 you why the ifdefs are needed? Think about it again. -AK */
333#ifdef CONFIG_X86_64
334# define COMPAT_TEST is_compat_task()
335#elif defined(CONFIG_IA64)
336# define COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current))
337#elif defined(CONFIG_S390)
338# define COMPAT_TEST test_thread_flag(TIF_31BIT)
339#elif defined(CONFIG_MIPS)
340# define COMPAT_TEST test_thread_flag(TIF_32BIT_ADDR)
341#else
342# define COMPAT_TEST test_thread_flag(TIF_32BIT)
343#endif
344
345static inline size_t evdev_event_size(void)
346{
347 return COMPAT_TEST ?
348 sizeof(struct input_event_compat) : sizeof(struct input_event);
349}
350
351static int evdev_event_from_user(const char __user *buffer,
352 struct input_event *event)
353{
354 if (COMPAT_TEST) {
355 struct input_event_compat compat_event;
356
357 if (copy_from_user(&compat_event, buffer,
358 sizeof(struct input_event_compat)))
359 return -EFAULT;
360
361 event->time.tv_sec = compat_event.time.tv_sec;
362 event->time.tv_usec = compat_event.time.tv_usec;
363 event->type = compat_event.type;
364 event->code = compat_event.code;
365 event->value = compat_event.value;
366
367 } else {
368 if (copy_from_user(event, buffer, sizeof(struct input_event)))
369 return -EFAULT;
370 }
371
372 return 0;
373}
374
375static int evdev_event_to_user(char __user *buffer,
376 const struct input_event *event)
377{
378 if (COMPAT_TEST) {
379 struct input_event_compat compat_event;
380
381 compat_event.time.tv_sec = event->time.tv_sec;
382 compat_event.time.tv_usec = event->time.tv_usec;
383 compat_event.type = event->type;
384 compat_event.code = event->code;
385 compat_event.value = event->value;
386
387 if (copy_to_user(buffer, &compat_event,
388 sizeof(struct input_event_compat)))
389 return -EFAULT;
390
391 } else {
392 if (copy_to_user(buffer, event, sizeof(struct input_event)))
393 return -EFAULT;
394 }
395
396 return 0;
397}
398
399static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
400 struct ff_effect *effect)
401{
402 if (COMPAT_TEST) {
403 struct ff_effect_compat *compat_effect;
404
405 if (size != sizeof(struct ff_effect_compat))
406 return -EINVAL;
407
408 /*
409 * It so happens that the pointer which needs to be changed
410 * is the last field in the structure, so we can copy the
411 * whole thing and replace just the pointer.
412 */
413
414 compat_effect = (struct ff_effect_compat *)effect;
415
416 if (copy_from_user(compat_effect, buffer,
417 sizeof(struct ff_effect_compat)))
418 return -EFAULT;
419
420 if (compat_effect->type == FF_PERIODIC &&
421 compat_effect->u.periodic.waveform == FF_CUSTOM)
422 effect->u.periodic.custom_data =
423 compat_ptr(compat_effect->u.periodic.custom_data);
424 } else {
425 if (size != sizeof(struct ff_effect))
426 return -EINVAL;
427
428 if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
429 return -EFAULT;
430 }
431
432 return 0;
433}
434
435#else
436
437static inline size_t evdev_event_size(void)
438{
439 return sizeof(struct input_event);
440}
441
442static int evdev_event_from_user(const char __user *buffer,
443 struct input_event *event)
444{
445 if (copy_from_user(event, buffer, sizeof(struct input_event)))
446 return -EFAULT;
447
448 return 0;
449}
450
451static int evdev_event_to_user(char __user *buffer,
452 const struct input_event *event)
453{
454 if (copy_to_user(buffer, event, sizeof(struct input_event)))
455 return -EFAULT;
456
457 return 0;
458}
459
460static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
461 struct ff_effect *effect)
462{
463 if (size != sizeof(struct ff_effect))
464 return -EINVAL;
465
466 if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
467 return -EFAULT;
468
469 return 0;
470}
471
472#endif /* CONFIG_COMPAT */
473
474static ssize_t evdev_write(struct file *file, const char __user *buffer, 293static ssize_t evdev_write(struct file *file, const char __user *buffer,
475 size_t count, loff_t *ppos) 294 size_t count, loff_t *ppos)
476{ 295{
@@ -490,14 +309,14 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
490 309
491 while (retval < count) { 310 while (retval < count) {
492 311
493 if (evdev_event_from_user(buffer + retval, &event)) { 312 if (input_event_from_user(buffer + retval, &event)) {
494 retval = -EFAULT; 313 retval = -EFAULT;
495 goto out; 314 goto out;
496 } 315 }
497 316
498 input_inject_event(&evdev->handle, 317 input_inject_event(&evdev->handle,
499 event.type, event.code, event.value); 318 event.type, event.code, event.value);
500 retval += evdev_event_size(); 319 retval += input_event_size();
501 } 320 }
502 321
503 out: 322 out:
@@ -531,7 +350,7 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
531 struct input_event event; 350 struct input_event event;
532 int retval; 351 int retval;
533 352
534 if (count < evdev_event_size()) 353 if (count < input_event_size())
535 return -EINVAL; 354 return -EINVAL;
536 355
537 if (client->head == client->tail && evdev->exist && 356 if (client->head == client->tail && evdev->exist &&
@@ -546,13 +365,13 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
546 if (!evdev->exist) 365 if (!evdev->exist)
547 return -ENODEV; 366 return -ENODEV;
548 367
549 while (retval + evdev_event_size() <= count && 368 while (retval + input_event_size() <= count &&
550 evdev_fetch_next_event(client, &event)) { 369 evdev_fetch_next_event(client, &event)) {
551 370
552 if (evdev_event_to_user(buffer + retval, &event)) 371 if (input_event_to_user(buffer + retval, &event))
553 return -EFAULT; 372 return -EFAULT;
554 373
555 retval += evdev_event_size(); 374 retval += input_event_size();
556 } 375 }
557 376
558 return retval; 377 return retval;
@@ -823,7 +642,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
823 642
824 if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) { 643 if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) {
825 644
826 if (evdev_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect)) 645 if (input_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect))
827 return -EFAULT; 646 return -EFAULT;
828 647
829 error = input_ff_upload(dev, &effect, file); 648 error = input_ff_upload(dev, &effect, file);
@@ -1000,7 +819,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
1000 evdev->handle.handler = handler; 819 evdev->handle.handler = handler;
1001 evdev->handle.private = evdev; 820 evdev->handle.private = evdev;
1002 821
1003 strlcpy(evdev->dev.bus_id, evdev->name, sizeof(evdev->dev.bus_id)); 822 dev_set_name(&evdev->dev, evdev->name);
1004 evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); 823 evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
1005 evdev->dev.class = &input_class; 824 evdev->dev.class = &input_class;
1006 evdev->dev.parent = &dev->dev; 825 evdev->dev.parent = &dev->dev;
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 2880eaae157a..ebf4be5b7c4e 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -530,8 +530,7 @@ static void gameport_init_port(struct gameport *gameport)
530 530
531 mutex_init(&gameport->drv_mutex); 531 mutex_init(&gameport->drv_mutex);
532 device_initialize(&gameport->dev); 532 device_initialize(&gameport->dev);
533 snprintf(gameport->dev.bus_id, sizeof(gameport->dev.bus_id), 533 dev_set_name(&gameport->dev, "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1);
534 "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1);
535 gameport->dev.bus = &gameport_bus; 534 gameport->dev.bus = &gameport_bus;
536 gameport->dev.release = gameport_release_port; 535 gameport->dev.release = gameport_release_port;
537 if (gameport->parent) 536 if (gameport->parent)
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
index 2b282cde4b89..db556b71ddda 100644
--- a/drivers/input/gameport/ns558.c
+++ b/drivers/input/gameport/ns558.c
@@ -226,7 +226,7 @@ static int ns558_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
226 ns558->gameport = port; 226 ns558->gameport = port;
227 227
228 gameport_set_name(port, "NS558 PnP Gameport"); 228 gameport_set_name(port, "NS558 PnP Gameport");
229 gameport_set_phys(port, "pnp%s/gameport0", dev->dev.bus_id); 229 gameport_set_phys(port, "pnp%s/gameport0", dev_name(&dev->dev));
230 port->dev.parent = &dev->dev; 230 port->dev.parent = &dev->dev;
231 port->io = ioport; 231 port->io = ioport;
232 232
diff --git a/drivers/input/input-compat.c b/drivers/input/input-compat.c
new file mode 100644
index 000000000000..1accb89ae66f
--- /dev/null
+++ b/drivers/input/input-compat.c
@@ -0,0 +1,135 @@
1/*
2 * 32bit compatibility wrappers for the input subsystem.
3 *
4 * Very heavily based on evdev.c - Copyright (c) 1999-2002 Vojtech Pavlik
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 */
10
11#include <asm/uaccess.h>
12#include "input-compat.h"
13
14#ifdef CONFIG_COMPAT
15
16int input_event_from_user(const char __user *buffer,
17 struct input_event *event)
18{
19 if (INPUT_COMPAT_TEST) {
20 struct input_event_compat compat_event;
21
22 if (copy_from_user(&compat_event, buffer,
23 sizeof(struct input_event_compat)))
24 return -EFAULT;
25
26 event->time.tv_sec = compat_event.time.tv_sec;
27 event->time.tv_usec = compat_event.time.tv_usec;
28 event->type = compat_event.type;
29 event->code = compat_event.code;
30 event->value = compat_event.value;
31
32 } else {
33 if (copy_from_user(event, buffer, sizeof(struct input_event)))
34 return -EFAULT;
35 }
36
37 return 0;
38}
39
40int input_event_to_user(char __user *buffer,
41 const struct input_event *event)
42{
43 if (INPUT_COMPAT_TEST) {
44 struct input_event_compat compat_event;
45
46 compat_event.time.tv_sec = event->time.tv_sec;
47 compat_event.time.tv_usec = event->time.tv_usec;
48 compat_event.type = event->type;
49 compat_event.code = event->code;
50 compat_event.value = event->value;
51
52 if (copy_to_user(buffer, &compat_event,
53 sizeof(struct input_event_compat)))
54 return -EFAULT;
55
56 } else {
57 if (copy_to_user(buffer, event, sizeof(struct input_event)))
58 return -EFAULT;
59 }
60
61 return 0;
62}
63
64int input_ff_effect_from_user(const char __user *buffer, size_t size,
65 struct ff_effect *effect)
66{
67 if (INPUT_COMPAT_TEST) {
68 struct ff_effect_compat *compat_effect;
69
70 if (size != sizeof(struct ff_effect_compat))
71 return -EINVAL;
72
73 /*
74 * It so happens that the pointer which needs to be changed
75 * is the last field in the structure, so we can retrieve the
76 * whole thing and replace just the pointer.
77 */
78 compat_effect = (struct ff_effect_compat *)effect;
79
80 if (copy_from_user(compat_effect, buffer,
81 sizeof(struct ff_effect_compat)))
82 return -EFAULT;
83
84 if (compat_effect->type == FF_PERIODIC &&
85 compat_effect->u.periodic.waveform == FF_CUSTOM)
86 effect->u.periodic.custom_data =
87 compat_ptr(compat_effect->u.periodic.custom_data);
88 } else {
89 if (size != sizeof(struct ff_effect))
90 return -EINVAL;
91
92 if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
93 return -EFAULT;
94 }
95
96 return 0;
97}
98
99#else
100
101int input_event_from_user(const char __user *buffer,
102 struct input_event *event)
103{
104 if (copy_from_user(event, buffer, sizeof(struct input_event)))
105 return -EFAULT;
106
107 return 0;
108}
109
110int input_event_to_user(char __user *buffer,
111 const struct input_event *event)
112{
113 if (copy_to_user(buffer, event, sizeof(struct input_event)))
114 return -EFAULT;
115
116 return 0;
117}
118
119int input_ff_effect_from_user(const char __user *buffer, size_t size,
120 struct ff_effect *effect)
121{
122 if (size != sizeof(struct ff_effect))
123 return -EINVAL;
124
125 if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
126 return -EFAULT;
127
128 return 0;
129}
130
131#endif /* CONFIG_COMPAT */
132
133EXPORT_SYMBOL_GPL(input_event_from_user);
134EXPORT_SYMBOL_GPL(input_event_to_user);
135EXPORT_SYMBOL_GPL(input_ff_effect_from_user);
diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
new file mode 100644
index 000000000000..47cd9eaee66a
--- /dev/null
+++ b/drivers/input/input-compat.h
@@ -0,0 +1,94 @@
1#ifndef _INPUT_COMPAT_H
2#define _INPUT_COMPAT_H
3
4/*
5 * 32bit compatibility wrappers for the input subsystem.
6 *
7 * Very heavily based on evdev.c - Copyright (c) 1999-2002 Vojtech Pavlik
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 */
13
14#include <linux/compiler.h>
15#include <linux/compat.h>
16#include <linux/input.h>
17
18#ifdef CONFIG_COMPAT
19
20/* Note to the author of this code: did it ever occur to
21 you why the ifdefs are needed? Think about it again. -AK */
22#ifdef CONFIG_X86_64
23# define INPUT_COMPAT_TEST is_compat_task()
24#elif defined(CONFIG_IA64)
25# define INPUT_COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current))
26#elif defined(CONFIG_S390)
27# define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
28#elif defined(CONFIG_MIPS)
29# define INPUT_COMPAT_TEST test_thread_flag(TIF_32BIT_ADDR)
30#else
31# define INPUT_COMPAT_TEST test_thread_flag(TIF_32BIT)
32#endif
33
34struct input_event_compat {
35 struct compat_timeval time;
36 __u16 type;
37 __u16 code;
38 __s32 value;
39};
40
41struct ff_periodic_effect_compat {
42 __u16 waveform;
43 __u16 period;
44 __s16 magnitude;
45 __s16 offset;
46 __u16 phase;
47
48 struct ff_envelope envelope;
49
50 __u32 custom_len;
51 compat_uptr_t custom_data;
52};
53
54struct ff_effect_compat {
55 __u16 type;
56 __s16 id;
57 __u16 direction;
58 struct ff_trigger trigger;
59 struct ff_replay replay;
60
61 union {
62 struct ff_constant_effect constant;
63 struct ff_ramp_effect ramp;
64 struct ff_periodic_effect_compat periodic;
65 struct ff_condition_effect condition[2]; /* One for each axis */
66 struct ff_rumble_effect rumble;
67 } u;
68};
69
70static inline size_t input_event_size(void)
71{
72 return INPUT_COMPAT_TEST ?
73 sizeof(struct input_event_compat) : sizeof(struct input_event);
74}
75
76#else
77
78static inline size_t input_event_size(void)
79{
80 return sizeof(struct input_event);
81}
82
83#endif /* CONFIG_COMPAT */
84
85int input_event_from_user(const char __user *buffer,
86 struct input_event *event);
87
88int input_event_to_user(char __user *buffer,
89 const struct input_event *event);
90
91int input_ff_effect_from_user(const char __user *buffer, size_t size,
92 struct ff_effect *effect);
93
94#endif /* _INPUT_COMPAT_H */
diff --git a/drivers/input/input.c b/drivers/input/input.c
index c13ced3e0d3d..1730d7331a5d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1389,8 +1389,8 @@ int input_register_device(struct input_dev *dev)
1389 if (!dev->setkeycode) 1389 if (!dev->setkeycode)
1390 dev->setkeycode = input_default_setkeycode; 1390 dev->setkeycode = input_default_setkeycode;
1391 1391
1392 snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), 1392 dev_set_name(&dev->dev, "input%ld",
1393 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); 1393 (unsigned long) atomic_inc_return(&input_no) - 1);
1394 1394
1395 error = device_add(&dev->dev); 1395 error = device_add(&dev->dev);
1396 if (error) 1396 if (error)
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index a85b1485e774..6f2366220a50 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -800,7 +800,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
800 } 800 }
801 } 801 }
802 802
803 strlcpy(joydev->dev.bus_id, joydev->name, sizeof(joydev->dev.bus_id)); 803 dev_set_name(&joydev->dev, joydev->name);
804 joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor); 804 joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
805 joydev->dev.class = &input_class; 805 joydev->dev.class = &input_class;
806 joydev->dev.parent = &dev->dev; 806 joydev->dev.parent = &dev->dev;
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index be5c14a5a0a4..b11419590cfe 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -294,4 +294,28 @@ config JOYSTICK_XPAD_LEDS
294 This option enables support for the LED which surrounds the Big X on 294 This option enables support for the LED which surrounds the Big X on
295 XBox 360 controller. 295 XBox 360 controller.
296 296
297config JOYSTICK_WALKERA0701
298 tristate "Walkera WK-0701 RC transmitter"
299 depends on HIGH_RES_TIMERS && PARPORT
300 help
301 Say Y or M here if you have a Walkera WK-0701 transmitter which is
302 supplied with a ready to fly Walkera helicopters such as HM36,
303 HM37, HM60 and want to use it via parport as a joystick. More
304 information is available: <file:Documentation/input/walkera0701.txt>
305
306 To compile this driver as a module, choose M here: the
307 module will be called walkera0701.
308
309config JOYSTICK_MAPLE
310 tristate "Dreamcast control pad"
311 depends on MAPLE
312 help
313 Say Y here if you have a SEGA Dreamcast and want to use your
314 controller as a joystick.
315
316 Most Dreamcast users will say Y.
317
318 To compile this as a module choose M here: the module will be called
319 maplecontrol.
320
297endif 321endif
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile
index fdbf8c4c2876..f3a8cbe2abb6 100644
--- a/drivers/input/joystick/Makefile
+++ b/drivers/input/joystick/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/
19obj-$(CONFIG_JOYSTICK_INTERACT) += interact.o 19obj-$(CONFIG_JOYSTICK_INTERACT) += interact.o
20obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydump.o 20obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydump.o
21obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o 21obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o
22obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o
22obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o 23obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o
23obj-$(CONFIG_JOYSTICK_SPACEBALL) += spaceball.o 24obj-$(CONFIG_JOYSTICK_SPACEBALL) += spaceball.o
24obj-$(CONFIG_JOYSTICK_SPACEORB) += spaceorb.o 25obj-$(CONFIG_JOYSTICK_SPACEORB) += spaceorb.o
@@ -29,4 +30,5 @@ obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o
29obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o 30obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o
30obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o 31obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o
31obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o 32obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o
33obj-$(CONFIG_JOYSTICK_WALKERA0701) += walkera0701.o
32 34
diff --git a/drivers/input/joystick/maplecontrol.c b/drivers/input/joystick/maplecontrol.c
new file mode 100644
index 000000000000..e50047bfe938
--- /dev/null
+++ b/drivers/input/joystick/maplecontrol.c
@@ -0,0 +1,193 @@
1/*
2 * SEGA Dreamcast controller driver
3 * Based on drivers/usb/iforce.c
4 *
5 * Copyright Yaegashi Takeshi, 2001
6 * Adrian McMenamin, 2008
7 */
8
9#include <linux/kernel.h>
10#include <linux/slab.h>
11#include <linux/input.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/timer.h>
15#include <linux/maple.h>
16
17MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
18MODULE_DESCRIPTION("SEGA Dreamcast controller driver");
19MODULE_LICENSE("GPL");
20
21struct dc_pad {
22 struct input_dev *dev;
23 struct maple_device *mdev;
24};
25
26static void dc_pad_callback(struct mapleq *mq)
27{
28 unsigned short buttons;
29 struct maple_device *mapledev = mq->dev;
30 struct dc_pad *pad = maple_get_drvdata(mapledev);
31 struct input_dev *dev = pad->dev;
32 unsigned char *res = mq->recvbuf;
33
34 buttons = ~le16_to_cpup((__le16 *)(res + 8));
35
36 input_report_abs(dev, ABS_HAT0Y,
37 (buttons & 0x0010 ? -1 : 0) + (buttons & 0x0020 ? 1 : 0));
38 input_report_abs(dev, ABS_HAT0X,
39 (buttons & 0x0040 ? -1 : 0) + (buttons & 0x0080 ? 1 : 0));
40 input_report_abs(dev, ABS_HAT1Y,
41 (buttons & 0x1000 ? -1 : 0) + (buttons & 0x2000 ? 1 : 0));
42 input_report_abs(dev, ABS_HAT1X,
43 (buttons & 0x4000 ? -1 : 0) + (buttons & 0x8000 ? 1 : 0));
44
45 input_report_key(dev, BTN_C, buttons & 0x0001);
46 input_report_key(dev, BTN_B, buttons & 0x0002);
47 input_report_key(dev, BTN_A, buttons & 0x0004);
48 input_report_key(dev, BTN_START, buttons & 0x0008);
49 input_report_key(dev, BTN_Z, buttons & 0x0100);
50 input_report_key(dev, BTN_Y, buttons & 0x0200);
51 input_report_key(dev, BTN_X, buttons & 0x0400);
52 input_report_key(dev, BTN_SELECT, buttons & 0x0800);
53
54 input_report_abs(dev, ABS_GAS, res[10]);
55 input_report_abs(dev, ABS_BRAKE, res[11]);
56 input_report_abs(dev, ABS_X, res[12]);
57 input_report_abs(dev, ABS_Y, res[13]);
58 input_report_abs(dev, ABS_RX, res[14]);
59 input_report_abs(dev, ABS_RY, res[15]);
60}
61
62static int dc_pad_open(struct input_dev *dev)
63{
64 struct dc_pad *pad = dev->dev.platform_data;
65
66 maple_getcond_callback(pad->mdev, dc_pad_callback, HZ/20,
67 MAPLE_FUNC_CONTROLLER);
68
69 return 0;
70}
71
72static void dc_pad_close(struct input_dev *dev)
73{
74 struct dc_pad *pad = dev->dev.platform_data;
75
76 maple_getcond_callback(pad->mdev, dc_pad_callback, 0,
77 MAPLE_FUNC_CONTROLLER);
78}
79
80/* allow the controller to be used */
81static int __devinit probe_maple_controller(struct device *dev)
82{
83 static const short btn_bit[32] = {
84 BTN_C, BTN_B, BTN_A, BTN_START, -1, -1, -1, -1,
85 BTN_Z, BTN_Y, BTN_X, BTN_SELECT, -1, -1, -1, -1,
86 -1, -1, -1, -1, -1, -1, -1, -1,
87 -1, -1, -1, -1, -1, -1, -1, -1,
88 };
89
90 static const short abs_bit[32] = {
91 -1, -1, -1, -1, ABS_HAT0Y, ABS_HAT0Y, ABS_HAT0X, ABS_HAT0X,
92 -1, -1, -1, -1, ABS_HAT1Y, ABS_HAT1Y, ABS_HAT1X, ABS_HAT1X,
93 ABS_GAS, ABS_BRAKE, ABS_X, ABS_Y, ABS_RX, ABS_RY, -1, -1,
94 -1, -1, -1, -1, -1, -1, -1, -1,
95 };
96
97 struct maple_device *mdev = to_maple_dev(dev);
98 struct maple_driver *mdrv = to_maple_driver(dev->driver);
99 int i, error;
100 struct dc_pad *pad;
101 struct input_dev *idev;
102 unsigned long data = be32_to_cpu(mdev->devinfo.function_data[0]);
103
104 pad = kzalloc(sizeof(struct dc_pad), GFP_KERNEL);
105 idev = input_allocate_device();
106 if (!pad || !idev) {
107 error = -ENOMEM;
108 goto fail;
109 }
110
111 pad->dev = idev;
112 pad->mdev = mdev;
113
114 idev->open = dc_pad_open;
115 idev->close = dc_pad_close;
116
117 for (i = 0; i < 32; i++) {
118 if (data & (1 << i)) {
119 if (btn_bit[i] >= 0)
120 __set_bit(btn_bit[i], idev->keybit);
121 else if (abs_bit[i] >= 0)
122 __set_bit(abs_bit[i], idev->absbit);
123 }
124 }
125
126 if (idev->keybit[BIT_WORD(BTN_JOYSTICK)])
127 idev->evbit[0] |= BIT_MASK(EV_KEY);
128
129 if (idev->absbit[0])
130 idev->evbit[0] |= BIT_MASK(EV_ABS);
131
132 for (i = ABS_X; i <= ABS_BRAKE; i++)
133 input_set_abs_params(idev, i, 0, 255, 0, 0);
134
135 for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++)
136 input_set_abs_params(idev, i, 1, -1, 0, 0);
137
138 idev->dev.platform_data = pad;
139 idev->dev.parent = &mdev->dev;
140 idev->name = mdev->product_name;
141 idev->id.bustype = BUS_HOST;
142 input_set_drvdata(idev, pad);
143
144 error = input_register_device(idev);
145 if (error)
146 goto fail;
147
148 mdev->driver = mdrv;
149 maple_set_drvdata(mdev, pad);
150
151 return 0;
152
153fail:
154 input_free_device(idev);
155 kfree(pad);
156 maple_set_drvdata(mdev, NULL);
157 return error;
158}
159
160static int __devexit remove_maple_controller(struct device *dev)
161{
162 struct maple_device *mdev = to_maple_dev(dev);
163 struct dc_pad *pad = maple_get_drvdata(mdev);
164
165 mdev->callback = NULL;
166 input_unregister_device(pad->dev);
167 maple_set_drvdata(mdev, NULL);
168 kfree(pad);
169
170 return 0;
171}
172
173static struct maple_driver dc_pad_driver = {
174 .function = MAPLE_FUNC_CONTROLLER,
175 .drv = {
176 .name = "Dreamcast_controller",
177 .probe = probe_maple_controller,
178 .remove = __devexit_p(remove_maple_controller),
179 },
180};
181
182static int __init dc_pad_init(void)
183{
184 return maple_driver_register(&dc_pad_driver);
185}
186
187static void __exit dc_pad_exit(void)
188{
189 maple_driver_unregister(&dc_pad_driver);
190}
191
192module_init(dc_pad_init);
193module_exit(dc_pad_exit);
diff --git a/drivers/input/joystick/walkera0701.c b/drivers/input/joystick/walkera0701.c
new file mode 100644
index 000000000000..4dfa1eed4b7c
--- /dev/null
+++ b/drivers/input/joystick/walkera0701.c
@@ -0,0 +1,292 @@
1/*
2 * Parallel port to Walkera WK-0701 TX joystick
3 *
4 * Copyright (c) 2008 Peter Popovec
5 *
6 * More about driver: <file:Documentation/input/walkera0701.txt>
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13*/
14
15/* #define WK0701_DEBUG */
16
17#define RESERVE 20000
18#define SYNC_PULSE 1306000
19#define BIN0_PULSE 288000
20#define BIN1_PULSE 438000
21
22#define ANALOG_MIN_PULSE 318000
23#define ANALOG_MAX_PULSE 878000
24#define ANALOG_DELTA 80000
25
26#define BIN_SAMPLE ((BIN0_PULSE + BIN1_PULSE) / 2)
27
28#define NO_SYNC 25
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/parport.h>
33#include <linux/input.h>
34#include <linux/hrtimer.h>
35
36MODULE_AUTHOR("Peter Popovec <popovec@fei.tuke.sk>");
37MODULE_DESCRIPTION("Walkera WK-0701 TX as joystick");
38MODULE_LICENSE("GPL");
39
40static unsigned int walkera0701_pp_no;
41module_param_named(port, walkera0701_pp_no, int, 0);
42MODULE_PARM_DESC(port,
43 "Parallel port adapter for Walkera WK-0701 TX (default is 0)");
44
45/*
46 * For now, only one device is supported, if somebody need more devices, code
47 * can be expanded, one struct walkera_dev per device must be allocated and
48 * set up by walkera0701_connect (release of device by walkera0701_disconnect)
49 */
50
51struct walkera_dev {
52 unsigned char buf[25];
53 u64 irq_time, irq_lasttime;
54 int counter;
55 int ack;
56
57 struct input_dev *input_dev;
58 struct hrtimer timer;
59
60 struct parport *parport;
61 struct pardevice *pardevice;
62};
63
64static struct walkera_dev w_dev;
65
66static inline void walkera0701_parse_frame(struct walkera_dev *w)
67{
68 int i;
69 int val1, val2, val3, val4, val5, val6, val7, val8;
70 int crc1, crc2;
71
72 for (crc1 = crc2 = i = 0; i < 10; i++) {
73 crc1 += w->buf[i] & 7;
74 crc2 += (w->buf[i] & 8) >> 3;
75 }
76 if ((w->buf[10] & 7) != (crc1 & 7))
77 return;
78 if (((w->buf[10] & 8) >> 3) != (((crc1 >> 3) + crc2) & 1))
79 return;
80 for (crc1 = crc2 = 0, i = 11; i < 23; i++) {
81 crc1 += w->buf[i] & 7;
82 crc2 += (w->buf[i] & 8) >> 3;
83 }
84 if ((w->buf[23] & 7) != (crc1 & 7))
85 return;
86 if (((w->buf[23] & 8) >> 3) != (((crc1 >> 3) + crc2) & 1))
87 return;
88 val1 = ((w->buf[0] & 7) * 256 + w->buf[1] * 16 + w->buf[2]) >> 2;
89 val1 *= ((w->buf[0] >> 2) & 2) - 1; /* sign */
90 val2 = (w->buf[2] & 1) << 8 | (w->buf[3] << 4) | w->buf[4];
91 val2 *= (w->buf[2] & 2) - 1; /* sign */
92 val3 = ((w->buf[5] & 7) * 256 + w->buf[6] * 16 + w->buf[7]) >> 2;
93 val3 *= ((w->buf[5] >> 2) & 2) - 1; /* sign */
94 val4 = (w->buf[7] & 1) << 8 | (w->buf[8] << 4) | w->buf[9];
95 val4 *= (w->buf[7] & 2) - 1; /* sign */
96 val5 = ((w->buf[11] & 7) * 256 + w->buf[12] * 16 + w->buf[13]) >> 2;
97 val5 *= ((w->buf[11] >> 2) & 2) - 1; /* sign */
98 val6 = (w->buf[13] & 1) << 8 | (w->buf[14] << 4) | w->buf[15];
99 val6 *= (w->buf[13] & 2) - 1; /* sign */
100 val7 = ((w->buf[16] & 7) * 256 + w->buf[17] * 16 + w->buf[18]) >> 2;
101 val7 *= ((w->buf[16] >> 2) & 2) - 1; /*sign */
102 val8 = (w->buf[18] & 1) << 8 | (w->buf[19] << 4) | w->buf[20];
103 val8 *= (w->buf[18] & 2) - 1; /*sign */
104
105#ifdef WK0701_DEBUG
106 {
107 int magic, magic_bit;
108 magic = (w->buf[21] << 4) | w->buf[22];
109 magic_bit = (w->buf[24] & 8) >> 3;
110 printk(KERN_DEBUG
111 "walkera0701: %4d %4d %4d %4d %4d %4d %4d %4d (magic %2x %d)\n",
112 val1, val2, val3, val4, val5, val6, val7, val8, magic,
113 magic_bit);
114 }
115#endif
116 input_report_abs(w->input_dev, ABS_X, val2);
117 input_report_abs(w->input_dev, ABS_Y, val1);
118 input_report_abs(w->input_dev, ABS_Z, val6);
119 input_report_abs(w->input_dev, ABS_THROTTLE, val3);
120 input_report_abs(w->input_dev, ABS_RUDDER, val4);
121 input_report_abs(w->input_dev, ABS_MISC, val7);
122 input_report_key(w->input_dev, BTN_GEAR_DOWN, val5 > 0);
123}
124
125static inline int read_ack(struct pardevice *p)
126{
127 return parport_read_status(p->port) & 0x40;
128}
129
130/* falling edge, prepare to BIN value calculation */
131static void walkera0701_irq_handler(void *handler_data)
132{
133 u64 pulse_time;
134 struct walkera_dev *w = handler_data;
135
136 w->irq_time = ktime_to_ns(ktime_get());
137 pulse_time = w->irq_time - w->irq_lasttime;
138 w->irq_lasttime = w->irq_time;
139
140 /* cancel timer, if in handler or active do resync */
141 if (unlikely(0 != hrtimer_try_to_cancel(&w->timer))) {
142 w->counter = NO_SYNC;
143 return;
144 }
145
146 if (w->counter < NO_SYNC) {
147 if (w->ack) {
148 pulse_time -= BIN1_PULSE;
149 w->buf[w->counter] = 8;
150 } else {
151 pulse_time -= BIN0_PULSE;
152 w->buf[w->counter] = 0;
153 }
154 if (w->counter == 24) { /* full frame */
155 walkera0701_parse_frame(w);
156 w->counter = NO_SYNC;
157 if (abs(pulse_time - SYNC_PULSE) < RESERVE) /* new frame sync */
158 w->counter = 0;
159 } else {
160 if ((pulse_time > (ANALOG_MIN_PULSE - RESERVE)
161 && (pulse_time < (ANALOG_MAX_PULSE + RESERVE)))) {
162 pulse_time -= (ANALOG_MIN_PULSE - RESERVE);
163 pulse_time = (u32) pulse_time / ANALOG_DELTA; /* overtiping is safe, pulsetime < s32.. */
164 w->buf[w->counter++] |= (pulse_time & 7);
165 } else
166 w->counter = NO_SYNC;
167 }
168 } else if (abs(pulse_time - SYNC_PULSE - BIN0_PULSE) <
169 RESERVE + BIN1_PULSE - BIN0_PULSE) /* frame sync .. */
170 w->counter = 0;
171
172 hrtimer_start(&w->timer, ktime_set(0, BIN_SAMPLE), HRTIMER_MODE_REL);
173}
174
175static enum hrtimer_restart timer_handler(struct hrtimer
176 *handle)
177{
178 struct walkera_dev *w;
179
180 w = container_of(handle, struct walkera_dev, timer);
181 w->ack = read_ack(w->pardevice);
182
183 return HRTIMER_NORESTART;
184}
185
186static int walkera0701_open(struct input_dev *dev)
187{
188 struct walkera_dev *w = input_get_drvdata(dev);
189
190 parport_enable_irq(w->parport);
191 return 0;
192}
193
194static void walkera0701_close(struct input_dev *dev)
195{
196 struct walkera_dev *w = input_get_drvdata(dev);
197
198 parport_disable_irq(w->parport);
199}
200
201static int walkera0701_connect(struct walkera_dev *w, int parport)
202{
203 int err = -ENODEV;
204
205 w->parport = parport_find_number(parport);
206 if (w->parport == NULL)
207 return -ENODEV;
208
209 if (w->parport->irq == -1) {
210 printk(KERN_ERR "walkera0701: parport without interrupt\n");
211 goto init_err;
212 }
213
214 err = -EBUSY;
215 w->pardevice = parport_register_device(w->parport, "walkera0701",
216 NULL, NULL, walkera0701_irq_handler,
217 PARPORT_DEV_EXCL, w);
218 if (!w->pardevice)
219 goto init_err;
220
221 if (parport_negotiate(w->pardevice->port, IEEE1284_MODE_COMPAT))
222 goto init_err1;
223
224 if (parport_claim(w->pardevice))
225 goto init_err1;
226
227 w->input_dev = input_allocate_device();
228 if (!w->input_dev)
229 goto init_err2;
230
231 input_set_drvdata(w->input_dev, w);
232 w->input_dev->name = "Walkera WK-0701 TX";
233 w->input_dev->phys = w->parport->name;
234 w->input_dev->id.bustype = BUS_PARPORT;
235
236 /* TODO what id vendor/product/version ? */
237 w->input_dev->id.vendor = 0x0001;
238 w->input_dev->id.product = 0x0001;
239 w->input_dev->id.version = 0x0100;
240 w->input_dev->open = walkera0701_open;
241 w->input_dev->close = walkera0701_close;
242
243 w->input_dev->evbit[0] = BIT(EV_ABS) | BIT_MASK(EV_KEY);
244 w->input_dev->keybit[BIT_WORD(BTN_GEAR_DOWN)] = BIT_MASK(BTN_GEAR_DOWN);
245
246 input_set_abs_params(w->input_dev, ABS_X, -512, 512, 0, 0);
247 input_set_abs_params(w->input_dev, ABS_Y, -512, 512, 0, 0);
248 input_set_abs_params(w->input_dev, ABS_Z, -512, 512, 0, 0);
249 input_set_abs_params(w->input_dev, ABS_THROTTLE, -512, 512, 0, 0);
250 input_set_abs_params(w->input_dev, ABS_RUDDER, -512, 512, 0, 0);
251 input_set_abs_params(w->input_dev, ABS_MISC, -512, 512, 0, 0);
252
253 err = input_register_device(w->input_dev);
254 if (err)
255 goto init_err3;
256
257 hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
258 w->timer.function = timer_handler;
259 return 0;
260
261 init_err3:
262 input_free_device(w->input_dev);
263 init_err2:
264 parport_release(w->pardevice);
265 init_err1:
266 parport_unregister_device(w->pardevice);
267 init_err:
268 parport_put_port(w->parport);
269 return err;
270}
271
272static void walkera0701_disconnect(struct walkera_dev *w)
273{
274 hrtimer_cancel(&w->timer);
275 input_unregister_device(w->input_dev);
276 parport_release(w->pardevice);
277 parport_unregister_device(w->pardevice);
278 parport_put_port(w->parport);
279}
280
281static int __init walkera0701_init(void)
282{
283 return walkera0701_connect(&w_dev, walkera0701_pp_no);
284}
285
286static void __exit walkera0701_exit(void)
287{
288 walkera0701_disconnect(&w_dev);
289}
290
291module_init(walkera0701_init);
292module_exit(walkera0701_exit);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index efd70a974591..35561689ff38 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -268,6 +268,15 @@ config KEYBOARD_PXA27x
268 To compile this driver as a module, choose M here: the 268 To compile this driver as a module, choose M here: the
269 module will be called pxa27x_keypad. 269 module will be called pxa27x_keypad.
270 270
271config KEYBOARD_PXA930_ROTARY
272 tristate "PXA930/PXA935 Enhanced Rotary Controller Support"
273 depends on CPU_PXA930 || CPU_PXA935
274 help
275 Enable support for PXA930/PXA935 Enhanced Rotary Controller.
276
277 To compile this driver as a module, choose M here: the
278 module will be called pxa930_rotary.
279
271config KEYBOARD_AAED2000 280config KEYBOARD_AAED2000
272 tristate "AAED-2000 keyboard" 281 tristate "AAED-2000 keyboard"
273 depends on MACH_AAED2000 282 depends on MACH_AAED2000
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 0edc8f285d1c..36351e1190f9 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
20obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o 20obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
21obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o 21obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
22obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o 22obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
23obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o
23obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o 24obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
24obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o 25obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
25obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o 26obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 379b7ff354ec..f6e9f39a527b 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -884,6 +884,39 @@ static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd)
884} 884}
885 885
886/* 886/*
887 * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
888 * for its volume buttons
889 */
890static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd)
891{
892 const unsigned int forced_release_keys[] = {
893 0xae, 0xb0,
894 };
895 int i;
896
897 if (atkbd->set == 2)
898 for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
899 __set_bit(forced_release_keys[i],
900 atkbd->force_release_mask);
901}
902
903/*
904 * Samsung NC10 with Fn+F? key release not working
905 */
906static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd)
907{
908 const unsigned int forced_release_keys[] = {
909 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9,
910 };
911 int i;
912
913 if (atkbd->set == 2)
914 for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
915 __set_bit(forced_release_keys[i],
916 atkbd->force_release_mask);
917}
918
919/*
887 * atkbd_set_keycode_table() initializes keyboard's keycode table 920 * atkbd_set_keycode_table() initializes keyboard's keycode table
888 * according to the selected scancode set 921 * according to the selected scancode set
889 */ 922 */
@@ -1476,6 +1509,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1476 .driver_data = atkbd_dell_laptop_keymap_fixup, 1509 .driver_data = atkbd_dell_laptop_keymap_fixup,
1477 }, 1510 },
1478 { 1511 {
1512 .ident = "Dell Laptop",
1513 .matches = {
1514 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
1515 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
1516 },
1517 .callback = atkbd_setup_fixup,
1518 .driver_data = atkbd_dell_laptop_keymap_fixup,
1519 },
1520 {
1479 .ident = "HP 2133", 1521 .ident = "HP 2133",
1480 .matches = { 1522 .matches = {
1481 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 1523 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
@@ -1485,6 +1527,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1485 .driver_data = atkbd_hp_keymap_fixup, 1527 .driver_data = atkbd_hp_keymap_fixup,
1486 }, 1528 },
1487 { 1529 {
1530 .ident = "HP Pavilion ZV6100",
1531 .matches = {
1532 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1533 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
1534 },
1535 .callback = atkbd_setup_fixup,
1536 .driver_data = atkbd_hp_zv6100_keymap_fixup,
1537 },
1538 {
1488 .ident = "Inventec Symphony", 1539 .ident = "Inventec Symphony",
1489 .matches = { 1540 .matches = {
1490 DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), 1541 DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
@@ -1493,6 +1544,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1493 .callback = atkbd_setup_fixup, 1544 .callback = atkbd_setup_fixup,
1494 .driver_data = atkbd_inventec_keymap_fixup, 1545 .driver_data = atkbd_inventec_keymap_fixup,
1495 }, 1546 },
1547 {
1548 .ident = "Samsung NC10",
1549 .matches = {
1550 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
1551 DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
1552 },
1553 .callback = atkbd_setup_fixup,
1554 .driver_data = atkbd_samsung_keymap_fixup,
1555 },
1496 { } 1556 { }
1497}; 1557};
1498 1558
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 05f3f43582c2..ad67d763fdbd 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -98,6 +98,10 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
98 input->id.product = 0x0001; 98 input->id.product = 0x0001;
99 input->id.version = 0x0100; 99 input->id.version = 0x0100;
100 100
101 /* Enable auto repeat feature of Linux input subsystem */
102 if (pdata->rep)
103 __set_bit(EV_REP, input->evbit);
104
101 ddata->input = input; 105 ddata->input = input;
102 106
103 for (i = 0; i < pdata->nbuttons; i++) { 107 for (i = 0; i < pdata->nbuttons; i++) {
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index 71c1971abf80..6f356705ee3b 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -47,6 +47,7 @@
47MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); 47MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
48MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver"); 48MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
49MODULE_LICENSE("Dual BSD/GPL"); 49MODULE_LICENSE("Dual BSD/GPL");
50MODULE_ALIAS("serio:ty03pr25id00ex*");
50 51
51#define HIL_KBD_MAX_LENGTH 16 52#define HIL_KBD_MAX_LENGTH 16
52 53
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index db22fd9b4cf2..3f3d1198cdb1 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -122,14 +122,10 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state)
122 122
123 /* read the keypad status */ 123 /* read the keypad status */
124 if (cpu_is_omap24xx()) { 124 if (cpu_is_omap24xx()) {
125 int i;
126 for (i = 0; i < omap_kp->rows; i++)
127 disable_irq(OMAP_GPIO_IRQ(row_gpios[i]));
128
129 /* read the keypad status */ 125 /* read the keypad status */
130 for (col = 0; col < omap_kp->cols; col++) { 126 for (col = 0; col < omap_kp->cols; col++) {
131 set_col_gpio_val(omap_kp, ~(1 << col)); 127 set_col_gpio_val(omap_kp, ~(1 << col));
132 state[col] = ~(get_row_gpio_val(omap_kp)) & 0x3f; 128 state[col] = ~(get_row_gpio_val(omap_kp)) & 0xff;
133 } 129 }
134 set_col_gpio_val(omap_kp, 0); 130 set_col_gpio_val(omap_kp, 0);
135 131
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c
new file mode 100644
index 000000000000..95fbba470e65
--- /dev/null
+++ b/drivers/input/keyboard/pxa930_rotary.c
@@ -0,0 +1,212 @@
1/*
2 * Driver for the enhanced rotary controller on pxa930 and pxa935
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#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/interrupt.h>
13#include <linux/input.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16
17#include <mach/pxa930_rotary.h>
18
19#define SBCR (0x04)
20#define ERCR (0x0c)
21
22#define SBCR_ERSB (1 << 5)
23
24struct pxa930_rotary {
25 struct input_dev *input_dev;
26 void __iomem *mmio_base;
27 int last_ercr;
28
29 struct pxa930_rotary_platform_data *pdata;
30};
31
32static void clear_sbcr(struct pxa930_rotary *r)
33{
34 uint32_t sbcr = __raw_readl(r->mmio_base + SBCR);
35
36 __raw_writel(sbcr | SBCR_ERSB, r->mmio_base + SBCR);
37 __raw_writel(sbcr & ~SBCR_ERSB, r->mmio_base + SBCR);
38}
39
40static irqreturn_t rotary_irq(int irq, void *dev_id)
41{
42 struct pxa930_rotary *r = dev_id;
43 struct pxa930_rotary_platform_data *pdata = r->pdata;
44 int ercr, delta, key;
45
46 ercr = __raw_readl(r->mmio_base + ERCR) & 0xf;
47 clear_sbcr(r);
48
49 delta = ercr - r->last_ercr;
50 if (delta == 0)
51 return IRQ_HANDLED;
52
53 r->last_ercr = ercr;
54
55 if (pdata->up_key && pdata->down_key) {
56 key = (delta > 0) ? pdata->up_key : pdata->down_key;
57 input_report_key(r->input_dev, key, 1);
58 input_sync(r->input_dev);
59 input_report_key(r->input_dev, key, 0);
60 } else
61 input_report_rel(r->input_dev, pdata->rel_code, delta);
62
63 input_sync(r->input_dev);
64
65 return IRQ_HANDLED;
66}
67
68static int pxa930_rotary_open(struct input_dev *dev)
69{
70 struct pxa930_rotary *r = input_get_drvdata(dev);
71
72 clear_sbcr(r);
73
74 return 0;
75}
76
77static void pxa930_rotary_close(struct input_dev *dev)
78{
79 struct pxa930_rotary *r = input_get_drvdata(dev);
80
81 clear_sbcr(r);
82}
83
84static int __devinit pxa930_rotary_probe(struct platform_device *pdev)
85{
86 struct pxa930_rotary_platform_data *pdata = pdev->dev.platform_data;
87 struct pxa930_rotary *r;
88 struct input_dev *input_dev;
89 struct resource *res;
90 int irq;
91 int err;
92
93 irq = platform_get_irq(pdev, 0);
94 if (irq < 0) {
95 dev_err(&pdev->dev, "no irq for rotary controller\n");
96 return -ENXIO;
97 }
98
99 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
100 if (!res) {
101 dev_err(&pdev->dev, "no I/O memory defined\n");
102 return -ENXIO;
103 }
104
105 if (!pdata) {
106 dev_err(&pdev->dev, "no platform data defined\n");
107 return -EINVAL;
108 }
109
110 r = kzalloc(sizeof(struct pxa930_rotary), GFP_KERNEL);
111 if (!r)
112 return -ENOMEM;
113
114 r->mmio_base = ioremap_nocache(res->start, resource_size(res));
115 if (r->mmio_base == NULL) {
116 dev_err(&pdev->dev, "failed to remap IO memory\n");
117 err = -ENXIO;
118 goto failed_free;
119 }
120
121 r->pdata = pdata;
122 platform_set_drvdata(pdev, r);
123
124 /* allocate and register the input device */
125 input_dev = input_allocate_device();
126 if (!input_dev) {
127 dev_err(&pdev->dev, "failed to allocate input device\n");
128 err = -ENOMEM;
129 goto failed_free_io;
130 }
131
132 input_dev->name = pdev->name;
133 input_dev->id.bustype = BUS_HOST;
134 input_dev->open = pxa930_rotary_open;
135 input_dev->close = pxa930_rotary_close;
136 input_dev->dev.parent = &pdev->dev;
137
138 if (pdata->up_key && pdata->down_key) {
139 __set_bit(pdata->up_key, input_dev->keybit);
140 __set_bit(pdata->down_key, input_dev->keybit);
141 __set_bit(EV_KEY, input_dev->evbit);
142 } else {
143 __set_bit(pdata->rel_code, input_dev->relbit);
144 __set_bit(EV_REL, input_dev->evbit);
145 }
146
147 r->input_dev = input_dev;
148 input_set_drvdata(input_dev, r);
149
150 err = request_irq(irq, rotary_irq, IRQF_DISABLED,
151 "enhanced rotary", r);
152 if (err) {
153 dev_err(&pdev->dev, "failed to request IRQ\n");
154 goto failed_free_input;
155 }
156
157 err = input_register_device(input_dev);
158 if (err) {
159 dev_err(&pdev->dev, "failed to register input device\n");
160 goto failed_free_irq;
161 }
162
163 return 0;
164
165failed_free_irq:
166 free_irq(irq, r);
167failed_free_input:
168 input_free_device(input_dev);
169failed_free_io:
170 iounmap(r->mmio_base);
171failed_free:
172 kfree(r);
173 return err;
174}
175
176static int __devexit pxa930_rotary_remove(struct platform_device *pdev)
177{
178 struct pxa930_rotary *r = platform_get_drvdata(pdev);
179
180 free_irq(platform_get_irq(pdev, 0), r);
181 input_unregister_device(r->input_dev);
182 iounmap(r->mmio_base);
183 platform_set_drvdata(pdev, NULL);
184 kfree(r);
185
186 return 0;
187}
188
189static struct platform_driver pxa930_rotary_driver = {
190 .driver = {
191 .name = "pxa930-rotary",
192 .owner = THIS_MODULE,
193 },
194 .probe = pxa930_rotary_probe,
195 .remove = __devexit_p(pxa930_rotary_remove),
196};
197
198static int __init pxa930_rotary_init(void)
199{
200 return platform_driver_register(&pxa930_rotary_driver);
201}
202module_init(pxa930_rotary_init);
203
204static void __exit pxa930_rotary_exit(void)
205{
206 platform_driver_unregister(&pxa930_rotary_driver);
207}
208module_exit(pxa930_rotary_exit);
209
210MODULE_LICENSE("GPL");
211MODULE_DESCRIPTION("Driver for PXA93x Enhanced Rotary Controller");
212MODULE_AUTHOR("Yao Yong <yaoyong@marvell.com>");
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index 43aaa5cebd12..d6a30cee7bc7 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -52,13 +52,13 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
52 spin_lock_irqsave(&i8253_lock, flags); 52 spin_lock_irqsave(&i8253_lock, flags);
53 53
54 if (count) { 54 if (count) {
55 /* enable counter 2 */
56 outb_p(inb_p(0x61) | 3, 0x61);
57 /* set command for counter 2, 2 byte write */ 55 /* set command for counter 2, 2 byte write */
58 outb_p(0xB6, 0x43); 56 outb_p(0xB6, 0x43);
59 /* select desired HZ */ 57 /* select desired HZ */
60 outb_p(count & 0xff, 0x42); 58 outb_p(count & 0xff, 0x42);
61 outb((count >> 8) & 0xff, 0x42); 59 outb((count >> 8) & 0xff, 0x42);
60 /* enable counter 2 */
61 outb_p(inb_p(0x61) | 3, 0x61);
62 } else { 62 } else {
63 /* disable counter 2 */ 63 /* disable counter 2 */
64 outb(inb_p(0x61) & 0xFC, 0x61); 64 outb(inb_p(0x61) & 0xFC, 0x61);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 223d56d5555b..46b7caeb2817 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -37,6 +37,7 @@
37#include <linux/fs.h> 37#include <linux/fs.h>
38#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
39#include <linux/uinput.h> 39#include <linux/uinput.h>
40#include "../input-compat.h"
40 41
41static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 42static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
42{ 43{
@@ -78,6 +79,7 @@ static struct uinput_request* uinput_request_find(struct uinput_device *udev, in
78 /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ 79 /* Find an input request, by ID. Returns NULL if the ID isn't valid. */
79 if (id >= UINPUT_NUM_REQUESTS || id < 0) 80 if (id >= UINPUT_NUM_REQUESTS || id < 0)
80 return NULL; 81 return NULL;
82
81 return udev->requests[id]; 83 return udev->requests[id];
82} 84}
83 85
@@ -127,6 +129,17 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff
127 struct uinput_request request; 129 struct uinput_request request;
128 int retval; 130 int retval;
129 131
132 /*
133 * uinput driver does not currently support periodic effects with
134 * custom waveform since it does not have a way to pass buffer of
135 * samples (custom_data) to userspace. If ever there is a device
136 * supporting custom waveforms we would need to define an additional
137 * ioctl (UI_UPLOAD_SAMPLES) but for now we just bail out.
138 */
139 if (effect->type == FF_PERIODIC &&
140 effect->u.periodic.waveform == FF_CUSTOM)
141 return -EINVAL;
142
130 request.id = -1; 143 request.id = -1;
131 init_completion(&request.done); 144 init_completion(&request.done);
132 request.code = UI_FF_UPLOAD; 145 request.code = UI_FF_UPLOAD;
@@ -353,15 +366,15 @@ static inline ssize_t uinput_inject_event(struct uinput_device *udev, const char
353{ 366{
354 struct input_event ev; 367 struct input_event ev;
355 368
356 if (count != sizeof(struct input_event)) 369 if (count < input_event_size())
357 return -EINVAL; 370 return -EINVAL;
358 371
359 if (copy_from_user(&ev, buffer, sizeof(struct input_event))) 372 if (input_event_from_user(buffer, &ev))
360 return -EFAULT; 373 return -EFAULT;
361 374
362 input_event(udev->dev, ev.type, ev.code, ev.value); 375 input_event(udev->dev, ev.type, ev.code, ev.value);
363 376
364 return sizeof(struct input_event); 377 return input_event_size();
365} 378}
366 379
367static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 380static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
@@ -407,13 +420,13 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count,
407 goto out; 420 goto out;
408 } 421 }
409 422
410 while (udev->head != udev->tail && retval + sizeof(struct input_event) <= count) { 423 while (udev->head != udev->tail && retval + input_event_size() <= count) {
411 if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event))) { 424 if (input_event_to_user(buffer + retval, &udev->buff[udev->tail])) {
412 retval = -EFAULT; 425 retval = -EFAULT;
413 goto out; 426 goto out;
414 } 427 }
415 udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; 428 udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
416 retval += sizeof(struct input_event); 429 retval += input_event_size();
417 } 430 }
418 431
419 out: 432 out:
@@ -444,6 +457,93 @@ static int uinput_release(struct inode *inode, struct file *file)
444 return 0; 457 return 0;
445} 458}
446 459
460#ifdef CONFIG_COMPAT
461struct uinput_ff_upload_compat {
462 int request_id;
463 int retval;
464 struct ff_effect_compat effect;
465 struct ff_effect_compat old;
466};
467
468static int uinput_ff_upload_to_user(char __user *buffer,
469 const struct uinput_ff_upload *ff_up)
470{
471 if (INPUT_COMPAT_TEST) {
472 struct uinput_ff_upload_compat ff_up_compat;
473
474 ff_up_compat.request_id = ff_up->request_id;
475 ff_up_compat.retval = ff_up->retval;
476 /*
477 * It so happens that the pointer that gives us the trouble
478 * is the last field in the structure. Since we don't support
479 * custom waveforms in uinput anyway we can just copy the whole
480 * thing (to the compat size) and ignore the pointer.
481 */
482 memcpy(&ff_up_compat.effect, &ff_up->effect,
483 sizeof(struct ff_effect_compat));
484 memcpy(&ff_up_compat.old, &ff_up->old,
485 sizeof(struct ff_effect_compat));
486
487 if (copy_to_user(buffer, &ff_up_compat,
488 sizeof(struct uinput_ff_upload_compat)))
489 return -EFAULT;
490 } else {
491 if (copy_to_user(buffer, ff_up,
492 sizeof(struct uinput_ff_upload)))
493 return -EFAULT;
494 }
495
496 return 0;
497}
498
499static int uinput_ff_upload_from_user(const char __user *buffer,
500 struct uinput_ff_upload *ff_up)
501{
502 if (INPUT_COMPAT_TEST) {
503 struct uinput_ff_upload_compat ff_up_compat;
504
505 if (copy_from_user(&ff_up_compat, buffer,
506 sizeof(struct uinput_ff_upload_compat)))
507 return -EFAULT;
508
509 ff_up->request_id = ff_up_compat.request_id;
510 ff_up->retval = ff_up_compat.retval;
511 memcpy(&ff_up->effect, &ff_up_compat.effect,
512 sizeof(struct ff_effect_compat));
513 memcpy(&ff_up->old, &ff_up_compat.old,
514 sizeof(struct ff_effect_compat));
515
516 } else {
517 if (copy_from_user(ff_up, buffer,
518 sizeof(struct uinput_ff_upload)))
519 return -EFAULT;
520 }
521
522 return 0;
523}
524
525#else
526
527static int uinput_ff_upload_to_user(char __user *buffer,
528 const struct uinput_ff_upload *ff_up)
529{
530 if (copy_to_user(buffer, ff_up, sizeof(struct uinput_ff_upload)))
531 return -EFAULT;
532
533 return 0;
534}
535
536static int uinput_ff_upload_from_user(const char __user *buffer,
537 struct uinput_ff_upload *ff_up)
538{
539 if (copy_from_user(ff_up, buffer, sizeof(struct uinput_ff_upload)))
540 return -EFAULT;
541
542 return 0;
543}
544
545#endif
546
447#define uinput_set_bit(_arg, _bit, _max) \ 547#define uinput_set_bit(_arg, _bit, _max) \
448({ \ 548({ \
449 int __ret = 0; \ 549 int __ret = 0; \
@@ -455,19 +555,17 @@ static int uinput_release(struct inode *inode, struct file *file)
455 __ret; \ 555 __ret; \
456}) 556})
457 557
458static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 558static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
559 unsigned long arg, void __user *p)
459{ 560{
460 int retval; 561 int retval;
461 struct uinput_device *udev; 562 struct uinput_device *udev = file->private_data;
462 void __user *p = (void __user *)arg;
463 struct uinput_ff_upload ff_up; 563 struct uinput_ff_upload ff_up;
464 struct uinput_ff_erase ff_erase; 564 struct uinput_ff_erase ff_erase;
465 struct uinput_request *req; 565 struct uinput_request *req;
466 int length; 566 int length;
467 char *phys; 567 char *phys;
468 568
469 udev = file->private_data;
470
471 retval = mutex_lock_interruptible(&udev->mutex); 569 retval = mutex_lock_interruptible(&udev->mutex);
472 if (retval) 570 if (retval)
473 return retval; 571 return retval;
@@ -549,26 +647,24 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
549 break; 647 break;
550 648
551 case UI_BEGIN_FF_UPLOAD: 649 case UI_BEGIN_FF_UPLOAD:
552 if (copy_from_user(&ff_up, p, sizeof(ff_up))) { 650 retval = uinput_ff_upload_from_user(p, &ff_up);
553 retval = -EFAULT; 651 if (retval)
554 break; 652 break;
555 } 653
556 req = uinput_request_find(udev, ff_up.request_id); 654 req = uinput_request_find(udev, ff_up.request_id);
557 if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) { 655 if (!req || req->code != UI_FF_UPLOAD || !req->u.upload.effect) {
558 retval = -EINVAL; 656 retval = -EINVAL;
559 break; 657 break;
560 } 658 }
659
561 ff_up.retval = 0; 660 ff_up.retval = 0;
562 memcpy(&ff_up.effect, req->u.upload.effect, sizeof(struct ff_effect)); 661 ff_up.effect = *req->u.upload.effect;
563 if (req->u.upload.old) 662 if (req->u.upload.old)
564 memcpy(&ff_up.old, req->u.upload.old, sizeof(struct ff_effect)); 663 ff_up.old = *req->u.upload.old;
565 else 664 else
566 memset(&ff_up.old, 0, sizeof(struct ff_effect)); 665 memset(&ff_up.old, 0, sizeof(struct ff_effect));
567 666
568 if (copy_to_user(p, &ff_up, sizeof(ff_up))) { 667 retval = uinput_ff_upload_to_user(p, &ff_up);
569 retval = -EFAULT;
570 break;
571 }
572 break; 668 break;
573 669
574 case UI_BEGIN_FF_ERASE: 670 case UI_BEGIN_FF_ERASE:
@@ -576,29 +672,34 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
576 retval = -EFAULT; 672 retval = -EFAULT;
577 break; 673 break;
578 } 674 }
675
579 req = uinput_request_find(udev, ff_erase.request_id); 676 req = uinput_request_find(udev, ff_erase.request_id);
580 if (!(req && req->code == UI_FF_ERASE)) { 677 if (!req || req->code != UI_FF_ERASE) {
581 retval = -EINVAL; 678 retval = -EINVAL;
582 break; 679 break;
583 } 680 }
681
584 ff_erase.retval = 0; 682 ff_erase.retval = 0;
585 ff_erase.effect_id = req->u.effect_id; 683 ff_erase.effect_id = req->u.effect_id;
586 if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) { 684 if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) {
587 retval = -EFAULT; 685 retval = -EFAULT;
588 break; 686 break;
589 } 687 }
688
590 break; 689 break;
591 690
592 case UI_END_FF_UPLOAD: 691 case UI_END_FF_UPLOAD:
593 if (copy_from_user(&ff_up, p, sizeof(ff_up))) { 692 retval = uinput_ff_upload_from_user(p, &ff_up);
594 retval = -EFAULT; 693 if (retval)
595 break; 694 break;
596 } 695
597 req = uinput_request_find(udev, ff_up.request_id); 696 req = uinput_request_find(udev, ff_up.request_id);
598 if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) { 697 if (!req || req->code != UI_FF_UPLOAD ||
698 !req->u.upload.effect) {
599 retval = -EINVAL; 699 retval = -EINVAL;
600 break; 700 break;
601 } 701 }
702
602 req->retval = ff_up.retval; 703 req->retval = ff_up.retval;
603 uinput_request_done(udev, req); 704 uinput_request_done(udev, req);
604 break; 705 break;
@@ -608,11 +709,13 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
608 retval = -EFAULT; 709 retval = -EFAULT;
609 break; 710 break;
610 } 711 }
712
611 req = uinput_request_find(udev, ff_erase.request_id); 713 req = uinput_request_find(udev, ff_erase.request_id);
612 if (!(req && req->code == UI_FF_ERASE)) { 714 if (!req || req->code != UI_FF_ERASE) {
613 retval = -EINVAL; 715 retval = -EINVAL;
614 break; 716 break;
615 } 717 }
718
616 req->retval = ff_erase.retval; 719 req->retval = ff_erase.retval;
617 uinput_request_done(udev, req); 720 uinput_request_done(udev, req);
618 break; 721 break;
@@ -626,6 +729,18 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
626 return retval; 729 return retval;
627} 730}
628 731
732static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
733{
734 return uinput_ioctl_handler(file, cmd, arg, (void __user *)arg);
735}
736
737#ifdef CONFIG_COMPAT
738static long uinput_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
739{
740 return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
741}
742#endif
743
629static const struct file_operations uinput_fops = { 744static const struct file_operations uinput_fops = {
630 .owner = THIS_MODULE, 745 .owner = THIS_MODULE,
631 .open = uinput_open, 746 .open = uinput_open,
@@ -634,6 +749,9 @@ static const struct file_operations uinput_fops = {
634 .write = uinput_write, 749 .write = uinput_write,
635 .poll = uinput_poll, 750 .poll = uinput_poll,
636 .unlocked_ioctl = uinput_ioctl, 751 .unlocked_ioctl = uinput_ioctl,
752#ifdef CONFIG_COMPAT
753 .compat_ioctl = uinput_compat_ioctl,
754#endif
637}; 755};
638 756
639static struct miscdevice uinput_misc = { 757static struct miscdevice uinput_misc = {
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 4e9934259775..093c8c1bca74 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -286,4 +286,10 @@ config MOUSE_GPIO
286 To compile this driver as a module, choose M here: the 286 To compile this driver as a module, choose M here: the
287 module will be called gpio_mouse. 287 module will be called gpio_mouse.
288 288
289config MOUSE_PXA930_TRKBALL
290 tristate "PXA930 Trackball mouse"
291 depends on CPU_PXA930 || CPU_PXA935
292 help
293 Say Y here to support PXA930 Trackball mouse.
294
289endif 295endif
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 96f1dd8037f8..8c8a1f236e28 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -4,19 +4,20 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o 7obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o
8obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o 8obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
9obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o 9obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
10obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o 10obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
11obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o 11obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o
12obj-$(CONFIG_MOUSE_INPORT) += inport.o 12obj-$(CONFIG_MOUSE_INPORT) += inport.o
13obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o 13obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
14obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o 14obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o
15obj-$(CONFIG_MOUSE_PS2) += psmouse.o 15obj-$(CONFIG_MOUSE_PS2) += psmouse.o
16obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o 16obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o
17obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o 17obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
18obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o 18obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
19obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o 19obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
20obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
20 21
21psmouse-objs := psmouse-base.o synaptics.o 22psmouse-objs := psmouse-base.o synaptics.o
22 23
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 079816e6b23b..454b96112f03 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2005-2008 Johannes Berg (johannes@sipsolutions.net) 5 * Copyright (C) 2005-2008 Johannes Berg (johannes@sipsolutions.net)
6 * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 6 * Copyright (C) 2005-2008 Stelian Pop (stelian@popies.net)
7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) 9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
@@ -35,16 +35,74 @@
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/usb/input.h> 36#include <linux/usb/input.h>
37 37
38/* Type of touchpad */ 38/*
39enum atp_touchpad_type { 39 * Note: We try to keep the touchpad aspect ratio while still doing only
40 ATP_FOUNTAIN, 40 * simple arithmetics:
41 ATP_GEYSER1, 41 * 0 <= x <= (xsensors - 1) * xfact
42 ATP_GEYSER2, 42 * 0 <= y <= (ysensors - 1) * yfact
43 ATP_GEYSER3, 43 */
44 ATP_GEYSER4 44struct atp_info {
45 int xsensors; /* number of X sensors */
46 int xsensors_17; /* 17" models have more sensors */
47 int ysensors; /* number of Y sensors */
48 int xfact; /* X multiplication factor */
49 int yfact; /* Y multiplication factor */
50 int datalen; /* size of USB transfers */
51 void (*callback)(struct urb *); /* callback function */
52};
53
54static void atp_complete_geyser_1_2(struct urb *urb);
55static void atp_complete_geyser_3_4(struct urb *urb);
56
57static const struct atp_info fountain_info = {
58 .xsensors = 16,
59 .xsensors_17 = 26,
60 .ysensors = 16,
61 .xfact = 64,
62 .yfact = 43,
63 .datalen = 81,
64 .callback = atp_complete_geyser_1_2,
65};
66
67static const struct atp_info geyser1_info = {
68 .xsensors = 16,
69 .xsensors_17 = 26,
70 .ysensors = 16,
71 .xfact = 64,
72 .yfact = 43,
73 .datalen = 81,
74 .callback = atp_complete_geyser_1_2,
75};
76
77static const struct atp_info geyser2_info = {
78 .xsensors = 15,
79 .xsensors_17 = 20,
80 .ysensors = 9,
81 .xfact = 64,
82 .yfact = 43,
83 .datalen = 64,
84 .callback = atp_complete_geyser_1_2,
85};
86
87static const struct atp_info geyser3_info = {
88 .xsensors = 20,
89 .ysensors = 10,
90 .xfact = 64,
91 .yfact = 64,
92 .datalen = 64,
93 .callback = atp_complete_geyser_3_4,
45}; 94};
46 95
47#define ATP_DEVICE(prod, type) \ 96static const struct atp_info geyser4_info = {
97 .xsensors = 20,
98 .ysensors = 10,
99 .xfact = 64,
100 .yfact = 64,
101 .datalen = 64,
102 .callback = atp_complete_geyser_3_4,
103};
104
105#define ATP_DEVICE(prod, info) \
48{ \ 106{ \
49 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ 107 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
50 USB_DEVICE_ID_MATCH_INT_CLASS | \ 108 USB_DEVICE_ID_MATCH_INT_CLASS | \
@@ -53,7 +111,7 @@ enum atp_touchpad_type {
53 .idProduct = (prod), \ 111 .idProduct = (prod), \
54 .bInterfaceClass = 0x03, \ 112 .bInterfaceClass = 0x03, \
55 .bInterfaceProtocol = 0x02, \ 113 .bInterfaceProtocol = 0x02, \
56 .driver_info = ATP_ ## type, \ 114 .driver_info = (unsigned long) &info, \
57} 115}
58 116
59/* 117/*
@@ -62,43 +120,39 @@ enum atp_touchpad_type {
62 * According to Info.plist Geyser IV is the same as Geyser III.) 120 * According to Info.plist Geyser IV is the same as Geyser III.)
63 */ 121 */
64 122
65static struct usb_device_id atp_table [] = { 123static struct usb_device_id atp_table[] = {
66 /* PowerBooks Feb 2005, iBooks G4 */ 124 /* PowerBooks Feb 2005, iBooks G4 */
67 ATP_DEVICE(0x020e, FOUNTAIN), /* FOUNTAIN ANSI */ 125 ATP_DEVICE(0x020e, fountain_info), /* FOUNTAIN ANSI */
68 ATP_DEVICE(0x020f, FOUNTAIN), /* FOUNTAIN ISO */ 126 ATP_DEVICE(0x020f, fountain_info), /* FOUNTAIN ISO */
69 ATP_DEVICE(0x030a, FOUNTAIN), /* FOUNTAIN TP ONLY */ 127 ATP_DEVICE(0x030a, fountain_info), /* FOUNTAIN TP ONLY */
70 ATP_DEVICE(0x030b, GEYSER1), /* GEYSER 1 TP ONLY */ 128 ATP_DEVICE(0x030b, geyser1_info), /* GEYSER 1 TP ONLY */
71 129
72 /* PowerBooks Oct 2005 */ 130 /* PowerBooks Oct 2005 */
73 ATP_DEVICE(0x0214, GEYSER2), /* GEYSER 2 ANSI */ 131 ATP_DEVICE(0x0214, geyser2_info), /* GEYSER 2 ANSI */
74 ATP_DEVICE(0x0215, GEYSER2), /* GEYSER 2 ISO */ 132 ATP_DEVICE(0x0215, geyser2_info), /* GEYSER 2 ISO */
75 ATP_DEVICE(0x0216, GEYSER2), /* GEYSER 2 JIS */ 133 ATP_DEVICE(0x0216, geyser2_info), /* GEYSER 2 JIS */
76 134
77 /* Core Duo MacBook & MacBook Pro */ 135 /* Core Duo MacBook & MacBook Pro */
78 ATP_DEVICE(0x0217, GEYSER3), /* GEYSER 3 ANSI */ 136 ATP_DEVICE(0x0217, geyser3_info), /* GEYSER 3 ANSI */
79 ATP_DEVICE(0x0218, GEYSER3), /* GEYSER 3 ISO */ 137 ATP_DEVICE(0x0218, geyser3_info), /* GEYSER 3 ISO */
80 ATP_DEVICE(0x0219, GEYSER3), /* GEYSER 3 JIS */ 138 ATP_DEVICE(0x0219, geyser3_info), /* GEYSER 3 JIS */
81 139
82 /* Core2 Duo MacBook & MacBook Pro */ 140 /* Core2 Duo MacBook & MacBook Pro */
83 ATP_DEVICE(0x021a, GEYSER4), /* GEYSER 4 ANSI */ 141 ATP_DEVICE(0x021a, geyser4_info), /* GEYSER 4 ANSI */
84 ATP_DEVICE(0x021b, GEYSER4), /* GEYSER 4 ISO */ 142 ATP_DEVICE(0x021b, geyser4_info), /* GEYSER 4 ISO */
85 ATP_DEVICE(0x021c, GEYSER4), /* GEYSER 4 JIS */ 143 ATP_DEVICE(0x021c, geyser4_info), /* GEYSER 4 JIS */
86 144
87 /* Core2 Duo MacBook3,1 */ 145 /* Core2 Duo MacBook3,1 */
88 ATP_DEVICE(0x0229, GEYSER4), /* GEYSER 4 HF ANSI */ 146 ATP_DEVICE(0x0229, geyser4_info), /* GEYSER 4 HF ANSI */
89 ATP_DEVICE(0x022a, GEYSER4), /* GEYSER 4 HF ISO */ 147 ATP_DEVICE(0x022a, geyser4_info), /* GEYSER 4 HF ISO */
90 ATP_DEVICE(0x022b, GEYSER4), /* GEYSER 4 HF JIS */ 148 ATP_DEVICE(0x022b, geyser4_info), /* GEYSER 4 HF JIS */
91 149
92 /* Terminating entry */ 150 /* Terminating entry */
93 { } 151 { }
94}; 152};
95MODULE_DEVICE_TABLE(usb, atp_table); 153MODULE_DEVICE_TABLE(usb, atp_table);
96 154
97/* 155/* maximum number of sensors */
98 * number of sensors. Note that only 16 instead of 26 X (horizontal)
99 * sensors exist on 12" and 15" PowerBooks. All models have 16 Y
100 * (vertical) sensors.
101 */
102#define ATP_XSENSORS 26 156#define ATP_XSENSORS 26
103#define ATP_YSENSORS 16 157#define ATP_YSENSORS 16
104 158
@@ -107,21 +161,6 @@ MODULE_DEVICE_TABLE(usb, atp_table);
107 161
108/* maximum pressure this driver will report */ 162/* maximum pressure this driver will report */
109#define ATP_PRESSURE 300 163#define ATP_PRESSURE 300
110/*
111 * multiplication factor for the X and Y coordinates.
112 * We try to keep the touchpad aspect ratio while still doing only simple
113 * arithmetics.
114 * The factors below give coordinates like:
115 *
116 * 0 <= x < 960 on 12" and 15" Powerbooks
117 * 0 <= x < 1600 on 17" Powerbooks and 17" MacBook Pro
118 * 0 <= x < 1216 on MacBooks and 15" MacBook Pro
119 *
120 * 0 <= y < 646 on all Powerbooks
121 * 0 <= y < 774 on all MacBooks
122 */
123#define ATP_XFACT 64
124#define ATP_YFACT 43
125 164
126/* 165/*
127 * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is 166 * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is
@@ -159,7 +198,7 @@ struct atp {
159 struct urb *urb; /* usb request block */ 198 struct urb *urb; /* usb request block */
160 u8 *data; /* transferred data */ 199 u8 *data; /* transferred data */
161 struct input_dev *input; /* input dev */ 200 struct input_dev *input; /* input dev */
162 enum atp_touchpad_type type; /* type of touchpad */ 201 const struct atp_info *info; /* touchpad model */
163 bool open; 202 bool open;
164 bool valid; /* are the samples valid? */ 203 bool valid; /* are the samples valid? */
165 bool size_detect_done; 204 bool size_detect_done;
@@ -169,7 +208,6 @@ struct atp {
169 signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; 208 signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS];
170 signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; 209 signed char xy_old[ATP_XSENSORS + ATP_YSENSORS];
171 int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; 210 int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
172 int datalen; /* size of USB transfer */
173 int idlecount; /* number of empty packets */ 211 int idlecount; /* number of empty packets */
174 struct work_struct work; 212 struct work_struct work;
175}; 213};
@@ -359,7 +397,7 @@ static int atp_status_check(struct urb *urb)
359 if (!dev->overflow_warned) { 397 if (!dev->overflow_warned) {
360 printk(KERN_WARNING "appletouch: OVERFLOW with data " 398 printk(KERN_WARNING "appletouch: OVERFLOW with data "
361 "length %d, actual length is %d\n", 399 "length %d, actual length is %d\n",
362 dev->datalen, dev->urb->actual_length); 400 dev->info->datalen, dev->urb->actual_length);
363 dev->overflow_warned = true; 401 dev->overflow_warned = true;
364 } 402 }
365 case -ECONNRESET: 403 case -ECONNRESET:
@@ -377,7 +415,7 @@ static int atp_status_check(struct urb *urb)
377 } 415 }
378 416
379 /* drop incomplete datasets */ 417 /* drop incomplete datasets */
380 if (dev->urb->actual_length != dev->datalen) { 418 if (dev->urb->actual_length != dev->info->datalen) {
381 dprintk("appletouch: incomplete data package" 419 dprintk("appletouch: incomplete data package"
382 " (first byte: %d, length: %d).\n", 420 " (first byte: %d, length: %d).\n",
383 dev->data[0], dev->urb->actual_length); 421 dev->data[0], dev->urb->actual_length);
@@ -387,6 +425,25 @@ static int atp_status_check(struct urb *urb)
387 return ATP_URB_STATUS_SUCCESS; 425 return ATP_URB_STATUS_SUCCESS;
388} 426}
389 427
428static void atp_detect_size(struct atp *dev)
429{
430 int i;
431
432 /* 17" Powerbooks have extra X sensors */
433 for (i = dev->info->xsensors; i < ATP_XSENSORS; i++) {
434 if (dev->xy_cur[i]) {
435
436 printk(KERN_INFO "appletouch: 17\" model detected.\n");
437
438 input_set_abs_params(dev->input, ABS_X, 0,
439 (dev->info->xsensors_17 - 1) *
440 dev->info->xfact - 1,
441 ATP_FUZZ, 0);
442 break;
443 }
444 }
445}
446
390/* 447/*
391 * USB interrupt callback functions 448 * USB interrupt callback functions
392 */ 449 */
@@ -407,7 +464,7 @@ static void atp_complete_geyser_1_2(struct urb *urb)
407 goto exit; 464 goto exit;
408 465
409 /* reorder the sensors values */ 466 /* reorder the sensors values */
410 if (dev->type == ATP_GEYSER2) { 467 if (dev->info == &geyser2_info) {
411 memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); 468 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
412 469
413 /* 470 /*
@@ -437,8 +494,8 @@ static void atp_complete_geyser_1_2(struct urb *urb)
437 dev->xy_cur[i + 24] = dev->data[5 * i + 44]; 494 dev->xy_cur[i + 24] = dev->data[5 * i + 44];
438 495
439 /* Y values */ 496 /* Y values */
440 dev->xy_cur[i + 26] = dev->data[5 * i + 1]; 497 dev->xy_cur[ATP_XSENSORS + i] = dev->data[5 * i + 1];
441 dev->xy_cur[i + 34] = dev->data[5 * i + 3]; 498 dev->xy_cur[ATP_XSENSORS + i + 8] = dev->data[5 * i + 3];
442 } 499 }
443 } 500 }
444 501
@@ -453,32 +510,8 @@ static void atp_complete_geyser_1_2(struct urb *urb)
453 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 510 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
454 511
455 /* Perform size detection, if not done already */ 512 /* Perform size detection, if not done already */
456 if (!dev->size_detect_done) { 513 if (unlikely(!dev->size_detect_done)) {
457 514 atp_detect_size(dev);
458 /* 17" Powerbooks have extra X sensors */
459 for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
460 i < ATP_XSENSORS; i++) {
461 if (!dev->xy_cur[i])
462 continue;
463
464 printk(KERN_INFO
465 "appletouch: 17\" model detected.\n");
466
467 if (dev->type == ATP_GEYSER2)
468 input_set_abs_params(dev->input, ABS_X,
469 0,
470 (20 - 1) *
471 ATP_XFACT - 1,
472 ATP_FUZZ, 0);
473 else
474 input_set_abs_params(dev->input, ABS_X,
475 0,
476 (26 - 1) *
477 ATP_XFACT - 1,
478 ATP_FUZZ, 0);
479 break;
480 }
481
482 dev->size_detect_done = 1; 515 dev->size_detect_done = 1;
483 goto exit; 516 goto exit;
484 } 517 }
@@ -499,10 +532,10 @@ static void atp_complete_geyser_1_2(struct urb *urb)
499 dbg_dump("accumulator", dev->xy_acc); 532 dbg_dump("accumulator", dev->xy_acc);
500 533
501 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, 534 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
502 ATP_XFACT, &x_z, &x_f); 535 dev->info->xfact, &x_z, &x_f);
503 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 536 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
504 ATP_YFACT, &y_z, &y_f); 537 dev->info->yfact, &y_z, &y_f);
505 key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON; 538 key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON;
506 539
507 if (x && y) { 540 if (x && y) {
508 if (dev->x_old != -1) { 541 if (dev->x_old != -1) {
@@ -583,7 +616,7 @@ static void atp_complete_geyser_3_4(struct urb *urb)
583 dbg_dump("sample", dev->xy_cur); 616 dbg_dump("sample", dev->xy_cur);
584 617
585 /* Just update the base values (i.e. touchpad in untouched state) */ 618 /* Just update the base values (i.e. touchpad in untouched state) */
586 if (dev->data[dev->datalen - 1] & ATP_STATUS_BASE_UPDATE) { 619 if (dev->data[dev->info->datalen - 1] & ATP_STATUS_BASE_UPDATE) {
587 620
588 dprintk(KERN_DEBUG "appletouch: updated base values\n"); 621 dprintk(KERN_DEBUG "appletouch: updated base values\n");
589 622
@@ -610,10 +643,10 @@ static void atp_complete_geyser_3_4(struct urb *urb)
610 dbg_dump("accumulator", dev->xy_acc); 643 dbg_dump("accumulator", dev->xy_acc);
611 644
612 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, 645 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
613 ATP_XFACT, &x_z, &x_f); 646 dev->info->xfact, &x_z, &x_f);
614 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 647 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
615 ATP_YFACT, &y_z, &y_f); 648 dev->info->yfact, &y_z, &y_f);
616 key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON; 649 key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON;
617 650
618 if (x && y) { 651 if (x && y) {
619 if (dev->x_old != -1) { 652 if (dev->x_old != -1) {
@@ -705,7 +738,7 @@ static int atp_handle_geyser(struct atp *dev)
705{ 738{
706 struct usb_device *udev = dev->udev; 739 struct usb_device *udev = dev->udev;
707 740
708 if (dev->type != ATP_FOUNTAIN) { 741 if (dev->info != &fountain_info) {
709 /* switch to raw sensor mode */ 742 /* switch to raw sensor mode */
710 if (atp_geyser_init(udev)) 743 if (atp_geyser_init(udev))
711 return -EIO; 744 return -EIO;
@@ -726,6 +759,7 @@ static int atp_probe(struct usb_interface *iface,
726 struct usb_endpoint_descriptor *endpoint; 759 struct usb_endpoint_descriptor *endpoint;
727 int int_in_endpointAddr = 0; 760 int int_in_endpointAddr = 0;
728 int i, error = -ENOMEM; 761 int i, error = -ENOMEM;
762 const struct atp_info *info = (const struct atp_info *)id->driver_info;
729 763
730 /* set up the endpoint information */ 764 /* set up the endpoint information */
731 /* use only the first interrupt-in endpoint */ 765 /* use only the first interrupt-in endpoint */
@@ -753,35 +787,22 @@ static int atp_probe(struct usb_interface *iface,
753 787
754 dev->udev = udev; 788 dev->udev = udev;
755 dev->input = input_dev; 789 dev->input = input_dev;
756 dev->type = id->driver_info; 790 dev->info = info;
757 dev->overflow_warned = false; 791 dev->overflow_warned = false;
758 if (dev->type == ATP_FOUNTAIN || dev->type == ATP_GEYSER1)
759 dev->datalen = 81;
760 else
761 dev->datalen = 64;
762 792
763 dev->urb = usb_alloc_urb(0, GFP_KERNEL); 793 dev->urb = usb_alloc_urb(0, GFP_KERNEL);
764 if (!dev->urb) 794 if (!dev->urb)
765 goto err_free_devs; 795 goto err_free_devs;
766 796
767 dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL, 797 dev->data = usb_buffer_alloc(dev->udev, dev->info->datalen, GFP_KERNEL,
768 &dev->urb->transfer_dma); 798 &dev->urb->transfer_dma);
769 if (!dev->data) 799 if (!dev->data)
770 goto err_free_urb; 800 goto err_free_urb;
771 801
772 /* Select the USB complete (callback) function */ 802 usb_fill_int_urb(dev->urb, udev,
773 if (dev->type == ATP_FOUNTAIN || 803 usb_rcvintpipe(udev, int_in_endpointAddr),
774 dev->type == ATP_GEYSER1 || 804 dev->data, dev->info->datalen,
775 dev->type == ATP_GEYSER2) 805 dev->info->callback, dev, 1);
776 usb_fill_int_urb(dev->urb, udev,
777 usb_rcvintpipe(udev, int_in_endpointAddr),
778 dev->data, dev->datalen,
779 atp_complete_geyser_1_2, dev, 1);
780 else
781 usb_fill_int_urb(dev->urb, udev,
782 usb_rcvintpipe(udev, int_in_endpointAddr),
783 dev->data, dev->datalen,
784 atp_complete_geyser_3_4, dev, 1);
785 806
786 error = atp_handle_geyser(dev); 807 error = atp_handle_geyser(dev);
787 if (error) 808 if (error)
@@ -802,35 +823,12 @@ static int atp_probe(struct usb_interface *iface,
802 823
803 set_bit(EV_ABS, input_dev->evbit); 824 set_bit(EV_ABS, input_dev->evbit);
804 825
805 if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) { 826 input_set_abs_params(input_dev, ABS_X, 0,
806 /* 827 (dev->info->xsensors - 1) * dev->info->xfact - 1,
807 * MacBook have 20 X sensors, 10 Y sensors 828 ATP_FUZZ, 0);
808 */ 829 input_set_abs_params(input_dev, ABS_Y, 0,
809 input_set_abs_params(input_dev, ABS_X, 0, 830 (dev->info->ysensors - 1) * dev->info->yfact - 1,
810 ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0); 831 ATP_FUZZ, 0);
811 input_set_abs_params(input_dev, ABS_Y, 0,
812 ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
813 } else if (dev->type == ATP_GEYSER2) {
814 /*
815 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
816 * later.
817 */
818 input_set_abs_params(input_dev, ABS_X, 0,
819 ((15 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
820 input_set_abs_params(input_dev, ABS_Y, 0,
821 ((9 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
822 } else {
823 /*
824 * 12" and 15" Powerbooks only have 16 x sensors,
825 * 17" models are detected later.
826 */
827 input_set_abs_params(input_dev, ABS_X, 0,
828 (16 - 1) * ATP_XFACT - 1,
829 ATP_FUZZ, 0);
830 input_set_abs_params(input_dev, ABS_Y, 0,
831 (ATP_YSENSORS - 1) * ATP_YFACT - 1,
832 ATP_FUZZ, 0);
833 }
834 input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); 832 input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
835 833
836 set_bit(EV_KEY, input_dev->evbit); 834 set_bit(EV_KEY, input_dev->evbit);
@@ -852,7 +850,7 @@ static int atp_probe(struct usb_interface *iface,
852 return 0; 850 return 0;
853 851
854 err_free_buffer: 852 err_free_buffer:
855 usb_buffer_free(dev->udev, dev->datalen, 853 usb_buffer_free(dev->udev, dev->info->datalen,
856 dev->data, dev->urb->transfer_dma); 854 dev->data, dev->urb->transfer_dma);
857 err_free_urb: 855 err_free_urb:
858 usb_free_urb(dev->urb); 856 usb_free_urb(dev->urb);
@@ -871,7 +869,7 @@ static void atp_disconnect(struct usb_interface *iface)
871 if (dev) { 869 if (dev) {
872 usb_kill_urb(dev->urb); 870 usb_kill_urb(dev->urb);
873 input_unregister_device(dev->input); 871 input_unregister_device(dev->input);
874 usb_buffer_free(dev->udev, dev->datalen, 872 usb_buffer_free(dev->udev, dev->info->datalen,
875 dev->data, dev->urb->transfer_dma); 873 dev->data, dev->urb->transfer_dma);
876 usb_free_urb(dev->urb); 874 usb_free_urb(dev->urb);
877 kfree(dev); 875 kfree(dev);
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index 72cf5e33790e..0db8d16c5edd 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -173,7 +173,7 @@ static int __devexit gpio_mouse_remove(struct platform_device *pdev)
173/* work with hotplug and coldplug */ 173/* work with hotplug and coldplug */
174MODULE_ALIAS("platform:gpio_mouse"); 174MODULE_ALIAS("platform:gpio_mouse");
175 175
176struct platform_driver gpio_mouse_device_driver = { 176static struct platform_driver gpio_mouse_device_driver = {
177 .remove = __devexit_p(gpio_mouse_remove), 177 .remove = __devexit_p(gpio_mouse_remove),
178 .driver = { 178 .driver = {
179 .name = "gpio_mouse", 179 .name = "gpio_mouse",
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index 88f04bf2ad6c..81e6ebf323e9 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -48,6 +48,30 @@ module_param(recalib_delta, int, 0644);
48MODULE_PARM_DESC(recalib_delta, 48MODULE_PARM_DESC(recalib_delta,
49 "packets containing a delta this large will cause a recalibration."); 49 "packets containing a delta this large will cause a recalibration.");
50 50
51static int jumpy_delay = 1000;
52module_param(jumpy_delay, int, 0644);
53MODULE_PARM_DESC(jumpy_delay,
54 "delay (ms) before recal after jumpiness detected");
55
56static int spew_delay = 1000;
57module_param(spew_delay, int, 0644);
58MODULE_PARM_DESC(spew_delay,
59 "delay (ms) before recal after packet spew detected");
60
61static int recal_guard_time = 2000;
62module_param(recal_guard_time, int, 0644);
63MODULE_PARM_DESC(recal_guard_time,
64 "interval (ms) during which recal will be restarted if packet received");
65
66static int post_interrupt_delay = 1000;
67module_param(post_interrupt_delay, int, 0644);
68MODULE_PARM_DESC(post_interrupt_delay,
69 "delay (ms) before recal after recal interrupt detected");
70
71static int autorecal = 1;
72module_param(autorecal, int, 0644);
73MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");
74
51/* 75/*
52 * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" 76 * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"
53 * above the pad and still have it send packets. This causes a jump cursor 77 * above the pad and still have it send packets. This causes a jump cursor
@@ -66,7 +90,7 @@ static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y)
66 /* My car gets forty rods to the hogshead and that's the 90 /* My car gets forty rods to the hogshead and that's the
67 * way I likes it! */ 91 * way I likes it! */
68 psmouse_queue_work(psmouse, &priv->recalib_wq, 92 psmouse_queue_work(psmouse, &priv->recalib_wq,
69 msecs_to_jiffies(1000)); 93 msecs_to_jiffies(jumpy_delay));
70 } 94 }
71} 95}
72 96
@@ -103,7 +127,7 @@ static void hgpk_spewing_hack(struct psmouse *psmouse,
103 hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n", 127 hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n",
104 priv->x_tally, priv->y_tally); 128 priv->x_tally, priv->y_tally);
105 psmouse_queue_work(psmouse, &priv->recalib_wq, 129 psmouse_queue_work(psmouse, &priv->recalib_wq,
106 msecs_to_jiffies(1000)); 130 msecs_to_jiffies(spew_delay));
107 } 131 }
108 /* reset every 100 packets */ 132 /* reset every 100 packets */
109 priv->count = 0; 133 priv->count = 0;
@@ -181,7 +205,7 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
181 "packet inside calibration window, " 205 "packet inside calibration window, "
182 "queueing another recalibration\n"); 206 "queueing another recalibration\n");
183 psmouse_queue_work(psmouse, &priv->recalib_wq, 207 psmouse_queue_work(psmouse, &priv->recalib_wq,
184 msecs_to_jiffies(1000)); 208 msecs_to_jiffies(post_interrupt_delay));
185 } 209 }
186 priv->recalib_window = 0; 210 priv->recalib_window = 0;
187 } 211 }
@@ -231,7 +255,7 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse)
231 * If someone's finger *was* on the touchpad, it's probably 255 * If someone's finger *was* on the touchpad, it's probably
232 * miscalibrated. So, we should schedule another recalibration 256 * miscalibrated. So, we should schedule another recalibration
233 */ 257 */
234 priv->recalib_window = jiffies + msecs_to_jiffies(2000); 258 priv->recalib_window = jiffies + msecs_to_jiffies(recal_guard_time);
235 259
236 return 0; 260 return 0;
237} 261}
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
index e532c48410ea..3263ce083bf0 100644
--- a/drivers/input/mouse/hil_ptr.c
+++ b/drivers/input/mouse/hil_ptr.c
@@ -46,7 +46,7 @@
46MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); 46MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
47MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver"); 47MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
48MODULE_LICENSE("Dual BSD/GPL"); 48MODULE_LICENSE("Dual BSD/GPL");
49 49MODULE_ALIAS("serio:ty03pr25id0Fex*");
50 50
51#define TABLET_SIMULATES_MOUSE /* allow tablet to be used as mouse */ 51#define TABLET_SIMULATES_MOUSE /* allow tablet to be used as mouse */
52#undef TABLET_AUTOADJUST /* auto-adjust valid tablet ranges */ 52#undef TABLET_AUTOADJUST /* auto-adjust valid tablet ranges */
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c
new file mode 100644
index 000000000000..a0f45c4fc198
--- /dev/null
+++ b/drivers/input/mouse/pxa930_trkball.c
@@ -0,0 +1,269 @@
1/*
2 * PXA930 track ball mouse driver
3 *
4 * Copyright (C) 2007 Marvell International Ltd.
5 * 2008-02-28: Yong Yao <yaoyong@marvell.com>
6 * initial version
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/input.h>
15#include <linux/version.h>
16#include <linux/interrupt.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/delay.h>
20#include <linux/io.h>
21
22#include <mach/hardware.h>
23#include <mach/pxa930_trkball.h>
24
25/* Trackball Controller Register Definitions */
26#define TBCR (0x000C)
27#define TBCNTR (0x0010)
28#define TBSBC (0x0014)
29
30#define TBCR_TBRST (1 << 1)
31#define TBCR_TBSB (1 << 10)
32
33#define TBCR_Y_FLT(n) (((n) & 0xf) << 6)
34#define TBCR_X_FLT(n) (((n) & 0xf) << 2)
35
36#define TBCNTR_YM(n) (((n) >> 24) & 0xff)
37#define TBCNTR_YP(n) (((n) >> 16) & 0xff)
38#define TBCNTR_XM(n) (((n) >> 8) & 0xff)
39#define TBCNTR_XP(n) ((n) & 0xff)
40
41#define TBSBC_TBSBC (0x1)
42
43struct pxa930_trkball {
44 struct pxa930_trkball_platform_data *pdata;
45
46 /* Memory Mapped Register */
47 struct resource *mem;
48 void __iomem *mmio_base;
49
50 struct input_dev *input;
51};
52
53static irqreturn_t pxa930_trkball_interrupt(int irq, void *dev_id)
54{
55 struct pxa930_trkball *trkball = dev_id;
56 struct input_dev *input = trkball->input;
57 int tbcntr, x, y;
58
59 /* According to the spec software must read TBCNTR twice:
60 * if the read value is the same, the reading is valid
61 */
62 tbcntr = __raw_readl(trkball->mmio_base + TBCNTR);
63
64 if (tbcntr == __raw_readl(trkball->mmio_base + TBCNTR)) {
65 x = (TBCNTR_XP(tbcntr) - TBCNTR_XM(tbcntr)) / 2;
66 y = (TBCNTR_YP(tbcntr) - TBCNTR_YM(tbcntr)) / 2;
67
68 input_report_rel(input, REL_X, x);
69 input_report_rel(input, REL_Y, y);
70 input_sync(input);
71 }
72
73 __raw_writel(TBSBC_TBSBC, trkball->mmio_base + TBSBC);
74 __raw_writel(0, trkball->mmio_base + TBSBC);
75
76 return IRQ_HANDLED;
77}
78
79/* For TBCR, we need to wait for a while to make sure it has been modified. */
80static int write_tbcr(struct pxa930_trkball *trkball, int v)
81{
82 int i = 100;
83
84 __raw_writel(v, trkball->mmio_base + TBCR);
85
86 while (i--) {
87 if (__raw_readl(trkball->mmio_base + TBCR) == v)
88 break;
89 msleep(1);
90 }
91
92 if (i == 0) {
93 pr_err("%s: timed out writing TBCR(%x)!\n", __func__, v);
94 return -ETIMEDOUT;
95 }
96
97 return 0;
98}
99
100static void pxa930_trkball_config(struct pxa930_trkball *trkball)
101{
102 uint32_t tbcr;
103
104 /* According to spec, need to write the filters of x,y to 0xf first! */
105 tbcr = __raw_readl(trkball->mmio_base + TBCR);
106 write_tbcr(trkball, tbcr | TBCR_X_FLT(0xf) | TBCR_Y_FLT(0xf));
107 write_tbcr(trkball, TBCR_X_FLT(trkball->pdata->x_filter) |
108 TBCR_Y_FLT(trkball->pdata->y_filter));
109
110 /* According to spec, set TBCR_TBRST first, before clearing it! */
111 tbcr = __raw_readl(trkball->mmio_base + TBCR);
112 write_tbcr(trkball, tbcr | TBCR_TBRST);
113 write_tbcr(trkball, tbcr & ~TBCR_TBRST);
114
115 __raw_writel(TBSBC_TBSBC, trkball->mmio_base + TBSBC);
116 __raw_writel(0, trkball->mmio_base + TBSBC);
117
118 pr_debug("%s: final TBCR=%x!\n", __func__,
119 __raw_readl(trkball->mmio_base + TBCR));
120}
121
122static int pxa930_trkball_open(struct input_dev *dev)
123{
124 struct pxa930_trkball *trkball = input_get_drvdata(dev);
125
126 pxa930_trkball_config(trkball);
127
128 return 0;
129}
130
131static void pxa930_trkball_disable(struct pxa930_trkball *trkball)
132{
133 uint32_t tbcr = __raw_readl(trkball->mmio_base + TBCR);
134
135 /* Held in reset, gate the 32-KHz input clock off */
136 write_tbcr(trkball, tbcr | TBCR_TBRST);
137}
138
139static void pxa930_trkball_close(struct input_dev *dev)
140{
141 struct pxa930_trkball *trkball = input_get_drvdata(dev);
142
143 pxa930_trkball_disable(trkball);
144}
145
146static int __devinit pxa930_trkball_probe(struct platform_device *pdev)
147{
148 struct pxa930_trkball *trkball;
149 struct input_dev *input;
150 struct resource *res;
151 int irq, error;
152
153 irq = platform_get_irq(pdev, 0);
154 if (irq < 0) {
155 dev_err(&pdev->dev, "failed to get trkball irq\n");
156 return -ENXIO;
157 }
158
159 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
160 if (!res) {
161 dev_err(&pdev->dev, "failed to get register memory\n");
162 return -ENXIO;
163 }
164
165 trkball = kzalloc(sizeof(struct pxa930_trkball), GFP_KERNEL);
166 if (!trkball)
167 return -ENOMEM;
168
169 trkball->pdata = pdev->dev.platform_data;
170 if (!trkball->pdata) {
171 dev_err(&pdev->dev, "no platform data defined\n");
172 error = -EINVAL;
173 goto failed;
174 }
175
176 trkball->mmio_base = ioremap_nocache(res->start, resource_size(res));
177 if (!trkball->mmio_base) {
178 dev_err(&pdev->dev, "failed to ioremap registers\n");
179 error = -ENXIO;
180 goto failed;
181 }
182
183 /* held the module in reset, will be enabled in open() */
184 pxa930_trkball_disable(trkball);
185
186 error = request_irq(irq, pxa930_trkball_interrupt, IRQF_DISABLED,
187 pdev->name, trkball);
188 if (error) {
189 dev_err(&pdev->dev, "failed to request irq: %d\n", ret);
190 goto failed_free_io;
191 }
192
193 platform_set_drvdata(pdev, trkball);
194
195 input = input_allocate_device();
196 if (!input) {
197 dev_err(&pdev->dev, "failed to allocate input device\n");
198 error = -ENOMEM;
199 goto failed_free_irq;
200 }
201
202 input->name = pdev->name;
203 input->id.bustype = BUS_HOST;
204 input->open = pxa930_trkball_open;
205 input->close = pxa930_trkball_close;
206 input->dev.parent = &pdev->dev;
207 input_set_drvdata(input, trkball);
208
209 trkball->input = input;
210
211 input_set_capability(input, EV_REL, REL_X);
212 input_set_capability(input, EV_REL, REL_Y);
213
214 error = input_register_device(input);
215 if (error) {
216 dev_err(&pdev->dev, "unable to register input device\n");
217 goto failed_free_input;
218 }
219
220 return 0;
221
222failed_free_input:
223 input_free_device(input);
224failed_free_irq:
225 free_irq(irq, trkball);
226failed_free_io:
227 iounmap(trkball->mmio_base);
228failed:
229 kfree(trkball);
230 return ret;
231}
232
233static int __devexit pxa930_trkball_remove(struct platform_device *pdev)
234{
235 struct pxa930_trkball *trkball = platform_get_drvdata(pdev);
236 int irq = platform_get_irq(pdev, 0);
237
238 input_unregister_device(trkball->input);
239 free_irq(irq, trkball);
240 iounmap(trkball->mmio_base);
241 kfree(trkball);
242
243 return 0;
244}
245
246static struct platform_driver pxa930_trkball_driver = {
247 .driver = {
248 .name = "pxa930-trkball",
249 },
250 .probe = pxa930_trkball_probe,
251 .remove = __devexit_p(pxa930_trkball_remove),
252};
253
254static int __init pxa930_trkball_init(void)
255{
256 return platform_driver_register(&pxa930_trkball_driver);
257}
258
259static void __exit pxa930_trkball_exit(void)
260{
261 platform_driver_unregister(&pxa930_trkball_driver);
262}
263
264module_init(pxa930_trkball_init);
265module_exit(pxa930_trkball_exit);
266
267MODULE_AUTHOR("Yong Yao <yaoyong@marvell.com>");
268MODULE_DESCRIPTION("PXA930 Trackball Mouse Driver");
269MODULE_LICENSE("GPL");
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index d349c4a5e3e8..865fc69e9bc3 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -445,12 +445,14 @@ static void synaptics_process_packet(struct psmouse *psmouse)
445 445
446 input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); 446 input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
447 input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); 447 input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
448 input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
449 input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
450
451 input_report_key(dev, BTN_LEFT, hw.left); 448 input_report_key(dev, BTN_LEFT, hw.left);
452 input_report_key(dev, BTN_RIGHT, hw.right); 449 input_report_key(dev, BTN_RIGHT, hw.right);
453 450
451 if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
452 input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
453 input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
454 }
455
454 if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) 456 if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
455 input_report_key(dev, BTN_MIDDLE, hw.middle); 457 input_report_key(dev, BTN_MIDDLE, hw.middle);
456 458
@@ -543,12 +545,14 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
543 set_bit(EV_KEY, dev->evbit); 545 set_bit(EV_KEY, dev->evbit);
544 set_bit(BTN_TOUCH, dev->keybit); 546 set_bit(BTN_TOUCH, dev->keybit);
545 set_bit(BTN_TOOL_FINGER, dev->keybit); 547 set_bit(BTN_TOOL_FINGER, dev->keybit);
546 set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
547 set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
548
549 set_bit(BTN_LEFT, dev->keybit); 548 set_bit(BTN_LEFT, dev->keybit);
550 set_bit(BTN_RIGHT, dev->keybit); 549 set_bit(BTN_RIGHT, dev->keybit);
551 550
551 if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
552 set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
553 set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
554 }
555
552 if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) 556 if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
553 set_bit(BTN_MIDDLE, dev->keybit); 557 set_bit(BTN_MIDDLE, dev->keybit);
554 558
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index d8c056fe7e98..ef99a7e6d40c 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -878,8 +878,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
878 mousedev->handle.handler = handler; 878 mousedev->handle.handler = handler;
879 mousedev->handle.private = mousedev; 879 mousedev->handle.private = mousedev;
880 880
881 strlcpy(mousedev->dev.bus_id, mousedev->name, 881 dev_set_name(&mousedev->dev, mousedev->name);
882 sizeof(mousedev->dev.bus_id));
883 mousedev->dev.class = &input_class; 882 mousedev->dev.class = &input_class;
884 if (dev) 883 if (dev)
885 mousedev->dev.parent = &dev->dev; 884 mousedev->dev.parent = &dev->dev;
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index 37586a68d345..7ba9f2b2c041 100644
--- a/drivers/input/serio/hil_mlc.c
+++ b/drivers/input/serio/hil_mlc.c
@@ -934,6 +934,7 @@ int hil_mlc_register(hil_mlc *mlc)
934 snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); 934 snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i);
935 snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); 935 snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i);
936 mlc_serio->id = hil_mlc_serio_id; 936 mlc_serio->id = hil_mlc_serio_id;
937 mlc_serio->id.id = i; /* HIL port no. */
937 mlc_serio->write = hil_mlc_serio_write; 938 mlc_serio->write = hil_mlc_serio_write;
938 mlc_serio->open = hil_mlc_serio_open; 939 mlc_serio->open = hil_mlc_serio_open;
939 mlc_serio->close = hil_mlc_serio_close; 940 mlc_serio->close = hil_mlc_serio_close;
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 29e686388a2c..6fa2deff7446 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -143,6 +143,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
143 DMI_MATCH(DMI_PRODUCT_VERSION, "M606"), 143 DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
144 }, 144 },
145 }, 145 },
146 {
147 .ident = "Gigabyte M912",
148 .matches = {
149 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
150 DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
151 DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
152 },
153 },
146 { } 154 { }
147}; 155};
148 156
@@ -351,6 +359,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
351 DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), 359 DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
352 }, 360 },
353 }, 361 },
362 {
363 .ident = "Dell Vostro 1510",
364 .matches = {
365 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
366 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
367 },
368 },
354 { } 369 { }
355}; 370};
356 371
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 2b304c22c200..67248c31e19a 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -262,9 +262,17 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
262 break; 262 break;
263 263
264 case PS2_RET_NAK: 264 case PS2_RET_NAK:
265 ps2dev->nak = 1; 265 ps2dev->flags |= PS2_FLAG_NAK;
266 ps2dev->nak = PS2_RET_NAK;
266 break; 267 break;
267 268
269 case PS2_RET_ERR:
270 if (ps2dev->flags & PS2_FLAG_NAK) {
271 ps2dev->flags &= ~PS2_FLAG_NAK;
272 ps2dev->nak = PS2_RET_ERR;
273 break;
274 }
275
268 /* 276 /*
269 * Workaround for mice which don't ACK the Get ID command. 277 * Workaround for mice which don't ACK the Get ID command.
270 * These are valid mouse IDs that we recognize. 278 * These are valid mouse IDs that we recognize.
@@ -282,8 +290,11 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
282 } 290 }
283 291
284 292
285 if (!ps2dev->nak && ps2dev->cmdcnt) 293 if (!ps2dev->nak) {
286 ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; 294 ps2dev->flags &= ~PS2_FLAG_NAK;
295 if (ps2dev->cmdcnt)
296 ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
297 }
287 298
288 ps2dev->flags &= ~PS2_FLAG_ACK; 299 ps2dev->flags &= ~PS2_FLAG_ACK;
289 wake_up(&ps2dev->wait); 300 wake_up(&ps2dev->wait);
@@ -329,6 +340,7 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev)
329 if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) 340 if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
330 wake_up(&ps2dev->wait); 341 wake_up(&ps2dev->wait);
331 342
332 ps2dev->flags = 0; 343 /* reset all flags except last nack */
344 ps2dev->flags &= PS2_FLAG_NAK;
333} 345}
334EXPORT_SYMBOL(ps2_cmd_aborted); 346EXPORT_SYMBOL(ps2_cmd_aborted);
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
index 1b404f9e3bff..1dacbe0d9348 100644
--- a/drivers/input/serio/pcips2.c
+++ b/drivers/input/serio/pcips2.c
@@ -153,7 +153,7 @@ static int __devinit pcips2_probe(struct pci_dev *dev, const struct pci_device_i
153 serio->open = pcips2_open; 153 serio->open = pcips2_open;
154 serio->close = pcips2_close; 154 serio->close = pcips2_close;
155 strlcpy(serio->name, pci_name(dev), sizeof(serio->name)); 155 strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
156 strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); 156 strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
157 serio->port_data = ps2if; 157 serio->port_data = ps2if;
158 serio->dev.parent = &dev->dev; 158 serio->dev.parent = &dev->dev;
159 ps2if->io = serio; 159 ps2if->io = serio;
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 2f12d60eee3b..bc033250dfcd 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -546,8 +546,8 @@ static void serio_init_port(struct serio *serio)
546 spin_lock_init(&serio->lock); 546 spin_lock_init(&serio->lock);
547 mutex_init(&serio->drv_mutex); 547 mutex_init(&serio->drv_mutex);
548 device_initialize(&serio->dev); 548 device_initialize(&serio->dev);
549 snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), 549 dev_set_name(&serio->dev, "serio%ld",
550 "serio%ld", (long)atomic_inc_return(&serio_no) - 1); 550 (long)atomic_inc_return(&serio_no) - 1);
551 serio->dev.bus = &serio_bus; 551 serio->dev.bus = &serio_bus;
552 serio->dev.release = serio_release_port; 552 serio->dev.release = serio_release_port;
553 if (serio->parent) { 553 if (serio->parent) {
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index 765007899d9a..ebb22f88c842 100644
--- a/drivers/input/serio/xilinx_ps2.c
+++ b/drivers/input/serio/xilinx_ps2.c
@@ -58,23 +58,20 @@
58 58
59/* Mask for all the Receive Interrupts */ 59/* Mask for all the Receive Interrupts */
60#define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \ 60#define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \
61 XPS2_IPIXR_RX_FULL) 61 XPS2_IPIXR_RX_FULL)
62 62
63/* Mask for all the Interrupts */ 63/* Mask for all the Interrupts */
64#define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \ 64#define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \
65 XPS2_IPIXR_WDT_TOUT) 65 XPS2_IPIXR_WDT_TOUT)
66 66
67/* Global Interrupt Enable mask */ 67/* Global Interrupt Enable mask */
68#define XPS2_GIER_GIE_MASK 0x80000000 68#define XPS2_GIER_GIE_MASK 0x80000000
69 69
70struct xps2data { 70struct xps2data {
71 int irq; 71 int irq;
72 u32 phys_addr;
73 u32 remap_size;
74 spinlock_t lock; 72 spinlock_t lock;
75 u8 rxb; /* Rx buffer */
76 void __iomem *base_address; /* virt. address of control registers */ 73 void __iomem *base_address; /* virt. address of control registers */
77 unsigned int dfl; 74 unsigned int flags;
78 struct serio serio; /* serio */ 75 struct serio serio; /* serio */
79}; 76};
80 77
@@ -82,8 +79,13 @@ struct xps2data {
82/* XPS PS/2 data transmission calls */ 79/* XPS PS/2 data transmission calls */
83/************************************/ 80/************************************/
84 81
85/* 82/**
86 * xps2_recv() will attempt to receive a byte of data from the PS/2 port. 83 * xps2_recv() - attempts to receive a byte from the PS/2 port.
84 * @drvdata: pointer to ps2 device private data structure
85 * @byte: address where the read data will be copied
86 *
87 * If there is any data available in the PS/2 receiver, this functions reads
88 * the data, otherwise it returns error.
87 */ 89 */
88static int xps2_recv(struct xps2data *drvdata, u8 *byte) 90static int xps2_recv(struct xps2data *drvdata, u8 *byte)
89{ 91{
@@ -116,33 +118,27 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id)
116 118
117 /* Check which interrupt is active */ 119 /* Check which interrupt is active */
118 if (intr_sr & XPS2_IPIXR_RX_OVF) 120 if (intr_sr & XPS2_IPIXR_RX_OVF)
119 printk(KERN_WARNING "%s: receive overrun error\n", 121 dev_warn(drvdata->serio.dev.parent, "receive overrun error\n");
120 drvdata->serio.name);
121 122
122 if (intr_sr & XPS2_IPIXR_RX_ERR) 123 if (intr_sr & XPS2_IPIXR_RX_ERR)
123 drvdata->dfl |= SERIO_PARITY; 124 drvdata->flags |= SERIO_PARITY;
124 125
125 if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT)) 126 if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
126 drvdata->dfl |= SERIO_TIMEOUT; 127 drvdata->flags |= SERIO_TIMEOUT;
127 128
128 if (intr_sr & XPS2_IPIXR_RX_FULL) { 129 if (intr_sr & XPS2_IPIXR_RX_FULL) {
129 status = xps2_recv(drvdata, &drvdata->rxb); 130 status = xps2_recv(drvdata, &c);
130 131
131 /* Error, if a byte is not received */ 132 /* Error, if a byte is not received */
132 if (status) { 133 if (status) {
133 printk(KERN_ERR 134 dev_err(drvdata->serio.dev.parent,
134 "%s: wrong rcvd byte count (%d)\n", 135 "wrong rcvd byte count (%d)\n", status);
135 drvdata->serio.name, status);
136 } else { 136 } else {
137 c = drvdata->rxb; 137 serio_interrupt(&drvdata->serio, c, drvdata->flags);
138 serio_interrupt(&drvdata->serio, c, drvdata->dfl); 138 drvdata->flags = 0;
139 drvdata->dfl = 0;
140 } 139 }
141 } 140 }
142 141
143 if (intr_sr & XPS2_IPIXR_TX_ACK)
144 drvdata->dfl = 0;
145
146 return IRQ_HANDLED; 142 return IRQ_HANDLED;
147} 143}
148 144
@@ -150,8 +146,15 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id)
150/* serio callbacks */ 146/* serio callbacks */
151/*******************/ 147/*******************/
152 148
153/* 149/**
154 * sxps2_write() sends a byte out through the PS/2 interface. 150 * sxps2_write() - sends a byte out through the PS/2 port.
151 * @pserio: pointer to the serio structure of the PS/2 port
152 * @c: data that needs to be written to the PS/2 port
153 *
154 * This function checks if the PS/2 transmitter is empty and sends a byte.
155 * Otherwise it returns error. Transmission fails only when nothing is connected
156 * to the PS/2 port. Thats why, we do not try to resend the data in case of a
157 * failure.
155 */ 158 */
156static int sxps2_write(struct serio *pserio, unsigned char c) 159static int sxps2_write(struct serio *pserio, unsigned char c)
157{ 160{
@@ -174,33 +177,39 @@ static int sxps2_write(struct serio *pserio, unsigned char c)
174 return status; 177 return status;
175} 178}
176 179
177/* 180/**
178 * sxps2_open() is called when a port is open by the higher layer. 181 * sxps2_open() - called when a port is opened by the higher layer.
182 * @pserio: pointer to the serio structure of the PS/2 device
183 *
184 * This function requests irq and enables interrupts for the PS/2 device.
179 */ 185 */
180static int sxps2_open(struct serio *pserio) 186static int sxps2_open(struct serio *pserio)
181{ 187{
182 struct xps2data *drvdata = pserio->port_data; 188 struct xps2data *drvdata = pserio->port_data;
183 int retval; 189 int error;
190 u8 c;
184 191
185 retval = request_irq(drvdata->irq, &xps2_interrupt, 0, 192 error = request_irq(drvdata->irq, &xps2_interrupt, 0,
186 DRIVER_NAME, drvdata); 193 DRIVER_NAME, drvdata);
187 if (retval) { 194 if (error) {
188 printk(KERN_ERR 195 dev_err(drvdata->serio.dev.parent,
189 "%s: Couldn't allocate interrupt %d\n", 196 "Couldn't allocate interrupt %d\n", drvdata->irq);
190 drvdata->serio.name, drvdata->irq); 197 return error;
191 return retval;
192 } 198 }
193 199
194 /* start reception by enabling the interrupts */ 200 /* start reception by enabling the interrupts */
195 out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK); 201 out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK);
196 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL); 202 out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL);
197 (void)xps2_recv(drvdata, &drvdata->rxb); 203 (void)xps2_recv(drvdata, &c);
198 204
199 return 0; /* success */ 205 return 0; /* success */
200} 206}
201 207
202/* 208/**
203 * sxps2_close() frees the interrupt. 209 * sxps2_close() - frees the interrupt.
210 * @pserio: pointer to the serio structure of the PS/2 device
211 *
212 * This function frees the irq and disables interrupts for the PS/2 device.
204 */ 213 */
205static void sxps2_close(struct serio *pserio) 214static void sxps2_close(struct serio *pserio)
206{ 215{
@@ -212,24 +221,41 @@ static void sxps2_close(struct serio *pserio)
212 free_irq(drvdata->irq, drvdata); 221 free_irq(drvdata->irq, drvdata);
213} 222}
214 223
215/*********************/ 224/**
216/* Device setup code */ 225 * xps2_of_probe - probe method for the PS/2 device.
217/*********************/ 226 * @of_dev: pointer to OF device structure
218 227 * @match: pointer to the stucture used for matching a device
219static int xps2_setup(struct device *dev, struct resource *regs_res, 228 *
220 struct resource *irq_res) 229 * This function probes the PS/2 device in the device tree.
230 * It initializes the driver data structure and the hardware.
231 * It returns 0, if the driver is bound to the PS/2 device, or a negative
232 * value if there is an error.
233 */
234static int __devinit xps2_of_probe(struct of_device *ofdev,
235 const struct of_device_id *match)
221{ 236{
237 struct resource r_irq; /* Interrupt resources */
238 struct resource r_mem; /* IO mem resources */
222 struct xps2data *drvdata; 239 struct xps2data *drvdata;
223 struct serio *serio; 240 struct serio *serio;
224 unsigned long remap_size; 241 struct device *dev = &ofdev->dev;
225 int retval; 242 resource_size_t remap_size, phys_addr;
243 int error;
244
245 dev_info(dev, "Device Tree Probing \'%s\'\n",
246 ofdev->node->name);
226 247
227 if (!dev) 248 /* Get iospace for the device */
228 return -EINVAL; 249 error = of_address_to_resource(ofdev->node, 0, &r_mem);
250 if (error) {
251 dev_err(dev, "invalid address\n");
252 return error;
253 }
229 254
230 if (!regs_res || !irq_res) { 255 /* Get IRQ for the device */
231 dev_err(dev, "IO resource(s) not found\n"); 256 if (of_irq_to_resource(ofdev->node, 0, &r_irq) == NO_IRQ) {
232 return -EINVAL; 257 dev_err(dev, "no IRQ found\n");
258 return -ENODEV;
233 } 259 }
234 260
235 drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL); 261 drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
@@ -241,24 +267,23 @@ static int xps2_setup(struct device *dev, struct resource *regs_res,
241 dev_set_drvdata(dev, drvdata); 267 dev_set_drvdata(dev, drvdata);
242 268
243 spin_lock_init(&drvdata->lock); 269 spin_lock_init(&drvdata->lock);
244 drvdata->irq = irq_res->start; 270 drvdata->irq = r_irq.start;
245 271
246 remap_size = regs_res->end - regs_res->start + 1; 272 phys_addr = r_mem.start;
247 if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) { 273 remap_size = r_mem.end - r_mem.start + 1;
248 dev_err(dev, "Couldn't lock memory region at 0x%08X\n", 274 if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
249 (unsigned int)regs_res->start); 275 dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
250 retval = -EBUSY; 276 (unsigned long long)phys_addr);
277 error = -EBUSY;
251 goto failed1; 278 goto failed1;
252 } 279 }
253 280
254 /* Fill in configuration data and add them to the list */ 281 /* Fill in configuration data and add them to the list */
255 drvdata->phys_addr = regs_res->start; 282 drvdata->base_address = ioremap(phys_addr, remap_size);
256 drvdata->remap_size = remap_size;
257 drvdata->base_address = ioremap(regs_res->start, remap_size);
258 if (drvdata->base_address == NULL) { 283 if (drvdata->base_address == NULL) {
259 dev_err(dev, "Couldn't ioremap memory at 0x%08X\n", 284 dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
260 (unsigned int)regs_res->start); 285 (unsigned long long)phys_addr);
261 retval = -EFAULT; 286 error = -EFAULT;
262 goto failed2; 287 goto failed2;
263 } 288 }
264 289
@@ -269,8 +294,9 @@ static int xps2_setup(struct device *dev, struct resource *regs_res,
269 * we have the PS2 in a good state */ 294 * we have the PS2 in a good state */
270 out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET); 295 out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);
271 296
272 dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%p, irq=%d\n", 297 dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
273 drvdata->phys_addr, drvdata->base_address, drvdata->irq); 298 (unsigned long long)phys_addr, drvdata->base_address,
299 drvdata->irq);
274 300
275 serio = &drvdata->serio; 301 serio = &drvdata->serio;
276 serio->id.type = SERIO_8042; 302 serio->id.type = SERIO_8042;
@@ -280,71 +306,51 @@ static int xps2_setup(struct device *dev, struct resource *regs_res,
280 serio->port_data = drvdata; 306 serio->port_data = drvdata;
281 serio->dev.parent = dev; 307 serio->dev.parent = dev;
282 snprintf(serio->name, sizeof(serio->name), 308 snprintf(serio->name, sizeof(serio->name),
283 "Xilinx XPS PS/2 at %08X", drvdata->phys_addr); 309 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
284 snprintf(serio->phys, sizeof(serio->phys), 310 snprintf(serio->phys, sizeof(serio->phys),
285 "xilinxps2/serio at %08X", drvdata->phys_addr); 311 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);
312
286 serio_register_port(serio); 313 serio_register_port(serio);
287 314
288 return 0; /* success */ 315 return 0; /* success */
289 316
290failed2: 317failed2:
291 release_mem_region(regs_res->start, remap_size); 318 release_mem_region(phys_addr, remap_size);
292failed1: 319failed1:
293 kfree(drvdata); 320 kfree(drvdata);
294 dev_set_drvdata(dev, NULL); 321 dev_set_drvdata(dev, NULL);
295 322
296 return retval; 323 return error;
297}
298
299/***************************/
300/* OF Platform Bus Support */
301/***************************/
302
303static int __devinit xps2_of_probe(struct of_device *ofdev, const struct
304 of_device_id * match)
305{
306 struct resource r_irq; /* Interrupt resources */
307 struct resource r_mem; /* IO mem resources */
308 int rc = 0;
309
310 printk(KERN_INFO "Device Tree Probing \'%s\'\n",
311 ofdev->node->name);
312
313 /* Get iospace for the device */
314 rc = of_address_to_resource(ofdev->node, 0, &r_mem);
315 if (rc) {
316 dev_err(&ofdev->dev, "invalid address\n");
317 return rc;
318 }
319
320 /* Get IRQ for the device */
321 rc = of_irq_to_resource(ofdev->node, 0, &r_irq);
322 if (rc == NO_IRQ) {
323 dev_err(&ofdev->dev, "no IRQ found\n");
324 return rc;
325 }
326
327 return xps2_setup(&ofdev->dev, &r_mem, &r_irq);
328} 324}
329 325
326/**
327 * xps2_of_remove - unbinds the driver from the PS/2 device.
328 * @of_dev: pointer to OF device structure
329 *
330 * This function is called if a device is physically removed from the system or
331 * if the driver module is being unloaded. It frees any resources allocated to
332 * the device.
333 */
330static int __devexit xps2_of_remove(struct of_device *of_dev) 334static int __devexit xps2_of_remove(struct of_device *of_dev)
331{ 335{
332 struct device *dev = &of_dev->dev; 336 struct device *dev = &of_dev->dev;
333 struct xps2data *drvdata; 337 struct xps2data *drvdata = dev_get_drvdata(dev);
334 338 struct resource r_mem; /* IO mem resources */
335 if (!dev)
336 return -EINVAL;
337
338 drvdata = dev_get_drvdata(dev);
339 339
340 serio_unregister_port(&drvdata->serio); 340 serio_unregister_port(&drvdata->serio);
341 iounmap(drvdata->base_address); 341 iounmap(drvdata->base_address);
342 release_mem_region(drvdata->phys_addr, drvdata->remap_size); 342
343 /* Get iospace of the device */
344 if (of_address_to_resource(of_dev->node, 0, &r_mem))
345 dev_err(dev, "invalid address\n");
346 else
347 release_mem_region(r_mem.start, r_mem.end - r_mem.start + 1);
348
343 kfree(drvdata); 349 kfree(drvdata);
344 350
345 dev_set_drvdata(dev, NULL); 351 dev_set_drvdata(dev, NULL);
346 352
347 return 0; /* success */ 353 return 0;
348} 354}
349 355
350/* Match table for of_platform binding */ 356/* Match table for of_platform binding */
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index 5524e01dbb1a..2e18a1c0c351 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -877,7 +877,7 @@ static int gtco_probe(struct usb_interface *usbinterface,
877 dbg("num endpoints: %d", usbinterface->cur_altsetting->desc.bNumEndpoints); 877 dbg("num endpoints: %d", usbinterface->cur_altsetting->desc.bNumEndpoints);
878 dbg("interface class: %d", usbinterface->cur_altsetting->desc.bInterfaceClass); 878 dbg("interface class: %d", usbinterface->cur_altsetting->desc.bInterfaceClass);
879 dbg("endpoint: attribute:0x%x type:0x%x", endpoint->bmAttributes, endpoint->bDescriptorType); 879 dbg("endpoint: attribute:0x%x type:0x%x", endpoint->bmAttributes, endpoint->bDescriptorType);
880 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) 880 if (usb_endpoint_xfer_int(endpoint))
881 dbg("endpoint: we have interrupt endpoint\n"); 881 dbg("endpoint: we have interrupt endpoint\n");
882 882
883 dbg("endpoint extra len:%d ", usbinterface->altsetting[0].extralen); 883 dbg("endpoint extra len:%d ", usbinterface->altsetting[0].extralen);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 8dc8d1e59bea..2638811c61ac 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -535,7 +535,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
535 return 1; 535 return 1;
536} 536}
537 537
538int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) 538static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
539{ 539{
540 char *data = wacom->data; 540 char *data = wacom->data;
541 int prox = 0, pressure; 541 int prox = 0, pressure;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 3d1ab8fa9acc..bb6486a8c070 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -58,6 +58,14 @@ config TOUCHSCREEN_CORGI
58 NOTE: this driver is deprecated, try enable SPI and generic 58 NOTE: this driver is deprecated, try enable SPI and generic
59 ADS7846-based touchscreen driver. 59 ADS7846-based touchscreen driver.
60 60
61config TOUCHSCREEN_DA9034
62 tristate "Touchscreen support for Dialog Semiconductor DA9034"
63 depends on PMIC_DA903X
64 default y
65 help
66 Say Y here to enable the support for the touchscreen found
67 on Dialog Semiconductor DA9034 PMIC.
68
61config TOUCHSCREEN_FUJITSU 69config TOUCHSCREEN_FUJITSU
62 tristate "Fujitsu serial touchscreen" 70 tristate "Fujitsu serial touchscreen"
63 select SERIO 71 select SERIO
@@ -95,6 +103,19 @@ config TOUCHSCREEN_ELO
95 To compile this driver as a module, choose M here: the 103 To compile this driver as a module, choose M here: the
96 module will be called elo. 104 module will be called elo.
97 105
106config TOUCHSCREEN_WACOM_W8001
107 tristate "Wacom W8001 penabled serial touchscreen"
108 select SERIO
109 help
110 Say Y here if you have an Wacom W8001 penabled serial touchscreen
111 connected to your system.
112
113 If unsure, say N.
114
115 To compile this driver as a module, choose M here: the
116 module will be called wacom_w8001.
117
118
98config TOUCHSCREEN_MTOUCH 119config TOUCHSCREEN_MTOUCH
99 tristate "MicroTouch serial touchscreens" 120 tristate "MicroTouch serial touchscreens"
100 select SERIO 121 select SERIO
@@ -376,4 +397,15 @@ config TOUCHSCREEN_TOUCHIT213
376 To compile this driver as a module, choose M here: the 397 To compile this driver as a module, choose M here: the
377 module will be called touchit213. 398 module will be called touchit213.
378 399
400config TOUCHSCREEN_TSC2007
401 tristate "TSC2007 based touchscreens"
402 depends on I2C
403 help
404 Say Y here if you have a TSC2007 based touchscreen.
405
406 If unsure, say N.
407
408 To compile this driver as a module, choose M here: the
409 module will be called tsc2007.
410
379endif 411endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 15cf29079489..d3375aff46fe 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -25,8 +25,11 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
25obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o 25obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
26obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o 26obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
27obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o 27obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
28obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
28obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o 29obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
30obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
29obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o 31obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
32obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
30wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o 33wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
31wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o 34wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
32wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o 35wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index e1ece89fe922..7c27c8b9b6d0 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -472,7 +472,7 @@ static ssize_t ads7846_disable_store(struct device *dev,
472 const char *buf, size_t count) 472 const char *buf, size_t count)
473{ 473{
474 struct ads7846 *ts = dev_get_drvdata(dev); 474 struct ads7846 *ts = dev_get_drvdata(dev);
475 long i; 475 unsigned long i;
476 476
477 if (strict_strtoul(buf, 10, &i)) 477 if (strict_strtoul(buf, 10, &i))
478 return -EINVAL; 478 return -EINVAL;
@@ -559,7 +559,7 @@ static void ads7846_rx(void *ads)
559 if (packet->tc.ignore || Rt > ts->pressure_max) { 559 if (packet->tc.ignore || Rt > ts->pressure_max) {
560#ifdef VERBOSE 560#ifdef VERBOSE
561 pr_debug("%s: ignored %d pressure %d\n", 561 pr_debug("%s: ignored %d pressure %d\n",
562 ts->spi->dev.bus_id, packet->tc.ignore, Rt); 562 dev_name(&ts->spi->dev), packet->tc.ignore, Rt);
563#endif 563#endif
564 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), 564 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
565 HRTIMER_MODE_REL); 565 HRTIMER_MODE_REL);
@@ -947,7 +947,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
947 ts->penirq_recheck_delay_usecs = 947 ts->penirq_recheck_delay_usecs =
948 pdata->penirq_recheck_delay_usecs; 948 pdata->penirq_recheck_delay_usecs;
949 949
950 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); 950 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
951 951
952 input_dev->name = "ADS784x Touchscreen"; 952 input_dev->name = "ADS784x Touchscreen";
953 input_dev->phys = ts->phys; 953 input_dev->phys = ts->phys;
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c
new file mode 100644
index 000000000000..4342e77814b5
--- /dev/null
+++ b/drivers/input/touchscreen/da9034-ts.c
@@ -0,0 +1,389 @@
1/*
2 * Touchscreen driver for Dialog Semiconductor DA9034
3 *
4 * Copyright (C) 2006-2008 Marvell International Ltd.
5 * Fengwei Yin <fengwei.yin@marvell.com>
6 * Eric Miao <eric.miao@marvell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/platform_device.h>
18#include <linux/input.h>
19#include <linux/mfd/da903x.h>
20
21#define DA9034_MANUAL_CTRL 0x50
22#define DA9034_LDO_ADC_EN (1 << 4)
23
24#define DA9034_AUTO_CTRL1 0x51
25
26#define DA9034_AUTO_CTRL2 0x52
27#define DA9034_AUTO_TSI_EN (1 << 3)
28#define DA9034_PEN_DETECT (1 << 4)
29
30#define DA9034_TSI_CTRL1 0x53
31#define DA9034_TSI_CTRL2 0x54
32#define DA9034_TSI_X_MSB 0x6c
33#define DA9034_TSI_Y_MSB 0x6d
34#define DA9034_TSI_XY_LSB 0x6e
35
36enum {
37 STATE_IDLE, /* wait for pendown */
38 STATE_BUSY, /* TSI busy sampling */
39 STATE_STOP, /* sample available */
40 STATE_WAIT, /* Wait to start next sample */
41};
42
43enum {
44 EVENT_PEN_DOWN,
45 EVENT_PEN_UP,
46 EVENT_TSI_READY,
47 EVENT_TIMEDOUT,
48};
49
50struct da9034_touch {
51 struct device *da9034_dev;
52 struct input_dev *input_dev;
53
54 struct delayed_work tsi_work;
55 struct notifier_block notifier;
56
57 int state;
58
59 int interval_ms;
60 int x_inverted;
61 int y_inverted;
62
63 int last_x;
64 int last_y;
65};
66
67static inline int is_pen_down(struct da9034_touch *touch)
68{
69 return da903x_query_status(touch->da9034_dev, DA9034_STATUS_PEN_DOWN);
70}
71
72static inline int detect_pen_down(struct da9034_touch *touch, int on)
73{
74 if (on)
75 return da903x_set_bits(touch->da9034_dev,
76 DA9034_AUTO_CTRL2, DA9034_PEN_DETECT);
77 else
78 return da903x_clr_bits(touch->da9034_dev,
79 DA9034_AUTO_CTRL2, DA9034_PEN_DETECT);
80}
81
82static int read_tsi(struct da9034_touch *touch)
83{
84 uint8_t _x, _y, _v;
85 int ret;
86
87 ret = da903x_read(touch->da9034_dev, DA9034_TSI_X_MSB, &_x);
88 if (ret)
89 return ret;
90
91 ret = da903x_read(touch->da9034_dev, DA9034_TSI_Y_MSB, &_y);
92 if (ret)
93 return ret;
94
95 ret = da903x_read(touch->da9034_dev, DA9034_TSI_XY_LSB, &_v);
96 if (ret)
97 return ret;
98
99 touch->last_x = ((_x << 2) & 0x3fc) | (_v & 0x3);
100 touch->last_y = ((_y << 2) & 0x3fc) | ((_v & 0xc) >> 2);
101
102 return 0;
103}
104
105static inline int start_tsi(struct da9034_touch *touch)
106{
107 return da903x_set_bits(touch->da9034_dev,
108 DA9034_AUTO_CTRL2, DA9034_AUTO_TSI_EN);
109}
110
111static inline int stop_tsi(struct da9034_touch *touch)
112{
113 return da903x_clr_bits(touch->da9034_dev,
114 DA9034_AUTO_CTRL2, DA9034_AUTO_TSI_EN);
115}
116
117static inline void report_pen_down(struct da9034_touch *touch)
118{
119 int x = touch->last_x;
120 int y = touch->last_y;
121
122 x &= 0xfff;
123 if (touch->x_inverted)
124 x = 1024 - x;
125 y &= 0xfff;
126 if (touch->y_inverted)
127 y = 1024 - y;
128
129 input_report_abs(touch->input_dev, ABS_X, x);
130 input_report_abs(touch->input_dev, ABS_Y, y);
131 input_report_key(touch->input_dev, BTN_TOUCH, 1);
132
133 input_sync(touch->input_dev);
134}
135
136static inline void report_pen_up(struct da9034_touch *touch)
137{
138 input_report_key(touch->input_dev, BTN_TOUCH, 0);
139 input_sync(touch->input_dev);
140}
141
142static void da9034_event_handler(struct da9034_touch *touch, int event)
143{
144 int err;
145
146 switch (touch->state) {
147 case STATE_IDLE:
148 if (event != EVENT_PEN_DOWN)
149 break;
150
151 /* Enable auto measurement of the TSI, this will
152 * automatically disable pen down detection
153 */
154 err = start_tsi(touch);
155 if (err)
156 goto err_reset;
157
158 touch->state = STATE_BUSY;
159 break;
160
161 case STATE_BUSY:
162 if (event != EVENT_TSI_READY)
163 break;
164
165 err = read_tsi(touch);
166 if (err)
167 goto err_reset;
168
169 /* Disable auto measurement of the TSI, so that
170 * pen down status will be available
171 */
172 err = stop_tsi(touch);
173 if (err)
174 goto err_reset;
175
176 touch->state = STATE_STOP;
177 break;
178
179 case STATE_STOP:
180 if (event == EVENT_PEN_DOWN) {
181 report_pen_down(touch);
182 schedule_delayed_work(&touch->tsi_work,
183 msecs_to_jiffies(touch->interval_ms));
184 touch->state = STATE_WAIT;
185 }
186
187 if (event == EVENT_PEN_UP) {
188 report_pen_up(touch);
189 touch->state = STATE_IDLE;
190 }
191
192 input_sync(touch->input_dev);
193 break;
194
195 case STATE_WAIT:
196 if (event != EVENT_TIMEDOUT)
197 break;
198
199 if (is_pen_down(touch)) {
200 start_tsi(touch);
201 touch->state = STATE_BUSY;
202 } else
203 touch->state = STATE_IDLE;
204 break;
205 }
206 return;
207
208err_reset:
209 touch->state = STATE_IDLE;
210 stop_tsi(touch);
211 detect_pen_down(touch, 1);
212}
213
214static void da9034_tsi_work(struct work_struct *work)
215{
216 struct da9034_touch *touch =
217 container_of(work, struct da9034_touch, tsi_work.work);
218
219 da9034_event_handler(touch, EVENT_TIMEDOUT);
220}
221
222static int da9034_touch_notifier(struct notifier_block *nb,
223 unsigned long event, void *data)
224{
225 struct da9034_touch *touch =
226 container_of(nb, struct da9034_touch, notifier);
227
228 if (event & DA9034_EVENT_PEN_DOWN) {
229 if (is_pen_down(touch))
230 da9034_event_handler(touch, EVENT_PEN_DOWN);
231 else
232 da9034_event_handler(touch, EVENT_PEN_UP);
233 }
234
235 if (event & DA9034_EVENT_TSI_READY)
236 da9034_event_handler(touch, EVENT_TSI_READY);
237
238 return 0;
239}
240
241static int da9034_touch_open(struct input_dev *dev)
242{
243 struct da9034_touch *touch = input_get_drvdata(dev);
244 int ret;
245
246 ret = da903x_register_notifier(touch->da9034_dev, &touch->notifier,
247 DA9034_EVENT_PEN_DOWN | DA9034_EVENT_TSI_READY);
248 if (ret)
249 return -EBUSY;
250
251 /* Enable ADC LDO */
252 ret = da903x_set_bits(touch->da9034_dev,
253 DA9034_MANUAL_CTRL, DA9034_LDO_ADC_EN);
254 if (ret)
255 return ret;
256
257 /* TSI_DELAY: 3 slots, TSI_SKIP: 3 slots */
258 ret = da903x_write(touch->da9034_dev, DA9034_TSI_CTRL1, 0x1b);
259 if (ret)
260 return ret;
261
262 ret = da903x_write(touch->da9034_dev, DA9034_TSI_CTRL2, 0x00);
263 if (ret)
264 return ret;
265
266 touch->state = STATE_IDLE;
267 detect_pen_down(touch, 1);
268
269 return 0;
270}
271
272static void da9034_touch_close(struct input_dev *dev)
273{
274 struct da9034_touch *touch = input_get_drvdata(dev);
275
276 da903x_unregister_notifier(touch->da9034_dev, &touch->notifier,
277 DA9034_EVENT_PEN_DOWN | DA9034_EVENT_TSI_READY);
278
279 cancel_delayed_work_sync(&touch->tsi_work);
280
281 touch->state = STATE_IDLE;
282 stop_tsi(touch);
283 detect_pen_down(touch, 0);
284
285 /* Disable ADC LDO */
286 da903x_clr_bits(touch->da9034_dev,
287 DA9034_MANUAL_CTRL, DA9034_LDO_ADC_EN);
288}
289
290
291static int __devinit da9034_touch_probe(struct platform_device *pdev)
292{
293 struct da9034_touch_pdata *pdata = pdev->dev.platform_data;
294 struct da9034_touch *touch;
295 struct input_dev *input_dev;
296 int ret;
297
298 touch = kzalloc(sizeof(struct da9034_touch), GFP_KERNEL);
299 if (touch == NULL) {
300 dev_err(&pdev->dev, "failed to allocate driver data\n");
301 return -ENOMEM;
302 }
303
304 touch->da9034_dev = pdev->dev.parent;
305
306 if (pdata) {
307 touch->interval_ms = pdata->interval_ms;
308 touch->x_inverted = pdata->x_inverted;
309 touch->y_inverted = pdata->y_inverted;
310 } else
311 /* fallback into default */
312 touch->interval_ms = 10;
313
314 INIT_DELAYED_WORK(&touch->tsi_work, da9034_tsi_work);
315 touch->notifier.notifier_call = da9034_touch_notifier;
316
317 input_dev = input_allocate_device();
318 if (!input_dev) {
319 dev_err(&pdev->dev, "failed to allocate input device\n");
320 ret = -ENOMEM;
321 goto err_free_touch;
322 }
323
324 input_dev->name = pdev->name;
325 input_dev->open = da9034_touch_open;
326 input_dev->close = da9034_touch_close;
327 input_dev->dev.parent = &pdev->dev;
328
329 __set_bit(EV_ABS, input_dev->evbit);
330 __set_bit(ABS_X, input_dev->absbit);
331 __set_bit(ABS_Y, input_dev->absbit);
332 input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
333 input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
334
335 __set_bit(EV_KEY, input_dev->evbit);
336 __set_bit(BTN_TOUCH, input_dev->keybit);
337
338 touch->input_dev = input_dev;
339 input_set_drvdata(input_dev, touch);
340
341 ret = input_register_device(input_dev);
342 if (ret)
343 goto err_free_input;
344
345 platform_set_drvdata(pdev, touch);
346 return 0;
347
348err_free_input:
349 input_free_device(input_dev);
350err_free_touch:
351 kfree(touch);
352 return ret;
353}
354
355static int __devexit da9034_touch_remove(struct platform_device *pdev)
356{
357 struct da9034_touch *touch = platform_get_drvdata(pdev);
358
359 input_unregister_device(touch->input_dev);
360 kfree(touch);
361
362 return 0;
363}
364
365static struct platform_driver da9034_touch_driver = {
366 .driver = {
367 .name = "da9034-touch",
368 .owner = THIS_MODULE,
369 },
370 .probe = da9034_touch_probe,
371 .remove = __devexit_p(da9034_touch_remove),
372};
373
374static int __init da9034_touch_init(void)
375{
376 return platform_driver_register(&da9034_touch_driver);
377}
378module_init(da9034_touch_init);
379
380static void __exit da9034_touch_exit(void)
381{
382 platform_driver_unregister(&da9034_touch_driver);
383}
384module_exit(da9034_touch_exit);
385
386MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034");
387MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
388MODULE_LICENSE("GPL");
389MODULE_ALIAS("platform:da9034-touch");
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
new file mode 100644
index 000000000000..b75dc2990574
--- /dev/null
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -0,0 +1,381 @@
1/*
2 * drivers/input/touchscreen/tsc2007.c
3 *
4 * Copyright (c) 2008 MtekVision Co., Ltd.
5 * Kwangwoo Lee <kwlee@mtekvision.com>
6 *
7 * Using code from:
8 * - ads7846.c
9 * Copyright (c) 2005 David Brownell
10 * Copyright (c) 2006 Nokia Corporation
11 * - corgi_ts.c
12 * Copyright (C) 2004-2005 Richard Purdie
13 * - omap_ts.[hc], ads7846.h, ts_osk.c
14 * Copyright (C) 2002 MontaVista Software
15 * Copyright (C) 2004 Texas Instruments
16 * Copyright (C) 2005 Dirk Behme
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/module.h>
24#include <linux/hrtimer.h>
25#include <linux/slab.h>
26#include <linux/input.h>
27#include <linux/interrupt.h>
28#include <linux/i2c.h>
29#include <linux/i2c/tsc2007.h>
30
31#define TS_POLL_DELAY (10 * 1000) /* ns delay before the first sample */
32#define TS_POLL_PERIOD (5 * 1000) /* ns delay between samples */
33
34#define TSC2007_MEASURE_TEMP0 (0x0 << 4)
35#define TSC2007_MEASURE_AUX (0x2 << 4)
36#define TSC2007_MEASURE_TEMP1 (0x4 << 4)
37#define TSC2007_ACTIVATE_XN (0x8 << 4)
38#define TSC2007_ACTIVATE_YN (0x9 << 4)
39#define TSC2007_ACTIVATE_YP_XN (0xa << 4)
40#define TSC2007_SETUP (0xb << 4)
41#define TSC2007_MEASURE_X (0xc << 4)
42#define TSC2007_MEASURE_Y (0xd << 4)
43#define TSC2007_MEASURE_Z1 (0xe << 4)
44#define TSC2007_MEASURE_Z2 (0xf << 4)
45
46#define TSC2007_POWER_OFF_IRQ_EN (0x0 << 2)
47#define TSC2007_ADC_ON_IRQ_DIS0 (0x1 << 2)
48#define TSC2007_ADC_OFF_IRQ_EN (0x2 << 2)
49#define TSC2007_ADC_ON_IRQ_DIS1 (0x3 << 2)
50
51#define TSC2007_12BIT (0x0 << 1)
52#define TSC2007_8BIT (0x1 << 1)
53
54#define MAX_12BIT ((1 << 12) - 1)
55
56#define ADC_ON_12BIT (TSC2007_12BIT | TSC2007_ADC_ON_IRQ_DIS0)
57
58#define READ_Y (ADC_ON_12BIT | TSC2007_MEASURE_Y)
59#define READ_Z1 (ADC_ON_12BIT | TSC2007_MEASURE_Z1)
60#define READ_Z2 (ADC_ON_12BIT | TSC2007_MEASURE_Z2)
61#define READ_X (ADC_ON_12BIT | TSC2007_MEASURE_X)
62#define PWRDOWN (TSC2007_12BIT | TSC2007_POWER_OFF_IRQ_EN)
63
64struct ts_event {
65 u16 x;
66 u16 y;
67 u16 z1, z2;
68};
69
70struct tsc2007 {
71 struct input_dev *input;
72 char phys[32];
73 struct hrtimer timer;
74 struct ts_event tc;
75
76 struct i2c_client *client;
77
78 spinlock_t lock;
79
80 u16 model;
81 u16 x_plate_ohms;
82
83 unsigned pendown;
84 int irq;
85
86 int (*get_pendown_state)(void);
87 void (*clear_penirq)(void);
88};
89
90static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
91{
92 s32 data;
93 u16 val;
94
95 data = i2c_smbus_read_word_data(tsc->client, cmd);
96 if (data < 0) {
97 dev_err(&tsc->client->dev, "i2c io error: %d\n", data);
98 return data;
99 }
100
101 /* The protocol and raw data format from i2c interface:
102 * S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
103 * Where DataLow has [D11-D4], DataHigh has [D3-D0 << 4 | Dummy 4bit].
104 */
105 val = swab16(data) >> 4;
106
107 dev_dbg(&tsc->client->dev, "data: 0x%x, val: 0x%x\n", data, val);
108
109 return val;
110}
111
112static void tsc2007_send_event(void *tsc)
113{
114 struct tsc2007 *ts = tsc;
115 u32 rt;
116 u16 x, y, z1, z2;
117
118 x = ts->tc.x;
119 y = ts->tc.y;
120 z1 = ts->tc.z1;
121 z2 = ts->tc.z2;
122
123 /* range filtering */
124 if (x == MAX_12BIT)
125 x = 0;
126
127 if (likely(x && z1)) {
128 /* compute touch pressure resistance using equation #1 */
129 rt = z2;
130 rt -= z1;
131 rt *= x;
132 rt *= ts->x_plate_ohms;
133 rt /= z1;
134 rt = (rt + 2047) >> 12;
135 } else
136 rt = 0;
137
138 /* Sample found inconsistent by debouncing or pressure is beyond
139 * the maximum. Don't report it to user space, repeat at least
140 * once more the measurement
141 */
142 if (rt > MAX_12BIT) {
143 dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt);
144
145 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
146 HRTIMER_MODE_REL);
147 return;
148 }
149
150 /* NOTE: We can't rely on the pressure to determine the pen down
151 * state, even this controller has a pressure sensor. The pressure
152 * value can fluctuate for quite a while after lifting the pen and
153 * in some cases may not even settle at the expected value.
154 *
155 * The only safe way to check for the pen up condition is in the
156 * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
157 */
158 if (rt) {
159 struct input_dev *input = ts->input;
160
161 if (!ts->pendown) {
162 dev_dbg(&ts->client->dev, "DOWN\n");
163
164 input_report_key(input, BTN_TOUCH, 1);
165 ts->pendown = 1;
166 }
167
168 input_report_abs(input, ABS_X, x);
169 input_report_abs(input, ABS_Y, y);
170 input_report_abs(input, ABS_PRESSURE, rt);
171
172 input_sync(input);
173
174 dev_dbg(&ts->client->dev, "point(%4d,%4d), pressure (%4u)\n",
175 x, y, rt);
176 }
177
178 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
179 HRTIMER_MODE_REL);
180}
181
182static int tsc2007_read_values(struct tsc2007 *tsc)
183{
184 /* y- still on; turn on only y+ (and ADC) */
185 tsc->tc.y = tsc2007_xfer(tsc, READ_Y);
186
187 /* turn y- off, x+ on, then leave in lowpower */
188 tsc->tc.x = tsc2007_xfer(tsc, READ_X);
189
190 /* turn y+ off, x- on; we'll use formula #1 */
191 tsc->tc.z1 = tsc2007_xfer(tsc, READ_Z1);
192 tsc->tc.z2 = tsc2007_xfer(tsc, READ_Z2);
193
194 /* power down */
195 tsc2007_xfer(tsc, PWRDOWN);
196
197 return 0;
198}
199
200static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle)
201{
202 struct tsc2007 *ts = container_of(handle, struct tsc2007, timer);
203
204 spin_lock_irq(&ts->lock);
205
206 if (unlikely(!ts->get_pendown_state() && ts->pendown)) {
207 struct input_dev *input = ts->input;
208
209 dev_dbg(&ts->client->dev, "UP\n");
210
211 input_report_key(input, BTN_TOUCH, 0);
212 input_report_abs(input, ABS_PRESSURE, 0);
213 input_sync(input);
214
215 ts->pendown = 0;
216 enable_irq(ts->irq);
217 } else {
218 /* pen is still down, continue with the measurement */
219 dev_dbg(&ts->client->dev, "pen is still down\n");
220
221 tsc2007_read_values(ts);
222 tsc2007_send_event(ts);
223 }
224
225 spin_unlock_irq(&ts->lock);
226
227 return HRTIMER_NORESTART;
228}
229
230static irqreturn_t tsc2007_irq(int irq, void *handle)
231{
232 struct tsc2007 *ts = handle;
233 unsigned long flags;
234
235 spin_lock_irqsave(&ts->lock, flags);
236
237 if (likely(ts->get_pendown_state())) {
238 disable_irq(ts->irq);
239 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
240 HRTIMER_MODE_REL);
241 }
242
243 if (ts->clear_penirq)
244 ts->clear_penirq();
245
246 spin_unlock_irqrestore(&ts->lock, flags);
247
248 return IRQ_HANDLED;
249}
250
251static int tsc2007_probe(struct i2c_client *client,
252 const struct i2c_device_id *id)
253{
254 struct tsc2007 *ts;
255 struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data;
256 struct input_dev *input_dev;
257 int err;
258
259 if (!pdata) {
260 dev_err(&client->dev, "platform data is required!\n");
261 return -EINVAL;
262 }
263
264 if (!i2c_check_functionality(client->adapter,
265 I2C_FUNC_SMBUS_READ_WORD_DATA))
266 return -EIO;
267
268 ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL);
269 input_dev = input_allocate_device();
270 if (!ts || !input_dev) {
271 err = -ENOMEM;
272 goto err_free_mem;
273 }
274
275 ts->client = client;
276 i2c_set_clientdata(client, ts);
277
278 ts->input = input_dev;
279
280 hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
281 ts->timer.function = tsc2007_timer;
282
283 spin_lock_init(&ts->lock);
284
285 ts->model = pdata->model;
286 ts->x_plate_ohms = pdata->x_plate_ohms;
287 ts->get_pendown_state = pdata->get_pendown_state;
288 ts->clear_penirq = pdata->clear_penirq;
289
290 pdata->init_platform_hw();
291
292 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", client->dev.bus_id);
293
294 input_dev->name = "TSC2007 Touchscreen";
295 input_dev->phys = ts->phys;
296 input_dev->id.bustype = BUS_I2C;
297
298 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
299 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
300
301 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
302 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
303 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
304
305 tsc2007_read_values(ts);
306
307 ts->irq = client->irq;
308
309 err = request_irq(ts->irq, tsc2007_irq, 0,
310 client->dev.driver->name, ts);
311 if (err < 0) {
312 dev_err(&client->dev, "irq %d busy?\n", ts->irq);
313 goto err_free_mem;
314 }
315
316 err = input_register_device(input_dev);
317 if (err)
318 goto err_free_irq;
319
320 dev_info(&client->dev, "registered with irq (%d)\n", ts->irq);
321
322 return 0;
323
324 err_free_irq:
325 free_irq(ts->irq, ts);
326 hrtimer_cancel(&ts->timer);
327 err_free_mem:
328 input_free_device(input_dev);
329 kfree(ts);
330 return err;
331}
332
333static int tsc2007_remove(struct i2c_client *client)
334{
335 struct tsc2007 *ts = i2c_get_clientdata(client);
336 struct tsc2007_platform_data *pdata;
337
338 pdata = client->dev.platform_data;
339 pdata->exit_platform_hw();
340
341 free_irq(ts->irq, ts);
342 hrtimer_cancel(&ts->timer);
343 input_unregister_device(ts->input);
344 kfree(ts);
345
346 return 0;
347}
348
349static struct i2c_device_id tsc2007_idtable[] = {
350 { "tsc2007", 0 },
351 { }
352};
353
354MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
355
356static struct i2c_driver tsc2007_driver = {
357 .driver = {
358 .owner = THIS_MODULE,
359 .name = "tsc2007"
360 },
361 .id_table = tsc2007_idtable,
362 .probe = tsc2007_probe,
363 .remove = tsc2007_remove,
364};
365
366static int __init tsc2007_init(void)
367{
368 return i2c_add_driver(&tsc2007_driver);
369}
370
371static void __exit tsc2007_exit(void)
372{
373 i2c_del_driver(&tsc2007_driver);
374}
375
376module_init(tsc2007_init);
377module_exit(tsc2007_exit);
378
379MODULE_AUTHOR("Kwangwoo Lee <kwlee@mtekvision.com>");
380MODULE_DESCRIPTION("TSC2007 TouchScreen Driver");
381MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index fdd645c214a2..5080b26ba160 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -424,7 +424,7 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
424 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT); 424 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
425 if (ret < 0) 425 if (ret < 0)
426 goto err_out; 426 goto err_out;
427 if (buf[0] != 0x06 || buf[1] != 0x00) { 427 if (buf[0] != 0x06) {
428 ret = -ENODEV; 428 ret = -ENODEV;
429 goto err_out; 429 goto err_out;
430 } 430 }
@@ -437,8 +437,7 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
437 TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT); 437 TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
438 if (ret < 0) 438 if (ret < 0)
439 goto err_out; 439 goto err_out;
440 if ((buf[0] != 0x06 || buf[1] != 0x00) && 440 if ((buf[0] != 0x06) && (buf[0] != 0x15 || buf[1] != 0x01)) {
441 (buf[0] != 0x15 || buf[1] != 0x01)) {
442 ret = -ENODEV; 441 ret = -ENODEV;
443 goto err_out; 442 goto err_out;
444 } 443 }
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
new file mode 100644
index 000000000000..2f33a0167644
--- /dev/null
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -0,0 +1,325 @@
1/*
2 * Wacom W8001 penabled serial touchscreen driver
3 *
4 * Copyright (c) 2008 Jaya Kumar
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 *
10 * Layout based on Elo serial touchscreen driver by Vojtech Pavlik
11 */
12
13#include <linux/errno.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/slab.h>
17#include <linux/input.h>
18#include <linux/serio.h>
19#include <linux/init.h>
20#include <linux/ctype.h>
21
22#define DRIVER_DESC "Wacom W8001 serial touchscreen driver"
23
24MODULE_AUTHOR("Jaya Kumar <jayakumar.lkml@gmail.com>");
25MODULE_DESCRIPTION(DRIVER_DESC);
26MODULE_LICENSE("GPL");
27
28/*
29 * Definitions & global arrays.
30 */
31
32#define W8001_MAX_LENGTH 11
33#define W8001_PACKET_LEN 11
34#define W8001_LEAD_MASK 0x80
35#define W8001_LEAD_BYTE 0x80
36#define W8001_TAB_MASK 0x40
37#define W8001_TAB_BYTE 0x40
38
39#define W8001_QUERY_PACKET 0x20
40
41struct w8001_coord {
42 u8 rdy;
43 u8 tsw;
44 u8 f1;
45 u8 f2;
46 u16 x;
47 u16 y;
48 u16 pen_pressure;
49 u8 tilt_x;
50 u8 tilt_y;
51};
52
53/*
54 * Per-touchscreen data.
55 */
56
57struct w8001 {
58 struct input_dev *dev;
59 struct serio *serio;
60 struct mutex cmd_mutex;
61 struct completion cmd_done;
62 int id;
63 int idx;
64 unsigned char expected_packet;
65 unsigned char data[W8001_MAX_LENGTH];
66 unsigned char response[W8001_PACKET_LEN];
67 char phys[32];
68};
69
70static int parse_data(u8 *data, struct w8001_coord *coord)
71{
72 coord->rdy = data[0] & 0x20;
73 coord->tsw = data[0] & 0x01;
74 coord->f1 = data[0] & 0x02;
75 coord->f2 = data[0] & 0x04;
76
77 coord->x = (data[1] & 0x7F) << 9;
78 coord->x |= (data[2] & 0x7F) << 2;
79 coord->x |= (data[6] & 0x60) >> 5;
80
81 coord->y = (data[3] & 0x7F) << 9;
82 coord->y |= (data[4] & 0x7F) << 2;
83 coord->y |= (data[6] & 0x18) >> 3;
84
85 coord->pen_pressure = data[5] & 0x7F;
86 coord->pen_pressure |= (data[6] & 0x07) << 7 ;
87
88 coord->tilt_x = data[7] & 0x7F;
89 coord->tilt_y = data[8] & 0x7F;
90
91 return 0;
92}
93
94static void w8001_process_data(struct w8001 *w8001, unsigned char data)
95{
96 struct input_dev *dev = w8001->dev;
97 u8 tmp;
98 struct w8001_coord coord;
99
100 w8001->data[w8001->idx] = data;
101 switch (w8001->idx++) {
102 case 0:
103 if ((data & W8001_LEAD_MASK) != W8001_LEAD_BYTE) {
104 pr_debug("w8001: unsynchronized data: 0x%02x\n", data);
105 w8001->idx = 0;
106 }
107 break;
108 case 8:
109 tmp = w8001->data[0] & W8001_TAB_MASK;
110 if (unlikely(tmp == W8001_TAB_BYTE))
111 break;
112 w8001->idx = 0;
113 memset(&coord, 0, sizeof(coord));
114 parse_data(w8001->data, &coord);
115 input_report_abs(dev, ABS_X, coord.x);
116 input_report_abs(dev, ABS_Y, coord.y);
117 input_report_abs(dev, ABS_PRESSURE, coord.pen_pressure);
118 input_report_key(dev, BTN_TOUCH, coord.tsw);
119 input_sync(dev);
120 break;
121 case 10:
122 w8001->idx = 0;
123 memcpy(w8001->response, &w8001->data, W8001_PACKET_LEN);
124 w8001->expected_packet = W8001_QUERY_PACKET;
125 complete(&w8001->cmd_done);
126 break;
127 }
128}
129
130
131static irqreturn_t w8001_interrupt(struct serio *serio,
132 unsigned char data, unsigned int flags)
133{
134 struct w8001 *w8001 = serio_get_drvdata(serio);
135
136 w8001_process_data(w8001, data);
137
138 return IRQ_HANDLED;
139}
140
141static int w8001_async_command(struct w8001 *w8001, unsigned char *packet,
142 int len)
143{
144 int rc = -1;
145 int i;
146
147 mutex_lock(&w8001->cmd_mutex);
148
149 for (i = 0; i < len; i++) {
150 if (serio_write(w8001->serio, packet[i]))
151 goto out;
152 }
153 rc = 0;
154
155out:
156 mutex_unlock(&w8001->cmd_mutex);
157 return rc;
158}
159
160static int w8001_command(struct w8001 *w8001, unsigned char *packet, int len)
161{
162 int rc = -1;
163 int i;
164
165 mutex_lock(&w8001->cmd_mutex);
166
167 serio_pause_rx(w8001->serio);
168 init_completion(&w8001->cmd_done);
169 serio_continue_rx(w8001->serio);
170
171 for (i = 0; i < len; i++) {
172 if (serio_write(w8001->serio, packet[i]))
173 goto out;
174 }
175
176 wait_for_completion_timeout(&w8001->cmd_done, HZ);
177
178 if (w8001->expected_packet == W8001_QUERY_PACKET) {
179 /* We are back in reporting mode, the query was ACKed */
180 memcpy(packet, w8001->response, W8001_PACKET_LEN);
181 rc = 0;
182 }
183
184out:
185 mutex_unlock(&w8001->cmd_mutex);
186 return rc;
187}
188
189static int w8001_setup(struct w8001 *w8001)
190{
191 struct w8001_coord coord;
192 struct input_dev *dev = w8001->dev;
193 unsigned char start[1] = { '1' };
194 unsigned char query[11] = { '*' };
195
196 if (w8001_command(w8001, query, 1))
197 return -1;
198
199 memset(&coord, 0, sizeof(coord));
200 parse_data(query, &coord);
201
202 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
203 input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
204 input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0);
205 input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
206 input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
207
208 if (w8001_async_command(w8001, start, 1))
209 return -1;
210
211 return 0;
212}
213
214/*
215 * w8001_disconnect() is the opposite of w8001_connect()
216 */
217
218static void w8001_disconnect(struct serio *serio)
219{
220 struct w8001 *w8001 = serio_get_drvdata(serio);
221
222 input_get_device(w8001->dev);
223 input_unregister_device(w8001->dev);
224 serio_close(serio);
225 serio_set_drvdata(serio, NULL);
226 input_put_device(w8001->dev);
227 kfree(w8001);
228}
229
230/*
231 * w8001_connect() is the routine that is called when someone adds a
232 * new serio device that supports the w8001 protocol and registers it as
233 * an input device.
234 */
235
236static int w8001_connect(struct serio *serio, struct serio_driver *drv)
237{
238 struct w8001 *w8001;
239 struct input_dev *input_dev;
240 int err;
241
242 w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL);
243 input_dev = input_allocate_device();
244 if (!w8001 || !input_dev) {
245 err = -ENOMEM;
246 goto fail1;
247 }
248
249 w8001->serio = serio;
250 w8001->id = serio->id.id;
251 w8001->dev = input_dev;
252 mutex_init(&w8001->cmd_mutex);
253 init_completion(&w8001->cmd_done);
254 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
255
256 input_dev->name = "Wacom W8001 Penabled Serial TouchScreen";
257 input_dev->phys = w8001->phys;
258 input_dev->id.bustype = BUS_RS232;
259 input_dev->id.vendor = SERIO_W8001;
260 input_dev->id.product = w8001->id;
261 input_dev->id.version = 0x0100;
262 input_dev->dev.parent = &serio->dev;
263
264 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
265 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
266
267 serio_set_drvdata(serio, w8001);
268 err = serio_open(serio, drv);
269 if (err)
270 goto fail2;
271
272 if (w8001_setup(w8001))
273 goto fail3;
274
275 err = input_register_device(w8001->dev);
276 if (err)
277 goto fail3;
278
279 return 0;
280
281fail3:
282 serio_close(serio);
283fail2:
284 serio_set_drvdata(serio, NULL);
285fail1:
286 input_free_device(input_dev);
287 kfree(w8001);
288 return err;
289}
290
291static struct serio_device_id w8001_serio_ids[] = {
292 {
293 .type = SERIO_RS232,
294 .proto = SERIO_W8001,
295 .id = SERIO_ANY,
296 .extra = SERIO_ANY,
297 },
298 { 0 }
299};
300
301MODULE_DEVICE_TABLE(serio, w8001_serio_ids);
302
303static struct serio_driver w8001_drv = {
304 .driver = {
305 .name = "w8001",
306 },
307 .description = DRIVER_DESC,
308 .id_table = w8001_serio_ids,
309 .interrupt = w8001_interrupt,
310 .connect = w8001_connect,
311 .disconnect = w8001_disconnect,
312};
313
314static int __init w8001_init(void)
315{
316 return serio_register_driver(&w8001_drv);
317}
318
319static void __exit w8001_exit(void)
320{
321 serio_unregister_driver(&w8001_drv);
322}
323
324module_init(w8001_init);
325module_exit(w8001_exit);