diff options
Diffstat (limited to 'drivers/input')
167 files changed, 17404 insertions, 5588 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 07c2cd43109c..23e82e46656d 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig | |||
@@ -6,7 +6,7 @@ menu "Input device support" | |||
6 | depends on !S390 | 6 | depends on !S390 |
7 | 7 | ||
8 | config INPUT | 8 | config INPUT |
9 | tristate "Generic input layer (needed for keyboard, mouse, ...)" if EMBEDDED | 9 | tristate "Generic input layer (needed for keyboard, mouse, ...)" if EXPERT |
10 | default y | 10 | default y |
11 | help | 11 | help |
12 | Say Y here if you have any input device (mouse, keyboard, tablet, | 12 | Say Y here if you have any input device (mouse, keyboard, tablet, |
@@ -67,7 +67,7 @@ config INPUT_SPARSEKMAP | |||
67 | comment "Userland interfaces" | 67 | comment "Userland interfaces" |
68 | 68 | ||
69 | config INPUT_MOUSEDEV | 69 | config INPUT_MOUSEDEV |
70 | tristate "Mouse interface" if EMBEDDED | 70 | tristate "Mouse interface" if EXPERT |
71 | default y | 71 | default y |
72 | help | 72 | help |
73 | Say Y here if you want your mouse to be accessible as char devices | 73 | Say Y here if you want your mouse to be accessible as char devices |
@@ -150,7 +150,7 @@ config INPUT_EVBUG | |||
150 | module will be called evbug. | 150 | module will be called evbug. |
151 | 151 | ||
152 | config INPUT_APMPOWER | 152 | config INPUT_APMPOWER |
153 | tristate "Input Power Event -> APM Bridge" if EMBEDDED | 153 | tristate "Input Power Event -> APM Bridge" if EXPERT |
154 | depends on INPUT && APM_EMULATION | 154 | depends on INPUT && APM_EMULATION |
155 | help | 155 | help |
156 | Say Y here if you want suspend key events to trigger a user | 156 | Say Y here if you want suspend key events to trigger a user |
@@ -161,16 +161,6 @@ config INPUT_APMPOWER | |||
161 | To compile this driver as a module, choose M here: the | 161 | To compile this driver as a module, choose M here: the |
162 | module will be called apm-power. | 162 | module will be called apm-power. |
163 | 163 | ||
164 | config XEN_KBDDEV_FRONTEND | ||
165 | tristate "Xen virtual keyboard and mouse support" | ||
166 | depends on XEN_FBDEV_FRONTEND | ||
167 | default y | ||
168 | select XEN_XENBUS_FRONTEND | ||
169 | help | ||
170 | This driver implements the front-end of the Xen virtual | ||
171 | keyboard and mouse device driver. It communicates with a back-end | ||
172 | in another domain. | ||
173 | |||
174 | comment "Input Device Drivers" | 164 | comment "Input Device Drivers" |
175 | 165 | ||
176 | source "drivers/input/keyboard/Kconfig" | 166 | source "drivers/input/keyboard/Kconfig" |
diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 7ad212d31f99..0c789490e0b3 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 | ||
7 | obj-$(CONFIG_INPUT) += input-core.o | 7 | obj-$(CONFIG_INPUT) += input-core.o |
8 | input-core-objs := input.o input-compat.o ff-core.o | 8 | input-core-y := input.o input-compat.o input-mt.o ff-core.o |
9 | 9 | ||
10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o | 10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o |
11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o | 11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o |
@@ -24,5 +24,3 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ | |||
24 | obj-$(CONFIG_INPUT_MISC) += misc/ | 24 | obj-$(CONFIG_INPUT_MISC) += misc/ |
25 | 25 | ||
26 | obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o | 26 | obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o |
27 | |||
28 | obj-$(CONFIG_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o | ||
diff --git a/drivers/input/apm-power.c b/drivers/input/apm-power.c index 7d61a9660806..e90ee3d30613 100644 --- a/drivers/input/apm-power.c +++ b/drivers/input/apm-power.c | |||
@@ -9,6 +9,8 @@ | |||
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
13 | |||
12 | #include <linux/module.h> | 14 | #include <linux/module.h> |
13 | #include <linux/input.h> | 15 | #include <linux/input.h> |
14 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
@@ -23,8 +25,7 @@ static void system_power_event(unsigned int keycode) | |||
23 | switch (keycode) { | 25 | switch (keycode) { |
24 | case KEY_SUSPEND: | 26 | case KEY_SUSPEND: |
25 | apm_queue_event(APM_USER_SUSPEND); | 27 | apm_queue_event(APM_USER_SUSPEND); |
26 | 28 | pr_info("Requesting system suspend...\n"); | |
27 | printk(KERN_INFO "apm-power: Requesting system suspend...\n"); | ||
28 | break; | 29 | break; |
29 | default: | 30 | default: |
30 | break; | 31 | break; |
@@ -65,18 +66,15 @@ static int apmpower_connect(struct input_handler *handler, | |||
65 | 66 | ||
66 | error = input_register_handle(handle); | 67 | error = input_register_handle(handle); |
67 | if (error) { | 68 | if (error) { |
68 | printk(KERN_ERR | 69 | pr_err("Failed to register input power handler, error %d\n", |
69 | "apm-power: Failed to register input power handler, " | 70 | error); |
70 | "error %d\n", error); | ||
71 | kfree(handle); | 71 | kfree(handle); |
72 | return error; | 72 | return error; |
73 | } | 73 | } |
74 | 74 | ||
75 | error = input_open_device(handle); | 75 | error = input_open_device(handle); |
76 | if (error) { | 76 | if (error) { |
77 | printk(KERN_ERR | 77 | pr_err("Failed to open input power device, error %d\n", error); |
78 | "apm-power: Failed to open input power device, " | ||
79 | "error %d\n", error); | ||
80 | input_unregister_handle(handle); | 78 | input_unregister_handle(handle); |
81 | kfree(handle); | 79 | kfree(handle); |
82 | return error; | 80 | return error; |
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c index f7c5c14ec12a..cd4e6679d61a 100644 --- a/drivers/input/evbug.c +++ b/drivers/input/evbug.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
29 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
30 | #include <linux/module.h> | 32 | #include <linux/module.h> |
31 | #include <linux/input.h> | 33 | #include <linux/input.h> |
@@ -38,8 +40,8 @@ MODULE_LICENSE("GPL"); | |||
38 | 40 | ||
39 | static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | 41 | static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) |
40 | { | 42 | { |
41 | printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", | 43 | printk(KERN_DEBUG pr_fmt("Event. Dev: %s, Type: %d, Code: %d, Value: %d\n"), |
42 | dev_name(&handle->dev->dev), type, code, value); | 44 | dev_name(&handle->dev->dev), type, code, value); |
43 | } | 45 | } |
44 | 46 | ||
45 | static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | 47 | static int evbug_connect(struct input_handler *handler, struct input_dev *dev, |
@@ -64,10 +66,10 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | |||
64 | if (error) | 66 | if (error) |
65 | goto err_unregister_handle; | 67 | goto err_unregister_handle; |
66 | 68 | ||
67 | printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n", | 69 | printk(KERN_DEBUG pr_fmt("Connected device: %s (%s at %s)\n"), |
68 | dev_name(&dev->dev), | 70 | dev_name(&dev->dev), |
69 | dev->name ?: "unknown", | 71 | dev->name ?: "unknown", |
70 | dev->phys ?: "unknown"); | 72 | dev->phys ?: "unknown"); |
71 | 73 | ||
72 | return 0; | 74 | return 0; |
73 | 75 | ||
@@ -80,8 +82,8 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | |||
80 | 82 | ||
81 | static void evbug_disconnect(struct input_handle *handle) | 83 | static void evbug_disconnect(struct input_handle *handle) |
82 | { | 84 | { |
83 | printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", | 85 | printk(KERN_DEBUG pr_fmt("Disconnected device: %s\n"), |
84 | dev_name(&handle->dev->dev)); | 86 | dev_name(&handle->dev->dev)); |
85 | 87 | ||
86 | input_close_device(handle); | 88 | input_close_device(handle); |
87 | input_unregister_handle(handle); | 89 | input_unregister_handle(handle); |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 9ddafc30f432..4cf25347b015 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * the Free Software Foundation. | 8 | * the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
12 | |||
11 | #define EVDEV_MINOR_BASE 64 | 13 | #define EVDEV_MINOR_BASE 64 |
12 | #define EVDEV_MINORS 32 | 14 | #define EVDEV_MINORS 32 |
13 | #define EVDEV_MIN_BUFFER_SIZE 64U | 15 | #define EVDEV_MIN_BUFFER_SIZE 64U |
@@ -28,7 +30,7 @@ struct evdev { | |||
28 | int minor; | 30 | int minor; |
29 | struct input_handle handle; | 31 | struct input_handle handle; |
30 | wait_queue_head_t wait; | 32 | wait_queue_head_t wait; |
31 | struct evdev_client *grab; | 33 | struct evdev_client __rcu *grab; |
32 | struct list_head client_list; | 34 | struct list_head client_list; |
33 | spinlock_t client_lock; /* protects client_list */ | 35 | spinlock_t client_lock; /* protects client_list */ |
34 | struct mutex mutex; | 36 | struct mutex mutex; |
@@ -37,13 +39,14 @@ struct evdev { | |||
37 | }; | 39 | }; |
38 | 40 | ||
39 | struct evdev_client { | 41 | struct evdev_client { |
40 | int head; | 42 | unsigned int head; |
41 | int tail; | 43 | unsigned int tail; |
44 | unsigned int packet_head; /* [future] position of the first element of next packet */ | ||
42 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ | 45 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ |
43 | struct fasync_struct *fasync; | 46 | struct fasync_struct *fasync; |
44 | struct evdev *evdev; | 47 | struct evdev *evdev; |
45 | struct list_head node; | 48 | struct list_head node; |
46 | int bufsize; | 49 | unsigned int bufsize; |
47 | struct input_event buffer[]; | 50 | struct input_event buffer[]; |
48 | }; | 51 | }; |
49 | 52 | ||
@@ -53,20 +56,33 @@ static DEFINE_MUTEX(evdev_table_mutex); | |||
53 | static void evdev_pass_event(struct evdev_client *client, | 56 | static void evdev_pass_event(struct evdev_client *client, |
54 | struct input_event *event) | 57 | struct input_event *event) |
55 | { | 58 | { |
56 | /* | 59 | /* Interrupts are disabled, just acquire the lock. */ |
57 | * Interrupts are disabled, just acquire the lock. | ||
58 | * Make sure we don't leave with the client buffer | ||
59 | * "empty" by having client->head == client->tail. | ||
60 | */ | ||
61 | spin_lock(&client->buffer_lock); | 60 | spin_lock(&client->buffer_lock); |
62 | do { | ||
63 | client->buffer[client->head++] = *event; | ||
64 | client->head &= client->bufsize - 1; | ||
65 | } while (client->head == client->tail); | ||
66 | spin_unlock(&client->buffer_lock); | ||
67 | 61 | ||
68 | if (event->type == EV_SYN) | 62 | client->buffer[client->head++] = *event; |
63 | client->head &= client->bufsize - 1; | ||
64 | |||
65 | if (unlikely(client->head == client->tail)) { | ||
66 | /* | ||
67 | * This effectively "drops" all unconsumed events, leaving | ||
68 | * EV_SYN/SYN_DROPPED plus the newest event in the queue. | ||
69 | */ | ||
70 | client->tail = (client->head - 2) & (client->bufsize - 1); | ||
71 | |||
72 | client->buffer[client->tail].time = event->time; | ||
73 | client->buffer[client->tail].type = EV_SYN; | ||
74 | client->buffer[client->tail].code = SYN_DROPPED; | ||
75 | client->buffer[client->tail].value = 0; | ||
76 | |||
77 | client->packet_head = client->tail; | ||
78 | } | ||
79 | |||
80 | if (event->type == EV_SYN && event->code == SYN_REPORT) { | ||
81 | client->packet_head = client->head; | ||
69 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | 82 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
83 | } | ||
84 | |||
85 | spin_unlock(&client->buffer_lock); | ||
70 | } | 86 | } |
71 | 87 | ||
72 | /* | 88 | /* |
@@ -95,7 +111,8 @@ static void evdev_event(struct input_handle *handle, | |||
95 | 111 | ||
96 | rcu_read_unlock(); | 112 | rcu_read_unlock(); |
97 | 113 | ||
98 | wake_up_interruptible(&evdev->wait); | 114 | if (type == EV_SYN && code == SYN_REPORT) |
115 | wake_up_interruptible(&evdev->wait); | ||
99 | } | 116 | } |
100 | 117 | ||
101 | static int evdev_fasync(int fd, struct file *file, int on) | 118 | static int evdev_fasync(int fd, struct file *file, int on) |
@@ -148,7 +165,6 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client) | |||
148 | return error; | 165 | return error; |
149 | 166 | ||
150 | rcu_assign_pointer(evdev->grab, client); | 167 | rcu_assign_pointer(evdev->grab, client); |
151 | synchronize_rcu(); | ||
152 | 168 | ||
153 | return 0; | 169 | return 0; |
154 | } | 170 | } |
@@ -171,7 +187,6 @@ static void evdev_attach_client(struct evdev *evdev, | |||
171 | spin_lock(&evdev->client_lock); | 187 | spin_lock(&evdev->client_lock); |
172 | list_add_tail_rcu(&client->node, &evdev->client_list); | 188 | list_add_tail_rcu(&client->node, &evdev->client_list); |
173 | spin_unlock(&evdev->client_lock); | 189 | spin_unlock(&evdev->client_lock); |
174 | synchronize_rcu(); | ||
175 | } | 190 | } |
176 | 191 | ||
177 | static void evdev_detach_client(struct evdev *evdev, | 192 | static void evdev_detach_client(struct evdev *evdev, |
@@ -319,6 +334,9 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, | |||
319 | struct input_event event; | 334 | struct input_event event; |
320 | int retval; | 335 | int retval; |
321 | 336 | ||
337 | if (count < input_event_size()) | ||
338 | return -EINVAL; | ||
339 | |||
322 | retval = mutex_lock_interruptible(&evdev->mutex); | 340 | retval = mutex_lock_interruptible(&evdev->mutex); |
323 | if (retval) | 341 | if (retval) |
324 | return retval; | 342 | return retval; |
@@ -328,17 +346,16 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, | |||
328 | goto out; | 346 | goto out; |
329 | } | 347 | } |
330 | 348 | ||
331 | while (retval < count) { | 349 | do { |
332 | |||
333 | if (input_event_from_user(buffer + retval, &event)) { | 350 | if (input_event_from_user(buffer + retval, &event)) { |
334 | retval = -EFAULT; | 351 | retval = -EFAULT; |
335 | goto out; | 352 | goto out; |
336 | } | 353 | } |
354 | retval += input_event_size(); | ||
337 | 355 | ||
338 | input_inject_event(&evdev->handle, | 356 | input_inject_event(&evdev->handle, |
339 | event.type, event.code, event.value); | 357 | event.type, event.code, event.value); |
340 | retval += input_event_size(); | 358 | } while (retval + input_event_size() <= count); |
341 | } | ||
342 | 359 | ||
343 | out: | 360 | out: |
344 | mutex_unlock(&evdev->mutex); | 361 | mutex_unlock(&evdev->mutex); |
@@ -374,12 +391,12 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, | |||
374 | if (count < input_event_size()) | 391 | if (count < input_event_size()) |
375 | return -EINVAL; | 392 | return -EINVAL; |
376 | 393 | ||
377 | if (client->head == client->tail && evdev->exist && | 394 | if (client->packet_head == client->tail && evdev->exist && |
378 | (file->f_flags & O_NONBLOCK)) | 395 | (file->f_flags & O_NONBLOCK)) |
379 | return -EAGAIN; | 396 | return -EAGAIN; |
380 | 397 | ||
381 | retval = wait_event_interruptible(evdev->wait, | 398 | retval = wait_event_interruptible(evdev->wait, |
382 | client->head != client->tail || !evdev->exist); | 399 | client->packet_head != client->tail || !evdev->exist); |
383 | if (retval) | 400 | if (retval) |
384 | return retval; | 401 | return retval; |
385 | 402 | ||
@@ -408,7 +425,7 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait) | |||
408 | poll_wait(file, &evdev->wait, wait); | 425 | poll_wait(file, &evdev->wait, wait); |
409 | 426 | ||
410 | mask = evdev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR; | 427 | mask = evdev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR; |
411 | if (client->head != client->tail) | 428 | if (client->packet_head != client->tail) |
412 | mask |= POLLIN | POLLRDNORM; | 429 | mask |= POLLIN | POLLRDNORM; |
413 | 430 | ||
414 | return mask; | 431 | return mask; |
@@ -522,18 +539,88 @@ static int handle_eviocgbit(struct input_dev *dev, | |||
522 | if (type == EV_KEY && size == OLD_KEY_MAX) { | 539 | if (type == EV_KEY && size == OLD_KEY_MAX) { |
523 | len = OLD_KEY_MAX; | 540 | len = OLD_KEY_MAX; |
524 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) | 541 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) |
525 | printk(KERN_WARNING | 542 | pr_warning("(EVIOCGBIT): Suspicious buffer size %u, " |
526 | "evdev.c(EVIOCGBIT): Suspicious buffer size %u, " | 543 | "limiting output to %zu bytes. See " |
527 | "limiting output to %zu bytes. See " | 544 | "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n", |
528 | "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n", | 545 | OLD_KEY_MAX, |
529 | OLD_KEY_MAX, | 546 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); |
530 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); | ||
531 | } | 547 | } |
532 | 548 | ||
533 | return bits_to_user(bits, len, size, p, compat_mode); | 549 | return bits_to_user(bits, len, size, p, compat_mode); |
534 | } | 550 | } |
535 | #undef OLD_KEY_MAX | 551 | #undef OLD_KEY_MAX |
536 | 552 | ||
553 | static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p) | ||
554 | { | ||
555 | struct input_keymap_entry ke = { | ||
556 | .len = sizeof(unsigned int), | ||
557 | .flags = 0, | ||
558 | }; | ||
559 | int __user *ip = (int __user *)p; | ||
560 | int error; | ||
561 | |||
562 | /* legacy case */ | ||
563 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | ||
564 | return -EFAULT; | ||
565 | |||
566 | error = input_get_keycode(dev, &ke); | ||
567 | if (error) | ||
568 | return error; | ||
569 | |||
570 | if (put_user(ke.keycode, ip + 1)) | ||
571 | return -EFAULT; | ||
572 | |||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p) | ||
577 | { | ||
578 | struct input_keymap_entry ke; | ||
579 | int error; | ||
580 | |||
581 | if (copy_from_user(&ke, p, sizeof(ke))) | ||
582 | return -EFAULT; | ||
583 | |||
584 | error = input_get_keycode(dev, &ke); | ||
585 | if (error) | ||
586 | return error; | ||
587 | |||
588 | if (copy_to_user(p, &ke, sizeof(ke))) | ||
589 | return -EFAULT; | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p) | ||
595 | { | ||
596 | struct input_keymap_entry ke = { | ||
597 | .len = sizeof(unsigned int), | ||
598 | .flags = 0, | ||
599 | }; | ||
600 | int __user *ip = (int __user *)p; | ||
601 | |||
602 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | ||
603 | return -EFAULT; | ||
604 | |||
605 | if (get_user(ke.keycode, ip + 1)) | ||
606 | return -EFAULT; | ||
607 | |||
608 | return input_set_keycode(dev, &ke); | ||
609 | } | ||
610 | |||
611 | static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) | ||
612 | { | ||
613 | struct input_keymap_entry ke; | ||
614 | |||
615 | if (copy_from_user(&ke, p, sizeof(ke))) | ||
616 | return -EFAULT; | ||
617 | |||
618 | if (ke.len > sizeof(ke.scancode)) | ||
619 | return -EINVAL; | ||
620 | |||
621 | return input_set_keycode(dev, &ke); | ||
622 | } | ||
623 | |||
537 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, | 624 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, |
538 | void __user *p, int compat_mode) | 625 | void __user *p, int compat_mode) |
539 | { | 626 | { |
@@ -580,25 +667,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
580 | 667 | ||
581 | return 0; | 668 | return 0; |
582 | 669 | ||
583 | case EVIOCGKEYCODE: | ||
584 | if (get_user(t, ip)) | ||
585 | return -EFAULT; | ||
586 | |||
587 | error = input_get_keycode(dev, t, &v); | ||
588 | if (error) | ||
589 | return error; | ||
590 | |||
591 | if (put_user(v, ip + 1)) | ||
592 | return -EFAULT; | ||
593 | |||
594 | return 0; | ||
595 | |||
596 | case EVIOCSKEYCODE: | ||
597 | if (get_user(t, ip) || get_user(v, ip + 1)) | ||
598 | return -EFAULT; | ||
599 | |||
600 | return input_set_keycode(dev, t, v); | ||
601 | |||
602 | case EVIOCRMFF: | 670 | case EVIOCRMFF: |
603 | return input_ff_erase(dev, (int)(unsigned long) p, file); | 671 | return input_ff_erase(dev, (int)(unsigned long) p, file); |
604 | 672 | ||
@@ -614,15 +682,30 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
614 | return evdev_grab(evdev, client); | 682 | return evdev_grab(evdev, client); |
615 | else | 683 | else |
616 | return evdev_ungrab(evdev, client); | 684 | return evdev_ungrab(evdev, client); |
685 | |||
686 | case EVIOCGKEYCODE: | ||
687 | return evdev_handle_get_keycode(dev, p); | ||
688 | |||
689 | case EVIOCSKEYCODE: | ||
690 | return evdev_handle_set_keycode(dev, p); | ||
691 | |||
692 | case EVIOCGKEYCODE_V2: | ||
693 | return evdev_handle_get_keycode_v2(dev, p); | ||
694 | |||
695 | case EVIOCSKEYCODE_V2: | ||
696 | return evdev_handle_set_keycode_v2(dev, p); | ||
617 | } | 697 | } |
618 | 698 | ||
619 | size = _IOC_SIZE(cmd); | 699 | size = _IOC_SIZE(cmd); |
620 | 700 | ||
621 | /* Now check variable-length commands */ | 701 | /* Now check variable-length commands */ |
622 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) | 702 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
623 | |||
624 | switch (EVIOC_MASK_SIZE(cmd)) { | 703 | switch (EVIOC_MASK_SIZE(cmd)) { |
625 | 704 | ||
705 | case EVIOCGPROP(0): | ||
706 | return bits_to_user(dev->propbit, INPUT_PROP_MAX, | ||
707 | size, p, compat_mode); | ||
708 | |||
626 | case EVIOCGKEY(0): | 709 | case EVIOCGKEY(0): |
627 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); | 710 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); |
628 | 711 | ||
@@ -767,7 +850,8 @@ static const struct file_operations evdev_fops = { | |||
767 | .compat_ioctl = evdev_ioctl_compat, | 850 | .compat_ioctl = evdev_ioctl_compat, |
768 | #endif | 851 | #endif |
769 | .fasync = evdev_fasync, | 852 | .fasync = evdev_fasync, |
770 | .flush = evdev_flush | 853 | .flush = evdev_flush, |
854 | .llseek = no_llseek, | ||
771 | }; | 855 | }; |
772 | 856 | ||
773 | static int evdev_install_chrdev(struct evdev *evdev) | 857 | static int evdev_install_chrdev(struct evdev *evdev) |
@@ -833,7 +917,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
833 | break; | 917 | break; |
834 | 918 | ||
835 | if (minor == EVDEV_MINORS) { | 919 | if (minor == EVDEV_MINORS) { |
836 | printk(KERN_ERR "evdev: no more free evdev devices\n"); | 920 | pr_err("no more free evdev devices\n"); |
837 | return -ENFILE; | 921 | return -ENFILE; |
838 | } | 922 | } |
839 | 923 | ||
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 03078c08309a..3367f760d75a 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | /* #define DEBUG */ | 24 | /* #define DEBUG */ |
25 | 25 | ||
26 | #define debug(format, arg...) pr_debug("ff-core: " format "\n", ## arg) | 26 | #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt |
27 | 27 | ||
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -116,7 +116,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, | |||
116 | 116 | ||
117 | if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX || | 117 | if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX || |
118 | !test_bit(effect->type, dev->ffbit)) { | 118 | !test_bit(effect->type, dev->ffbit)) { |
119 | debug("invalid or not supported effect type in upload"); | 119 | pr_debug("invalid or not supported effect type in upload\n"); |
120 | return -EINVAL; | 120 | return -EINVAL; |
121 | } | 121 | } |
122 | 122 | ||
@@ -124,7 +124,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, | |||
124 | (effect->u.periodic.waveform < FF_WAVEFORM_MIN || | 124 | (effect->u.periodic.waveform < FF_WAVEFORM_MIN || |
125 | effect->u.periodic.waveform > FF_WAVEFORM_MAX || | 125 | effect->u.periodic.waveform > FF_WAVEFORM_MAX || |
126 | !test_bit(effect->u.periodic.waveform, dev->ffbit))) { | 126 | !test_bit(effect->u.periodic.waveform, dev->ffbit))) { |
127 | debug("invalid or not supported wave form in upload"); | 127 | pr_debug("invalid or not supported wave form in upload\n"); |
128 | return -EINVAL; | 128 | return -EINVAL; |
129 | } | 129 | } |
130 | 130 | ||
@@ -246,7 +246,7 @@ static int flush_effects(struct input_dev *dev, struct file *file) | |||
246 | struct ff_device *ff = dev->ff; | 246 | struct ff_device *ff = dev->ff; |
247 | int i; | 247 | int i; |
248 | 248 | ||
249 | debug("flushing now"); | 249 | pr_debug("flushing now\n"); |
250 | 250 | ||
251 | mutex_lock(&ff->mutex); | 251 | mutex_lock(&ff->mutex); |
252 | 252 | ||
@@ -315,8 +315,7 @@ int input_ff_create(struct input_dev *dev, int max_effects) | |||
315 | int i; | 315 | int i; |
316 | 316 | ||
317 | if (!max_effects) { | 317 | if (!max_effects) { |
318 | printk(KERN_ERR | 318 | pr_err("cannot allocate device without any effects\n"); |
319 | "ff-core: cannot allocate device without any effects\n"); | ||
320 | return -EINVAL; | 319 | return -EINVAL; |
321 | } | 320 | } |
322 | 321 | ||
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index 1d881c96ba8f..117a59aaa70e 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | /* #define DEBUG */ | 24 | /* #define DEBUG */ |
25 | 25 | ||
26 | #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg) | 26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
27 | 27 | ||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
@@ -129,7 +129,7 @@ static void ml_schedule_timer(struct ml_device *ml) | |||
129 | int events = 0; | 129 | int events = 0; |
130 | int i; | 130 | int i; |
131 | 131 | ||
132 | debug("calculating next timer"); | 132 | pr_debug("calculating next timer\n"); |
133 | 133 | ||
134 | for (i = 0; i < FF_MEMLESS_EFFECTS; i++) { | 134 | for (i = 0; i < FF_MEMLESS_EFFECTS; i++) { |
135 | 135 | ||
@@ -149,10 +149,10 @@ static void ml_schedule_timer(struct ml_device *ml) | |||
149 | } | 149 | } |
150 | 150 | ||
151 | if (!events) { | 151 | if (!events) { |
152 | debug("no actions"); | 152 | pr_debug("no actions\n"); |
153 | del_timer(&ml->timer); | 153 | del_timer(&ml->timer); |
154 | } else { | 154 | } else { |
155 | debug("timer set"); | 155 | pr_debug("timer set\n"); |
156 | mod_timer(&ml->timer, earliest); | 156 | mod_timer(&ml->timer, earliest); |
157 | } | 157 | } |
158 | } | 158 | } |
@@ -173,8 +173,8 @@ static int apply_envelope(struct ml_effect_state *state, int value, | |||
173 | if (envelope->attack_length && | 173 | if (envelope->attack_length && |
174 | time_before(now, | 174 | time_before(now, |
175 | state->play_at + msecs_to_jiffies(envelope->attack_length))) { | 175 | state->play_at + msecs_to_jiffies(envelope->attack_length))) { |
176 | debug("value = 0x%x, attack_level = 0x%x", value, | 176 | pr_debug("value = 0x%x, attack_level = 0x%x\n", |
177 | envelope->attack_level); | 177 | value, envelope->attack_level); |
178 | time_from_level = jiffies_to_msecs(now - state->play_at); | 178 | time_from_level = jiffies_to_msecs(now - state->play_at); |
179 | time_of_envelope = envelope->attack_length; | 179 | time_of_envelope = envelope->attack_length; |
180 | envelope_level = min_t(__s16, envelope->attack_level, 0x7fff); | 180 | envelope_level = min_t(__s16, envelope->attack_level, 0x7fff); |
@@ -191,13 +191,13 @@ static int apply_envelope(struct ml_effect_state *state, int value, | |||
191 | 191 | ||
192 | difference = abs(value) - envelope_level; | 192 | difference = abs(value) - envelope_level; |
193 | 193 | ||
194 | debug("difference = %d", difference); | 194 | pr_debug("difference = %d\n", difference); |
195 | debug("time_from_level = 0x%x", time_from_level); | 195 | pr_debug("time_from_level = 0x%x\n", time_from_level); |
196 | debug("time_of_envelope = 0x%x", time_of_envelope); | 196 | pr_debug("time_of_envelope = 0x%x\n", time_of_envelope); |
197 | 197 | ||
198 | difference = difference * time_from_level / time_of_envelope; | 198 | difference = difference * time_from_level / time_of_envelope; |
199 | 199 | ||
200 | debug("difference = %d", difference); | 200 | pr_debug("difference = %d\n", difference); |
201 | 201 | ||
202 | return value < 0 ? | 202 | return value < 0 ? |
203 | -(difference + envelope_level) : (difference + envelope_level); | 203 | -(difference + envelope_level) : (difference + envelope_level); |
@@ -215,8 +215,7 @@ static int get_compatible_type(struct ff_device *ff, int effect_type) | |||
215 | if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit)) | 215 | if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit)) |
216 | return FF_RUMBLE; | 216 | return FF_RUMBLE; |
217 | 217 | ||
218 | printk(KERN_ERR | 218 | pr_err("invalid type in get_compatible_type()\n"); |
219 | "ff-memless: invalid type in get_compatible_type()\n"); | ||
220 | 219 | ||
221 | return 0; | 220 | return 0; |
222 | } | 221 | } |
@@ -312,7 +311,7 @@ static void ml_combine_effects(struct ff_effect *effect, | |||
312 | break; | 311 | break; |
313 | 312 | ||
314 | default: | 313 | default: |
315 | printk(KERN_ERR "ff-memless: invalid type in ml_combine_effects()\n"); | 314 | pr_err("invalid type in ml_combine_effects()\n"); |
316 | break; | 315 | break; |
317 | } | 316 | } |
318 | 317 | ||
@@ -406,7 +405,7 @@ static void ml_effect_timer(unsigned long timer_data) | |||
406 | struct ml_device *ml = dev->ff->private; | 405 | struct ml_device *ml = dev->ff->private; |
407 | unsigned long flags; | 406 | unsigned long flags; |
408 | 407 | ||
409 | debug("timer: updating effects"); | 408 | pr_debug("timer: updating effects\n"); |
410 | 409 | ||
411 | spin_lock_irqsave(&dev->event_lock, flags); | 410 | spin_lock_irqsave(&dev->event_lock, flags); |
412 | ml_play_effects(ml); | 411 | ml_play_effects(ml); |
@@ -438,7 +437,7 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) | |||
438 | struct ml_effect_state *state = &ml->states[effect_id]; | 437 | struct ml_effect_state *state = &ml->states[effect_id]; |
439 | 438 | ||
440 | if (value > 0) { | 439 | if (value > 0) { |
441 | debug("initiated play"); | 440 | pr_debug("initiated play\n"); |
442 | 441 | ||
443 | __set_bit(FF_EFFECT_STARTED, &state->flags); | 442 | __set_bit(FF_EFFECT_STARTED, &state->flags); |
444 | state->count = value; | 443 | state->count = value; |
@@ -449,7 +448,7 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) | |||
449 | state->adj_at = state->play_at; | 448 | state->adj_at = state->play_at; |
450 | 449 | ||
451 | } else { | 450 | } else { |
452 | debug("initiated stop"); | 451 | pr_debug("initiated stop\n"); |
453 | 452 | ||
454 | if (test_bit(FF_EFFECT_PLAYING, &state->flags)) | 453 | if (test_bit(FF_EFFECT_PLAYING, &state->flags)) |
455 | __set_bit(FF_EFFECT_ABORTING, &state->flags); | 454 | __set_bit(FF_EFFECT_ABORTING, &state->flags); |
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index 7392992da424..422aa0a6b77f 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c | |||
@@ -59,44 +59,52 @@ MODULE_DEVICE_TABLE(pci, emu_tbl); | |||
59 | 59 | ||
60 | static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 60 | static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
61 | { | 61 | { |
62 | int ioport, iolen; | ||
63 | struct emu *emu; | 62 | struct emu *emu; |
64 | struct gameport *port; | 63 | struct gameport *port; |
65 | 64 | int error; | |
66 | if (pci_enable_device(pdev)) | ||
67 | return -EBUSY; | ||
68 | |||
69 | ioport = pci_resource_start(pdev, 0); | ||
70 | iolen = pci_resource_len(pdev, 0); | ||
71 | |||
72 | if (!request_region(ioport, iolen, "emu10k1-gp")) | ||
73 | return -EBUSY; | ||
74 | 65 | ||
75 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); | 66 | emu = kzalloc(sizeof(struct emu), GFP_KERNEL); |
76 | port = gameport_allocate_port(); | 67 | port = gameport_allocate_port(); |
77 | if (!emu || !port) { | 68 | if (!emu || !port) { |
78 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); | 69 | printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); |
79 | release_region(ioport, iolen); | 70 | error = -ENOMEM; |
80 | kfree(emu); | 71 | goto err_out_free; |
81 | gameport_free_port(port); | ||
82 | return -ENOMEM; | ||
83 | } | 72 | } |
84 | 73 | ||
85 | emu->io = ioport; | 74 | error = pci_enable_device(pdev); |
86 | emu->size = iolen; | 75 | if (error) |
76 | goto err_out_free; | ||
77 | |||
78 | emu->io = pci_resource_start(pdev, 0); | ||
79 | emu->size = pci_resource_len(pdev, 0); | ||
80 | |||
87 | emu->dev = pdev; | 81 | emu->dev = pdev; |
88 | emu->gameport = port; | 82 | emu->gameport = port; |
89 | 83 | ||
90 | gameport_set_name(port, "EMU10K1"); | 84 | gameport_set_name(port, "EMU10K1"); |
91 | gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); | 85 | gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); |
92 | port->dev.parent = &pdev->dev; | 86 | port->dev.parent = &pdev->dev; |
93 | port->io = ioport; | 87 | port->io = emu->io; |
88 | |||
89 | if (!request_region(emu->io, emu->size, "emu10k1-gp")) { | ||
90 | printk(KERN_ERR "emu10k1-gp: unable to grab region 0x%x-0x%x\n", | ||
91 | emu->io, emu->io + emu->size - 1); | ||
92 | error = -EBUSY; | ||
93 | goto err_out_disable_dev; | ||
94 | } | ||
94 | 95 | ||
95 | pci_set_drvdata(pdev, emu); | 96 | pci_set_drvdata(pdev, emu); |
96 | 97 | ||
97 | gameport_register_port(port); | 98 | gameport_register_port(port); |
98 | 99 | ||
99 | return 0; | 100 | return 0; |
101 | |||
102 | err_out_disable_dev: | ||
103 | pci_disable_device(pdev); | ||
104 | err_out_free: | ||
105 | gameport_free_port(port); | ||
106 | kfree(emu); | ||
107 | return error; | ||
100 | } | 108 | } |
101 | 109 | ||
102 | static void __devexit emu_remove(struct pci_dev *pdev) | 110 | static void __devexit emu_remove(struct pci_dev *pdev) |
@@ -106,6 +114,8 @@ static void __devexit emu_remove(struct pci_dev *pdev) | |||
106 | gameport_unregister_port(emu->gameport); | 114 | gameport_unregister_port(emu->gameport); |
107 | release_region(emu->io, emu->size); | 115 | release_region(emu->io, emu->size); |
108 | kfree(emu); | 116 | kfree(emu); |
117 | |||
118 | pci_disable_device(pdev); | ||
109 | } | 119 | } |
110 | 120 | ||
111 | static struct pci_driver emu_driver = { | 121 | static struct pci_driver emu_driver = { |
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 14d3f3e208a2..a3b70ff21018 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
@@ -133,11 +133,11 @@ static void __devexit fm801_gp_remove(struct pci_dev *pci) | |||
133 | { | 133 | { |
134 | struct fm801_gp *gp = pci_get_drvdata(pci); | 134 | struct fm801_gp *gp = pci_get_drvdata(pci); |
135 | 135 | ||
136 | if (gp) { | 136 | gameport_unregister_port(gp->gameport); |
137 | gameport_unregister_port(gp->gameport); | 137 | release_resource(gp->res_port); |
138 | release_resource(gp->res_port); | 138 | kfree(gp); |
139 | kfree(gp); | 139 | |
140 | } | 140 | pci_disable_device(pci); |
141 | } | 141 | } |
142 | 142 | ||
143 | static const struct pci_device_id fm801_gp_id_table[] = { | 143 | static const struct pci_device_id fm801_gp_id_table[] = { |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 46239e47a260..5b8f59d6c3e8 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -18,13 +18,11 @@ | |||
18 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/gameport.h> | 20 | #include <linux/gameport.h> |
21 | #include <linux/wait.h> | ||
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
23 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
24 | #include <linux/kthread.h> | 23 | #include <linux/workqueue.h> |
25 | #include <linux/sched.h> /* HZ */ | 24 | #include <linux/sched.h> /* HZ */ |
26 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
27 | #include <linux/freezer.h> | ||
28 | 26 | ||
29 | /*#include <asm/io.h>*/ | 27 | /*#include <asm/io.h>*/ |
30 | 28 | ||
@@ -123,7 +121,7 @@ static int gameport_measure_speed(struct gameport *gameport) | |||
123 | } | 121 | } |
124 | 122 | ||
125 | gameport_close(gameport); | 123 | gameport_close(gameport); |
126 | return (cpu_data(raw_smp_processor_id()).loops_per_jiffy * | 124 | return (this_cpu_read(cpu_info.loops_per_jiffy) * |
127 | (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx); | 125 | (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx); |
128 | 126 | ||
129 | #else | 127 | #else |
@@ -234,58 +232,22 @@ struct gameport_event { | |||
234 | 232 | ||
235 | static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ | 233 | static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ |
236 | static LIST_HEAD(gameport_event_list); | 234 | static LIST_HEAD(gameport_event_list); |
237 | static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); | ||
238 | static struct task_struct *gameport_task; | ||
239 | 235 | ||
240 | static int gameport_queue_event(void *object, struct module *owner, | 236 | static struct gameport_event *gameport_get_event(void) |
241 | enum gameport_event_type event_type) | ||
242 | { | 237 | { |
238 | struct gameport_event *event = NULL; | ||
243 | unsigned long flags; | 239 | unsigned long flags; |
244 | struct gameport_event *event; | ||
245 | int retval = 0; | ||
246 | 240 | ||
247 | spin_lock_irqsave(&gameport_event_lock, flags); | 241 | spin_lock_irqsave(&gameport_event_lock, flags); |
248 | 242 | ||
249 | /* | 243 | if (!list_empty(&gameport_event_list)) { |
250 | * Scan event list for the other events for the same gameport port, | 244 | event = list_first_entry(&gameport_event_list, |
251 | * starting with the most recent one. If event is the same we | 245 | struct gameport_event, node); |
252 | * do not need add new one. If event is of different type we | 246 | list_del_init(&event->node); |
253 | * need to add this event and should not look further because | ||
254 | * we need to preseve sequence of distinct events. | ||
255 | */ | ||
256 | list_for_each_entry_reverse(event, &gameport_event_list, node) { | ||
257 | if (event->object == object) { | ||
258 | if (event->type == event_type) | ||
259 | goto out; | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); | ||
265 | if (!event) { | ||
266 | pr_err("Not enough memory to queue event %d\n", event_type); | ||
267 | retval = -ENOMEM; | ||
268 | goto out; | ||
269 | } | ||
270 | |||
271 | if (!try_module_get(owner)) { | ||
272 | pr_warning("Can't get module reference, dropping event %d\n", | ||
273 | event_type); | ||
274 | kfree(event); | ||
275 | retval = -EINVAL; | ||
276 | goto out; | ||
277 | } | 247 | } |
278 | 248 | ||
279 | event->type = event_type; | ||
280 | event->object = object; | ||
281 | event->owner = owner; | ||
282 | |||
283 | list_add_tail(&event->node, &gameport_event_list); | ||
284 | wake_up(&gameport_wait); | ||
285 | |||
286 | out: | ||
287 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 249 | spin_unlock_irqrestore(&gameport_event_lock, flags); |
288 | return retval; | 250 | return event; |
289 | } | 251 | } |
290 | 252 | ||
291 | static void gameport_free_event(struct gameport_event *event) | 253 | static void gameport_free_event(struct gameport_event *event) |
@@ -319,24 +281,8 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) | |||
319 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 281 | spin_unlock_irqrestore(&gameport_event_lock, flags); |
320 | } | 282 | } |
321 | 283 | ||
322 | static struct gameport_event *gameport_get_event(void) | ||
323 | { | ||
324 | struct gameport_event *event = NULL; | ||
325 | unsigned long flags; | ||
326 | |||
327 | spin_lock_irqsave(&gameport_event_lock, flags); | ||
328 | |||
329 | if (!list_empty(&gameport_event_list)) { | ||
330 | event = list_first_entry(&gameport_event_list, | ||
331 | struct gameport_event, node); | ||
332 | list_del_init(&event->node); | ||
333 | } | ||
334 | |||
335 | spin_unlock_irqrestore(&gameport_event_lock, flags); | ||
336 | return event; | ||
337 | } | ||
338 | 284 | ||
339 | static void gameport_handle_event(void) | 285 | static void gameport_handle_events(struct work_struct *work) |
340 | { | 286 | { |
341 | struct gameport_event *event; | 287 | struct gameport_event *event; |
342 | 288 | ||
@@ -368,6 +314,59 @@ static void gameport_handle_event(void) | |||
368 | mutex_unlock(&gameport_mutex); | 314 | mutex_unlock(&gameport_mutex); |
369 | } | 315 | } |
370 | 316 | ||
317 | static DECLARE_WORK(gameport_event_work, gameport_handle_events); | ||
318 | |||
319 | static int gameport_queue_event(void *object, struct module *owner, | ||
320 | enum gameport_event_type event_type) | ||
321 | { | ||
322 | unsigned long flags; | ||
323 | struct gameport_event *event; | ||
324 | int retval = 0; | ||
325 | |||
326 | spin_lock_irqsave(&gameport_event_lock, flags); | ||
327 | |||
328 | /* | ||
329 | * Scan event list for the other events for the same gameport port, | ||
330 | * starting with the most recent one. If event is the same we | ||
331 | * do not need add new one. If event is of different type we | ||
332 | * need to add this event and should not look further because | ||
333 | * we need to preserve sequence of distinct events. | ||
334 | */ | ||
335 | list_for_each_entry_reverse(event, &gameport_event_list, node) { | ||
336 | if (event->object == object) { | ||
337 | if (event->type == event_type) | ||
338 | goto out; | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); | ||
344 | if (!event) { | ||
345 | pr_err("Not enough memory to queue event %d\n", event_type); | ||
346 | retval = -ENOMEM; | ||
347 | goto out; | ||
348 | } | ||
349 | |||
350 | if (!try_module_get(owner)) { | ||
351 | pr_warning("Can't get module reference, dropping event %d\n", | ||
352 | event_type); | ||
353 | kfree(event); | ||
354 | retval = -EINVAL; | ||
355 | goto out; | ||
356 | } | ||
357 | |||
358 | event->type = event_type; | ||
359 | event->object = object; | ||
360 | event->owner = owner; | ||
361 | |||
362 | list_add_tail(&event->node, &gameport_event_list); | ||
363 | queue_work(system_long_wq, &gameport_event_work); | ||
364 | |||
365 | out: | ||
366 | spin_unlock_irqrestore(&gameport_event_lock, flags); | ||
367 | return retval; | ||
368 | } | ||
369 | |||
371 | /* | 370 | /* |
372 | * Remove all events that have been submitted for a given object, | 371 | * Remove all events that have been submitted for a given object, |
373 | * be it a gameport port or a driver. | 372 | * be it a gameport port or a driver. |
@@ -419,19 +418,6 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent) | |||
419 | return child; | 418 | return child; |
420 | } | 419 | } |
421 | 420 | ||
422 | static int gameport_thread(void *nothing) | ||
423 | { | ||
424 | set_freezable(); | ||
425 | do { | ||
426 | gameport_handle_event(); | ||
427 | wait_event_freezable(gameport_wait, | ||
428 | kthread_should_stop() || !list_empty(&gameport_event_list)); | ||
429 | } while (!kthread_should_stop()); | ||
430 | |||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | |||
435 | /* | 421 | /* |
436 | * Gameport port operations | 422 | * Gameport port operations |
437 | */ | 423 | */ |
@@ -814,13 +800,6 @@ static int __init gameport_init(void) | |||
814 | return error; | 800 | return error; |
815 | } | 801 | } |
816 | 802 | ||
817 | gameport_task = kthread_run(gameport_thread, NULL, "kgameportd"); | ||
818 | if (IS_ERR(gameport_task)) { | ||
819 | bus_unregister(&gameport_bus); | ||
820 | error = PTR_ERR(gameport_task); | ||
821 | pr_err("Failed to start kgameportd, error: %d\n", error); | ||
822 | return error; | ||
823 | } | ||
824 | 803 | ||
825 | return 0; | 804 | return 0; |
826 | } | 805 | } |
@@ -828,7 +807,12 @@ static int __init gameport_init(void) | |||
828 | static void __exit gameport_exit(void) | 807 | static void __exit gameport_exit(void) |
829 | { | 808 | { |
830 | bus_unregister(&gameport_bus); | 809 | bus_unregister(&gameport_bus); |
831 | kthread_stop(gameport_task); | 810 | |
811 | /* | ||
812 | * There should not be any outstanding events but work may | ||
813 | * still be scheduled so simply cancel it. | ||
814 | */ | ||
815 | cancel_work_sync(&gameport_event_work); | ||
832 | } | 816 | } |
833 | 817 | ||
834 | subsys_initcall(gameport_init); | 818 | subsys_initcall(gameport_init); |
diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h index 4d8ea32e8a00..22be27b424de 100644 --- a/drivers/input/input-compat.h +++ b/drivers/input/input-compat.h | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | /* Note to the author of this code: did it ever occur to | 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 */ | 21 | you why the ifdefs are needed? Think about it again. -AK */ |
22 | #ifdef CONFIG_X86_64 | 22 | #if defined(CONFIG_X86_64) || defined(CONFIG_TILE) |
23 | # define INPUT_COMPAT_TEST is_compat_task() | 23 | # define INPUT_COMPAT_TEST is_compat_task() |
24 | #elif defined(CONFIG_S390) | 24 | #elif defined(CONFIG_S390) |
25 | # define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT) | 25 | # define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT) |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c new file mode 100644 index 000000000000..c48c81f0308d --- /dev/null +++ b/drivers/input/input-mt.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* | ||
2 | * Input Multitouch Library | ||
3 | * | ||
4 | * Copyright (c) 2008-2010 Henrik Rydberg | ||
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 <linux/input/mt.h> | ||
12 | #include <linux/slab.h> | ||
13 | |||
14 | #define TRKID_SGN ((TRKID_MAX + 1) >> 1) | ||
15 | |||
16 | /** | ||
17 | * input_mt_init_slots() - initialize MT input slots | ||
18 | * @dev: input device supporting MT events and finger tracking | ||
19 | * @num_slots: number of slots used by the device | ||
20 | * | ||
21 | * This function allocates all necessary memory for MT slot handling | ||
22 | * in the input device, prepares the ABS_MT_SLOT and | ||
23 | * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. | ||
24 | * May be called repeatedly. Returns -EINVAL if attempting to | ||
25 | * reinitialize with a different number of slots. | ||
26 | */ | ||
27 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) | ||
28 | { | ||
29 | int i; | ||
30 | |||
31 | if (!num_slots) | ||
32 | return 0; | ||
33 | if (dev->mt) | ||
34 | return dev->mtsize != num_slots ? -EINVAL : 0; | ||
35 | |||
36 | dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL); | ||
37 | if (!dev->mt) | ||
38 | return -ENOMEM; | ||
39 | |||
40 | dev->mtsize = num_slots; | ||
41 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); | ||
42 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); | ||
43 | input_set_events_per_packet(dev, 6 * num_slots); | ||
44 | |||
45 | /* Mark slots as 'unused' */ | ||
46 | for (i = 0; i < num_slots; i++) | ||
47 | input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1); | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | EXPORT_SYMBOL(input_mt_init_slots); | ||
52 | |||
53 | /** | ||
54 | * input_mt_destroy_slots() - frees the MT slots of the input device | ||
55 | * @dev: input device with allocated MT slots | ||
56 | * | ||
57 | * This function is only needed in error path as the input core will | ||
58 | * automatically free the MT slots when the device is destroyed. | ||
59 | */ | ||
60 | void input_mt_destroy_slots(struct input_dev *dev) | ||
61 | { | ||
62 | kfree(dev->mt); | ||
63 | dev->mt = NULL; | ||
64 | dev->mtsize = 0; | ||
65 | dev->slot = 0; | ||
66 | dev->trkid = 0; | ||
67 | } | ||
68 | EXPORT_SYMBOL(input_mt_destroy_slots); | ||
69 | |||
70 | /** | ||
71 | * input_mt_report_slot_state() - report contact state | ||
72 | * @dev: input device with allocated MT slots | ||
73 | * @tool_type: the tool type to use in this slot | ||
74 | * @active: true if contact is active, false otherwise | ||
75 | * | ||
76 | * Reports a contact via ABS_MT_TRACKING_ID, and optionally | ||
77 | * ABS_MT_TOOL_TYPE. If active is true and the slot is currently | ||
78 | * inactive, or if the tool type is changed, a new tracking id is | ||
79 | * assigned to the slot. The tool type is only reported if the | ||
80 | * corresponding absbit field is set. | ||
81 | */ | ||
82 | void input_mt_report_slot_state(struct input_dev *dev, | ||
83 | unsigned int tool_type, bool active) | ||
84 | { | ||
85 | struct input_mt_slot *mt; | ||
86 | int id; | ||
87 | |||
88 | if (!dev->mt || !active) { | ||
89 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | mt = &dev->mt[dev->slot]; | ||
94 | id = input_mt_get_value(mt, ABS_MT_TRACKING_ID); | ||
95 | if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type) | ||
96 | id = input_mt_new_trkid(dev); | ||
97 | |||
98 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); | ||
99 | input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type); | ||
100 | } | ||
101 | EXPORT_SYMBOL(input_mt_report_slot_state); | ||
102 | |||
103 | /** | ||
104 | * input_mt_report_finger_count() - report contact count | ||
105 | * @dev: input device with allocated MT slots | ||
106 | * @count: the number of contacts | ||
107 | * | ||
108 | * Reports the contact count via BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, | ||
109 | * BTN_TOOL_TRIPLETAP and BTN_TOOL_QUADTAP. | ||
110 | * | ||
111 | * The input core ensures only the KEY events already setup for | ||
112 | * this device will produce output. | ||
113 | */ | ||
114 | void input_mt_report_finger_count(struct input_dev *dev, int count) | ||
115 | { | ||
116 | input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1); | ||
117 | input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2); | ||
118 | input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3); | ||
119 | input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4); | ||
120 | } | ||
121 | EXPORT_SYMBOL(input_mt_report_finger_count); | ||
122 | |||
123 | /** | ||
124 | * input_mt_report_pointer_emulation() - common pointer emulation | ||
125 | * @dev: input device with allocated MT slots | ||
126 | * @use_count: report number of active contacts as finger count | ||
127 | * | ||
128 | * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and | ||
129 | * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true. | ||
130 | * | ||
131 | * The input core ensures only the KEY and ABS axes already setup for | ||
132 | * this device will produce output. | ||
133 | */ | ||
134 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) | ||
135 | { | ||
136 | struct input_mt_slot *oldest = 0; | ||
137 | int oldid = dev->trkid; | ||
138 | int count = 0; | ||
139 | int i; | ||
140 | |||
141 | for (i = 0; i < dev->mtsize; ++i) { | ||
142 | struct input_mt_slot *ps = &dev->mt[i]; | ||
143 | int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); | ||
144 | |||
145 | if (id < 0) | ||
146 | continue; | ||
147 | if ((id - oldid) & TRKID_SGN) { | ||
148 | oldest = ps; | ||
149 | oldid = id; | ||
150 | } | ||
151 | count++; | ||
152 | } | ||
153 | |||
154 | input_event(dev, EV_KEY, BTN_TOUCH, count > 0); | ||
155 | if (use_count) | ||
156 | input_mt_report_finger_count(dev, count); | ||
157 | |||
158 | if (oldest) { | ||
159 | int x = input_mt_get_value(oldest, ABS_MT_POSITION_X); | ||
160 | int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y); | ||
161 | int p = input_mt_get_value(oldest, ABS_MT_PRESSURE); | ||
162 | |||
163 | input_event(dev, EV_ABS, ABS_X, x); | ||
164 | input_event(dev, EV_ABS, ABS_Y, y); | ||
165 | input_event(dev, EV_ABS, ABS_PRESSURE, p); | ||
166 | } else { | ||
167 | input_event(dev, EV_ABS, ABS_PRESSURE, 0); | ||
168 | } | ||
169 | } | ||
170 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); | ||
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 10c9b0a845f0..b1aabde87523 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c | |||
@@ -8,9 +8,12 @@ | |||
8 | * the Free Software Foundation. | 8 | * the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
12 | |||
11 | #include <linux/jiffies.h> | 13 | #include <linux/jiffies.h> |
12 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
13 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
16 | #include <linux/workqueue.h> | ||
14 | #include <linux/input-polldev.h> | 17 | #include <linux/input-polldev.h> |
15 | 18 | ||
16 | MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); | 19 | MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); |
@@ -18,45 +21,6 @@ MODULE_DESCRIPTION("Generic implementation of a polled input device"); | |||
18 | MODULE_LICENSE("GPL v2"); | 21 | MODULE_LICENSE("GPL v2"); |
19 | MODULE_VERSION("0.1"); | 22 | MODULE_VERSION("0.1"); |
20 | 23 | ||
21 | static DEFINE_MUTEX(polldev_mutex); | ||
22 | static int polldev_users; | ||
23 | static struct workqueue_struct *polldev_wq; | ||
24 | |||
25 | static int input_polldev_start_workqueue(void) | ||
26 | { | ||
27 | int retval; | ||
28 | |||
29 | retval = mutex_lock_interruptible(&polldev_mutex); | ||
30 | if (retval) | ||
31 | return retval; | ||
32 | |||
33 | if (!polldev_users) { | ||
34 | polldev_wq = create_singlethread_workqueue("ipolldevd"); | ||
35 | if (!polldev_wq) { | ||
36 | printk(KERN_ERR "input-polldev: failed to create " | ||
37 | "ipolldevd workqueue\n"); | ||
38 | retval = -ENOMEM; | ||
39 | goto out; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | polldev_users++; | ||
44 | |||
45 | out: | ||
46 | mutex_unlock(&polldev_mutex); | ||
47 | return retval; | ||
48 | } | ||
49 | |||
50 | static void input_polldev_stop_workqueue(void) | ||
51 | { | ||
52 | mutex_lock(&polldev_mutex); | ||
53 | |||
54 | if (!--polldev_users) | ||
55 | destroy_workqueue(polldev_wq); | ||
56 | |||
57 | mutex_unlock(&polldev_mutex); | ||
58 | } | ||
59 | |||
60 | static void input_polldev_queue_work(struct input_polled_dev *dev) | 24 | static void input_polldev_queue_work(struct input_polled_dev *dev) |
61 | { | 25 | { |
62 | unsigned long delay; | 26 | unsigned long delay; |
@@ -65,7 +29,7 @@ static void input_polldev_queue_work(struct input_polled_dev *dev) | |||
65 | if (delay >= HZ) | 29 | if (delay >= HZ) |
66 | delay = round_jiffies_relative(delay); | 30 | delay = round_jiffies_relative(delay); |
67 | 31 | ||
68 | queue_delayed_work(polldev_wq, &dev->work, delay); | 32 | queue_delayed_work(system_freezable_wq, &dev->work, delay); |
69 | } | 33 | } |
70 | 34 | ||
71 | static void input_polled_device_work(struct work_struct *work) | 35 | static void input_polled_device_work(struct work_struct *work) |
@@ -80,18 +44,13 @@ static void input_polled_device_work(struct work_struct *work) | |||
80 | static int input_open_polled_device(struct input_dev *input) | 44 | static int input_open_polled_device(struct input_dev *input) |
81 | { | 45 | { |
82 | struct input_polled_dev *dev = input_get_drvdata(input); | 46 | struct input_polled_dev *dev = input_get_drvdata(input); |
83 | int error; | ||
84 | |||
85 | error = input_polldev_start_workqueue(); | ||
86 | if (error) | ||
87 | return error; | ||
88 | 47 | ||
89 | if (dev->open) | 48 | if (dev->open) |
90 | dev->open(dev); | 49 | dev->open(dev); |
91 | 50 | ||
92 | /* Only start polling if polling is enabled */ | 51 | /* Only start polling if polling is enabled */ |
93 | if (dev->poll_interval > 0) | 52 | if (dev->poll_interval > 0) |
94 | queue_delayed_work(polldev_wq, &dev->work, 0); | 53 | queue_delayed_work(system_freezable_wq, &dev->work, 0); |
95 | 54 | ||
96 | return 0; | 55 | return 0; |
97 | } | 56 | } |
@@ -101,13 +60,6 @@ static void input_close_polled_device(struct input_dev *input) | |||
101 | struct input_polled_dev *dev = input_get_drvdata(input); | 60 | struct input_polled_dev *dev = input_get_drvdata(input); |
102 | 61 | ||
103 | cancel_delayed_work_sync(&dev->work); | 62 | cancel_delayed_work_sync(&dev->work); |
104 | /* | ||
105 | * Clean up work struct to remove references to the workqueue. | ||
106 | * It may be destroyed by the next call. This causes problems | ||
107 | * at next device open-close in case of poll_interval == 0. | ||
108 | */ | ||
109 | INIT_DELAYED_WORK(&dev->work, dev->work.work.func); | ||
110 | input_polldev_stop_workqueue(); | ||
111 | 63 | ||
112 | if (dev->close) | 64 | if (dev->close) |
113 | dev->close(dev); | 65 | dev->close(dev); |
@@ -191,7 +143,7 @@ static struct attribute_group input_polldev_attribute_group = { | |||
191 | }; | 143 | }; |
192 | 144 | ||
193 | /** | 145 | /** |
194 | * input_allocate_polled_device - allocated memory polled device | 146 | * input_allocate_polled_device - allocate memory for polled device |
195 | * | 147 | * |
196 | * The function allocates memory for a polled device and also | 148 | * The function allocates memory for a polled device and also |
197 | * for an input device associated with this polled device. | 149 | * for an input device associated with this polled device. |
@@ -238,7 +190,7 @@ EXPORT_SYMBOL(input_free_polled_device); | |||
238 | * with input layer. The device should be allocated with call to | 190 | * with input layer. The device should be allocated with call to |
239 | * input_allocate_polled_device(). Callers should also set up poll() | 191 | * input_allocate_polled_device(). Callers should also set up poll() |
240 | * method and set up capabilities (id, name, phys, bits) of the | 192 | * method and set up capabilities (id, name, phys, bits) of the |
241 | * corresponing input_dev structure. | 193 | * corresponding input_dev structure. |
242 | */ | 194 | */ |
243 | int input_register_polled_device(struct input_polled_dev *dev) | 195 | int input_register_polled_device(struct input_polled_dev *dev) |
244 | { | 196 | { |
@@ -294,4 +246,3 @@ void input_unregister_polled_device(struct input_polled_dev *dev) | |||
294 | input_unregister_device(dev->input); | 246 | input_unregister_device(dev->input); |
295 | } | 247 | } |
296 | EXPORT_SYMBOL(input_unregister_polled_device); | 248 | EXPORT_SYMBOL(input_unregister_polled_device); |
297 | |||
diff --git a/drivers/input/input.c b/drivers/input/input.c index ab6982056518..da38d97a51b1 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -10,9 +10,11 @@ | |||
10 | * the Free Software Foundation. | 10 | * the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt | ||
14 | |||
13 | #include <linux/init.h> | 15 | #include <linux/init.h> |
14 | #include <linux/types.h> | 16 | #include <linux/types.h> |
15 | #include <linux/input.h> | 17 | #include <linux/input/mt.h> |
16 | #include <linux/module.h> | 18 | #include <linux/module.h> |
17 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
18 | #include <linux/random.h> | 20 | #include <linux/random.h> |
@@ -24,7 +26,6 @@ | |||
24 | #include <linux/device.h> | 26 | #include <linux/device.h> |
25 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
26 | #include <linux/rcupdate.h> | 28 | #include <linux/rcupdate.h> |
27 | #include <linux/smp_lock.h> | ||
28 | #include "input-compat.h" | 29 | #include "input-compat.h" |
29 | 30 | ||
30 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | 31 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); |
@@ -171,7 +172,7 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
171 | if (code == ABS_MT_SLOT) { | 172 | if (code == ABS_MT_SLOT) { |
172 | /* | 173 | /* |
173 | * "Stage" the event; we'll flush it later, when we | 174 | * "Stage" the event; we'll flush it later, when we |
174 | * get actiual touch data. | 175 | * get actual touch data. |
175 | */ | 176 | */ |
176 | if (*pval >= 0 && *pval < dev->mtsize) | 177 | if (*pval >= 0 && *pval < dev->mtsize) |
177 | dev->slot = *pval; | 178 | dev->slot = *pval; |
@@ -188,7 +189,7 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
188 | pold = &mtslot->abs[code - ABS_MT_FIRST]; | 189 | pold = &mtslot->abs[code - ABS_MT_FIRST]; |
189 | } else { | 190 | } else { |
190 | /* | 191 | /* |
191 | * Bypass filtering for multitouch events when | 192 | * Bypass filtering for multi-touch events when |
192 | * not employing slots. | 193 | * not employing slots. |
193 | */ | 194 | */ |
194 | pold = NULL; | 195 | pold = NULL; |
@@ -450,7 +451,6 @@ int input_grab_device(struct input_handle *handle) | |||
450 | } | 451 | } |
451 | 452 | ||
452 | rcu_assign_pointer(dev->grab, handle); | 453 | rcu_assign_pointer(dev->grab, handle); |
453 | synchronize_rcu(); | ||
454 | 454 | ||
455 | out: | 455 | out: |
456 | mutex_unlock(&dev->mutex); | 456 | mutex_unlock(&dev->mutex); |
@@ -634,78 +634,141 @@ static void input_disconnect_device(struct input_dev *dev) | |||
634 | spin_unlock_irq(&dev->event_lock); | 634 | spin_unlock_irq(&dev->event_lock); |
635 | } | 635 | } |
636 | 636 | ||
637 | static int input_fetch_keycode(struct input_dev *dev, int scancode) | 637 | /** |
638 | * input_scancode_to_scalar() - converts scancode in &struct input_keymap_entry | ||
639 | * @ke: keymap entry containing scancode to be converted. | ||
640 | * @scancode: pointer to the location where converted scancode should | ||
641 | * be stored. | ||
642 | * | ||
643 | * This function is used to convert scancode stored in &struct keymap_entry | ||
644 | * into scalar form understood by legacy keymap handling methods. These | ||
645 | * methods expect scancodes to be represented as 'unsigned int'. | ||
646 | */ | ||
647 | int input_scancode_to_scalar(const struct input_keymap_entry *ke, | ||
648 | unsigned int *scancode) | ||
649 | { | ||
650 | switch (ke->len) { | ||
651 | case 1: | ||
652 | *scancode = *((u8 *)ke->scancode); | ||
653 | break; | ||
654 | |||
655 | case 2: | ||
656 | *scancode = *((u16 *)ke->scancode); | ||
657 | break; | ||
658 | |||
659 | case 4: | ||
660 | *scancode = *((u32 *)ke->scancode); | ||
661 | break; | ||
662 | |||
663 | default: | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | |||
667 | return 0; | ||
668 | } | ||
669 | EXPORT_SYMBOL(input_scancode_to_scalar); | ||
670 | |||
671 | /* | ||
672 | * Those routines handle the default case where no [gs]etkeycode() is | ||
673 | * defined. In this case, an array indexed by the scancode is used. | ||
674 | */ | ||
675 | |||
676 | static unsigned int input_fetch_keycode(struct input_dev *dev, | ||
677 | unsigned int index) | ||
638 | { | 678 | { |
639 | switch (dev->keycodesize) { | 679 | switch (dev->keycodesize) { |
640 | case 1: | 680 | case 1: |
641 | return ((u8 *)dev->keycode)[scancode]; | 681 | return ((u8 *)dev->keycode)[index]; |
642 | 682 | ||
643 | case 2: | 683 | case 2: |
644 | return ((u16 *)dev->keycode)[scancode]; | 684 | return ((u16 *)dev->keycode)[index]; |
645 | 685 | ||
646 | default: | 686 | default: |
647 | return ((u32 *)dev->keycode)[scancode]; | 687 | return ((u32 *)dev->keycode)[index]; |
648 | } | 688 | } |
649 | } | 689 | } |
650 | 690 | ||
651 | static int input_default_getkeycode(struct input_dev *dev, | 691 | static int input_default_getkeycode(struct input_dev *dev, |
652 | unsigned int scancode, | 692 | struct input_keymap_entry *ke) |
653 | unsigned int *keycode) | ||
654 | { | 693 | { |
694 | unsigned int index; | ||
695 | int error; | ||
696 | |||
655 | if (!dev->keycodesize) | 697 | if (!dev->keycodesize) |
656 | return -EINVAL; | 698 | return -EINVAL; |
657 | 699 | ||
658 | if (scancode >= dev->keycodemax) | 700 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) |
701 | index = ke->index; | ||
702 | else { | ||
703 | error = input_scancode_to_scalar(ke, &index); | ||
704 | if (error) | ||
705 | return error; | ||
706 | } | ||
707 | |||
708 | if (index >= dev->keycodemax) | ||
659 | return -EINVAL; | 709 | return -EINVAL; |
660 | 710 | ||
661 | *keycode = input_fetch_keycode(dev, scancode); | 711 | ke->keycode = input_fetch_keycode(dev, index); |
712 | ke->index = index; | ||
713 | ke->len = sizeof(index); | ||
714 | memcpy(ke->scancode, &index, sizeof(index)); | ||
662 | 715 | ||
663 | return 0; | 716 | return 0; |
664 | } | 717 | } |
665 | 718 | ||
666 | static int input_default_setkeycode(struct input_dev *dev, | 719 | static int input_default_setkeycode(struct input_dev *dev, |
667 | unsigned int scancode, | 720 | const struct input_keymap_entry *ke, |
668 | unsigned int keycode) | 721 | unsigned int *old_keycode) |
669 | { | 722 | { |
670 | int old_keycode; | 723 | unsigned int index; |
724 | int error; | ||
671 | int i; | 725 | int i; |
672 | 726 | ||
673 | if (scancode >= dev->keycodemax) | 727 | if (!dev->keycodesize) |
674 | return -EINVAL; | 728 | return -EINVAL; |
675 | 729 | ||
676 | if (!dev->keycodesize) | 730 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
731 | index = ke->index; | ||
732 | } else { | ||
733 | error = input_scancode_to_scalar(ke, &index); | ||
734 | if (error) | ||
735 | return error; | ||
736 | } | ||
737 | |||
738 | if (index >= dev->keycodemax) | ||
677 | return -EINVAL; | 739 | return -EINVAL; |
678 | 740 | ||
679 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) | 741 | if (dev->keycodesize < sizeof(ke->keycode) && |
742 | (ke->keycode >> (dev->keycodesize * 8))) | ||
680 | return -EINVAL; | 743 | return -EINVAL; |
681 | 744 | ||
682 | switch (dev->keycodesize) { | 745 | switch (dev->keycodesize) { |
683 | case 1: { | 746 | case 1: { |
684 | u8 *k = (u8 *)dev->keycode; | 747 | u8 *k = (u8 *)dev->keycode; |
685 | old_keycode = k[scancode]; | 748 | *old_keycode = k[index]; |
686 | k[scancode] = keycode; | 749 | k[index] = ke->keycode; |
687 | break; | 750 | break; |
688 | } | 751 | } |
689 | case 2: { | 752 | case 2: { |
690 | u16 *k = (u16 *)dev->keycode; | 753 | u16 *k = (u16 *)dev->keycode; |
691 | old_keycode = k[scancode]; | 754 | *old_keycode = k[index]; |
692 | k[scancode] = keycode; | 755 | k[index] = ke->keycode; |
693 | break; | 756 | break; |
694 | } | 757 | } |
695 | default: { | 758 | default: { |
696 | u32 *k = (u32 *)dev->keycode; | 759 | u32 *k = (u32 *)dev->keycode; |
697 | old_keycode = k[scancode]; | 760 | *old_keycode = k[index]; |
698 | k[scancode] = keycode; | 761 | k[index] = ke->keycode; |
699 | break; | 762 | break; |
700 | } | 763 | } |
701 | } | 764 | } |
702 | 765 | ||
703 | __clear_bit(old_keycode, dev->keybit); | 766 | __clear_bit(*old_keycode, dev->keybit); |
704 | __set_bit(keycode, dev->keybit); | 767 | __set_bit(ke->keycode, dev->keybit); |
705 | 768 | ||
706 | for (i = 0; i < dev->keycodemax; i++) { | 769 | for (i = 0; i < dev->keycodemax; i++) { |
707 | if (input_fetch_keycode(dev, i) == old_keycode) { | 770 | if (input_fetch_keycode(dev, i) == *old_keycode) { |
708 | __set_bit(old_keycode, dev->keybit); | 771 | __set_bit(*old_keycode, dev->keybit); |
709 | break; /* Setting the bit twice is useless, so break */ | 772 | break; /* Setting the bit twice is useless, so break */ |
710 | } | 773 | } |
711 | } | 774 | } |
@@ -716,21 +779,18 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
716 | /** | 779 | /** |
717 | * input_get_keycode - retrieve keycode currently mapped to a given scancode | 780 | * input_get_keycode - retrieve keycode currently mapped to a given scancode |
718 | * @dev: input device which keymap is being queried | 781 | * @dev: input device which keymap is being queried |
719 | * @scancode: scancode (or its equivalent for device in question) for which | 782 | * @ke: keymap entry |
720 | * keycode is needed | ||
721 | * @keycode: result | ||
722 | * | 783 | * |
723 | * This function should be called by anyone interested in retrieving current | 784 | * This function should be called by anyone interested in retrieving current |
724 | * keymap. Presently keyboard and evdev handlers use it. | 785 | * keymap. Presently evdev handlers use it. |
725 | */ | 786 | */ |
726 | int input_get_keycode(struct input_dev *dev, | 787 | int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke) |
727 | unsigned int scancode, unsigned int *keycode) | ||
728 | { | 788 | { |
729 | unsigned long flags; | 789 | unsigned long flags; |
730 | int retval; | 790 | int retval; |
731 | 791 | ||
732 | spin_lock_irqsave(&dev->event_lock, flags); | 792 | spin_lock_irqsave(&dev->event_lock, flags); |
733 | retval = dev->getkeycode(dev, scancode, keycode); | 793 | retval = dev->getkeycode(dev, ke); |
734 | spin_unlock_irqrestore(&dev->event_lock, flags); | 794 | spin_unlock_irqrestore(&dev->event_lock, flags); |
735 | 795 | ||
736 | return retval; | 796 | return retval; |
@@ -738,31 +798,26 @@ int input_get_keycode(struct input_dev *dev, | |||
738 | EXPORT_SYMBOL(input_get_keycode); | 798 | EXPORT_SYMBOL(input_get_keycode); |
739 | 799 | ||
740 | /** | 800 | /** |
741 | * input_get_keycode - assign new keycode to a given scancode | 801 | * input_set_keycode - attribute a keycode to a given scancode |
742 | * @dev: input device which keymap is being updated | 802 | * @dev: input device which keymap is being updated |
743 | * @scancode: scancode (or its equivalent for device in question) | 803 | * @ke: new keymap entry |
744 | * @keycode: new keycode to be assigned to the scancode | ||
745 | * | 804 | * |
746 | * This function should be called by anyone needing to update current | 805 | * This function should be called by anyone needing to update current |
747 | * keymap. Presently keyboard and evdev handlers use it. | 806 | * keymap. Presently keyboard and evdev handlers use it. |
748 | */ | 807 | */ |
749 | int input_set_keycode(struct input_dev *dev, | 808 | int input_set_keycode(struct input_dev *dev, |
750 | unsigned int scancode, unsigned int keycode) | 809 | const struct input_keymap_entry *ke) |
751 | { | 810 | { |
752 | unsigned long flags; | 811 | unsigned long flags; |
753 | unsigned int old_keycode; | 812 | unsigned int old_keycode; |
754 | int retval; | 813 | int retval; |
755 | 814 | ||
756 | if (keycode > KEY_MAX) | 815 | if (ke->keycode > KEY_MAX) |
757 | return -EINVAL; | 816 | return -EINVAL; |
758 | 817 | ||
759 | spin_lock_irqsave(&dev->event_lock, flags); | 818 | spin_lock_irqsave(&dev->event_lock, flags); |
760 | 819 | ||
761 | retval = dev->getkeycode(dev, scancode, &old_keycode); | 820 | retval = dev->setkeycode(dev, ke, &old_keycode); |
762 | if (retval) | ||
763 | goto out; | ||
764 | |||
765 | retval = dev->setkeycode(dev, scancode, keycode); | ||
766 | if (retval) | 821 | if (retval) |
767 | goto out; | 822 | goto out; |
768 | 823 | ||
@@ -848,10 +903,8 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
848 | 903 | ||
849 | error = handler->connect(handler, dev, id); | 904 | error = handler->connect(handler, dev, id); |
850 | if (error && error != -ENODEV) | 905 | if (error && error != -ENODEV) |
851 | printk(KERN_ERR | 906 | pr_err("failed to attach handler %s to device %s, error: %d\n", |
852 | "input: failed to attach handler %s to device %s, " | 907 | handler->name, kobject_name(&dev->dev.kobj), error); |
853 | "error: %d\n", | ||
854 | handler->name, kobject_name(&dev->dev.kobj), error); | ||
855 | 908 | ||
856 | return error; | 909 | return error; |
857 | } | 910 | } |
@@ -999,6 +1052,8 @@ static int input_devices_seq_show(struct seq_file *seq, void *v) | |||
999 | seq_printf(seq, "%s ", handle->name); | 1052 | seq_printf(seq, "%s ", handle->name); |
1000 | seq_putc(seq, '\n'); | 1053 | seq_putc(seq, '\n'); |
1001 | 1054 | ||
1055 | input_seq_print_bitmap(seq, "PROP", dev->propbit, INPUT_PROP_MAX); | ||
1056 | |||
1002 | input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX); | 1057 | input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX); |
1003 | if (test_bit(EV_KEY, dev->evbit)) | 1058 | if (test_bit(EV_KEY, dev->evbit)) |
1004 | input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX); | 1059 | input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX); |
@@ -1222,11 +1277,26 @@ static ssize_t input_dev_show_modalias(struct device *dev, | |||
1222 | } | 1277 | } |
1223 | static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); | 1278 | static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); |
1224 | 1279 | ||
1280 | static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, | ||
1281 | int max, int add_cr); | ||
1282 | |||
1283 | static ssize_t input_dev_show_properties(struct device *dev, | ||
1284 | struct device_attribute *attr, | ||
1285 | char *buf) | ||
1286 | { | ||
1287 | struct input_dev *input_dev = to_input_dev(dev); | ||
1288 | int len = input_print_bitmap(buf, PAGE_SIZE, input_dev->propbit, | ||
1289 | INPUT_PROP_MAX, true); | ||
1290 | return min_t(int, len, PAGE_SIZE); | ||
1291 | } | ||
1292 | static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL); | ||
1293 | |||
1225 | static struct attribute *input_dev_attrs[] = { | 1294 | static struct attribute *input_dev_attrs[] = { |
1226 | &dev_attr_name.attr, | 1295 | &dev_attr_name.attr, |
1227 | &dev_attr_phys.attr, | 1296 | &dev_attr_phys.attr, |
1228 | &dev_attr_uniq.attr, | 1297 | &dev_attr_uniq.attr, |
1229 | &dev_attr_modalias.attr, | 1298 | &dev_attr_modalias.attr, |
1299 | &dev_attr_properties.attr, | ||
1230 | NULL | 1300 | NULL |
1231 | }; | 1301 | }; |
1232 | 1302 | ||
@@ -1360,7 +1430,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, | |||
1360 | { | 1430 | { |
1361 | int len; | 1431 | int len; |
1362 | 1432 | ||
1363 | if (add_uevent_var(env, "%s=", name)) | 1433 | if (add_uevent_var(env, "%s", name)) |
1364 | return -ENOMEM; | 1434 | return -ENOMEM; |
1365 | 1435 | ||
1366 | len = input_print_bitmap(&env->buf[env->buflen - 1], | 1436 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
@@ -1426,6 +1496,8 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
1426 | if (dev->uniq) | 1496 | if (dev->uniq) |
1427 | INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); | 1497 | INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); |
1428 | 1498 | ||
1499 | INPUT_ADD_HOTPLUG_BM_VAR("PROP=", dev->propbit, INPUT_PROP_MAX); | ||
1500 | |||
1429 | INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); | 1501 | INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); |
1430 | if (test_bit(EV_KEY, dev->evbit)) | 1502 | if (test_bit(EV_KEY, dev->evbit)) |
1431 | INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX); | 1503 | INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX); |
@@ -1469,8 +1541,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
1469 | } \ | 1541 | } \ |
1470 | } while (0) | 1542 | } while (0) |
1471 | 1543 | ||
1472 | #ifdef CONFIG_PM | 1544 | static void input_dev_toggle(struct input_dev *dev, bool activate) |
1473 | static void input_dev_reset(struct input_dev *dev, bool activate) | ||
1474 | { | 1545 | { |
1475 | if (!dev->event) | 1546 | if (!dev->event) |
1476 | return; | 1547 | return; |
@@ -1484,12 +1555,44 @@ static void input_dev_reset(struct input_dev *dev, bool activate) | |||
1484 | } | 1555 | } |
1485 | } | 1556 | } |
1486 | 1557 | ||
1558 | /** | ||
1559 | * input_reset_device() - reset/restore the state of input device | ||
1560 | * @dev: input device whose state needs to be reset | ||
1561 | * | ||
1562 | * This function tries to reset the state of an opened input device and | ||
1563 | * bring internal state and state if the hardware in sync with each other. | ||
1564 | * We mark all keys as released, restore LED state, repeat rate, etc. | ||
1565 | */ | ||
1566 | void input_reset_device(struct input_dev *dev) | ||
1567 | { | ||
1568 | mutex_lock(&dev->mutex); | ||
1569 | |||
1570 | if (dev->users) { | ||
1571 | input_dev_toggle(dev, true); | ||
1572 | |||
1573 | /* | ||
1574 | * Keys that have been pressed at suspend time are unlikely | ||
1575 | * to be still pressed when we resume. | ||
1576 | */ | ||
1577 | spin_lock_irq(&dev->event_lock); | ||
1578 | input_dev_release_keys(dev); | ||
1579 | spin_unlock_irq(&dev->event_lock); | ||
1580 | } | ||
1581 | |||
1582 | mutex_unlock(&dev->mutex); | ||
1583 | } | ||
1584 | EXPORT_SYMBOL(input_reset_device); | ||
1585 | |||
1586 | #ifdef CONFIG_PM | ||
1487 | static int input_dev_suspend(struct device *dev) | 1587 | static int input_dev_suspend(struct device *dev) |
1488 | { | 1588 | { |
1489 | struct input_dev *input_dev = to_input_dev(dev); | 1589 | struct input_dev *input_dev = to_input_dev(dev); |
1490 | 1590 | ||
1491 | mutex_lock(&input_dev->mutex); | 1591 | mutex_lock(&input_dev->mutex); |
1492 | input_dev_reset(input_dev, false); | 1592 | |
1593 | if (input_dev->users) | ||
1594 | input_dev_toggle(input_dev, false); | ||
1595 | |||
1493 | mutex_unlock(&input_dev->mutex); | 1596 | mutex_unlock(&input_dev->mutex); |
1494 | 1597 | ||
1495 | return 0; | 1598 | return 0; |
@@ -1499,18 +1602,7 @@ static int input_dev_resume(struct device *dev) | |||
1499 | { | 1602 | { |
1500 | struct input_dev *input_dev = to_input_dev(dev); | 1603 | struct input_dev *input_dev = to_input_dev(dev); |
1501 | 1604 | ||
1502 | mutex_lock(&input_dev->mutex); | 1605 | input_reset_device(input_dev); |
1503 | input_dev_reset(input_dev, true); | ||
1504 | |||
1505 | /* | ||
1506 | * Keys that have been pressed at suspend time are unlikely | ||
1507 | * to be still pressed when we resume. | ||
1508 | */ | ||
1509 | spin_lock_irq(&input_dev->event_lock); | ||
1510 | input_dev_release_keys(input_dev); | ||
1511 | spin_unlock_irq(&input_dev->event_lock); | ||
1512 | |||
1513 | mutex_unlock(&input_dev->mutex); | ||
1514 | 1606 | ||
1515 | return 0; | 1607 | return 0; |
1516 | } | 1608 | } |
@@ -1595,52 +1687,6 @@ void input_free_device(struct input_dev *dev) | |||
1595 | EXPORT_SYMBOL(input_free_device); | 1687 | EXPORT_SYMBOL(input_free_device); |
1596 | 1688 | ||
1597 | /** | 1689 | /** |
1598 | * input_mt_create_slots() - create MT input slots | ||
1599 | * @dev: input device supporting MT events and finger tracking | ||
1600 | * @num_slots: number of slots used by the device | ||
1601 | * | ||
1602 | * This function allocates all necessary memory for MT slot handling in the | ||
1603 | * input device, and adds ABS_MT_SLOT to the device capabilities. All slots | ||
1604 | * are initially marked as unused iby setting ABS_MT_TRACKING_ID to -1. | ||
1605 | */ | ||
1606 | int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots) | ||
1607 | { | ||
1608 | int i; | ||
1609 | |||
1610 | if (!num_slots) | ||
1611 | return 0; | ||
1612 | |||
1613 | dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL); | ||
1614 | if (!dev->mt) | ||
1615 | return -ENOMEM; | ||
1616 | |||
1617 | dev->mtsize = num_slots; | ||
1618 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); | ||
1619 | |||
1620 | /* Mark slots as 'unused' */ | ||
1621 | for (i = 0; i < num_slots; i++) | ||
1622 | dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1; | ||
1623 | |||
1624 | return 0; | ||
1625 | } | ||
1626 | EXPORT_SYMBOL(input_mt_create_slots); | ||
1627 | |||
1628 | /** | ||
1629 | * input_mt_destroy_slots() - frees the MT slots of the input device | ||
1630 | * @dev: input device with allocated MT slots | ||
1631 | * | ||
1632 | * This function is only needed in error path as the input core will | ||
1633 | * automatically free the MT slots when the device is destroyed. | ||
1634 | */ | ||
1635 | void input_mt_destroy_slots(struct input_dev *dev) | ||
1636 | { | ||
1637 | kfree(dev->mt); | ||
1638 | dev->mt = NULL; | ||
1639 | dev->mtsize = 0; | ||
1640 | } | ||
1641 | EXPORT_SYMBOL(input_mt_destroy_slots); | ||
1642 | |||
1643 | /** | ||
1644 | * input_set_capability - mark device as capable of a certain event | 1690 | * input_set_capability - mark device as capable of a certain event |
1645 | * @dev: device that is capable of emitting or accepting event | 1691 | * @dev: device that is capable of emitting or accepting event |
1646 | * @type: type of the event (EV_KEY, EV_REL, etc...) | 1692 | * @type: type of the event (EV_KEY, EV_REL, etc...) |
@@ -1689,9 +1735,8 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int | |||
1689 | break; | 1735 | break; |
1690 | 1736 | ||
1691 | default: | 1737 | default: |
1692 | printk(KERN_ERR | 1738 | pr_err("input_set_capability: unknown type %u (code %u)\n", |
1693 | "input_set_capability: unknown type %u (code %u)\n", | 1739 | type, code); |
1694 | type, code); | ||
1695 | dump_stack(); | 1740 | dump_stack(); |
1696 | return; | 1741 | return; |
1697 | } | 1742 | } |
@@ -1700,6 +1745,42 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int | |||
1700 | } | 1745 | } |
1701 | EXPORT_SYMBOL(input_set_capability); | 1746 | EXPORT_SYMBOL(input_set_capability); |
1702 | 1747 | ||
1748 | static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | ||
1749 | { | ||
1750 | int mt_slots; | ||
1751 | int i; | ||
1752 | unsigned int events; | ||
1753 | |||
1754 | if (dev->mtsize) { | ||
1755 | mt_slots = dev->mtsize; | ||
1756 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { | ||
1757 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - | ||
1758 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, | ||
1759 | mt_slots = clamp(mt_slots, 2, 32); | ||
1760 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | ||
1761 | mt_slots = 2; | ||
1762 | } else { | ||
1763 | mt_slots = 0; | ||
1764 | } | ||
1765 | |||
1766 | events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ | ||
1767 | |||
1768 | for (i = 0; i < ABS_CNT; i++) { | ||
1769 | if (test_bit(i, dev->absbit)) { | ||
1770 | if (input_is_mt_axis(i)) | ||
1771 | events += mt_slots; | ||
1772 | else | ||
1773 | events++; | ||
1774 | } | ||
1775 | } | ||
1776 | |||
1777 | for (i = 0; i < REL_CNT; i++) | ||
1778 | if (test_bit(i, dev->relbit)) | ||
1779 | events++; | ||
1780 | |||
1781 | return events; | ||
1782 | } | ||
1783 | |||
1703 | #define INPUT_CLEANSE_BITMASK(dev, type, bits) \ | 1784 | #define INPUT_CLEANSE_BITMASK(dev, type, bits) \ |
1704 | do { \ | 1785 | do { \ |
1705 | if (!test_bit(EV_##type, dev->evbit)) \ | 1786 | if (!test_bit(EV_##type, dev->evbit)) \ |
@@ -1747,6 +1828,10 @@ int input_register_device(struct input_dev *dev) | |||
1747 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ | 1828 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ |
1748 | input_cleanse_bitmasks(dev); | 1829 | input_cleanse_bitmasks(dev); |
1749 | 1830 | ||
1831 | if (!dev->hint_events_per_packet) | ||
1832 | dev->hint_events_per_packet = | ||
1833 | input_estimate_events_per_packet(dev); | ||
1834 | |||
1750 | /* | 1835 | /* |
1751 | * If delay and period are pre-set by the driver, then autorepeating | 1836 | * If delay and period are pre-set by the driver, then autorepeating |
1752 | * is handled by the driver itself and we don't do it in input.c. | 1837 | * is handled by the driver itself and we don't do it in input.c. |
@@ -1773,8 +1858,9 @@ int input_register_device(struct input_dev *dev) | |||
1773 | return error; | 1858 | return error; |
1774 | 1859 | ||
1775 | path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); | 1860 | path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); |
1776 | printk(KERN_INFO "input: %s as %s\n", | 1861 | pr_info("%s as %s\n", |
1777 | dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); | 1862 | dev->name ? dev->name : "Unspecified device", |
1863 | path ? path : "N/A"); | ||
1778 | kfree(path); | 1864 | kfree(path); |
1779 | 1865 | ||
1780 | error = mutex_lock_interruptible(&input_mutex); | 1866 | error = mutex_lock_interruptible(&input_mutex); |
@@ -2047,6 +2133,7 @@ out: | |||
2047 | static const struct file_operations input_fops = { | 2133 | static const struct file_operations input_fops = { |
2048 | .owner = THIS_MODULE, | 2134 | .owner = THIS_MODULE, |
2049 | .open = input_open_file, | 2135 | .open = input_open_file, |
2136 | .llseek = noop_llseek, | ||
2050 | }; | 2137 | }; |
2051 | 2138 | ||
2052 | static int __init input_init(void) | 2139 | static int __init input_init(void) |
@@ -2055,7 +2142,7 @@ static int __init input_init(void) | |||
2055 | 2142 | ||
2056 | err = class_register(&input_class); | 2143 | err = class_register(&input_class); |
2057 | if (err) { | 2144 | if (err) { |
2058 | printk(KERN_ERR "input: unable to register input_dev class\n"); | 2145 | pr_err("unable to register input_dev class\n"); |
2059 | return err; | 2146 | return err; |
2060 | } | 2147 | } |
2061 | 2148 | ||
@@ -2065,7 +2152,7 @@ static int __init input_init(void) | |||
2065 | 2152 | ||
2066 | err = register_chrdev(INPUT_MAJOR, "input", &input_fops); | 2153 | err = register_chrdev(INPUT_MAJOR, "input", &input_fops); |
2067 | if (err) { | 2154 | if (err) { |
2068 | printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); | 2155 | pr_err("unable to register char major %d", INPUT_MAJOR); |
2069 | goto fail2; | 2156 | goto fail2; |
2070 | } | 2157 | } |
2071 | 2158 | ||
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 22239e988498..c24ec2d5f926 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -10,6 +10,8 @@ | |||
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
14 | |||
13 | #include <asm/io.h> | 15 | #include <asm/io.h> |
14 | #include <asm/system.h> | 16 | #include <asm/system.h> |
15 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
@@ -178,7 +180,6 @@ static void joydev_attach_client(struct joydev *joydev, | |||
178 | spin_lock(&joydev->client_lock); | 180 | spin_lock(&joydev->client_lock); |
179 | list_add_tail_rcu(&client->node, &joydev->client_list); | 181 | list_add_tail_rcu(&client->node, &joydev->client_list); |
180 | spin_unlock(&joydev->client_lock); | 182 | spin_unlock(&joydev->client_lock); |
181 | synchronize_rcu(); | ||
182 | } | 183 | } |
183 | 184 | ||
184 | static void joydev_detach_client(struct joydev *joydev, | 185 | static void joydev_detach_client(struct joydev *joydev, |
@@ -739,6 +740,7 @@ static const struct file_operations joydev_fops = { | |||
739 | .compat_ioctl = joydev_compat_ioctl, | 740 | .compat_ioctl = joydev_compat_ioctl, |
740 | #endif | 741 | #endif |
741 | .fasync = joydev_fasync, | 742 | .fasync = joydev_fasync, |
743 | .llseek = no_llseek, | ||
742 | }; | 744 | }; |
743 | 745 | ||
744 | static int joydev_install_chrdev(struct joydev *joydev) | 746 | static int joydev_install_chrdev(struct joydev *joydev) |
@@ -755,7 +757,7 @@ static void joydev_remove_chrdev(struct joydev *joydev) | |||
755 | } | 757 | } |
756 | 758 | ||
757 | /* | 759 | /* |
758 | * Mark device non-existant. This disables writes, ioctls and | 760 | * Mark device non-existent. This disables writes, ioctls and |
759 | * prevents new users from opening the device. Already posted | 761 | * prevents new users from opening the device. Already posted |
760 | * blocking reads will stay, however new ones will fail. | 762 | * blocking reads will stay, however new ones will fail. |
761 | */ | 763 | */ |
@@ -774,7 +776,7 @@ static void joydev_cleanup(struct joydev *joydev) | |||
774 | joydev_hangup(joydev); | 776 | joydev_hangup(joydev); |
775 | joydev_remove_chrdev(joydev); | 777 | joydev_remove_chrdev(joydev); |
776 | 778 | ||
777 | /* joydev is marked dead so noone else accesses joydev->open */ | 779 | /* joydev is marked dead so no one else accesses joydev->open */ |
778 | if (joydev->open) | 780 | if (joydev->open) |
779 | input_close_device(handle); | 781 | input_close_device(handle); |
780 | } | 782 | } |
@@ -805,7 +807,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
805 | break; | 807 | break; |
806 | 808 | ||
807 | if (minor == JOYDEV_MINORS) { | 809 | if (minor == JOYDEV_MINORS) { |
808 | printk(KERN_ERR "joydev: no more free joydev devices\n"); | 810 | pr_err("no more free joydev devices\n"); |
809 | return -ENFILE; | 811 | return -ENFILE; |
810 | } | 812 | } |
811 | 813 | ||
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 5b596165b571..56eb471b5576 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig | |||
@@ -255,6 +255,16 @@ config JOYSTICK_AMIGA | |||
255 | To compile this driver as a module, choose M here: the | 255 | To compile this driver as a module, choose M here: the |
256 | module will be called amijoy. | 256 | module will be called amijoy. |
257 | 257 | ||
258 | config JOYSTICK_AS5011 | ||
259 | tristate "Austria Microsystem AS5011 joystick" | ||
260 | depends on I2C | ||
261 | help | ||
262 | Say Y here if you have an AS5011 digital joystick connected to your | ||
263 | system. | ||
264 | |||
265 | To compile this driver as a module, choose M here: the | ||
266 | module will be called as5011. | ||
267 | |||
258 | config JOYSTICK_JOYDUMP | 268 | config JOYSTICK_JOYDUMP |
259 | tristate "Gameport data dumper" | 269 | tristate "Gameport data dumper" |
260 | select GAMEPORT | 270 | select GAMEPORT |
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile index f3a8cbe2abb6..92dc0de9dfed 100644 --- a/drivers/input/joystick/Makefile +++ b/drivers/input/joystick/Makefile | |||
@@ -7,6 +7,7 @@ | |||
7 | obj-$(CONFIG_JOYSTICK_A3D) += a3d.o | 7 | obj-$(CONFIG_JOYSTICK_A3D) += a3d.o |
8 | obj-$(CONFIG_JOYSTICK_ADI) += adi.o | 8 | obj-$(CONFIG_JOYSTICK_ADI) += adi.o |
9 | obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o | 9 | obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o |
10 | obj-$(CONFIG_JOYSTICK_AS5011) += as5011.o | ||
10 | obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o | 11 | obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o |
11 | obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o | 12 | obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o |
12 | obj-$(CONFIG_JOYSTICK_DB9) += db9.o | 13 | obj-$(CONFIG_JOYSTICK_DB9) += db9.o |
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index d259b41354b8..1639ab2b94b7 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c | |||
@@ -3,7 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | /* | 5 | /* |
6 | * FP-Gaming Assasin 3D joystick driver for Linux | 6 | * FP-Gaming Assassin 3D joystick driver for Linux |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* | 9 | /* |
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/input.h> | 34 | #include <linux/input.h> |
35 | #include <linux/jiffies.h> | 35 | #include <linux/jiffies.h> |
36 | 36 | ||
37 | #define DRIVER_DESC "FP-Gaming Assasin 3D joystick driver" | 37 | #define DRIVER_DESC "FP-Gaming Assassin 3D joystick driver" |
38 | 38 | ||
39 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 39 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
40 | MODULE_DESCRIPTION(DRIVER_DESC); | 40 | MODULE_DESCRIPTION(DRIVER_DESC); |
diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c new file mode 100644 index 000000000000..f6732b57ca07 --- /dev/null +++ b/drivers/input/joystick/as5011.c | |||
@@ -0,0 +1,367 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com> | ||
3 | * Sponsored by ARMadeus Systems | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | * Driver for Austria Microsystems joysticks AS5011 | ||
20 | * | ||
21 | * TODO: | ||
22 | * - Power on the chip when open() and power down when close() | ||
23 | * - Manage power mode | ||
24 | */ | ||
25 | |||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/input.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/input/as5011.h> | ||
32 | #include <linux/slab.h> | ||
33 | |||
34 | #define DRIVER_DESC "Driver for Austria Microsystems AS5011 joystick" | ||
35 | #define MODULE_DEVICE_ALIAS "as5011" | ||
36 | |||
37 | MODULE_AUTHOR("Fabien Marteau <fabien.marteau@armadeus.com>"); | ||
38 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
39 | MODULE_LICENSE("GPL"); | ||
40 | |||
41 | /* registers */ | ||
42 | #define AS5011_CTRL1 0x76 | ||
43 | #define AS5011_CTRL2 0x75 | ||
44 | #define AS5011_XP 0x43 | ||
45 | #define AS5011_XN 0x44 | ||
46 | #define AS5011_YP 0x53 | ||
47 | #define AS5011_YN 0x54 | ||
48 | #define AS5011_X_REG 0x41 | ||
49 | #define AS5011_Y_REG 0x42 | ||
50 | #define AS5011_X_RES_INT 0x51 | ||
51 | #define AS5011_Y_RES_INT 0x52 | ||
52 | |||
53 | /* CTRL1 bits */ | ||
54 | #define AS5011_CTRL1_LP_PULSED 0x80 | ||
55 | #define AS5011_CTRL1_LP_ACTIVE 0x40 | ||
56 | #define AS5011_CTRL1_LP_CONTINUE 0x20 | ||
57 | #define AS5011_CTRL1_INT_WUP_EN 0x10 | ||
58 | #define AS5011_CTRL1_INT_ACT_EN 0x08 | ||
59 | #define AS5011_CTRL1_EXT_CLK_EN 0x04 | ||
60 | #define AS5011_CTRL1_SOFT_RST 0x02 | ||
61 | #define AS5011_CTRL1_DATA_VALID 0x01 | ||
62 | |||
63 | /* CTRL2 bits */ | ||
64 | #define AS5011_CTRL2_EXT_SAMPLE_EN 0x08 | ||
65 | #define AS5011_CTRL2_RC_BIAS_ON 0x04 | ||
66 | #define AS5011_CTRL2_INV_SPINNING 0x02 | ||
67 | |||
68 | #define AS5011_MAX_AXIS 80 | ||
69 | #define AS5011_MIN_AXIS (-80) | ||
70 | #define AS5011_FUZZ 8 | ||
71 | #define AS5011_FLAT 40 | ||
72 | |||
73 | struct as5011_device { | ||
74 | struct input_dev *input_dev; | ||
75 | struct i2c_client *i2c_client; | ||
76 | unsigned int button_gpio; | ||
77 | unsigned int button_irq; | ||
78 | unsigned int axis_irq; | ||
79 | }; | ||
80 | |||
81 | static int as5011_i2c_write(struct i2c_client *client, | ||
82 | uint8_t aregaddr, | ||
83 | uint8_t avalue) | ||
84 | { | ||
85 | uint8_t data[2] = { aregaddr, avalue }; | ||
86 | struct i2c_msg msg = { | ||
87 | client->addr, I2C_M_IGNORE_NAK, 2, (uint8_t *)data | ||
88 | }; | ||
89 | int error; | ||
90 | |||
91 | error = i2c_transfer(client->adapter, &msg, 1); | ||
92 | return error < 0 ? error : 0; | ||
93 | } | ||
94 | |||
95 | static int as5011_i2c_read(struct i2c_client *client, | ||
96 | uint8_t aregaddr, signed char *value) | ||
97 | { | ||
98 | uint8_t data[2] = { aregaddr }; | ||
99 | struct i2c_msg msg_set[2] = { | ||
100 | { client->addr, I2C_M_REV_DIR_ADDR, 1, (uint8_t *)data }, | ||
101 | { client->addr, I2C_M_RD | I2C_M_NOSTART, 1, (uint8_t *)data } | ||
102 | }; | ||
103 | int error; | ||
104 | |||
105 | error = i2c_transfer(client->adapter, msg_set, 2); | ||
106 | if (error < 0) | ||
107 | return error; | ||
108 | |||
109 | *value = data[0] & 0x80 ? -1 * (1 + ~data[0]) : data[0]; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static irqreturn_t as5011_button_interrupt(int irq, void *dev_id) | ||
114 | { | ||
115 | struct as5011_device *as5011 = dev_id; | ||
116 | int val = gpio_get_value_cansleep(as5011->button_gpio); | ||
117 | |||
118 | input_report_key(as5011->input_dev, BTN_JOYSTICK, !val); | ||
119 | input_sync(as5011->input_dev); | ||
120 | |||
121 | return IRQ_HANDLED; | ||
122 | } | ||
123 | |||
124 | static irqreturn_t as5011_axis_interrupt(int irq, void *dev_id) | ||
125 | { | ||
126 | struct as5011_device *as5011 = dev_id; | ||
127 | int error; | ||
128 | signed char x, y; | ||
129 | |||
130 | error = as5011_i2c_read(as5011->i2c_client, AS5011_X_RES_INT, &x); | ||
131 | if (error < 0) | ||
132 | goto out; | ||
133 | |||
134 | error = as5011_i2c_read(as5011->i2c_client, AS5011_Y_RES_INT, &y); | ||
135 | if (error < 0) | ||
136 | goto out; | ||
137 | |||
138 | input_report_abs(as5011->input_dev, ABS_X, x); | ||
139 | input_report_abs(as5011->input_dev, ABS_Y, y); | ||
140 | input_sync(as5011->input_dev); | ||
141 | |||
142 | out: | ||
143 | return IRQ_HANDLED; | ||
144 | } | ||
145 | |||
146 | static int __devinit as5011_configure_chip(struct as5011_device *as5011, | ||
147 | const struct as5011_platform_data *plat_dat) | ||
148 | { | ||
149 | struct i2c_client *client = as5011->i2c_client; | ||
150 | int error; | ||
151 | signed char value; | ||
152 | |||
153 | /* chip soft reset */ | ||
154 | error = as5011_i2c_write(client, AS5011_CTRL1, | ||
155 | AS5011_CTRL1_SOFT_RST); | ||
156 | if (error < 0) { | ||
157 | dev_err(&client->dev, "Soft reset failed\n"); | ||
158 | return error; | ||
159 | } | ||
160 | |||
161 | mdelay(10); | ||
162 | |||
163 | error = as5011_i2c_write(client, AS5011_CTRL1, | ||
164 | AS5011_CTRL1_LP_PULSED | | ||
165 | AS5011_CTRL1_LP_ACTIVE | | ||
166 | AS5011_CTRL1_INT_ACT_EN); | ||
167 | if (error < 0) { | ||
168 | dev_err(&client->dev, "Power config failed\n"); | ||
169 | return error; | ||
170 | } | ||
171 | |||
172 | error = as5011_i2c_write(client, AS5011_CTRL2, | ||
173 | AS5011_CTRL2_INV_SPINNING); | ||
174 | if (error < 0) { | ||
175 | dev_err(&client->dev, "Can't invert spinning\n"); | ||
176 | return error; | ||
177 | } | ||
178 | |||
179 | /* write threshold */ | ||
180 | error = as5011_i2c_write(client, AS5011_XP, plat_dat->xp); | ||
181 | if (error < 0) { | ||
182 | dev_err(&client->dev, "Can't write threshold\n"); | ||
183 | return error; | ||
184 | } | ||
185 | |||
186 | error = as5011_i2c_write(client, AS5011_XN, plat_dat->xn); | ||
187 | if (error < 0) { | ||
188 | dev_err(&client->dev, "Can't write threshold\n"); | ||
189 | return error; | ||
190 | } | ||
191 | |||
192 | error = as5011_i2c_write(client, AS5011_YP, plat_dat->yp); | ||
193 | if (error < 0) { | ||
194 | dev_err(&client->dev, "Can't write threshold\n"); | ||
195 | return error; | ||
196 | } | ||
197 | |||
198 | error = as5011_i2c_write(client, AS5011_YN, plat_dat->yn); | ||
199 | if (error < 0) { | ||
200 | dev_err(&client->dev, "Can't write threshold\n"); | ||
201 | return error; | ||
202 | } | ||
203 | |||
204 | /* to free irq gpio in chip */ | ||
205 | error = as5011_i2c_read(client, AS5011_X_RES_INT, &value); | ||
206 | if (error < 0) { | ||
207 | dev_err(&client->dev, "Can't read i2c X resolution value\n"); | ||
208 | return error; | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int __devinit as5011_probe(struct i2c_client *client, | ||
215 | const struct i2c_device_id *id) | ||
216 | { | ||
217 | const struct as5011_platform_data *plat_data; | ||
218 | struct as5011_device *as5011; | ||
219 | struct input_dev *input_dev; | ||
220 | int irq; | ||
221 | int error; | ||
222 | |||
223 | plat_data = client->dev.platform_data; | ||
224 | if (!plat_data) | ||
225 | return -EINVAL; | ||
226 | |||
227 | if (!plat_data->axis_irq) { | ||
228 | dev_err(&client->dev, "No axis IRQ?\n"); | ||
229 | return -EINVAL; | ||
230 | } | ||
231 | |||
232 | if (!i2c_check_functionality(client->adapter, | ||
233 | I2C_FUNC_PROTOCOL_MANGLING)) { | ||
234 | dev_err(&client->dev, | ||
235 | "need i2c bus that supports protocol mangling\n"); | ||
236 | return -ENODEV; | ||
237 | } | ||
238 | |||
239 | as5011 = kmalloc(sizeof(struct as5011_device), GFP_KERNEL); | ||
240 | input_dev = input_allocate_device(); | ||
241 | if (!as5011 || !input_dev) { | ||
242 | dev_err(&client->dev, | ||
243 | "Can't allocate memory for device structure\n"); | ||
244 | error = -ENOMEM; | ||
245 | goto err_free_mem; | ||
246 | } | ||
247 | |||
248 | as5011->i2c_client = client; | ||
249 | as5011->input_dev = input_dev; | ||
250 | as5011->button_gpio = plat_data->button_gpio; | ||
251 | as5011->axis_irq = plat_data->axis_irq; | ||
252 | |||
253 | input_dev->name = "Austria Microsystem as5011 joystick"; | ||
254 | input_dev->id.bustype = BUS_I2C; | ||
255 | input_dev->dev.parent = &client->dev; | ||
256 | |||
257 | __set_bit(EV_KEY, input_dev->evbit); | ||
258 | __set_bit(EV_ABS, input_dev->evbit); | ||
259 | __set_bit(BTN_JOYSTICK, input_dev->keybit); | ||
260 | |||
261 | input_set_abs_params(input_dev, ABS_X, | ||
262 | AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT); | ||
263 | input_set_abs_params(as5011->input_dev, ABS_Y, | ||
264 | AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT); | ||
265 | |||
266 | error = gpio_request(as5011->button_gpio, "AS5011 button"); | ||
267 | if (error < 0) { | ||
268 | dev_err(&client->dev, "Failed to request button gpio\n"); | ||
269 | goto err_free_mem; | ||
270 | } | ||
271 | |||
272 | irq = gpio_to_irq(as5011->button_gpio); | ||
273 | if (irq < 0) { | ||
274 | dev_err(&client->dev, | ||
275 | "Failed to get irq number for button gpio\n"); | ||
276 | goto err_free_button_gpio; | ||
277 | } | ||
278 | |||
279 | as5011->button_irq = irq; | ||
280 | |||
281 | error = request_threaded_irq(as5011->button_irq, | ||
282 | NULL, as5011_button_interrupt, | ||
283 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
284 | "as5011_button", as5011); | ||
285 | if (error < 0) { | ||
286 | dev_err(&client->dev, | ||
287 | "Can't allocate button irq %d\n", as5011->button_irq); | ||
288 | goto err_free_button_gpio; | ||
289 | } | ||
290 | |||
291 | error = as5011_configure_chip(as5011, plat_data); | ||
292 | if (error) | ||
293 | goto err_free_button_irq; | ||
294 | |||
295 | error = request_threaded_irq(as5011->axis_irq, NULL, | ||
296 | as5011_axis_interrupt, | ||
297 | plat_data->axis_irqflags, | ||
298 | "as5011_joystick", as5011); | ||
299 | if (error) { | ||
300 | dev_err(&client->dev, | ||
301 | "Can't allocate axis irq %d\n", plat_data->axis_irq); | ||
302 | goto err_free_button_irq; | ||
303 | } | ||
304 | |||
305 | error = input_register_device(as5011->input_dev); | ||
306 | if (error) { | ||
307 | dev_err(&client->dev, "Failed to register input device\n"); | ||
308 | goto err_free_axis_irq; | ||
309 | } | ||
310 | |||
311 | i2c_set_clientdata(client, as5011); | ||
312 | |||
313 | return 0; | ||
314 | |||
315 | err_free_axis_irq: | ||
316 | free_irq(as5011->axis_irq, as5011); | ||
317 | err_free_button_irq: | ||
318 | free_irq(as5011->button_irq, as5011); | ||
319 | err_free_button_gpio: | ||
320 | gpio_free(as5011->button_gpio); | ||
321 | err_free_mem: | ||
322 | input_free_device(input_dev); | ||
323 | kfree(as5011); | ||
324 | |||
325 | return error; | ||
326 | } | ||
327 | |||
328 | static int __devexit as5011_remove(struct i2c_client *client) | ||
329 | { | ||
330 | struct as5011_device *as5011 = i2c_get_clientdata(client); | ||
331 | |||
332 | free_irq(as5011->axis_irq, as5011); | ||
333 | free_irq(as5011->button_irq, as5011); | ||
334 | gpio_free(as5011->button_gpio); | ||
335 | |||
336 | input_unregister_device(as5011->input_dev); | ||
337 | kfree(as5011); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static const struct i2c_device_id as5011_id[] = { | ||
343 | { MODULE_DEVICE_ALIAS, 0 }, | ||
344 | { } | ||
345 | }; | ||
346 | MODULE_DEVICE_TABLE(i2c, as5011_id); | ||
347 | |||
348 | static struct i2c_driver as5011_driver = { | ||
349 | .driver = { | ||
350 | .name = "as5011", | ||
351 | }, | ||
352 | .probe = as5011_probe, | ||
353 | .remove = __devexit_p(as5011_remove), | ||
354 | .id_table = as5011_id, | ||
355 | }; | ||
356 | |||
357 | static int __init as5011_init(void) | ||
358 | { | ||
359 | return i2c_add_driver(&as5011_driver); | ||
360 | } | ||
361 | module_init(as5011_init); | ||
362 | |||
363 | static void __exit as5011_exit(void) | ||
364 | { | ||
365 | i2c_del_driver(&as5011_driver); | ||
366 | } | ||
367 | module_exit(as5011_exit); | ||
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 0ffaf2c77a19..e68e49786483 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c | |||
@@ -521,9 +521,8 @@ static void gc_multi_process_packet(struct gc *gc) | |||
521 | * PSX support | 521 | * PSX support |
522 | * | 522 | * |
523 | * See documentation at: | 523 | * See documentation at: |
524 | * http://www.dim.com/~mackys/psxmemcard/ps-eng2.txt | 524 | * http://www.geocities.co.jp/Playtown/2004/psx/ps_eng.txt |
525 | * http://www.gamesx.com/controldata/psxcont/psxcont.htm | 525 | * http://www.gamesx.com/controldata/psxcont/psxcont.htm |
526 | * ftp://milano.usal.es/pablo/ | ||
527 | * | 526 | * |
528 | */ | 527 | */ |
529 | 528 | ||
diff --git a/drivers/input/joystick/iforce/Makefile b/drivers/input/joystick/iforce/Makefile index 74daff49ab6e..bc5bda22f15e 100644 --- a/drivers/input/joystick/iforce/Makefile +++ b/drivers/input/joystick/iforce/Makefile | |||
@@ -4,17 +4,8 @@ | |||
4 | # By Johann Deneux <johann.deneux@gmail.com> | 4 | # By Johann Deneux <johann.deneux@gmail.com> |
5 | # | 5 | # |
6 | 6 | ||
7 | # Goal definition | ||
8 | iforce-objs := iforce-ff.o iforce-main.o iforce-packets.o | ||
9 | |||
10 | obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o | 7 | obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o |
11 | 8 | ||
12 | ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y) | 9 | iforce-y := iforce-ff.o iforce-main.o iforce-packets.o |
13 | iforce-objs += iforce-serio.o | 10 | iforce-$(CONFIG_JOYSTICK_IFORCE_232) += iforce-serio.o |
14 | endif | 11 | iforce-$(CONFIG_JOYSTICK_IFORCE_USB) += iforce-usb.o |
15 | |||
16 | ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y) | ||
17 | iforce-objs += iforce-usb.o | ||
18 | endif | ||
19 | |||
20 | EXTRA_CFLAGS = -Werror-implicit-function-declaration | ||
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index d53b9e900234..27b6a3ce18ca 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c | |||
@@ -245,6 +245,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) | |||
245 | goto err_free_tgfx; | 245 | goto err_free_tgfx; |
246 | } | 246 | } |
247 | 247 | ||
248 | parport_put_port(pp); | ||
248 | return tgfx; | 249 | return tgfx; |
249 | 250 | ||
250 | err_free_dev: | 251 | err_free_dev: |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f9fb7fa10af3..56abf3d0e911 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -543,21 +543,25 @@ exit: | |||
543 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | 543 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) |
544 | { | 544 | { |
545 | struct usb_endpoint_descriptor *ep_irq_out; | 545 | struct usb_endpoint_descriptor *ep_irq_out; |
546 | int error = -ENOMEM; | 546 | int error; |
547 | 547 | ||
548 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) | 548 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
549 | return 0; | 549 | return 0; |
550 | 550 | ||
551 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, | 551 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, |
552 | GFP_KERNEL, &xpad->odata_dma); | 552 | GFP_KERNEL, &xpad->odata_dma); |
553 | if (!xpad->odata) | 553 | if (!xpad->odata) { |
554 | error = -ENOMEM; | ||
554 | goto fail1; | 555 | goto fail1; |
556 | } | ||
555 | 557 | ||
556 | mutex_init(&xpad->odata_mutex); | 558 | mutex_init(&xpad->odata_mutex); |
557 | 559 | ||
558 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); | 560 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); |
559 | if (!xpad->irq_out) | 561 | if (!xpad->irq_out) { |
562 | error = -ENOMEM; | ||
560 | goto fail2; | 563 | goto fail2; |
564 | } | ||
561 | 565 | ||
562 | ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; | 566 | ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; |
563 | usb_fill_int_urb(xpad->irq_out, xpad->udev, | 567 | usb_fill_int_urb(xpad->irq_out, xpad->udev, |
@@ -728,7 +732,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) | |||
728 | 732 | ||
729 | if (xpad_led) { | 733 | if (xpad_led) { |
730 | led_classdev_unregister(&xpad_led->led_cdev); | 734 | led_classdev_unregister(&xpad_led->led_cdev); |
731 | kfree(xpad_led->name); | 735 | kfree(xpad_led); |
732 | } | 736 | } |
733 | } | 737 | } |
734 | #else | 738 | #else |
@@ -756,8 +760,9 @@ static void xpad_close(struct input_dev *dev) | |||
756 | { | 760 | { |
757 | struct usb_xpad *xpad = input_get_drvdata(dev); | 761 | struct usb_xpad *xpad = input_get_drvdata(dev); |
758 | 762 | ||
759 | if(xpad->xtype != XTYPE_XBOX360W) | 763 | if (xpad->xtype != XTYPE_XBOX360W) |
760 | usb_kill_urb(xpad->irq_in); | 764 | usb_kill_urb(xpad->irq_in); |
765 | |||
761 | xpad_stop_output(xpad); | 766 | xpad_stop_output(xpad); |
762 | } | 767 | } |
763 | 768 | ||
@@ -789,8 +794,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
789 | struct usb_xpad *xpad; | 794 | struct usb_xpad *xpad; |
790 | struct input_dev *input_dev; | 795 | struct input_dev *input_dev; |
791 | struct usb_endpoint_descriptor *ep_irq_in; | 796 | struct usb_endpoint_descriptor *ep_irq_in; |
792 | int i; | 797 | int i, error; |
793 | int error = -ENOMEM; | ||
794 | 798 | ||
795 | for (i = 0; xpad_device[i].idVendor; i++) { | 799 | for (i = 0; xpad_device[i].idVendor; i++) { |
796 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && | 800 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && |
@@ -800,17 +804,23 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
800 | 804 | ||
801 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); | 805 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); |
802 | input_dev = input_allocate_device(); | 806 | input_dev = input_allocate_device(); |
803 | if (!xpad || !input_dev) | 807 | if (!xpad || !input_dev) { |
808 | error = -ENOMEM; | ||
804 | goto fail1; | 809 | goto fail1; |
810 | } | ||
805 | 811 | ||
806 | xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, | 812 | xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, |
807 | GFP_KERNEL, &xpad->idata_dma); | 813 | GFP_KERNEL, &xpad->idata_dma); |
808 | if (!xpad->idata) | 814 | if (!xpad->idata) { |
815 | error = -ENOMEM; | ||
809 | goto fail1; | 816 | goto fail1; |
817 | } | ||
810 | 818 | ||
811 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); | 819 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); |
812 | if (!xpad->irq_in) | 820 | if (!xpad->irq_in) { |
821 | error = -ENOMEM; | ||
813 | goto fail2; | 822 | goto fail2; |
823 | } | ||
814 | 824 | ||
815 | xpad->udev = udev; | 825 | xpad->udev = udev; |
816 | xpad->mapping = xpad_device[i].mapping; | 826 | xpad->mapping = xpad_device[i].mapping; |
@@ -887,15 +897,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
887 | 897 | ||
888 | error = xpad_init_output(intf, xpad); | 898 | error = xpad_init_output(intf, xpad); |
889 | if (error) | 899 | if (error) |
890 | goto fail2; | 900 | goto fail3; |
891 | 901 | ||
892 | error = xpad_init_ff(xpad); | 902 | error = xpad_init_ff(xpad); |
893 | if (error) | 903 | if (error) |
894 | goto fail3; | 904 | goto fail4; |
895 | 905 | ||
896 | error = xpad_led_probe(xpad); | 906 | error = xpad_led_probe(xpad); |
897 | if (error) | 907 | if (error) |
898 | goto fail3; | 908 | goto fail5; |
899 | 909 | ||
900 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 910 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; |
901 | usb_fill_int_urb(xpad->irq_in, udev, | 911 | usb_fill_int_urb(xpad->irq_in, udev, |
@@ -907,34 +917,26 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
907 | 917 | ||
908 | error = input_register_device(xpad->dev); | 918 | error = input_register_device(xpad->dev); |
909 | if (error) | 919 | if (error) |
910 | goto fail4; | 920 | goto fail6; |
911 | 921 | ||
912 | usb_set_intfdata(intf, xpad); | 922 | usb_set_intfdata(intf, xpad); |
913 | 923 | ||
914 | /* | ||
915 | * Submit the int URB immediatly rather than waiting for open | ||
916 | * because we get status messages from the device whether | ||
917 | * or not any controllers are attached. In fact, it's | ||
918 | * exactly the message that a controller has arrived that | ||
919 | * we're waiting for. | ||
920 | */ | ||
921 | if (xpad->xtype == XTYPE_XBOX360W) { | 924 | if (xpad->xtype == XTYPE_XBOX360W) { |
922 | xpad->irq_in->dev = xpad->udev; | ||
923 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); | ||
924 | if (error) | ||
925 | goto fail4; | ||
926 | |||
927 | /* | 925 | /* |
928 | * Setup the message to set the LEDs on the | 926 | * Setup the message to set the LEDs on the |
929 | * controller when it shows up | 927 | * controller when it shows up |
930 | */ | 928 | */ |
931 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); | 929 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); |
932 | if(!xpad->bulk_out) | 930 | if (!xpad->bulk_out) { |
933 | goto fail5; | 931 | error = -ENOMEM; |
932 | goto fail7; | ||
933 | } | ||
934 | 934 | ||
935 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); | 935 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); |
936 | if(!xpad->bdata) | 936 | if (!xpad->bdata) { |
937 | goto fail6; | 937 | error = -ENOMEM; |
938 | goto fail8; | ||
939 | } | ||
938 | 940 | ||
939 | xpad->bdata[2] = 0x08; | 941 | xpad->bdata[2] = 0x08; |
940 | switch (intf->cur_altsetting->desc.bInterfaceNumber) { | 942 | switch (intf->cur_altsetting->desc.bInterfaceNumber) { |
@@ -955,14 +957,31 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
955 | usb_fill_bulk_urb(xpad->bulk_out, udev, | 957 | usb_fill_bulk_urb(xpad->bulk_out, udev, |
956 | usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), | 958 | usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), |
957 | xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); | 959 | xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); |
960 | |||
961 | /* | ||
962 | * Submit the int URB immediately rather than waiting for open | ||
963 | * because we get status messages from the device whether | ||
964 | * or not any controllers are attached. In fact, it's | ||
965 | * exactly the message that a controller has arrived that | ||
966 | * we're waiting for. | ||
967 | */ | ||
968 | xpad->irq_in->dev = xpad->udev; | ||
969 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); | ||
970 | if (error) | ||
971 | goto fail9; | ||
958 | } | 972 | } |
959 | 973 | ||
960 | return 0; | 974 | return 0; |
961 | 975 | ||
962 | fail6: usb_free_urb(xpad->bulk_out); | 976 | fail9: kfree(xpad->bdata); |
963 | fail5: usb_kill_urb(xpad->irq_in); | 977 | fail8: usb_free_urb(xpad->bulk_out); |
964 | fail4: usb_free_urb(xpad->irq_in); | 978 | fail7: input_unregister_device(input_dev); |
965 | fail3: xpad_deinit_output(xpad); | 979 | input_dev = NULL; |
980 | fail6: xpad_led_disconnect(xpad); | ||
981 | fail5: if (input_dev) | ||
982 | input_ff_destroy(input_dev); | ||
983 | fail4: xpad_deinit_output(xpad); | ||
984 | fail3: usb_free_urb(xpad->irq_in); | ||
966 | fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | 985 | fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); |
967 | fail1: input_free_device(input_dev); | 986 | fail1: input_free_device(input_dev); |
968 | kfree(xpad); | 987 | kfree(xpad); |
@@ -974,21 +993,24 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
974 | { | 993 | { |
975 | struct usb_xpad *xpad = usb_get_intfdata (intf); | 994 | struct usb_xpad *xpad = usb_get_intfdata (intf); |
976 | 995 | ||
977 | usb_set_intfdata(intf, NULL); | 996 | xpad_led_disconnect(xpad); |
978 | if (xpad) { | 997 | input_unregister_device(xpad->dev); |
979 | xpad_led_disconnect(xpad); | 998 | xpad_deinit_output(xpad); |
980 | input_unregister_device(xpad->dev); | 999 | |
981 | xpad_deinit_output(xpad); | 1000 | if (xpad->xtype == XTYPE_XBOX360W) { |
982 | if (xpad->xtype == XTYPE_XBOX360W) { | 1001 | usb_kill_urb(xpad->bulk_out); |
983 | usb_kill_urb(xpad->bulk_out); | 1002 | usb_free_urb(xpad->bulk_out); |
984 | usb_free_urb(xpad->bulk_out); | 1003 | usb_kill_urb(xpad->irq_in); |
985 | usb_kill_urb(xpad->irq_in); | ||
986 | } | ||
987 | usb_free_urb(xpad->irq_in); | ||
988 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, | ||
989 | xpad->idata, xpad->idata_dma); | ||
990 | kfree(xpad); | ||
991 | } | 1004 | } |
1005 | |||
1006 | usb_free_urb(xpad->irq_in); | ||
1007 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, | ||
1008 | xpad->idata, xpad->idata_dma); | ||
1009 | |||
1010 | kfree(xpad->bdata); | ||
1011 | kfree(xpad); | ||
1012 | |||
1013 | usb_set_intfdata(intf, NULL); | ||
992 | } | 1014 | } |
993 | 1015 | ||
994 | static struct usb_driver xpad_driver = { | 1016 | static struct usb_driver xpad_driver = { |
@@ -1000,10 +1022,7 @@ static struct usb_driver xpad_driver = { | |||
1000 | 1022 | ||
1001 | static int __init usb_xpad_init(void) | 1023 | static int __init usb_xpad_init(void) |
1002 | { | 1024 | { |
1003 | int result = usb_register(&xpad_driver); | 1025 | return usb_register(&xpad_driver); |
1004 | if (result == 0) | ||
1005 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); | ||
1006 | return result; | ||
1007 | } | 1026 | } |
1008 | 1027 | ||
1009 | static void __exit usb_xpad_exit(void) | 1028 | static void __exit usb_xpad_exit(void) |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 9cc488d21490..b4dee9d5a055 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -2,7 +2,7 @@ | |||
2 | # Input core configuration | 2 | # Input core configuration |
3 | # | 3 | # |
4 | menuconfig INPUT_KEYBOARD | 4 | menuconfig INPUT_KEYBOARD |
5 | bool "Keyboards" if EMBEDDED || !X86 | 5 | bool "Keyboards" if EXPERT || !X86 |
6 | default y | 6 | default y |
7 | help | 7 | help |
8 | Say Y here, and a list of supported keyboards will be displayed. | 8 | Say Y here, and a list of supported keyboards will be displayed. |
@@ -12,18 +12,6 @@ menuconfig INPUT_KEYBOARD | |||
12 | 12 | ||
13 | if INPUT_KEYBOARD | 13 | if INPUT_KEYBOARD |
14 | 14 | ||
15 | config KEYBOARD_AAED2000 | ||
16 | tristate "AAED-2000 keyboard" | ||
17 | depends on MACH_AAED2000 | ||
18 | select INPUT_POLLDEV | ||
19 | default y | ||
20 | help | ||
21 | Say Y here to enable the keyboard on the Agilent AAED-2000 | ||
22 | development board. | ||
23 | |||
24 | To compile this driver as a module, choose M here: the | ||
25 | module will be called aaed2000_kbd. | ||
26 | |||
27 | config KEYBOARD_ADP5520 | 15 | config KEYBOARD_ADP5520 |
28 | tristate "Keypad Support for ADP5520 PMIC" | 16 | tristate "Keypad Support for ADP5520 PMIC" |
29 | depends on PMIC_ADP5520 | 17 | depends on PMIC_ADP5520 |
@@ -44,6 +32,16 @@ config KEYBOARD_ADP5588 | |||
44 | To compile this driver as a module, choose M here: the | 32 | To compile this driver as a module, choose M here: the |
45 | module will be called adp5588-keys. | 33 | module will be called adp5588-keys. |
46 | 34 | ||
35 | config KEYBOARD_ADP5589 | ||
36 | tristate "ADP5589 I2C QWERTY Keypad and IO Expander" | ||
37 | depends on I2C | ||
38 | help | ||
39 | Say Y here if you want to use a ADP5589 attached to your | ||
40 | system I2C bus. | ||
41 | |||
42 | To compile this driver as a module, choose M here: the | ||
43 | module will be called adp5589-keys. | ||
44 | |||
47 | config KEYBOARD_AMIGA | 45 | config KEYBOARD_AMIGA |
48 | tristate "Amiga keyboard" | 46 | tristate "Amiga keyboard" |
49 | depends on AMIGA | 47 | depends on AMIGA |
@@ -69,7 +67,7 @@ config KEYBOARD_ATARI | |||
69 | module will be called atakbd. | 67 | module will be called atakbd. |
70 | 68 | ||
71 | config KEYBOARD_ATKBD | 69 | config KEYBOARD_ATKBD |
72 | tristate "AT keyboard" if EMBEDDED || !X86 | 70 | tristate "AT keyboard" if EXPERT || !X86 |
73 | default y | 71 | default y |
74 | select SERIO | 72 | select SERIO |
75 | select SERIO_LIBPS2 | 73 | select SERIO_LIBPS2 |
@@ -124,6 +122,16 @@ config KEYBOARD_ATKBD_RDI_KEYCODES | |||
124 | right-hand column will be interpreted as the key shown in the | 122 | right-hand column will be interpreted as the key shown in the |
125 | left-hand column. | 123 | left-hand column. |
126 | 124 | ||
125 | config KEYBOARD_QT1070 | ||
126 | tristate "Atmel AT42QT1070 Touch Sensor Chip" | ||
127 | depends on I2C | ||
128 | help | ||
129 | Say Y here if you want to use Atmel AT42QT1070 QTouch | ||
130 | Sensor chip as input device. | ||
131 | |||
132 | To compile this driver as a module, choose M here: | ||
133 | the module will be called qt1070 | ||
134 | |||
127 | config KEYBOARD_QT2160 | 135 | config KEYBOARD_QT2160 |
128 | tristate "Atmel AT42QT2160 Touch Sensor Chip" | 136 | tristate "Atmel AT42QT2160 Touch Sensor Chip" |
129 | depends on I2C && EXPERIMENTAL | 137 | depends on I2C && EXPERIMENTAL |
@@ -179,21 +187,39 @@ config KEYBOARD_GPIO | |||
179 | To compile this driver as a module, choose M here: the | 187 | To compile this driver as a module, choose M here: the |
180 | module will be called gpio_keys. | 188 | module will be called gpio_keys. |
181 | 189 | ||
190 | config KEYBOARD_GPIO_POLLED | ||
191 | tristate "Polled GPIO buttons" | ||
192 | depends on GENERIC_GPIO | ||
193 | select INPUT_POLLDEV | ||
194 | help | ||
195 | This driver implements support for buttons connected | ||
196 | to GPIO pins that are not capable of generating interrupts. | ||
197 | |||
198 | Say Y here if your device has buttons connected | ||
199 | directly to such GPIO pins. Your board-specific | ||
200 | setup logic must also provide a platform device, | ||
201 | with configuration data saying which GPIOs are used. | ||
202 | |||
203 | To compile this driver as a module, choose M here: the | ||
204 | module will be called gpio_keys_polled. | ||
205 | |||
182 | config KEYBOARD_TCA6416 | 206 | config KEYBOARD_TCA6416 |
183 | tristate "TCA6416 Keypad Support" | 207 | tristate "TCA6416/TCA6408A Keypad Support" |
184 | depends on I2C | 208 | depends on I2C |
185 | help | 209 | help |
186 | This driver implements basic keypad functionality | 210 | This driver implements basic keypad functionality |
187 | for keys connected through TCA6416 IO expander | 211 | for keys connected through TCA6416/TCA6408A IO expanders. |
188 | 212 | ||
189 | Say Y here if your device has keys connected to | 213 | Say Y here if your device has keys connected to |
190 | TCA6416 IO expander. Your board-specific setup logic | 214 | TCA6416/TCA6408A IO expander. Your board-specific setup logic |
191 | must also provide pin-mask details(of which TCA6416 pins | 215 | must also provide pin-mask details(of which TCA6416 pins |
192 | are used for keypad). | 216 | are used for keypad). |
193 | 217 | ||
194 | If enabled the complete TCA6416 device will be managed through | 218 | If enabled the entire TCA6416 device will be managed through |
195 | this driver. | 219 | this driver. |
196 | 220 | ||
221 | To compile this driver as a module, choose M here: the | ||
222 | module will be called tca6416_keypad. | ||
197 | 223 | ||
198 | config KEYBOARD_MATRIX | 224 | config KEYBOARD_MATRIX |
199 | tristate "GPIO driven matrix keypad support" | 225 | tristate "GPIO driven matrix keypad support" |
@@ -309,6 +335,18 @@ config KEYBOARD_MCS | |||
309 | To compile this driver as a module, choose M here: the | 335 | To compile this driver as a module, choose M here: the |
310 | module will be called mcs_touchkey. | 336 | module will be called mcs_touchkey. |
311 | 337 | ||
338 | config KEYBOARD_MPR121 | ||
339 | tristate "Freescale MPR121 Touchkey" | ||
340 | depends on I2C | ||
341 | help | ||
342 | Say Y here if you have Freescale MPR121 touchkey controller | ||
343 | chip in your system. | ||
344 | |||
345 | If unsure, say N. | ||
346 | |||
347 | To compile this driver as a module, choose M here: the | ||
348 | module will be called mpr121_touchkey. | ||
349 | |||
312 | config KEYBOARD_IMX | 350 | config KEYBOARD_IMX |
313 | tristate "IMX keypad support" | 351 | tristate "IMX keypad support" |
314 | depends on ARCH_MXC | 352 | depends on ARCH_MXC |
@@ -327,6 +365,26 @@ config KEYBOARD_NEWTON | |||
327 | To compile this driver as a module, choose M here: the | 365 | To compile this driver as a module, choose M here: the |
328 | module will be called newtonkbd. | 366 | module will be called newtonkbd. |
329 | 367 | ||
368 | config KEYBOARD_NOMADIK | ||
369 | tristate "ST-Ericsson Nomadik SKE keyboard" | ||
370 | depends on PLAT_NOMADIK | ||
371 | help | ||
372 | Say Y here if you want to use a keypad provided on the SKE controller | ||
373 | used on the Ux500 and Nomadik platforms | ||
374 | |||
375 | To compile this driver as a module, choose M here: the | ||
376 | module will be called nmk-ske-keypad. | ||
377 | |||
378 | config KEYBOARD_TEGRA | ||
379 | tristate "NVIDIA Tegra internal matrix keyboard controller support" | ||
380 | depends on ARCH_TEGRA | ||
381 | help | ||
382 | Say Y here if you want to use a matrix keyboard connected directly | ||
383 | to the internal keyboard controller on Tegra SoCs. | ||
384 | |||
385 | To compile this driver as a module, choose M here: the | ||
386 | module will be called tegra-kbc. | ||
387 | |||
330 | config KEYBOARD_OPENCORES | 388 | config KEYBOARD_OPENCORES |
331 | tristate "OpenCores Keyboard Controller" | 389 | tristate "OpenCores Keyboard Controller" |
332 | help | 390 | help |
@@ -338,7 +396,7 @@ config KEYBOARD_OPENCORES | |||
338 | 396 | ||
339 | config KEYBOARD_PXA27x | 397 | config KEYBOARD_PXA27x |
340 | tristate "PXA27x/PXA3xx keypad support" | 398 | tristate "PXA27x/PXA3xx keypad support" |
341 | depends on PXA27x || PXA3xx | 399 | depends on PXA27x || PXA3xx || ARCH_MMP |
342 | help | 400 | help |
343 | Enable support for PXA27x/PXA3xx keypad controller. | 401 | Enable support for PXA27x/PXA3xx keypad controller. |
344 | 402 | ||
@@ -354,6 +412,17 @@ config KEYBOARD_PXA930_ROTARY | |||
354 | To compile this driver as a module, choose M here: the | 412 | To compile this driver as a module, choose M here: the |
355 | module will be called pxa930_rotary. | 413 | module will be called pxa930_rotary. |
356 | 414 | ||
415 | config KEYBOARD_PMIC8XXX | ||
416 | tristate "Qualcomm PMIC8XXX keypad support" | ||
417 | depends on MFD_PM8XXX | ||
418 | help | ||
419 | Say Y here if you want to enable the driver for the PMIC8XXX | ||
420 | keypad provided as a reference design from Qualcomm. This is intended | ||
421 | to support upto 18x8 matrix based keypad design. | ||
422 | |||
423 | To compile this driver as a module, choose M here: the module will | ||
424 | be called pmic8xxx-keypad. | ||
425 | |||
357 | config KEYBOARD_SAMSUNG | 426 | config KEYBOARD_SAMSUNG |
358 | tristate "Samsung keypad support" | 427 | tristate "Samsung keypad support" |
359 | depends on SAMSUNG_DEV_KEYPAD | 428 | depends on SAMSUNG_DEV_KEYPAD |
@@ -424,6 +493,43 @@ config KEYBOARD_OMAP | |||
424 | To compile this driver as a module, choose M here: the | 493 | To compile this driver as a module, choose M here: the |
425 | module will be called omap-keypad. | 494 | module will be called omap-keypad. |
426 | 495 | ||
496 | config KEYBOARD_OMAP4 | ||
497 | tristate "TI OMAP4 keypad support" | ||
498 | depends on ARCH_OMAP4 | ||
499 | help | ||
500 | Say Y here if you want to use the OMAP4 keypad. | ||
501 | |||
502 | To compile this driver as a module, choose M here: the | ||
503 | module will be called omap4-keypad. | ||
504 | |||
505 | config KEYBOARD_SPEAR | ||
506 | tristate "ST SPEAR keyboard support" | ||
507 | depends on PLAT_SPEAR | ||
508 | help | ||
509 | Say Y here if you want to use the SPEAR keyboard. | ||
510 | |||
511 | To compile this driver as a module, choose M here: the | ||
512 | module will be called spear-keboard. | ||
513 | |||
514 | config KEYBOARD_TC3589X | ||
515 | tristate "TC3589X Keypad support" | ||
516 | depends on MFD_TC3589X | ||
517 | help | ||
518 | Say Y here if you want to use the keypad controller on | ||
519 | TC35892/3 I/O expander. | ||
520 | |||
521 | To compile this driver as a module, choose M here: the | ||
522 | module will be called tc3589x-keypad. | ||
523 | |||
524 | config KEYBOARD_TNETV107X | ||
525 | tristate "TI TNETV107X keypad support" | ||
526 | depends on ARCH_DAVINCI_TNETV107X | ||
527 | help | ||
528 | Say Y here if you want to use the TNETV107X keypad. | ||
529 | |||
530 | To compile this driver as a module, choose M here: the | ||
531 | module will be called tnetv107x-keypad. | ||
532 | |||
427 | config KEYBOARD_TWL4030 | 533 | config KEYBOARD_TWL4030 |
428 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" | 534 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" |
429 | depends on TWL4030_CORE | 535 | depends on TWL4030_CORE |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 504b591be0cd..ddde0fd476f7 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -4,9 +4,9 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | ||
8 | obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o | 7 | obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o |
9 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o | 8 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o |
9 | obj-$(CONFIG_KEYBOARD_ADP5589) += adp5589-keys.o | ||
10 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | 10 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o |
11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o |
12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
@@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | |||
14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | 14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o |
15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
17 | obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o | ||
17 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o | 18 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o |
18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 20 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
@@ -27,17 +28,26 @@ obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | |||
27 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o | 28 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o |
28 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o | 29 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o |
29 | obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o | 30 | obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o |
31 | obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o | ||
30 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | 32 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o |
33 | obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o | ||
31 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 34 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
35 | obj-$(CONFIG_KEYBOARD_OMAP4) += omap4-keypad.o | ||
32 | obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o | 36 | obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o |
37 | obj-$(CONFIG_KEYBOARD_PMIC8XXX) += pmic8xxx-keypad.o | ||
33 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o | 38 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o |
34 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o | 39 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o |
40 | obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o | ||
35 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o | 41 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o |
36 | obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o | 42 | obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o |
37 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | 43 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o |
44 | obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o | ||
38 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o | 45 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o |
39 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | 46 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o |
40 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | 47 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o |
48 | obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o | ||
49 | obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o | ||
50 | obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o | ||
41 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o | 51 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o |
42 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | 52 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o |
43 | obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o | 53 | obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o |
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c deleted file mode 100644 index 18222a689a03..000000000000 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ /dev/null | |||
@@ -1,186 +0,0 @@ | |||
1 | /* | ||
2 | * Keyboard driver for the AAED-2000 dev board | ||
3 | * | ||
4 | * Copyright (c) 2006 Nicolas Bellido Y Ortega | ||
5 | * | ||
6 | * Based on corgikbd.c | ||
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 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input-polldev.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/jiffies.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include <mach/hardware.h> | ||
24 | #include <mach/aaed2000.h> | ||
25 | |||
26 | #define KB_ROWS 12 | ||
27 | #define KB_COLS 8 | ||
28 | #define KB_ROWMASK(r) (1 << (r)) | ||
29 | #define SCANCODE(r,c) (((c) * KB_ROWS) + (r)) | ||
30 | #define NR_SCANCODES (KB_COLS * KB_ROWS) | ||
31 | |||
32 | #define SCAN_INTERVAL (50) /* ms */ | ||
33 | #define KB_ACTIVATE_DELAY (20) /* us */ | ||
34 | |||
35 | static unsigned char aaedkbd_keycode[NR_SCANCODES] = { | ||
36 | KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, 0, KEY_SPACE, KEY_KP6, 0, KEY_KPDOT, 0, 0, | ||
37 | KEY_K, KEY_M, KEY_O, KEY_DOT, KEY_SLASH, 0, KEY_F, 0, 0, 0, KEY_LEFTSHIFT, 0, | ||
38 | KEY_I, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, 0, 0, 0, 0, KEY_RIGHTSHIFT, 0, | ||
39 | KEY_8, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0, | ||
40 | KEY_J, KEY_H, KEY_B, KEY_KP8, KEY_KP4, 0, KEY_C, KEY_D, KEY_S, KEY_A, 0, KEY_CAPSLOCK, | ||
41 | KEY_Y, KEY_U, KEY_N, KEY_T, 0, 0, KEY_R, KEY_E, KEY_W, KEY_Q, 0, KEY_TAB, | ||
42 | KEY_7, KEY_6, KEY_G, 0, KEY_5, 0, KEY_4, KEY_3, KEY_2, KEY_1, 0, KEY_GRAVE, | ||
43 | 0, 0, KEY_COMMA, 0, KEY_KP2, 0, KEY_V, KEY_LEFTALT, KEY_X, KEY_Z, 0, KEY_LEFTCTRL | ||
44 | }; | ||
45 | |||
46 | struct aaedkbd { | ||
47 | unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)]; | ||
48 | struct input_polled_dev *poll_dev; | ||
49 | int kbdscan_state[KB_COLS]; | ||
50 | int kbdscan_count[KB_COLS]; | ||
51 | }; | ||
52 | |||
53 | #define KBDSCAN_STABLE_COUNT 2 | ||
54 | |||
55 | static void aaedkbd_report_col(struct aaedkbd *aaedkbd, | ||
56 | unsigned int col, unsigned int rowd) | ||
57 | { | ||
58 | unsigned int scancode, pressed; | ||
59 | unsigned int row; | ||
60 | |||
61 | for (row = 0; row < KB_ROWS; row++) { | ||
62 | scancode = SCANCODE(row, col); | ||
63 | pressed = rowd & KB_ROWMASK(row); | ||
64 | |||
65 | input_report_key(aaedkbd->poll_dev->input, | ||
66 | aaedkbd->keycode[scancode], pressed); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | /* Scan the hardware keyboard and push any changes up through the input layer */ | ||
71 | static void aaedkbd_poll(struct input_polled_dev *dev) | ||
72 | { | ||
73 | struct aaedkbd *aaedkbd = dev->private; | ||
74 | unsigned int col, rowd; | ||
75 | |||
76 | col = 0; | ||
77 | do { | ||
78 | AAEC_GPIO_KSCAN = col + 8; | ||
79 | udelay(KB_ACTIVATE_DELAY); | ||
80 | rowd = AAED_EXT_GPIO & AAED_EGPIO_KBD_SCAN; | ||
81 | |||
82 | if (rowd != aaedkbd->kbdscan_state[col]) { | ||
83 | aaedkbd->kbdscan_count[col] = 0; | ||
84 | aaedkbd->kbdscan_state[col] = rowd; | ||
85 | } else if (++aaedkbd->kbdscan_count[col] >= KBDSCAN_STABLE_COUNT) { | ||
86 | aaedkbd_report_col(aaedkbd, col, rowd); | ||
87 | col++; | ||
88 | } | ||
89 | } while (col < KB_COLS); | ||
90 | |||
91 | AAEC_GPIO_KSCAN = 0x07; | ||
92 | input_sync(dev->input); | ||
93 | } | ||
94 | |||
95 | static int __devinit aaedkbd_probe(struct platform_device *pdev) | ||
96 | { | ||
97 | struct aaedkbd *aaedkbd; | ||
98 | struct input_polled_dev *poll_dev; | ||
99 | struct input_dev *input_dev; | ||
100 | int i; | ||
101 | int error; | ||
102 | |||
103 | aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL); | ||
104 | poll_dev = input_allocate_polled_device(); | ||
105 | if (!aaedkbd || !poll_dev) { | ||
106 | error = -ENOMEM; | ||
107 | goto fail; | ||
108 | } | ||
109 | |||
110 | platform_set_drvdata(pdev, aaedkbd); | ||
111 | |||
112 | aaedkbd->poll_dev = poll_dev; | ||
113 | memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode)); | ||
114 | |||
115 | poll_dev->private = aaedkbd; | ||
116 | poll_dev->poll = aaedkbd_poll; | ||
117 | poll_dev->poll_interval = SCAN_INTERVAL; | ||
118 | |||
119 | input_dev = poll_dev->input; | ||
120 | input_dev->name = "AAED-2000 Keyboard"; | ||
121 | input_dev->phys = "aaedkbd/input0"; | ||
122 | input_dev->id.bustype = BUS_HOST; | ||
123 | input_dev->id.vendor = 0x0001; | ||
124 | input_dev->id.product = 0x0001; | ||
125 | input_dev->id.version = 0x0100; | ||
126 | input_dev->dev.parent = &pdev->dev; | ||
127 | |||
128 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
129 | input_dev->keycode = aaedkbd->keycode; | ||
130 | input_dev->keycodesize = sizeof(unsigned char); | ||
131 | input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode); | ||
132 | |||
133 | for (i = 0; i < ARRAY_SIZE(aaedkbd_keycode); i++) | ||
134 | set_bit(aaedkbd->keycode[i], input_dev->keybit); | ||
135 | clear_bit(0, input_dev->keybit); | ||
136 | |||
137 | error = input_register_polled_device(aaedkbd->poll_dev); | ||
138 | if (error) | ||
139 | goto fail; | ||
140 | |||
141 | return 0; | ||
142 | |||
143 | fail: kfree(aaedkbd); | ||
144 | input_free_polled_device(poll_dev); | ||
145 | return error; | ||
146 | } | ||
147 | |||
148 | static int __devexit aaedkbd_remove(struct platform_device *pdev) | ||
149 | { | ||
150 | struct aaedkbd *aaedkbd = platform_get_drvdata(pdev); | ||
151 | |||
152 | input_unregister_polled_device(aaedkbd->poll_dev); | ||
153 | input_free_polled_device(aaedkbd->poll_dev); | ||
154 | kfree(aaedkbd); | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | /* work with hotplug and coldplug */ | ||
160 | MODULE_ALIAS("platform:aaed2000-keyboard"); | ||
161 | |||
162 | static struct platform_driver aaedkbd_driver = { | ||
163 | .probe = aaedkbd_probe, | ||
164 | .remove = __devexit_p(aaedkbd_remove), | ||
165 | .driver = { | ||
166 | .name = "aaed2000-keyboard", | ||
167 | .owner = THIS_MODULE, | ||
168 | }, | ||
169 | }; | ||
170 | |||
171 | static int __init aaedkbd_init(void) | ||
172 | { | ||
173 | return platform_driver_register(&aaedkbd_driver); | ||
174 | } | ||
175 | |||
176 | static void __exit aaedkbd_exit(void) | ||
177 | { | ||
178 | platform_driver_unregister(&aaedkbd_driver); | ||
179 | } | ||
180 | |||
181 | module_init(aaedkbd_init); | ||
182 | module_exit(aaedkbd_exit); | ||
183 | |||
184 | MODULE_AUTHOR("Nicolas Bellido Y Ortega"); | ||
185 | MODULE_DESCRIPTION("AAED-2000 Keyboard Driver"); | ||
186 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index d6918cb966c0..af45d275f686 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * I2C QWERTY Keypad and IO Expander | 4 | * I2C QWERTY Keypad and IO Expander |
5 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 5 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
6 | * | 6 | * |
7 | * Copyright (C) 2008-2009 Analog Devices Inc. | 7 | * Copyright (C) 2008-2010 Analog Devices Inc. |
8 | * Licensed under the GPL-2 or later. | 8 | * Licensed under the GPL-2 or later. |
9 | */ | 9 | */ |
10 | 10 | ||
@@ -24,29 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/i2c/adp5588.h> | 25 | #include <linux/i2c/adp5588.h> |
26 | 26 | ||
27 | /* Configuration Register1 */ | ||
28 | #define AUTO_INC (1 << 7) | ||
29 | #define GPIEM_CFG (1 << 6) | ||
30 | #define OVR_FLOW_M (1 << 5) | ||
31 | #define INT_CFG (1 << 4) | ||
32 | #define OVR_FLOW_IEN (1 << 3) | ||
33 | #define K_LCK_IM (1 << 2) | ||
34 | #define GPI_IEN (1 << 1) | ||
35 | #define KE_IEN (1 << 0) | ||
36 | |||
37 | /* Interrupt Status Register */ | ||
38 | #define CMP2_INT (1 << 5) | ||
39 | #define CMP1_INT (1 << 4) | ||
40 | #define OVR_FLOW_INT (1 << 3) | ||
41 | #define K_LCK_INT (1 << 2) | ||
42 | #define GPI_INT (1 << 1) | ||
43 | #define KE_INT (1 << 0) | ||
44 | |||
45 | /* Key Lock and Event Counter Register */ | ||
46 | #define K_LCK_EN (1 << 6) | ||
47 | #define LCK21 0x30 | ||
48 | #define KEC 0xF | ||
49 | |||
50 | /* Key Event Register xy */ | 27 | /* Key Event Register xy */ |
51 | #define KEY_EV_PRESSED (1 << 7) | 28 | #define KEY_EV_PRESSED (1 << 7) |
52 | #define KEY_EV_MASK (0x7F) | 29 | #define KEY_EV_MASK (0x7F) |
@@ -55,10 +32,6 @@ | |||
55 | 32 | ||
56 | #define KEYP_MAX_EVENT 10 | 33 | #define KEYP_MAX_EVENT 10 |
57 | 34 | ||
58 | #define MAXGPIO 18 | ||
59 | #define ADP_BANK(offs) ((offs) >> 3) | ||
60 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) | ||
61 | |||
62 | /* | 35 | /* |
63 | * Early pre 4.0 Silicon required to delay readout by at least 25ms, | 36 | * Early pre 4.0 Silicon required to delay readout by at least 25ms, |
64 | * since the Event Counter Register updated 25ms after the interrupt | 37 | * since the Event Counter Register updated 25ms after the interrupt |
@@ -75,7 +48,7 @@ struct adp5588_kpad { | |||
75 | const struct adp5588_gpi_map *gpimap; | 48 | const struct adp5588_gpi_map *gpimap; |
76 | unsigned short gpimapsize; | 49 | unsigned short gpimapsize; |
77 | #ifdef CONFIG_GPIOLIB | 50 | #ifdef CONFIG_GPIOLIB |
78 | unsigned char gpiomap[MAXGPIO]; | 51 | unsigned char gpiomap[ADP5588_MAXGPIO]; |
79 | bool export_gpio; | 52 | bool export_gpio; |
80 | struct gpio_chip gc; | 53 | struct gpio_chip gc; |
81 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ | 54 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ |
@@ -103,8 +76,8 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) | |||
103 | static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) | 76 | static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) |
104 | { | 77 | { |
105 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 78 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
106 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 79 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
107 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 80 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
108 | 81 | ||
109 | return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); | 82 | return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); |
110 | } | 83 | } |
@@ -113,8 +86,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, | |||
113 | unsigned off, int val) | 86 | unsigned off, int val) |
114 | { | 87 | { |
115 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 88 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
116 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 89 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
117 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 90 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
118 | 91 | ||
119 | mutex_lock(&kpad->gpio_lock); | 92 | mutex_lock(&kpad->gpio_lock); |
120 | 93 | ||
@@ -132,8 +105,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, | |||
132 | static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) | 105 | static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) |
133 | { | 106 | { |
134 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 107 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
135 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 108 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
136 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 109 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
137 | int ret; | 110 | int ret; |
138 | 111 | ||
139 | mutex_lock(&kpad->gpio_lock); | 112 | mutex_lock(&kpad->gpio_lock); |
@@ -150,8 +123,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, | |||
150 | unsigned off, int val) | 123 | unsigned off, int val) |
151 | { | 124 | { |
152 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 125 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
153 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 126 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
154 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 127 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
155 | int ret; | 128 | int ret; |
156 | 129 | ||
157 | mutex_lock(&kpad->gpio_lock); | 130 | mutex_lock(&kpad->gpio_lock); |
@@ -176,7 +149,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, | |||
176 | static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, | 149 | static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, |
177 | const struct adp5588_kpad_platform_data *pdata) | 150 | const struct adp5588_kpad_platform_data *pdata) |
178 | { | 151 | { |
179 | bool pin_used[MAXGPIO]; | 152 | bool pin_used[ADP5588_MAXGPIO]; |
180 | int n_unused = 0; | 153 | int n_unused = 0; |
181 | int i; | 154 | int i; |
182 | 155 | ||
@@ -191,7 +164,7 @@ static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, | |||
191 | for (i = 0; i < kpad->gpimapsize; i++) | 164 | for (i = 0; i < kpad->gpimapsize; i++) |
192 | pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; | 165 | pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; |
193 | 166 | ||
194 | for (i = 0; i < MAXGPIO; i++) | 167 | for (i = 0; i < ADP5588_MAXGPIO; i++) |
195 | if (!pin_used[i]) | 168 | if (!pin_used[i]) |
196 | kpad->gpiomap[n_unused++] = i; | 169 | kpad->gpiomap[n_unused++] = i; |
197 | 170 | ||
@@ -234,7 +207,7 @@ static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad) | |||
234 | return error; | 207 | return error; |
235 | } | 208 | } |
236 | 209 | ||
237 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | 210 | for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { |
238 | kpad->dat_out[i] = adp5588_read(kpad->client, | 211 | kpad->dat_out[i] = adp5588_read(kpad->client, |
239 | GPIO_DAT_OUT1 + i); | 212 | GPIO_DAT_OUT1 + i); |
240 | kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); | 213 | kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); |
@@ -318,11 +291,11 @@ static void adp5588_work(struct work_struct *work) | |||
318 | 291 | ||
319 | status = adp5588_read(client, INT_STAT); | 292 | status = adp5588_read(client, INT_STAT); |
320 | 293 | ||
321 | if (status & OVR_FLOW_INT) /* Unlikely and should never happen */ | 294 | if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */ |
322 | dev_err(&client->dev, "Event Overflow Error\n"); | 295 | dev_err(&client->dev, "Event Overflow Error\n"); |
323 | 296 | ||
324 | if (status & KE_INT) { | 297 | if (status & ADP5588_KE_INT) { |
325 | ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; | 298 | ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC; |
326 | if (ev_cnt) { | 299 | if (ev_cnt) { |
327 | adp5588_report_events(kpad, ev_cnt); | 300 | adp5588_report_events(kpad, ev_cnt); |
328 | input_sync(kpad->input); | 301 | input_sync(kpad->input); |
@@ -360,7 +333,7 @@ static int __devinit adp5588_setup(struct i2c_client *client) | |||
360 | if (pdata->en_keylock) { | 333 | if (pdata->en_keylock) { |
361 | ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); | 334 | ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); |
362 | ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); | 335 | ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); |
363 | ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN); | 336 | ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN); |
364 | } | 337 | } |
365 | 338 | ||
366 | for (i = 0; i < KEYP_MAX_EVENT; i++) | 339 | for (i = 0; i < KEYP_MAX_EVENT; i++) |
@@ -384,7 +357,7 @@ static int __devinit adp5588_setup(struct i2c_client *client) | |||
384 | } | 357 | } |
385 | 358 | ||
386 | if (gpio_data) { | 359 | if (gpio_data) { |
387 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | 360 | for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { |
388 | int pull_mask = gpio_data->pullup_dis_mask; | 361 | int pull_mask = gpio_data->pullup_dis_mask; |
389 | 362 | ||
390 | ret |= adp5588_write(client, GPIO_PULL1 + i, | 363 | ret |= adp5588_write(client, GPIO_PULL1 + i, |
@@ -392,11 +365,14 @@ static int __devinit adp5588_setup(struct i2c_client *client) | |||
392 | } | 365 | } |
393 | } | 366 | } |
394 | 367 | ||
395 | ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | | 368 | ret |= adp5588_write(client, INT_STAT, |
396 | OVR_FLOW_INT | K_LCK_INT | | 369 | ADP5588_CMP2_INT | ADP5588_CMP1_INT | |
397 | GPI_INT | KE_INT); /* Status is W1C */ | 370 | ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | |
371 | ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */ | ||
398 | 372 | ||
399 | ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN); | 373 | ret |= adp5588_write(client, CFG, ADP5588_INT_CFG | |
374 | ADP5588_OVR_FLOW_IEN | | ||
375 | ADP5588_KE_IEN); | ||
400 | 376 | ||
401 | if (ret < 0) { | 377 | if (ret < 0) { |
402 | dev_err(&client->dev, "Write Error\n"); | 378 | dev_err(&client->dev, "Write Error\n"); |
@@ -660,7 +636,7 @@ static const struct dev_pm_ops adp5588_dev_pm_ops = { | |||
660 | #endif | 636 | #endif |
661 | 637 | ||
662 | static const struct i2c_device_id adp5588_id[] = { | 638 | static const struct i2c_device_id adp5588_id[] = { |
663 | { KBUILD_MODNAME, 0 }, | 639 | { "adp5588-keys", 0 }, |
664 | { "adp5587-keys", 0 }, | 640 | { "adp5587-keys", 0 }, |
665 | { } | 641 | { } |
666 | }; | 642 | }; |
diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c new file mode 100644 index 000000000000..631598663aab --- /dev/null +++ b/drivers/input/keyboard/adp5589-keys.c | |||
@@ -0,0 +1,771 @@ | |||
1 | /* | ||
2 | * Description: keypad driver for ADP5589 | ||
3 | * I2C QWERTY Keypad and IO Expander | ||
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
5 | * | ||
6 | * Copyright (C) 2010-2011 Analog Devices Inc. | ||
7 | * Licensed under the GPL-2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/version.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/workqueue.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #include <linux/input/adp5589.h> | ||
25 | |||
26 | /* GENERAL_CFG Register */ | ||
27 | #define OSC_EN (1 << 7) | ||
28 | #define CORE_CLK(x) (((x) & 0x3) << 5) | ||
29 | #define LCK_TRK_LOGIC (1 << 4) | ||
30 | #define LCK_TRK_GPI (1 << 3) | ||
31 | #define INT_CFG (1 << 1) | ||
32 | #define RST_CFG (1 << 0) | ||
33 | |||
34 | /* INT_EN Register */ | ||
35 | #define LOGIC2_IEN (1 << 5) | ||
36 | #define LOGIC1_IEN (1 << 4) | ||
37 | #define LOCK_IEN (1 << 3) | ||
38 | #define OVRFLOW_IEN (1 << 2) | ||
39 | #define GPI_IEN (1 << 1) | ||
40 | #define EVENT_IEN (1 << 0) | ||
41 | |||
42 | /* Interrupt Status Register */ | ||
43 | #define LOGIC2_INT (1 << 5) | ||
44 | #define LOGIC1_INT (1 << 4) | ||
45 | #define LOCK_INT (1 << 3) | ||
46 | #define OVRFLOW_INT (1 << 2) | ||
47 | #define GPI_INT (1 << 1) | ||
48 | #define EVENT_INT (1 << 0) | ||
49 | |||
50 | /* STATUS Register */ | ||
51 | |||
52 | #define LOGIC2_STAT (1 << 7) | ||
53 | #define LOGIC1_STAT (1 << 6) | ||
54 | #define LOCK_STAT (1 << 5) | ||
55 | #define KEC 0xF | ||
56 | |||
57 | /* PIN_CONFIG_D Register */ | ||
58 | #define C4_EXTEND_CFG (1 << 6) /* RESET2 */ | ||
59 | #define R4_EXTEND_CFG (1 << 5) /* RESET1 */ | ||
60 | |||
61 | /* LOCK_CFG */ | ||
62 | #define LOCK_EN (1 << 0) | ||
63 | |||
64 | #define PTIME_MASK 0x3 | ||
65 | #define LTIME_MASK 0x3 | ||
66 | |||
67 | /* Key Event Register xy */ | ||
68 | #define KEY_EV_PRESSED (1 << 7) | ||
69 | #define KEY_EV_MASK (0x7F) | ||
70 | |||
71 | #define KEYP_MAX_EVENT 16 | ||
72 | |||
73 | #define MAXGPIO 19 | ||
74 | #define ADP_BANK(offs) ((offs) >> 3) | ||
75 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) | ||
76 | |||
77 | struct adp5589_kpad { | ||
78 | struct i2c_client *client; | ||
79 | struct input_dev *input; | ||
80 | unsigned short keycode[ADP5589_KEYMAPSIZE]; | ||
81 | const struct adp5589_gpi_map *gpimap; | ||
82 | unsigned short gpimapsize; | ||
83 | unsigned extend_cfg; | ||
84 | #ifdef CONFIG_GPIOLIB | ||
85 | unsigned char gpiomap[MAXGPIO]; | ||
86 | bool export_gpio; | ||
87 | struct gpio_chip gc; | ||
88 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ | ||
89 | u8 dat_out[3]; | ||
90 | u8 dir[3]; | ||
91 | #endif | ||
92 | }; | ||
93 | |||
94 | static int adp5589_read(struct i2c_client *client, u8 reg) | ||
95 | { | ||
96 | int ret = i2c_smbus_read_byte_data(client, reg); | ||
97 | |||
98 | if (ret < 0) | ||
99 | dev_err(&client->dev, "Read Error\n"); | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | static int adp5589_write(struct i2c_client *client, u8 reg, u8 val) | ||
105 | { | ||
106 | return i2c_smbus_write_byte_data(client, reg, val); | ||
107 | } | ||
108 | |||
109 | #ifdef CONFIG_GPIOLIB | ||
110 | static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) | ||
111 | { | ||
112 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | ||
113 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | ||
114 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | ||
115 | |||
116 | return !!(adp5589_read(kpad->client, ADP5589_GPI_STATUS_A + bank) & | ||
117 | bit); | ||
118 | } | ||
119 | |||
120 | static void adp5589_gpio_set_value(struct gpio_chip *chip, | ||
121 | unsigned off, int val) | ||
122 | { | ||
123 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | ||
124 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | ||
125 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | ||
126 | |||
127 | mutex_lock(&kpad->gpio_lock); | ||
128 | |||
129 | if (val) | ||
130 | kpad->dat_out[bank] |= bit; | ||
131 | else | ||
132 | kpad->dat_out[bank] &= ~bit; | ||
133 | |||
134 | adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, | ||
135 | kpad->dat_out[bank]); | ||
136 | |||
137 | mutex_unlock(&kpad->gpio_lock); | ||
138 | } | ||
139 | |||
140 | static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) | ||
141 | { | ||
142 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | ||
143 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | ||
144 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | ||
145 | int ret; | ||
146 | |||
147 | mutex_lock(&kpad->gpio_lock); | ||
148 | |||
149 | kpad->dir[bank] &= ~bit; | ||
150 | ret = adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, | ||
151 | kpad->dir[bank]); | ||
152 | |||
153 | mutex_unlock(&kpad->gpio_lock); | ||
154 | |||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | static int adp5589_gpio_direction_output(struct gpio_chip *chip, | ||
159 | unsigned off, int val) | ||
160 | { | ||
161 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | ||
162 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | ||
163 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | ||
164 | int ret; | ||
165 | |||
166 | mutex_lock(&kpad->gpio_lock); | ||
167 | |||
168 | kpad->dir[bank] |= bit; | ||
169 | |||
170 | if (val) | ||
171 | kpad->dat_out[bank] |= bit; | ||
172 | else | ||
173 | kpad->dat_out[bank] &= ~bit; | ||
174 | |||
175 | ret = adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, | ||
176 | kpad->dat_out[bank]); | ||
177 | ret |= adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, | ||
178 | kpad->dir[bank]); | ||
179 | |||
180 | mutex_unlock(&kpad->gpio_lock); | ||
181 | |||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | static int __devinit adp5589_build_gpiomap(struct adp5589_kpad *kpad, | ||
186 | const struct adp5589_kpad_platform_data *pdata) | ||
187 | { | ||
188 | bool pin_used[MAXGPIO]; | ||
189 | int n_unused = 0; | ||
190 | int i; | ||
191 | |||
192 | memset(pin_used, false, sizeof(pin_used)); | ||
193 | |||
194 | for (i = 0; i < MAXGPIO; i++) | ||
195 | if (pdata->keypad_en_mask & (1 << i)) | ||
196 | pin_used[i] = true; | ||
197 | |||
198 | for (i = 0; i < kpad->gpimapsize; i++) | ||
199 | pin_used[kpad->gpimap[i].pin - ADP5589_GPI_PIN_BASE] = true; | ||
200 | |||
201 | if (kpad->extend_cfg & R4_EXTEND_CFG) | ||
202 | pin_used[4] = true; | ||
203 | |||
204 | if (kpad->extend_cfg & C4_EXTEND_CFG) | ||
205 | pin_used[12] = true; | ||
206 | |||
207 | for (i = 0; i < MAXGPIO; i++) | ||
208 | if (!pin_used[i]) | ||
209 | kpad->gpiomap[n_unused++] = i; | ||
210 | |||
211 | return n_unused; | ||
212 | } | ||
213 | |||
214 | static int __devinit adp5589_gpio_add(struct adp5589_kpad *kpad) | ||
215 | { | ||
216 | struct device *dev = &kpad->client->dev; | ||
217 | const struct adp5589_kpad_platform_data *pdata = dev->platform_data; | ||
218 | const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; | ||
219 | int i, error; | ||
220 | |||
221 | if (!gpio_data) | ||
222 | return 0; | ||
223 | |||
224 | kpad->gc.ngpio = adp5589_build_gpiomap(kpad, pdata); | ||
225 | if (kpad->gc.ngpio == 0) { | ||
226 | dev_info(dev, "No unused gpios left to export\n"); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | kpad->export_gpio = true; | ||
231 | |||
232 | kpad->gc.direction_input = adp5589_gpio_direction_input; | ||
233 | kpad->gc.direction_output = adp5589_gpio_direction_output; | ||
234 | kpad->gc.get = adp5589_gpio_get_value; | ||
235 | kpad->gc.set = adp5589_gpio_set_value; | ||
236 | kpad->gc.can_sleep = 1; | ||
237 | |||
238 | kpad->gc.base = gpio_data->gpio_start; | ||
239 | kpad->gc.label = kpad->client->name; | ||
240 | kpad->gc.owner = THIS_MODULE; | ||
241 | |||
242 | mutex_init(&kpad->gpio_lock); | ||
243 | |||
244 | error = gpiochip_add(&kpad->gc); | ||
245 | if (error) { | ||
246 | dev_err(dev, "gpiochip_add failed, err: %d\n", error); | ||
247 | return error; | ||
248 | } | ||
249 | |||
250 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | ||
251 | kpad->dat_out[i] = adp5589_read(kpad->client, | ||
252 | ADP5589_GPO_DATA_OUT_A + i); | ||
253 | kpad->dir[i] = adp5589_read(kpad->client, | ||
254 | ADP5589_GPIO_DIRECTION_A + i); | ||
255 | } | ||
256 | |||
257 | if (gpio_data->setup) { | ||
258 | error = gpio_data->setup(kpad->client, | ||
259 | kpad->gc.base, kpad->gc.ngpio, | ||
260 | gpio_data->context); | ||
261 | if (error) | ||
262 | dev_warn(dev, "setup failed, %d\n", error); | ||
263 | } | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static void __devexit adp5589_gpio_remove(struct adp5589_kpad *kpad) | ||
269 | { | ||
270 | struct device *dev = &kpad->client->dev; | ||
271 | const struct adp5589_kpad_platform_data *pdata = dev->platform_data; | ||
272 | const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; | ||
273 | int error; | ||
274 | |||
275 | if (!kpad->export_gpio) | ||
276 | return; | ||
277 | |||
278 | if (gpio_data->teardown) { | ||
279 | error = gpio_data->teardown(kpad->client, | ||
280 | kpad->gc.base, kpad->gc.ngpio, | ||
281 | gpio_data->context); | ||
282 | if (error) | ||
283 | dev_warn(dev, "teardown failed %d\n", error); | ||
284 | } | ||
285 | |||
286 | error = gpiochip_remove(&kpad->gc); | ||
287 | if (error) | ||
288 | dev_warn(dev, "gpiochip_remove failed %d\n", error); | ||
289 | } | ||
290 | #else | ||
291 | static inline int adp5589_gpio_add(struct adp5589_kpad *kpad) | ||
292 | { | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static inline void adp5589_gpio_remove(struct adp5589_kpad *kpad) | ||
297 | { | ||
298 | } | ||
299 | #endif | ||
300 | |||
301 | static void adp5589_report_switches(struct adp5589_kpad *kpad, | ||
302 | int key, int key_val) | ||
303 | { | ||
304 | int i; | ||
305 | |||
306 | for (i = 0; i < kpad->gpimapsize; i++) { | ||
307 | if (key_val == kpad->gpimap[i].pin) { | ||
308 | input_report_switch(kpad->input, | ||
309 | kpad->gpimap[i].sw_evt, | ||
310 | key & KEY_EV_PRESSED); | ||
311 | break; | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | static void adp5589_report_events(struct adp5589_kpad *kpad, int ev_cnt) | ||
317 | { | ||
318 | int i; | ||
319 | |||
320 | for (i = 0; i < ev_cnt; i++) { | ||
321 | int key = adp5589_read(kpad->client, ADP5589_FIFO_1 + i); | ||
322 | int key_val = key & KEY_EV_MASK; | ||
323 | |||
324 | if (key_val >= ADP5589_GPI_PIN_BASE && | ||
325 | key_val <= ADP5589_GPI_PIN_END) { | ||
326 | adp5589_report_switches(kpad, key, key_val); | ||
327 | } else { | ||
328 | input_report_key(kpad->input, | ||
329 | kpad->keycode[key_val - 1], | ||
330 | key & KEY_EV_PRESSED); | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
335 | static irqreturn_t adp5589_irq(int irq, void *handle) | ||
336 | { | ||
337 | struct adp5589_kpad *kpad = handle; | ||
338 | struct i2c_client *client = kpad->client; | ||
339 | int status, ev_cnt; | ||
340 | |||
341 | status = adp5589_read(client, ADP5589_INT_STATUS); | ||
342 | |||
343 | if (status & OVRFLOW_INT) /* Unlikely and should never happen */ | ||
344 | dev_err(&client->dev, "Event Overflow Error\n"); | ||
345 | |||
346 | if (status & EVENT_INT) { | ||
347 | ev_cnt = adp5589_read(client, ADP5589_STATUS) & KEC; | ||
348 | if (ev_cnt) { | ||
349 | adp5589_report_events(kpad, ev_cnt); | ||
350 | input_sync(kpad->input); | ||
351 | } | ||
352 | } | ||
353 | |||
354 | adp5589_write(client, ADP5589_INT_STATUS, status); /* Status is W1C */ | ||
355 | |||
356 | return IRQ_HANDLED; | ||
357 | } | ||
358 | |||
359 | static int __devinit adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key) | ||
360 | { | ||
361 | int i; | ||
362 | |||
363 | for (i = 0; i < ADP5589_KEYMAPSIZE; i++) | ||
364 | if (key == kpad->keycode[i]) | ||
365 | return (i + 1) | KEY_EV_PRESSED; | ||
366 | |||
367 | dev_err(&kpad->client->dev, "RESET/UNLOCK key not in keycode map\n"); | ||
368 | |||
369 | return -EINVAL; | ||
370 | } | ||
371 | |||
372 | static int __devinit adp5589_setup(struct adp5589_kpad *kpad) | ||
373 | { | ||
374 | struct i2c_client *client = kpad->client; | ||
375 | const struct adp5589_kpad_platform_data *pdata = | ||
376 | client->dev.platform_data; | ||
377 | int i, ret; | ||
378 | unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; | ||
379 | unsigned char pull_mask = 0; | ||
380 | |||
381 | ret = adp5589_write(client, ADP5589_PIN_CONFIG_A, | ||
382 | pdata->keypad_en_mask & 0xFF); | ||
383 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_B, | ||
384 | (pdata->keypad_en_mask >> 8) & 0xFF); | ||
385 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C, | ||
386 | (pdata->keypad_en_mask >> 16) & 0xFF); | ||
387 | |||
388 | if (pdata->en_keylock) { | ||
389 | ret |= adp5589_write(client, ADP5589_UNLOCK1, | ||
390 | pdata->unlock_key1); | ||
391 | ret |= adp5589_write(client, ADP5589_UNLOCK2, | ||
392 | pdata->unlock_key2); | ||
393 | ret |= adp5589_write(client, ADP5589_UNLOCK_TIMERS, | ||
394 | pdata->unlock_timer & LTIME_MASK); | ||
395 | ret |= adp5589_write(client, ADP5589_LOCK_CFG, LOCK_EN); | ||
396 | } | ||
397 | |||
398 | for (i = 0; i < KEYP_MAX_EVENT; i++) | ||
399 | ret |= adp5589_read(client, ADP5589_FIFO_1 + i); | ||
400 | |||
401 | for (i = 0; i < pdata->gpimapsize; i++) { | ||
402 | unsigned short pin = pdata->gpimap[i].pin; | ||
403 | |||
404 | if (pin <= ADP5589_GPI_PIN_ROW_END) { | ||
405 | evt_mode1 |= (1 << (pin - ADP5589_GPI_PIN_ROW_BASE)); | ||
406 | } else { | ||
407 | evt_mode2 |= | ||
408 | ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) & 0xFF); | ||
409 | evt_mode3 |= | ||
410 | ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) >> 8); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | if (pdata->gpimapsize) { | ||
415 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_A, evt_mode1); | ||
416 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_B, evt_mode2); | ||
417 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_C, evt_mode3); | ||
418 | } | ||
419 | |||
420 | if (pdata->pull_dis_mask & pdata->pullup_en_100k & | ||
421 | pdata->pullup_en_300k & pdata->pulldown_en_300k) | ||
422 | dev_warn(&client->dev, "Conflicting pull resistor config\n"); | ||
423 | |||
424 | for (i = 0; i < MAXGPIO; i++) { | ||
425 | unsigned val = 0; | ||
426 | |||
427 | if (pdata->pullup_en_300k & (1 << i)) | ||
428 | val = 0; | ||
429 | else if (pdata->pulldown_en_300k & (1 << i)) | ||
430 | val = 1; | ||
431 | else if (pdata->pullup_en_100k & (1 << i)) | ||
432 | val = 2; | ||
433 | else if (pdata->pull_dis_mask & (1 << i)) | ||
434 | val = 3; | ||
435 | |||
436 | pull_mask |= val << (2 * (i & 0x3)); | ||
437 | |||
438 | if ((i & 0x3) == 0x3 || i == MAXGPIO - 1) { | ||
439 | ret |= adp5589_write(client, | ||
440 | ADP5589_RPULL_CONFIG_A + (i >> 2), | ||
441 | pull_mask); | ||
442 | pull_mask = 0; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) { | ||
447 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_A, | ||
448 | adp5589_get_evcode(kpad, | ||
449 | pdata->reset1_key_1)); | ||
450 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_B, | ||
451 | adp5589_get_evcode(kpad, | ||
452 | pdata->reset1_key_2)); | ||
453 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_C, | ||
454 | adp5589_get_evcode(kpad, | ||
455 | pdata->reset1_key_3)); | ||
456 | kpad->extend_cfg |= R4_EXTEND_CFG; | ||
457 | } | ||
458 | |||
459 | if (pdata->reset2_key_1 && pdata->reset2_key_2) { | ||
460 | ret |= adp5589_write(client, ADP5589_RESET2_EVENT_A, | ||
461 | adp5589_get_evcode(kpad, | ||
462 | pdata->reset2_key_1)); | ||
463 | ret |= adp5589_write(client, ADP5589_RESET2_EVENT_B, | ||
464 | adp5589_get_evcode(kpad, | ||
465 | pdata->reset2_key_2)); | ||
466 | kpad->extend_cfg |= C4_EXTEND_CFG; | ||
467 | } | ||
468 | |||
469 | if (kpad->extend_cfg) { | ||
470 | ret |= adp5589_write(client, ADP5589_RESET_CFG, | ||
471 | pdata->reset_cfg); | ||
472 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_D, | ||
473 | kpad->extend_cfg); | ||
474 | } | ||
475 | |||
476 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) | ||
477 | ret |= adp5589_write(client, ADP5589_DEBOUNCE_DIS_A + i, | ||
478 | pdata->debounce_dis_mask >> (i * 8)); | ||
479 | |||
480 | ret |= adp5589_write(client, ADP5589_POLL_PTIME_CFG, | ||
481 | pdata->scan_cycle_time & PTIME_MASK); | ||
482 | ret |= adp5589_write(client, ADP5589_INT_STATUS, LOGIC2_INT | | ||
483 | LOGIC1_INT | OVRFLOW_INT | LOCK_INT | | ||
484 | GPI_INT | EVENT_INT); /* Status is W1C */ | ||
485 | |||
486 | ret |= adp5589_write(client, ADP5589_GENERAL_CFG, | ||
487 | INT_CFG | OSC_EN | CORE_CLK(3)); | ||
488 | ret |= adp5589_write(client, ADP5589_INT_EN, | ||
489 | OVRFLOW_IEN | GPI_IEN | EVENT_IEN); | ||
490 | |||
491 | if (ret < 0) { | ||
492 | dev_err(&client->dev, "Write Error\n"); | ||
493 | return ret; | ||
494 | } | ||
495 | |||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static void __devinit adp5589_report_switch_state(struct adp5589_kpad *kpad) | ||
500 | { | ||
501 | int gpi_stat1 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_A); | ||
502 | int gpi_stat2 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_B); | ||
503 | int gpi_stat3 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_C); | ||
504 | int gpi_stat_tmp, pin_loc; | ||
505 | int i; | ||
506 | |||
507 | for (i = 0; i < kpad->gpimapsize; i++) { | ||
508 | unsigned short pin = kpad->gpimap[i].pin; | ||
509 | |||
510 | if (pin <= ADP5589_GPI_PIN_ROW_END) { | ||
511 | gpi_stat_tmp = gpi_stat1; | ||
512 | pin_loc = pin - ADP5589_GPI_PIN_ROW_BASE; | ||
513 | } else if ((pin - ADP5589_GPI_PIN_COL_BASE) < 8) { | ||
514 | gpi_stat_tmp = gpi_stat2; | ||
515 | pin_loc = pin - ADP5589_GPI_PIN_COL_BASE; | ||
516 | } else { | ||
517 | gpi_stat_tmp = gpi_stat3; | ||
518 | pin_loc = pin - ADP5589_GPI_PIN_COL_BASE - 8; | ||
519 | } | ||
520 | |||
521 | if (gpi_stat_tmp < 0) { | ||
522 | dev_err(&kpad->client->dev, | ||
523 | "Can't read GPIO_DAT_STAT switch" | ||
524 | " %d default to OFF\n", pin); | ||
525 | gpi_stat_tmp = 0; | ||
526 | } | ||
527 | |||
528 | input_report_switch(kpad->input, | ||
529 | kpad->gpimap[i].sw_evt, | ||
530 | !(gpi_stat_tmp & (1 << pin_loc))); | ||
531 | } | ||
532 | |||
533 | input_sync(kpad->input); | ||
534 | } | ||
535 | |||
536 | static int __devinit adp5589_probe(struct i2c_client *client, | ||
537 | const struct i2c_device_id *id) | ||
538 | { | ||
539 | struct adp5589_kpad *kpad; | ||
540 | const struct adp5589_kpad_platform_data *pdata; | ||
541 | struct input_dev *input; | ||
542 | unsigned int revid; | ||
543 | int ret, i; | ||
544 | int error; | ||
545 | |||
546 | if (!i2c_check_functionality(client->adapter, | ||
547 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
548 | dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); | ||
549 | return -EIO; | ||
550 | } | ||
551 | |||
552 | pdata = client->dev.platform_data; | ||
553 | if (!pdata) { | ||
554 | dev_err(&client->dev, "no platform data?\n"); | ||
555 | return -EINVAL; | ||
556 | } | ||
557 | |||
558 | if (!((pdata->keypad_en_mask & 0xFF) && | ||
559 | (pdata->keypad_en_mask >> 8)) || !pdata->keymap) { | ||
560 | dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); | ||
561 | return -EINVAL; | ||
562 | } | ||
563 | |||
564 | if (pdata->keymapsize != ADP5589_KEYMAPSIZE) { | ||
565 | dev_err(&client->dev, "invalid keymapsize\n"); | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | |||
569 | if (!pdata->gpimap && pdata->gpimapsize) { | ||
570 | dev_err(&client->dev, "invalid gpimap from pdata\n"); | ||
571 | return -EINVAL; | ||
572 | } | ||
573 | |||
574 | if (pdata->gpimapsize > ADP5589_GPIMAPSIZE_MAX) { | ||
575 | dev_err(&client->dev, "invalid gpimapsize\n"); | ||
576 | return -EINVAL; | ||
577 | } | ||
578 | |||
579 | for (i = 0; i < pdata->gpimapsize; i++) { | ||
580 | unsigned short pin = pdata->gpimap[i].pin; | ||
581 | |||
582 | if (pin < ADP5589_GPI_PIN_BASE || pin > ADP5589_GPI_PIN_END) { | ||
583 | dev_err(&client->dev, "invalid gpi pin data\n"); | ||
584 | return -EINVAL; | ||
585 | } | ||
586 | |||
587 | if ((1 << (pin - ADP5589_GPI_PIN_ROW_BASE)) & | ||
588 | pdata->keypad_en_mask) { | ||
589 | dev_err(&client->dev, "invalid gpi row/col data\n"); | ||
590 | return -EINVAL; | ||
591 | } | ||
592 | } | ||
593 | |||
594 | if (!client->irq) { | ||
595 | dev_err(&client->dev, "no IRQ?\n"); | ||
596 | return -EINVAL; | ||
597 | } | ||
598 | |||
599 | kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); | ||
600 | input = input_allocate_device(); | ||
601 | if (!kpad || !input) { | ||
602 | error = -ENOMEM; | ||
603 | goto err_free_mem; | ||
604 | } | ||
605 | |||
606 | kpad->client = client; | ||
607 | kpad->input = input; | ||
608 | |||
609 | ret = adp5589_read(client, ADP5589_ID); | ||
610 | if (ret < 0) { | ||
611 | error = ret; | ||
612 | goto err_free_mem; | ||
613 | } | ||
614 | |||
615 | revid = (u8) ret & ADP5589_DEVICE_ID_MASK; | ||
616 | |||
617 | input->name = client->name; | ||
618 | input->phys = "adp5589-keys/input0"; | ||
619 | input->dev.parent = &client->dev; | ||
620 | |||
621 | input_set_drvdata(input, kpad); | ||
622 | |||
623 | input->id.bustype = BUS_I2C; | ||
624 | input->id.vendor = 0x0001; | ||
625 | input->id.product = 0x0001; | ||
626 | input->id.version = revid; | ||
627 | |||
628 | input->keycodesize = sizeof(kpad->keycode[0]); | ||
629 | input->keycodemax = pdata->keymapsize; | ||
630 | input->keycode = kpad->keycode; | ||
631 | |||
632 | memcpy(kpad->keycode, pdata->keymap, | ||
633 | pdata->keymapsize * input->keycodesize); | ||
634 | |||
635 | kpad->gpimap = pdata->gpimap; | ||
636 | kpad->gpimapsize = pdata->gpimapsize; | ||
637 | |||
638 | /* setup input device */ | ||
639 | __set_bit(EV_KEY, input->evbit); | ||
640 | |||
641 | if (pdata->repeat) | ||
642 | __set_bit(EV_REP, input->evbit); | ||
643 | |||
644 | for (i = 0; i < input->keycodemax; i++) | ||
645 | __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit); | ||
646 | __clear_bit(KEY_RESERVED, input->keybit); | ||
647 | |||
648 | if (kpad->gpimapsize) | ||
649 | __set_bit(EV_SW, input->evbit); | ||
650 | for (i = 0; i < kpad->gpimapsize; i++) | ||
651 | __set_bit(kpad->gpimap[i].sw_evt, input->swbit); | ||
652 | |||
653 | error = input_register_device(input); | ||
654 | if (error) { | ||
655 | dev_err(&client->dev, "unable to register input device\n"); | ||
656 | goto err_free_mem; | ||
657 | } | ||
658 | |||
659 | error = request_threaded_irq(client->irq, NULL, adp5589_irq, | ||
660 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
661 | client->dev.driver->name, kpad); | ||
662 | if (error) { | ||
663 | dev_err(&client->dev, "irq %d busy?\n", client->irq); | ||
664 | goto err_unreg_dev; | ||
665 | } | ||
666 | |||
667 | error = adp5589_setup(kpad); | ||
668 | if (error) | ||
669 | goto err_free_irq; | ||
670 | |||
671 | if (kpad->gpimapsize) | ||
672 | adp5589_report_switch_state(kpad); | ||
673 | |||
674 | error = adp5589_gpio_add(kpad); | ||
675 | if (error) | ||
676 | goto err_free_irq; | ||
677 | |||
678 | device_init_wakeup(&client->dev, 1); | ||
679 | i2c_set_clientdata(client, kpad); | ||
680 | |||
681 | dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); | ||
682 | return 0; | ||
683 | |||
684 | err_free_irq: | ||
685 | free_irq(client->irq, kpad); | ||
686 | err_unreg_dev: | ||
687 | input_unregister_device(input); | ||
688 | input = NULL; | ||
689 | err_free_mem: | ||
690 | input_free_device(input); | ||
691 | kfree(kpad); | ||
692 | |||
693 | return error; | ||
694 | } | ||
695 | |||
696 | static int __devexit adp5589_remove(struct i2c_client *client) | ||
697 | { | ||
698 | struct adp5589_kpad *kpad = i2c_get_clientdata(client); | ||
699 | |||
700 | adp5589_write(client, ADP5589_GENERAL_CFG, 0); | ||
701 | free_irq(client->irq, kpad); | ||
702 | input_unregister_device(kpad->input); | ||
703 | adp5589_gpio_remove(kpad); | ||
704 | kfree(kpad); | ||
705 | |||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | #ifdef CONFIG_PM_SLEEP | ||
710 | static int adp5589_suspend(struct device *dev) | ||
711 | { | ||
712 | struct adp5589_kpad *kpad = dev_get_drvdata(dev); | ||
713 | struct i2c_client *client = kpad->client; | ||
714 | |||
715 | disable_irq(client->irq); | ||
716 | |||
717 | if (device_may_wakeup(&client->dev)) | ||
718 | enable_irq_wake(client->irq); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static int adp5589_resume(struct device *dev) | ||
724 | { | ||
725 | struct adp5589_kpad *kpad = dev_get_drvdata(dev); | ||
726 | struct i2c_client *client = kpad->client; | ||
727 | |||
728 | if (device_may_wakeup(&client->dev)) | ||
729 | disable_irq_wake(client->irq); | ||
730 | |||
731 | enable_irq(client->irq); | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | #endif | ||
736 | |||
737 | static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume); | ||
738 | |||
739 | static const struct i2c_device_id adp5589_id[] = { | ||
740 | {"adp5589-keys", 0}, | ||
741 | {} | ||
742 | }; | ||
743 | |||
744 | MODULE_DEVICE_TABLE(i2c, adp5589_id); | ||
745 | |||
746 | static struct i2c_driver adp5589_driver = { | ||
747 | .driver = { | ||
748 | .name = KBUILD_MODNAME, | ||
749 | .owner = THIS_MODULE, | ||
750 | .pm = &adp5589_dev_pm_ops, | ||
751 | }, | ||
752 | .probe = adp5589_probe, | ||
753 | .remove = __devexit_p(adp5589_remove), | ||
754 | .id_table = adp5589_id, | ||
755 | }; | ||
756 | |||
757 | static int __init adp5589_init(void) | ||
758 | { | ||
759 | return i2c_add_driver(&adp5589_driver); | ||
760 | } | ||
761 | module_init(adp5589_init); | ||
762 | |||
763 | static void __exit adp5589_exit(void) | ||
764 | { | ||
765 | i2c_del_driver(&adp5589_driver); | ||
766 | } | ||
767 | module_exit(adp5589_exit); | ||
768 | |||
769 | MODULE_LICENSE("GPL"); | ||
770 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
771 | MODULE_DESCRIPTION("ADP5589 Keypad driver"); | ||
diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c index 1839194ea987..10bcd4ae5402 100644 --- a/drivers/input/keyboard/atakbd.c +++ b/drivers/input/keyboard/atakbd.c | |||
@@ -223,8 +223,9 @@ static int __init atakbd_init(void) | |||
223 | return -ENODEV; | 223 | return -ENODEV; |
224 | 224 | ||
225 | // need to init core driver if not already done so | 225 | // need to init core driver if not already done so |
226 | if (atari_keyb_init()) | 226 | error = atari_keyb_init(); |
227 | return -ENODEV; | 227 | if (error) |
228 | return error; | ||
228 | 229 | ||
229 | atakbd_dev = input_allocate_device(); | 230 | atakbd_dev = input_allocate_device(); |
230 | if (!atakbd_dev) | 231 | if (!atakbd_dev) |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index d358ef8623f4..11478eb2c27d 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -63,6 +63,10 @@ static bool atkbd_extra; | |||
63 | module_param_named(extra, atkbd_extra, bool, 0); | 63 | module_param_named(extra, atkbd_extra, bool, 0); |
64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); | 64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); |
65 | 65 | ||
66 | static bool atkbd_terminal; | ||
67 | module_param_named(terminal, atkbd_terminal, bool, 0); | ||
68 | MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2"); | ||
69 | |||
66 | /* | 70 | /* |
67 | * Scancode to keycode tables. These are just the default setting, and | 71 | * Scancode to keycode tables. These are just the default setting, and |
68 | * are loadable via a userland utility. | 72 | * are loadable via a userland utility. |
@@ -136,7 +140,8 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
136 | #define ATKBD_CMD_ENABLE 0x00f4 | 140 | #define ATKBD_CMD_ENABLE 0x00f4 |
137 | #define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ | 141 | #define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ |
138 | #define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ | 142 | #define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ |
139 | #define ATKBD_CMD_SETALL_MBR 0x00fa | 143 | #define ATKBD_CMD_SETALL_MB 0x00f8 /* Set all keys to give break codes */ |
144 | #define ATKBD_CMD_SETALL_MBR 0x00fa /* ... and repeat */ | ||
140 | #define ATKBD_CMD_RESET_BAT 0x02ff | 145 | #define ATKBD_CMD_RESET_BAT 0x02ff |
141 | #define ATKBD_CMD_RESEND 0x00fe | 146 | #define ATKBD_CMD_RESEND 0x00fe |
142 | #define ATKBD_CMD_EX_ENABLE 0x10ea | 147 | #define ATKBD_CMD_EX_ENABLE 0x10ea |
@@ -764,6 +769,11 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
764 | } | 769 | } |
765 | } | 770 | } |
766 | 771 | ||
772 | if (atkbd_terminal) { | ||
773 | ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MB); | ||
774 | return 3; | ||
775 | } | ||
776 | |||
767 | if (target_set != 3) | 777 | if (target_set != 3) |
768 | return 2; | 778 | return 2; |
769 | 779 | ||
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index a91ee941b5c1..cd89d17162a3 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> | 6 | * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> |
7 | * | 7 | * |
8 | * Intial Code: Sandeep Paulraj <s-paulraj@ti.com> | 8 | * Initial Code: Sandeep Paulraj <s-paulraj@ti.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 6069abe31e42..6e6145b9a4c1 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -322,9 +322,14 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata) | |||
322 | struct gpio_keys_button *button = bdata->button; | 322 | struct gpio_keys_button *button = bdata->button; |
323 | struct input_dev *input = bdata->input; | 323 | struct input_dev *input = bdata->input; |
324 | unsigned int type = button->type ?: EV_KEY; | 324 | unsigned int type = button->type ?: EV_KEY; |
325 | int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; | 325 | int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; |
326 | 326 | ||
327 | input_event(input, type, button->code, !!state); | 327 | if (type == EV_ABS) { |
328 | if (state) | ||
329 | input_event(input, type, button->code, button->value); | ||
330 | } else { | ||
331 | input_event(input, type, button->code, !!state); | ||
332 | } | ||
328 | input_sync(input); | 333 | input_sync(input); |
329 | } | 334 | } |
330 | 335 | ||
@@ -363,7 +368,7 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, | |||
363 | struct gpio_button_data *bdata, | 368 | struct gpio_button_data *bdata, |
364 | struct gpio_keys_button *button) | 369 | struct gpio_keys_button *button) |
365 | { | 370 | { |
366 | char *desc = button->desc ? button->desc : "gpio_keys"; | 371 | const char *desc = button->desc ? button->desc : "gpio_keys"; |
367 | struct device *dev = &pdev->dev; | 372 | struct device *dev = &pdev->dev; |
368 | unsigned long irqflags; | 373 | unsigned long irqflags; |
369 | int irq, error; | 374 | int irq, error; |
@@ -410,8 +415,8 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, | |||
410 | if (!button->can_disable) | 415 | if (!button->can_disable) |
411 | irqflags |= IRQF_SHARED; | 416 | irqflags |= IRQF_SHARED; |
412 | 417 | ||
413 | error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); | 418 | error = request_any_context_irq(irq, gpio_keys_isr, irqflags, desc, bdata); |
414 | if (error) { | 419 | if (error < 0) { |
415 | dev_err(dev, "Unable to claim irq %d; error %d\n", | 420 | dev_err(dev, "Unable to claim irq %d; error %d\n", |
416 | irq, error); | 421 | irq, error); |
417 | goto fail3; | 422 | goto fail3; |
@@ -468,7 +473,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
468 | platform_set_drvdata(pdev, ddata); | 473 | platform_set_drvdata(pdev, ddata); |
469 | input_set_drvdata(input, ddata); | 474 | input_set_drvdata(input, ddata); |
470 | 475 | ||
471 | input->name = pdev->name; | 476 | input->name = pdata->name ? : pdev->name; |
472 | input->phys = "gpio-keys/input0"; | 477 | input->phys = "gpio-keys/input0"; |
473 | input->dev.parent = &pdev->dev; | 478 | input->dev.parent = &pdev->dev; |
474 | input->open = gpio_keys_open; | 479 | input->open = gpio_keys_open; |
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c new file mode 100644 index 000000000000..4c17aff20657 --- /dev/null +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* | ||
2 | * Driver for buttons on GPIO lines not capable of generating interrupts | ||
3 | * | ||
4 | * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com> | ||
6 | * | ||
7 | * This file was based on: /drivers/input/misc/cobalt_btns.c | ||
8 | * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | ||
9 | * | ||
10 | * also was based on: /drivers/input/keyboard/gpio_keys.c | ||
11 | * Copyright 2005 Phil Blundell | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/input-polldev.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/gpio_keys.h> | ||
28 | |||
29 | #define DRV_NAME "gpio-keys-polled" | ||
30 | |||
31 | struct gpio_keys_button_data { | ||
32 | int last_state; | ||
33 | int count; | ||
34 | int threshold; | ||
35 | int can_sleep; | ||
36 | }; | ||
37 | |||
38 | struct gpio_keys_polled_dev { | ||
39 | struct input_polled_dev *poll_dev; | ||
40 | struct device *dev; | ||
41 | struct gpio_keys_platform_data *pdata; | ||
42 | struct gpio_keys_button_data data[0]; | ||
43 | }; | ||
44 | |||
45 | static void gpio_keys_polled_check_state(struct input_dev *input, | ||
46 | struct gpio_keys_button *button, | ||
47 | struct gpio_keys_button_data *bdata) | ||
48 | { | ||
49 | int state; | ||
50 | |||
51 | if (bdata->can_sleep) | ||
52 | state = !!gpio_get_value_cansleep(button->gpio); | ||
53 | else | ||
54 | state = !!gpio_get_value(button->gpio); | ||
55 | |||
56 | if (state != bdata->last_state) { | ||
57 | unsigned int type = button->type ?: EV_KEY; | ||
58 | |||
59 | input_event(input, type, button->code, | ||
60 | !!(state ^ button->active_low)); | ||
61 | input_sync(input); | ||
62 | bdata->count = 0; | ||
63 | bdata->last_state = state; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | static void gpio_keys_polled_poll(struct input_polled_dev *dev) | ||
68 | { | ||
69 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
70 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
71 | struct input_dev *input = dev->input; | ||
72 | int i; | ||
73 | |||
74 | for (i = 0; i < bdev->pdata->nbuttons; i++) { | ||
75 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | ||
76 | |||
77 | if (bdata->count < bdata->threshold) | ||
78 | bdata->count++; | ||
79 | else | ||
80 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | ||
81 | bdata); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | static void gpio_keys_polled_open(struct input_polled_dev *dev) | ||
86 | { | ||
87 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
88 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
89 | |||
90 | if (pdata->enable) | ||
91 | pdata->enable(bdev->dev); | ||
92 | } | ||
93 | |||
94 | static void gpio_keys_polled_close(struct input_polled_dev *dev) | ||
95 | { | ||
96 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
97 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
98 | |||
99 | if (pdata->disable) | ||
100 | pdata->disable(bdev->dev); | ||
101 | } | ||
102 | |||
103 | static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) | ||
104 | { | ||
105 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
106 | struct device *dev = &pdev->dev; | ||
107 | struct gpio_keys_polled_dev *bdev; | ||
108 | struct input_polled_dev *poll_dev; | ||
109 | struct input_dev *input; | ||
110 | int error; | ||
111 | int i; | ||
112 | |||
113 | if (!pdata || !pdata->poll_interval) | ||
114 | return -EINVAL; | ||
115 | |||
116 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + | ||
117 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), | ||
118 | GFP_KERNEL); | ||
119 | if (!bdev) { | ||
120 | dev_err(dev, "no memory for private data\n"); | ||
121 | return -ENOMEM; | ||
122 | } | ||
123 | |||
124 | poll_dev = input_allocate_polled_device(); | ||
125 | if (!poll_dev) { | ||
126 | dev_err(dev, "no memory for polled device\n"); | ||
127 | error = -ENOMEM; | ||
128 | goto err_free_bdev; | ||
129 | } | ||
130 | |||
131 | poll_dev->private = bdev; | ||
132 | poll_dev->poll = gpio_keys_polled_poll; | ||
133 | poll_dev->poll_interval = pdata->poll_interval; | ||
134 | poll_dev->open = gpio_keys_polled_open; | ||
135 | poll_dev->close = gpio_keys_polled_close; | ||
136 | |||
137 | input = poll_dev->input; | ||
138 | |||
139 | input->evbit[0] = BIT(EV_KEY); | ||
140 | input->name = pdev->name; | ||
141 | input->phys = DRV_NAME"/input0"; | ||
142 | input->dev.parent = &pdev->dev; | ||
143 | |||
144 | input->id.bustype = BUS_HOST; | ||
145 | input->id.vendor = 0x0001; | ||
146 | input->id.product = 0x0001; | ||
147 | input->id.version = 0x0100; | ||
148 | |||
149 | for (i = 0; i < pdata->nbuttons; i++) { | ||
150 | struct gpio_keys_button *button = &pdata->buttons[i]; | ||
151 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | ||
152 | unsigned int gpio = button->gpio; | ||
153 | unsigned int type = button->type ?: EV_KEY; | ||
154 | |||
155 | if (button->wakeup) { | ||
156 | dev_err(dev, DRV_NAME " does not support wakeup\n"); | ||
157 | error = -EINVAL; | ||
158 | goto err_free_gpio; | ||
159 | } | ||
160 | |||
161 | error = gpio_request(gpio, | ||
162 | button->desc ? button->desc : DRV_NAME); | ||
163 | if (error) { | ||
164 | dev_err(dev, "unable to claim gpio %u, err=%d\n", | ||
165 | gpio, error); | ||
166 | goto err_free_gpio; | ||
167 | } | ||
168 | |||
169 | error = gpio_direction_input(gpio); | ||
170 | if (error) { | ||
171 | dev_err(dev, | ||
172 | "unable to set direction on gpio %u, err=%d\n", | ||
173 | gpio, error); | ||
174 | goto err_free_gpio; | ||
175 | } | ||
176 | |||
177 | bdata->can_sleep = gpio_cansleep(gpio); | ||
178 | bdata->last_state = -1; | ||
179 | bdata->threshold = DIV_ROUND_UP(button->debounce_interval, | ||
180 | pdata->poll_interval); | ||
181 | |||
182 | input_set_capability(input, type, button->code); | ||
183 | } | ||
184 | |||
185 | bdev->poll_dev = poll_dev; | ||
186 | bdev->dev = dev; | ||
187 | bdev->pdata = pdata; | ||
188 | platform_set_drvdata(pdev, bdev); | ||
189 | |||
190 | error = input_register_polled_device(poll_dev); | ||
191 | if (error) { | ||
192 | dev_err(dev, "unable to register polled device, err=%d\n", | ||
193 | error); | ||
194 | goto err_free_gpio; | ||
195 | } | ||
196 | |||
197 | /* report initial state of the buttons */ | ||
198 | for (i = 0; i < pdata->nbuttons; i++) | ||
199 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | ||
200 | &bdev->data[i]); | ||
201 | |||
202 | return 0; | ||
203 | |||
204 | err_free_gpio: | ||
205 | while (--i >= 0) | ||
206 | gpio_free(pdata->buttons[i].gpio); | ||
207 | |||
208 | input_free_polled_device(poll_dev); | ||
209 | |||
210 | err_free_bdev: | ||
211 | kfree(bdev); | ||
212 | |||
213 | platform_set_drvdata(pdev, NULL); | ||
214 | return error; | ||
215 | } | ||
216 | |||
217 | static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) | ||
218 | { | ||
219 | struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); | ||
220 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
221 | int i; | ||
222 | |||
223 | input_unregister_polled_device(bdev->poll_dev); | ||
224 | |||
225 | for (i = 0; i < pdata->nbuttons; i++) | ||
226 | gpio_free(pdata->buttons[i].gpio); | ||
227 | |||
228 | input_free_polled_device(bdev->poll_dev); | ||
229 | |||
230 | kfree(bdev); | ||
231 | platform_set_drvdata(pdev, NULL); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct platform_driver gpio_keys_polled_driver = { | ||
237 | .probe = gpio_keys_polled_probe, | ||
238 | .remove = __devexit_p(gpio_keys_polled_remove), | ||
239 | .driver = { | ||
240 | .name = DRV_NAME, | ||
241 | .owner = THIS_MODULE, | ||
242 | }, | ||
243 | }; | ||
244 | |||
245 | static int __init gpio_keys_polled_init(void) | ||
246 | { | ||
247 | return platform_driver_register(&gpio_keys_polled_driver); | ||
248 | } | ||
249 | |||
250 | static void __exit gpio_keys_polled_exit(void) | ||
251 | { | ||
252 | platform_driver_unregister(&gpio_keys_polled_driver); | ||
253 | } | ||
254 | |||
255 | module_init(gpio_keys_polled_init); | ||
256 | module_exit(gpio_keys_polled_exit); | ||
257 | |||
258 | MODULE_LICENSE("GPL v2"); | ||
259 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); | ||
260 | MODULE_DESCRIPTION("Polled GPIO Buttons driver"); | ||
261 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 19fa94af207a..fed31e0947a1 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -570,6 +570,8 @@ static struct serio_device_id hil_dev_ids[] = { | |||
570 | { 0 } | 570 | { 0 } |
571 | }; | 571 | }; |
572 | 572 | ||
573 | MODULE_DEVICE_TABLE(serio, hil_dev_ids); | ||
574 | |||
573 | static struct serio_driver hil_serio_drv = { | 575 | static struct serio_driver hil_serio_drv = { |
574 | .driver = { | 576 | .driver = { |
575 | .name = "hil_dev", | 577 | .name = "hil_dev", |
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 5fc976dbce0b..7197c5698747 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c | |||
@@ -139,35 +139,35 @@ static void jornada_scan_keyb(unsigned char *s) | |||
139 | }, *y = matrix_PDE; | 139 | }, *y = matrix_PDE; |
140 | 140 | ||
141 | /* Save these control reg bits */ | 141 | /* Save these control reg bits */ |
142 | dc_static = (ctrl_inw(PDCR) & (~0xcc0c)); | 142 | dc_static = (__raw_readw(PDCR) & (~0xcc0c)); |
143 | ec_static = (ctrl_inw(PECR) & (~0xf0cf)); | 143 | ec_static = (__raw_readw(PECR) & (~0xf0cf)); |
144 | 144 | ||
145 | for (i = 0; i < 8; i++) { | 145 | for (i = 0; i < 8; i++) { |
146 | /* disable output for all but the one we want to scan */ | 146 | /* disable output for all but the one we want to scan */ |
147 | ctrl_outw((dc_static | *y++), PDCR); | 147 | __raw_writew((dc_static | *y++), PDCR); |
148 | ctrl_outw((ec_static | *y++), PECR); | 148 | __raw_writew((ec_static | *y++), PECR); |
149 | udelay(5); | 149 | udelay(5); |
150 | 150 | ||
151 | /* Get scanline row */ | 151 | /* Get scanline row */ |
152 | ctrl_outb(*t++, PDDR); | 152 | __raw_writeb(*t++, PDDR); |
153 | ctrl_outb(*t++, PEDR); | 153 | __raw_writeb(*t++, PEDR); |
154 | udelay(50); | 154 | udelay(50); |
155 | 155 | ||
156 | /* Read data */ | 156 | /* Read data */ |
157 | *s++ = ctrl_inb(PCDR); | 157 | *s++ = __raw_readb(PCDR); |
158 | *s++ = ctrl_inb(PFDR); | 158 | *s++ = __raw_readb(PFDR); |
159 | } | 159 | } |
160 | /* Scan no lines */ | 160 | /* Scan no lines */ |
161 | ctrl_outb(0xff, PDDR); | 161 | __raw_writeb(0xff, PDDR); |
162 | ctrl_outb(0xff, PEDR); | 162 | __raw_writeb(0xff, PEDR); |
163 | 163 | ||
164 | /* Enable all scanlines */ | 164 | /* Enable all scanlines */ |
165 | ctrl_outw((dc_static | (0x5555 & 0xcc0c)),PDCR); | 165 | __raw_writew((dc_static | (0x5555 & 0xcc0c)),PDCR); |
166 | ctrl_outw((ec_static | (0x5555 & 0xf0cf)),PECR); | 166 | __raw_writew((ec_static | (0x5555 & 0xf0cf)),PECR); |
167 | 167 | ||
168 | /* Ignore extra keys and events */ | 168 | /* Ignore extra keys and events */ |
169 | *s++ = ctrl_inb(PGDR); | 169 | *s++ = __raw_readb(PGDR); |
170 | *s++ = ctrl_inb(PHDR); | 170 | *s++ = __raw_readb(PHDR); |
171 | } | 171 | } |
172 | 172 | ||
173 | static void jornadakbd680_poll(struct input_polled_dev *dev) | 173 | static void jornadakbd680_poll(struct input_polled_dev *dev) |
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index f7c2a166576b..71f744a8e686 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/leds.h> | 32 | #include <linux/leds.h> |
33 | #include <linux/pm.h> | ||
33 | #include <linux/i2c/lm8323.h> | 34 | #include <linux/i2c/lm8323.h> |
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | 36 | ||
@@ -802,12 +803,13 @@ static int __devexit lm8323_remove(struct i2c_client *client) | |||
802 | * We don't need to explicitly suspend the chip, as it already switches off | 803 | * We don't need to explicitly suspend the chip, as it already switches off |
803 | * when there's no activity. | 804 | * when there's no activity. |
804 | */ | 805 | */ |
805 | static int lm8323_suspend(struct i2c_client *client, pm_message_t mesg) | 806 | static int lm8323_suspend(struct device *dev) |
806 | { | 807 | { |
808 | struct i2c_client *client = to_i2c_client(dev); | ||
807 | struct lm8323_chip *lm = i2c_get_clientdata(client); | 809 | struct lm8323_chip *lm = i2c_get_clientdata(client); |
808 | int i; | 810 | int i; |
809 | 811 | ||
810 | set_irq_wake(client->irq, 0); | 812 | irq_set_irq_wake(client->irq, 0); |
811 | disable_irq(client->irq); | 813 | disable_irq(client->irq); |
812 | 814 | ||
813 | mutex_lock(&lm->lock); | 815 | mutex_lock(&lm->lock); |
@@ -821,8 +823,9 @@ static int lm8323_suspend(struct i2c_client *client, pm_message_t mesg) | |||
821 | return 0; | 823 | return 0; |
822 | } | 824 | } |
823 | 825 | ||
824 | static int lm8323_resume(struct i2c_client *client) | 826 | static int lm8323_resume(struct device *dev) |
825 | { | 827 | { |
828 | struct i2c_client *client = to_i2c_client(dev); | ||
826 | struct lm8323_chip *lm = i2c_get_clientdata(client); | 829 | struct lm8323_chip *lm = i2c_get_clientdata(client); |
827 | int i; | 830 | int i; |
828 | 831 | ||
@@ -835,15 +838,14 @@ static int lm8323_resume(struct i2c_client *client) | |||
835 | led_classdev_resume(&lm->pwm[i].cdev); | 838 | led_classdev_resume(&lm->pwm[i].cdev); |
836 | 839 | ||
837 | enable_irq(client->irq); | 840 | enable_irq(client->irq); |
838 | set_irq_wake(client->irq, 1); | 841 | irq_set_irq_wake(client->irq, 1); |
839 | 842 | ||
840 | return 0; | 843 | return 0; |
841 | } | 844 | } |
842 | #else | ||
843 | #define lm8323_suspend NULL | ||
844 | #define lm8323_resume NULL | ||
845 | #endif | 845 | #endif |
846 | 846 | ||
847 | static SIMPLE_DEV_PM_OPS(lm8323_pm_ops, lm8323_suspend, lm8323_resume); | ||
848 | |||
847 | static const struct i2c_device_id lm8323_id[] = { | 849 | static const struct i2c_device_id lm8323_id[] = { |
848 | { "lm8323", 0 }, | 850 | { "lm8323", 0 }, |
849 | { } | 851 | { } |
@@ -852,11 +854,10 @@ static const struct i2c_device_id lm8323_id[] = { | |||
852 | static struct i2c_driver lm8323_i2c_driver = { | 854 | static struct i2c_driver lm8323_i2c_driver = { |
853 | .driver = { | 855 | .driver = { |
854 | .name = "lm8323", | 856 | .name = "lm8323", |
857 | .pm = &lm8323_pm_ops, | ||
855 | }, | 858 | }, |
856 | .probe = lm8323_probe, | 859 | .probe = lm8323_probe, |
857 | .remove = __devexit_p(lm8323_remove), | 860 | .remove = __devexit_p(lm8323_remove), |
858 | .suspend = lm8323_suspend, | ||
859 | .resume = lm8323_resume, | ||
860 | .id_table = lm8323_id, | 861 | .id_table = lm8323_id, |
861 | }; | 862 | }; |
862 | MODULE_DEVICE_TABLE(i2c, lm8323_id); | 863 | MODULE_DEVICE_TABLE(i2c, lm8323_id); |
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 9091ff5ea808..5afe35ad24d3 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/pm.h> | ||
20 | #include <linux/input.h> | 21 | #include <linux/input.h> |
21 | #include <linux/input/matrix_keypad.h> | 22 | #include <linux/input/matrix_keypad.h> |
22 | 23 | ||
@@ -271,8 +272,10 @@ static int __devexit max7359_remove(struct i2c_client *client) | |||
271 | } | 272 | } |
272 | 273 | ||
273 | #ifdef CONFIG_PM | 274 | #ifdef CONFIG_PM |
274 | static int max7359_suspend(struct i2c_client *client, pm_message_t mesg) | 275 | static int max7359_suspend(struct device *dev) |
275 | { | 276 | { |
277 | struct i2c_client *client = to_i2c_client(dev); | ||
278 | |||
276 | max7359_fall_deepsleep(client); | 279 | max7359_fall_deepsleep(client); |
277 | 280 | ||
278 | if (device_may_wakeup(&client->dev)) | 281 | if (device_may_wakeup(&client->dev)) |
@@ -281,8 +284,10 @@ static int max7359_suspend(struct i2c_client *client, pm_message_t mesg) | |||
281 | return 0; | 284 | return 0; |
282 | } | 285 | } |
283 | 286 | ||
284 | static int max7359_resume(struct i2c_client *client) | 287 | static int max7359_resume(struct device *dev) |
285 | { | 288 | { |
289 | struct i2c_client *client = to_i2c_client(dev); | ||
290 | |||
286 | if (device_may_wakeup(&client->dev)) | 291 | if (device_may_wakeup(&client->dev)) |
287 | disable_irq_wake(client->irq); | 292 | disable_irq_wake(client->irq); |
288 | 293 | ||
@@ -291,11 +296,10 @@ static int max7359_resume(struct i2c_client *client) | |||
291 | 296 | ||
292 | return 0; | 297 | return 0; |
293 | } | 298 | } |
294 | #else | ||
295 | #define max7359_suspend NULL | ||
296 | #define max7359_resume NULL | ||
297 | #endif | 299 | #endif |
298 | 300 | ||
301 | static SIMPLE_DEV_PM_OPS(max7359_pm, max7359_suspend, max7359_resume); | ||
302 | |||
299 | static const struct i2c_device_id max7359_ids[] = { | 303 | static const struct i2c_device_id max7359_ids[] = { |
300 | { "max7359", 0 }, | 304 | { "max7359", 0 }, |
301 | { } | 305 | { } |
@@ -305,11 +309,10 @@ MODULE_DEVICE_TABLE(i2c, max7359_ids); | |||
305 | static struct i2c_driver max7359_i2c_driver = { | 309 | static struct i2c_driver max7359_i2c_driver = { |
306 | .driver = { | 310 | .driver = { |
307 | .name = "max7359", | 311 | .name = "max7359", |
312 | .pm = &max7359_pm, | ||
308 | }, | 313 | }, |
309 | .probe = max7359_probe, | 314 | .probe = max7359_probe, |
310 | .remove = __devexit_p(max7359_remove), | 315 | .remove = __devexit_p(max7359_remove), |
311 | .suspend = max7359_suspend, | ||
312 | .resume = max7359_resume, | ||
313 | .id_table = max7359_ids, | 316 | .id_table = max7359_ids, |
314 | }; | 317 | }; |
315 | 318 | ||
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 63b849d7e90b..af1aab324a4c 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * mcs_touchkey.c - Touchkey driver for MELFAS MCS5000/5080 controller | 2 | * Touchkey driver for MELFAS MCS5000/5080 controller |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | 4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd |
5 | * Author: HeungJun Kim <riverful.kim@samsung.com> | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/pm.h> | ||
22 | 23 | ||
23 | /* MCS5000 Touchkey */ | 24 | /* MCS5000 Touchkey */ |
24 | #define MCS5000_TOUCHKEY_STATUS 0x04 | 25 | #define MCS5000_TOUCHKEY_STATUS 0x04 |
@@ -45,6 +46,8 @@ struct mcs_touchkey_chip { | |||
45 | }; | 46 | }; |
46 | 47 | ||
47 | struct mcs_touchkey_data { | 48 | struct mcs_touchkey_data { |
49 | void (*poweron)(bool); | ||
50 | |||
48 | struct i2c_client *client; | 51 | struct i2c_client *client; |
49 | struct input_dev *input_dev; | 52 | struct input_dev *input_dev; |
50 | struct mcs_touchkey_chip chip; | 53 | struct mcs_touchkey_chip chip; |
@@ -169,6 +172,11 @@ static int __devinit mcs_touchkey_probe(struct i2c_client *client, | |||
169 | if (pdata->cfg_pin) | 172 | if (pdata->cfg_pin) |
170 | pdata->cfg_pin(); | 173 | pdata->cfg_pin(); |
171 | 174 | ||
175 | if (pdata->poweron) { | ||
176 | data->poweron = pdata->poweron; | ||
177 | data->poweron(true); | ||
178 | } | ||
179 | |||
172 | error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, | 180 | error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, |
173 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); | 181 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); |
174 | if (error) { | 182 | if (error) { |
@@ -196,12 +204,57 @@ static int __devexit mcs_touchkey_remove(struct i2c_client *client) | |||
196 | struct mcs_touchkey_data *data = i2c_get_clientdata(client); | 204 | struct mcs_touchkey_data *data = i2c_get_clientdata(client); |
197 | 205 | ||
198 | free_irq(client->irq, data); | 206 | free_irq(client->irq, data); |
207 | if (data->poweron) | ||
208 | data->poweron(false); | ||
199 | input_unregister_device(data->input_dev); | 209 | input_unregister_device(data->input_dev); |
200 | kfree(data); | 210 | kfree(data); |
201 | 211 | ||
202 | return 0; | 212 | return 0; |
203 | } | 213 | } |
204 | 214 | ||
215 | static void mcs_touchkey_shutdown(struct i2c_client *client) | ||
216 | { | ||
217 | struct mcs_touchkey_data *data = i2c_get_clientdata(client); | ||
218 | |||
219 | if (data->poweron) | ||
220 | data->poweron(false); | ||
221 | } | ||
222 | |||
223 | #ifdef CONFIG_PM_SLEEP | ||
224 | static int mcs_touchkey_suspend(struct device *dev) | ||
225 | { | ||
226 | struct mcs_touchkey_data *data = dev_get_drvdata(dev); | ||
227 | struct i2c_client *client = data->client; | ||
228 | |||
229 | /* Disable the work */ | ||
230 | disable_irq(client->irq); | ||
231 | |||
232 | /* Finally turn off the power */ | ||
233 | if (data->poweron) | ||
234 | data->poweron(false); | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int mcs_touchkey_resume(struct device *dev) | ||
240 | { | ||
241 | struct mcs_touchkey_data *data = dev_get_drvdata(dev); | ||
242 | struct i2c_client *client = data->client; | ||
243 | |||
244 | /* Enable the device first */ | ||
245 | if (data->poweron) | ||
246 | data->poweron(true); | ||
247 | |||
248 | /* Enable irq again */ | ||
249 | enable_irq(client->irq); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | #endif | ||
254 | |||
255 | static SIMPLE_DEV_PM_OPS(mcs_touchkey_pm_ops, | ||
256 | mcs_touchkey_suspend, mcs_touchkey_resume); | ||
257 | |||
205 | static const struct i2c_device_id mcs_touchkey_id[] = { | 258 | static const struct i2c_device_id mcs_touchkey_id[] = { |
206 | { "mcs5000_touchkey", MCS5000_TOUCHKEY }, | 259 | { "mcs5000_touchkey", MCS5000_TOUCHKEY }, |
207 | { "mcs5080_touchkey", MCS5080_TOUCHKEY }, | 260 | { "mcs5080_touchkey", MCS5080_TOUCHKEY }, |
@@ -213,9 +266,11 @@ static struct i2c_driver mcs_touchkey_driver = { | |||
213 | .driver = { | 266 | .driver = { |
214 | .name = "mcs_touchkey", | 267 | .name = "mcs_touchkey", |
215 | .owner = THIS_MODULE, | 268 | .owner = THIS_MODULE, |
269 | .pm = &mcs_touchkey_pm_ops, | ||
216 | }, | 270 | }, |
217 | .probe = mcs_touchkey_probe, | 271 | .probe = mcs_touchkey_probe, |
218 | .remove = __devexit_p(mcs_touchkey_remove), | 272 | .remove = __devexit_p(mcs_touchkey_remove), |
273 | .shutdown = mcs_touchkey_shutdown, | ||
219 | .id_table = mcs_touchkey_id, | 274 | .id_table = mcs_touchkey_id, |
220 | }; | 275 | }; |
221 | 276 | ||
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c new file mode 100644 index 000000000000..0a9e81194888 --- /dev/null +++ b/drivers/input/keyboard/mpr121_touchkey.c | |||
@@ -0,0 +1,339 @@ | |||
1 | /* | ||
2 | * Touchkey driver for Freescale MPR121 Controllor | ||
3 | * | ||
4 | * Copyright (C) 2011 Freescale Semiconductor, Inc. | ||
5 | * Author: Zhang Jiejing <jiejing.zhang@freescale.com> | ||
6 | * | ||
7 | * Based on mcs_touchkey.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/bitops.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/i2c/mpr121_touchkey.h> | ||
24 | |||
25 | /* Register definitions */ | ||
26 | #define ELE_TOUCH_STATUS_0_ADDR 0x0 | ||
27 | #define ELE_TOUCH_STATUS_1_ADDR 0X1 | ||
28 | #define MHD_RISING_ADDR 0x2b | ||
29 | #define NHD_RISING_ADDR 0x2c | ||
30 | #define NCL_RISING_ADDR 0x2d | ||
31 | #define FDL_RISING_ADDR 0x2e | ||
32 | #define MHD_FALLING_ADDR 0x2f | ||
33 | #define NHD_FALLING_ADDR 0x30 | ||
34 | #define NCL_FALLING_ADDR 0x31 | ||
35 | #define FDL_FALLING_ADDR 0x32 | ||
36 | #define ELE0_TOUCH_THRESHOLD_ADDR 0x41 | ||
37 | #define ELE0_RELEASE_THRESHOLD_ADDR 0x42 | ||
38 | #define AFE_CONF_ADDR 0x5c | ||
39 | #define FILTER_CONF_ADDR 0x5d | ||
40 | |||
41 | /* | ||
42 | * ELECTRODE_CONF_ADDR: This register configures the number of | ||
43 | * enabled capacitance sensing inputs and its run/suspend mode. | ||
44 | */ | ||
45 | #define ELECTRODE_CONF_ADDR 0x5e | ||
46 | #define AUTO_CONFIG_CTRL_ADDR 0x7b | ||
47 | #define AUTO_CONFIG_USL_ADDR 0x7d | ||
48 | #define AUTO_CONFIG_LSL_ADDR 0x7e | ||
49 | #define AUTO_CONFIG_TL_ADDR 0x7f | ||
50 | |||
51 | /* Threshold of touch/release trigger */ | ||
52 | #define TOUCH_THRESHOLD 0x0f | ||
53 | #define RELEASE_THRESHOLD 0x0a | ||
54 | /* Masks for touch and release triggers */ | ||
55 | #define TOUCH_STATUS_MASK 0xfff | ||
56 | /* MPR121 has 12 keys */ | ||
57 | #define MPR121_MAX_KEY_COUNT 12 | ||
58 | |||
59 | struct mpr121_touchkey { | ||
60 | struct i2c_client *client; | ||
61 | struct input_dev *input_dev; | ||
62 | unsigned int key_val; | ||
63 | unsigned int statusbits; | ||
64 | unsigned int keycount; | ||
65 | u16 keycodes[MPR121_MAX_KEY_COUNT]; | ||
66 | }; | ||
67 | |||
68 | struct mpr121_init_register { | ||
69 | int addr; | ||
70 | u8 val; | ||
71 | }; | ||
72 | |||
73 | static const struct mpr121_init_register init_reg_table[] __devinitconst = { | ||
74 | { MHD_RISING_ADDR, 0x1 }, | ||
75 | { NHD_RISING_ADDR, 0x1 }, | ||
76 | { MHD_FALLING_ADDR, 0x1 }, | ||
77 | { NHD_FALLING_ADDR, 0x1 }, | ||
78 | { NCL_FALLING_ADDR, 0xff }, | ||
79 | { FDL_FALLING_ADDR, 0x02 }, | ||
80 | { FILTER_CONF_ADDR, 0x04 }, | ||
81 | { AFE_CONF_ADDR, 0x0b }, | ||
82 | { AUTO_CONFIG_CTRL_ADDR, 0x0b }, | ||
83 | }; | ||
84 | |||
85 | static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) | ||
86 | { | ||
87 | struct mpr121_touchkey *mpr121 = dev_id; | ||
88 | struct i2c_client *client = mpr121->client; | ||
89 | struct input_dev *input = mpr121->input_dev; | ||
90 | unsigned int key_num, key_val, pressed; | ||
91 | int reg; | ||
92 | |||
93 | reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR); | ||
94 | if (reg < 0) { | ||
95 | dev_err(&client->dev, "i2c read error [%d]\n", reg); | ||
96 | goto out; | ||
97 | } | ||
98 | |||
99 | reg <<= 8; | ||
100 | reg |= i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_0_ADDR); | ||
101 | if (reg < 0) { | ||
102 | dev_err(&client->dev, "i2c read error [%d]\n", reg); | ||
103 | goto out; | ||
104 | } | ||
105 | |||
106 | reg &= TOUCH_STATUS_MASK; | ||
107 | /* use old press bit to figure out which bit changed */ | ||
108 | key_num = ffs(reg ^ mpr121->statusbits) - 1; | ||
109 | pressed = reg & (1 << key_num); | ||
110 | mpr121->statusbits = reg; | ||
111 | |||
112 | key_val = mpr121->keycodes[key_num]; | ||
113 | |||
114 | input_event(input, EV_MSC, MSC_SCAN, key_num); | ||
115 | input_report_key(input, key_val, pressed); | ||
116 | input_sync(input); | ||
117 | |||
118 | dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val, | ||
119 | pressed ? "pressed" : "released"); | ||
120 | |||
121 | out: | ||
122 | return IRQ_HANDLED; | ||
123 | } | ||
124 | |||
125 | static int __devinit mpr121_phys_init(const struct mpr121_platform_data *pdata, | ||
126 | struct mpr121_touchkey *mpr121, | ||
127 | struct i2c_client *client) | ||
128 | { | ||
129 | const struct mpr121_init_register *reg; | ||
130 | unsigned char usl, lsl, tl; | ||
131 | int i, t, vdd, ret; | ||
132 | |||
133 | /* Set up touch/release threshold for ele0-ele11 */ | ||
134 | for (i = 0; i <= MPR121_MAX_KEY_COUNT; i++) { | ||
135 | t = ELE0_TOUCH_THRESHOLD_ADDR + (i * 2); | ||
136 | ret = i2c_smbus_write_byte_data(client, t, TOUCH_THRESHOLD); | ||
137 | if (ret < 0) | ||
138 | goto err_i2c_write; | ||
139 | ret = i2c_smbus_write_byte_data(client, t + 1, | ||
140 | RELEASE_THRESHOLD); | ||
141 | if (ret < 0) | ||
142 | goto err_i2c_write; | ||
143 | } | ||
144 | |||
145 | /* Set up init register */ | ||
146 | for (i = 0; i < ARRAY_SIZE(init_reg_table); i++) { | ||
147 | reg = &init_reg_table[i]; | ||
148 | ret = i2c_smbus_write_byte_data(client, reg->addr, reg->val); | ||
149 | if (ret < 0) | ||
150 | goto err_i2c_write; | ||
151 | } | ||
152 | |||
153 | |||
154 | /* | ||
155 | * Capacitance on sensing input varies and needs to be compensated. | ||
156 | * The internal MPR121-auto-configuration can do this if it's | ||
157 | * registers are set properly (based on pdata->vdd_uv). | ||
158 | */ | ||
159 | vdd = pdata->vdd_uv / 1000; | ||
160 | usl = ((vdd - 700) * 256) / vdd; | ||
161 | lsl = (usl * 65) / 100; | ||
162 | tl = (usl * 90) / 100; | ||
163 | ret = i2c_smbus_write_byte_data(client, AUTO_CONFIG_USL_ADDR, usl); | ||
164 | ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_LSL_ADDR, lsl); | ||
165 | ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_TL_ADDR, tl); | ||
166 | ret |= i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, | ||
167 | mpr121->keycount); | ||
168 | if (ret != 0) | ||
169 | goto err_i2c_write; | ||
170 | |||
171 | dev_dbg(&client->dev, "set up with %x keys.\n", mpr121->keycount); | ||
172 | |||
173 | return 0; | ||
174 | |||
175 | err_i2c_write: | ||
176 | dev_err(&client->dev, "i2c write error: %d\n", ret); | ||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | static int __devinit mpr_touchkey_probe(struct i2c_client *client, | ||
181 | const struct i2c_device_id *id) | ||
182 | { | ||
183 | const struct mpr121_platform_data *pdata = client->dev.platform_data; | ||
184 | struct mpr121_touchkey *mpr121; | ||
185 | struct input_dev *input_dev; | ||
186 | int error; | ||
187 | int i; | ||
188 | |||
189 | if (!pdata) { | ||
190 | dev_err(&client->dev, "no platform data defined\n"); | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | if (!pdata->keymap || !pdata->keymap_size) { | ||
195 | dev_err(&client->dev, "missing keymap data\n"); | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | |||
199 | if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) { | ||
200 | dev_err(&client->dev, "too many keys defined\n"); | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | |||
204 | if (!client->irq) { | ||
205 | dev_err(&client->dev, "irq number should not be zero\n"); | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | |||
209 | mpr121 = kzalloc(sizeof(struct mpr121_touchkey), GFP_KERNEL); | ||
210 | input_dev = input_allocate_device(); | ||
211 | if (!mpr121 || !input_dev) { | ||
212 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
213 | error = -ENOMEM; | ||
214 | goto err_free_mem; | ||
215 | } | ||
216 | |||
217 | mpr121->client = client; | ||
218 | mpr121->input_dev = input_dev; | ||
219 | mpr121->keycount = pdata->keymap_size; | ||
220 | |||
221 | input_dev->name = "Freescale MPR121 Touchkey"; | ||
222 | input_dev->id.bustype = BUS_I2C; | ||
223 | input_dev->dev.parent = &client->dev; | ||
224 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
225 | |||
226 | input_dev->keycode = mpr121->keycodes; | ||
227 | input_dev->keycodesize = sizeof(mpr121->keycodes[0]); | ||
228 | input_dev->keycodemax = mpr121->keycount; | ||
229 | |||
230 | for (i = 0; i < pdata->keymap_size; i++) { | ||
231 | input_set_capability(input_dev, EV_KEY, pdata->keymap[i]); | ||
232 | mpr121->keycodes[i] = pdata->keymap[i]; | ||
233 | } | ||
234 | |||
235 | error = mpr121_phys_init(pdata, mpr121, client); | ||
236 | if (error) { | ||
237 | dev_err(&client->dev, "Failed to init register\n"); | ||
238 | goto err_free_mem; | ||
239 | } | ||
240 | |||
241 | error = request_threaded_irq(client->irq, NULL, | ||
242 | mpr_touchkey_interrupt, | ||
243 | IRQF_TRIGGER_FALLING, | ||
244 | client->dev.driver->name, mpr121); | ||
245 | if (error) { | ||
246 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
247 | goto err_free_mem; | ||
248 | } | ||
249 | |||
250 | error = input_register_device(input_dev); | ||
251 | if (error) | ||
252 | goto err_free_irq; | ||
253 | |||
254 | i2c_set_clientdata(client, mpr121); | ||
255 | device_init_wakeup(&client->dev, pdata->wakeup); | ||
256 | |||
257 | return 0; | ||
258 | |||
259 | err_free_irq: | ||
260 | free_irq(client->irq, mpr121); | ||
261 | err_free_mem: | ||
262 | input_free_device(input_dev); | ||
263 | kfree(mpr121); | ||
264 | return error; | ||
265 | } | ||
266 | |||
267 | static int __devexit mpr_touchkey_remove(struct i2c_client *client) | ||
268 | { | ||
269 | struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); | ||
270 | |||
271 | free_irq(client->irq, mpr121); | ||
272 | input_unregister_device(mpr121->input_dev); | ||
273 | kfree(mpr121); | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | #ifdef CONFIG_PM_SLEEP | ||
279 | static int mpr_suspend(struct device *dev) | ||
280 | { | ||
281 | struct i2c_client *client = to_i2c_client(dev); | ||
282 | |||
283 | if (device_may_wakeup(&client->dev)) | ||
284 | enable_irq_wake(client->irq); | ||
285 | |||
286 | i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, 0x00); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int mpr_resume(struct device *dev) | ||
292 | { | ||
293 | struct i2c_client *client = to_i2c_client(dev); | ||
294 | struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); | ||
295 | |||
296 | if (device_may_wakeup(&client->dev)) | ||
297 | disable_irq_wake(client->irq); | ||
298 | |||
299 | i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, | ||
300 | mpr121->keycount); | ||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | #endif | ||
305 | |||
306 | static SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume); | ||
307 | |||
308 | static const struct i2c_device_id mpr121_id[] = { | ||
309 | { "mpr121_touchkey", 0 }, | ||
310 | { } | ||
311 | }; | ||
312 | MODULE_DEVICE_TABLE(i2c, mpr121_id); | ||
313 | |||
314 | static struct i2c_driver mpr_touchkey_driver = { | ||
315 | .driver = { | ||
316 | .name = "mpr121", | ||
317 | .owner = THIS_MODULE, | ||
318 | .pm = &mpr121_touchkey_pm_ops, | ||
319 | }, | ||
320 | .id_table = mpr121_id, | ||
321 | .probe = mpr_touchkey_probe, | ||
322 | .remove = __devexit_p(mpr_touchkey_remove), | ||
323 | }; | ||
324 | |||
325 | static int __init mpr_touchkey_init(void) | ||
326 | { | ||
327 | return i2c_add_driver(&mpr_touchkey_driver); | ||
328 | } | ||
329 | module_init(mpr_touchkey_init); | ||
330 | |||
331 | static void __exit mpr_touchkey_exit(void) | ||
332 | { | ||
333 | i2c_del_driver(&mpr_touchkey_driver); | ||
334 | } | ||
335 | module_exit(mpr_touchkey_exit); | ||
336 | |||
337 | MODULE_LICENSE("GPL"); | ||
338 | MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>"); | ||
339 | MODULE_DESCRIPTION("Touch Key driver for Freescale MPR121 Chip"); | ||
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c new file mode 100644 index 000000000000..6e0f23091360 --- /dev/null +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
6 | * | ||
7 | * License terms:GNU General Public License (GPL) version 2 | ||
8 | * | ||
9 | * Keypad controller driver for the SKE (Scroll Key Encoder) module used in | ||
10 | * the Nomadik 8815 and Ux500 platforms. | ||
11 | */ | ||
12 | |||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/clk.h> | ||
21 | |||
22 | #include <plat/ske.h> | ||
23 | |||
24 | /* SKE_CR bits */ | ||
25 | #define SKE_KPMLT (0x1 << 6) | ||
26 | #define SKE_KPCN (0x7 << 3) | ||
27 | #define SKE_KPASEN (0x1 << 2) | ||
28 | #define SKE_KPASON (0x1 << 7) | ||
29 | |||
30 | /* SKE_IMSC bits */ | ||
31 | #define SKE_KPIMA (0x1 << 2) | ||
32 | |||
33 | /* SKE_ICR bits */ | ||
34 | #define SKE_KPICS (0x1 << 3) | ||
35 | #define SKE_KPICA (0x1 << 2) | ||
36 | |||
37 | /* SKE_RIS bits */ | ||
38 | #define SKE_KPRISA (0x1 << 2) | ||
39 | |||
40 | #define SKE_KEYPAD_ROW_SHIFT 3 | ||
41 | #define SKE_KPD_KEYMAP_SIZE (8 * 8) | ||
42 | |||
43 | /* keypad auto scan registers */ | ||
44 | #define SKE_ASR0 0x20 | ||
45 | #define SKE_ASR1 0x24 | ||
46 | #define SKE_ASR2 0x28 | ||
47 | #define SKE_ASR3 0x2C | ||
48 | |||
49 | #define SKE_NUM_ASRX_REGISTERS (4) | ||
50 | |||
51 | /** | ||
52 | * struct ske_keypad - data structure used by keypad driver | ||
53 | * @irq: irq no | ||
54 | * @reg_base: ske regsiters base address | ||
55 | * @input: pointer to input device object | ||
56 | * @board: keypad platform device | ||
57 | * @keymap: matrix scan code table for keycodes | ||
58 | * @clk: clock structure pointer | ||
59 | */ | ||
60 | struct ske_keypad { | ||
61 | int irq; | ||
62 | void __iomem *reg_base; | ||
63 | struct input_dev *input; | ||
64 | const struct ske_keypad_platform_data *board; | ||
65 | unsigned short keymap[SKE_KPD_KEYMAP_SIZE]; | ||
66 | struct clk *clk; | ||
67 | spinlock_t ske_keypad_lock; | ||
68 | }; | ||
69 | |||
70 | static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr, | ||
71 | u8 mask, u8 data) | ||
72 | { | ||
73 | u32 ret; | ||
74 | |||
75 | spin_lock(&keypad->ske_keypad_lock); | ||
76 | |||
77 | ret = readl(keypad->reg_base + addr); | ||
78 | ret &= ~mask; | ||
79 | ret |= data; | ||
80 | writel(ret, keypad->reg_base + addr); | ||
81 | |||
82 | spin_unlock(&keypad->ske_keypad_lock); | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * ske_keypad_chip_init: init keypad controller configuration | ||
87 | * | ||
88 | * Enable Multi key press detection, auto scan mode | ||
89 | */ | ||
90 | static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad) | ||
91 | { | ||
92 | u32 value; | ||
93 | int timeout = 50; | ||
94 | |||
95 | /* check SKE_RIS to be 0 */ | ||
96 | while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--) | ||
97 | cpu_relax(); | ||
98 | |||
99 | if (!timeout) | ||
100 | return -EINVAL; | ||
101 | |||
102 | /* | ||
103 | * set debounce value | ||
104 | * keypad dbounce is configured in DBCR[15:8] | ||
105 | * dbounce value in steps of 32/32.768 ms | ||
106 | */ | ||
107 | spin_lock(&keypad->ske_keypad_lock); | ||
108 | value = readl(keypad->reg_base + SKE_DBCR); | ||
109 | value = value & 0xff; | ||
110 | value |= ((keypad->board->debounce_ms * 32000)/32768) << 8; | ||
111 | writel(value, keypad->reg_base + SKE_DBCR); | ||
112 | spin_unlock(&keypad->ske_keypad_lock); | ||
113 | |||
114 | /* enable multi key detection */ | ||
115 | ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPMLT); | ||
116 | |||
117 | /* | ||
118 | * set up the number of columns | ||
119 | * KPCN[5:3] defines no. of keypad columns to be auto scanned | ||
120 | */ | ||
121 | value = (keypad->board->kcol - 1) << 3; | ||
122 | ske_keypad_set_bits(keypad, SKE_CR, SKE_KPCN, value); | ||
123 | |||
124 | /* clear keypad interrupt for auto(and pending SW) scans */ | ||
125 | ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA | SKE_KPICS); | ||
126 | |||
127 | /* un-mask keypad interrupts */ | ||
128 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
129 | |||
130 | /* enable automatic scan */ | ||
131 | ske_keypad_set_bits(keypad, SKE_CR, 0x0, SKE_KPASEN); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static void ske_keypad_read_data(struct ske_keypad *keypad) | ||
137 | { | ||
138 | struct input_dev *input = keypad->input; | ||
139 | u16 status; | ||
140 | int col = 0, row = 0, code; | ||
141 | int ske_asr, ske_ris, key_pressed, i; | ||
142 | |||
143 | /* | ||
144 | * Read the auto scan registers | ||
145 | * | ||
146 | * Each SKE_ASRx (x=0 to x=3) contains two row values. | ||
147 | * lower byte contains row value for column 2*x, | ||
148 | * upper byte contains row value for column 2*x + 1 | ||
149 | */ | ||
150 | for (i = 0; i < SKE_NUM_ASRX_REGISTERS; i++) { | ||
151 | ske_asr = readl(keypad->reg_base + SKE_ASR0 + (4 * i)); | ||
152 | if (!ske_asr) | ||
153 | continue; | ||
154 | |||
155 | /* now that ASRx is zero, find out the column x and row y*/ | ||
156 | if (ske_asr & 0xff) { | ||
157 | col = i * 2; | ||
158 | status = ske_asr & 0xff; | ||
159 | } else { | ||
160 | col = (i * 2) + 1; | ||
161 | status = (ske_asr & 0xff00) >> 8; | ||
162 | } | ||
163 | |||
164 | /* find out the row */ | ||
165 | row = __ffs(status); | ||
166 | |||
167 | code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); | ||
168 | ske_ris = readl(keypad->reg_base + SKE_RIS); | ||
169 | key_pressed = ske_ris & SKE_KPRISA; | ||
170 | |||
171 | input_event(input, EV_MSC, MSC_SCAN, code); | ||
172 | input_report_key(input, keypad->keymap[code], key_pressed); | ||
173 | input_sync(input); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static irqreturn_t ske_keypad_irq(int irq, void *dev_id) | ||
178 | { | ||
179 | struct ske_keypad *keypad = dev_id; | ||
180 | int retries = 20; | ||
181 | |||
182 | /* disable auto scan interrupt; mask the interrupt generated */ | ||
183 | ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); | ||
184 | ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); | ||
185 | |||
186 | while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries) | ||
187 | msleep(5); | ||
188 | |||
189 | if (retries) { | ||
190 | /* SKEx registers are stable and can be read */ | ||
191 | ske_keypad_read_data(keypad); | ||
192 | } | ||
193 | |||
194 | /* enable auto scan interrupts */ | ||
195 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
196 | |||
197 | return IRQ_HANDLED; | ||
198 | } | ||
199 | |||
200 | static int __devinit ske_keypad_probe(struct platform_device *pdev) | ||
201 | { | ||
202 | const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; | ||
203 | struct ske_keypad *keypad; | ||
204 | struct input_dev *input; | ||
205 | struct resource *res; | ||
206 | int irq; | ||
207 | int error; | ||
208 | |||
209 | if (!plat) { | ||
210 | dev_err(&pdev->dev, "invalid keypad platform data\n"); | ||
211 | return -EINVAL; | ||
212 | } | ||
213 | |||
214 | irq = platform_get_irq(pdev, 0); | ||
215 | if (irq < 0) { | ||
216 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
221 | if (!res) { | ||
222 | dev_err(&pdev->dev, "missing platform resources\n"); | ||
223 | return -EINVAL; | ||
224 | } | ||
225 | |||
226 | keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL); | ||
227 | input = input_allocate_device(); | ||
228 | if (!keypad || !input) { | ||
229 | dev_err(&pdev->dev, "failed to allocate keypad memory\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | keypad->irq = irq; | ||
235 | keypad->board = plat; | ||
236 | keypad->input = input; | ||
237 | spin_lock_init(&keypad->ske_keypad_lock); | ||
238 | |||
239 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
240 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
241 | error = -EBUSY; | ||
242 | goto err_free_mem; | ||
243 | } | ||
244 | |||
245 | keypad->reg_base = ioremap(res->start, resource_size(res)); | ||
246 | if (!keypad->reg_base) { | ||
247 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
248 | error = -ENXIO; | ||
249 | goto err_free_mem_region; | ||
250 | } | ||
251 | |||
252 | keypad->clk = clk_get(&pdev->dev, NULL); | ||
253 | if (IS_ERR(keypad->clk)) { | ||
254 | dev_err(&pdev->dev, "failed to get clk\n"); | ||
255 | error = PTR_ERR(keypad->clk); | ||
256 | goto err_iounmap; | ||
257 | } | ||
258 | |||
259 | input->id.bustype = BUS_HOST; | ||
260 | input->name = "ux500-ske-keypad"; | ||
261 | input->dev.parent = &pdev->dev; | ||
262 | |||
263 | input->keycode = keypad->keymap; | ||
264 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
265 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
266 | |||
267 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
268 | |||
269 | __set_bit(EV_KEY, input->evbit); | ||
270 | if (!plat->no_autorepeat) | ||
271 | __set_bit(EV_REP, input->evbit); | ||
272 | |||
273 | matrix_keypad_build_keymap(plat->keymap_data, SKE_KEYPAD_ROW_SHIFT, | ||
274 | input->keycode, input->keybit); | ||
275 | |||
276 | clk_enable(keypad->clk); | ||
277 | |||
278 | /* go through board initialization helpers */ | ||
279 | if (keypad->board->init) | ||
280 | keypad->board->init(); | ||
281 | |||
282 | error = ske_keypad_chip_init(keypad); | ||
283 | if (error) { | ||
284 | dev_err(&pdev->dev, "unable to init keypad hardware\n"); | ||
285 | goto err_clk_disable; | ||
286 | } | ||
287 | |||
288 | error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq, | ||
289 | IRQF_ONESHOT, "ske-keypad", keypad); | ||
290 | if (error) { | ||
291 | dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq); | ||
292 | goto err_clk_disable; | ||
293 | } | ||
294 | |||
295 | error = input_register_device(input); | ||
296 | if (error) { | ||
297 | dev_err(&pdev->dev, | ||
298 | "unable to register input device: %d\n", error); | ||
299 | goto err_free_irq; | ||
300 | } | ||
301 | |||
302 | if (plat->wakeup_enable) | ||
303 | device_init_wakeup(&pdev->dev, true); | ||
304 | |||
305 | platform_set_drvdata(pdev, keypad); | ||
306 | |||
307 | return 0; | ||
308 | |||
309 | err_free_irq: | ||
310 | free_irq(keypad->irq, keypad); | ||
311 | err_clk_disable: | ||
312 | clk_disable(keypad->clk); | ||
313 | clk_put(keypad->clk); | ||
314 | err_iounmap: | ||
315 | iounmap(keypad->reg_base); | ||
316 | err_free_mem_region: | ||
317 | release_mem_region(res->start, resource_size(res)); | ||
318 | err_free_mem: | ||
319 | input_free_device(input); | ||
320 | kfree(keypad); | ||
321 | return error; | ||
322 | } | ||
323 | |||
324 | static int __devexit ske_keypad_remove(struct platform_device *pdev) | ||
325 | { | ||
326 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
327 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
328 | |||
329 | free_irq(keypad->irq, keypad); | ||
330 | |||
331 | input_unregister_device(keypad->input); | ||
332 | |||
333 | clk_disable(keypad->clk); | ||
334 | clk_put(keypad->clk); | ||
335 | |||
336 | if (keypad->board->exit) | ||
337 | keypad->board->exit(); | ||
338 | |||
339 | iounmap(keypad->reg_base); | ||
340 | release_mem_region(res->start, resource_size(res)); | ||
341 | kfree(keypad); | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | #ifdef CONFIG_PM | ||
347 | static int ske_keypad_suspend(struct device *dev) | ||
348 | { | ||
349 | struct platform_device *pdev = to_platform_device(dev); | ||
350 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
351 | int irq = platform_get_irq(pdev, 0); | ||
352 | |||
353 | if (device_may_wakeup(dev)) | ||
354 | enable_irq_wake(irq); | ||
355 | else | ||
356 | ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static int ske_keypad_resume(struct device *dev) | ||
362 | { | ||
363 | struct platform_device *pdev = to_platform_device(dev); | ||
364 | struct ske_keypad *keypad = platform_get_drvdata(pdev); | ||
365 | int irq = platform_get_irq(pdev, 0); | ||
366 | |||
367 | if (device_may_wakeup(dev)) | ||
368 | disable_irq_wake(irq); | ||
369 | else | ||
370 | ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA); | ||
371 | |||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static const struct dev_pm_ops ske_keypad_dev_pm_ops = { | ||
376 | .suspend = ske_keypad_suspend, | ||
377 | .resume = ske_keypad_resume, | ||
378 | }; | ||
379 | #endif | ||
380 | |||
381 | struct platform_driver ske_keypad_driver = { | ||
382 | .driver = { | ||
383 | .name = "nmk-ske-keypad", | ||
384 | .owner = THIS_MODULE, | ||
385 | #ifdef CONFIG_PM | ||
386 | .pm = &ske_keypad_dev_pm_ops, | ||
387 | #endif | ||
388 | }, | ||
389 | .probe = ske_keypad_probe, | ||
390 | .remove = __devexit_p(ske_keypad_remove), | ||
391 | }; | ||
392 | |||
393 | static int __init ske_keypad_init(void) | ||
394 | { | ||
395 | return platform_driver_probe(&ske_keypad_driver, ske_keypad_probe); | ||
396 | } | ||
397 | module_init(ske_keypad_init); | ||
398 | |||
399 | static void __exit ske_keypad_exit(void) | ||
400 | { | ||
401 | platform_driver_unregister(&ske_keypad_driver); | ||
402 | } | ||
403 | module_exit(ske_keypad_exit); | ||
404 | |||
405 | MODULE_LICENSE("GPL v2"); | ||
406 | MODULE_AUTHOR("Naveen Kumar <naveen.gaddipati@stericsson.com> / Sundar Iyer <sundar.iyer@stericsson.com>"); | ||
407 | MODULE_DESCRIPTION("Nomadik Scroll-Key-Encoder Keypad Driver"); | ||
408 | MODULE_ALIAS("platform:nomadik-ske-keypad"); | ||
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index a72e61ddca91..33d0bdc837c0 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -65,7 +65,6 @@ struct omap_kp { | |||
65 | 65 | ||
66 | static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); | 66 | static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); |
67 | 67 | ||
68 | static int *keymap; | ||
69 | static unsigned int *row_gpios; | 68 | static unsigned int *row_gpios; |
70 | static unsigned int *col_gpios; | 69 | static unsigned int *col_gpios; |
71 | 70 | ||
@@ -162,20 +161,11 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state) | |||
162 | } | 161 | } |
163 | } | 162 | } |
164 | 163 | ||
165 | static inline int omap_kp_find_key(int col, int row) | ||
166 | { | ||
167 | int i, key; | ||
168 | |||
169 | key = KEY(col, row, 0); | ||
170 | for (i = 0; keymap[i] != 0; i++) | ||
171 | if ((keymap[i] & 0xff000000) == key) | ||
172 | return keymap[i] & 0x00ffffff; | ||
173 | return -1; | ||
174 | } | ||
175 | |||
176 | static void omap_kp_tasklet(unsigned long data) | 164 | static void omap_kp_tasklet(unsigned long data) |
177 | { | 165 | { |
178 | struct omap_kp *omap_kp_data = (struct omap_kp *) data; | 166 | struct omap_kp *omap_kp_data = (struct omap_kp *) data; |
167 | unsigned short *keycodes = omap_kp_data->input->keycode; | ||
168 | unsigned int row_shift = get_count_order(omap_kp_data->cols); | ||
179 | unsigned char new_state[8], changed, key_down = 0; | 169 | unsigned char new_state[8], changed, key_down = 0; |
180 | int col, row; | 170 | int col, row; |
181 | int spurious = 0; | 171 | int spurious = 0; |
@@ -199,7 +189,7 @@ static void omap_kp_tasklet(unsigned long data) | |||
199 | row, (new_state[col] & (1 << row)) ? | 189 | row, (new_state[col] & (1 << row)) ? |
200 | "pressed" : "released"); | 190 | "pressed" : "released"); |
201 | #else | 191 | #else |
202 | key = omap_kp_find_key(col, row); | 192 | key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; |
203 | if (key < 0) { | 193 | if (key < 0) { |
204 | printk(KERN_WARNING | 194 | printk(KERN_WARNING |
205 | "omap-keypad: Spurious key event %d-%d\n", | 195 | "omap-keypad: Spurious key event %d-%d\n", |
@@ -219,6 +209,7 @@ static void omap_kp_tasklet(unsigned long data) | |||
219 | #endif | 209 | #endif |
220 | } | 210 | } |
221 | } | 211 | } |
212 | input_sync(omap_kp_data->input); | ||
222 | memcpy(keypad_state, new_state, sizeof(keypad_state)); | 213 | memcpy(keypad_state, new_state, sizeof(keypad_state)); |
223 | 214 | ||
224 | if (key_down) { | 215 | if (key_down) { |
@@ -298,13 +289,18 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
298 | struct input_dev *input_dev; | 289 | struct input_dev *input_dev; |
299 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; | 290 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; |
300 | int i, col_idx, row_idx, irq_idx, ret; | 291 | int i, col_idx, row_idx, irq_idx, ret; |
292 | unsigned int row_shift, keycodemax; | ||
301 | 293 | ||
302 | if (!pdata->rows || !pdata->cols || !pdata->keymap) { | 294 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { |
303 | printk(KERN_ERR "No rows, cols or keymap from pdata\n"); | 295 | printk(KERN_ERR "No rows, cols or keymap_data from pdata\n"); |
304 | return -EINVAL; | 296 | return -EINVAL; |
305 | } | 297 | } |
306 | 298 | ||
307 | omap_kp = kzalloc(sizeof(struct omap_kp), GFP_KERNEL); | 299 | row_shift = get_count_order(pdata->cols); |
300 | keycodemax = pdata->rows << row_shift; | ||
301 | |||
302 | omap_kp = kzalloc(sizeof(struct omap_kp) + | ||
303 | keycodemax * sizeof(unsigned short), GFP_KERNEL); | ||
308 | input_dev = input_allocate_device(); | 304 | input_dev = input_allocate_device(); |
309 | if (!omap_kp || !input_dev) { | 305 | if (!omap_kp || !input_dev) { |
310 | kfree(omap_kp); | 306 | kfree(omap_kp); |
@@ -320,7 +316,9 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
320 | if (!cpu_is_omap24xx()) | 316 | if (!cpu_is_omap24xx()) |
321 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | 317 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
322 | 318 | ||
323 | keymap = pdata->keymap; | 319 | input_dev->keycode = &omap_kp[1]; |
320 | input_dev->keycodesize = sizeof(unsigned short); | ||
321 | input_dev->keycodemax = keycodemax; | ||
324 | 322 | ||
325 | if (pdata->rep) | 323 | if (pdata->rep) |
326 | __set_bit(EV_REP, input_dev->evbit); | 324 | __set_bit(EV_REP, input_dev->evbit); |
@@ -374,8 +372,8 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
374 | 372 | ||
375 | /* setup input device */ | 373 | /* setup input device */ |
376 | __set_bit(EV_KEY, input_dev->evbit); | 374 | __set_bit(EV_KEY, input_dev->evbit); |
377 | for (i = 0; keymap[i] != 0; i++) | 375 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, |
378 | __set_bit(keymap[i] & KEY_MAX, input_dev->keybit); | 376 | input_dev->keycode, input_dev->keybit); |
379 | input_dev->name = "omap-keypad"; | 377 | input_dev->name = "omap-keypad"; |
380 | input_dev->phys = "omap-keypad/input0"; | 378 | input_dev->phys = "omap-keypad/input0"; |
381 | input_dev->dev.parent = &pdev->dev; | 379 | input_dev->dev.parent = &pdev->dev; |
@@ -416,7 +414,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
416 | return 0; | 414 | return 0; |
417 | err5: | 415 | err5: |
418 | for (i = irq_idx - 1; i >=0; i--) | 416 | for (i = irq_idx - 1; i >=0; i--) |
419 | free_irq(row_gpios[i], 0); | 417 | free_irq(row_gpios[i], omap_kp); |
420 | err4: | 418 | err4: |
421 | input_unregister_device(omap_kp->input); | 419 | input_unregister_device(omap_kp->input); |
422 | input_dev = NULL; | 420 | input_dev = NULL; |
@@ -447,11 +445,11 @@ static int __devexit omap_kp_remove(struct platform_device *pdev) | |||
447 | gpio_free(col_gpios[i]); | 445 | gpio_free(col_gpios[i]); |
448 | for (i = 0; i < omap_kp->rows; i++) { | 446 | for (i = 0; i < omap_kp->rows; i++) { |
449 | gpio_free(row_gpios[i]); | 447 | gpio_free(row_gpios[i]); |
450 | free_irq(gpio_to_irq(row_gpios[i]), 0); | 448 | free_irq(gpio_to_irq(row_gpios[i]), omap_kp); |
451 | } | 449 | } |
452 | } else { | 450 | } else { |
453 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | 451 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
454 | free_irq(omap_kp->irq, 0); | 452 | free_irq(omap_kp->irq, omap_kp); |
455 | } | 453 | } |
456 | 454 | ||
457 | del_timer_sync(&omap_kp->timer); | 455 | del_timer_sync(&omap_kp->timer); |
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c new file mode 100644 index 000000000000..c51a3c4a7feb --- /dev/null +++ b/drivers/input/keyboard/omap4-keypad.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* | ||
2 | * OMAP4 Keypad Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * Author: Abraham Arce <x0066660@ti.com> | ||
7 | * Initial Code: Syed Rafiuddin <rafiuddin.syed@ti.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/pm_runtime.h> | ||
33 | |||
34 | #include <plat/omap4-keypad.h> | ||
35 | |||
36 | /* OMAP4 registers */ | ||
37 | #define OMAP4_KBD_REVISION 0x00 | ||
38 | #define OMAP4_KBD_SYSCONFIG 0x10 | ||
39 | #define OMAP4_KBD_SYSSTATUS 0x14 | ||
40 | #define OMAP4_KBD_IRQSTATUS 0x18 | ||
41 | #define OMAP4_KBD_IRQENABLE 0x1C | ||
42 | #define OMAP4_KBD_WAKEUPENABLE 0x20 | ||
43 | #define OMAP4_KBD_PENDING 0x24 | ||
44 | #define OMAP4_KBD_CTRL 0x28 | ||
45 | #define OMAP4_KBD_DEBOUNCINGTIME 0x2C | ||
46 | #define OMAP4_KBD_LONGKEYTIME 0x30 | ||
47 | #define OMAP4_KBD_TIMEOUT 0x34 | ||
48 | #define OMAP4_KBD_STATEMACHINE 0x38 | ||
49 | #define OMAP4_KBD_ROWINPUTS 0x3C | ||
50 | #define OMAP4_KBD_COLUMNOUTPUTS 0x40 | ||
51 | #define OMAP4_KBD_FULLCODE31_0 0x44 | ||
52 | #define OMAP4_KBD_FULLCODE63_32 0x48 | ||
53 | |||
54 | /* OMAP4 bit definitions */ | ||
55 | #define OMAP4_DEF_IRQENABLE_EVENTEN (1 << 0) | ||
56 | #define OMAP4_DEF_IRQENABLE_LONGKEY (1 << 1) | ||
57 | #define OMAP4_DEF_IRQENABLE_TIMEOUTEN (1 << 2) | ||
58 | #define OMAP4_DEF_WUP_EVENT_ENA (1 << 0) | ||
59 | #define OMAP4_DEF_WUP_LONG_KEY_ENA (1 << 1) | ||
60 | #define OMAP4_DEF_CTRL_NOSOFTMODE (1 << 1) | ||
61 | #define OMAP4_DEF_CTRLPTVVALUE (1 << 2) | ||
62 | #define OMAP4_DEF_CTRLPTV (1 << 1) | ||
63 | |||
64 | /* OMAP4 values */ | ||
65 | #define OMAP4_VAL_IRQDISABLE 0x00 | ||
66 | #define OMAP4_VAL_DEBOUNCINGTIME 0x07 | ||
67 | #define OMAP4_VAL_FUNCTIONALCFG 0x1E | ||
68 | |||
69 | #define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF | ||
70 | |||
71 | struct omap4_keypad { | ||
72 | struct input_dev *input; | ||
73 | |||
74 | void __iomem *base; | ||
75 | int irq; | ||
76 | |||
77 | unsigned int rows; | ||
78 | unsigned int cols; | ||
79 | unsigned int row_shift; | ||
80 | unsigned char key_state[8]; | ||
81 | unsigned short keymap[]; | ||
82 | }; | ||
83 | |||
84 | /* Interrupt handler */ | ||
85 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | ||
86 | { | ||
87 | struct omap4_keypad *keypad_data = dev_id; | ||
88 | struct input_dev *input_dev = keypad_data->input; | ||
89 | unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)]; | ||
90 | unsigned int col, row, code, changed; | ||
91 | u32 *new_state = (u32 *) key_state; | ||
92 | |||
93 | /* Disable interrupts */ | ||
94 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
95 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
96 | |||
97 | *new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0); | ||
98 | *(new_state + 1) = __raw_readl(keypad_data->base | ||
99 | + OMAP4_KBD_FULLCODE63_32); | ||
100 | |||
101 | for (row = 0; row < keypad_data->rows; row++) { | ||
102 | changed = key_state[row] ^ keypad_data->key_state[row]; | ||
103 | if (!changed) | ||
104 | continue; | ||
105 | |||
106 | for (col = 0; col < keypad_data->cols; col++) { | ||
107 | if (changed & (1 << col)) { | ||
108 | code = MATRIX_SCAN_CODE(row, col, | ||
109 | keypad_data->row_shift); | ||
110 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
111 | input_report_key(input_dev, | ||
112 | keypad_data->keymap[code], | ||
113 | key_state[row] & (1 << col)); | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | |||
118 | input_sync(input_dev); | ||
119 | |||
120 | memcpy(keypad_data->key_state, key_state, | ||
121 | sizeof(keypad_data->key_state)); | ||
122 | |||
123 | /* clear pending interrupts */ | ||
124 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), | ||
125 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
126 | |||
127 | /* enable interrupts */ | ||
128 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | ||
129 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
130 | |||
131 | return IRQ_HANDLED; | ||
132 | } | ||
133 | |||
134 | static int omap4_keypad_open(struct input_dev *input) | ||
135 | { | ||
136 | struct omap4_keypad *keypad_data = input_get_drvdata(input); | ||
137 | |||
138 | pm_runtime_get_sync(input->dev.parent); | ||
139 | |||
140 | disable_irq(keypad_data->irq); | ||
141 | |||
142 | __raw_writel(OMAP4_VAL_FUNCTIONALCFG, | ||
143 | keypad_data->base + OMAP4_KBD_CTRL); | ||
144 | __raw_writel(OMAP4_VAL_DEBOUNCINGTIME, | ||
145 | keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME); | ||
146 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
147 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
148 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | ||
149 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
150 | __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA, | ||
151 | keypad_data->base + OMAP4_KBD_WAKEUPENABLE); | ||
152 | |||
153 | enable_irq(keypad_data->irq); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static void omap4_keypad_close(struct input_dev *input) | ||
159 | { | ||
160 | struct omap4_keypad *keypad_data = input_get_drvdata(input); | ||
161 | |||
162 | disable_irq(keypad_data->irq); | ||
163 | |||
164 | /* Disable interrupts */ | ||
165 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
166 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
167 | |||
168 | /* clear pending interrupts */ | ||
169 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), | ||
170 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
171 | |||
172 | enable_irq(keypad_data->irq); | ||
173 | |||
174 | pm_runtime_put_sync(input->dev.parent); | ||
175 | } | ||
176 | |||
177 | static int __devinit omap4_keypad_probe(struct platform_device *pdev) | ||
178 | { | ||
179 | const struct omap4_keypad_platform_data *pdata; | ||
180 | struct omap4_keypad *keypad_data; | ||
181 | struct input_dev *input_dev; | ||
182 | struct resource *res; | ||
183 | resource_size_t size; | ||
184 | unsigned int row_shift, max_keys; | ||
185 | int irq; | ||
186 | int error; | ||
187 | |||
188 | /* platform data */ | ||
189 | pdata = pdev->dev.platform_data; | ||
190 | if (!pdata) { | ||
191 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | |||
195 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
196 | if (!res) { | ||
197 | dev_err(&pdev->dev, "no base address specified\n"); | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | irq = platform_get_irq(pdev, 0); | ||
202 | if (!irq) { | ||
203 | dev_err(&pdev->dev, "no keyboard irq assigned\n"); | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | if (!pdata->keymap_data) { | ||
208 | dev_err(&pdev->dev, "no keymap data defined\n"); | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | |||
212 | row_shift = get_count_order(pdata->cols); | ||
213 | max_keys = pdata->rows << row_shift; | ||
214 | |||
215 | keypad_data = kzalloc(sizeof(struct omap4_keypad) + | ||
216 | max_keys * sizeof(keypad_data->keymap[0]), | ||
217 | GFP_KERNEL); | ||
218 | if (!keypad_data) { | ||
219 | dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); | ||
220 | return -ENOMEM; | ||
221 | } | ||
222 | |||
223 | size = resource_size(res); | ||
224 | |||
225 | res = request_mem_region(res->start, size, pdev->name); | ||
226 | if (!res) { | ||
227 | dev_err(&pdev->dev, "can't request mem region\n"); | ||
228 | error = -EBUSY; | ||
229 | goto err_free_keypad; | ||
230 | } | ||
231 | |||
232 | keypad_data->base = ioremap(res->start, resource_size(res)); | ||
233 | if (!keypad_data->base) { | ||
234 | dev_err(&pdev->dev, "can't ioremap mem resource\n"); | ||
235 | error = -ENOMEM; | ||
236 | goto err_release_mem; | ||
237 | } | ||
238 | |||
239 | keypad_data->irq = irq; | ||
240 | keypad_data->row_shift = row_shift; | ||
241 | keypad_data->rows = pdata->rows; | ||
242 | keypad_data->cols = pdata->cols; | ||
243 | |||
244 | /* input device allocation */ | ||
245 | keypad_data->input = input_dev = input_allocate_device(); | ||
246 | if (!input_dev) { | ||
247 | error = -ENOMEM; | ||
248 | goto err_unmap; | ||
249 | } | ||
250 | |||
251 | input_dev->name = pdev->name; | ||
252 | input_dev->dev.parent = &pdev->dev; | ||
253 | input_dev->id.bustype = BUS_HOST; | ||
254 | input_dev->id.vendor = 0x0001; | ||
255 | input_dev->id.product = 0x0001; | ||
256 | input_dev->id.version = 0x0001; | ||
257 | |||
258 | input_dev->open = omap4_keypad_open; | ||
259 | input_dev->close = omap4_keypad_close; | ||
260 | |||
261 | input_dev->keycode = keypad_data->keymap; | ||
262 | input_dev->keycodesize = sizeof(keypad_data->keymap[0]); | ||
263 | input_dev->keycodemax = max_keys; | ||
264 | |||
265 | __set_bit(EV_KEY, input_dev->evbit); | ||
266 | __set_bit(EV_REP, input_dev->evbit); | ||
267 | |||
268 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
269 | |||
270 | input_set_drvdata(input_dev, keypad_data); | ||
271 | |||
272 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, | ||
273 | input_dev->keycode, input_dev->keybit); | ||
274 | |||
275 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, | ||
276 | IRQF_TRIGGER_RISING, | ||
277 | "omap4-keypad", keypad_data); | ||
278 | if (error) { | ||
279 | dev_err(&pdev->dev, "failed to register interrupt\n"); | ||
280 | goto err_free_input; | ||
281 | } | ||
282 | |||
283 | pm_runtime_enable(&pdev->dev); | ||
284 | |||
285 | error = input_register_device(keypad_data->input); | ||
286 | if (error < 0) { | ||
287 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
288 | goto err_pm_disable; | ||
289 | } | ||
290 | |||
291 | platform_set_drvdata(pdev, keypad_data); | ||
292 | return 0; | ||
293 | |||
294 | err_pm_disable: | ||
295 | pm_runtime_disable(&pdev->dev); | ||
296 | free_irq(keypad_data->irq, keypad_data); | ||
297 | err_free_input: | ||
298 | input_free_device(input_dev); | ||
299 | err_unmap: | ||
300 | iounmap(keypad_data->base); | ||
301 | err_release_mem: | ||
302 | release_mem_region(res->start, size); | ||
303 | err_free_keypad: | ||
304 | kfree(keypad_data); | ||
305 | return error; | ||
306 | } | ||
307 | |||
308 | static int __devexit omap4_keypad_remove(struct platform_device *pdev) | ||
309 | { | ||
310 | struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); | ||
311 | struct resource *res; | ||
312 | |||
313 | free_irq(keypad_data->irq, keypad_data); | ||
314 | |||
315 | pm_runtime_disable(&pdev->dev); | ||
316 | |||
317 | input_unregister_device(keypad_data->input); | ||
318 | |||
319 | iounmap(keypad_data->base); | ||
320 | |||
321 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
322 | release_mem_region(res->start, resource_size(res)); | ||
323 | |||
324 | kfree(keypad_data); | ||
325 | platform_set_drvdata(pdev, NULL); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static struct platform_driver omap4_keypad_driver = { | ||
331 | .probe = omap4_keypad_probe, | ||
332 | .remove = __devexit_p(omap4_keypad_remove), | ||
333 | .driver = { | ||
334 | .name = "omap4-keypad", | ||
335 | .owner = THIS_MODULE, | ||
336 | }, | ||
337 | }; | ||
338 | |||
339 | static int __init omap4_keypad_init(void) | ||
340 | { | ||
341 | return platform_driver_register(&omap4_keypad_driver); | ||
342 | } | ||
343 | module_init(omap4_keypad_init); | ||
344 | |||
345 | static void __exit omap4_keypad_exit(void) | ||
346 | { | ||
347 | platform_driver_unregister(&omap4_keypad_driver); | ||
348 | } | ||
349 | module_exit(omap4_keypad_exit); | ||
350 | |||
351 | MODULE_AUTHOR("Texas Instruments"); | ||
352 | MODULE_DESCRIPTION("OMAP4 Keypad Driver"); | ||
353 | MODULE_LICENSE("GPL"); | ||
354 | MODULE_ALIAS("platform:omap4-keypad"); | ||
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c new file mode 100644 index 000000000000..6229c3e8e78b --- /dev/null +++ b/drivers/input/keyboard/pmic8xxx-keypad.c | |||
@@ -0,0 +1,800 @@ | |||
1 | /* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License version 2 and | ||
5 | * only version 2 as published by the Free Software Foundation. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/bitops.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/mutex.h> | ||
22 | |||
23 | #include <linux/mfd/pm8xxx/core.h> | ||
24 | #include <linux/mfd/pm8xxx/gpio.h> | ||
25 | #include <linux/input/pmic8xxx-keypad.h> | ||
26 | |||
27 | #define PM8XXX_MAX_ROWS 18 | ||
28 | #define PM8XXX_MAX_COLS 8 | ||
29 | #define PM8XXX_ROW_SHIFT 3 | ||
30 | #define PM8XXX_MATRIX_MAX_SIZE (PM8XXX_MAX_ROWS * PM8XXX_MAX_COLS) | ||
31 | |||
32 | #define PM8XXX_MIN_ROWS 5 | ||
33 | #define PM8XXX_MIN_COLS 5 | ||
34 | |||
35 | #define MAX_SCAN_DELAY 128 | ||
36 | #define MIN_SCAN_DELAY 1 | ||
37 | |||
38 | /* in nanoseconds */ | ||
39 | #define MAX_ROW_HOLD_DELAY 122000 | ||
40 | #define MIN_ROW_HOLD_DELAY 30500 | ||
41 | |||
42 | #define MAX_DEBOUNCE_TIME 20 | ||
43 | #define MIN_DEBOUNCE_TIME 5 | ||
44 | |||
45 | #define KEYP_CTRL 0x148 | ||
46 | |||
47 | #define KEYP_CTRL_EVNTS BIT(0) | ||
48 | #define KEYP_CTRL_EVNTS_MASK 0x3 | ||
49 | |||
50 | #define KEYP_CTRL_SCAN_COLS_SHIFT 5 | ||
51 | #define KEYP_CTRL_SCAN_COLS_MIN 5 | ||
52 | #define KEYP_CTRL_SCAN_COLS_BITS 0x3 | ||
53 | |||
54 | #define KEYP_CTRL_SCAN_ROWS_SHIFT 2 | ||
55 | #define KEYP_CTRL_SCAN_ROWS_MIN 5 | ||
56 | #define KEYP_CTRL_SCAN_ROWS_BITS 0x7 | ||
57 | |||
58 | #define KEYP_CTRL_KEYP_EN BIT(7) | ||
59 | |||
60 | #define KEYP_SCAN 0x149 | ||
61 | |||
62 | #define KEYP_SCAN_READ_STATE BIT(0) | ||
63 | #define KEYP_SCAN_DBOUNCE_SHIFT 1 | ||
64 | #define KEYP_SCAN_PAUSE_SHIFT 3 | ||
65 | #define KEYP_SCAN_ROW_HOLD_SHIFT 6 | ||
66 | |||
67 | #define KEYP_TEST 0x14A | ||
68 | |||
69 | #define KEYP_TEST_CLEAR_RECENT_SCAN BIT(6) | ||
70 | #define KEYP_TEST_CLEAR_OLD_SCAN BIT(5) | ||
71 | #define KEYP_TEST_READ_RESET BIT(4) | ||
72 | #define KEYP_TEST_DTEST_EN BIT(3) | ||
73 | #define KEYP_TEST_ABORT_READ BIT(0) | ||
74 | |||
75 | #define KEYP_TEST_DBG_SELECT_SHIFT 1 | ||
76 | |||
77 | /* bits of these registers represent | ||
78 | * '0' for key press | ||
79 | * '1' for key release | ||
80 | */ | ||
81 | #define KEYP_RECENT_DATA 0x14B | ||
82 | #define KEYP_OLD_DATA 0x14C | ||
83 | |||
84 | #define KEYP_CLOCK_FREQ 32768 | ||
85 | |||
86 | /** | ||
87 | * struct pmic8xxx_kp - internal keypad data structure | ||
88 | * @pdata - keypad platform data pointer | ||
89 | * @input - input device pointer for keypad | ||
90 | * @key_sense_irq - key press/release irq number | ||
91 | * @key_stuck_irq - key stuck notification irq number | ||
92 | * @keycodes - array to hold the key codes | ||
93 | * @dev - parent device pointer | ||
94 | * @keystate - present key press/release state | ||
95 | * @stuckstate - present state when key stuck irq | ||
96 | * @ctrl_reg - control register value | ||
97 | */ | ||
98 | struct pmic8xxx_kp { | ||
99 | const struct pm8xxx_keypad_platform_data *pdata; | ||
100 | struct input_dev *input; | ||
101 | int key_sense_irq; | ||
102 | int key_stuck_irq; | ||
103 | |||
104 | unsigned short keycodes[PM8XXX_MATRIX_MAX_SIZE]; | ||
105 | |||
106 | struct device *dev; | ||
107 | u16 keystate[PM8XXX_MAX_ROWS]; | ||
108 | u16 stuckstate[PM8XXX_MAX_ROWS]; | ||
109 | |||
110 | u8 ctrl_reg; | ||
111 | }; | ||
112 | |||
113 | static int pmic8xxx_kp_write_u8(struct pmic8xxx_kp *kp, | ||
114 | u8 data, u16 reg) | ||
115 | { | ||
116 | int rc; | ||
117 | |||
118 | rc = pm8xxx_writeb(kp->dev->parent, reg, data); | ||
119 | return rc; | ||
120 | } | ||
121 | |||
122 | static int pmic8xxx_kp_read(struct pmic8xxx_kp *kp, | ||
123 | u8 *data, u16 reg, unsigned num_bytes) | ||
124 | { | ||
125 | int rc; | ||
126 | |||
127 | rc = pm8xxx_read_buf(kp->dev->parent, reg, data, num_bytes); | ||
128 | return rc; | ||
129 | } | ||
130 | |||
131 | static int pmic8xxx_kp_read_u8(struct pmic8xxx_kp *kp, | ||
132 | u8 *data, u16 reg) | ||
133 | { | ||
134 | int rc; | ||
135 | |||
136 | rc = pmic8xxx_kp_read(kp, data, reg, 1); | ||
137 | return rc; | ||
138 | } | ||
139 | |||
140 | static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) | ||
141 | { | ||
142 | /* all keys pressed on that particular row? */ | ||
143 | if (col == 0x00) | ||
144 | return 1 << kp->pdata->num_cols; | ||
145 | else | ||
146 | return col & ((1 << kp->pdata->num_cols) - 1); | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Synchronous read protocol for RevB0 onwards: | ||
151 | * | ||
152 | * 1. Write '1' to ReadState bit in KEYP_SCAN register | ||
153 | * 2. Wait 2*32KHz clocks, so that HW can successfully enter read mode | ||
154 | * synchronously | ||
155 | * 3. Read rows in old array first if events are more than one | ||
156 | * 4. Read rows in recent array | ||
157 | * 5. Wait 4*32KHz clocks | ||
158 | * 6. Write '0' to ReadState bit of KEYP_SCAN register so that hw can | ||
159 | * synchronously exit read mode. | ||
160 | */ | ||
161 | static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) | ||
162 | { | ||
163 | int rc; | ||
164 | u8 scan_val; | ||
165 | |||
166 | rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); | ||
167 | if (rc < 0) { | ||
168 | dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); | ||
169 | return rc; | ||
170 | } | ||
171 | |||
172 | scan_val |= 0x1; | ||
173 | |||
174 | rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); | ||
175 | if (rc < 0) { | ||
176 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | ||
177 | return rc; | ||
178 | } | ||
179 | |||
180 | /* 2 * 32KHz clocks */ | ||
181 | udelay((2 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); | ||
182 | |||
183 | return rc; | ||
184 | } | ||
185 | |||
186 | static int pmic8xxx_kp_read_data(struct pmic8xxx_kp *kp, u16 *state, | ||
187 | u16 data_reg, int read_rows) | ||
188 | { | ||
189 | int rc, row; | ||
190 | u8 new_data[PM8XXX_MAX_ROWS]; | ||
191 | |||
192 | rc = pmic8xxx_kp_read(kp, new_data, data_reg, read_rows); | ||
193 | if (rc) | ||
194 | return rc; | ||
195 | |||
196 | for (row = 0; row < kp->pdata->num_rows; row++) { | ||
197 | dev_dbg(kp->dev, "new_data[%d] = %d\n", row, | ||
198 | new_data[row]); | ||
199 | state[row] = pmic8xxx_col_state(kp, new_data[row]); | ||
200 | } | ||
201 | |||
202 | return rc; | ||
203 | } | ||
204 | |||
205 | static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, | ||
206 | u16 *old_state) | ||
207 | { | ||
208 | int rc, read_rows; | ||
209 | u8 scan_val; | ||
210 | |||
211 | if (kp->pdata->num_rows < PM8XXX_MIN_ROWS) | ||
212 | read_rows = PM8XXX_MIN_ROWS; | ||
213 | else | ||
214 | read_rows = kp->pdata->num_rows; | ||
215 | |||
216 | pmic8xxx_chk_sync_read(kp); | ||
217 | |||
218 | if (old_state) { | ||
219 | rc = pmic8xxx_kp_read_data(kp, old_state, KEYP_OLD_DATA, | ||
220 | read_rows); | ||
221 | if (rc < 0) { | ||
222 | dev_err(kp->dev, | ||
223 | "Error reading KEYP_OLD_DATA, rc=%d\n", rc); | ||
224 | return rc; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | rc = pmic8xxx_kp_read_data(kp, new_state, KEYP_RECENT_DATA, | ||
229 | read_rows); | ||
230 | if (rc < 0) { | ||
231 | dev_err(kp->dev, | ||
232 | "Error reading KEYP_RECENT_DATA, rc=%d\n", rc); | ||
233 | return rc; | ||
234 | } | ||
235 | |||
236 | /* 4 * 32KHz clocks */ | ||
237 | udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); | ||
238 | |||
239 | rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); | ||
240 | if (rc < 0) { | ||
241 | dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); | ||
242 | return rc; | ||
243 | } | ||
244 | |||
245 | scan_val &= 0xFE; | ||
246 | rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); | ||
247 | if (rc < 0) | ||
248 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | ||
249 | |||
250 | return rc; | ||
251 | } | ||
252 | |||
253 | static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, | ||
254 | u16 *old_state) | ||
255 | { | ||
256 | int row, col, code; | ||
257 | |||
258 | for (row = 0; row < kp->pdata->num_rows; row++) { | ||
259 | int bits_changed = new_state[row] ^ old_state[row]; | ||
260 | |||
261 | if (!bits_changed) | ||
262 | continue; | ||
263 | |||
264 | for (col = 0; col < kp->pdata->num_cols; col++) { | ||
265 | if (!(bits_changed & (1 << col))) | ||
266 | continue; | ||
267 | |||
268 | dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, | ||
269 | !(new_state[row] & (1 << col)) ? | ||
270 | "pressed" : "released"); | ||
271 | |||
272 | code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); | ||
273 | |||
274 | input_event(kp->input, EV_MSC, MSC_SCAN, code); | ||
275 | input_report_key(kp->input, | ||
276 | kp->keycodes[code], | ||
277 | !(new_state[row] & (1 << col))); | ||
278 | |||
279 | input_sync(kp->input); | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | |||
284 | static bool pmic8xxx_detect_ghost_keys(struct pmic8xxx_kp *kp, u16 *new_state) | ||
285 | { | ||
286 | int row, found_first = -1; | ||
287 | u16 check, row_state; | ||
288 | |||
289 | check = 0; | ||
290 | for (row = 0; row < kp->pdata->num_rows; row++) { | ||
291 | row_state = (~new_state[row]) & | ||
292 | ((1 << kp->pdata->num_cols) - 1); | ||
293 | |||
294 | if (hweight16(row_state) > 1) { | ||
295 | if (found_first == -1) | ||
296 | found_first = row; | ||
297 | if (check & row_state) { | ||
298 | dev_dbg(kp->dev, "detected ghost key on row[%d]" | ||
299 | " and row[%d]\n", found_first, row); | ||
300 | return true; | ||
301 | } | ||
302 | } | ||
303 | check |= row_state; | ||
304 | } | ||
305 | return false; | ||
306 | } | ||
307 | |||
308 | static int pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, unsigned int events) | ||
309 | { | ||
310 | u16 new_state[PM8XXX_MAX_ROWS]; | ||
311 | u16 old_state[PM8XXX_MAX_ROWS]; | ||
312 | int rc; | ||
313 | |||
314 | switch (events) { | ||
315 | case 0x1: | ||
316 | rc = pmic8xxx_kp_read_matrix(kp, new_state, NULL); | ||
317 | if (rc < 0) | ||
318 | return rc; | ||
319 | |||
320 | /* detecting ghost key is not an error */ | ||
321 | if (pmic8xxx_detect_ghost_keys(kp, new_state)) | ||
322 | return 0; | ||
323 | __pmic8xxx_kp_scan_matrix(kp, new_state, kp->keystate); | ||
324 | memcpy(kp->keystate, new_state, sizeof(new_state)); | ||
325 | break; | ||
326 | case 0x3: /* two events - eventcounter is gray-coded */ | ||
327 | rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); | ||
328 | if (rc < 0) | ||
329 | return rc; | ||
330 | |||
331 | __pmic8xxx_kp_scan_matrix(kp, old_state, kp->keystate); | ||
332 | __pmic8xxx_kp_scan_matrix(kp, new_state, old_state); | ||
333 | memcpy(kp->keystate, new_state, sizeof(new_state)); | ||
334 | break; | ||
335 | case 0x2: | ||
336 | dev_dbg(kp->dev, "Some key events were lost\n"); | ||
337 | rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); | ||
338 | if (rc < 0) | ||
339 | return rc; | ||
340 | __pmic8xxx_kp_scan_matrix(kp, old_state, kp->keystate); | ||
341 | __pmic8xxx_kp_scan_matrix(kp, new_state, old_state); | ||
342 | memcpy(kp->keystate, new_state, sizeof(new_state)); | ||
343 | break; | ||
344 | default: | ||
345 | rc = -EINVAL; | ||
346 | } | ||
347 | return rc; | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * NOTE: We are reading recent and old data registers blindly | ||
352 | * whenever key-stuck interrupt happens, because events counter doesn't | ||
353 | * get updated when this interrupt happens due to key stuck doesn't get | ||
354 | * considered as key state change. | ||
355 | * | ||
356 | * We are not using old data register contents after they are being read | ||
357 | * because it might report the key which was pressed before the key being stuck | ||
358 | * as stuck key because it's pressed status is stored in the old data | ||
359 | * register. | ||
360 | */ | ||
361 | static irqreturn_t pmic8xxx_kp_stuck_irq(int irq, void *data) | ||
362 | { | ||
363 | u16 new_state[PM8XXX_MAX_ROWS]; | ||
364 | u16 old_state[PM8XXX_MAX_ROWS]; | ||
365 | int rc; | ||
366 | struct pmic8xxx_kp *kp = data; | ||
367 | |||
368 | rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); | ||
369 | if (rc < 0) { | ||
370 | dev_err(kp->dev, "failed to read keypad matrix\n"); | ||
371 | return IRQ_HANDLED; | ||
372 | } | ||
373 | |||
374 | __pmic8xxx_kp_scan_matrix(kp, new_state, kp->stuckstate); | ||
375 | |||
376 | return IRQ_HANDLED; | ||
377 | } | ||
378 | |||
379 | static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) | ||
380 | { | ||
381 | struct pmic8xxx_kp *kp = data; | ||
382 | u8 ctrl_val, events; | ||
383 | int rc; | ||
384 | |||
385 | rc = pmic8xxx_kp_read(kp, &ctrl_val, KEYP_CTRL, 1); | ||
386 | if (rc < 0) { | ||
387 | dev_err(kp->dev, "failed to read keyp_ctrl register\n"); | ||
388 | return IRQ_HANDLED; | ||
389 | } | ||
390 | |||
391 | events = ctrl_val & KEYP_CTRL_EVNTS_MASK; | ||
392 | |||
393 | rc = pmic8xxx_kp_scan_matrix(kp, events); | ||
394 | if (rc < 0) | ||
395 | dev_err(kp->dev, "failed to scan matrix\n"); | ||
396 | |||
397 | return IRQ_HANDLED; | ||
398 | } | ||
399 | |||
400 | static int __devinit pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) | ||
401 | { | ||
402 | int bits, rc, cycles; | ||
403 | u8 scan_val = 0, ctrl_val = 0; | ||
404 | static const u8 row_bits[] = { | ||
405 | 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, | ||
406 | }; | ||
407 | |||
408 | /* Find column bits */ | ||
409 | if (kp->pdata->num_cols < KEYP_CTRL_SCAN_COLS_MIN) | ||
410 | bits = 0; | ||
411 | else | ||
412 | bits = kp->pdata->num_cols - KEYP_CTRL_SCAN_COLS_MIN; | ||
413 | ctrl_val = (bits & KEYP_CTRL_SCAN_COLS_BITS) << | ||
414 | KEYP_CTRL_SCAN_COLS_SHIFT; | ||
415 | |||
416 | /* Find row bits */ | ||
417 | if (kp->pdata->num_rows < KEYP_CTRL_SCAN_ROWS_MIN) | ||
418 | bits = 0; | ||
419 | else | ||
420 | bits = row_bits[kp->pdata->num_rows - KEYP_CTRL_SCAN_ROWS_MIN]; | ||
421 | |||
422 | ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT); | ||
423 | |||
424 | rc = pmic8xxx_kp_write_u8(kp, ctrl_val, KEYP_CTRL); | ||
425 | if (rc < 0) { | ||
426 | dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); | ||
427 | return rc; | ||
428 | } | ||
429 | |||
430 | bits = (kp->pdata->debounce_ms / 5) - 1; | ||
431 | |||
432 | scan_val |= (bits << KEYP_SCAN_DBOUNCE_SHIFT); | ||
433 | |||
434 | bits = fls(kp->pdata->scan_delay_ms) - 1; | ||
435 | scan_val |= (bits << KEYP_SCAN_PAUSE_SHIFT); | ||
436 | |||
437 | /* Row hold time is a multiple of 32KHz cycles. */ | ||
438 | cycles = (kp->pdata->row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC; | ||
439 | |||
440 | scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT); | ||
441 | |||
442 | rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); | ||
443 | if (rc) | ||
444 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | ||
445 | |||
446 | return rc; | ||
447 | |||
448 | } | ||
449 | |||
450 | static int __devinit pmic8xxx_kp_config_gpio(int gpio_start, int num_gpios, | ||
451 | struct pmic8xxx_kp *kp, struct pm_gpio *gpio_config) | ||
452 | { | ||
453 | int rc, i; | ||
454 | |||
455 | if (gpio_start < 0 || num_gpios < 0) | ||
456 | return -EINVAL; | ||
457 | |||
458 | for (i = 0; i < num_gpios; i++) { | ||
459 | rc = pm8xxx_gpio_config(gpio_start + i, gpio_config); | ||
460 | if (rc) { | ||
461 | dev_err(kp->dev, "%s: FAIL pm8xxx_gpio_config():" | ||
462 | "for PM GPIO [%d] rc=%d.\n", | ||
463 | __func__, gpio_start + i, rc); | ||
464 | return rc; | ||
465 | } | ||
466 | } | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp) | ||
472 | { | ||
473 | int rc; | ||
474 | |||
475 | kp->ctrl_reg |= KEYP_CTRL_KEYP_EN; | ||
476 | |||
477 | rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); | ||
478 | if (rc < 0) | ||
479 | dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); | ||
480 | |||
481 | return rc; | ||
482 | } | ||
483 | |||
484 | static int pmic8xxx_kp_disable(struct pmic8xxx_kp *kp) | ||
485 | { | ||
486 | int rc; | ||
487 | |||
488 | kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN; | ||
489 | |||
490 | rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); | ||
491 | if (rc < 0) | ||
492 | return rc; | ||
493 | |||
494 | return rc; | ||
495 | } | ||
496 | |||
497 | static int pmic8xxx_kp_open(struct input_dev *dev) | ||
498 | { | ||
499 | struct pmic8xxx_kp *kp = input_get_drvdata(dev); | ||
500 | |||
501 | return pmic8xxx_kp_enable(kp); | ||
502 | } | ||
503 | |||
504 | static void pmic8xxx_kp_close(struct input_dev *dev) | ||
505 | { | ||
506 | struct pmic8xxx_kp *kp = input_get_drvdata(dev); | ||
507 | |||
508 | pmic8xxx_kp_disable(kp); | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * keypad controller should be initialized in the following sequence | ||
513 | * only, otherwise it might get into FSM stuck state. | ||
514 | * | ||
515 | * - Initialize keypad control parameters, like no. of rows, columns, | ||
516 | * timing values etc., | ||
517 | * - configure rows and column gpios pull up/down. | ||
518 | * - set irq edge type. | ||
519 | * - enable the keypad controller. | ||
520 | */ | ||
521 | static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) | ||
522 | { | ||
523 | const struct pm8xxx_keypad_platform_data *pdata = | ||
524 | dev_get_platdata(&pdev->dev); | ||
525 | const struct matrix_keymap_data *keymap_data; | ||
526 | struct pmic8xxx_kp *kp; | ||
527 | int rc; | ||
528 | u8 ctrl_val; | ||
529 | |||
530 | struct pm_gpio kypd_drv = { | ||
531 | .direction = PM_GPIO_DIR_OUT, | ||
532 | .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, | ||
533 | .output_value = 0, | ||
534 | .pull = PM_GPIO_PULL_NO, | ||
535 | .vin_sel = PM_GPIO_VIN_S3, | ||
536 | .out_strength = PM_GPIO_STRENGTH_LOW, | ||
537 | .function = PM_GPIO_FUNC_1, | ||
538 | .inv_int_pol = 1, | ||
539 | }; | ||
540 | |||
541 | struct pm_gpio kypd_sns = { | ||
542 | .direction = PM_GPIO_DIR_IN, | ||
543 | .pull = PM_GPIO_PULL_UP_31P5, | ||
544 | .vin_sel = PM_GPIO_VIN_S3, | ||
545 | .out_strength = PM_GPIO_STRENGTH_NO, | ||
546 | .function = PM_GPIO_FUNC_NORMAL, | ||
547 | .inv_int_pol = 1, | ||
548 | }; | ||
549 | |||
550 | |||
551 | if (!pdata || !pdata->num_cols || !pdata->num_rows || | ||
552 | pdata->num_cols > PM8XXX_MAX_COLS || | ||
553 | pdata->num_rows > PM8XXX_MAX_ROWS || | ||
554 | pdata->num_cols < PM8XXX_MIN_COLS) { | ||
555 | dev_err(&pdev->dev, "invalid platform data\n"); | ||
556 | return -EINVAL; | ||
557 | } | ||
558 | |||
559 | if (!pdata->scan_delay_ms || | ||
560 | pdata->scan_delay_ms > MAX_SCAN_DELAY || | ||
561 | pdata->scan_delay_ms < MIN_SCAN_DELAY || | ||
562 | !is_power_of_2(pdata->scan_delay_ms)) { | ||
563 | dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); | ||
564 | return -EINVAL; | ||
565 | } | ||
566 | |||
567 | if (!pdata->row_hold_ns || | ||
568 | pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || | ||
569 | pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || | ||
570 | ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { | ||
571 | dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | |||
575 | if (!pdata->debounce_ms || | ||
576 | ((pdata->debounce_ms % 5) != 0) || | ||
577 | pdata->debounce_ms > MAX_DEBOUNCE_TIME || | ||
578 | pdata->debounce_ms < MIN_DEBOUNCE_TIME) { | ||
579 | dev_err(&pdev->dev, "invalid debounce time supplied\n"); | ||
580 | return -EINVAL; | ||
581 | } | ||
582 | |||
583 | keymap_data = pdata->keymap_data; | ||
584 | if (!keymap_data) { | ||
585 | dev_err(&pdev->dev, "no keymap data supplied\n"); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | kp = kzalloc(sizeof(*kp), GFP_KERNEL); | ||
590 | if (!kp) | ||
591 | return -ENOMEM; | ||
592 | |||
593 | platform_set_drvdata(pdev, kp); | ||
594 | |||
595 | kp->pdata = pdata; | ||
596 | kp->dev = &pdev->dev; | ||
597 | |||
598 | kp->input = input_allocate_device(); | ||
599 | if (!kp->input) { | ||
600 | dev_err(&pdev->dev, "unable to allocate input device\n"); | ||
601 | rc = -ENOMEM; | ||
602 | goto err_alloc_device; | ||
603 | } | ||
604 | |||
605 | kp->key_sense_irq = platform_get_irq(pdev, 0); | ||
606 | if (kp->key_sense_irq < 0) { | ||
607 | dev_err(&pdev->dev, "unable to get keypad sense irq\n"); | ||
608 | rc = -ENXIO; | ||
609 | goto err_get_irq; | ||
610 | } | ||
611 | |||
612 | kp->key_stuck_irq = platform_get_irq(pdev, 1); | ||
613 | if (kp->key_stuck_irq < 0) { | ||
614 | dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); | ||
615 | rc = -ENXIO; | ||
616 | goto err_get_irq; | ||
617 | } | ||
618 | |||
619 | kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; | ||
620 | kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; | ||
621 | |||
622 | kp->input->dev.parent = &pdev->dev; | ||
623 | |||
624 | kp->input->id.bustype = BUS_I2C; | ||
625 | kp->input->id.version = 0x0001; | ||
626 | kp->input->id.product = 0x0001; | ||
627 | kp->input->id.vendor = 0x0001; | ||
628 | |||
629 | kp->input->evbit[0] = BIT_MASK(EV_KEY); | ||
630 | |||
631 | if (pdata->rep) | ||
632 | __set_bit(EV_REP, kp->input->evbit); | ||
633 | |||
634 | kp->input->keycode = kp->keycodes; | ||
635 | kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; | ||
636 | kp->input->keycodesize = sizeof(kp->keycodes); | ||
637 | kp->input->open = pmic8xxx_kp_open; | ||
638 | kp->input->close = pmic8xxx_kp_close; | ||
639 | |||
640 | matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, | ||
641 | kp->input->keycode, kp->input->keybit); | ||
642 | |||
643 | input_set_capability(kp->input, EV_MSC, MSC_SCAN); | ||
644 | input_set_drvdata(kp->input, kp); | ||
645 | |||
646 | /* initialize keypad state */ | ||
647 | memset(kp->keystate, 0xff, sizeof(kp->keystate)); | ||
648 | memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); | ||
649 | |||
650 | rc = pmic8xxx_kpd_init(kp); | ||
651 | if (rc < 0) { | ||
652 | dev_err(&pdev->dev, "unable to initialize keypad controller\n"); | ||
653 | goto err_get_irq; | ||
654 | } | ||
655 | |||
656 | rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, | ||
657 | pdata->num_cols, kp, &kypd_sns); | ||
658 | if (rc < 0) { | ||
659 | dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); | ||
660 | goto err_gpio_config; | ||
661 | } | ||
662 | |||
663 | rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, | ||
664 | pdata->num_rows, kp, &kypd_drv); | ||
665 | if (rc < 0) { | ||
666 | dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); | ||
667 | goto err_gpio_config; | ||
668 | } | ||
669 | |||
670 | rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, | ||
671 | IRQF_TRIGGER_RISING, "pmic-keypad", kp); | ||
672 | if (rc < 0) { | ||
673 | dev_err(&pdev->dev, "failed to request keypad sense irq\n"); | ||
674 | goto err_get_irq; | ||
675 | } | ||
676 | |||
677 | rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, | ||
678 | IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); | ||
679 | if (rc < 0) { | ||
680 | dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); | ||
681 | goto err_req_stuck_irq; | ||
682 | } | ||
683 | |||
684 | rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); | ||
685 | if (rc < 0) { | ||
686 | dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); | ||
687 | goto err_pmic_reg_read; | ||
688 | } | ||
689 | |||
690 | kp->ctrl_reg = ctrl_val; | ||
691 | |||
692 | rc = input_register_device(kp->input); | ||
693 | if (rc < 0) { | ||
694 | dev_err(&pdev->dev, "unable to register keypad input device\n"); | ||
695 | goto err_pmic_reg_read; | ||
696 | } | ||
697 | |||
698 | device_init_wakeup(&pdev->dev, pdata->wakeup); | ||
699 | |||
700 | return 0; | ||
701 | |||
702 | err_pmic_reg_read: | ||
703 | free_irq(kp->key_stuck_irq, NULL); | ||
704 | err_req_stuck_irq: | ||
705 | free_irq(kp->key_sense_irq, NULL); | ||
706 | err_gpio_config: | ||
707 | err_get_irq: | ||
708 | input_free_device(kp->input); | ||
709 | err_alloc_device: | ||
710 | platform_set_drvdata(pdev, NULL); | ||
711 | kfree(kp); | ||
712 | return rc; | ||
713 | } | ||
714 | |||
715 | static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) | ||
716 | { | ||
717 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); | ||
718 | |||
719 | device_init_wakeup(&pdev->dev, 0); | ||
720 | free_irq(kp->key_stuck_irq, NULL); | ||
721 | free_irq(kp->key_sense_irq, NULL); | ||
722 | input_unregister_device(kp->input); | ||
723 | kfree(kp); | ||
724 | |||
725 | platform_set_drvdata(pdev, NULL); | ||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | #ifdef CONFIG_PM_SLEEP | ||
730 | static int pmic8xxx_kp_suspend(struct device *dev) | ||
731 | { | ||
732 | struct platform_device *pdev = to_platform_device(dev); | ||
733 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); | ||
734 | struct input_dev *input_dev = kp->input; | ||
735 | |||
736 | if (device_may_wakeup(dev)) { | ||
737 | enable_irq_wake(kp->key_sense_irq); | ||
738 | } else { | ||
739 | mutex_lock(&input_dev->mutex); | ||
740 | |||
741 | if (input_dev->users) | ||
742 | pmic8xxx_kp_disable(kp); | ||
743 | |||
744 | mutex_unlock(&input_dev->mutex); | ||
745 | } | ||
746 | |||
747 | return 0; | ||
748 | } | ||
749 | |||
750 | static int pmic8xxx_kp_resume(struct device *dev) | ||
751 | { | ||
752 | struct platform_device *pdev = to_platform_device(dev); | ||
753 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); | ||
754 | struct input_dev *input_dev = kp->input; | ||
755 | |||
756 | if (device_may_wakeup(dev)) { | ||
757 | disable_irq_wake(kp->key_sense_irq); | ||
758 | } else { | ||
759 | mutex_lock(&input_dev->mutex); | ||
760 | |||
761 | if (input_dev->users) | ||
762 | pmic8xxx_kp_enable(kp); | ||
763 | |||
764 | mutex_unlock(&input_dev->mutex); | ||
765 | } | ||
766 | |||
767 | return 0; | ||
768 | } | ||
769 | #endif | ||
770 | |||
771 | static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, | ||
772 | pmic8xxx_kp_suspend, pmic8xxx_kp_resume); | ||
773 | |||
774 | static struct platform_driver pmic8xxx_kp_driver = { | ||
775 | .probe = pmic8xxx_kp_probe, | ||
776 | .remove = __devexit_p(pmic8xxx_kp_remove), | ||
777 | .driver = { | ||
778 | .name = PM8XXX_KEYPAD_DEV_NAME, | ||
779 | .owner = THIS_MODULE, | ||
780 | .pm = &pm8xxx_kp_pm_ops, | ||
781 | }, | ||
782 | }; | ||
783 | |||
784 | static int __init pmic8xxx_kp_init(void) | ||
785 | { | ||
786 | return platform_driver_register(&pmic8xxx_kp_driver); | ||
787 | } | ||
788 | module_init(pmic8xxx_kp_init); | ||
789 | |||
790 | static void __exit pmic8xxx_kp_exit(void) | ||
791 | { | ||
792 | platform_driver_unregister(&pmic8xxx_kp_driver); | ||
793 | } | ||
794 | module_exit(pmic8xxx_kp_exit); | ||
795 | |||
796 | MODULE_LICENSE("GPL v2"); | ||
797 | MODULE_DESCRIPTION("PMIC8XXX keypad driver"); | ||
798 | MODULE_VERSION("1.0"); | ||
799 | MODULE_ALIAS("platform:pmic8xxx_keypad"); | ||
800 | MODULE_AUTHOR("Trilok Soni <tsoni@codeaurora.org>"); | ||
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index f32404f99189..4b0ec35259a1 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
33 | 33 | ||
34 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
35 | #include <mach/pxa27x_keypad.h> | 35 | #include <plat/pxa27x_keypad.h> |
36 | /* | 36 | /* |
37 | * Keypad Controller registers | 37 | * Keypad Controller registers |
38 | */ | 38 | */ |
@@ -330,11 +330,21 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) | |||
330 | keypad->direct_key_state = new_state; | 330 | keypad->direct_key_state = new_state; |
331 | } | 331 | } |
332 | 332 | ||
333 | static void clear_wakeup_event(struct pxa27x_keypad *keypad) | ||
334 | { | ||
335 | struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | ||
336 | |||
337 | if (pdata->clear_wakeup_event) | ||
338 | (pdata->clear_wakeup_event)(); | ||
339 | } | ||
340 | |||
333 | static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) | 341 | static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) |
334 | { | 342 | { |
335 | struct pxa27x_keypad *keypad = dev_id; | 343 | struct pxa27x_keypad *keypad = dev_id; |
336 | unsigned long kpc = keypad_readl(KPC); | 344 | unsigned long kpc = keypad_readl(KPC); |
337 | 345 | ||
346 | clear_wakeup_event(keypad); | ||
347 | |||
338 | if (kpc & KPC_DI) | 348 | if (kpc & KPC_DI) |
339 | pxa27x_keypad_scan_direct(keypad); | 349 | pxa27x_keypad_scan_direct(keypad); |
340 | 350 | ||
diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c new file mode 100644 index 000000000000..ca7b89196ab7 --- /dev/null +++ b/drivers/input/keyboard/qt1070.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * Atmel AT42QT1070 QTouch Sensor Controller | ||
3 | * | ||
4 | * Copyright (C) 2011 Atmel | ||
5 | * | ||
6 | * Authors: Bo Shen <voice.shen@atmel.com> | ||
7 | * | ||
8 | * Base on AT42QT2160 driver by: | ||
9 | * Raphael Derosso Pereira <raphaelpereira@gmail.com> | ||
10 | * Copyright (C) 2009 | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/irq.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/jiffies.h> | ||
35 | #include <linux/delay.h> | ||
36 | |||
37 | /* Address for each register */ | ||
38 | #define CHIP_ID 0x00 | ||
39 | #define QT1070_CHIP_ID 0x2E | ||
40 | |||
41 | #define FW_VERSION 0x01 | ||
42 | #define QT1070_FW_VERSION 0x15 | ||
43 | |||
44 | #define DET_STATUS 0x02 | ||
45 | |||
46 | #define KEY_STATUS 0x03 | ||
47 | |||
48 | /* Calibrate */ | ||
49 | #define CALIBRATE_CMD 0x38 | ||
50 | #define QT1070_CAL_TIME 200 | ||
51 | |||
52 | /* Reset */ | ||
53 | #define RESET 0x39 | ||
54 | #define QT1070_RESET_TIME 255 | ||
55 | |||
56 | /* AT42QT1070 support up to 7 keys */ | ||
57 | static const unsigned short qt1070_key2code[] = { | ||
58 | KEY_0, KEY_1, KEY_2, KEY_3, | ||
59 | KEY_4, KEY_5, KEY_6, | ||
60 | }; | ||
61 | |||
62 | struct qt1070_data { | ||
63 | struct i2c_client *client; | ||
64 | struct input_dev *input; | ||
65 | unsigned int irq; | ||
66 | unsigned short keycodes[ARRAY_SIZE(qt1070_key2code)]; | ||
67 | u8 last_keys; | ||
68 | }; | ||
69 | |||
70 | static int qt1070_read(struct i2c_client *client, u8 reg) | ||
71 | { | ||
72 | int ret; | ||
73 | |||
74 | ret = i2c_smbus_read_byte_data(client, reg); | ||
75 | if (ret < 0) | ||
76 | dev_err(&client->dev, | ||
77 | "can not read register, returned %d\n", ret); | ||
78 | |||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | static int qt1070_write(struct i2c_client *client, u8 reg, u8 data) | ||
83 | { | ||
84 | int ret; | ||
85 | |||
86 | ret = i2c_smbus_write_byte_data(client, reg, data); | ||
87 | if (ret < 0) | ||
88 | dev_err(&client->dev, | ||
89 | "can not write register, returned %d\n", ret); | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | static bool __devinit qt1070_identify(struct i2c_client *client) | ||
95 | { | ||
96 | int id, ver; | ||
97 | |||
98 | /* Read Chip ID */ | ||
99 | id = qt1070_read(client, CHIP_ID); | ||
100 | if (id != QT1070_CHIP_ID) { | ||
101 | dev_err(&client->dev, "ID %d not supported\n", id); | ||
102 | return false; | ||
103 | } | ||
104 | |||
105 | /* Read firmware version */ | ||
106 | ver = qt1070_read(client, FW_VERSION); | ||
107 | if (ver < 0) { | ||
108 | dev_err(&client->dev, "could not read the firmware version\n"); | ||
109 | return false; | ||
110 | } | ||
111 | |||
112 | dev_info(&client->dev, "AT42QT1070 firmware version %x\n", ver); | ||
113 | |||
114 | return true; | ||
115 | } | ||
116 | |||
117 | static irqreturn_t qt1070_interrupt(int irq, void *dev_id) | ||
118 | { | ||
119 | struct qt1070_data *data = dev_id; | ||
120 | struct i2c_client *client = data->client; | ||
121 | struct input_dev *input = data->input; | ||
122 | int i; | ||
123 | u8 new_keys, keyval, mask = 0x01; | ||
124 | |||
125 | /* Read the detected status register, thus clearing interrupt */ | ||
126 | qt1070_read(client, DET_STATUS); | ||
127 | |||
128 | /* Read which key changed */ | ||
129 | new_keys = qt1070_read(client, KEY_STATUS); | ||
130 | |||
131 | for (i = 0; i < ARRAY_SIZE(qt1070_key2code); i++) { | ||
132 | keyval = new_keys & mask; | ||
133 | if ((data->last_keys & mask) != keyval) | ||
134 | input_report_key(input, data->keycodes[i], keyval); | ||
135 | mask <<= 1; | ||
136 | } | ||
137 | input_sync(input); | ||
138 | |||
139 | data->last_keys = new_keys; | ||
140 | return IRQ_HANDLED; | ||
141 | } | ||
142 | |||
143 | static int __devinit qt1070_probe(struct i2c_client *client, | ||
144 | const struct i2c_device_id *id) | ||
145 | { | ||
146 | struct qt1070_data *data; | ||
147 | struct input_dev *input; | ||
148 | int i; | ||
149 | int err; | ||
150 | |||
151 | err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE); | ||
152 | if (!err) { | ||
153 | dev_err(&client->dev, "%s adapter not supported\n", | ||
154 | dev_driver_string(&client->adapter->dev)); | ||
155 | return -ENODEV; | ||
156 | } | ||
157 | |||
158 | if (!client->irq) { | ||
159 | dev_err(&client->dev, "please assign the irq to this device\n"); | ||
160 | return -EINVAL; | ||
161 | } | ||
162 | |||
163 | /* Identify the qt1070 chip */ | ||
164 | if (!qt1070_identify(client)) | ||
165 | return -ENODEV; | ||
166 | |||
167 | data = kzalloc(sizeof(struct qt1070_data), GFP_KERNEL); | ||
168 | input = input_allocate_device(); | ||
169 | if (!data || !input) { | ||
170 | dev_err(&client->dev, "insufficient memory\n"); | ||
171 | err = -ENOMEM; | ||
172 | goto err_free_mem; | ||
173 | } | ||
174 | |||
175 | data->client = client; | ||
176 | data->input = input; | ||
177 | data->irq = client->irq; | ||
178 | |||
179 | input->name = "AT42QT1070 QTouch Sensor"; | ||
180 | input->dev.parent = &client->dev; | ||
181 | input->id.bustype = BUS_I2C; | ||
182 | |||
183 | /* Add the keycode */ | ||
184 | input->keycode = data->keycodes; | ||
185 | input->keycodesize = sizeof(data->keycodes[0]); | ||
186 | input->keycodemax = ARRAY_SIZE(qt1070_key2code); | ||
187 | |||
188 | __set_bit(EV_KEY, input->evbit); | ||
189 | |||
190 | for (i = 0; i < ARRAY_SIZE(qt1070_key2code); i++) { | ||
191 | data->keycodes[i] = qt1070_key2code[i]; | ||
192 | __set_bit(qt1070_key2code[i], input->keybit); | ||
193 | } | ||
194 | |||
195 | /* Calibrate device */ | ||
196 | qt1070_write(client, CALIBRATE_CMD, 1); | ||
197 | msleep(QT1070_CAL_TIME); | ||
198 | |||
199 | /* Soft reset */ | ||
200 | qt1070_write(client, RESET, 1); | ||
201 | msleep(QT1070_RESET_TIME); | ||
202 | |||
203 | err = request_threaded_irq(client->irq, NULL, qt1070_interrupt, | ||
204 | IRQF_TRIGGER_NONE, client->dev.driver->name, data); | ||
205 | if (err) { | ||
206 | dev_err(&client->dev, "fail to request irq\n"); | ||
207 | goto err_free_mem; | ||
208 | } | ||
209 | |||
210 | /* Register the input device */ | ||
211 | err = input_register_device(data->input); | ||
212 | if (err) { | ||
213 | dev_err(&client->dev, "Failed to register input device\n"); | ||
214 | goto err_free_irq; | ||
215 | } | ||
216 | |||
217 | i2c_set_clientdata(client, data); | ||
218 | |||
219 | /* Read to clear the chang line */ | ||
220 | qt1070_read(client, DET_STATUS); | ||
221 | |||
222 | return 0; | ||
223 | |||
224 | err_free_irq: | ||
225 | free_irq(client->irq, data); | ||
226 | err_free_mem: | ||
227 | input_free_device(input); | ||
228 | kfree(data); | ||
229 | return err; | ||
230 | } | ||
231 | |||
232 | static int __devexit qt1070_remove(struct i2c_client *client) | ||
233 | { | ||
234 | struct qt1070_data *data = i2c_get_clientdata(client); | ||
235 | |||
236 | /* Release IRQ */ | ||
237 | free_irq(client->irq, data); | ||
238 | |||
239 | input_unregister_device(data->input); | ||
240 | kfree(data); | ||
241 | |||
242 | i2c_set_clientdata(client, NULL); | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static const struct i2c_device_id qt1070_id[] = { | ||
248 | { "qt1070", 0 }, | ||
249 | { }, | ||
250 | }; | ||
251 | MODULE_DEVICE_TABLE(i2c, qt1070_id); | ||
252 | |||
253 | static struct i2c_driver qt1070_driver = { | ||
254 | .driver = { | ||
255 | .name = "qt1070", | ||
256 | .owner = THIS_MODULE, | ||
257 | }, | ||
258 | .id_table = qt1070_id, | ||
259 | .probe = qt1070_probe, | ||
260 | .remove = __devexit_p(qt1070_remove), | ||
261 | }; | ||
262 | |||
263 | static int __init qt1070_init(void) | ||
264 | { | ||
265 | return i2c_add_driver(&qt1070_driver); | ||
266 | } | ||
267 | module_init(qt1070_init); | ||
268 | |||
269 | static void __exit qt1070_exit(void) | ||
270 | { | ||
271 | i2c_del_driver(&qt1070_driver); | ||
272 | } | ||
273 | module_exit(qt1070_exit); | ||
274 | |||
275 | MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>"); | ||
276 | MODULE_DESCRIPTION("Driver for AT42QT1070 QTouch sensor"); | ||
277 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index d7dafd9425b6..6876700a4469 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/input/sh_keysc.h> | 21 | #include <linux/input/sh_keysc.h> |
22 | #include <linux/bitmap.h> | 22 | #include <linux/bitmap.h> |
23 | #include <linux/clk.h> | 23 | #include <linux/pm_runtime.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | 26 | ||
@@ -32,12 +32,11 @@ static const struct { | |||
32 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, | 32 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, |
33 | [SH_KEYSC_MODE_4] = { 3, 6, 6 }, | 33 | [SH_KEYSC_MODE_4] = { 3, 6, 6 }, |
34 | [SH_KEYSC_MODE_5] = { 4, 6, 7 }, | 34 | [SH_KEYSC_MODE_5] = { 4, 6, 7 }, |
35 | [SH_KEYSC_MODE_6] = { 5, 7, 7 }, | 35 | [SH_KEYSC_MODE_6] = { 5, 8, 8 }, |
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct sh_keysc_priv { | 38 | struct sh_keysc_priv { |
39 | void __iomem *iomem_base; | 39 | void __iomem *iomem_base; |
40 | struct clk *clk; | ||
41 | DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); | 40 | DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); |
42 | struct input_dev *input; | 41 | struct input_dev *input; |
43 | struct sh_keysc_info pdata; | 42 | struct sh_keysc_info pdata; |
@@ -169,7 +168,6 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
169 | struct sh_keysc_info *pdata; | 168 | struct sh_keysc_info *pdata; |
170 | struct resource *res; | 169 | struct resource *res; |
171 | struct input_dev *input; | 170 | struct input_dev *input; |
172 | char clk_name[8]; | ||
173 | int i; | 171 | int i; |
174 | int irq, error; | 172 | int irq, error; |
175 | 173 | ||
@@ -210,19 +208,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
210 | goto err1; | 208 | goto err1; |
211 | } | 209 | } |
212 | 210 | ||
213 | snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id); | ||
214 | priv->clk = clk_get(&pdev->dev, clk_name); | ||
215 | if (IS_ERR(priv->clk)) { | ||
216 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); | ||
217 | error = PTR_ERR(priv->clk); | ||
218 | goto err2; | ||
219 | } | ||
220 | |||
221 | priv->input = input_allocate_device(); | 211 | priv->input = input_allocate_device(); |
222 | if (!priv->input) { | 212 | if (!priv->input) { |
223 | dev_err(&pdev->dev, "failed to allocate input device\n"); | 213 | dev_err(&pdev->dev, "failed to allocate input device\n"); |
224 | error = -ENOMEM; | 214 | error = -ENOMEM; |
225 | goto err3; | 215 | goto err2; |
226 | } | 216 | } |
227 | 217 | ||
228 | input = priv->input; | 218 | input = priv->input; |
@@ -241,10 +231,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
241 | input->keycodesize = sizeof(pdata->keycodes[0]); | 231 | input->keycodesize = sizeof(pdata->keycodes[0]); |
242 | input->keycodemax = ARRAY_SIZE(pdata->keycodes); | 232 | input->keycodemax = ARRAY_SIZE(pdata->keycodes); |
243 | 233 | ||
244 | error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); | 234 | error = request_threaded_irq(irq, NULL, sh_keysc_isr, IRQF_ONESHOT, |
235 | dev_name(&pdev->dev), pdev); | ||
245 | if (error) { | 236 | if (error) { |
246 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 237 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
247 | goto err4; | 238 | goto err3; |
248 | } | 239 | } |
249 | 240 | ||
250 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) | 241 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) |
@@ -254,10 +245,11 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
254 | error = input_register_device(input); | 245 | error = input_register_device(input); |
255 | if (error) { | 246 | if (error) { |
256 | dev_err(&pdev->dev, "failed to register input device\n"); | 247 | dev_err(&pdev->dev, "failed to register input device\n"); |
257 | goto err5; | 248 | goto err4; |
258 | } | 249 | } |
259 | 250 | ||
260 | clk_enable(priv->clk); | 251 | pm_runtime_enable(&pdev->dev); |
252 | pm_runtime_get_sync(&pdev->dev); | ||
261 | 253 | ||
262 | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | | 254 | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | |
263 | pdata->scan_timing); | 255 | pdata->scan_timing); |
@@ -267,12 +259,10 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
267 | 259 | ||
268 | return 0; | 260 | return 0; |
269 | 261 | ||
270 | err5: | ||
271 | free_irq(irq, pdev); | ||
272 | err4: | 262 | err4: |
273 | input_free_device(input); | 263 | free_irq(irq, pdev); |
274 | err3: | 264 | err3: |
275 | clk_put(priv->clk); | 265 | input_free_device(input); |
276 | err2: | 266 | err2: |
277 | iounmap(priv->iomem_base); | 267 | iounmap(priv->iomem_base); |
278 | err1: | 268 | err1: |
@@ -292,8 +282,8 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
292 | free_irq(platform_get_irq(pdev, 0), pdev); | 282 | free_irq(platform_get_irq(pdev, 0), pdev); |
293 | iounmap(priv->iomem_base); | 283 | iounmap(priv->iomem_base); |
294 | 284 | ||
295 | clk_disable(priv->clk); | 285 | pm_runtime_put_sync(&pdev->dev); |
296 | clk_put(priv->clk); | 286 | pm_runtime_disable(&pdev->dev); |
297 | 287 | ||
298 | platform_set_drvdata(pdev, NULL); | 288 | platform_set_drvdata(pdev, NULL); |
299 | kfree(priv); | 289 | kfree(priv); |
@@ -301,6 +291,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
301 | return 0; | 291 | return 0; |
302 | } | 292 | } |
303 | 293 | ||
294 | #if CONFIG_PM_SLEEP | ||
304 | static int sh_keysc_suspend(struct device *dev) | 295 | static int sh_keysc_suspend(struct device *dev) |
305 | { | 296 | { |
306 | struct platform_device *pdev = to_platform_device(dev); | 297 | struct platform_device *pdev = to_platform_device(dev); |
@@ -311,14 +302,13 @@ static int sh_keysc_suspend(struct device *dev) | |||
311 | value = sh_keysc_read(priv, KYCR1); | 302 | value = sh_keysc_read(priv, KYCR1); |
312 | 303 | ||
313 | if (device_may_wakeup(dev)) { | 304 | if (device_may_wakeup(dev)) { |
314 | value |= 0x80; | 305 | sh_keysc_write(priv, KYCR1, value | 0x80); |
315 | enable_irq_wake(irq); | 306 | enable_irq_wake(irq); |
316 | } else { | 307 | } else { |
317 | value &= ~0x80; | 308 | sh_keysc_write(priv, KYCR1, value & ~0x80); |
309 | pm_runtime_put_sync(dev); | ||
318 | } | 310 | } |
319 | 311 | ||
320 | sh_keysc_write(priv, KYCR1, value); | ||
321 | |||
322 | return 0; | 312 | return 0; |
323 | } | 313 | } |
324 | 314 | ||
@@ -329,16 +319,17 @@ static int sh_keysc_resume(struct device *dev) | |||
329 | 319 | ||
330 | if (device_may_wakeup(dev)) | 320 | if (device_may_wakeup(dev)) |
331 | disable_irq_wake(irq); | 321 | disable_irq_wake(irq); |
322 | else | ||
323 | pm_runtime_get_sync(dev); | ||
332 | 324 | ||
333 | return 0; | 325 | return 0; |
334 | } | 326 | } |
327 | #endif | ||
335 | 328 | ||
336 | static const struct dev_pm_ops sh_keysc_dev_pm_ops = { | 329 | static SIMPLE_DEV_PM_OPS(sh_keysc_dev_pm_ops, |
337 | .suspend = sh_keysc_suspend, | 330 | sh_keysc_suspend, sh_keysc_resume); |
338 | .resume = sh_keysc_resume, | ||
339 | }; | ||
340 | 331 | ||
341 | struct platform_driver sh_keysc_device_driver = { | 332 | static struct platform_driver sh_keysc_device_driver = { |
342 | .probe = sh_keysc_probe, | 333 | .probe = sh_keysc_probe, |
343 | .remove = __devexit_p(sh_keysc_remove), | 334 | .remove = __devexit_p(sh_keysc_remove), |
344 | .driver = { | 335 | .driver = { |
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c new file mode 100644 index 000000000000..d712dffd2157 --- /dev/null +++ b/drivers/input/keyboard/spear-keyboard.c | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * SPEAr Keyboard Driver | ||
3 | * Based on omap-keypad driver | ||
4 | * | ||
5 | * Copyright (C) 2010 ST Microelectronics | ||
6 | * Rajeev Kumar<rajeev-dlh.kumar@st.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk.h> | ||
14 | #include <linux/errno.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/input.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/pm_wakeup.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <plat/keyboard.h> | ||
27 | |||
28 | /* Keyboard Registers */ | ||
29 | #define MODE_REG 0x00 /* 16 bit reg */ | ||
30 | #define STATUS_REG 0x0C /* 2 bit reg */ | ||
31 | #define DATA_REG 0x10 /* 8 bit reg */ | ||
32 | #define INTR_MASK 0x54 | ||
33 | |||
34 | /* Register Values */ | ||
35 | /* | ||
36 | * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode | ||
37 | * control register as 1010010(82MHZ) | ||
38 | */ | ||
39 | #define PCLK_FREQ_MSK 0xA400 /* 82 MHz */ | ||
40 | #define START_SCAN 0x0100 | ||
41 | #define SCAN_RATE_10 0x0000 | ||
42 | #define SCAN_RATE_20 0x0004 | ||
43 | #define SCAN_RATE_40 0x0008 | ||
44 | #define SCAN_RATE_80 0x000C | ||
45 | #define MODE_KEYBOARD 0x0002 | ||
46 | #define DATA_AVAIL 0x2 | ||
47 | |||
48 | #define KEY_MASK 0xFF000000 | ||
49 | #define KEY_VALUE 0x00FFFFFF | ||
50 | #define ROW_MASK 0xF0 | ||
51 | #define COLUMN_MASK 0x0F | ||
52 | #define ROW_SHIFT 4 | ||
53 | |||
54 | struct spear_kbd { | ||
55 | struct input_dev *input; | ||
56 | struct resource *res; | ||
57 | void __iomem *io_base; | ||
58 | struct clk *clk; | ||
59 | unsigned int irq; | ||
60 | unsigned short last_key; | ||
61 | unsigned short keycodes[256]; | ||
62 | }; | ||
63 | |||
64 | static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) | ||
65 | { | ||
66 | struct spear_kbd *kbd = dev_id; | ||
67 | struct input_dev *input = kbd->input; | ||
68 | unsigned int key; | ||
69 | u8 sts, val; | ||
70 | |||
71 | sts = readb(kbd->io_base + STATUS_REG); | ||
72 | if (!(sts & DATA_AVAIL)) | ||
73 | return IRQ_NONE; | ||
74 | |||
75 | if (kbd->last_key != KEY_RESERVED) { | ||
76 | input_report_key(input, kbd->last_key, 0); | ||
77 | kbd->last_key = KEY_RESERVED; | ||
78 | } | ||
79 | |||
80 | /* following reads active (row, col) pair */ | ||
81 | val = readb(kbd->io_base + DATA_REG); | ||
82 | key = kbd->keycodes[val]; | ||
83 | |||
84 | input_event(input, EV_MSC, MSC_SCAN, val); | ||
85 | input_report_key(input, key, 1); | ||
86 | input_sync(input); | ||
87 | |||
88 | kbd->last_key = key; | ||
89 | |||
90 | /* clear interrupt */ | ||
91 | writeb(0, kbd->io_base + STATUS_REG); | ||
92 | |||
93 | return IRQ_HANDLED; | ||
94 | } | ||
95 | |||
96 | static int spear_kbd_open(struct input_dev *dev) | ||
97 | { | ||
98 | struct spear_kbd *kbd = input_get_drvdata(dev); | ||
99 | int error; | ||
100 | u16 val; | ||
101 | |||
102 | kbd->last_key = KEY_RESERVED; | ||
103 | |||
104 | error = clk_enable(kbd->clk); | ||
105 | if (error) | ||
106 | return error; | ||
107 | |||
108 | /* program keyboard */ | ||
109 | val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK; | ||
110 | writew(val, kbd->io_base + MODE_REG); | ||
111 | writeb(1, kbd->io_base + STATUS_REG); | ||
112 | |||
113 | /* start key scan */ | ||
114 | val = readw(kbd->io_base + MODE_REG); | ||
115 | val |= START_SCAN; | ||
116 | writew(val, kbd->io_base + MODE_REG); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static void spear_kbd_close(struct input_dev *dev) | ||
122 | { | ||
123 | struct spear_kbd *kbd = input_get_drvdata(dev); | ||
124 | u16 val; | ||
125 | |||
126 | /* stop key scan */ | ||
127 | val = readw(kbd->io_base + MODE_REG); | ||
128 | val &= ~START_SCAN; | ||
129 | writew(val, kbd->io_base + MODE_REG); | ||
130 | |||
131 | clk_disable(kbd->clk); | ||
132 | |||
133 | kbd->last_key = KEY_RESERVED; | ||
134 | } | ||
135 | |||
136 | static int __devinit spear_kbd_probe(struct platform_device *pdev) | ||
137 | { | ||
138 | const struct kbd_platform_data *pdata = pdev->dev.platform_data; | ||
139 | const struct matrix_keymap_data *keymap; | ||
140 | struct spear_kbd *kbd; | ||
141 | struct input_dev *input_dev; | ||
142 | struct resource *res; | ||
143 | int irq; | ||
144 | int error; | ||
145 | |||
146 | if (!pdata) { | ||
147 | dev_err(&pdev->dev, "Invalid platform data\n"); | ||
148 | return -EINVAL; | ||
149 | } | ||
150 | |||
151 | keymap = pdata->keymap; | ||
152 | if (!keymap) { | ||
153 | dev_err(&pdev->dev, "no keymap defined\n"); | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | |||
157 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
158 | if (!res) { | ||
159 | dev_err(&pdev->dev, "no keyboard resource defined\n"); | ||
160 | return -EBUSY; | ||
161 | } | ||
162 | |||
163 | irq = platform_get_irq(pdev, 0); | ||
164 | if (irq < 0) { | ||
165 | dev_err(&pdev->dev, "not able to get irq for the device\n"); | ||
166 | return irq; | ||
167 | } | ||
168 | |||
169 | kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); | ||
170 | input_dev = input_allocate_device(); | ||
171 | if (!kbd || !input_dev) { | ||
172 | dev_err(&pdev->dev, "out of memory\n"); | ||
173 | error = -ENOMEM; | ||
174 | goto err_free_mem; | ||
175 | } | ||
176 | |||
177 | kbd->input = input_dev; | ||
178 | kbd->irq = irq; | ||
179 | kbd->res = request_mem_region(res->start, resource_size(res), | ||
180 | pdev->name); | ||
181 | if (!kbd->res) { | ||
182 | dev_err(&pdev->dev, "keyboard region already claimed\n"); | ||
183 | error = -EBUSY; | ||
184 | goto err_free_mem; | ||
185 | } | ||
186 | |||
187 | kbd->io_base = ioremap(res->start, resource_size(res)); | ||
188 | if (!kbd->io_base) { | ||
189 | dev_err(&pdev->dev, "ioremap failed for kbd_region\n"); | ||
190 | error = -ENOMEM; | ||
191 | goto err_release_mem_region; | ||
192 | } | ||
193 | |||
194 | kbd->clk = clk_get(&pdev->dev, NULL); | ||
195 | if (IS_ERR(kbd->clk)) { | ||
196 | error = PTR_ERR(kbd->clk); | ||
197 | goto err_iounmap; | ||
198 | } | ||
199 | |||
200 | input_dev->name = "Spear Keyboard"; | ||
201 | input_dev->phys = "keyboard/input0"; | ||
202 | input_dev->dev.parent = &pdev->dev; | ||
203 | input_dev->id.bustype = BUS_HOST; | ||
204 | input_dev->id.vendor = 0x0001; | ||
205 | input_dev->id.product = 0x0001; | ||
206 | input_dev->id.version = 0x0100; | ||
207 | input_dev->open = spear_kbd_open; | ||
208 | input_dev->close = spear_kbd_close; | ||
209 | |||
210 | __set_bit(EV_KEY, input_dev->evbit); | ||
211 | if (pdata->rep) | ||
212 | __set_bit(EV_REP, input_dev->evbit); | ||
213 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
214 | |||
215 | input_dev->keycode = kbd->keycodes; | ||
216 | input_dev->keycodesize = sizeof(kbd->keycodes[0]); | ||
217 | input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes); | ||
218 | |||
219 | matrix_keypad_build_keymap(keymap, ROW_SHIFT, | ||
220 | input_dev->keycode, input_dev->keybit); | ||
221 | |||
222 | input_set_drvdata(input_dev, kbd); | ||
223 | |||
224 | error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd); | ||
225 | if (error) { | ||
226 | dev_err(&pdev->dev, "request_irq fail\n"); | ||
227 | goto err_put_clk; | ||
228 | } | ||
229 | |||
230 | error = input_register_device(input_dev); | ||
231 | if (error) { | ||
232 | dev_err(&pdev->dev, "Unable to register keyboard device\n"); | ||
233 | goto err_free_irq; | ||
234 | } | ||
235 | |||
236 | device_init_wakeup(&pdev->dev, 1); | ||
237 | platform_set_drvdata(pdev, kbd); | ||
238 | |||
239 | return 0; | ||
240 | |||
241 | err_free_irq: | ||
242 | free_irq(kbd->irq, kbd); | ||
243 | err_put_clk: | ||
244 | clk_put(kbd->clk); | ||
245 | err_iounmap: | ||
246 | iounmap(kbd->io_base); | ||
247 | err_release_mem_region: | ||
248 | release_mem_region(res->start, resource_size(res)); | ||
249 | err_free_mem: | ||
250 | input_free_device(input_dev); | ||
251 | kfree(kbd); | ||
252 | |||
253 | return error; | ||
254 | } | ||
255 | |||
256 | static int __devexit spear_kbd_remove(struct platform_device *pdev) | ||
257 | { | ||
258 | struct spear_kbd *kbd = platform_get_drvdata(pdev); | ||
259 | |||
260 | free_irq(kbd->irq, kbd); | ||
261 | input_unregister_device(kbd->input); | ||
262 | clk_put(kbd->clk); | ||
263 | iounmap(kbd->io_base); | ||
264 | release_mem_region(kbd->res->start, resource_size(kbd->res)); | ||
265 | kfree(kbd); | ||
266 | |||
267 | device_init_wakeup(&pdev->dev, 1); | ||
268 | platform_set_drvdata(pdev, NULL); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | #ifdef CONFIG_PM | ||
274 | static int spear_kbd_suspend(struct device *dev) | ||
275 | { | ||
276 | struct platform_device *pdev = to_platform_device(dev); | ||
277 | struct spear_kbd *kbd = platform_get_drvdata(pdev); | ||
278 | struct input_dev *input_dev = kbd->input; | ||
279 | |||
280 | mutex_lock(&input_dev->mutex); | ||
281 | |||
282 | if (input_dev->users) | ||
283 | clk_enable(kbd->clk); | ||
284 | |||
285 | if (device_may_wakeup(&pdev->dev)) | ||
286 | enable_irq_wake(kbd->irq); | ||
287 | |||
288 | mutex_unlock(&input_dev->mutex); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int spear_kbd_resume(struct device *dev) | ||
294 | { | ||
295 | struct platform_device *pdev = to_platform_device(dev); | ||
296 | struct spear_kbd *kbd = platform_get_drvdata(pdev); | ||
297 | struct input_dev *input_dev = kbd->input; | ||
298 | |||
299 | mutex_lock(&input_dev->mutex); | ||
300 | |||
301 | if (device_may_wakeup(&pdev->dev)) | ||
302 | disable_irq_wake(kbd->irq); | ||
303 | |||
304 | if (input_dev->users) | ||
305 | clk_enable(kbd->clk); | ||
306 | |||
307 | mutex_unlock(&input_dev->mutex); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static const struct dev_pm_ops spear_kbd_pm_ops = { | ||
313 | .suspend = spear_kbd_suspend, | ||
314 | .resume = spear_kbd_resume, | ||
315 | }; | ||
316 | #endif | ||
317 | |||
318 | static struct platform_driver spear_kbd_driver = { | ||
319 | .probe = spear_kbd_probe, | ||
320 | .remove = __devexit_p(spear_kbd_remove), | ||
321 | .driver = { | ||
322 | .name = "keyboard", | ||
323 | .owner = THIS_MODULE, | ||
324 | #ifdef CONFIG_PM | ||
325 | .pm = &spear_kbd_pm_ops, | ||
326 | #endif | ||
327 | }, | ||
328 | }; | ||
329 | |||
330 | static int __init spear_kbd_init(void) | ||
331 | { | ||
332 | return platform_driver_register(&spear_kbd_driver); | ||
333 | } | ||
334 | module_init(spear_kbd_init); | ||
335 | |||
336 | static void __exit spear_kbd_exit(void) | ||
337 | { | ||
338 | platform_driver_unregister(&spear_kbd_driver); | ||
339 | } | ||
340 | module_exit(spear_kbd_exit); | ||
341 | |||
342 | MODULE_AUTHOR("Rajeev Kumar"); | ||
343 | MODULE_DESCRIPTION("SPEAr Keyboard Driver"); | ||
344 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c new file mode 100644 index 000000000000..99122f59e988 --- /dev/null +++ b/drivers/input/keyboard/tc3589x-keypad.c | |||
@@ -0,0 +1,472 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Jayeeta Banerjee <jayeeta.banerjee@stericsson.com> | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
6 | * | ||
7 | * License Terms: GNU General Public License, version 2 | ||
8 | * | ||
9 | * TC35893 MFD Keypad Controller driver | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/input/matrix_keypad.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/mfd/tc3589x.h> | ||
21 | |||
22 | /* Maximum supported keypad matrix row/columns size */ | ||
23 | #define TC3589x_MAX_KPROW 8 | ||
24 | #define TC3589x_MAX_KPCOL 12 | ||
25 | |||
26 | /* keypad related Constants */ | ||
27 | #define TC3589x_MAX_DEBOUNCE_SETTLE 0xFF | ||
28 | #define DEDICATED_KEY_VAL 0xFF | ||
29 | |||
30 | /* Pull up/down masks */ | ||
31 | #define TC3589x_NO_PULL_MASK 0x0 | ||
32 | #define TC3589x_PULL_DOWN_MASK 0x1 | ||
33 | #define TC3589x_PULL_UP_MASK 0x2 | ||
34 | #define TC3589x_PULLUP_ALL_MASK 0xAA | ||
35 | #define TC3589x_IO_PULL_VAL(index, mask) ((mask)<<((index)%4)*2)) | ||
36 | |||
37 | /* Bit masks for IOCFG register */ | ||
38 | #define IOCFG_BALLCFG 0x01 | ||
39 | #define IOCFG_IG 0x08 | ||
40 | |||
41 | #define KP_EVCODE_COL_MASK 0x0F | ||
42 | #define KP_EVCODE_ROW_MASK 0x70 | ||
43 | #define KP_RELEASE_EVT_MASK 0x80 | ||
44 | |||
45 | #define KP_ROW_SHIFT 4 | ||
46 | |||
47 | #define KP_NO_VALID_KEY_MASK 0x7F | ||
48 | |||
49 | /* bit masks for RESTCTRL register */ | ||
50 | #define TC3589x_KBDRST 0x2 | ||
51 | #define TC3589x_IRQRST 0x10 | ||
52 | #define TC3589x_RESET_ALL 0x1B | ||
53 | |||
54 | /* KBDMFS register bit mask */ | ||
55 | #define TC3589x_KBDMFS_EN 0x1 | ||
56 | |||
57 | /* CLKEN register bitmask */ | ||
58 | #define KPD_CLK_EN 0x1 | ||
59 | |||
60 | /* RSTINTCLR register bit mask */ | ||
61 | #define IRQ_CLEAR 0x1 | ||
62 | |||
63 | /* bit masks for keyboard interrupts*/ | ||
64 | #define TC3589x_EVT_LOSS_INT 0x8 | ||
65 | #define TC3589x_EVT_INT 0x4 | ||
66 | #define TC3589x_KBD_LOSS_INT 0x2 | ||
67 | #define TC3589x_KBD_INT 0x1 | ||
68 | |||
69 | /* bit masks for keyboard interrupt clear*/ | ||
70 | #define TC3589x_EVT_INT_CLR 0x2 | ||
71 | #define TC3589x_KBD_INT_CLR 0x1 | ||
72 | |||
73 | #define TC3589x_KBD_KEYMAP_SIZE 64 | ||
74 | |||
75 | /** | ||
76 | * struct tc_keypad - data structure used by keypad driver | ||
77 | * @input: pointer to input device object | ||
78 | * @board: keypad platform device | ||
79 | * @krow: number of rows | ||
80 | * @kcol: number of coloumns | ||
81 | * @keymap: matrix scan code table for keycodes | ||
82 | */ | ||
83 | struct tc_keypad { | ||
84 | struct tc3589x *tc3589x; | ||
85 | struct input_dev *input; | ||
86 | const struct tc3589x_keypad_platform_data *board; | ||
87 | unsigned int krow; | ||
88 | unsigned int kcol; | ||
89 | unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE]; | ||
90 | bool keypad_stopped; | ||
91 | }; | ||
92 | |||
93 | static int __devinit tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) | ||
94 | { | ||
95 | int ret; | ||
96 | struct tc3589x *tc3589x = keypad->tc3589x; | ||
97 | u8 settle_time = keypad->board->settle_time; | ||
98 | u8 dbounce_period = keypad->board->debounce_period; | ||
99 | u8 rows = keypad->board->krow & 0xf; /* mask out the nibble */ | ||
100 | u8 column = keypad->board->kcol & 0xf; /* mask out the nibble */ | ||
101 | |||
102 | /* validate platform configurations */ | ||
103 | if (keypad->board->kcol > TC3589x_MAX_KPCOL || | ||
104 | keypad->board->krow > TC3589x_MAX_KPROW || | ||
105 | keypad->board->debounce_period > TC3589x_MAX_DEBOUNCE_SETTLE || | ||
106 | keypad->board->settle_time > TC3589x_MAX_DEBOUNCE_SETTLE) | ||
107 | return -EINVAL; | ||
108 | |||
109 | /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */ | ||
110 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE, | ||
111 | (rows << KP_ROW_SHIFT) | column); | ||
112 | if (ret < 0) | ||
113 | return ret; | ||
114 | |||
115 | /* configure dedicated key config, no dedicated key selected */ | ||
116 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_LSB, DEDICATED_KEY_VAL); | ||
117 | if (ret < 0) | ||
118 | return ret; | ||
119 | |||
120 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_MSB, DEDICATED_KEY_VAL); | ||
121 | if (ret < 0) | ||
122 | return ret; | ||
123 | |||
124 | /* Configure settle time */ | ||
125 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, settle_time); | ||
126 | if (ret < 0) | ||
127 | return ret; | ||
128 | |||
129 | /* Configure debounce time */ | ||
130 | ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, dbounce_period); | ||
131 | if (ret < 0) | ||
132 | return ret; | ||
133 | |||
134 | /* Start of initialise keypad GPIOs */ | ||
135 | ret = tc3589x_set_bits(tc3589x, TC3589x_IOCFG, 0x0, IOCFG_IG); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | /* Configure pull-up resistors for all row GPIOs */ | ||
140 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_LSB, | ||
141 | TC3589x_PULLUP_ALL_MASK); | ||
142 | if (ret < 0) | ||
143 | return ret; | ||
144 | |||
145 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_MSB, | ||
146 | TC3589x_PULLUP_ALL_MASK); | ||
147 | if (ret < 0) | ||
148 | return ret; | ||
149 | |||
150 | /* Configure pull-up resistors for all column GPIOs */ | ||
151 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_LSB, | ||
152 | TC3589x_PULLUP_ALL_MASK); | ||
153 | if (ret < 0) | ||
154 | return ret; | ||
155 | |||
156 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_MSB, | ||
157 | TC3589x_PULLUP_ALL_MASK); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | |||
161 | ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG2_LSB, | ||
162 | TC3589x_PULLUP_ALL_MASK); | ||
163 | |||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | #define TC35893_DATA_REGS 4 | ||
168 | #define TC35893_KEYCODE_FIFO_EMPTY 0x7f | ||
169 | #define TC35893_KEYCODE_FIFO_CLEAR 0xff | ||
170 | #define TC35893_KEYPAD_ROW_SHIFT 0x3 | ||
171 | |||
172 | static irqreturn_t tc3589x_keypad_irq(int irq, void *dev) | ||
173 | { | ||
174 | struct tc_keypad *keypad = dev; | ||
175 | struct tc3589x *tc3589x = keypad->tc3589x; | ||
176 | u8 i, row_index, col_index, kbd_code, up; | ||
177 | u8 code; | ||
178 | |||
179 | for (i = 0; i < TC35893_DATA_REGS * 2; i++) { | ||
180 | kbd_code = tc3589x_reg_read(tc3589x, TC3589x_EVTCODE_FIFO); | ||
181 | |||
182 | /* loop till fifo is empty and no more keys are pressed */ | ||
183 | if (kbd_code == TC35893_KEYCODE_FIFO_EMPTY || | ||
184 | kbd_code == TC35893_KEYCODE_FIFO_CLEAR) | ||
185 | continue; | ||
186 | |||
187 | /* valid key is found */ | ||
188 | col_index = kbd_code & KP_EVCODE_COL_MASK; | ||
189 | row_index = (kbd_code & KP_EVCODE_ROW_MASK) >> KP_ROW_SHIFT; | ||
190 | code = MATRIX_SCAN_CODE(row_index, col_index, | ||
191 | TC35893_KEYPAD_ROW_SHIFT); | ||
192 | up = kbd_code & KP_RELEASE_EVT_MASK; | ||
193 | |||
194 | input_event(keypad->input, EV_MSC, MSC_SCAN, code); | ||
195 | input_report_key(keypad->input, keypad->keymap[code], !up); | ||
196 | input_sync(keypad->input); | ||
197 | } | ||
198 | |||
199 | /* clear IRQ */ | ||
200 | tc3589x_set_bits(tc3589x, TC3589x_KBDIC, | ||
201 | 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR); | ||
202 | /* enable IRQ */ | ||
203 | tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, | ||
204 | 0x0, TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT); | ||
205 | |||
206 | return IRQ_HANDLED; | ||
207 | } | ||
208 | |||
209 | static int tc3589x_keypad_enable(struct tc_keypad *keypad) | ||
210 | { | ||
211 | struct tc3589x *tc3589x = keypad->tc3589x; | ||
212 | int ret; | ||
213 | |||
214 | /* pull the keypad module out of reset */ | ||
215 | ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x0); | ||
216 | if (ret < 0) | ||
217 | return ret; | ||
218 | |||
219 | /* configure KBDMFS */ | ||
220 | ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMFS, 0x0, TC3589x_KBDMFS_EN); | ||
221 | if (ret < 0) | ||
222 | return ret; | ||
223 | |||
224 | /* enable the keypad clock */ | ||
225 | ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x0, KPD_CLK_EN); | ||
226 | if (ret < 0) | ||
227 | return ret; | ||
228 | |||
229 | /* clear pending IRQs */ | ||
230 | ret = tc3589x_set_bits(tc3589x, TC3589x_RSTINTCLR, 0x0, 0x1); | ||
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | |||
234 | /* enable the IRQs */ | ||
235 | ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 0x0, | ||
236 | TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT); | ||
237 | if (ret < 0) | ||
238 | return ret; | ||
239 | |||
240 | keypad->keypad_stopped = false; | ||
241 | |||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | static int tc3589x_keypad_disable(struct tc_keypad *keypad) | ||
246 | { | ||
247 | struct tc3589x *tc3589x = keypad->tc3589x; | ||
248 | int ret; | ||
249 | |||
250 | /* clear IRQ */ | ||
251 | ret = tc3589x_set_bits(tc3589x, TC3589x_KBDIC, | ||
252 | 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR); | ||
253 | if (ret < 0) | ||
254 | return ret; | ||
255 | |||
256 | /* disable all interrupts */ | ||
257 | ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, | ||
258 | ~(TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT), 0x0); | ||
259 | if (ret < 0) | ||
260 | return ret; | ||
261 | |||
262 | /* disable the keypad module */ | ||
263 | ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x1, 0x0); | ||
264 | if (ret < 0) | ||
265 | return ret; | ||
266 | |||
267 | /* put the keypad module into reset */ | ||
268 | ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x1); | ||
269 | |||
270 | keypad->keypad_stopped = true; | ||
271 | |||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | static int tc3589x_keypad_open(struct input_dev *input) | ||
276 | { | ||
277 | int error; | ||
278 | struct tc_keypad *keypad = input_get_drvdata(input); | ||
279 | |||
280 | /* enable the keypad module */ | ||
281 | error = tc3589x_keypad_enable(keypad); | ||
282 | if (error < 0) { | ||
283 | dev_err(&input->dev, "failed to enable keypad module\n"); | ||
284 | return error; | ||
285 | } | ||
286 | |||
287 | error = tc3589x_keypad_init_key_hardware(keypad); | ||
288 | if (error < 0) { | ||
289 | dev_err(&input->dev, "failed to configure keypad module\n"); | ||
290 | return error; | ||
291 | } | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static void tc3589x_keypad_close(struct input_dev *input) | ||
297 | { | ||
298 | struct tc_keypad *keypad = input_get_drvdata(input); | ||
299 | |||
300 | /* disable the keypad module */ | ||
301 | tc3589x_keypad_disable(keypad); | ||
302 | } | ||
303 | |||
304 | static int __devinit tc3589x_keypad_probe(struct platform_device *pdev) | ||
305 | { | ||
306 | struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); | ||
307 | struct tc_keypad *keypad; | ||
308 | struct input_dev *input; | ||
309 | const struct tc3589x_keypad_platform_data *plat; | ||
310 | int error, irq; | ||
311 | |||
312 | plat = tc3589x->pdata->keypad; | ||
313 | if (!plat) { | ||
314 | dev_err(&pdev->dev, "invalid keypad platform data\n"); | ||
315 | return -EINVAL; | ||
316 | } | ||
317 | |||
318 | irq = platform_get_irq(pdev, 0); | ||
319 | if (irq < 0) | ||
320 | return irq; | ||
321 | |||
322 | keypad = kzalloc(sizeof(struct tc_keypad), GFP_KERNEL); | ||
323 | input = input_allocate_device(); | ||
324 | if (!keypad || !input) { | ||
325 | dev_err(&pdev->dev, "failed to allocate keypad memory\n"); | ||
326 | error = -ENOMEM; | ||
327 | goto err_free_mem; | ||
328 | } | ||
329 | |||
330 | keypad->board = plat; | ||
331 | keypad->input = input; | ||
332 | keypad->tc3589x = tc3589x; | ||
333 | |||
334 | input->id.bustype = BUS_I2C; | ||
335 | input->name = pdev->name; | ||
336 | input->dev.parent = &pdev->dev; | ||
337 | |||
338 | input->keycode = keypad->keymap; | ||
339 | input->keycodesize = sizeof(keypad->keymap[0]); | ||
340 | input->keycodemax = ARRAY_SIZE(keypad->keymap); | ||
341 | |||
342 | input->open = tc3589x_keypad_open; | ||
343 | input->close = tc3589x_keypad_close; | ||
344 | |||
345 | input_set_drvdata(input, keypad); | ||
346 | |||
347 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
348 | |||
349 | __set_bit(EV_KEY, input->evbit); | ||
350 | if (!plat->no_autorepeat) | ||
351 | __set_bit(EV_REP, input->evbit); | ||
352 | |||
353 | matrix_keypad_build_keymap(plat->keymap_data, 0x3, | ||
354 | input->keycode, input->keybit); | ||
355 | |||
356 | error = request_threaded_irq(irq, NULL, | ||
357 | tc3589x_keypad_irq, plat->irqtype, | ||
358 | "tc3589x-keypad", keypad); | ||
359 | if (error < 0) { | ||
360 | dev_err(&pdev->dev, | ||
361 | "Could not allocate irq %d,error %d\n", | ||
362 | irq, error); | ||
363 | goto err_free_mem; | ||
364 | } | ||
365 | |||
366 | error = input_register_device(input); | ||
367 | if (error) { | ||
368 | dev_err(&pdev->dev, "Could not register input device\n"); | ||
369 | goto err_free_irq; | ||
370 | } | ||
371 | |||
372 | /* let platform decide if keypad is a wakeup source or not */ | ||
373 | device_init_wakeup(&pdev->dev, plat->enable_wakeup); | ||
374 | device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup); | ||
375 | |||
376 | platform_set_drvdata(pdev, keypad); | ||
377 | |||
378 | return 0; | ||
379 | |||
380 | err_free_irq: | ||
381 | free_irq(irq, keypad); | ||
382 | err_free_mem: | ||
383 | input_free_device(input); | ||
384 | kfree(keypad); | ||
385 | return error; | ||
386 | } | ||
387 | |||
388 | static int __devexit tc3589x_keypad_remove(struct platform_device *pdev) | ||
389 | { | ||
390 | struct tc_keypad *keypad = platform_get_drvdata(pdev); | ||
391 | int irq = platform_get_irq(pdev, 0); | ||
392 | |||
393 | if (!keypad->keypad_stopped) | ||
394 | tc3589x_keypad_disable(keypad); | ||
395 | |||
396 | free_irq(irq, keypad); | ||
397 | |||
398 | input_unregister_device(keypad->input); | ||
399 | |||
400 | kfree(keypad); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | #ifdef CONFIG_PM_SLEEP | ||
406 | static int tc3589x_keypad_suspend(struct device *dev) | ||
407 | { | ||
408 | struct platform_device *pdev = to_platform_device(dev); | ||
409 | struct tc_keypad *keypad = platform_get_drvdata(pdev); | ||
410 | int irq = platform_get_irq(pdev, 0); | ||
411 | |||
412 | /* keypad is already off; we do nothing */ | ||
413 | if (keypad->keypad_stopped) | ||
414 | return 0; | ||
415 | |||
416 | /* if device is not a wakeup source, disable it for powersave */ | ||
417 | if (!device_may_wakeup(&pdev->dev)) | ||
418 | tc3589x_keypad_disable(keypad); | ||
419 | else | ||
420 | enable_irq_wake(irq); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static int tc3589x_keypad_resume(struct device *dev) | ||
426 | { | ||
427 | struct platform_device *pdev = to_platform_device(dev); | ||
428 | struct tc_keypad *keypad = platform_get_drvdata(pdev); | ||
429 | int irq = platform_get_irq(pdev, 0); | ||
430 | |||
431 | if (!keypad->keypad_stopped) | ||
432 | return 0; | ||
433 | |||
434 | /* enable the device to resume normal operations */ | ||
435 | if (!device_may_wakeup(&pdev->dev)) | ||
436 | tc3589x_keypad_enable(keypad); | ||
437 | else | ||
438 | disable_irq_wake(irq); | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | #endif | ||
443 | |||
444 | static SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops, | ||
445 | tc3589x_keypad_suspend, tc3589x_keypad_resume); | ||
446 | |||
447 | static struct platform_driver tc3589x_keypad_driver = { | ||
448 | .driver = { | ||
449 | .name = "tc3589x-keypad", | ||
450 | .owner = THIS_MODULE, | ||
451 | .pm = &tc3589x_keypad_dev_pm_ops, | ||
452 | }, | ||
453 | .probe = tc3589x_keypad_probe, | ||
454 | .remove = __devexit_p(tc3589x_keypad_remove), | ||
455 | }; | ||
456 | |||
457 | static int __init tc3589x_keypad_init(void) | ||
458 | { | ||
459 | return platform_driver_register(&tc3589x_keypad_driver); | ||
460 | } | ||
461 | module_init(tc3589x_keypad_init); | ||
462 | |||
463 | static void __exit tc3589x_keypad_exit(void) | ||
464 | { | ||
465 | return platform_driver_unregister(&tc3589x_keypad_driver); | ||
466 | } | ||
467 | module_exit(tc3589x_keypad_exit); | ||
468 | |||
469 | MODULE_LICENSE("GPL v2"); | ||
470 | MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer"); | ||
471 | MODULE_DESCRIPTION("TC35893 Keypad Driver"); | ||
472 | MODULE_ALIAS("platform:tc3589x-keypad"); | ||
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c index 00137bebcf97..3afea3f89718 100644 --- a/drivers/input/keyboard/tca6416-keypad.c +++ b/drivers/input/keyboard/tca6416-keypad.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | static const struct i2c_device_id tca6416_id[] = { | 30 | static const struct i2c_device_id tca6416_id[] = { |
31 | { "tca6416-keys", 16, }, | 31 | { "tca6416-keys", 16, }, |
32 | { "tca6408-keys", 8, }, | ||
32 | { } | 33 | { } |
33 | }; | 34 | }; |
34 | MODULE_DEVICE_TABLE(i2c, tca6416_id); | 35 | MODULE_DEVICE_TABLE(i2c, tca6416_id); |
@@ -46,8 +47,9 @@ struct tca6416_keypad_chip { | |||
46 | struct i2c_client *client; | 47 | struct i2c_client *client; |
47 | struct input_dev *input; | 48 | struct input_dev *input; |
48 | struct delayed_work dwork; | 49 | struct delayed_work dwork; |
49 | u16 pinmask; | 50 | int io_size; |
50 | int irqnum; | 51 | int irqnum; |
52 | u16 pinmask; | ||
51 | bool use_polling; | 53 | bool use_polling; |
52 | struct tca6416_button buttons[0]; | 54 | struct tca6416_button buttons[0]; |
53 | }; | 55 | }; |
@@ -56,7 +58,9 @@ static int tca6416_write_reg(struct tca6416_keypad_chip *chip, int reg, u16 val) | |||
56 | { | 58 | { |
57 | int error; | 59 | int error; |
58 | 60 | ||
59 | error = i2c_smbus_write_word_data(chip->client, reg << 1, val); | 61 | error = chip->io_size > 8 ? |
62 | i2c_smbus_write_word_data(chip->client, reg << 1, val) : | ||
63 | i2c_smbus_write_byte_data(chip->client, reg, val); | ||
60 | if (error < 0) { | 64 | if (error < 0) { |
61 | dev_err(&chip->client->dev, | 65 | dev_err(&chip->client->dev, |
62 | "%s failed, reg: %d, val: %d, error: %d\n", | 66 | "%s failed, reg: %d, val: %d, error: %d\n", |
@@ -71,7 +75,9 @@ static int tca6416_read_reg(struct tca6416_keypad_chip *chip, int reg, u16 *val) | |||
71 | { | 75 | { |
72 | int retval; | 76 | int retval; |
73 | 77 | ||
74 | retval = i2c_smbus_read_word_data(chip->client, reg << 1); | 78 | retval = chip->io_size > 8 ? |
79 | i2c_smbus_read_word_data(chip->client, reg << 1) : | ||
80 | i2c_smbus_read_byte_data(chip->client, reg); | ||
75 | if (retval < 0) { | 81 | if (retval < 0) { |
76 | dev_err(&chip->client->dev, "%s failed, reg: %d, error: %d\n", | 82 | dev_err(&chip->client->dev, "%s failed, reg: %d, error: %d\n", |
77 | __func__, reg, retval); | 83 | __func__, reg, retval); |
@@ -224,6 +230,7 @@ static int __devinit tca6416_keypad_probe(struct i2c_client *client, | |||
224 | 230 | ||
225 | chip->client = client; | 231 | chip->client = client; |
226 | chip->input = input; | 232 | chip->input = input; |
233 | chip->io_size = id->driver_data; | ||
227 | chip->pinmask = pdata->pinmask; | 234 | chip->pinmask = pdata->pinmask; |
228 | chip->use_polling = pdata->use_polling; | 235 | chip->use_polling = pdata->use_polling; |
229 | 236 | ||
@@ -290,6 +297,7 @@ static int __devinit tca6416_keypad_probe(struct i2c_client *client, | |||
290 | } | 297 | } |
291 | 298 | ||
292 | i2c_set_clientdata(client, chip); | 299 | i2c_set_clientdata(client, chip); |
300 | device_init_wakeup(&client->dev, 1); | ||
293 | 301 | ||
294 | return 0; | 302 | return 0; |
295 | 303 | ||
@@ -319,10 +327,37 @@ static int __devexit tca6416_keypad_remove(struct i2c_client *client) | |||
319 | return 0; | 327 | return 0; |
320 | } | 328 | } |
321 | 329 | ||
330 | #ifdef CONFIG_PM_SLEEP | ||
331 | static int tca6416_keypad_suspend(struct device *dev) | ||
332 | { | ||
333 | struct i2c_client *client = to_i2c_client(dev); | ||
334 | struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); | ||
335 | |||
336 | if (device_may_wakeup(dev)) | ||
337 | enable_irq_wake(chip->irqnum); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int tca6416_keypad_resume(struct device *dev) | ||
343 | { | ||
344 | struct i2c_client *client = to_i2c_client(dev); | ||
345 | struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); | ||
346 | |||
347 | if (device_may_wakeup(dev)) | ||
348 | disable_irq_wake(chip->irqnum); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | #endif | ||
353 | |||
354 | static SIMPLE_DEV_PM_OPS(tca6416_keypad_dev_pm_ops, | ||
355 | tca6416_keypad_suspend, tca6416_keypad_resume); | ||
322 | 356 | ||
323 | static struct i2c_driver tca6416_keypad_driver = { | 357 | static struct i2c_driver tca6416_keypad_driver = { |
324 | .driver = { | 358 | .driver = { |
325 | .name = "tca6416-keypad", | 359 | .name = "tca6416-keypad", |
360 | .pm = &tca6416_keypad_dev_pm_ops, | ||
326 | }, | 361 | }, |
327 | .probe = tca6416_keypad_probe, | 362 | .probe = tca6416_keypad_probe, |
328 | .remove = __devexit_p(tca6416_keypad_remove), | 363 | .remove = __devexit_p(tca6416_keypad_remove), |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c new file mode 100644 index 000000000000..2b3b73ec6689 --- /dev/null +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -0,0 +1,799 @@ | |||
1 | /* | ||
2 | * Keyboard class input driver for the NVIDIA Tegra SoC internal matrix | ||
3 | * keyboard controller | ||
4 | * | ||
5 | * Copyright (c) 2009-2011, NVIDIA Corporation. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/clk.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <mach/clk.h> | ||
31 | #include <mach/kbc.h> | ||
32 | |||
33 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu | ||
34 | |||
35 | /* KBC row scan time and delay for beginning the row scan. */ | ||
36 | #define KBC_ROW_SCAN_TIME 16 | ||
37 | #define KBC_ROW_SCAN_DLY 5 | ||
38 | |||
39 | /* KBC uses a 32KHz clock so a cycle = 1/32Khz */ | ||
40 | #define KBC_CYCLE_USEC 32 | ||
41 | |||
42 | /* KBC Registers */ | ||
43 | |||
44 | /* KBC Control Register */ | ||
45 | #define KBC_CONTROL_0 0x0 | ||
46 | #define KBC_FIFO_TH_CNT_SHIFT(cnt) (cnt << 14) | ||
47 | #define KBC_DEBOUNCE_CNT_SHIFT(cnt) (cnt << 4) | ||
48 | #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) | ||
49 | #define KBC_CONTROL_KBC_EN (1 << 0) | ||
50 | |||
51 | /* KBC Interrupt Register */ | ||
52 | #define KBC_INT_0 0x4 | ||
53 | #define KBC_INT_FIFO_CNT_INT_STATUS (1 << 2) | ||
54 | |||
55 | #define KBC_ROW_CFG0_0 0x8 | ||
56 | #define KBC_COL_CFG0_0 0x18 | ||
57 | #define KBC_INIT_DLY_0 0x28 | ||
58 | #define KBC_RPT_DLY_0 0x2c | ||
59 | #define KBC_KP_ENT0_0 0x30 | ||
60 | #define KBC_KP_ENT1_0 0x34 | ||
61 | #define KBC_ROW0_MASK_0 0x38 | ||
62 | |||
63 | #define KBC_ROW_SHIFT 3 | ||
64 | |||
65 | struct tegra_kbc { | ||
66 | void __iomem *mmio; | ||
67 | struct input_dev *idev; | ||
68 | unsigned int irq; | ||
69 | spinlock_t lock; | ||
70 | unsigned int repoll_dly; | ||
71 | unsigned long cp_dly_jiffies; | ||
72 | bool use_fn_map; | ||
73 | bool use_ghost_filter; | ||
74 | const struct tegra_kbc_platform_data *pdata; | ||
75 | unsigned short keycode[KBC_MAX_KEY * 2]; | ||
76 | unsigned short current_keys[KBC_MAX_KPENT]; | ||
77 | unsigned int num_pressed_keys; | ||
78 | struct timer_list timer; | ||
79 | struct clk *clk; | ||
80 | }; | ||
81 | |||
82 | static const u32 tegra_kbc_default_keymap[] = { | ||
83 | KEY(0, 2, KEY_W), | ||
84 | KEY(0, 3, KEY_S), | ||
85 | KEY(0, 4, KEY_A), | ||
86 | KEY(0, 5, KEY_Z), | ||
87 | KEY(0, 7, KEY_FN), | ||
88 | |||
89 | KEY(1, 7, KEY_LEFTMETA), | ||
90 | |||
91 | KEY(2, 6, KEY_RIGHTALT), | ||
92 | KEY(2, 7, KEY_LEFTALT), | ||
93 | |||
94 | KEY(3, 0, KEY_5), | ||
95 | KEY(3, 1, KEY_4), | ||
96 | KEY(3, 2, KEY_R), | ||
97 | KEY(3, 3, KEY_E), | ||
98 | KEY(3, 4, KEY_F), | ||
99 | KEY(3, 5, KEY_D), | ||
100 | KEY(3, 6, KEY_X), | ||
101 | |||
102 | KEY(4, 0, KEY_7), | ||
103 | KEY(4, 1, KEY_6), | ||
104 | KEY(4, 2, KEY_T), | ||
105 | KEY(4, 3, KEY_H), | ||
106 | KEY(4, 4, KEY_G), | ||
107 | KEY(4, 5, KEY_V), | ||
108 | KEY(4, 6, KEY_C), | ||
109 | KEY(4, 7, KEY_SPACE), | ||
110 | |||
111 | KEY(5, 0, KEY_9), | ||
112 | KEY(5, 1, KEY_8), | ||
113 | KEY(5, 2, KEY_U), | ||
114 | KEY(5, 3, KEY_Y), | ||
115 | KEY(5, 4, KEY_J), | ||
116 | KEY(5, 5, KEY_N), | ||
117 | KEY(5, 6, KEY_B), | ||
118 | KEY(5, 7, KEY_BACKSLASH), | ||
119 | |||
120 | KEY(6, 0, KEY_MINUS), | ||
121 | KEY(6, 1, KEY_0), | ||
122 | KEY(6, 2, KEY_O), | ||
123 | KEY(6, 3, KEY_I), | ||
124 | KEY(6, 4, KEY_L), | ||
125 | KEY(6, 5, KEY_K), | ||
126 | KEY(6, 6, KEY_COMMA), | ||
127 | KEY(6, 7, KEY_M), | ||
128 | |||
129 | KEY(7, 1, KEY_EQUAL), | ||
130 | KEY(7, 2, KEY_RIGHTBRACE), | ||
131 | KEY(7, 3, KEY_ENTER), | ||
132 | KEY(7, 7, KEY_MENU), | ||
133 | |||
134 | KEY(8, 4, KEY_RIGHTSHIFT), | ||
135 | KEY(8, 5, KEY_LEFTSHIFT), | ||
136 | |||
137 | KEY(9, 5, KEY_RIGHTCTRL), | ||
138 | KEY(9, 7, KEY_LEFTCTRL), | ||
139 | |||
140 | KEY(11, 0, KEY_LEFTBRACE), | ||
141 | KEY(11, 1, KEY_P), | ||
142 | KEY(11, 2, KEY_APOSTROPHE), | ||
143 | KEY(11, 3, KEY_SEMICOLON), | ||
144 | KEY(11, 4, KEY_SLASH), | ||
145 | KEY(11, 5, KEY_DOT), | ||
146 | |||
147 | KEY(12, 0, KEY_F10), | ||
148 | KEY(12, 1, KEY_F9), | ||
149 | KEY(12, 2, KEY_BACKSPACE), | ||
150 | KEY(12, 3, KEY_3), | ||
151 | KEY(12, 4, KEY_2), | ||
152 | KEY(12, 5, KEY_UP), | ||
153 | KEY(12, 6, KEY_PRINT), | ||
154 | KEY(12, 7, KEY_PAUSE), | ||
155 | |||
156 | KEY(13, 0, KEY_INSERT), | ||
157 | KEY(13, 1, KEY_DELETE), | ||
158 | KEY(13, 3, KEY_PAGEUP), | ||
159 | KEY(13, 4, KEY_PAGEDOWN), | ||
160 | KEY(13, 5, KEY_RIGHT), | ||
161 | KEY(13, 6, KEY_DOWN), | ||
162 | KEY(13, 7, KEY_LEFT), | ||
163 | |||
164 | KEY(14, 0, KEY_F11), | ||
165 | KEY(14, 1, KEY_F12), | ||
166 | KEY(14, 2, KEY_F8), | ||
167 | KEY(14, 3, KEY_Q), | ||
168 | KEY(14, 4, KEY_F4), | ||
169 | KEY(14, 5, KEY_F3), | ||
170 | KEY(14, 6, KEY_1), | ||
171 | KEY(14, 7, KEY_F7), | ||
172 | |||
173 | KEY(15, 0, KEY_ESC), | ||
174 | KEY(15, 1, KEY_GRAVE), | ||
175 | KEY(15, 2, KEY_F5), | ||
176 | KEY(15, 3, KEY_TAB), | ||
177 | KEY(15, 4, KEY_F1), | ||
178 | KEY(15, 5, KEY_F2), | ||
179 | KEY(15, 6, KEY_CAPSLOCK), | ||
180 | KEY(15, 7, KEY_F6), | ||
181 | |||
182 | /* Software Handled Function Keys */ | ||
183 | KEY(20, 0, KEY_KP7), | ||
184 | |||
185 | KEY(21, 0, KEY_KP9), | ||
186 | KEY(21, 1, KEY_KP8), | ||
187 | KEY(21, 2, KEY_KP4), | ||
188 | KEY(21, 4, KEY_KP1), | ||
189 | |||
190 | KEY(22, 1, KEY_KPSLASH), | ||
191 | KEY(22, 2, KEY_KP6), | ||
192 | KEY(22, 3, KEY_KP5), | ||
193 | KEY(22, 4, KEY_KP3), | ||
194 | KEY(22, 5, KEY_KP2), | ||
195 | KEY(22, 7, KEY_KP0), | ||
196 | |||
197 | KEY(27, 1, KEY_KPASTERISK), | ||
198 | KEY(27, 3, KEY_KPMINUS), | ||
199 | KEY(27, 4, KEY_KPPLUS), | ||
200 | KEY(27, 5, KEY_KPDOT), | ||
201 | |||
202 | KEY(28, 5, KEY_VOLUMEUP), | ||
203 | |||
204 | KEY(29, 3, KEY_HOME), | ||
205 | KEY(29, 4, KEY_END), | ||
206 | KEY(29, 5, KEY_BRIGHTNESSDOWN), | ||
207 | KEY(29, 6, KEY_VOLUMEDOWN), | ||
208 | KEY(29, 7, KEY_BRIGHTNESSUP), | ||
209 | |||
210 | KEY(30, 0, KEY_NUMLOCK), | ||
211 | KEY(30, 1, KEY_SCROLLLOCK), | ||
212 | KEY(30, 2, KEY_MUTE), | ||
213 | |||
214 | KEY(31, 4, KEY_HELP), | ||
215 | }; | ||
216 | |||
217 | static const struct matrix_keymap_data tegra_kbc_default_keymap_data = { | ||
218 | .keymap = tegra_kbc_default_keymap, | ||
219 | .keymap_size = ARRAY_SIZE(tegra_kbc_default_keymap), | ||
220 | }; | ||
221 | |||
222 | static void tegra_kbc_report_released_keys(struct input_dev *input, | ||
223 | unsigned short old_keycodes[], | ||
224 | unsigned int old_num_keys, | ||
225 | unsigned short new_keycodes[], | ||
226 | unsigned int new_num_keys) | ||
227 | { | ||
228 | unsigned int i, j; | ||
229 | |||
230 | for (i = 0; i < old_num_keys; i++) { | ||
231 | for (j = 0; j < new_num_keys; j++) | ||
232 | if (old_keycodes[i] == new_keycodes[j]) | ||
233 | break; | ||
234 | |||
235 | if (j == new_num_keys) | ||
236 | input_report_key(input, old_keycodes[i], 0); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static void tegra_kbc_report_pressed_keys(struct input_dev *input, | ||
241 | unsigned char scancodes[], | ||
242 | unsigned short keycodes[], | ||
243 | unsigned int num_pressed_keys) | ||
244 | { | ||
245 | unsigned int i; | ||
246 | |||
247 | for (i = 0; i < num_pressed_keys; i++) { | ||
248 | input_event(input, EV_MSC, MSC_SCAN, scancodes[i]); | ||
249 | input_report_key(input, keycodes[i], 1); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | static void tegra_kbc_report_keys(struct tegra_kbc *kbc) | ||
254 | { | ||
255 | unsigned char scancodes[KBC_MAX_KPENT]; | ||
256 | unsigned short keycodes[KBC_MAX_KPENT]; | ||
257 | u32 val = 0; | ||
258 | unsigned int i; | ||
259 | unsigned int num_down = 0; | ||
260 | unsigned long flags; | ||
261 | bool fn_keypress = false; | ||
262 | bool key_in_same_row = false; | ||
263 | bool key_in_same_col = false; | ||
264 | |||
265 | spin_lock_irqsave(&kbc->lock, flags); | ||
266 | for (i = 0; i < KBC_MAX_KPENT; i++) { | ||
267 | if ((i % 4) == 0) | ||
268 | val = readl(kbc->mmio + KBC_KP_ENT0_0 + i); | ||
269 | |||
270 | if (val & 0x80) { | ||
271 | unsigned int col = val & 0x07; | ||
272 | unsigned int row = (val >> 3) & 0x0f; | ||
273 | unsigned char scancode = | ||
274 | MATRIX_SCAN_CODE(row, col, KBC_ROW_SHIFT); | ||
275 | |||
276 | scancodes[num_down] = scancode; | ||
277 | keycodes[num_down] = kbc->keycode[scancode]; | ||
278 | /* If driver uses Fn map, do not report the Fn key. */ | ||
279 | if ((keycodes[num_down] == KEY_FN) && kbc->use_fn_map) | ||
280 | fn_keypress = true; | ||
281 | else | ||
282 | num_down++; | ||
283 | } | ||
284 | |||
285 | val >>= 8; | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * Matrix keyboard designs are prone to keyboard ghosting. | ||
290 | * Ghosting occurs if there are 3 keys such that - | ||
291 | * any 2 of the 3 keys share a row, and any 2 of them share a column. | ||
292 | * If so ignore the key presses for this iteration. | ||
293 | */ | ||
294 | if ((kbc->use_ghost_filter) && (num_down >= 3)) { | ||
295 | for (i = 0; i < num_down; i++) { | ||
296 | unsigned int j; | ||
297 | u8 curr_col = scancodes[i] & 0x07; | ||
298 | u8 curr_row = scancodes[i] >> KBC_ROW_SHIFT; | ||
299 | |||
300 | /* | ||
301 | * Find 2 keys such that one key is in the same row | ||
302 | * and the other is in the same column as the i-th key. | ||
303 | */ | ||
304 | for (j = i + 1; j < num_down; j++) { | ||
305 | u8 col = scancodes[j] & 0x07; | ||
306 | u8 row = scancodes[j] >> KBC_ROW_SHIFT; | ||
307 | |||
308 | if (col == curr_col) | ||
309 | key_in_same_col = true; | ||
310 | if (row == curr_row) | ||
311 | key_in_same_row = true; | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * If the platform uses Fn keymaps, translate keys on a Fn keypress. | ||
318 | * Function keycodes are KBC_MAX_KEY apart from the plain keycodes. | ||
319 | */ | ||
320 | if (fn_keypress) { | ||
321 | for (i = 0; i < num_down; i++) { | ||
322 | scancodes[i] += KBC_MAX_KEY; | ||
323 | keycodes[i] = kbc->keycode[scancodes[i]]; | ||
324 | } | ||
325 | } | ||
326 | |||
327 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
328 | |||
329 | /* Ignore the key presses for this iteration? */ | ||
330 | if (key_in_same_col && key_in_same_row) | ||
331 | return; | ||
332 | |||
333 | tegra_kbc_report_released_keys(kbc->idev, | ||
334 | kbc->current_keys, kbc->num_pressed_keys, | ||
335 | keycodes, num_down); | ||
336 | tegra_kbc_report_pressed_keys(kbc->idev, scancodes, keycodes, num_down); | ||
337 | input_sync(kbc->idev); | ||
338 | |||
339 | memcpy(kbc->current_keys, keycodes, sizeof(kbc->current_keys)); | ||
340 | kbc->num_pressed_keys = num_down; | ||
341 | } | ||
342 | |||
343 | static void tegra_kbc_keypress_timer(unsigned long data) | ||
344 | { | ||
345 | struct tegra_kbc *kbc = (struct tegra_kbc *)data; | ||
346 | unsigned long flags; | ||
347 | u32 val; | ||
348 | unsigned int i; | ||
349 | |||
350 | val = (readl(kbc->mmio + KBC_INT_0) >> 4) & 0xf; | ||
351 | if (val) { | ||
352 | unsigned long dly; | ||
353 | |||
354 | tegra_kbc_report_keys(kbc); | ||
355 | |||
356 | /* | ||
357 | * If more than one keys are pressed we need not wait | ||
358 | * for the repoll delay. | ||
359 | */ | ||
360 | dly = (val == 1) ? kbc->repoll_dly : 1; | ||
361 | mod_timer(&kbc->timer, jiffies + msecs_to_jiffies(dly)); | ||
362 | } else { | ||
363 | /* Release any pressed keys and exit the polling loop */ | ||
364 | for (i = 0; i < kbc->num_pressed_keys; i++) | ||
365 | input_report_key(kbc->idev, kbc->current_keys[i], 0); | ||
366 | input_sync(kbc->idev); | ||
367 | |||
368 | kbc->num_pressed_keys = 0; | ||
369 | |||
370 | /* All keys are released so enable the keypress interrupt */ | ||
371 | spin_lock_irqsave(&kbc->lock, flags); | ||
372 | val = readl(kbc->mmio + KBC_CONTROL_0); | ||
373 | val |= KBC_CONTROL_FIFO_CNT_INT_EN; | ||
374 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
375 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
376 | } | ||
377 | } | ||
378 | |||
379 | static irqreturn_t tegra_kbc_isr(int irq, void *args) | ||
380 | { | ||
381 | struct tegra_kbc *kbc = args; | ||
382 | u32 val, ctl; | ||
383 | |||
384 | /* | ||
385 | * Until all keys are released, defer further processing to | ||
386 | * the polling loop in tegra_kbc_keypress_timer | ||
387 | */ | ||
388 | ctl = readl(kbc->mmio + KBC_CONTROL_0); | ||
389 | ctl &= ~KBC_CONTROL_FIFO_CNT_INT_EN; | ||
390 | writel(ctl, kbc->mmio + KBC_CONTROL_0); | ||
391 | |||
392 | /* | ||
393 | * Quickly bail out & reenable interrupts if the fifo threshold | ||
394 | * count interrupt wasn't the interrupt source | ||
395 | */ | ||
396 | val = readl(kbc->mmio + KBC_INT_0); | ||
397 | writel(val, kbc->mmio + KBC_INT_0); | ||
398 | |||
399 | if (val & KBC_INT_FIFO_CNT_INT_STATUS) { | ||
400 | /* | ||
401 | * Schedule timer to run when hardware is in continuous | ||
402 | * polling mode. | ||
403 | */ | ||
404 | mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies); | ||
405 | } else { | ||
406 | ctl |= KBC_CONTROL_FIFO_CNT_INT_EN; | ||
407 | writel(ctl, kbc->mmio + KBC_CONTROL_0); | ||
408 | } | ||
409 | |||
410 | return IRQ_HANDLED; | ||
411 | } | ||
412 | |||
413 | static void tegra_kbc_setup_wakekeys(struct tegra_kbc *kbc, bool filter) | ||
414 | { | ||
415 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | ||
416 | int i; | ||
417 | unsigned int rst_val; | ||
418 | |||
419 | /* Either mask all keys or none. */ | ||
420 | rst_val = (filter && !pdata->wakeup) ? ~0 : 0; | ||
421 | |||
422 | for (i = 0; i < KBC_MAX_ROW; i++) | ||
423 | writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); | ||
424 | } | ||
425 | |||
426 | static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | ||
427 | { | ||
428 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | ||
429 | int i; | ||
430 | |||
431 | for (i = 0; i < KBC_MAX_GPIO; i++) { | ||
432 | u32 r_shft = 5 * (i % 6); | ||
433 | u32 c_shft = 4 * (i % 8); | ||
434 | u32 r_mask = 0x1f << r_shft; | ||
435 | u32 c_mask = 0x0f << c_shft; | ||
436 | u32 r_offs = (i / 6) * 4 + KBC_ROW_CFG0_0; | ||
437 | u32 c_offs = (i / 8) * 4 + KBC_COL_CFG0_0; | ||
438 | u32 row_cfg = readl(kbc->mmio + r_offs); | ||
439 | u32 col_cfg = readl(kbc->mmio + c_offs); | ||
440 | |||
441 | row_cfg &= ~r_mask; | ||
442 | col_cfg &= ~c_mask; | ||
443 | |||
444 | if (pdata->pin_cfg[i].is_row) | ||
445 | row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft; | ||
446 | else | ||
447 | col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft; | ||
448 | |||
449 | writel(row_cfg, kbc->mmio + r_offs); | ||
450 | writel(col_cfg, kbc->mmio + c_offs); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | static int tegra_kbc_start(struct tegra_kbc *kbc) | ||
455 | { | ||
456 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | ||
457 | unsigned long flags; | ||
458 | unsigned int debounce_cnt; | ||
459 | u32 val = 0; | ||
460 | |||
461 | clk_enable(kbc->clk); | ||
462 | |||
463 | /* Reset the KBC controller to clear all previous status.*/ | ||
464 | tegra_periph_reset_assert(kbc->clk); | ||
465 | udelay(100); | ||
466 | tegra_periph_reset_deassert(kbc->clk); | ||
467 | udelay(100); | ||
468 | |||
469 | tegra_kbc_config_pins(kbc); | ||
470 | tegra_kbc_setup_wakekeys(kbc, false); | ||
471 | |||
472 | writel(pdata->repeat_cnt, kbc->mmio + KBC_RPT_DLY_0); | ||
473 | |||
474 | /* Keyboard debounce count is maximum of 12 bits. */ | ||
475 | debounce_cnt = min(pdata->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); | ||
476 | val = KBC_DEBOUNCE_CNT_SHIFT(debounce_cnt); | ||
477 | val |= KBC_FIFO_TH_CNT_SHIFT(1); /* set fifo interrupt threshold to 1 */ | ||
478 | val |= KBC_CONTROL_FIFO_CNT_INT_EN; /* interrupt on FIFO threshold */ | ||
479 | val |= KBC_CONTROL_KBC_EN; /* enable */ | ||
480 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
481 | |||
482 | /* | ||
483 | * Compute the delay(ns) from interrupt mode to continuous polling | ||
484 | * mode so the timer routine is scheduled appropriately. | ||
485 | */ | ||
486 | val = readl(kbc->mmio + KBC_INIT_DLY_0); | ||
487 | kbc->cp_dly_jiffies = usecs_to_jiffies((val & 0xfffff) * 32); | ||
488 | |||
489 | kbc->num_pressed_keys = 0; | ||
490 | |||
491 | /* | ||
492 | * Atomically clear out any remaining entries in the key FIFO | ||
493 | * and enable keyboard interrupts. | ||
494 | */ | ||
495 | spin_lock_irqsave(&kbc->lock, flags); | ||
496 | while (1) { | ||
497 | val = readl(kbc->mmio + KBC_INT_0); | ||
498 | val >>= 4; | ||
499 | if (!val) | ||
500 | break; | ||
501 | |||
502 | val = readl(kbc->mmio + KBC_KP_ENT0_0); | ||
503 | val = readl(kbc->mmio + KBC_KP_ENT1_0); | ||
504 | } | ||
505 | writel(0x7, kbc->mmio + KBC_INT_0); | ||
506 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
507 | |||
508 | enable_irq(kbc->irq); | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static void tegra_kbc_stop(struct tegra_kbc *kbc) | ||
514 | { | ||
515 | unsigned long flags; | ||
516 | u32 val; | ||
517 | |||
518 | spin_lock_irqsave(&kbc->lock, flags); | ||
519 | val = readl(kbc->mmio + KBC_CONTROL_0); | ||
520 | val &= ~1; | ||
521 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
522 | spin_unlock_irqrestore(&kbc->lock, flags); | ||
523 | |||
524 | disable_irq(kbc->irq); | ||
525 | del_timer_sync(&kbc->timer); | ||
526 | |||
527 | clk_disable(kbc->clk); | ||
528 | } | ||
529 | |||
530 | static int tegra_kbc_open(struct input_dev *dev) | ||
531 | { | ||
532 | struct tegra_kbc *kbc = input_get_drvdata(dev); | ||
533 | |||
534 | return tegra_kbc_start(kbc); | ||
535 | } | ||
536 | |||
537 | static void tegra_kbc_close(struct input_dev *dev) | ||
538 | { | ||
539 | struct tegra_kbc *kbc = input_get_drvdata(dev); | ||
540 | |||
541 | return tegra_kbc_stop(kbc); | ||
542 | } | ||
543 | |||
544 | static bool __devinit | ||
545 | tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | ||
546 | struct device *dev, unsigned int *num_rows) | ||
547 | { | ||
548 | int i; | ||
549 | |||
550 | *num_rows = 0; | ||
551 | |||
552 | for (i = 0; i < KBC_MAX_GPIO; i++) { | ||
553 | const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i]; | ||
554 | |||
555 | if (pin_cfg->is_row) { | ||
556 | if (pin_cfg->num >= KBC_MAX_ROW) { | ||
557 | dev_err(dev, | ||
558 | "pin_cfg[%d]: invalid row number %d\n", | ||
559 | i, pin_cfg->num); | ||
560 | return false; | ||
561 | } | ||
562 | (*num_rows)++; | ||
563 | } else { | ||
564 | if (pin_cfg->num >= KBC_MAX_COL) { | ||
565 | dev_err(dev, | ||
566 | "pin_cfg[%d]: invalid column number %d\n", | ||
567 | i, pin_cfg->num); | ||
568 | return false; | ||
569 | } | ||
570 | } | ||
571 | } | ||
572 | |||
573 | return true; | ||
574 | } | ||
575 | |||
576 | static int __devinit tegra_kbc_probe(struct platform_device *pdev) | ||
577 | { | ||
578 | const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data; | ||
579 | const struct matrix_keymap_data *keymap_data; | ||
580 | struct tegra_kbc *kbc; | ||
581 | struct input_dev *input_dev; | ||
582 | struct resource *res; | ||
583 | int irq; | ||
584 | int err; | ||
585 | int num_rows = 0; | ||
586 | unsigned int debounce_cnt; | ||
587 | unsigned int scan_time_rows; | ||
588 | |||
589 | if (!pdata) | ||
590 | return -EINVAL; | ||
591 | |||
592 | if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows)) | ||
593 | return -EINVAL; | ||
594 | |||
595 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
596 | if (!res) { | ||
597 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
598 | return -ENXIO; | ||
599 | } | ||
600 | |||
601 | irq = platform_get_irq(pdev, 0); | ||
602 | if (irq < 0) { | ||
603 | dev_err(&pdev->dev, "failed to get keyboard IRQ\n"); | ||
604 | return -ENXIO; | ||
605 | } | ||
606 | |||
607 | kbc = kzalloc(sizeof(*kbc), GFP_KERNEL); | ||
608 | input_dev = input_allocate_device(); | ||
609 | if (!kbc || !input_dev) { | ||
610 | err = -ENOMEM; | ||
611 | goto err_free_mem; | ||
612 | } | ||
613 | |||
614 | kbc->pdata = pdata; | ||
615 | kbc->idev = input_dev; | ||
616 | kbc->irq = irq; | ||
617 | spin_lock_init(&kbc->lock); | ||
618 | setup_timer(&kbc->timer, tegra_kbc_keypress_timer, (unsigned long)kbc); | ||
619 | |||
620 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
621 | if (!res) { | ||
622 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
623 | err = -EBUSY; | ||
624 | goto err_free_mem; | ||
625 | } | ||
626 | |||
627 | kbc->mmio = ioremap(res->start, resource_size(res)); | ||
628 | if (!kbc->mmio) { | ||
629 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
630 | err = -ENXIO; | ||
631 | goto err_free_mem_region; | ||
632 | } | ||
633 | |||
634 | kbc->clk = clk_get(&pdev->dev, NULL); | ||
635 | if (IS_ERR(kbc->clk)) { | ||
636 | dev_err(&pdev->dev, "failed to get keyboard clock\n"); | ||
637 | err = PTR_ERR(kbc->clk); | ||
638 | goto err_iounmap; | ||
639 | } | ||
640 | |||
641 | /* | ||
642 | * The time delay between two consecutive reads of the FIFO is | ||
643 | * the sum of the repeat time and the time taken for scanning | ||
644 | * the rows. There is an additional delay before the row scanning | ||
645 | * starts. The repoll delay is computed in milliseconds. | ||
646 | */ | ||
647 | debounce_cnt = min(pdata->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); | ||
648 | scan_time_rows = (KBC_ROW_SCAN_TIME + debounce_cnt) * num_rows; | ||
649 | kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt; | ||
650 | kbc->repoll_dly = ((kbc->repoll_dly * KBC_CYCLE_USEC) + 999) / 1000; | ||
651 | |||
652 | input_dev->name = pdev->name; | ||
653 | input_dev->id.bustype = BUS_HOST; | ||
654 | input_dev->dev.parent = &pdev->dev; | ||
655 | input_dev->open = tegra_kbc_open; | ||
656 | input_dev->close = tegra_kbc_close; | ||
657 | |||
658 | input_set_drvdata(input_dev, kbc); | ||
659 | |||
660 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
661 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
662 | |||
663 | input_dev->keycode = kbc->keycode; | ||
664 | input_dev->keycodesize = sizeof(kbc->keycode[0]); | ||
665 | input_dev->keycodemax = KBC_MAX_KEY; | ||
666 | if (pdata->use_fn_map) | ||
667 | input_dev->keycodemax *= 2; | ||
668 | |||
669 | kbc->use_fn_map = pdata->use_fn_map; | ||
670 | kbc->use_ghost_filter = pdata->use_ghost_filter; | ||
671 | keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data; | ||
672 | matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT, | ||
673 | input_dev->keycode, input_dev->keybit); | ||
674 | |||
675 | err = request_irq(kbc->irq, tegra_kbc_isr, IRQF_TRIGGER_HIGH, | ||
676 | pdev->name, kbc); | ||
677 | if (err) { | ||
678 | dev_err(&pdev->dev, "failed to request keyboard IRQ\n"); | ||
679 | goto err_put_clk; | ||
680 | } | ||
681 | |||
682 | disable_irq(kbc->irq); | ||
683 | |||
684 | err = input_register_device(kbc->idev); | ||
685 | if (err) { | ||
686 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
687 | goto err_free_irq; | ||
688 | } | ||
689 | |||
690 | platform_set_drvdata(pdev, kbc); | ||
691 | device_init_wakeup(&pdev->dev, pdata->wakeup); | ||
692 | |||
693 | return 0; | ||
694 | |||
695 | err_free_irq: | ||
696 | free_irq(kbc->irq, pdev); | ||
697 | err_put_clk: | ||
698 | clk_put(kbc->clk); | ||
699 | err_iounmap: | ||
700 | iounmap(kbc->mmio); | ||
701 | err_free_mem_region: | ||
702 | release_mem_region(res->start, resource_size(res)); | ||
703 | err_free_mem: | ||
704 | input_free_device(kbc->idev); | ||
705 | kfree(kbc); | ||
706 | |||
707 | return err; | ||
708 | } | ||
709 | |||
710 | static int __devexit tegra_kbc_remove(struct platform_device *pdev) | ||
711 | { | ||
712 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); | ||
713 | struct resource *res; | ||
714 | |||
715 | free_irq(kbc->irq, pdev); | ||
716 | clk_put(kbc->clk); | ||
717 | |||
718 | input_unregister_device(kbc->idev); | ||
719 | iounmap(kbc->mmio); | ||
720 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
721 | release_mem_region(res->start, resource_size(res)); | ||
722 | |||
723 | kfree(kbc); | ||
724 | |||
725 | platform_set_drvdata(pdev, NULL); | ||
726 | |||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | #ifdef CONFIG_PM_SLEEP | ||
731 | static int tegra_kbc_suspend(struct device *dev) | ||
732 | { | ||
733 | struct platform_device *pdev = to_platform_device(dev); | ||
734 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); | ||
735 | |||
736 | if (device_may_wakeup(&pdev->dev)) { | ||
737 | tegra_kbc_setup_wakekeys(kbc, true); | ||
738 | enable_irq_wake(kbc->irq); | ||
739 | /* Forcefully clear the interrupt status */ | ||
740 | writel(0x7, kbc->mmio + KBC_INT_0); | ||
741 | msleep(30); | ||
742 | } else { | ||
743 | mutex_lock(&kbc->idev->mutex); | ||
744 | if (kbc->idev->users) | ||
745 | tegra_kbc_stop(kbc); | ||
746 | mutex_unlock(&kbc->idev->mutex); | ||
747 | } | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | static int tegra_kbc_resume(struct device *dev) | ||
753 | { | ||
754 | struct platform_device *pdev = to_platform_device(dev); | ||
755 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); | ||
756 | int err = 0; | ||
757 | |||
758 | if (device_may_wakeup(&pdev->dev)) { | ||
759 | disable_irq_wake(kbc->irq); | ||
760 | tegra_kbc_setup_wakekeys(kbc, false); | ||
761 | } else { | ||
762 | mutex_lock(&kbc->idev->mutex); | ||
763 | if (kbc->idev->users) | ||
764 | err = tegra_kbc_start(kbc); | ||
765 | mutex_unlock(&kbc->idev->mutex); | ||
766 | } | ||
767 | |||
768 | return err; | ||
769 | } | ||
770 | #endif | ||
771 | |||
772 | static SIMPLE_DEV_PM_OPS(tegra_kbc_pm_ops, tegra_kbc_suspend, tegra_kbc_resume); | ||
773 | |||
774 | static struct platform_driver tegra_kbc_driver = { | ||
775 | .probe = tegra_kbc_probe, | ||
776 | .remove = __devexit_p(tegra_kbc_remove), | ||
777 | .driver = { | ||
778 | .name = "tegra-kbc", | ||
779 | .owner = THIS_MODULE, | ||
780 | .pm = &tegra_kbc_pm_ops, | ||
781 | }, | ||
782 | }; | ||
783 | |||
784 | static void __exit tegra_kbc_exit(void) | ||
785 | { | ||
786 | platform_driver_unregister(&tegra_kbc_driver); | ||
787 | } | ||
788 | module_exit(tegra_kbc_exit); | ||
789 | |||
790 | static int __init tegra_kbc_init(void) | ||
791 | { | ||
792 | return platform_driver_register(&tegra_kbc_driver); | ||
793 | } | ||
794 | module_init(tegra_kbc_init); | ||
795 | |||
796 | MODULE_LICENSE("GPL"); | ||
797 | MODULE_AUTHOR("Rakesh Iyer <riyer@nvidia.com>"); | ||
798 | MODULE_DESCRIPTION("Tegra matrix keyboard controller driver"); | ||
799 | MODULE_ALIAS("platform:tegra-kbc"); | ||
diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c new file mode 100644 index 000000000000..c8f097a15d89 --- /dev/null +++ b/drivers/input/keyboard/tnetv107x-keypad.c | |||
@@ -0,0 +1,341 @@ | |||
1 | /* | ||
2 | * Texas Instruments TNETV107X Keypad Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/input/matrix_keypad.h> | ||
27 | |||
28 | #define BITS(x) (BIT(x) - 1) | ||
29 | |||
30 | #define KEYPAD_ROWS 9 | ||
31 | #define KEYPAD_COLS 9 | ||
32 | |||
33 | #define DEBOUNCE_MIN 0x400ul | ||
34 | #define DEBOUNCE_MAX 0x3ffffffful | ||
35 | |||
36 | struct keypad_regs { | ||
37 | u32 rev; | ||
38 | u32 mode; | ||
39 | u32 mask; | ||
40 | u32 pol; | ||
41 | u32 dclock; | ||
42 | u32 rclock; | ||
43 | u32 stable_cnt; | ||
44 | u32 in_en; | ||
45 | u32 out; | ||
46 | u32 out_en; | ||
47 | u32 in; | ||
48 | u32 lock; | ||
49 | u32 pres[3]; | ||
50 | }; | ||
51 | |||
52 | #define keypad_read(kp, reg) __raw_readl(&(kp)->regs->reg) | ||
53 | #define keypad_write(kp, reg, val) __raw_writel(val, &(kp)->regs->reg) | ||
54 | |||
55 | struct keypad_data { | ||
56 | struct input_dev *input_dev; | ||
57 | struct resource *res; | ||
58 | struct keypad_regs __iomem *regs; | ||
59 | struct clk *clk; | ||
60 | struct device *dev; | ||
61 | spinlock_t lock; | ||
62 | u32 irq_press; | ||
63 | u32 irq_release; | ||
64 | int rows, cols, row_shift; | ||
65 | int debounce_ms, active_low; | ||
66 | u32 prev_keys[3]; | ||
67 | unsigned short keycodes[]; | ||
68 | }; | ||
69 | |||
70 | static irqreturn_t keypad_irq(int irq, void *data) | ||
71 | { | ||
72 | struct keypad_data *kp = data; | ||
73 | int i, bit, val, row, col, code; | ||
74 | unsigned long flags; | ||
75 | u32 curr_keys[3]; | ||
76 | u32 change; | ||
77 | |||
78 | spin_lock_irqsave(&kp->lock, flags); | ||
79 | |||
80 | memset(curr_keys, 0, sizeof(curr_keys)); | ||
81 | if (irq == kp->irq_press) | ||
82 | for (i = 0; i < 3; i++) | ||
83 | curr_keys[i] = keypad_read(kp, pres[i]); | ||
84 | |||
85 | for (i = 0; i < 3; i++) { | ||
86 | change = curr_keys[i] ^ kp->prev_keys[i]; | ||
87 | |||
88 | while (change) { | ||
89 | bit = fls(change) - 1; | ||
90 | change ^= BIT(bit); | ||
91 | val = curr_keys[i] & BIT(bit); | ||
92 | bit += i * 32; | ||
93 | row = bit / KEYPAD_COLS; | ||
94 | col = bit % KEYPAD_COLS; | ||
95 | |||
96 | code = MATRIX_SCAN_CODE(row, col, kp->row_shift); | ||
97 | input_event(kp->input_dev, EV_MSC, MSC_SCAN, code); | ||
98 | input_report_key(kp->input_dev, kp->keycodes[code], | ||
99 | val); | ||
100 | } | ||
101 | } | ||
102 | input_sync(kp->input_dev); | ||
103 | memcpy(kp->prev_keys, curr_keys, sizeof(curr_keys)); | ||
104 | |||
105 | if (irq == kp->irq_press) | ||
106 | keypad_write(kp, lock, 0); /* Allow hardware updates */ | ||
107 | |||
108 | spin_unlock_irqrestore(&kp->lock, flags); | ||
109 | |||
110 | return IRQ_HANDLED; | ||
111 | } | ||
112 | |||
113 | static int keypad_start(struct input_dev *dev) | ||
114 | { | ||
115 | struct keypad_data *kp = input_get_drvdata(dev); | ||
116 | unsigned long mask, debounce, clk_rate_khz; | ||
117 | unsigned long flags; | ||
118 | |||
119 | clk_enable(kp->clk); | ||
120 | clk_rate_khz = clk_get_rate(kp->clk) / 1000; | ||
121 | |||
122 | spin_lock_irqsave(&kp->lock, flags); | ||
123 | |||
124 | /* Initialize device registers */ | ||
125 | keypad_write(kp, mode, 0); | ||
126 | |||
127 | mask = BITS(kp->rows) << KEYPAD_COLS; | ||
128 | mask |= BITS(kp->cols); | ||
129 | keypad_write(kp, mask, ~mask); | ||
130 | |||
131 | keypad_write(kp, pol, kp->active_low ? 0 : 0x3ffff); | ||
132 | keypad_write(kp, stable_cnt, 3); | ||
133 | |||
134 | debounce = kp->debounce_ms * clk_rate_khz; | ||
135 | debounce = clamp(debounce, DEBOUNCE_MIN, DEBOUNCE_MAX); | ||
136 | keypad_write(kp, dclock, debounce); | ||
137 | keypad_write(kp, rclock, 4 * debounce); | ||
138 | |||
139 | keypad_write(kp, in_en, 1); | ||
140 | |||
141 | spin_unlock_irqrestore(&kp->lock, flags); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static void keypad_stop(struct input_dev *dev) | ||
147 | { | ||
148 | struct keypad_data *kp = input_get_drvdata(dev); | ||
149 | |||
150 | synchronize_irq(kp->irq_press); | ||
151 | synchronize_irq(kp->irq_release); | ||
152 | clk_disable(kp->clk); | ||
153 | } | ||
154 | |||
155 | static int __devinit keypad_probe(struct platform_device *pdev) | ||
156 | { | ||
157 | const struct matrix_keypad_platform_data *pdata; | ||
158 | const struct matrix_keymap_data *keymap_data; | ||
159 | struct device *dev = &pdev->dev; | ||
160 | struct keypad_data *kp; | ||
161 | int error = 0, sz, row_shift; | ||
162 | u32 rev = 0; | ||
163 | |||
164 | pdata = pdev->dev.platform_data; | ||
165 | if (!pdata) { | ||
166 | dev_err(dev, "cannot find device data\n"); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | keymap_data = pdata->keymap_data; | ||
171 | if (!keymap_data) { | ||
172 | dev_err(dev, "cannot find keymap data\n"); | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | |||
176 | row_shift = get_count_order(pdata->num_col_gpios); | ||
177 | sz = offsetof(struct keypad_data, keycodes); | ||
178 | sz += (pdata->num_row_gpios << row_shift) * sizeof(kp->keycodes[0]); | ||
179 | kp = kzalloc(sz, GFP_KERNEL); | ||
180 | if (!kp) { | ||
181 | dev_err(dev, "cannot allocate device info\n"); | ||
182 | return -ENOMEM; | ||
183 | } | ||
184 | |||
185 | kp->dev = dev; | ||
186 | kp->rows = pdata->num_row_gpios; | ||
187 | kp->cols = pdata->num_col_gpios; | ||
188 | kp->row_shift = row_shift; | ||
189 | platform_set_drvdata(pdev, kp); | ||
190 | spin_lock_init(&kp->lock); | ||
191 | |||
192 | kp->irq_press = platform_get_irq_byname(pdev, "press"); | ||
193 | kp->irq_release = platform_get_irq_byname(pdev, "release"); | ||
194 | if (kp->irq_press < 0 || kp->irq_release < 0) { | ||
195 | dev_err(dev, "cannot determine device interrupts\n"); | ||
196 | error = -ENODEV; | ||
197 | goto error_res; | ||
198 | } | ||
199 | |||
200 | kp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
201 | if (!kp->res) { | ||
202 | dev_err(dev, "cannot determine register area\n"); | ||
203 | error = -ENODEV; | ||
204 | goto error_res; | ||
205 | } | ||
206 | |||
207 | if (!request_mem_region(kp->res->start, resource_size(kp->res), | ||
208 | pdev->name)) { | ||
209 | dev_err(dev, "cannot claim register memory\n"); | ||
210 | kp->res = NULL; | ||
211 | error = -EINVAL; | ||
212 | goto error_res; | ||
213 | } | ||
214 | |||
215 | kp->regs = ioremap(kp->res->start, resource_size(kp->res)); | ||
216 | if (!kp->regs) { | ||
217 | dev_err(dev, "cannot map register memory\n"); | ||
218 | error = -ENOMEM; | ||
219 | goto error_map; | ||
220 | } | ||
221 | |||
222 | kp->clk = clk_get(dev, NULL); | ||
223 | if (IS_ERR(kp->clk)) { | ||
224 | dev_err(dev, "cannot claim device clock\n"); | ||
225 | error = PTR_ERR(kp->clk); | ||
226 | goto error_clk; | ||
227 | } | ||
228 | |||
229 | error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, 0, | ||
230 | dev_name(dev), kp); | ||
231 | if (error < 0) { | ||
232 | dev_err(kp->dev, "Could not allocate keypad press key irq\n"); | ||
233 | goto error_irq_press; | ||
234 | } | ||
235 | |||
236 | error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, 0, | ||
237 | dev_name(dev), kp); | ||
238 | if (error < 0) { | ||
239 | dev_err(kp->dev, "Could not allocate keypad release key irq\n"); | ||
240 | goto error_irq_release; | ||
241 | } | ||
242 | |||
243 | kp->input_dev = input_allocate_device(); | ||
244 | if (!kp->input_dev) { | ||
245 | dev_err(dev, "cannot allocate input device\n"); | ||
246 | error = -ENOMEM; | ||
247 | goto error_input; | ||
248 | } | ||
249 | input_set_drvdata(kp->input_dev, kp); | ||
250 | |||
251 | kp->input_dev->name = pdev->name; | ||
252 | kp->input_dev->dev.parent = &pdev->dev; | ||
253 | kp->input_dev->open = keypad_start; | ||
254 | kp->input_dev->close = keypad_stop; | ||
255 | kp->input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
256 | if (!pdata->no_autorepeat) | ||
257 | kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
258 | |||
259 | clk_enable(kp->clk); | ||
260 | rev = keypad_read(kp, rev); | ||
261 | kp->input_dev->id.bustype = BUS_HOST; | ||
262 | kp->input_dev->id.product = ((rev >> 8) & 0x07); | ||
263 | kp->input_dev->id.version = ((rev >> 16) & 0xfff); | ||
264 | clk_disable(kp->clk); | ||
265 | |||
266 | kp->input_dev->keycode = kp->keycodes; | ||
267 | kp->input_dev->keycodesize = sizeof(kp->keycodes[0]); | ||
268 | kp->input_dev->keycodemax = kp->rows << kp->row_shift; | ||
269 | |||
270 | matrix_keypad_build_keymap(keymap_data, kp->row_shift, kp->keycodes, | ||
271 | kp->input_dev->keybit); | ||
272 | |||
273 | input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); | ||
274 | |||
275 | error = input_register_device(kp->input_dev); | ||
276 | if (error < 0) { | ||
277 | dev_err(dev, "Could not register input device\n"); | ||
278 | goto error_reg; | ||
279 | } | ||
280 | |||
281 | return 0; | ||
282 | |||
283 | |||
284 | error_reg: | ||
285 | input_free_device(kp->input_dev); | ||
286 | error_input: | ||
287 | free_irq(kp->irq_release, kp); | ||
288 | error_irq_release: | ||
289 | free_irq(kp->irq_press, kp); | ||
290 | error_irq_press: | ||
291 | clk_put(kp->clk); | ||
292 | error_clk: | ||
293 | iounmap(kp->regs); | ||
294 | error_map: | ||
295 | release_mem_region(kp->res->start, resource_size(kp->res)); | ||
296 | error_res: | ||
297 | platform_set_drvdata(pdev, NULL); | ||
298 | kfree(kp); | ||
299 | return error; | ||
300 | } | ||
301 | |||
302 | static int __devexit keypad_remove(struct platform_device *pdev) | ||
303 | { | ||
304 | struct keypad_data *kp = platform_get_drvdata(pdev); | ||
305 | |||
306 | free_irq(kp->irq_press, kp); | ||
307 | free_irq(kp->irq_release, kp); | ||
308 | input_unregister_device(kp->input_dev); | ||
309 | clk_put(kp->clk); | ||
310 | iounmap(kp->regs); | ||
311 | release_mem_region(kp->res->start, resource_size(kp->res)); | ||
312 | platform_set_drvdata(pdev, NULL); | ||
313 | kfree(kp); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static struct platform_driver keypad_driver = { | ||
319 | .probe = keypad_probe, | ||
320 | .remove = __devexit_p(keypad_remove), | ||
321 | .driver.name = "tnetv107x-keypad", | ||
322 | .driver.owner = THIS_MODULE, | ||
323 | }; | ||
324 | |||
325 | static int __init keypad_init(void) | ||
326 | { | ||
327 | return platform_driver_register(&keypad_driver); | ||
328 | } | ||
329 | |||
330 | static void __exit keypad_exit(void) | ||
331 | { | ||
332 | platform_driver_unregister(&keypad_driver); | ||
333 | } | ||
334 | |||
335 | module_init(keypad_init); | ||
336 | module_exit(keypad_exit); | ||
337 | |||
338 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
339 | MODULE_DESCRIPTION("TNETV107X Keypad Driver"); | ||
340 | MODULE_ALIAS("platform: tnetv107x-keypad"); | ||
341 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index fb16b5e5ea13..a26922cf0e84 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -332,18 +332,20 @@ static int __devinit twl4030_kp_program(struct twl4030_keypad *kp) | |||
332 | static int __devinit twl4030_kp_probe(struct platform_device *pdev) | 332 | static int __devinit twl4030_kp_probe(struct platform_device *pdev) |
333 | { | 333 | { |
334 | struct twl4030_keypad_data *pdata = pdev->dev.platform_data; | 334 | struct twl4030_keypad_data *pdata = pdev->dev.platform_data; |
335 | const struct matrix_keymap_data *keymap_data = pdata->keymap_data; | 335 | const struct matrix_keymap_data *keymap_data; |
336 | struct twl4030_keypad *kp; | 336 | struct twl4030_keypad *kp; |
337 | struct input_dev *input; | 337 | struct input_dev *input; |
338 | u8 reg; | 338 | u8 reg; |
339 | int error; | 339 | int error; |
340 | 340 | ||
341 | if (!pdata || !pdata->rows || !pdata->cols || | 341 | if (!pdata || !pdata->rows || !pdata->cols || !pdata->keymap_data || |
342 | pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) { | 342 | pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) { |
343 | dev_err(&pdev->dev, "Invalid platform_data\n"); | 343 | dev_err(&pdev->dev, "Invalid platform_data\n"); |
344 | return -EINVAL; | 344 | return -EINVAL; |
345 | } | 345 | } |
346 | 346 | ||
347 | keymap_data = pdata->keymap_data; | ||
348 | |||
347 | kp = kzalloc(sizeof(*kp), GFP_KERNEL); | 349 | kp = kzalloc(sizeof(*kp), GFP_KERNEL); |
348 | input = input_allocate_device(); | 350 | input = input_allocate_device(); |
349 | if (!kp || !input) { | 351 | if (!kp || !input) { |
@@ -406,23 +408,22 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) | |||
406 | if (error) { | 408 | if (error) { |
407 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", | 409 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", |
408 | kp->irq); | 410 | kp->irq); |
409 | goto err3; | 411 | goto err2; |
410 | } | 412 | } |
411 | 413 | ||
412 | /* Enable KP and TO interrupts now. */ | 414 | /* Enable KP and TO interrupts now. */ |
413 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); | 415 | reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); |
414 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { | 416 | if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { |
415 | error = -EIO; | 417 | error = -EIO; |
416 | goto err4; | 418 | goto err3; |
417 | } | 419 | } |
418 | 420 | ||
419 | platform_set_drvdata(pdev, kp); | 421 | platform_set_drvdata(pdev, kp); |
420 | return 0; | 422 | return 0; |
421 | 423 | ||
422 | err4: | 424 | err3: |
423 | /* mask all events - we don't care about the result */ | 425 | /* mask all events - we don't care about the result */ |
424 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); | 426 | (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); |
425 | err3: | ||
426 | free_irq(kp->irq, NULL); | 427 | free_irq(kp->irq, NULL); |
427 | err2: | 428 | err2: |
428 | input_unregister_device(input); | 429 | input_unregister_device(input); |
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c index 4cc82826ea6b..3dca3c14510e 100644 --- a/drivers/input/misc/88pm860x_onkey.c +++ b/drivers/input/misc/88pm860x_onkey.c | |||
@@ -74,7 +74,7 @@ static int __devinit pm860x_onkey_probe(struct platform_device *pdev) | |||
74 | info->chip = chip; | 74 | info->chip = chip; |
75 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | 75 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; |
76 | info->dev = &pdev->dev; | 76 | info->dev = &pdev->dev; |
77 | info->irq = irq + chip->irq_base; | 77 | info->irq = irq; |
78 | 78 | ||
79 | info->idev = input_allocate_device(); | 79 | info->idev = input_allocate_device(); |
80 | if (!info->idev) { | 80 | if (!info->idev) { |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index b49e23379723..45dc6aa62ba4 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -22,6 +22,16 @@ config INPUT_88PM860X_ONKEY | |||
22 | To compile this driver as a module, choose M here: the module | 22 | To compile this driver as a module, choose M here: the module |
23 | will be called 88pm860x_onkey. | 23 | will be called 88pm860x_onkey. |
24 | 24 | ||
25 | config INPUT_AB8500_PONKEY | ||
26 | tristate "AB8500 Pon (PowerOn) Key" | ||
27 | depends on AB8500_CORE | ||
28 | help | ||
29 | Say Y here to use the PowerOn Key for ST-Ericsson's AB8500 | ||
30 | Mix-Sig PMIC. | ||
31 | |||
32 | To compile this driver as a module, choose M here: the module | ||
33 | will be called ab8500-ponkey. | ||
34 | |||
25 | config INPUT_AD714X | 35 | config INPUT_AD714X |
26 | tristate "Analog Devices AD714x Capacitance Touch Sensor" | 36 | tristate "Analog Devices AD714x Capacitance Touch Sensor" |
27 | help | 37 | help |
@@ -284,24 +294,6 @@ config INPUT_SGI_BTNS | |||
284 | To compile this driver as a module, choose M here: the | 294 | To compile this driver as a module, choose M here: the |
285 | module will be called sgi_btns. | 295 | module will be called sgi_btns. |
286 | 296 | ||
287 | config INPUT_WINBOND_CIR | ||
288 | tristate "Winbond IR remote control" | ||
289 | depends on X86 && PNP | ||
290 | select NEW_LEDS | ||
291 | select LEDS_CLASS | ||
292 | select LEDS_TRIGGERS | ||
293 | select BITREVERSE | ||
294 | help | ||
295 | Say Y here if you want to use the IR remote functionality found | ||
296 | in some Winbond SuperI/O chips. Currently only the WPCD376I | ||
297 | chip is supported (included in some Intel Media series motherboards). | ||
298 | |||
299 | IR Receive and wake-on-IR from suspend and power-off is currently | ||
300 | supported. | ||
301 | |||
302 | To compile this driver as a module, choose M here: the module will be | ||
303 | called winbond_cir. | ||
304 | |||
305 | config HP_SDC_RTC | 297 | config HP_SDC_RTC |
306 | tristate "HP SDC Real Time Clock" | 298 | tristate "HP SDC Real Time Clock" |
307 | depends on (GSC || HP300) && SERIO | 299 | depends on (GSC || HP300) && SERIO |
@@ -338,6 +330,17 @@ config INPUT_PWM_BEEPER | |||
338 | To compile this driver as a module, choose M here: the module will be | 330 | To compile this driver as a module, choose M here: the module will be |
339 | called pwm-beeper. | 331 | called pwm-beeper. |
340 | 332 | ||
333 | config INPUT_PMIC8XXX_PWRKEY | ||
334 | tristate "PMIC8XXX power key support" | ||
335 | depends on MFD_PM8XXX | ||
336 | help | ||
337 | Say Y here if you want support for the PMIC8XXX power key. | ||
338 | |||
339 | If unsure, say N. | ||
340 | |||
341 | To compile this driver as a module, choose M here: the | ||
342 | module will be called pmic8xxx-pwrkey. | ||
343 | |||
341 | config INPUT_GPIO_ROTARY_ENCODER | 344 | config INPUT_GPIO_ROTARY_ENCODER |
342 | tristate "Rotary encoders connected to GPIO pins" | 345 | tristate "Rotary encoders connected to GPIO pins" |
343 | depends on GPIOLIB && GENERIC_GPIO | 346 | depends on GPIOLIB && GENERIC_GPIO |
@@ -438,4 +441,41 @@ config INPUT_ADXL34X_SPI | |||
438 | To compile this driver as a module, choose M here: the | 441 | To compile this driver as a module, choose M here: the |
439 | module will be called adxl34x-spi. | 442 | module will be called adxl34x-spi. |
440 | 443 | ||
444 | config INPUT_CMA3000 | ||
445 | tristate "VTI CMA3000 Tri-axis accelerometer" | ||
446 | help | ||
447 | Say Y here if you want to use VTI CMA3000_D0x Accelerometer | ||
448 | driver | ||
449 | |||
450 | This driver currently only supports I2C interface to the | ||
451 | controller. Also select the I2C method. | ||
452 | |||
453 | If unsure, say N | ||
454 | |||
455 | To compile this driver as a module, choose M here: the | ||
456 | module will be called cma3000_d0x. | ||
457 | |||
458 | config INPUT_CMA3000_I2C | ||
459 | tristate "Support I2C bus connection" | ||
460 | depends on INPUT_CMA3000 && I2C | ||
461 | help | ||
462 | Say Y here if you want to use VTI CMA3000_D0x Accelerometer | ||
463 | through I2C interface. | ||
464 | |||
465 | To compile this driver as a module, choose M here: the | ||
466 | module will be called cma3000_d0x_i2c. | ||
467 | |||
468 | config INPUT_XEN_KBDDEV_FRONTEND | ||
469 | tristate "Xen virtual keyboard and mouse support" | ||
470 | depends on XEN_FBDEV_FRONTEND | ||
471 | default y | ||
472 | select XEN_XENBUS_FRONTEND | ||
473 | help | ||
474 | This driver implements the front-end of the Xen virtual | ||
475 | keyboard and mouse device driver. It communicates with a back-end | ||
476 | in another domain. | ||
477 | |||
478 | To compile this driver as a module, choose M here: the | ||
479 | module will be called xen-kbdfront. | ||
480 | |||
441 | endif | 481 | endif |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 19ccca78fa76..38efb2cb182b 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o | 7 | obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o |
8 | obj-$(CONFIG_INPUT_AB8500_PONKEY) += ab8500-ponkey.o | ||
8 | obj-$(CONFIG_INPUT_AD714X) += ad714x.o | 9 | obj-$(CONFIG_INPUT_AD714X) += ad714x.o |
9 | obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o | 10 | obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o |
10 | obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o | 11 | obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o |
@@ -17,6 +18,8 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o | |||
17 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o | 18 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o |
18 | obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o | 19 | obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o |
19 | obj-$(CONFIG_INPUT_CM109) += cm109.o | 20 | obj-$(CONFIG_INPUT_CM109) += cm109.o |
21 | obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o | ||
22 | obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o | ||
20 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o | 23 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o |
21 | obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o | 24 | obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o |
22 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 25 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
@@ -30,6 +33,7 @@ obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o | |||
30 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o | 33 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o |
31 | obj-$(CONFIG_INPUT_POWERMATE) += powermate.o | 34 | obj-$(CONFIG_INPUT_POWERMATE) += powermate.o |
32 | obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o | 35 | obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o |
36 | obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o | ||
33 | obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o | 37 | obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o |
34 | obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o | 38 | obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o |
35 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | 39 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o |
@@ -37,8 +41,8 @@ obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | |||
37 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o | 41 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o |
38 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o | 42 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o |
39 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 43 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
40 | obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o | ||
41 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 44 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
42 | obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o | 45 | obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o |
46 | obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o | ||
43 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o | 47 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o |
44 | 48 | ||
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c new file mode 100644 index 000000000000..3d3288a78fdc --- /dev/null +++ b/drivers/input/misc/ab8500-ponkey.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
6 | * | ||
7 | * AB8500 Power-On Key handler | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/mfd/ab8500.h> | ||
16 | #include <linux/slab.h> | ||
17 | |||
18 | /** | ||
19 | * struct ab8500_ponkey - ab8500 ponkey information | ||
20 | * @input_dev: pointer to input device | ||
21 | * @ab8500: ab8500 parent | ||
22 | * @irq_dbf: irq number for falling transition | ||
23 | * @irq_dbr: irq number for rising transition | ||
24 | */ | ||
25 | struct ab8500_ponkey { | ||
26 | struct input_dev *idev; | ||
27 | struct ab8500 *ab8500; | ||
28 | int irq_dbf; | ||
29 | int irq_dbr; | ||
30 | }; | ||
31 | |||
32 | /* AB8500 gives us an interrupt when ONKEY is held */ | ||
33 | static irqreturn_t ab8500_ponkey_handler(int irq, void *data) | ||
34 | { | ||
35 | struct ab8500_ponkey *ponkey = data; | ||
36 | |||
37 | if (irq == ponkey->irq_dbf) | ||
38 | input_report_key(ponkey->idev, KEY_POWER, true); | ||
39 | else if (irq == ponkey->irq_dbr) | ||
40 | input_report_key(ponkey->idev, KEY_POWER, false); | ||
41 | |||
42 | input_sync(ponkey->idev); | ||
43 | |||
44 | return IRQ_HANDLED; | ||
45 | } | ||
46 | |||
47 | static int __devinit ab8500_ponkey_probe(struct platform_device *pdev) | ||
48 | { | ||
49 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | ||
50 | struct ab8500_ponkey *ponkey; | ||
51 | struct input_dev *input; | ||
52 | int irq_dbf, irq_dbr; | ||
53 | int error; | ||
54 | |||
55 | irq_dbf = platform_get_irq_byname(pdev, "ONKEY_DBF"); | ||
56 | if (irq_dbf < 0) { | ||
57 | dev_err(&pdev->dev, "No IRQ for ONKEY_DBF, error=%d\n", irq_dbf); | ||
58 | return irq_dbf; | ||
59 | } | ||
60 | |||
61 | irq_dbr = platform_get_irq_byname(pdev, "ONKEY_DBR"); | ||
62 | if (irq_dbr < 0) { | ||
63 | dev_err(&pdev->dev, "No IRQ for ONKEY_DBR, error=%d\n", irq_dbr); | ||
64 | return irq_dbr; | ||
65 | } | ||
66 | |||
67 | ponkey = kzalloc(sizeof(struct ab8500_ponkey), GFP_KERNEL); | ||
68 | input = input_allocate_device(); | ||
69 | if (!ponkey || !input) { | ||
70 | error = -ENOMEM; | ||
71 | goto err_free_mem; | ||
72 | } | ||
73 | |||
74 | ponkey->idev = input; | ||
75 | ponkey->ab8500 = ab8500; | ||
76 | ponkey->irq_dbf = irq_dbf; | ||
77 | ponkey->irq_dbr = irq_dbr; | ||
78 | |||
79 | input->name = "AB8500 POn(PowerOn) Key"; | ||
80 | input->dev.parent = &pdev->dev; | ||
81 | |||
82 | input_set_capability(input, EV_KEY, KEY_POWER); | ||
83 | |||
84 | error = request_any_context_irq(ponkey->irq_dbf, ab8500_ponkey_handler, | ||
85 | 0, "ab8500-ponkey-dbf", ponkey); | ||
86 | if (error < 0) { | ||
87 | dev_err(ab8500->dev, "Failed to request dbf IRQ#%d: %d\n", | ||
88 | ponkey->irq_dbf, error); | ||
89 | goto err_free_mem; | ||
90 | } | ||
91 | |||
92 | error = request_any_context_irq(ponkey->irq_dbr, ab8500_ponkey_handler, | ||
93 | 0, "ab8500-ponkey-dbr", ponkey); | ||
94 | if (error < 0) { | ||
95 | dev_err(ab8500->dev, "Failed to request dbr IRQ#%d: %d\n", | ||
96 | ponkey->irq_dbr, error); | ||
97 | goto err_free_dbf_irq; | ||
98 | } | ||
99 | |||
100 | error = input_register_device(ponkey->idev); | ||
101 | if (error) { | ||
102 | dev_err(ab8500->dev, "Can't register input device: %d\n", error); | ||
103 | goto err_free_dbr_irq; | ||
104 | } | ||
105 | |||
106 | platform_set_drvdata(pdev, ponkey); | ||
107 | return 0; | ||
108 | |||
109 | err_free_dbr_irq: | ||
110 | free_irq(ponkey->irq_dbr, ponkey); | ||
111 | err_free_dbf_irq: | ||
112 | free_irq(ponkey->irq_dbf, ponkey); | ||
113 | err_free_mem: | ||
114 | input_free_device(input); | ||
115 | kfree(ponkey); | ||
116 | |||
117 | return error; | ||
118 | } | ||
119 | |||
120 | static int __devexit ab8500_ponkey_remove(struct platform_device *pdev) | ||
121 | { | ||
122 | struct ab8500_ponkey *ponkey = platform_get_drvdata(pdev); | ||
123 | |||
124 | free_irq(ponkey->irq_dbf, ponkey); | ||
125 | free_irq(ponkey->irq_dbr, ponkey); | ||
126 | input_unregister_device(ponkey->idev); | ||
127 | kfree(ponkey); | ||
128 | |||
129 | platform_set_drvdata(pdev, NULL); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct platform_driver ab8500_ponkey_driver = { | ||
135 | .driver = { | ||
136 | .name = "ab8500-poweron-key", | ||
137 | .owner = THIS_MODULE, | ||
138 | }, | ||
139 | .probe = ab8500_ponkey_probe, | ||
140 | .remove = __devexit_p(ab8500_ponkey_remove), | ||
141 | }; | ||
142 | |||
143 | static int __init ab8500_ponkey_init(void) | ||
144 | { | ||
145 | return platform_driver_register(&ab8500_ponkey_driver); | ||
146 | } | ||
147 | module_init(ab8500_ponkey_init); | ||
148 | |||
149 | static void __exit ab8500_ponkey_exit(void) | ||
150 | { | ||
151 | platform_driver_unregister(&ab8500_ponkey_driver); | ||
152 | } | ||
153 | module_exit(ab8500_ponkey_exit); | ||
154 | |||
155 | MODULE_LICENSE("GPL v2"); | ||
156 | MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>"); | ||
157 | MODULE_DESCRIPTION("ST-Ericsson AB8500 Power-ON(Pon) Key driver"); | ||
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c index 2bef8fa56c94..e21deb1baa8a 100644 --- a/drivers/input/misc/ad714x-i2c.c +++ b/drivers/input/misc/ad714x-i2c.c | |||
@@ -10,23 +10,23 @@ | |||
10 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/pm.h> | ||
13 | #include "ad714x.h" | 14 | #include "ad714x.h" |
14 | 15 | ||
15 | #ifdef CONFIG_PM | 16 | #ifdef CONFIG_PM |
16 | static int ad714x_i2c_suspend(struct i2c_client *client, pm_message_t message) | 17 | static int ad714x_i2c_suspend(struct device *dev) |
17 | { | 18 | { |
18 | return ad714x_disable(i2c_get_clientdata(client)); | 19 | return ad714x_disable(i2c_get_clientdata(to_i2c_client(dev))); |
19 | } | 20 | } |
20 | 21 | ||
21 | static int ad714x_i2c_resume(struct i2c_client *client) | 22 | static int ad714x_i2c_resume(struct device *dev) |
22 | { | 23 | { |
23 | return ad714x_enable(i2c_get_clientdata(client)); | 24 | return ad714x_enable(i2c_get_clientdata(to_i2c_client(dev))); |
24 | } | 25 | } |
25 | #else | ||
26 | # define ad714x_i2c_suspend NULL | ||
27 | # define ad714x_i2c_resume NULL | ||
28 | #endif | 26 | #endif |
29 | 27 | ||
28 | static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume); | ||
29 | |||
30 | static int ad714x_i2c_write(struct device *dev, unsigned short reg, | 30 | static int ad714x_i2c_write(struct device *dev, unsigned short reg, |
31 | unsigned short data) | 31 | unsigned short data) |
32 | { | 32 | { |
@@ -114,11 +114,10 @@ MODULE_DEVICE_TABLE(i2c, ad714x_id); | |||
114 | static struct i2c_driver ad714x_i2c_driver = { | 114 | static struct i2c_driver ad714x_i2c_driver = { |
115 | .driver = { | 115 | .driver = { |
116 | .name = "ad714x_captouch", | 116 | .name = "ad714x_captouch", |
117 | .pm = &ad714x_i2c_pm, | ||
117 | }, | 118 | }, |
118 | .probe = ad714x_i2c_probe, | 119 | .probe = ad714x_i2c_probe, |
119 | .remove = __devexit_p(ad714x_i2c_remove), | 120 | .remove = __devexit_p(ad714x_i2c_remove), |
120 | .suspend = ad714x_i2c_suspend, | ||
121 | .resume = ad714x_i2c_resume, | ||
122 | .id_table = ad714x_id, | 121 | .id_table = ad714x_id, |
123 | }; | 122 | }; |
124 | 123 | ||
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c index 7f8dedfd1bfe..4120dd549305 100644 --- a/drivers/input/misc/ad714x-spi.c +++ b/drivers/input/misc/ad714x-spi.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/input.h> /* BUS_I2C */ | 9 | #include <linux/input.h> /* BUS_I2C */ |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/spi/spi.h> | 11 | #include <linux/spi/spi.h> |
12 | #include <linux/pm.h> | ||
12 | #include <linux/types.h> | 13 | #include <linux/types.h> |
13 | #include "ad714x.h" | 14 | #include "ad714x.h" |
14 | 15 | ||
@@ -16,20 +17,19 @@ | |||
16 | #define AD714x_SPI_READ BIT(10) | 17 | #define AD714x_SPI_READ BIT(10) |
17 | 18 | ||
18 | #ifdef CONFIG_PM | 19 | #ifdef CONFIG_PM |
19 | static int ad714x_spi_suspend(struct spi_device *spi, pm_message_t message) | 20 | static int ad714x_spi_suspend(struct device *dev) |
20 | { | 21 | { |
21 | return ad714x_disable(spi_get_drvdata(spi)); | 22 | return ad714x_disable(spi_get_drvdata(to_spi_device(dev))); |
22 | } | 23 | } |
23 | 24 | ||
24 | static int ad714x_spi_resume(struct spi_device *spi) | 25 | static int ad714x_spi_resume(struct device *dev) |
25 | { | 26 | { |
26 | return ad714x_enable(spi_get_drvdata(spi)); | 27 | return ad714x_enable(spi_get_drvdata(to_spi_device(dev))); |
27 | } | 28 | } |
28 | #else | ||
29 | # define ad714x_spi_suspend NULL | ||
30 | # define ad714x_spi_resume NULL | ||
31 | #endif | 29 | #endif |
32 | 30 | ||
31 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); | ||
32 | |||
33 | static int ad714x_spi_read(struct device *dev, unsigned short reg, | 33 | static int ad714x_spi_read(struct device *dev, unsigned short reg, |
34 | unsigned short *data) | 34 | unsigned short *data) |
35 | { | 35 | { |
@@ -79,11 +79,10 @@ static struct spi_driver ad714x_spi_driver = { | |||
79 | .driver = { | 79 | .driver = { |
80 | .name = "ad714x_captouch", | 80 | .name = "ad714x_captouch", |
81 | .owner = THIS_MODULE, | 81 | .owner = THIS_MODULE, |
82 | .pm = &ad714x_spi_pm, | ||
82 | }, | 83 | }, |
83 | .probe = ad714x_spi_probe, | 84 | .probe = ad714x_spi_probe, |
84 | .remove = __devexit_p(ad714x_spi_remove), | 85 | .remove = __devexit_p(ad714x_spi_remove), |
85 | .suspend = ad714x_spi_suspend, | ||
86 | .resume = ad714x_spi_resume, | ||
87 | }; | 86 | }; |
88 | 87 | ||
89 | static __init int ad714x_spi_init(void) | 88 | static __init int ad714x_spi_init(void) |
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c index c431d09e401a..c3a62c42cd28 100644 --- a/drivers/input/misc/ad714x.c +++ b/drivers/input/misc/ad714x.c | |||
@@ -79,13 +79,7 @@ struct ad714x_slider_drv { | |||
79 | struct ad714x_wheel_drv { | 79 | struct ad714x_wheel_drv { |
80 | int abs_pos; | 80 | int abs_pos; |
81 | int flt_pos; | 81 | int flt_pos; |
82 | int pre_mean_value; | ||
83 | int pre_highest_stage; | 82 | int pre_highest_stage; |
84 | int pre_mean_value_no_offset; | ||
85 | int mean_value; | ||
86 | int mean_value_no_offset; | ||
87 | int pos_offset; | ||
88 | int pos_ratio; | ||
89 | int highest_stage; | 83 | int highest_stage; |
90 | enum ad714x_device_state state; | 84 | enum ad714x_device_state state; |
91 | struct input_dev *input; | 85 | struct input_dev *input; |
@@ -158,10 +152,10 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x, | |||
158 | unsigned short data; | 152 | unsigned short data; |
159 | unsigned short mask; | 153 | unsigned short mask; |
160 | 154 | ||
161 | mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage); | 155 | mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); |
162 | 156 | ||
163 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); | 157 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); |
164 | data |= 1 << start_stage; | 158 | data |= 1 << end_stage; |
165 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); | 159 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); |
166 | 160 | ||
167 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); | 161 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); |
@@ -175,10 +169,10 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x, | |||
175 | unsigned short data; | 169 | unsigned short data; |
176 | unsigned short mask; | 170 | unsigned short mask; |
177 | 171 | ||
178 | mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage); | 172 | mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); |
179 | 173 | ||
180 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); | 174 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); |
181 | data &= ~(1 << start_stage); | 175 | data &= ~(1 << end_stage); |
182 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); | 176 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); |
183 | 177 | ||
184 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); | 178 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); |
@@ -404,7 +398,6 @@ static void ad714x_slider_state_machine(struct ad714x_chip *ad714x, int idx) | |||
404 | ad714x_slider_cal_highest_stage(ad714x, idx); | 398 | ad714x_slider_cal_highest_stage(ad714x, idx); |
405 | ad714x_slider_cal_abs_pos(ad714x, idx); | 399 | ad714x_slider_cal_abs_pos(ad714x, idx); |
406 | ad714x_slider_cal_flt_pos(ad714x, idx); | 400 | ad714x_slider_cal_flt_pos(ad714x, idx); |
407 | |||
408 | input_report_abs(sw->input, ABS_X, sw->flt_pos); | 401 | input_report_abs(sw->input, ABS_X, sw->flt_pos); |
409 | input_report_key(sw->input, BTN_TOUCH, 1); | 402 | input_report_key(sw->input, BTN_TOUCH, 1); |
410 | } else { | 403 | } else { |
@@ -468,104 +461,41 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx) | |||
468 | /* | 461 | /* |
469 | * When the scroll wheel is activated, we compute the absolute position based | 462 | * When the scroll wheel is activated, we compute the absolute position based |
470 | * on the sensor values. To calculate the position, we first determine the | 463 | * on the sensor values. To calculate the position, we first determine the |
471 | * sensor that has the greatest response among the 8 sensors that constitutes | 464 | * sensor that has the greatest response among the sensors that constitutes |
472 | * the scrollwheel. Then we determined the 2 sensors on either sides of the | 465 | * the scrollwheel. Then we determined the sensors on either sides of the |
473 | * sensor with the highest response and we apply weights to these sensors. The | 466 | * sensor with the highest response and we apply weights to these sensors. The |
474 | * result of this computation gives us the mean value which defined by the | 467 | * result of this computation gives us the mean value. |
475 | * following formula: | ||
476 | * For i= second_before_highest_stage to i= second_after_highest_stage | ||
477 | * v += Sensor response(i)*WEIGHT*(i+3) | ||
478 | * w += Sensor response(i) | ||
479 | * Mean_Value=v/w | ||
480 | * pos_on_scrollwheel = (Mean_Value - position_offset) / position_ratio | ||
481 | */ | 468 | */ |
482 | 469 | ||
483 | #define WEIGHT_FACTOR 30 | ||
484 | /* This constant prevents the "PositionOffset" from reaching a big value */ | ||
485 | #define OFFSET_POSITION_CLAMP 120 | ||
486 | static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx) | 470 | static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx) |
487 | { | 471 | { |
488 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | 472 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; |
489 | struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; | 473 | struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; |
490 | int stage_num = hw->end_stage - hw->start_stage + 1; | 474 | int stage_num = hw->end_stage - hw->start_stage + 1; |
491 | int second_before, first_before, highest, first_after, second_after; | 475 | int first_before, highest, first_after; |
492 | int a_param, b_param; | 476 | int a_param, b_param; |
493 | 477 | ||
494 | /* Calculate Mean value */ | ||
495 | |||
496 | second_before = (sw->highest_stage + stage_num - 2) % stage_num; | ||
497 | first_before = (sw->highest_stage + stage_num - 1) % stage_num; | 478 | first_before = (sw->highest_stage + stage_num - 1) % stage_num; |
498 | highest = sw->highest_stage; | 479 | highest = sw->highest_stage; |
499 | first_after = (sw->highest_stage + stage_num + 1) % stage_num; | 480 | first_after = (sw->highest_stage + stage_num + 1) % stage_num; |
500 | second_after = (sw->highest_stage + stage_num + 2) % stage_num; | ||
501 | |||
502 | if (((sw->highest_stage - hw->start_stage) > 1) && | ||
503 | ((hw->end_stage - sw->highest_stage) > 1)) { | ||
504 | a_param = ad714x->sensor_val[second_before] * | ||
505 | (second_before - hw->start_stage + 3) + | ||
506 | ad714x->sensor_val[first_before] * | ||
507 | (second_before - hw->start_stage + 3) + | ||
508 | ad714x->sensor_val[highest] * | ||
509 | (second_before - hw->start_stage + 3) + | ||
510 | ad714x->sensor_val[first_after] * | ||
511 | (first_after - hw->start_stage + 3) + | ||
512 | ad714x->sensor_val[second_after] * | ||
513 | (second_after - hw->start_stage + 3); | ||
514 | } else { | ||
515 | a_param = ad714x->sensor_val[second_before] * | ||
516 | (second_before - hw->start_stage + 1) + | ||
517 | ad714x->sensor_val[first_before] * | ||
518 | (second_before - hw->start_stage + 2) + | ||
519 | ad714x->sensor_val[highest] * | ||
520 | (second_before - hw->start_stage + 3) + | ||
521 | ad714x->sensor_val[first_after] * | ||
522 | (first_after - hw->start_stage + 4) + | ||
523 | ad714x->sensor_val[second_after] * | ||
524 | (second_after - hw->start_stage + 5); | ||
525 | } | ||
526 | a_param *= WEIGHT_FACTOR; | ||
527 | 481 | ||
528 | b_param = ad714x->sensor_val[second_before] + | 482 | a_param = ad714x->sensor_val[highest] * |
483 | (highest - hw->start_stage) + | ||
484 | ad714x->sensor_val[first_before] * | ||
485 | (highest - hw->start_stage - 1) + | ||
486 | ad714x->sensor_val[first_after] * | ||
487 | (highest - hw->start_stage + 1); | ||
488 | b_param = ad714x->sensor_val[highest] + | ||
529 | ad714x->sensor_val[first_before] + | 489 | ad714x->sensor_val[first_before] + |
530 | ad714x->sensor_val[highest] + | 490 | ad714x->sensor_val[first_after]; |
531 | ad714x->sensor_val[first_after] + | 491 | |
532 | ad714x->sensor_val[second_after]; | 492 | sw->abs_pos = ((hw->max_coord / (hw->end_stage - hw->start_stage)) * |
533 | 493 | a_param) / b_param; | |
534 | sw->pre_mean_value = sw->mean_value; | 494 | |
535 | sw->mean_value = a_param / b_param; | ||
536 | |||
537 | /* Calculate the offset */ | ||
538 | |||
539 | if ((sw->pre_highest_stage == hw->end_stage) && | ||
540 | (sw->highest_stage == hw->start_stage)) | ||
541 | sw->pos_offset = sw->mean_value; | ||
542 | else if ((sw->pre_highest_stage == hw->start_stage) && | ||
543 | (sw->highest_stage == hw->end_stage)) | ||
544 | sw->pos_offset = sw->pre_mean_value; | ||
545 | |||
546 | if (sw->pos_offset > OFFSET_POSITION_CLAMP) | ||
547 | sw->pos_offset = OFFSET_POSITION_CLAMP; | ||
548 | |||
549 | /* Calculate the mean value without the offset */ | ||
550 | |||
551 | sw->pre_mean_value_no_offset = sw->mean_value_no_offset; | ||
552 | sw->mean_value_no_offset = sw->mean_value - sw->pos_offset; | ||
553 | if (sw->mean_value_no_offset < 0) | ||
554 | sw->mean_value_no_offset = 0; | ||
555 | |||
556 | /* Calculate ratio to scale down to NUMBER_OF_WANTED_POSITIONS */ | ||
557 | |||
558 | if ((sw->pre_highest_stage == hw->end_stage) && | ||
559 | (sw->highest_stage == hw->start_stage)) | ||
560 | sw->pos_ratio = (sw->pre_mean_value_no_offset * 100) / | ||
561 | hw->max_coord; | ||
562 | else if ((sw->pre_highest_stage == hw->start_stage) && | ||
563 | (sw->highest_stage == hw->end_stage)) | ||
564 | sw->pos_ratio = (sw->mean_value_no_offset * 100) / | ||
565 | hw->max_coord; | ||
566 | sw->abs_pos = (sw->mean_value_no_offset * 100) / sw->pos_ratio; | ||
567 | if (sw->abs_pos > hw->max_coord) | 495 | if (sw->abs_pos > hw->max_coord) |
568 | sw->abs_pos = hw->max_coord; | 496 | sw->abs_pos = hw->max_coord; |
497 | else if (sw->abs_pos < 0) | ||
498 | sw->abs_pos = 0; | ||
569 | } | 499 | } |
570 | 500 | ||
571 | static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx) | 501 | static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx) |
@@ -639,9 +569,8 @@ static void ad714x_wheel_state_machine(struct ad714x_chip *ad714x, int idx) | |||
639 | ad714x_wheel_cal_highest_stage(ad714x, idx); | 569 | ad714x_wheel_cal_highest_stage(ad714x, idx); |
640 | ad714x_wheel_cal_abs_pos(ad714x, idx); | 570 | ad714x_wheel_cal_abs_pos(ad714x, idx); |
641 | ad714x_wheel_cal_flt_pos(ad714x, idx); | 571 | ad714x_wheel_cal_flt_pos(ad714x, idx); |
642 | |||
643 | input_report_abs(sw->input, ABS_WHEEL, | 572 | input_report_abs(sw->input, ABS_WHEEL, |
644 | sw->abs_pos); | 573 | sw->flt_pos); |
645 | input_report_key(sw->input, BTN_TOUCH, 1); | 574 | input_report_key(sw->input, BTN_TOUCH, 1); |
646 | } else { | 575 | } else { |
647 | /* When the user lifts off the sensor, configure | 576 | /* When the user lifts off the sensor, configure |
@@ -1149,6 +1078,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1149 | input[alloc_idx]->id.bustype = bus_type; | 1078 | input[alloc_idx]->id.bustype = bus_type; |
1150 | input[alloc_idx]->id.product = ad714x->product; | 1079 | input[alloc_idx]->id.product = ad714x->product; |
1151 | input[alloc_idx]->id.version = ad714x->version; | 1080 | input[alloc_idx]->id.version = ad714x->version; |
1081 | input[alloc_idx]->name = "ad714x_captouch_slider"; | ||
1082 | input[alloc_idx]->dev.parent = dev; | ||
1152 | 1083 | ||
1153 | error = input_register_device(input[alloc_idx]); | 1084 | error = input_register_device(input[alloc_idx]); |
1154 | if (error) | 1085 | if (error) |
@@ -1179,6 +1110,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1179 | input[alloc_idx]->id.bustype = bus_type; | 1110 | input[alloc_idx]->id.bustype = bus_type; |
1180 | input[alloc_idx]->id.product = ad714x->product; | 1111 | input[alloc_idx]->id.product = ad714x->product; |
1181 | input[alloc_idx]->id.version = ad714x->version; | 1112 | input[alloc_idx]->id.version = ad714x->version; |
1113 | input[alloc_idx]->name = "ad714x_captouch_wheel"; | ||
1114 | input[alloc_idx]->dev.parent = dev; | ||
1182 | 1115 | ||
1183 | error = input_register_device(input[alloc_idx]); | 1116 | error = input_register_device(input[alloc_idx]); |
1184 | if (error) | 1117 | if (error) |
@@ -1212,6 +1145,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1212 | input[alloc_idx]->id.bustype = bus_type; | 1145 | input[alloc_idx]->id.bustype = bus_type; |
1213 | input[alloc_idx]->id.product = ad714x->product; | 1146 | input[alloc_idx]->id.product = ad714x->product; |
1214 | input[alloc_idx]->id.version = ad714x->version; | 1147 | input[alloc_idx]->id.version = ad714x->version; |
1148 | input[alloc_idx]->name = "ad714x_captouch_pad"; | ||
1149 | input[alloc_idx]->dev.parent = dev; | ||
1215 | 1150 | ||
1216 | error = input_register_device(input[alloc_idx]); | 1151 | error = input_register_device(input[alloc_idx]); |
1217 | if (error) | 1152 | if (error) |
@@ -1240,6 +1175,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1240 | input[alloc_idx]->id.bustype = bus_type; | 1175 | input[alloc_idx]->id.bustype = bus_type; |
1241 | input[alloc_idx]->id.product = ad714x->product; | 1176 | input[alloc_idx]->id.product = ad714x->product; |
1242 | input[alloc_idx]->id.version = ad714x->version; | 1177 | input[alloc_idx]->id.version = ad714x->version; |
1178 | input[alloc_idx]->name = "ad714x_captouch_button"; | ||
1179 | input[alloc_idx]->dev.parent = dev; | ||
1243 | 1180 | ||
1244 | error = input_register_device(input[alloc_idx]); | 1181 | error = input_register_device(input[alloc_idx]); |
1245 | if (error) | 1182 | if (error) |
@@ -1249,7 +1186,9 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1249 | } | 1186 | } |
1250 | 1187 | ||
1251 | error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, | 1188 | error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, |
1252 | IRQF_TRIGGER_FALLING, "ad714x_captouch", ad714x); | 1189 | plat_data->irqflags ? |
1190 | plat_data->irqflags : IRQF_TRIGGER_FALLING, | ||
1191 | "ad714x_captouch", ad714x); | ||
1253 | if (error) { | 1192 | if (error) { |
1254 | dev_err(dev, "can't allocate irq %d\n", ad714x->irq); | 1193 | dev_err(dev, "can't allocate irq %d\n", ad714x->irq); |
1255 | goto err_unreg_dev; | 1194 | goto err_unreg_dev; |
diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c index 0779724af7e7..ccacf2bb06a4 100644 --- a/drivers/input/misc/adxl34x-i2c.c +++ b/drivers/input/misc/adxl34x-i2c.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/i2c.h> | 11 | #include <linux/i2c.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/pm.h> | ||
14 | #include "adxl34x.h" | 15 | #include "adxl34x.h" |
15 | 16 | ||
16 | static int adxl34x_smbus_read(struct device *dev, unsigned char reg) | 17 | static int adxl34x_smbus_read(struct device *dev, unsigned char reg) |
@@ -105,8 +106,9 @@ static int __devexit adxl34x_i2c_remove(struct i2c_client *client) | |||
105 | } | 106 | } |
106 | 107 | ||
107 | #ifdef CONFIG_PM | 108 | #ifdef CONFIG_PM |
108 | static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message) | 109 | static int adxl34x_i2c_suspend(struct device *dev) |
109 | { | 110 | { |
111 | struct i2c_client *client = to_i2c_client(dev); | ||
110 | struct adxl34x *ac = i2c_get_clientdata(client); | 112 | struct adxl34x *ac = i2c_get_clientdata(client); |
111 | 113 | ||
112 | adxl34x_suspend(ac); | 114 | adxl34x_suspend(ac); |
@@ -114,19 +116,20 @@ static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message) | |||
114 | return 0; | 116 | return 0; |
115 | } | 117 | } |
116 | 118 | ||
117 | static int adxl34x_i2c_resume(struct i2c_client *client) | 119 | static int adxl34x_i2c_resume(struct device *dev) |
118 | { | 120 | { |
121 | struct i2c_client *client = to_i2c_client(dev); | ||
119 | struct adxl34x *ac = i2c_get_clientdata(client); | 122 | struct adxl34x *ac = i2c_get_clientdata(client); |
120 | 123 | ||
121 | adxl34x_resume(ac); | 124 | adxl34x_resume(ac); |
122 | 125 | ||
123 | return 0; | 126 | return 0; |
124 | } | 127 | } |
125 | #else | ||
126 | # define adxl34x_i2c_suspend NULL | ||
127 | # define adxl34x_i2c_resume NULL | ||
128 | #endif | 128 | #endif |
129 | 129 | ||
130 | static SIMPLE_DEV_PM_OPS(adxl34x_i2c_pm, adxl34x_i2c_suspend, | ||
131 | adxl34x_i2c_resume); | ||
132 | |||
130 | static const struct i2c_device_id adxl34x_id[] = { | 133 | static const struct i2c_device_id adxl34x_id[] = { |
131 | { "adxl34x", 0 }, | 134 | { "adxl34x", 0 }, |
132 | { } | 135 | { } |
@@ -138,11 +141,10 @@ static struct i2c_driver adxl34x_driver = { | |||
138 | .driver = { | 141 | .driver = { |
139 | .name = "adxl34x", | 142 | .name = "adxl34x", |
140 | .owner = THIS_MODULE, | 143 | .owner = THIS_MODULE, |
144 | .pm = &adxl34x_i2c_pm, | ||
141 | }, | 145 | }, |
142 | .probe = adxl34x_i2c_probe, | 146 | .probe = adxl34x_i2c_probe, |
143 | .remove = __devexit_p(adxl34x_i2c_remove), | 147 | .remove = __devexit_p(adxl34x_i2c_remove), |
144 | .suspend = adxl34x_i2c_suspend, | ||
145 | .resume = adxl34x_i2c_resume, | ||
146 | .id_table = adxl34x_id, | 148 | .id_table = adxl34x_id, |
147 | }; | 149 | }; |
148 | 150 | ||
diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c index 782de9e89828..f29de22fdda0 100644 --- a/drivers/input/misc/adxl34x-spi.c +++ b/drivers/input/misc/adxl34x-spi.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/input.h> /* BUS_SPI */ | 10 | #include <linux/input.h> /* BUS_SPI */ |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/spi/spi.h> | 12 | #include <linux/spi/spi.h> |
13 | #include <linux/pm.h> | ||
13 | #include <linux/types.h> | 14 | #include <linux/types.h> |
14 | #include "adxl34x.h" | 15 | #include "adxl34x.h" |
15 | 16 | ||
@@ -57,7 +58,7 @@ static int adxl34x_spi_read_block(struct device *dev, | |||
57 | return (status < 0) ? status : 0; | 58 | return (status < 0) ? status : 0; |
58 | } | 59 | } |
59 | 60 | ||
60 | static const struct adxl34x_bus_ops adx134x_spi_bops = { | 61 | static const struct adxl34x_bus_ops adxl34x_spi_bops = { |
61 | .bustype = BUS_SPI, | 62 | .bustype = BUS_SPI, |
62 | .write = adxl34x_spi_write, | 63 | .write = adxl34x_spi_write, |
63 | .read = adxl34x_spi_read, | 64 | .read = adxl34x_spi_read, |
@@ -76,7 +77,7 @@ static int __devinit adxl34x_spi_probe(struct spi_device *spi) | |||
76 | 77 | ||
77 | ac = adxl34x_probe(&spi->dev, spi->irq, | 78 | ac = adxl34x_probe(&spi->dev, spi->irq, |
78 | spi->max_speed_hz > MAX_FREQ_NO_FIFODELAY, | 79 | spi->max_speed_hz > MAX_FREQ_NO_FIFODELAY, |
79 | &adx134x_spi_bops); | 80 | &adxl34x_spi_bops); |
80 | 81 | ||
81 | if (IS_ERR(ac)) | 82 | if (IS_ERR(ac)) |
82 | return PTR_ERR(ac); | 83 | return PTR_ERR(ac); |
@@ -94,8 +95,9 @@ static int __devexit adxl34x_spi_remove(struct spi_device *spi) | |||
94 | } | 95 | } |
95 | 96 | ||
96 | #ifdef CONFIG_PM | 97 | #ifdef CONFIG_PM |
97 | static int adxl34x_spi_suspend(struct spi_device *spi, pm_message_t message) | 98 | static int adxl34x_spi_suspend(struct device *dev) |
98 | { | 99 | { |
100 | struct spi_device *spi = to_spi_device(dev); | ||
99 | struct adxl34x *ac = dev_get_drvdata(&spi->dev); | 101 | struct adxl34x *ac = dev_get_drvdata(&spi->dev); |
100 | 102 | ||
101 | adxl34x_suspend(ac); | 103 | adxl34x_suspend(ac); |
@@ -103,29 +105,29 @@ static int adxl34x_spi_suspend(struct spi_device *spi, pm_message_t message) | |||
103 | return 0; | 105 | return 0; |
104 | } | 106 | } |
105 | 107 | ||
106 | static int adxl34x_spi_resume(struct spi_device *spi) | 108 | static int adxl34x_spi_resume(struct device *dev) |
107 | { | 109 | { |
110 | struct spi_device *spi = to_spi_device(dev); | ||
108 | struct adxl34x *ac = dev_get_drvdata(&spi->dev); | 111 | struct adxl34x *ac = dev_get_drvdata(&spi->dev); |
109 | 112 | ||
110 | adxl34x_resume(ac); | 113 | adxl34x_resume(ac); |
111 | 114 | ||
112 | return 0; | 115 | return 0; |
113 | } | 116 | } |
114 | #else | ||
115 | # define adxl34x_spi_suspend NULL | ||
116 | # define adxl34x_spi_resume NULL | ||
117 | #endif | 117 | #endif |
118 | 118 | ||
119 | static SIMPLE_DEV_PM_OPS(adxl34x_spi_pm, adxl34x_spi_suspend, | ||
120 | adxl34x_spi_resume); | ||
121 | |||
119 | static struct spi_driver adxl34x_driver = { | 122 | static struct spi_driver adxl34x_driver = { |
120 | .driver = { | 123 | .driver = { |
121 | .name = "adxl34x", | 124 | .name = "adxl34x", |
122 | .bus = &spi_bus_type, | 125 | .bus = &spi_bus_type, |
123 | .owner = THIS_MODULE, | 126 | .owner = THIS_MODULE, |
127 | .pm = &adxl34x_spi_pm, | ||
124 | }, | 128 | }, |
125 | .probe = adxl34x_spi_probe, | 129 | .probe = adxl34x_spi_probe, |
126 | .remove = __devexit_p(adxl34x_spi_remove), | 130 | .remove = __devexit_p(adxl34x_spi_remove), |
127 | .suspend = adxl34x_spi_suspend, | ||
128 | .resume = adxl34x_spi_resume, | ||
129 | }; | 131 | }; |
130 | 132 | ||
131 | static int __init adxl34x_spi_init(void) | 133 | static int __init adxl34x_spi_init(void) |
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index de5900d50788..144ddbdeb9b3 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c | |||
@@ -716,7 +716,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, | |||
716 | pdata = dev->platform_data; | 716 | pdata = dev->platform_data; |
717 | if (!pdata) { | 717 | if (!pdata) { |
718 | dev_dbg(dev, | 718 | dev_dbg(dev, |
719 | "No platfrom data: Using default initialization\n"); | 719 | "No platform data: Using default initialization\n"); |
720 | pdata = &adxl34x_default_init; | 720 | pdata = &adxl34x_default_init; |
721 | } | 721 | } |
722 | 722 | ||
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 23257652b8e8..1de58e8a1b71 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -483,51 +483,88 @@ static void ati_remote2_complete_key(struct urb *urb) | |||
483 | } | 483 | } |
484 | 484 | ||
485 | static int ati_remote2_getkeycode(struct input_dev *idev, | 485 | static int ati_remote2_getkeycode(struct input_dev *idev, |
486 | unsigned int scancode, unsigned int *keycode) | 486 | struct input_keymap_entry *ke) |
487 | { | 487 | { |
488 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 488 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
489 | unsigned int mode; | 489 | unsigned int mode; |
490 | int index; | 490 | int offset; |
491 | 491 | unsigned int index; | |
492 | mode = scancode >> 8; | 492 | unsigned int scancode; |
493 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 493 | |
494 | return -EINVAL; | 494 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
495 | index = ke->index; | ||
496 | if (index >= ATI_REMOTE2_MODES * | ||
497 | ARRAY_SIZE(ati_remote2_key_table)) | ||
498 | return -EINVAL; | ||
499 | |||
500 | mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); | ||
501 | offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); | ||
502 | scancode = (mode << 8) + ati_remote2_key_table[offset].hw_code; | ||
503 | } else { | ||
504 | if (input_scancode_to_scalar(ke, &scancode)) | ||
505 | return -EINVAL; | ||
506 | |||
507 | mode = scancode >> 8; | ||
508 | if (mode > ATI_REMOTE2_PC) | ||
509 | return -EINVAL; | ||
510 | |||
511 | offset = ati_remote2_lookup(scancode & 0xff); | ||
512 | if (offset < 0) | ||
513 | return -EINVAL; | ||
514 | |||
515 | index = mode * ARRAY_SIZE(ati_remote2_key_table) + offset; | ||
516 | } | ||
495 | 517 | ||
496 | index = ati_remote2_lookup(scancode & 0xFF); | 518 | ke->keycode = ar2->keycode[mode][offset]; |
497 | if (index < 0) | 519 | ke->len = sizeof(scancode); |
498 | return -EINVAL; | 520 | memcpy(&ke->scancode, &scancode, sizeof(scancode)); |
521 | ke->index = index; | ||
499 | 522 | ||
500 | *keycode = ar2->keycode[mode][index]; | ||
501 | return 0; | 523 | return 0; |
502 | } | 524 | } |
503 | 525 | ||
504 | static int ati_remote2_setkeycode(struct input_dev *idev, | 526 | static int ati_remote2_setkeycode(struct input_dev *idev, |
505 | unsigned int scancode, unsigned int keycode) | 527 | const struct input_keymap_entry *ke, |
528 | unsigned int *old_keycode) | ||
506 | { | 529 | { |
507 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 530 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
508 | unsigned int mode, old_keycode; | 531 | unsigned int mode; |
509 | int index; | 532 | int offset; |
510 | 533 | unsigned int index; | |
511 | mode = scancode >> 8; | 534 | unsigned int scancode; |
512 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 535 | |
513 | return -EINVAL; | 536 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
514 | 537 | if (ke->index >= ATI_REMOTE2_MODES * | |
515 | index = ati_remote2_lookup(scancode & 0xFF); | 538 | ARRAY_SIZE(ati_remote2_key_table)) |
516 | if (index < 0) | 539 | return -EINVAL; |
517 | return -EINVAL; | 540 | |
541 | mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); | ||
542 | offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); | ||
543 | } else { | ||
544 | if (input_scancode_to_scalar(ke, &scancode)) | ||
545 | return -EINVAL; | ||
546 | |||
547 | mode = scancode >> 8; | ||
548 | if (mode > ATI_REMOTE2_PC) | ||
549 | return -EINVAL; | ||
550 | |||
551 | offset = ati_remote2_lookup(scancode & 0xff); | ||
552 | if (offset < 0) | ||
553 | return -EINVAL; | ||
554 | } | ||
518 | 555 | ||
519 | old_keycode = ar2->keycode[mode][index]; | 556 | *old_keycode = ar2->keycode[mode][offset]; |
520 | ar2->keycode[mode][index] = keycode; | 557 | ar2->keycode[mode][offset] = ke->keycode; |
521 | __set_bit(keycode, idev->keybit); | 558 | __set_bit(ke->keycode, idev->keybit); |
522 | 559 | ||
523 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { | 560 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { |
524 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { | 561 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { |
525 | if (ar2->keycode[mode][index] == old_keycode) | 562 | if (ar2->keycode[mode][index] == *old_keycode) |
526 | return 0; | 563 | return 0; |
527 | } | 564 | } |
528 | } | 565 | } |
529 | 566 | ||
530 | __clear_bit(old_keycode, idev->keybit); | 567 | __clear_bit(*old_keycode, idev->keybit); |
531 | 568 | ||
532 | return 0; | 569 | return 0; |
533 | } | 570 | } |
@@ -700,14 +737,17 @@ static ssize_t ati_remote2_store_channel_mask(struct device *dev, | |||
700 | 737 | ||
701 | mutex_lock(&ati_remote2_mutex); | 738 | mutex_lock(&ati_remote2_mutex); |
702 | 739 | ||
703 | if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask)) | 740 | if (mask != ar2->channel_mask) { |
704 | ar2->channel_mask = mask; | 741 | r = ati_remote2_setup(ar2, mask); |
742 | if (!r) | ||
743 | ar2->channel_mask = mask; | ||
744 | } | ||
705 | 745 | ||
706 | mutex_unlock(&ati_remote2_mutex); | 746 | mutex_unlock(&ati_remote2_mutex); |
707 | 747 | ||
708 | usb_autopm_put_interface(ar2->intf[0]); | 748 | usb_autopm_put_interface(ar2->intf[0]); |
709 | 749 | ||
710 | return count; | 750 | return r ? r : count; |
711 | } | 751 | } |
712 | 752 | ||
713 | static ssize_t ati_remote2_show_mode_mask(struct device *dev, | 753 | static ssize_t ati_remote2_show_mode_mask(struct device *dev, |
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c index 2b0eba6619bd..b09c7d127219 100644 --- a/drivers/input/misc/cm109.c +++ b/drivers/input/misc/cm109.c | |||
@@ -259,7 +259,7 @@ static unsigned short keymap_usbph01(int scancode) | |||
259 | 259 | ||
260 | /* | 260 | /* |
261 | * Keymap for ATCom AU-100 | 261 | * Keymap for ATCom AU-100 |
262 | * http://www.atcom.cn/En_products_AU100.html | 262 | * http://www.atcom.cn/products.html |
263 | * http://www.packetizer.com/products/au100/ | 263 | * http://www.packetizer.com/products/au100/ |
264 | * http://www.voip-info.org/wiki/view/AU-100 | 264 | * http://www.voip-info.org/wiki/view/AU-100 |
265 | * | 265 | * |
diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c new file mode 100644 index 000000000000..1633b6342267 --- /dev/null +++ b/drivers/input/misc/cma3000_d0x.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * VTI CMA3000_D0x Accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * Author: Hemanth V <hemanthv@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/types.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/input/cma3000.h> | ||
26 | |||
27 | #include "cma3000_d0x.h" | ||
28 | |||
29 | #define CMA3000_WHOAMI 0x00 | ||
30 | #define CMA3000_REVID 0x01 | ||
31 | #define CMA3000_CTRL 0x02 | ||
32 | #define CMA3000_STATUS 0x03 | ||
33 | #define CMA3000_RSTR 0x04 | ||
34 | #define CMA3000_INTSTATUS 0x05 | ||
35 | #define CMA3000_DOUTX 0x06 | ||
36 | #define CMA3000_DOUTY 0x07 | ||
37 | #define CMA3000_DOUTZ 0x08 | ||
38 | #define CMA3000_MDTHR 0x09 | ||
39 | #define CMA3000_MDFFTMR 0x0A | ||
40 | #define CMA3000_FFTHR 0x0B | ||
41 | |||
42 | #define CMA3000_RANGE2G (1 << 7) | ||
43 | #define CMA3000_RANGE8G (0 << 7) | ||
44 | #define CMA3000_BUSI2C (0 << 4) | ||
45 | #define CMA3000_MODEMASK (7 << 1) | ||
46 | #define CMA3000_GRANGEMASK (1 << 7) | ||
47 | |||
48 | #define CMA3000_STATUS_PERR 1 | ||
49 | #define CMA3000_INTSTATUS_FFDET (1 << 2) | ||
50 | |||
51 | /* Settling time delay in ms */ | ||
52 | #define CMA3000_SETDELAY 30 | ||
53 | |||
54 | /* Delay for clearing interrupt in us */ | ||
55 | #define CMA3000_INTDELAY 44 | ||
56 | |||
57 | |||
58 | /* | ||
59 | * Bit weights in mg for bit 0, other bits need | ||
60 | * multipy factor 2^n. Eight bit is the sign bit. | ||
61 | */ | ||
62 | #define BIT_TO_2G 18 | ||
63 | #define BIT_TO_8G 71 | ||
64 | |||
65 | struct cma3000_accl_data { | ||
66 | const struct cma3000_bus_ops *bus_ops; | ||
67 | const struct cma3000_platform_data *pdata; | ||
68 | |||
69 | struct device *dev; | ||
70 | struct input_dev *input_dev; | ||
71 | |||
72 | int bit_to_mg; | ||
73 | int irq; | ||
74 | |||
75 | int g_range; | ||
76 | u8 mode; | ||
77 | |||
78 | struct mutex mutex; | ||
79 | bool opened; | ||
80 | bool suspended; | ||
81 | }; | ||
82 | |||
83 | #define CMA3000_READ(data, reg, msg) \ | ||
84 | (data->bus_ops->read(data->dev, reg, msg)) | ||
85 | #define CMA3000_SET(data, reg, val, msg) \ | ||
86 | ((data)->bus_ops->write(data->dev, reg, val, msg)) | ||
87 | |||
88 | /* | ||
89 | * Conversion for each of the eight modes to g, depending | ||
90 | * on G range i.e 2G or 8G. Some modes always operate in | ||
91 | * 8G. | ||
92 | */ | ||
93 | |||
94 | static int mode_to_mg[8][2] = { | ||
95 | { 0, 0 }, | ||
96 | { BIT_TO_8G, BIT_TO_2G }, | ||
97 | { BIT_TO_8G, BIT_TO_2G }, | ||
98 | { BIT_TO_8G, BIT_TO_8G }, | ||
99 | { BIT_TO_8G, BIT_TO_8G }, | ||
100 | { BIT_TO_8G, BIT_TO_2G }, | ||
101 | { BIT_TO_8G, BIT_TO_2G }, | ||
102 | { 0, 0}, | ||
103 | }; | ||
104 | |||
105 | static void decode_mg(struct cma3000_accl_data *data, int *datax, | ||
106 | int *datay, int *dataz) | ||
107 | { | ||
108 | /* Data in 2's complement, convert to mg */ | ||
109 | *datax = ((s8)*datax) * data->bit_to_mg; | ||
110 | *datay = ((s8)*datay) * data->bit_to_mg; | ||
111 | *dataz = ((s8)*dataz) * data->bit_to_mg; | ||
112 | } | ||
113 | |||
114 | static irqreturn_t cma3000_thread_irq(int irq, void *dev_id) | ||
115 | { | ||
116 | struct cma3000_accl_data *data = dev_id; | ||
117 | int datax, datay, dataz; | ||
118 | u8 ctrl, mode, range, intr_status; | ||
119 | |||
120 | intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status"); | ||
121 | if (intr_status < 0) | ||
122 | return IRQ_NONE; | ||
123 | |||
124 | /* Check if free fall is detected, report immediately */ | ||
125 | if (intr_status & CMA3000_INTSTATUS_FFDET) { | ||
126 | input_report_abs(data->input_dev, ABS_MISC, 1); | ||
127 | input_sync(data->input_dev); | ||
128 | } else { | ||
129 | input_report_abs(data->input_dev, ABS_MISC, 0); | ||
130 | } | ||
131 | |||
132 | datax = CMA3000_READ(data, CMA3000_DOUTX, "X"); | ||
133 | datay = CMA3000_READ(data, CMA3000_DOUTY, "Y"); | ||
134 | dataz = CMA3000_READ(data, CMA3000_DOUTZ, "Z"); | ||
135 | |||
136 | ctrl = CMA3000_READ(data, CMA3000_CTRL, "ctrl"); | ||
137 | mode = (ctrl & CMA3000_MODEMASK) >> 1; | ||
138 | range = (ctrl & CMA3000_GRANGEMASK) >> 7; | ||
139 | |||
140 | data->bit_to_mg = mode_to_mg[mode][range]; | ||
141 | |||
142 | /* Interrupt not for this device */ | ||
143 | if (data->bit_to_mg == 0) | ||
144 | return IRQ_NONE; | ||
145 | |||
146 | /* Decode register values to milli g */ | ||
147 | decode_mg(data, &datax, &datay, &dataz); | ||
148 | |||
149 | input_report_abs(data->input_dev, ABS_X, datax); | ||
150 | input_report_abs(data->input_dev, ABS_Y, datay); | ||
151 | input_report_abs(data->input_dev, ABS_Z, dataz); | ||
152 | input_sync(data->input_dev); | ||
153 | |||
154 | return IRQ_HANDLED; | ||
155 | } | ||
156 | |||
157 | static int cma3000_reset(struct cma3000_accl_data *data) | ||
158 | { | ||
159 | int val; | ||
160 | |||
161 | /* Reset sequence */ | ||
162 | CMA3000_SET(data, CMA3000_RSTR, 0x02, "Reset"); | ||
163 | CMA3000_SET(data, CMA3000_RSTR, 0x0A, "Reset"); | ||
164 | CMA3000_SET(data, CMA3000_RSTR, 0x04, "Reset"); | ||
165 | |||
166 | /* Settling time delay */ | ||
167 | mdelay(10); | ||
168 | |||
169 | val = CMA3000_READ(data, CMA3000_STATUS, "Status"); | ||
170 | if (val < 0) { | ||
171 | dev_err(data->dev, "Reset failed\n"); | ||
172 | return val; | ||
173 | } | ||
174 | |||
175 | if (val & CMA3000_STATUS_PERR) { | ||
176 | dev_err(data->dev, "Parity Error\n"); | ||
177 | return -EIO; | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int cma3000_poweron(struct cma3000_accl_data *data) | ||
184 | { | ||
185 | const struct cma3000_platform_data *pdata = data->pdata; | ||
186 | u8 ctrl = 0; | ||
187 | int ret; | ||
188 | |||
189 | if (data->g_range == CMARANGE_2G) { | ||
190 | ctrl = (data->mode << 1) | CMA3000_RANGE2G; | ||
191 | } else if (data->g_range == CMARANGE_8G) { | ||
192 | ctrl = (data->mode << 1) | CMA3000_RANGE8G; | ||
193 | } else { | ||
194 | dev_info(data->dev, | ||
195 | "Invalid G range specified, assuming 8G\n"); | ||
196 | ctrl = (data->mode << 1) | CMA3000_RANGE8G; | ||
197 | } | ||
198 | |||
199 | ctrl |= data->bus_ops->ctrl_mod; | ||
200 | |||
201 | CMA3000_SET(data, CMA3000_MDTHR, pdata->mdthr, | ||
202 | "Motion Detect Threshold"); | ||
203 | CMA3000_SET(data, CMA3000_MDFFTMR, pdata->mdfftmr, | ||
204 | "Time register"); | ||
205 | CMA3000_SET(data, CMA3000_FFTHR, pdata->ffthr, | ||
206 | "Free fall threshold"); | ||
207 | ret = CMA3000_SET(data, CMA3000_CTRL, ctrl, "Mode setting"); | ||
208 | if (ret < 0) | ||
209 | return -EIO; | ||
210 | |||
211 | msleep(CMA3000_SETDELAY); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int cma3000_poweroff(struct cma3000_accl_data *data) | ||
217 | { | ||
218 | int ret; | ||
219 | |||
220 | ret = CMA3000_SET(data, CMA3000_CTRL, CMAMODE_POFF, "Mode setting"); | ||
221 | msleep(CMA3000_SETDELAY); | ||
222 | |||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | static int cma3000_open(struct input_dev *input_dev) | ||
227 | { | ||
228 | struct cma3000_accl_data *data = input_get_drvdata(input_dev); | ||
229 | |||
230 | mutex_lock(&data->mutex); | ||
231 | |||
232 | if (!data->suspended) | ||
233 | cma3000_poweron(data); | ||
234 | |||
235 | data->opened = true; | ||
236 | |||
237 | mutex_unlock(&data->mutex); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static void cma3000_close(struct input_dev *input_dev) | ||
243 | { | ||
244 | struct cma3000_accl_data *data = input_get_drvdata(input_dev); | ||
245 | |||
246 | mutex_lock(&data->mutex); | ||
247 | |||
248 | if (!data->suspended) | ||
249 | cma3000_poweroff(data); | ||
250 | |||
251 | data->opened = false; | ||
252 | |||
253 | mutex_unlock(&data->mutex); | ||
254 | } | ||
255 | |||
256 | void cma3000_suspend(struct cma3000_accl_data *data) | ||
257 | { | ||
258 | mutex_lock(&data->mutex); | ||
259 | |||
260 | if (!data->suspended && data->opened) | ||
261 | cma3000_poweroff(data); | ||
262 | |||
263 | data->suspended = true; | ||
264 | |||
265 | mutex_unlock(&data->mutex); | ||
266 | } | ||
267 | EXPORT_SYMBOL(cma3000_suspend); | ||
268 | |||
269 | |||
270 | void cma3000_resume(struct cma3000_accl_data *data) | ||
271 | { | ||
272 | mutex_lock(&data->mutex); | ||
273 | |||
274 | if (data->suspended && data->opened) | ||
275 | cma3000_poweron(data); | ||
276 | |||
277 | data->suspended = false; | ||
278 | |||
279 | mutex_unlock(&data->mutex); | ||
280 | } | ||
281 | EXPORT_SYMBOL(cma3000_resume); | ||
282 | |||
283 | struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, | ||
284 | const struct cma3000_bus_ops *bops) | ||
285 | { | ||
286 | const struct cma3000_platform_data *pdata = dev->platform_data; | ||
287 | struct cma3000_accl_data *data; | ||
288 | struct input_dev *input_dev; | ||
289 | int rev; | ||
290 | int error; | ||
291 | |||
292 | if (!pdata) { | ||
293 | dev_err(dev, "platform data not found\n"); | ||
294 | error = -EINVAL; | ||
295 | goto err_out; | ||
296 | } | ||
297 | |||
298 | |||
299 | /* if no IRQ return error */ | ||
300 | if (irq == 0) { | ||
301 | error = -EINVAL; | ||
302 | goto err_out; | ||
303 | } | ||
304 | |||
305 | data = kzalloc(sizeof(struct cma3000_accl_data), GFP_KERNEL); | ||
306 | input_dev = input_allocate_device(); | ||
307 | if (!data || !input_dev) { | ||
308 | error = -ENOMEM; | ||
309 | goto err_free_mem; | ||
310 | } | ||
311 | |||
312 | data->dev = dev; | ||
313 | data->input_dev = input_dev; | ||
314 | data->bus_ops = bops; | ||
315 | data->pdata = pdata; | ||
316 | data->irq = irq; | ||
317 | mutex_init(&data->mutex); | ||
318 | |||
319 | data->mode = pdata->mode; | ||
320 | if (data->mode < CMAMODE_DEFAULT || data->mode > CMAMODE_POFF) { | ||
321 | data->mode = CMAMODE_MOTDET; | ||
322 | dev_warn(dev, | ||
323 | "Invalid mode specified, assuming Motion Detect\n"); | ||
324 | } | ||
325 | |||
326 | data->g_range = pdata->g_range; | ||
327 | if (data->g_range != CMARANGE_2G && data->g_range != CMARANGE_8G) { | ||
328 | dev_info(dev, | ||
329 | "Invalid G range specified, assuming 8G\n"); | ||
330 | data->g_range = CMARANGE_8G; | ||
331 | } | ||
332 | |||
333 | input_dev->name = "cma3000-accelerometer"; | ||
334 | input_dev->id.bustype = bops->bustype; | ||
335 | input_dev->open = cma3000_open; | ||
336 | input_dev->close = cma3000_close; | ||
337 | |||
338 | __set_bit(EV_ABS, input_dev->evbit); | ||
339 | |||
340 | input_set_abs_params(input_dev, ABS_X, | ||
341 | -data->g_range, data->g_range, pdata->fuzz_x, 0); | ||
342 | input_set_abs_params(input_dev, ABS_Y, | ||
343 | -data->g_range, data->g_range, pdata->fuzz_y, 0); | ||
344 | input_set_abs_params(input_dev, ABS_Z, | ||
345 | -data->g_range, data->g_range, pdata->fuzz_z, 0); | ||
346 | input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0); | ||
347 | |||
348 | input_set_drvdata(input_dev, data); | ||
349 | |||
350 | error = cma3000_reset(data); | ||
351 | if (error) | ||
352 | goto err_free_mem; | ||
353 | |||
354 | rev = CMA3000_READ(data, CMA3000_REVID, "Revid"); | ||
355 | if (rev < 0) { | ||
356 | error = rev; | ||
357 | goto err_free_mem; | ||
358 | } | ||
359 | |||
360 | pr_info("CMA3000 Accelerometer: Revision %x\n", rev); | ||
361 | |||
362 | error = request_threaded_irq(irq, NULL, cma3000_thread_irq, | ||
363 | pdata->irqflags | IRQF_ONESHOT, | ||
364 | "cma3000_d0x", data); | ||
365 | if (error) { | ||
366 | dev_err(dev, "request_threaded_irq failed\n"); | ||
367 | goto err_free_mem; | ||
368 | } | ||
369 | |||
370 | error = input_register_device(data->input_dev); | ||
371 | if (error) { | ||
372 | dev_err(dev, "Unable to register input device\n"); | ||
373 | goto err_free_irq; | ||
374 | } | ||
375 | |||
376 | return data; | ||
377 | |||
378 | err_free_irq: | ||
379 | free_irq(irq, data); | ||
380 | err_free_mem: | ||
381 | input_free_device(input_dev); | ||
382 | kfree(data); | ||
383 | err_out: | ||
384 | return ERR_PTR(error); | ||
385 | } | ||
386 | EXPORT_SYMBOL(cma3000_init); | ||
387 | |||
388 | void cma3000_exit(struct cma3000_accl_data *data) | ||
389 | { | ||
390 | free_irq(data->irq, data); | ||
391 | input_unregister_device(data->input_dev); | ||
392 | kfree(data); | ||
393 | } | ||
394 | EXPORT_SYMBOL(cma3000_exit); | ||
395 | |||
396 | MODULE_DESCRIPTION("CMA3000-D0x Accelerometer Driver"); | ||
397 | MODULE_LICENSE("GPL"); | ||
398 | MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>"); | ||
diff --git a/drivers/input/misc/cma3000_d0x.h b/drivers/input/misc/cma3000_d0x.h new file mode 100644 index 000000000000..2304ce306e1c --- /dev/null +++ b/drivers/input/misc/cma3000_d0x.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * VTI CMA3000_D0x Accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * Author: Hemanth V <hemanthv@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifndef _INPUT_CMA3000_H | ||
21 | #define _INPUT_CMA3000_H | ||
22 | |||
23 | #include <linux/types.h> | ||
24 | #include <linux/input.h> | ||
25 | |||
26 | struct device; | ||
27 | struct cma3000_accl_data; | ||
28 | |||
29 | struct cma3000_bus_ops { | ||
30 | u16 bustype; | ||
31 | u8 ctrl_mod; | ||
32 | int (*read)(struct device *, u8, char *); | ||
33 | int (*write)(struct device *, u8, u8, char *); | ||
34 | }; | ||
35 | |||
36 | struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, | ||
37 | const struct cma3000_bus_ops *bops); | ||
38 | void cma3000_exit(struct cma3000_accl_data *); | ||
39 | void cma3000_suspend(struct cma3000_accl_data *); | ||
40 | void cma3000_resume(struct cma3000_accl_data *); | ||
41 | |||
42 | #endif | ||
diff --git a/drivers/input/misc/cma3000_d0x_i2c.c b/drivers/input/misc/cma3000_d0x_i2c.c new file mode 100644 index 000000000000..d100cc5c5783 --- /dev/null +++ b/drivers/input/misc/cma3000_d0x_i2c.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * Implements I2C interface for VTI CMA300_D0x Accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * Author: Hemanth V <hemanthv@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/input/cma3000.h> | ||
23 | #include "cma3000_d0x.h" | ||
24 | |||
25 | static int cma3000_i2c_set(struct device *dev, | ||
26 | u8 reg, u8 val, char *msg) | ||
27 | { | ||
28 | struct i2c_client *client = to_i2c_client(dev); | ||
29 | int ret; | ||
30 | |||
31 | ret = i2c_smbus_write_byte_data(client, reg, val); | ||
32 | if (ret < 0) | ||
33 | dev_err(&client->dev, | ||
34 | "%s failed (%s, %d)\n", __func__, msg, ret); | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | static int cma3000_i2c_read(struct device *dev, u8 reg, char *msg) | ||
39 | { | ||
40 | struct i2c_client *client = to_i2c_client(dev); | ||
41 | int ret; | ||
42 | |||
43 | ret = i2c_smbus_read_byte_data(client, reg); | ||
44 | if (ret < 0) | ||
45 | dev_err(&client->dev, | ||
46 | "%s failed (%s, %d)\n", __func__, msg, ret); | ||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static const struct cma3000_bus_ops cma3000_i2c_bops = { | ||
51 | .bustype = BUS_I2C, | ||
52 | #define CMA3000_BUSI2C (0 << 4) | ||
53 | .ctrl_mod = CMA3000_BUSI2C, | ||
54 | .read = cma3000_i2c_read, | ||
55 | .write = cma3000_i2c_set, | ||
56 | }; | ||
57 | |||
58 | static int __devinit cma3000_i2c_probe(struct i2c_client *client, | ||
59 | const struct i2c_device_id *id) | ||
60 | { | ||
61 | struct cma3000_accl_data *data; | ||
62 | |||
63 | data = cma3000_init(&client->dev, client->irq, &cma3000_i2c_bops); | ||
64 | if (IS_ERR(data)) | ||
65 | return PTR_ERR(data); | ||
66 | |||
67 | i2c_set_clientdata(client, data); | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int __devexit cma3000_i2c_remove(struct i2c_client *client) | ||
73 | { | ||
74 | struct cma3000_accl_data *data = i2c_get_clientdata(client); | ||
75 | |||
76 | cma3000_exit(data); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | #ifdef CONFIG_PM | ||
82 | static int cma3000_i2c_suspend(struct device *dev) | ||
83 | { | ||
84 | struct i2c_client *client = to_i2c_client(dev); | ||
85 | struct cma3000_accl_data *data = i2c_get_clientdata(client); | ||
86 | |||
87 | cma3000_suspend(data); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int cma3000_i2c_resume(struct device *dev) | ||
93 | { | ||
94 | struct i2c_client *client = to_i2c_client(dev); | ||
95 | struct cma3000_accl_data *data = i2c_get_clientdata(client); | ||
96 | |||
97 | cma3000_resume(data); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static const struct dev_pm_ops cma3000_i2c_pm_ops = { | ||
103 | .suspend = cma3000_i2c_suspend, | ||
104 | .resume = cma3000_i2c_resume, | ||
105 | }; | ||
106 | #endif | ||
107 | |||
108 | static const struct i2c_device_id cma3000_i2c_id[] = { | ||
109 | { "cma3000_d01", 0 }, | ||
110 | { }, | ||
111 | }; | ||
112 | |||
113 | MODULE_DEVICE_TABLE(i2c, cma3000_i2c_id); | ||
114 | |||
115 | static struct i2c_driver cma3000_i2c_driver = { | ||
116 | .probe = cma3000_i2c_probe, | ||
117 | .remove = __devexit_p(cma3000_i2c_remove), | ||
118 | .id_table = cma3000_i2c_id, | ||
119 | .driver = { | ||
120 | .name = "cma3000_i2c_accl", | ||
121 | .owner = THIS_MODULE, | ||
122 | #ifdef CONFIG_PM | ||
123 | .pm = &cma3000_i2c_pm_ops, | ||
124 | #endif | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | static int __init cma3000_i2c_init(void) | ||
129 | { | ||
130 | return i2c_add_driver(&cma3000_i2c_driver); | ||
131 | } | ||
132 | |||
133 | static void __exit cma3000_i2c_exit(void) | ||
134 | { | ||
135 | i2c_del_driver(&cma3000_i2c_driver); | ||
136 | } | ||
137 | |||
138 | module_init(cma3000_i2c_init); | ||
139 | module_exit(cma3000_i2c_exit); | ||
140 | |||
141 | MODULE_DESCRIPTION("CMA3000-D0x Accelerometer I2C Driver"); | ||
142 | MODULE_LICENSE("GPL"); | ||
143 | MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>"); | ||
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index c19066479057..0b4f54265f62 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <linux/proc_fs.h> | 43 | #include <linux/proc_fs.h> |
44 | #include <linux/poll.h> | 44 | #include <linux/poll.h> |
45 | #include <linux/rtc.h> | 45 | #include <linux/rtc.h> |
46 | #include <linux/smp_lock.h> | 46 | #include <linux/mutex.h> |
47 | #include <linux/semaphore.h> | 47 | #include <linux/semaphore.h> |
48 | 48 | ||
49 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); | 49 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); |
@@ -52,6 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
52 | 52 | ||
53 | #define RTC_VERSION "1.10d" | 53 | #define RTC_VERSION "1.10d" |
54 | 54 | ||
55 | static DEFINE_MUTEX(hp_sdc_rtc_mutex); | ||
55 | static unsigned long epoch = 2000; | 56 | static unsigned long epoch = 2000; |
56 | 57 | ||
57 | static struct semaphore i8042tregs; | 58 | static struct semaphore i8042tregs; |
@@ -104,7 +105,7 @@ static int hp_sdc_rtc_do_read_bbrtc (struct rtc_time *rtctm) | |||
104 | t.endidx = 91; | 105 | t.endidx = 91; |
105 | t.seq = tseq; | 106 | t.seq = tseq; |
106 | t.act.semaphore = &tsem; | 107 | t.act.semaphore = &tsem; |
107 | init_MUTEX_LOCKED(&tsem); | 108 | sema_init(&tsem, 0); |
108 | 109 | ||
109 | if (hp_sdc_enqueue_transaction(&t)) return -1; | 110 | if (hp_sdc_enqueue_transaction(&t)) return -1; |
110 | 111 | ||
@@ -665,9 +666,9 @@ static long hp_sdc_rtc_unlocked_ioctl(struct file *file, | |||
665 | { | 666 | { |
666 | int ret; | 667 | int ret; |
667 | 668 | ||
668 | lock_kernel(); | 669 | mutex_lock(&hp_sdc_rtc_mutex); |
669 | ret = hp_sdc_rtc_ioctl(file, cmd, arg); | 670 | ret = hp_sdc_rtc_ioctl(file, cmd, arg); |
670 | unlock_kernel(); | 671 | mutex_unlock(&hp_sdc_rtc_mutex); |
671 | 672 | ||
672 | return ret; | 673 | return ret; |
673 | } | 674 | } |
@@ -698,7 +699,7 @@ static int __init hp_sdc_rtc_init(void) | |||
698 | return -ENODEV; | 699 | return -ENODEV; |
699 | #endif | 700 | #endif |
700 | 701 | ||
701 | init_MUTEX(&i8042tregs); | 702 | sema_init(&i8042tregs, 1); |
702 | 703 | ||
703 | if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) | 704 | if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) |
704 | return ret; | 705 | return ret; |
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index 9dfd6e5f786f..1f38302a5951 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c | |||
@@ -69,11 +69,7 @@ static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned | |||
69 | } | 69 | } |
70 | 70 | ||
71 | if (value > 20 && value < 32767) | 71 | if (value > 20 && value < 32767) |
72 | #ifndef FREQ | 72 | count = (IXP4XX_TIMER_FREQ / (value * 4)) - 1; |
73 | count = (ixp4xx_get_board_tick_rate() / (value * 4)) - 1; | ||
74 | #else | ||
75 | count = (FREQ / (value * 4)) - 1; | ||
76 | #endif | ||
77 | 73 | ||
78 | ixp4xx_spkr_control(pin, count); | 74 | ixp4xx_spkr_control(pin, count); |
79 | 75 | ||
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index a93c525475c6..fc62256c963f 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c | |||
@@ -312,7 +312,7 @@ static void keyspan_check_data(struct usb_keyspan *remote) | |||
312 | remote->data.tester = remote->data.tester >> 5; | 312 | remote->data.tester = remote->data.tester >> 5; |
313 | remote->data.bits_left -= 5; | 313 | remote->data.bits_left -= 5; |
314 | } else { | 314 | } else { |
315 | err("Bad message recieved, no stop bit found.\n"); | 315 | err("Bad message received, no stop bit found.\n"); |
316 | } | 316 | } |
317 | 317 | ||
318 | dev_dbg(&remote->udev->dev, | 318 | dev_dbg(&remote->udev->dev, |
diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c index 80af44608018..7de0ded4ccc3 100644 --- a/drivers/input/misc/max8925_onkey.c +++ b/drivers/input/misc/max8925_onkey.c | |||
@@ -27,27 +27,37 @@ | |||
27 | #include <linux/mfd/max8925.h> | 27 | #include <linux/mfd/max8925.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | 29 | ||
30 | #define SW_INPUT (1 << 7) /* 0/1 -- up/down */ | ||
30 | #define HARDRESET_EN (1 << 7) | 31 | #define HARDRESET_EN (1 << 7) |
31 | #define PWREN_EN (1 << 7) | 32 | #define PWREN_EN (1 << 7) |
32 | 33 | ||
33 | struct max8925_onkey_info { | 34 | struct max8925_onkey_info { |
34 | struct input_dev *idev; | 35 | struct input_dev *idev; |
35 | struct i2c_client *i2c; | 36 | struct i2c_client *i2c; |
36 | int irq; | 37 | struct device *dev; |
38 | int irq[2]; | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | /* | 41 | /* |
40 | * MAX8925 gives us an interrupt when ONKEY is held for 3 seconds. | 42 | * MAX8925 gives us an interrupt when ONKEY is pressed or released. |
41 | * max8925_set_bits() operates I2C bus and may sleep. So implement | 43 | * max8925_set_bits() operates I2C bus and may sleep. So implement |
42 | * it in thread IRQ handler. | 44 | * it in thread IRQ handler. |
43 | */ | 45 | */ |
44 | static irqreturn_t max8925_onkey_handler(int irq, void *data) | 46 | static irqreturn_t max8925_onkey_handler(int irq, void *data) |
45 | { | 47 | { |
46 | struct max8925_onkey_info *info = data; | 48 | struct max8925_onkey_info *info = data; |
47 | 49 | int ret, event; | |
48 | input_report_key(info->idev, KEY_POWER, 1); | 50 | |
51 | ret = max8925_reg_read(info->i2c, MAX8925_ON_OFF_STATUS); | ||
52 | if (ret & SW_INPUT) | ||
53 | event = 1; | ||
54 | else | ||
55 | event = 0; | ||
56 | input_report_key(info->idev, KEY_POWER, event); | ||
49 | input_sync(info->idev); | 57 | input_sync(info->idev); |
50 | 58 | ||
59 | dev_dbg(info->dev, "onkey event:%d\n", event); | ||
60 | |||
51 | /* Enable hardreset to halt if system isn't shutdown on time */ | 61 | /* Enable hardreset to halt if system isn't shutdown on time */ |
52 | max8925_set_bits(info->i2c, MAX8925_SYSENSEL, | 62 | max8925_set_bits(info->i2c, MAX8925_SYSENSEL, |
53 | HARDRESET_EN, HARDRESET_EN); | 63 | HARDRESET_EN, HARDRESET_EN); |
@@ -59,14 +69,42 @@ static int __devinit max8925_onkey_probe(struct platform_device *pdev) | |||
59 | { | 69 | { |
60 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | 70 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); |
61 | struct max8925_onkey_info *info; | 71 | struct max8925_onkey_info *info; |
62 | int error; | 72 | int irq[2], error; |
73 | |||
74 | irq[0] = platform_get_irq(pdev, 0); | ||
75 | if (irq[0] < 0) { | ||
76 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | irq[1] = platform_get_irq(pdev, 1); | ||
80 | if (irq[1] < 0) { | ||
81 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
82 | return -EINVAL; | ||
83 | } | ||
63 | 84 | ||
64 | info = kzalloc(sizeof(struct max8925_onkey_info), GFP_KERNEL); | 85 | info = kzalloc(sizeof(struct max8925_onkey_info), GFP_KERNEL); |
65 | if (!info) | 86 | if (!info) |
66 | return -ENOMEM; | 87 | return -ENOMEM; |
67 | 88 | ||
68 | info->i2c = chip->i2c; | 89 | info->i2c = chip->i2c; |
69 | info->irq = chip->irq_base + MAX8925_IRQ_GPM_SW_3SEC; | 90 | info->dev = &pdev->dev; |
91 | irq[0] += chip->irq_base; | ||
92 | irq[1] += chip->irq_base; | ||
93 | |||
94 | error = request_threaded_irq(irq[0], NULL, max8925_onkey_handler, | ||
95 | IRQF_ONESHOT, "onkey-down", info); | ||
96 | if (error < 0) { | ||
97 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
98 | irq[0], error); | ||
99 | goto out; | ||
100 | } | ||
101 | error = request_threaded_irq(irq[1], NULL, max8925_onkey_handler, | ||
102 | IRQF_ONESHOT, "onkey-up", info); | ||
103 | if (error < 0) { | ||
104 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
105 | irq[1], error); | ||
106 | goto out_irq; | ||
107 | } | ||
70 | 108 | ||
71 | info->idev = input_allocate_device(); | 109 | info->idev = input_allocate_device(); |
72 | if (!info->idev) { | 110 | if (!info->idev) { |
@@ -79,32 +117,29 @@ static int __devinit max8925_onkey_probe(struct platform_device *pdev) | |||
79 | info->idev->phys = "max8925_on/input0"; | 117 | info->idev->phys = "max8925_on/input0"; |
80 | info->idev->id.bustype = BUS_I2C; | 118 | info->idev->id.bustype = BUS_I2C; |
81 | info->idev->dev.parent = &pdev->dev; | 119 | info->idev->dev.parent = &pdev->dev; |
120 | info->irq[0] = irq[0]; | ||
121 | info->irq[1] = irq[1]; | ||
82 | info->idev->evbit[0] = BIT_MASK(EV_KEY); | 122 | info->idev->evbit[0] = BIT_MASK(EV_KEY); |
83 | info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); | 123 | info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); |
84 | 124 | ||
85 | error = request_threaded_irq(info->irq, NULL, max8925_onkey_handler, | ||
86 | IRQF_ONESHOT, "onkey", info); | ||
87 | if (error < 0) { | ||
88 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
89 | info->irq, error); | ||
90 | goto out_irq; | ||
91 | } | ||
92 | 125 | ||
93 | error = input_register_device(info->idev); | 126 | error = input_register_device(info->idev); |
94 | if (error) { | 127 | if (error) { |
95 | dev_err(chip->dev, "Can't register input device: %d\n", error); | 128 | dev_err(chip->dev, "Can't register input device: %d\n", error); |
96 | goto out; | 129 | goto out_reg; |
97 | } | 130 | } |
98 | 131 | ||
99 | platform_set_drvdata(pdev, info); | 132 | platform_set_drvdata(pdev, info); |
100 | 133 | ||
101 | return 0; | 134 | return 0; |
102 | 135 | ||
103 | out: | 136 | out_reg: |
104 | free_irq(info->irq, info); | ||
105 | out_irq: | ||
106 | input_free_device(info->idev); | 137 | input_free_device(info->idev); |
107 | out_input: | 138 | out_input: |
139 | free_irq(info->irq[1], info); | ||
140 | out_irq: | ||
141 | free_irq(info->irq[0], info); | ||
142 | out: | ||
108 | kfree(info); | 143 | kfree(info); |
109 | return error; | 144 | return error; |
110 | } | 145 | } |
@@ -113,7 +148,8 @@ static int __devexit max8925_onkey_remove(struct platform_device *pdev) | |||
113 | { | 148 | { |
114 | struct max8925_onkey_info *info = platform_get_drvdata(pdev); | 149 | struct max8925_onkey_info *info = platform_get_drvdata(pdev); |
115 | 150 | ||
116 | free_irq(info->irq, info); | 151 | free_irq(info->irq[0], info); |
152 | free_irq(info->irq[1], info); | ||
117 | input_unregister_device(info->idev); | 153 | input_unregister_device(info->idev); |
118 | kfree(info); | 154 | kfree(info); |
119 | 155 | ||
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index 4b42ffc0532a..08be1a355956 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c | |||
@@ -127,14 +127,6 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 | |||
127 | idev->id.product = 0x0001; | 127 | idev->id.product = 0x0001; |
128 | idev->id.version = 0x0100; | 128 | idev->id.version = 0x0100; |
129 | 129 | ||
130 | input_set_drvdata(idev, lp); | ||
131 | |||
132 | ret = input_register_device(idev); | ||
133 | if (ret) { | ||
134 | dev_err(&client->dev, "input_register_device() failed\n"); | ||
135 | goto fail_register; | ||
136 | } | ||
137 | |||
138 | lp->laststate = read_state(lp); | 130 | lp->laststate = read_state(lp); |
139 | 131 | ||
140 | ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler, | 132 | ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler, |
@@ -142,16 +134,21 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 | |||
142 | DRV_NAME, lp); | 134 | DRV_NAME, lp); |
143 | if (ret) { | 135 | if (ret) { |
144 | dev_err(&client->dev, "IRQ %d is not free\n", client->irq); | 136 | dev_err(&client->dev, "IRQ %d is not free\n", client->irq); |
145 | goto fail_irq; | 137 | goto fail_free_device; |
138 | } | ||
139 | |||
140 | ret = input_register_device(idev); | ||
141 | if (ret) { | ||
142 | dev_err(&client->dev, "input_register_device() failed\n"); | ||
143 | goto fail_free_irq; | ||
146 | } | 144 | } |
147 | 145 | ||
148 | i2c_set_clientdata(client, lp); | 146 | i2c_set_clientdata(client, lp); |
149 | return 0; | 147 | return 0; |
150 | 148 | ||
151 | fail_irq: | 149 | fail_free_irq: |
152 | input_unregister_device(idev); | 150 | free_irq(client->irq, lp); |
153 | fail_register: | 151 | fail_free_device: |
154 | input_set_drvdata(idev, NULL); | ||
155 | input_free_device(idev); | 152 | input_free_device(idev); |
156 | fail_allocate: | 153 | fail_allocate: |
157 | kfree(lp); | 154 | kfree(lp); |
@@ -172,19 +169,29 @@ static int __devexit pcf8574_kp_remove(struct i2c_client *client) | |||
172 | } | 169 | } |
173 | 170 | ||
174 | #ifdef CONFIG_PM | 171 | #ifdef CONFIG_PM |
175 | static int pcf8574_kp_resume(struct i2c_client *client) | 172 | static int pcf8574_kp_resume(struct device *dev) |
176 | { | 173 | { |
174 | struct i2c_client *client = to_i2c_client(dev); | ||
175 | |||
177 | enable_irq(client->irq); | 176 | enable_irq(client->irq); |
178 | 177 | ||
179 | return 0; | 178 | return 0; |
180 | } | 179 | } |
181 | 180 | ||
182 | static int pcf8574_kp_suspend(struct i2c_client *client, pm_message_t mesg) | 181 | static int pcf8574_kp_suspend(struct device *dev) |
183 | { | 182 | { |
183 | struct i2c_client *client = to_i2c_client(dev); | ||
184 | |||
184 | disable_irq(client->irq); | 185 | disable_irq(client->irq); |
185 | 186 | ||
186 | return 0; | 187 | return 0; |
187 | } | 188 | } |
189 | |||
190 | static const struct dev_pm_ops pcf8574_kp_pm_ops = { | ||
191 | .suspend = pcf8574_kp_suspend, | ||
192 | .resume = pcf8574_kp_resume, | ||
193 | }; | ||
194 | |||
188 | #else | 195 | #else |
189 | # define pcf8574_kp_resume NULL | 196 | # define pcf8574_kp_resume NULL |
190 | # define pcf8574_kp_suspend NULL | 197 | # define pcf8574_kp_suspend NULL |
@@ -200,11 +207,12 @@ static struct i2c_driver pcf8574_kp_driver = { | |||
200 | .driver = { | 207 | .driver = { |
201 | .name = DRV_NAME, | 208 | .name = DRV_NAME, |
202 | .owner = THIS_MODULE, | 209 | .owner = THIS_MODULE, |
210 | #ifdef CONFIG_PM | ||
211 | .pm = &pcf8574_kp_pm_ops, | ||
212 | #endif | ||
203 | }, | 213 | }, |
204 | .probe = pcf8574_kp_probe, | 214 | .probe = pcf8574_kp_probe, |
205 | .remove = __devexit_p(pcf8574_kp_remove), | 215 | .remove = __devexit_p(pcf8574_kp_remove), |
206 | .suspend = pcf8574_kp_suspend, | ||
207 | .resume = pcf8574_kp_resume, | ||
208 | .id_table = pcf8574_kp_id, | 216 | .id_table = pcf8574_kp_id, |
209 | }; | 217 | }; |
210 | 218 | ||
diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c new file mode 100644 index 000000000000..b3cfb9c71e66 --- /dev/null +++ b/drivers/input/misc/pmic8xxx-pwrkey.c | |||
@@ -0,0 +1,232 @@ | |||
1 | /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License version 2 and | ||
5 | * only version 2 as published by the Free Software Foundation. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/log2.h> | ||
22 | |||
23 | #include <linux/mfd/pm8xxx/core.h> | ||
24 | #include <linux/input/pmic8xxx-pwrkey.h> | ||
25 | |||
26 | #define PON_CNTL_1 0x1C | ||
27 | #define PON_CNTL_PULL_UP BIT(7) | ||
28 | #define PON_CNTL_TRIG_DELAY_MASK (0x7) | ||
29 | |||
30 | /** | ||
31 | * struct pmic8xxx_pwrkey - pmic8xxx pwrkey information | ||
32 | * @key_press_irq: key press irq number | ||
33 | */ | ||
34 | struct pmic8xxx_pwrkey { | ||
35 | struct input_dev *pwr; | ||
36 | int key_press_irq; | ||
37 | }; | ||
38 | |||
39 | static irqreturn_t pwrkey_press_irq(int irq, void *_pwrkey) | ||
40 | { | ||
41 | struct pmic8xxx_pwrkey *pwrkey = _pwrkey; | ||
42 | |||
43 | input_report_key(pwrkey->pwr, KEY_POWER, 1); | ||
44 | input_sync(pwrkey->pwr); | ||
45 | |||
46 | return IRQ_HANDLED; | ||
47 | } | ||
48 | |||
49 | static irqreturn_t pwrkey_release_irq(int irq, void *_pwrkey) | ||
50 | { | ||
51 | struct pmic8xxx_pwrkey *pwrkey = _pwrkey; | ||
52 | |||
53 | input_report_key(pwrkey->pwr, KEY_POWER, 0); | ||
54 | input_sync(pwrkey->pwr); | ||
55 | |||
56 | return IRQ_HANDLED; | ||
57 | } | ||
58 | |||
59 | #ifdef CONFIG_PM_SLEEP | ||
60 | static int pmic8xxx_pwrkey_suspend(struct device *dev) | ||
61 | { | ||
62 | struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); | ||
63 | |||
64 | if (device_may_wakeup(dev)) | ||
65 | enable_irq_wake(pwrkey->key_press_irq); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int pmic8xxx_pwrkey_resume(struct device *dev) | ||
71 | { | ||
72 | struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); | ||
73 | |||
74 | if (device_may_wakeup(dev)) | ||
75 | disable_irq_wake(pwrkey->key_press_irq); | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | #endif | ||
80 | |||
81 | static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops, | ||
82 | pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume); | ||
83 | |||
84 | static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev) | ||
85 | { | ||
86 | struct input_dev *pwr; | ||
87 | int key_release_irq = platform_get_irq(pdev, 0); | ||
88 | int key_press_irq = platform_get_irq(pdev, 1); | ||
89 | int err; | ||
90 | unsigned int delay; | ||
91 | u8 pon_cntl; | ||
92 | struct pmic8xxx_pwrkey *pwrkey; | ||
93 | const struct pm8xxx_pwrkey_platform_data *pdata = | ||
94 | dev_get_platdata(&pdev->dev); | ||
95 | |||
96 | if (!pdata) { | ||
97 | dev_err(&pdev->dev, "power key platform data not supplied\n"); | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | |||
101 | if (pdata->kpd_trigger_delay_us > 62500) { | ||
102 | dev_err(&pdev->dev, "invalid power key trigger delay\n"); | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | |||
106 | pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL); | ||
107 | if (!pwrkey) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | pwr = input_allocate_device(); | ||
111 | if (!pwr) { | ||
112 | dev_dbg(&pdev->dev, "Can't allocate power button\n"); | ||
113 | err = -ENOMEM; | ||
114 | goto free_pwrkey; | ||
115 | } | ||
116 | |||
117 | input_set_capability(pwr, EV_KEY, KEY_POWER); | ||
118 | |||
119 | pwr->name = "pmic8xxx_pwrkey"; | ||
120 | pwr->phys = "pmic8xxx_pwrkey/input0"; | ||
121 | pwr->dev.parent = &pdev->dev; | ||
122 | |||
123 | delay = (pdata->kpd_trigger_delay_us << 10) / USEC_PER_SEC; | ||
124 | delay = 1 + ilog2(delay); | ||
125 | |||
126 | err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl); | ||
127 | if (err < 0) { | ||
128 | dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err); | ||
129 | goto free_input_dev; | ||
130 | } | ||
131 | |||
132 | pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; | ||
133 | pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK); | ||
134 | if (pdata->pull_up) | ||
135 | pon_cntl |= PON_CNTL_PULL_UP; | ||
136 | else | ||
137 | pon_cntl &= ~PON_CNTL_PULL_UP; | ||
138 | |||
139 | err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl); | ||
140 | if (err < 0) { | ||
141 | dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err); | ||
142 | goto free_input_dev; | ||
143 | } | ||
144 | |||
145 | err = input_register_device(pwr); | ||
146 | if (err) { | ||
147 | dev_dbg(&pdev->dev, "Can't register power key: %d\n", err); | ||
148 | goto free_input_dev; | ||
149 | } | ||
150 | |||
151 | pwrkey->key_press_irq = key_press_irq; | ||
152 | pwrkey->pwr = pwr; | ||
153 | |||
154 | platform_set_drvdata(pdev, pwrkey); | ||
155 | |||
156 | err = request_irq(key_press_irq, pwrkey_press_irq, | ||
157 | IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey); | ||
158 | if (err < 0) { | ||
159 | dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", | ||
160 | key_press_irq, err); | ||
161 | goto unreg_input_dev; | ||
162 | } | ||
163 | |||
164 | err = request_irq(key_release_irq, pwrkey_release_irq, | ||
165 | IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey); | ||
166 | if (err < 0) { | ||
167 | dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", | ||
168 | key_release_irq, err); | ||
169 | |||
170 | goto free_press_irq; | ||
171 | } | ||
172 | |||
173 | device_init_wakeup(&pdev->dev, pdata->wakeup); | ||
174 | |||
175 | return 0; | ||
176 | |||
177 | free_press_irq: | ||
178 | free_irq(key_press_irq, NULL); | ||
179 | unreg_input_dev: | ||
180 | platform_set_drvdata(pdev, NULL); | ||
181 | input_unregister_device(pwr); | ||
182 | pwr = NULL; | ||
183 | free_input_dev: | ||
184 | input_free_device(pwr); | ||
185 | free_pwrkey: | ||
186 | kfree(pwrkey); | ||
187 | return err; | ||
188 | } | ||
189 | |||
190 | static int __devexit pmic8xxx_pwrkey_remove(struct platform_device *pdev) | ||
191 | { | ||
192 | struct pmic8xxx_pwrkey *pwrkey = platform_get_drvdata(pdev); | ||
193 | int key_release_irq = platform_get_irq(pdev, 0); | ||
194 | int key_press_irq = platform_get_irq(pdev, 1); | ||
195 | |||
196 | device_init_wakeup(&pdev->dev, 0); | ||
197 | |||
198 | free_irq(key_press_irq, pwrkey); | ||
199 | free_irq(key_release_irq, pwrkey); | ||
200 | input_unregister_device(pwrkey->pwr); | ||
201 | platform_set_drvdata(pdev, NULL); | ||
202 | kfree(pwrkey); | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static struct platform_driver pmic8xxx_pwrkey_driver = { | ||
208 | .probe = pmic8xxx_pwrkey_probe, | ||
209 | .remove = __devexit_p(pmic8xxx_pwrkey_remove), | ||
210 | .driver = { | ||
211 | .name = PM8XXX_PWRKEY_DEV_NAME, | ||
212 | .owner = THIS_MODULE, | ||
213 | .pm = &pm8xxx_pwr_key_pm_ops, | ||
214 | }, | ||
215 | }; | ||
216 | |||
217 | static int __init pmic8xxx_pwrkey_init(void) | ||
218 | { | ||
219 | return platform_driver_register(&pmic8xxx_pwrkey_driver); | ||
220 | } | ||
221 | module_init(pmic8xxx_pwrkey_init); | ||
222 | |||
223 | static void __exit pmic8xxx_pwrkey_exit(void) | ||
224 | { | ||
225 | platform_driver_unregister(&pmic8xxx_pwrkey_driver); | ||
226 | } | ||
227 | module_exit(pmic8xxx_pwrkey_exit); | ||
228 | |||
229 | MODULE_ALIAS("platform:pmic8xxx_pwrkey"); | ||
230 | MODULE_DESCRIPTION("PMIC8XXX Power Key driver"); | ||
231 | MODULE_LICENSE("GPL v2"); | ||
232 | MODULE_AUTHOR("Trilok Soni <tsoni@codeaurora.org>"); | ||
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index bf170f6b4422..f45947190e4f 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c | |||
@@ -280,7 +280,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev | |||
280 | 280 | ||
281 | pm->configcr = kmalloc(sizeof(*(pm->configcr)), GFP_KERNEL); | 281 | pm->configcr = kmalloc(sizeof(*(pm->configcr)), GFP_KERNEL); |
282 | if (!pm->configcr) | 282 | if (!pm->configcr) |
283 | return -1; | 283 | return -ENOMEM; |
284 | 284 | ||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 1f8e0108962e..2c8b84dd9dac 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * rotary_encoder.c | 2 | * rotary_encoder.c |
3 | * | 3 | * |
4 | * (c) 2009 Daniel Mack <daniel@caiaq.de> | 4 | * (c) 2009 Daniel Mack <daniel@caiaq.de> |
5 | * Copyright (C) 2011 Johan Hovold <jhovold@gmail.com> | ||
5 | * | 6 | * |
6 | * state machine code inspired by code from Tim Ruetz | 7 | * state machine code inspired by code from Tim Ruetz |
7 | * | 8 | * |
@@ -38,52 +39,66 @@ struct rotary_encoder { | |||
38 | 39 | ||
39 | bool armed; | 40 | bool armed; |
40 | unsigned char dir; /* 0 - clockwise, 1 - CCW */ | 41 | unsigned char dir; /* 0 - clockwise, 1 - CCW */ |
42 | |||
43 | char last_stable; | ||
41 | }; | 44 | }; |
42 | 45 | ||
43 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | 46 | static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata) |
44 | { | 47 | { |
45 | struct rotary_encoder *encoder = dev_id; | ||
46 | struct rotary_encoder_platform_data *pdata = encoder->pdata; | ||
47 | int a = !!gpio_get_value(pdata->gpio_a); | 48 | int a = !!gpio_get_value(pdata->gpio_a); |
48 | int b = !!gpio_get_value(pdata->gpio_b); | 49 | int b = !!gpio_get_value(pdata->gpio_b); |
49 | int state; | ||
50 | 50 | ||
51 | a ^= pdata->inverted_a; | 51 | a ^= pdata->inverted_a; |
52 | b ^= pdata->inverted_b; | 52 | b ^= pdata->inverted_b; |
53 | state = (a << 1) | b; | ||
54 | 53 | ||
55 | switch (state) { | 54 | return ((a << 1) | b); |
55 | } | ||
56 | 56 | ||
57 | case 0x0: | 57 | static void rotary_encoder_report_event(struct rotary_encoder *encoder) |
58 | if (!encoder->armed) | 58 | { |
59 | break; | 59 | struct rotary_encoder_platform_data *pdata = encoder->pdata; |
60 | 60 | ||
61 | if (pdata->relative_axis) { | 61 | if (pdata->relative_axis) { |
62 | input_report_rel(encoder->input, pdata->axis, | 62 | input_report_rel(encoder->input, |
63 | encoder->dir ? -1 : 1); | 63 | pdata->axis, encoder->dir ? -1 : 1); |
64 | } else { | 64 | } else { |
65 | unsigned int pos = encoder->pos; | 65 | unsigned int pos = encoder->pos; |
66 | 66 | ||
67 | if (encoder->dir) { | 67 | if (encoder->dir) { |
68 | /* turning counter-clockwise */ | 68 | /* turning counter-clockwise */ |
69 | if (pdata->rollover) | ||
70 | pos += pdata->steps; | ||
71 | if (pos) | ||
72 | pos--; | ||
73 | } else { | ||
74 | /* turning clockwise */ | ||
75 | if (pdata->rollover || pos < pdata->steps) | ||
76 | pos++; | ||
77 | } | ||
78 | if (pdata->rollover) | 69 | if (pdata->rollover) |
79 | pos %= pdata->steps; | 70 | pos += pdata->steps; |
80 | encoder->pos = pos; | 71 | if (pos) |
81 | input_report_abs(encoder->input, pdata->axis, | 72 | pos--; |
82 | encoder->pos); | 73 | } else { |
74 | /* turning clockwise */ | ||
75 | if (pdata->rollover || pos < pdata->steps) | ||
76 | pos++; | ||
83 | } | 77 | } |
84 | input_sync(encoder->input); | ||
85 | 78 | ||
86 | encoder->armed = false; | 79 | if (pdata->rollover) |
80 | pos %= pdata->steps; | ||
81 | |||
82 | encoder->pos = pos; | ||
83 | input_report_abs(encoder->input, pdata->axis, encoder->pos); | ||
84 | } | ||
85 | |||
86 | input_sync(encoder->input); | ||
87 | } | ||
88 | |||
89 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | ||
90 | { | ||
91 | struct rotary_encoder *encoder = dev_id; | ||
92 | int state; | ||
93 | |||
94 | state = rotary_encoder_get_state(encoder->pdata); | ||
95 | |||
96 | switch (state) { | ||
97 | case 0x0: | ||
98 | if (encoder->armed) { | ||
99 | rotary_encoder_report_event(encoder); | ||
100 | encoder->armed = false; | ||
101 | } | ||
87 | break; | 102 | break; |
88 | 103 | ||
89 | case 0x1: | 104 | case 0x1: |
@@ -100,11 +115,37 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | |||
100 | return IRQ_HANDLED; | 115 | return IRQ_HANDLED; |
101 | } | 116 | } |
102 | 117 | ||
118 | static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) | ||
119 | { | ||
120 | struct rotary_encoder *encoder = dev_id; | ||
121 | int state; | ||
122 | |||
123 | state = rotary_encoder_get_state(encoder->pdata); | ||
124 | |||
125 | switch (state) { | ||
126 | case 0x00: | ||
127 | case 0x03: | ||
128 | if (state != encoder->last_stable) { | ||
129 | rotary_encoder_report_event(encoder); | ||
130 | encoder->last_stable = state; | ||
131 | } | ||
132 | break; | ||
133 | |||
134 | case 0x01: | ||
135 | case 0x02: | ||
136 | encoder->dir = (encoder->last_stable + state) & 0x01; | ||
137 | break; | ||
138 | } | ||
139 | |||
140 | return IRQ_HANDLED; | ||
141 | } | ||
142 | |||
103 | static int __devinit rotary_encoder_probe(struct platform_device *pdev) | 143 | static int __devinit rotary_encoder_probe(struct platform_device *pdev) |
104 | { | 144 | { |
105 | struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; | 145 | struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; |
106 | struct rotary_encoder *encoder; | 146 | struct rotary_encoder *encoder; |
107 | struct input_dev *input; | 147 | struct input_dev *input; |
148 | irq_handler_t handler; | ||
108 | int err; | 149 | int err; |
109 | 150 | ||
110 | if (!pdata) { | 151 | if (!pdata) { |
@@ -175,8 +216,15 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
175 | } | 216 | } |
176 | 217 | ||
177 | /* request the IRQs */ | 218 | /* request the IRQs */ |
178 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, | 219 | if (pdata->half_period) { |
179 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | 220 | handler = &rotary_encoder_half_period_irq; |
221 | encoder->last_stable = rotary_encoder_get_state(pdata); | ||
222 | } else { | ||
223 | handler = &rotary_encoder_irq; | ||
224 | } | ||
225 | |||
226 | err = request_irq(encoder->irq_a, handler, | ||
227 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
180 | DRV_NAME, encoder); | 228 | DRV_NAME, encoder); |
181 | if (err) { | 229 | if (err) { |
182 | dev_err(&pdev->dev, "unable to request IRQ %d\n", | 230 | dev_err(&pdev->dev, "unable to request IRQ %d\n", |
@@ -184,8 +232,8 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
184 | goto exit_free_gpio_b; | 232 | goto exit_free_gpio_b; |
185 | } | 233 | } |
186 | 234 | ||
187 | err = request_irq(encoder->irq_b, &rotary_encoder_irq, | 235 | err = request_irq(encoder->irq_b, handler, |
188 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | 236 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
189 | DRV_NAME, encoder); | 237 | DRV_NAME, encoder); |
190 | if (err) { | 238 | if (err) { |
191 | dev_err(&pdev->dev, "unable to request IRQ %d\n", | 239 | dev_err(&pdev->dev, "unable to request IRQ %d\n", |
@@ -252,6 +300,5 @@ module_exit(rotary_encoder_exit); | |||
252 | 300 | ||
253 | MODULE_ALIAS("platform:" DRV_NAME); | 301 | MODULE_ALIAS("platform:" DRV_NAME); |
254 | MODULE_DESCRIPTION("GPIO rotary encoder driver"); | 302 | MODULE_DESCRIPTION("GPIO rotary encoder driver"); |
255 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 303 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>, Johan Hovold"); |
256 | MODULE_LICENSE("GPL v2"); | 304 | MODULE_LICENSE("GPL v2"); |
257 | |||
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 8e130bf7d32b..0122f5351577 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c | |||
@@ -173,18 +173,16 @@ static int __devinit sparcspkr_probe(struct device *dev) | |||
173 | return 0; | 173 | return 0; |
174 | } | 174 | } |
175 | 175 | ||
176 | static int sparcspkr_shutdown(struct platform_device *dev) | 176 | static void sparcspkr_shutdown(struct platform_device *dev) |
177 | { | 177 | { |
178 | struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); | 178 | struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); |
179 | struct input_dev *input_dev = state->input_dev; | 179 | struct input_dev *input_dev = state->input_dev; |
180 | 180 | ||
181 | /* turn off the speaker */ | 181 | /* turn off the speaker */ |
182 | state->event(input_dev, EV_SND, SND_BELL, 0); | 182 | state->event(input_dev, EV_SND, SND_BELL, 0); |
183 | |||
184 | return 0; | ||
185 | } | 183 | } |
186 | 184 | ||
187 | static int __devinit bbc_beep_probe(struct platform_device *op, const struct of_device_id *match) | 185 | static int __devinit bbc_beep_probe(struct platform_device *op) |
188 | { | 186 | { |
189 | struct sparcspkr_state *state; | 187 | struct sparcspkr_state *state; |
190 | struct bbc_beep_info *info; | 188 | struct bbc_beep_info *info; |
@@ -258,7 +256,7 @@ static const struct of_device_id bbc_beep_match[] = { | |||
258 | {}, | 256 | {}, |
259 | }; | 257 | }; |
260 | 258 | ||
261 | static struct of_platform_driver bbc_beep_driver = { | 259 | static struct platform_driver bbc_beep_driver = { |
262 | .driver = { | 260 | .driver = { |
263 | .name = "bbcbeep", | 261 | .name = "bbcbeep", |
264 | .owner = THIS_MODULE, | 262 | .owner = THIS_MODULE, |
@@ -269,7 +267,7 @@ static struct of_platform_driver bbc_beep_driver = { | |||
269 | .shutdown = sparcspkr_shutdown, | 267 | .shutdown = sparcspkr_shutdown, |
270 | }; | 268 | }; |
271 | 269 | ||
272 | static int __devinit grover_beep_probe(struct platform_device *op, const struct of_device_id *match) | 270 | static int __devinit grover_beep_probe(struct platform_device *op) |
273 | { | 271 | { |
274 | struct sparcspkr_state *state; | 272 | struct sparcspkr_state *state; |
275 | struct grover_beep_info *info; | 273 | struct grover_beep_info *info; |
@@ -340,7 +338,7 @@ static const struct of_device_id grover_beep_match[] = { | |||
340 | {}, | 338 | {}, |
341 | }; | 339 | }; |
342 | 340 | ||
343 | static struct of_platform_driver grover_beep_driver = { | 341 | static struct platform_driver grover_beep_driver = { |
344 | .driver = { | 342 | .driver = { |
345 | .name = "groverbeep", | 343 | .name = "groverbeep", |
346 | .owner = THIS_MODULE, | 344 | .owner = THIS_MODULE, |
@@ -353,12 +351,12 @@ static struct of_platform_driver grover_beep_driver = { | |||
353 | 351 | ||
354 | static int __init sparcspkr_init(void) | 352 | static int __init sparcspkr_init(void) |
355 | { | 353 | { |
356 | int err = of_register_platform_driver(&bbc_beep_driver); | 354 | int err = platform_driver_register(&bbc_beep_driver); |
357 | 355 | ||
358 | if (!err) { | 356 | if (!err) { |
359 | err = of_register_platform_driver(&grover_beep_driver); | 357 | err = platform_driver_register(&grover_beep_driver); |
360 | if (err) | 358 | if (err) |
361 | of_unregister_platform_driver(&bbc_beep_driver); | 359 | platform_driver_unregister(&bbc_beep_driver); |
362 | } | 360 | } |
363 | 361 | ||
364 | return err; | 362 | return err; |
@@ -366,8 +364,8 @@ static int __init sparcspkr_init(void) | |||
366 | 364 | ||
367 | static void __exit sparcspkr_exit(void) | 365 | static void __exit sparcspkr_exit(void) |
368 | { | 366 | { |
369 | of_unregister_platform_driver(&bbc_beep_driver); | 367 | platform_driver_unregister(&bbc_beep_driver); |
370 | of_unregister_platform_driver(&grover_beep_driver); | 368 | platform_driver_unregister(&grover_beep_driver); |
371 | } | 369 | } |
372 | 370 | ||
373 | module_init(sparcspkr_init); | 371 | module_init(sparcspkr_init); |
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index f16972bddca4..38e4b507b94c 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c | |||
@@ -89,7 +89,7 @@ static int __init twl4030_pwrbutton_probe(struct platform_device *pdev) | |||
89 | return 0; | 89 | return 0; |
90 | 90 | ||
91 | free_irq: | 91 | free_irq: |
92 | free_irq(irq, NULL); | 92 | free_irq(irq, pwr); |
93 | free_input_dev: | 93 | free_input_dev: |
94 | input_free_device(pwr); | 94 | input_free_device(pwr); |
95 | return err; | 95 | return err; |
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index 4f9b2afc24e8..014dd4ad0d4f 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c | |||
@@ -271,7 +271,7 @@ static struct platform_driver twl4030_vibra_driver = { | |||
271 | .probe = twl4030_vibra_probe, | 271 | .probe = twl4030_vibra_probe, |
272 | .remove = __devexit_p(twl4030_vibra_remove), | 272 | .remove = __devexit_p(twl4030_vibra_remove), |
273 | .driver = { | 273 | .driver = { |
274 | .name = "twl4030_codec_vibra", | 274 | .name = "twl4030-vibra", |
275 | .owner = THIS_MODULE, | 275 | .owner = THIS_MODULE, |
276 | #ifdef CONFIG_PM | 276 | #ifdef CONFIG_PM |
277 | .pm = &twl4030_vibra_pm_ops, | 277 | .pm = &twl4030_vibra_pm_ops, |
@@ -291,7 +291,7 @@ static void __exit twl4030_vibra_exit(void) | |||
291 | } | 291 | } |
292 | module_exit(twl4030_vibra_exit); | 292 | module_exit(twl4030_vibra_exit); |
293 | 293 | ||
294 | MODULE_ALIAS("platform:twl4030_codec_vibra"); | 294 | MODULE_ALIAS("platform:twl4030-vibra"); |
295 | 295 | ||
296 | MODULE_DESCRIPTION("TWL4030 Vibra driver"); | 296 | MODULE_DESCRIPTION("TWL4030 Vibra driver"); |
297 | MODULE_LICENSE("GPL"); | 297 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 360698553eb5..736056897e50 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 <linux/input/mt.h> | ||
40 | #include "../input-compat.h" | 41 | #include "../input-compat.h" |
41 | 42 | ||
42 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 43 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
@@ -301,10 +302,14 @@ static int uinput_validate_absbits(struct input_dev *dev) | |||
301 | int retval = 0; | 302 | int retval = 0; |
302 | 303 | ||
303 | for (cnt = 0; cnt < ABS_CNT; cnt++) { | 304 | for (cnt = 0; cnt < ABS_CNT; cnt++) { |
305 | int min, max; | ||
304 | if (!test_bit(cnt, dev->absbit)) | 306 | if (!test_bit(cnt, dev->absbit)) |
305 | continue; | 307 | continue; |
306 | 308 | ||
307 | if (input_abs_get_max(dev, cnt) <= input_abs_get_min(dev, cnt)) { | 309 | min = input_abs_get_min(dev, cnt); |
310 | max = input_abs_get_max(dev, cnt); | ||
311 | |||
312 | if ((min != 0 || max != 0) && max <= min) { | ||
308 | printk(KERN_DEBUG | 313 | printk(KERN_DEBUG |
309 | "%s: invalid abs[%02x] min:%d max:%d\n", | 314 | "%s: invalid abs[%02x] min:%d max:%d\n", |
310 | UINPUT_NAME, cnt, | 315 | UINPUT_NAME, cnt, |
@@ -346,8 +351,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
346 | { | 351 | { |
347 | struct uinput_user_dev *user_dev; | 352 | struct uinput_user_dev *user_dev; |
348 | struct input_dev *dev; | 353 | struct input_dev *dev; |
349 | char *name; | 354 | int i; |
350 | int i, size; | ||
351 | int retval; | 355 | int retval; |
352 | 356 | ||
353 | if (count != sizeof(struct uinput_user_dev)) | 357 | if (count != sizeof(struct uinput_user_dev)) |
@@ -361,30 +365,25 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
361 | 365 | ||
362 | dev = udev->dev; | 366 | dev = udev->dev; |
363 | 367 | ||
364 | user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); | 368 | user_dev = memdup_user(buffer, sizeof(struct uinput_user_dev)); |
365 | if (!user_dev) | 369 | if (IS_ERR(user_dev)) |
366 | return -ENOMEM; | 370 | return PTR_ERR(user_dev); |
367 | |||
368 | if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) { | ||
369 | retval = -EFAULT; | ||
370 | goto exit; | ||
371 | } | ||
372 | 371 | ||
373 | udev->ff_effects_max = user_dev->ff_effects_max; | 372 | udev->ff_effects_max = user_dev->ff_effects_max; |
374 | 373 | ||
375 | size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; | 374 | /* Ensure name is filled in */ |
376 | if (!size) { | 375 | if (!user_dev->name[0]) { |
377 | retval = -EINVAL; | 376 | retval = -EINVAL; |
378 | goto exit; | 377 | goto exit; |
379 | } | 378 | } |
380 | 379 | ||
381 | kfree(dev->name); | 380 | kfree(dev->name); |
382 | dev->name = name = kmalloc(size, GFP_KERNEL); | 381 | dev->name = kstrndup(user_dev->name, UINPUT_MAX_NAME_SIZE, |
383 | if (!name) { | 382 | GFP_KERNEL); |
383 | if (!dev->name) { | ||
384 | retval = -ENOMEM; | 384 | retval = -ENOMEM; |
385 | goto exit; | 385 | goto exit; |
386 | } | 386 | } |
387 | strlcpy(name, user_dev->name, size); | ||
388 | 387 | ||
389 | dev->id.bustype = user_dev->id.bustype; | 388 | dev->id.bustype = user_dev->id.bustype; |
390 | dev->id.vendor = user_dev->id.vendor; | 389 | dev->id.vendor = user_dev->id.vendor; |
@@ -406,8 +405,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
406 | goto exit; | 405 | goto exit; |
407 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { | 406 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { |
408 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; | 407 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; |
409 | input_mt_create_slots(dev, nslot); | 408 | input_mt_init_slots(dev, nslot); |
410 | input_set_events_per_packet(dev, 6 * nslot); | ||
411 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | 409 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { |
412 | input_set_events_per_packet(dev, 60); | 410 | input_set_events_per_packet(dev, 60); |
413 | } | 411 | } |
@@ -622,7 +620,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, | |||
622 | struct uinput_ff_upload ff_up; | 620 | struct uinput_ff_upload ff_up; |
623 | struct uinput_ff_erase ff_erase; | 621 | struct uinput_ff_erase ff_erase; |
624 | struct uinput_request *req; | 622 | struct uinput_request *req; |
625 | int length; | ||
626 | char *phys; | 623 | char *phys; |
627 | 624 | ||
628 | retval = mutex_lock_interruptible(&udev->mutex); | 625 | retval = mutex_lock_interruptible(&udev->mutex); |
@@ -680,29 +677,24 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, | |||
680 | retval = uinput_set_bit(arg, swbit, SW_MAX); | 677 | retval = uinput_set_bit(arg, swbit, SW_MAX); |
681 | break; | 678 | break; |
682 | 679 | ||
680 | case UI_SET_PROPBIT: | ||
681 | retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX); | ||
682 | break; | ||
683 | |||
683 | case UI_SET_PHYS: | 684 | case UI_SET_PHYS: |
684 | if (udev->state == UIST_CREATED) { | 685 | if (udev->state == UIST_CREATED) { |
685 | retval = -EINVAL; | 686 | retval = -EINVAL; |
686 | goto out; | 687 | goto out; |
687 | } | 688 | } |
688 | length = strnlen_user(p, 1024); | 689 | |
689 | if (length <= 0) { | 690 | phys = strndup_user(p, 1024); |
690 | retval = -EFAULT; | 691 | if (IS_ERR(phys)) { |
691 | break; | 692 | retval = PTR_ERR(phys); |
693 | goto out; | ||
692 | } | 694 | } |
695 | |||
693 | kfree(udev->dev->phys); | 696 | kfree(udev->dev->phys); |
694 | udev->dev->phys = phys = kmalloc(length, GFP_KERNEL); | 697 | udev->dev->phys = phys; |
695 | if (!phys) { | ||
696 | retval = -ENOMEM; | ||
697 | break; | ||
698 | } | ||
699 | if (copy_from_user(phys, p, length)) { | ||
700 | udev->dev->phys = NULL; | ||
701 | kfree(phys); | ||
702 | retval = -EFAULT; | ||
703 | break; | ||
704 | } | ||
705 | phys[length - 1] = '\0'; | ||
706 | break; | 698 | break; |
707 | 699 | ||
708 | case UI_BEGIN_FF_UPLOAD: | 700 | case UI_BEGIN_FF_UPLOAD: |
@@ -811,6 +803,7 @@ static const struct file_operations uinput_fops = { | |||
811 | #ifdef CONFIG_COMPAT | 803 | #ifdef CONFIG_COMPAT |
812 | .compat_ioctl = uinput_compat_ioctl, | 804 | .compat_ioctl = uinput_compat_ioctl, |
813 | #endif | 805 | #endif |
806 | .llseek = no_llseek, | ||
814 | }; | 807 | }; |
815 | 808 | ||
816 | static struct miscdevice uinput_misc = { | 809 | static struct miscdevice uinput_misc = { |
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c deleted file mode 100644 index 64f1de7960c6..000000000000 --- a/drivers/input/misc/winbond-cir.c +++ /dev/null | |||
@@ -1,1608 +0,0 @@ | |||
1 | /* | ||
2 | * winbond-cir.c - Driver for the Consumer IR functionality of Winbond | ||
3 | * SuperI/O chips. | ||
4 | * | ||
5 | * Currently supports the Winbond WPCD376i chip (PNP id WEC1022), but | ||
6 | * could probably support others (Winbond WEC102X, NatSemi, etc) | ||
7 | * with minor modifications. | ||
8 | * | ||
9 | * Original Author: David Härdeman <david@hardeman.nu> | ||
10 | * Copyright (C) 2009 David Härdeman <david@hardeman.nu> | ||
11 | * | ||
12 | * Dedicated to Matilda, my newborn daughter, without whose loving attention | ||
13 | * this driver would have been finished in half the time and with a fraction | ||
14 | * of the bugs. | ||
15 | * | ||
16 | * Written using: | ||
17 | * o Winbond WPCD376I datasheet helpfully provided by Jesse Barnes at Intel | ||
18 | * o NatSemi PC87338/PC97338 datasheet (for the serial port stuff) | ||
19 | * o DSDT dumps | ||
20 | * | ||
21 | * Supported features: | ||
22 | * o RC6 | ||
23 | * o Wake-On-CIR functionality | ||
24 | * | ||
25 | * To do: | ||
26 | * o Test NEC and RC5 | ||
27 | * | ||
28 | * Left as an exercise for the reader: | ||
29 | * o Learning (I have neither the hardware, nor the need) | ||
30 | * o IR Transmit (ibid) | ||
31 | * | ||
32 | * This program is free software; you can redistribute it and/or modify | ||
33 | * it under the terms of the GNU General Public License as published by | ||
34 | * the Free Software Foundation; either version 2 of the License, or | ||
35 | * (at your option) any later version. | ||
36 | * | ||
37 | * This program is distributed in the hope that it will be useful, | ||
38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
40 | * GNU General Public License for more details. | ||
41 | * | ||
42 | * You should have received a copy of the GNU General Public License | ||
43 | * along with this program; if not, write to the Free Software | ||
44 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
45 | */ | ||
46 | |||
47 | #include <linux/module.h> | ||
48 | #include <linux/pnp.h> | ||
49 | #include <linux/interrupt.h> | ||
50 | #include <linux/timer.h> | ||
51 | #include <linux/input.h> | ||
52 | #include <linux/leds.h> | ||
53 | #include <linux/list.h> | ||
54 | #include <linux/spinlock.h> | ||
55 | #include <linux/pci_ids.h> | ||
56 | #include <linux/io.h> | ||
57 | #include <linux/bitrev.h> | ||
58 | #include <linux/bitops.h> | ||
59 | #include <linux/slab.h> | ||
60 | |||
61 | #define DRVNAME "winbond-cir" | ||
62 | |||
63 | /* CEIR Wake-Up Registers, relative to data->wbase */ | ||
64 | #define WBCIR_REG_WCEIR_CTL 0x03 /* CEIR Receiver Control */ | ||
65 | #define WBCIR_REG_WCEIR_STS 0x04 /* CEIR Receiver Status */ | ||
66 | #define WBCIR_REG_WCEIR_EV_EN 0x05 /* CEIR Receiver Event Enable */ | ||
67 | #define WBCIR_REG_WCEIR_CNTL 0x06 /* CEIR Receiver Counter Low */ | ||
68 | #define WBCIR_REG_WCEIR_CNTH 0x07 /* CEIR Receiver Counter High */ | ||
69 | #define WBCIR_REG_WCEIR_INDEX 0x08 /* CEIR Receiver Index */ | ||
70 | #define WBCIR_REG_WCEIR_DATA 0x09 /* CEIR Receiver Data */ | ||
71 | #define WBCIR_REG_WCEIR_CSL 0x0A /* CEIR Re. Compare Strlen */ | ||
72 | #define WBCIR_REG_WCEIR_CFG1 0x0B /* CEIR Re. Configuration 1 */ | ||
73 | #define WBCIR_REG_WCEIR_CFG2 0x0C /* CEIR Re. Configuration 2 */ | ||
74 | |||
75 | /* CEIR Enhanced Functionality Registers, relative to data->ebase */ | ||
76 | #define WBCIR_REG_ECEIR_CTS 0x00 /* Enhanced IR Control Status */ | ||
77 | #define WBCIR_REG_ECEIR_CCTL 0x01 /* Infrared Counter Control */ | ||
78 | #define WBCIR_REG_ECEIR_CNT_LO 0x02 /* Infrared Counter LSB */ | ||
79 | #define WBCIR_REG_ECEIR_CNT_HI 0x03 /* Infrared Counter MSB */ | ||
80 | #define WBCIR_REG_ECEIR_IREM 0x04 /* Infrared Emitter Status */ | ||
81 | |||
82 | /* SP3 Banked Registers, relative to data->sbase */ | ||
83 | #define WBCIR_REG_SP3_BSR 0x03 /* Bank Select, all banks */ | ||
84 | /* Bank 0 */ | ||
85 | #define WBCIR_REG_SP3_RXDATA 0x00 /* FIFO RX data (r) */ | ||
86 | #define WBCIR_REG_SP3_TXDATA 0x00 /* FIFO TX data (w) */ | ||
87 | #define WBCIR_REG_SP3_IER 0x01 /* Interrupt Enable */ | ||
88 | #define WBCIR_REG_SP3_EIR 0x02 /* Event Identification (r) */ | ||
89 | #define WBCIR_REG_SP3_FCR 0x02 /* FIFO Control (w) */ | ||
90 | #define WBCIR_REG_SP3_MCR 0x04 /* Mode Control */ | ||
91 | #define WBCIR_REG_SP3_LSR 0x05 /* Link Status */ | ||
92 | #define WBCIR_REG_SP3_MSR 0x06 /* Modem Status */ | ||
93 | #define WBCIR_REG_SP3_ASCR 0x07 /* Aux Status and Control */ | ||
94 | /* Bank 2 */ | ||
95 | #define WBCIR_REG_SP3_BGDL 0x00 /* Baud Divisor LSB */ | ||
96 | #define WBCIR_REG_SP3_BGDH 0x01 /* Baud Divisor MSB */ | ||
97 | #define WBCIR_REG_SP3_EXCR1 0x02 /* Extended Control 1 */ | ||
98 | #define WBCIR_REG_SP3_EXCR2 0x04 /* Extended Control 2 */ | ||
99 | #define WBCIR_REG_SP3_TXFLV 0x06 /* TX FIFO Level */ | ||
100 | #define WBCIR_REG_SP3_RXFLV 0x07 /* RX FIFO Level */ | ||
101 | /* Bank 3 */ | ||
102 | #define WBCIR_REG_SP3_MRID 0x00 /* Module Identification */ | ||
103 | #define WBCIR_REG_SP3_SH_LCR 0x01 /* LCR Shadow */ | ||
104 | #define WBCIR_REG_SP3_SH_FCR 0x02 /* FCR Shadow */ | ||
105 | /* Bank 4 */ | ||
106 | #define WBCIR_REG_SP3_IRCR1 0x02 /* Infrared Control 1 */ | ||
107 | /* Bank 5 */ | ||
108 | #define WBCIR_REG_SP3_IRCR2 0x04 /* Infrared Control 2 */ | ||
109 | /* Bank 6 */ | ||
110 | #define WBCIR_REG_SP3_IRCR3 0x00 /* Infrared Control 3 */ | ||
111 | #define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */ | ||
112 | /* Bank 7 */ | ||
113 | #define WBCIR_REG_SP3_IRRXDC 0x00 /* IR RX Demod Control */ | ||
114 | #define WBCIR_REG_SP3_IRTXMC 0x01 /* IR TX Mod Control */ | ||
115 | #define WBCIR_REG_SP3_RCCFG 0x02 /* CEIR Config */ | ||
116 | #define WBCIR_REG_SP3_IRCFG1 0x04 /* Infrared Config 1 */ | ||
117 | #define WBCIR_REG_SP3_IRCFG4 0x07 /* Infrared Config 4 */ | ||
118 | |||
119 | /* | ||
120 | * Magic values follow | ||
121 | */ | ||
122 | |||
123 | /* No interrupts for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ | ||
124 | #define WBCIR_IRQ_NONE 0x00 | ||
125 | /* RX data bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ | ||
126 | #define WBCIR_IRQ_RX 0x01 | ||
127 | /* Over/Under-flow bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ | ||
128 | #define WBCIR_IRQ_ERR 0x04 | ||
129 | /* Led enable/disable bit for WBCIR_REG_ECEIR_CTS */ | ||
130 | #define WBCIR_LED_ENABLE 0x80 | ||
131 | /* RX data available bit for WBCIR_REG_SP3_LSR */ | ||
132 | #define WBCIR_RX_AVAIL 0x01 | ||
133 | /* RX disable bit for WBCIR_REG_SP3_ASCR */ | ||
134 | #define WBCIR_RX_DISABLE 0x20 | ||
135 | /* Extended mode enable bit for WBCIR_REG_SP3_EXCR1 */ | ||
136 | #define WBCIR_EXT_ENABLE 0x01 | ||
137 | /* Select compare register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */ | ||
138 | #define WBCIR_REGSEL_COMPARE 0x10 | ||
139 | /* Select mask register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */ | ||
140 | #define WBCIR_REGSEL_MASK 0x20 | ||
141 | /* Starting address of selected register in WBCIR_REG_WCEIR_INDEX */ | ||
142 | #define WBCIR_REG_ADDR0 0x00 | ||
143 | |||
144 | /* Valid banks for the SP3 UART */ | ||
145 | enum wbcir_bank { | ||
146 | WBCIR_BANK_0 = 0x00, | ||
147 | WBCIR_BANK_1 = 0x80, | ||
148 | WBCIR_BANK_2 = 0xE0, | ||
149 | WBCIR_BANK_3 = 0xE4, | ||
150 | WBCIR_BANK_4 = 0xE8, | ||
151 | WBCIR_BANK_5 = 0xEC, | ||
152 | WBCIR_BANK_6 = 0xF0, | ||
153 | WBCIR_BANK_7 = 0xF4, | ||
154 | }; | ||
155 | |||
156 | /* Supported IR Protocols */ | ||
157 | enum wbcir_protocol { | ||
158 | IR_PROTOCOL_RC5 = 0x0, | ||
159 | IR_PROTOCOL_NEC = 0x1, | ||
160 | IR_PROTOCOL_RC6 = 0x2, | ||
161 | }; | ||
162 | |||
163 | /* Misc */ | ||
164 | #define WBCIR_NAME "Winbond CIR" | ||
165 | #define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */ | ||
166 | #define WBCIR_ID_CHIP 0x04 /* Chip ID for the WPCD376I */ | ||
167 | #define IR_KEYPRESS_TIMEOUT 250 /* FIXME: should be per-protocol? */ | ||
168 | #define INVALID_SCANCODE 0x7FFFFFFF /* Invalid with all protos */ | ||
169 | #define WAKEUP_IOMEM_LEN 0x10 /* Wake-Up I/O Reg Len */ | ||
170 | #define EHFUNC_IOMEM_LEN 0x10 /* Enhanced Func I/O Reg Len */ | ||
171 | #define SP_IOMEM_LEN 0x08 /* Serial Port 3 (IR) Reg Len */ | ||
172 | #define WBCIR_MAX_IDLE_BYTES 10 | ||
173 | |||
174 | static DEFINE_SPINLOCK(wbcir_lock); | ||
175 | static DEFINE_RWLOCK(keytable_lock); | ||
176 | |||
177 | struct wbcir_key { | ||
178 | u32 scancode; | ||
179 | unsigned int keycode; | ||
180 | }; | ||
181 | |||
182 | struct wbcir_keyentry { | ||
183 | struct wbcir_key key; | ||
184 | struct list_head list; | ||
185 | }; | ||
186 | |||
187 | static struct wbcir_key rc6_def_keymap[] = { | ||
188 | { 0x800F0400, KEY_NUMERIC_0 }, | ||
189 | { 0x800F0401, KEY_NUMERIC_1 }, | ||
190 | { 0x800F0402, KEY_NUMERIC_2 }, | ||
191 | { 0x800F0403, KEY_NUMERIC_3 }, | ||
192 | { 0x800F0404, KEY_NUMERIC_4 }, | ||
193 | { 0x800F0405, KEY_NUMERIC_5 }, | ||
194 | { 0x800F0406, KEY_NUMERIC_6 }, | ||
195 | { 0x800F0407, KEY_NUMERIC_7 }, | ||
196 | { 0x800F0408, KEY_NUMERIC_8 }, | ||
197 | { 0x800F0409, KEY_NUMERIC_9 }, | ||
198 | { 0x800F041D, KEY_NUMERIC_STAR }, | ||
199 | { 0x800F041C, KEY_NUMERIC_POUND }, | ||
200 | { 0x800F0410, KEY_VOLUMEUP }, | ||
201 | { 0x800F0411, KEY_VOLUMEDOWN }, | ||
202 | { 0x800F0412, KEY_CHANNELUP }, | ||
203 | { 0x800F0413, KEY_CHANNELDOWN }, | ||
204 | { 0x800F040E, KEY_MUTE }, | ||
205 | { 0x800F040D, KEY_VENDOR }, /* Vista Logo Key */ | ||
206 | { 0x800F041E, KEY_UP }, | ||
207 | { 0x800F041F, KEY_DOWN }, | ||
208 | { 0x800F0420, KEY_LEFT }, | ||
209 | { 0x800F0421, KEY_RIGHT }, | ||
210 | { 0x800F0422, KEY_OK }, | ||
211 | { 0x800F0423, KEY_ESC }, | ||
212 | { 0x800F040F, KEY_INFO }, | ||
213 | { 0x800F040A, KEY_CLEAR }, | ||
214 | { 0x800F040B, KEY_ENTER }, | ||
215 | { 0x800F045B, KEY_RED }, | ||
216 | { 0x800F045C, KEY_GREEN }, | ||
217 | { 0x800F045D, KEY_YELLOW }, | ||
218 | { 0x800F045E, KEY_BLUE }, | ||
219 | { 0x800F045A, KEY_TEXT }, | ||
220 | { 0x800F0427, KEY_SWITCHVIDEOMODE }, | ||
221 | { 0x800F040C, KEY_POWER }, | ||
222 | { 0x800F0450, KEY_RADIO }, | ||
223 | { 0x800F0448, KEY_PVR }, | ||
224 | { 0x800F0447, KEY_AUDIO }, | ||
225 | { 0x800F0426, KEY_EPG }, | ||
226 | { 0x800F0449, KEY_CAMERA }, | ||
227 | { 0x800F0425, KEY_TV }, | ||
228 | { 0x800F044A, KEY_VIDEO }, | ||
229 | { 0x800F0424, KEY_DVD }, | ||
230 | { 0x800F0416, KEY_PLAY }, | ||
231 | { 0x800F0418, KEY_PAUSE }, | ||
232 | { 0x800F0419, KEY_STOP }, | ||
233 | { 0x800F0414, KEY_FASTFORWARD }, | ||
234 | { 0x800F041A, KEY_NEXT }, | ||
235 | { 0x800F041B, KEY_PREVIOUS }, | ||
236 | { 0x800F0415, KEY_REWIND }, | ||
237 | { 0x800F0417, KEY_RECORD }, | ||
238 | }; | ||
239 | |||
240 | /* Registers and other state is protected by wbcir_lock */ | ||
241 | struct wbcir_data { | ||
242 | unsigned long wbase; /* Wake-Up Baseaddr */ | ||
243 | unsigned long ebase; /* Enhanced Func. Baseaddr */ | ||
244 | unsigned long sbase; /* Serial Port Baseaddr */ | ||
245 | unsigned int irq; /* Serial Port IRQ */ | ||
246 | |||
247 | struct input_dev *input_dev; | ||
248 | struct timer_list timer_keyup; | ||
249 | struct led_trigger *rxtrigger; | ||
250 | struct led_trigger *txtrigger; | ||
251 | struct led_classdev led; | ||
252 | |||
253 | u32 last_scancode; | ||
254 | unsigned int last_keycode; | ||
255 | u8 last_toggle; | ||
256 | u8 keypressed; | ||
257 | unsigned long keyup_jiffies; | ||
258 | unsigned int idle_count; | ||
259 | |||
260 | /* RX irdata and parsing state */ | ||
261 | unsigned long irdata[30]; | ||
262 | unsigned int irdata_count; | ||
263 | unsigned int irdata_idle; | ||
264 | unsigned int irdata_off; | ||
265 | unsigned int irdata_error; | ||
266 | |||
267 | /* Protected by keytable_lock */ | ||
268 | struct list_head keytable; | ||
269 | }; | ||
270 | |||
271 | static enum wbcir_protocol protocol = IR_PROTOCOL_RC6; | ||
272 | module_param(protocol, uint, 0444); | ||
273 | MODULE_PARM_DESC(protocol, "IR protocol to use " | ||
274 | "(0 = RC5, 1 = NEC, 2 = RC6A, default)"); | ||
275 | |||
276 | static int invert; /* default = 0 */ | ||
277 | module_param(invert, bool, 0444); | ||
278 | MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver"); | ||
279 | |||
280 | static unsigned int wake_sc = 0x800F040C; | ||
281 | module_param(wake_sc, uint, 0644); | ||
282 | MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command"); | ||
283 | |||
284 | static unsigned int wake_rc6mode = 6; | ||
285 | module_param(wake_rc6mode, uint, 0644); | ||
286 | MODULE_PARM_DESC(wake_rc6mode, "RC6 mode for the power-on command " | ||
287 | "(0 = 0, 6 = 6A, default)"); | ||
288 | |||
289 | |||
290 | |||
291 | /***************************************************************************** | ||
292 | * | ||
293 | * UTILITY FUNCTIONS | ||
294 | * | ||
295 | *****************************************************************************/ | ||
296 | |||
297 | /* Caller needs to hold wbcir_lock */ | ||
298 | static void | ||
299 | wbcir_set_bits(unsigned long addr, u8 bits, u8 mask) | ||
300 | { | ||
301 | u8 val; | ||
302 | |||
303 | val = inb(addr); | ||
304 | val = ((val & ~mask) | (bits & mask)); | ||
305 | outb(val, addr); | ||
306 | } | ||
307 | |||
308 | /* Selects the register bank for the serial port */ | ||
309 | static inline void | ||
310 | wbcir_select_bank(struct wbcir_data *data, enum wbcir_bank bank) | ||
311 | { | ||
312 | outb(bank, data->sbase + WBCIR_REG_SP3_BSR); | ||
313 | } | ||
314 | |||
315 | static enum led_brightness | ||
316 | wbcir_led_brightness_get(struct led_classdev *led_cdev) | ||
317 | { | ||
318 | struct wbcir_data *data = container_of(led_cdev, | ||
319 | struct wbcir_data, | ||
320 | led); | ||
321 | |||
322 | if (inb(data->ebase + WBCIR_REG_ECEIR_CTS) & WBCIR_LED_ENABLE) | ||
323 | return LED_FULL; | ||
324 | else | ||
325 | return LED_OFF; | ||
326 | } | ||
327 | |||
328 | static void | ||
329 | wbcir_led_brightness_set(struct led_classdev *led_cdev, | ||
330 | enum led_brightness brightness) | ||
331 | { | ||
332 | struct wbcir_data *data = container_of(led_cdev, | ||
333 | struct wbcir_data, | ||
334 | led); | ||
335 | |||
336 | wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, | ||
337 | brightness == LED_OFF ? 0x00 : WBCIR_LED_ENABLE, | ||
338 | WBCIR_LED_ENABLE); | ||
339 | } | ||
340 | |||
341 | /* Manchester encodes bits to RC6 message cells (see wbcir_parse_rc6) */ | ||
342 | static u8 | ||
343 | wbcir_to_rc6cells(u8 val) | ||
344 | { | ||
345 | u8 coded = 0x00; | ||
346 | int i; | ||
347 | |||
348 | val &= 0x0F; | ||
349 | for (i = 0; i < 4; i++) { | ||
350 | if (val & 0x01) | ||
351 | coded |= 0x02 << (i * 2); | ||
352 | else | ||
353 | coded |= 0x01 << (i * 2); | ||
354 | val >>= 1; | ||
355 | } | ||
356 | |||
357 | return coded; | ||
358 | } | ||
359 | |||
360 | |||
361 | |||
362 | /***************************************************************************** | ||
363 | * | ||
364 | * INPUT FUNCTIONS | ||
365 | * | ||
366 | *****************************************************************************/ | ||
367 | |||
368 | static unsigned int | ||
369 | wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode) | ||
370 | { | ||
371 | struct wbcir_keyentry *keyentry; | ||
372 | unsigned int keycode = KEY_RESERVED; | ||
373 | unsigned long flags; | ||
374 | |||
375 | read_lock_irqsave(&keytable_lock, flags); | ||
376 | |||
377 | list_for_each_entry(keyentry, &data->keytable, list) { | ||
378 | if (keyentry->key.scancode == scancode) { | ||
379 | keycode = keyentry->key.keycode; | ||
380 | break; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | read_unlock_irqrestore(&keytable_lock, flags); | ||
385 | return keycode; | ||
386 | } | ||
387 | |||
388 | static int | ||
389 | wbcir_getkeycode(struct input_dev *dev, | ||
390 | unsigned int scancode, unsigned int *keycode) | ||
391 | { | ||
392 | struct wbcir_data *data = input_get_drvdata(dev); | ||
393 | |||
394 | *keycode = wbcir_do_getkeycode(data, scancode); | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int | ||
399 | wbcir_setkeycode(struct input_dev *dev, | ||
400 | unsigned int scancode, unsigned int keycode) | ||
401 | { | ||
402 | struct wbcir_data *data = input_get_drvdata(dev); | ||
403 | struct wbcir_keyentry *keyentry; | ||
404 | struct wbcir_keyentry *new_keyentry; | ||
405 | unsigned long flags; | ||
406 | unsigned int old_keycode = KEY_RESERVED; | ||
407 | |||
408 | new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); | ||
409 | if (!new_keyentry) | ||
410 | return -ENOMEM; | ||
411 | |||
412 | write_lock_irqsave(&keytable_lock, flags); | ||
413 | |||
414 | list_for_each_entry(keyentry, &data->keytable, list) { | ||
415 | if (keyentry->key.scancode != scancode) | ||
416 | continue; | ||
417 | |||
418 | old_keycode = keyentry->key.keycode; | ||
419 | keyentry->key.keycode = keycode; | ||
420 | |||
421 | if (keyentry->key.keycode == KEY_RESERVED) { | ||
422 | list_del(&keyentry->list); | ||
423 | kfree(keyentry); | ||
424 | } | ||
425 | |||
426 | break; | ||
427 | } | ||
428 | |||
429 | set_bit(keycode, dev->keybit); | ||
430 | |||
431 | if (old_keycode == KEY_RESERVED) { | ||
432 | new_keyentry->key.scancode = scancode; | ||
433 | new_keyentry->key.keycode = keycode; | ||
434 | list_add(&new_keyentry->list, &data->keytable); | ||
435 | } else { | ||
436 | kfree(new_keyentry); | ||
437 | clear_bit(old_keycode, dev->keybit); | ||
438 | list_for_each_entry(keyentry, &data->keytable, list) { | ||
439 | if (keyentry->key.keycode == old_keycode) { | ||
440 | set_bit(old_keycode, dev->keybit); | ||
441 | break; | ||
442 | } | ||
443 | } | ||
444 | } | ||
445 | |||
446 | write_unlock_irqrestore(&keytable_lock, flags); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | /* | ||
451 | * Timer function to report keyup event some time after keydown is | ||
452 | * reported by the ISR. | ||
453 | */ | ||
454 | static void | ||
455 | wbcir_keyup(unsigned long cookie) | ||
456 | { | ||
457 | struct wbcir_data *data = (struct wbcir_data *)cookie; | ||
458 | unsigned long flags; | ||
459 | |||
460 | /* | ||
461 | * data->keyup_jiffies is used to prevent a race condition if a | ||
462 | * hardware interrupt occurs at this point and the keyup timer | ||
463 | * event is moved further into the future as a result. | ||
464 | * | ||
465 | * The timer will then be reactivated and this function called | ||
466 | * again in the future. We need to exit gracefully in that case | ||
467 | * to allow the input subsystem to do its auto-repeat magic or | ||
468 | * a keyup event might follow immediately after the keydown. | ||
469 | */ | ||
470 | |||
471 | spin_lock_irqsave(&wbcir_lock, flags); | ||
472 | |||
473 | if (time_is_after_eq_jiffies(data->keyup_jiffies) && data->keypressed) { | ||
474 | data->keypressed = 0; | ||
475 | led_trigger_event(data->rxtrigger, LED_OFF); | ||
476 | input_report_key(data->input_dev, data->last_keycode, 0); | ||
477 | input_sync(data->input_dev); | ||
478 | } | ||
479 | |||
480 | spin_unlock_irqrestore(&wbcir_lock, flags); | ||
481 | } | ||
482 | |||
483 | static void | ||
484 | wbcir_keydown(struct wbcir_data *data, u32 scancode, u8 toggle) | ||
485 | { | ||
486 | unsigned int keycode; | ||
487 | |||
488 | /* Repeat? */ | ||
489 | if (data->last_scancode == scancode && | ||
490 | data->last_toggle == toggle && | ||
491 | data->keypressed) | ||
492 | goto set_timer; | ||
493 | data->last_scancode = scancode; | ||
494 | |||
495 | /* Do we need to release an old keypress? */ | ||
496 | if (data->keypressed) { | ||
497 | input_report_key(data->input_dev, data->last_keycode, 0); | ||
498 | input_sync(data->input_dev); | ||
499 | data->keypressed = 0; | ||
500 | } | ||
501 | |||
502 | /* Report scancode */ | ||
503 | input_event(data->input_dev, EV_MSC, MSC_SCAN, (int)scancode); | ||
504 | |||
505 | /* Do we know this scancode? */ | ||
506 | keycode = wbcir_do_getkeycode(data, scancode); | ||
507 | if (keycode == KEY_RESERVED) | ||
508 | goto set_timer; | ||
509 | |||
510 | /* Register a keypress */ | ||
511 | input_report_key(data->input_dev, keycode, 1); | ||
512 | data->keypressed = 1; | ||
513 | data->last_keycode = keycode; | ||
514 | data->last_toggle = toggle; | ||
515 | |||
516 | set_timer: | ||
517 | input_sync(data->input_dev); | ||
518 | led_trigger_event(data->rxtrigger, | ||
519 | data->keypressed ? LED_FULL : LED_OFF); | ||
520 | data->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); | ||
521 | mod_timer(&data->timer_keyup, data->keyup_jiffies); | ||
522 | } | ||
523 | |||
524 | |||
525 | |||
526 | /***************************************************************************** | ||
527 | * | ||
528 | * IR PARSING FUNCTIONS | ||
529 | * | ||
530 | *****************************************************************************/ | ||
531 | |||
532 | /* Resets all irdata */ | ||
533 | static void | ||
534 | wbcir_reset_irdata(struct wbcir_data *data) | ||
535 | { | ||
536 | memset(data->irdata, 0, sizeof(data->irdata)); | ||
537 | data->irdata_count = 0; | ||
538 | data->irdata_off = 0; | ||
539 | data->irdata_error = 0; | ||
540 | data->idle_count = 0; | ||
541 | } | ||
542 | |||
543 | /* Adds one bit of irdata */ | ||
544 | static void | ||
545 | add_irdata_bit(struct wbcir_data *data, int set) | ||
546 | { | ||
547 | if (data->irdata_count >= sizeof(data->irdata) * 8) { | ||
548 | data->irdata_error = 1; | ||
549 | return; | ||
550 | } | ||
551 | |||
552 | if (set) | ||
553 | __set_bit(data->irdata_count, data->irdata); | ||
554 | data->irdata_count++; | ||
555 | } | ||
556 | |||
557 | /* Gets count bits of irdata */ | ||
558 | static u16 | ||
559 | get_bits(struct wbcir_data *data, int count) | ||
560 | { | ||
561 | u16 val = 0x0; | ||
562 | |||
563 | if (data->irdata_count - data->irdata_off < count) { | ||
564 | data->irdata_error = 1; | ||
565 | return 0x0; | ||
566 | } | ||
567 | |||
568 | while (count > 0) { | ||
569 | val <<= 1; | ||
570 | if (test_bit(data->irdata_off, data->irdata)) | ||
571 | val |= 0x1; | ||
572 | count--; | ||
573 | data->irdata_off++; | ||
574 | } | ||
575 | |||
576 | return val; | ||
577 | } | ||
578 | |||
579 | /* Reads 16 cells and converts them to a byte */ | ||
580 | static u8 | ||
581 | wbcir_rc6cells_to_byte(struct wbcir_data *data) | ||
582 | { | ||
583 | u16 raw = get_bits(data, 16); | ||
584 | u8 val = 0x00; | ||
585 | int bit; | ||
586 | |||
587 | for (bit = 0; bit < 8; bit++) { | ||
588 | switch (raw & 0x03) { | ||
589 | case 0x01: | ||
590 | break; | ||
591 | case 0x02: | ||
592 | val |= (0x01 << bit); | ||
593 | break; | ||
594 | default: | ||
595 | data->irdata_error = 1; | ||
596 | break; | ||
597 | } | ||
598 | raw >>= 2; | ||
599 | } | ||
600 | |||
601 | return val; | ||
602 | } | ||
603 | |||
604 | /* Decodes a number of bits from raw RC5 data */ | ||
605 | static u8 | ||
606 | wbcir_get_rc5bits(struct wbcir_data *data, unsigned int count) | ||
607 | { | ||
608 | u16 raw = get_bits(data, count * 2); | ||
609 | u8 val = 0x00; | ||
610 | int bit; | ||
611 | |||
612 | for (bit = 0; bit < count; bit++) { | ||
613 | switch (raw & 0x03) { | ||
614 | case 0x01: | ||
615 | val |= (0x01 << bit); | ||
616 | break; | ||
617 | case 0x02: | ||
618 | break; | ||
619 | default: | ||
620 | data->irdata_error = 1; | ||
621 | break; | ||
622 | } | ||
623 | raw >>= 2; | ||
624 | } | ||
625 | |||
626 | return val; | ||
627 | } | ||
628 | |||
629 | static void | ||
630 | wbcir_parse_rc6(struct device *dev, struct wbcir_data *data) | ||
631 | { | ||
632 | /* | ||
633 | * Normal bits are manchester coded as follows: | ||
634 | * cell0 + cell1 = logic "0" | ||
635 | * cell1 + cell0 = logic "1" | ||
636 | * | ||
637 | * The IR pulse has the following components: | ||
638 | * | ||
639 | * Leader - 6 * cell1 - discarded | ||
640 | * Gap - 2 * cell0 - discarded | ||
641 | * Start bit - Normal Coding - always "1" | ||
642 | * Mode Bit 2 - 0 - Normal Coding | ||
643 | * Toggle bit - Normal Coding with double bit time, | ||
644 | * e.g. cell0 + cell0 + cell1 + cell1 | ||
645 | * means logic "0". | ||
646 | * | ||
647 | * The rest depends on the mode, the following modes are known: | ||
648 | * | ||
649 | * MODE 0: | ||
650 | * Address Bit 7 - 0 - Normal Coding | ||
651 | * Command Bit 7 - 0 - Normal Coding | ||
652 | * | ||
653 | * MODE 6: | ||
654 | * The above Toggle Bit is used as a submode bit, 0 = A, 1 = B. | ||
655 | * Submode B is for pointing devices, only remotes using submode A | ||
656 | * are supported. | ||
657 | * | ||
658 | * Customer range bit - 0 => Customer = 7 bits, 0...127 | ||
659 | * 1 => Customer = 15 bits, 32768...65535 | ||
660 | * Customer Bits - Normal Coding | ||
661 | * | ||
662 | * Customer codes are allocated by Philips. The rest of the bits | ||
663 | * are customer dependent. The following is commonly used (and the | ||
664 | * only supported config): | ||
665 | * | ||
666 | * Toggle Bit - Normal Coding | ||
667 | * Address Bit 6 - 0 - Normal Coding | ||
668 | * Command Bit 7 - 0 - Normal Coding | ||
669 | * | ||
670 | * All modes are followed by at least 6 * cell0. | ||
671 | * | ||
672 | * MODE 0 msglen: | ||
673 | * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (toggle) + | ||
674 | * 8 * 2 (address) + 8 * 2 (command) = | ||
675 | * 44 cells | ||
676 | * | ||
677 | * MODE 6A msglen: | ||
678 | * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (submode) + | ||
679 | * 1 * 2 (customer range bit) + 7/15 * 2 (customer bits) + | ||
680 | * 1 * 2 (toggle bit) + 7 * 2 (address) + 8 * 2 (command) = | ||
681 | * 60 - 76 cells | ||
682 | */ | ||
683 | u8 mode; | ||
684 | u8 toggle; | ||
685 | u16 customer = 0x0; | ||
686 | u8 address; | ||
687 | u8 command; | ||
688 | u32 scancode; | ||
689 | |||
690 | /* Leader mark */ | ||
691 | while (get_bits(data, 1) && !data->irdata_error) | ||
692 | /* Do nothing */; | ||
693 | |||
694 | /* Leader space */ | ||
695 | if (get_bits(data, 1)) { | ||
696 | dev_dbg(dev, "RC6 - Invalid leader space\n"); | ||
697 | return; | ||
698 | } | ||
699 | |||
700 | /* Start bit */ | ||
701 | if (get_bits(data, 2) != 0x02) { | ||
702 | dev_dbg(dev, "RC6 - Invalid start bit\n"); | ||
703 | return; | ||
704 | } | ||
705 | |||
706 | /* Mode */ | ||
707 | mode = get_bits(data, 6); | ||
708 | switch (mode) { | ||
709 | case 0x15: /* 010101 = b000 */ | ||
710 | mode = 0; | ||
711 | break; | ||
712 | case 0x29: /* 101001 = b110 */ | ||
713 | mode = 6; | ||
714 | break; | ||
715 | default: | ||
716 | dev_dbg(dev, "RC6 - Invalid mode\n"); | ||
717 | return; | ||
718 | } | ||
719 | |||
720 | /* Toggle bit / Submode bit */ | ||
721 | toggle = get_bits(data, 4); | ||
722 | switch (toggle) { | ||
723 | case 0x03: | ||
724 | toggle = 0; | ||
725 | break; | ||
726 | case 0x0C: | ||
727 | toggle = 1; | ||
728 | break; | ||
729 | default: | ||
730 | dev_dbg(dev, "RC6 - Toggle bit error\n"); | ||
731 | break; | ||
732 | } | ||
733 | |||
734 | /* Customer */ | ||
735 | if (mode == 6) { | ||
736 | if (toggle != 0) { | ||
737 | dev_dbg(dev, "RC6B - Not Supported\n"); | ||
738 | return; | ||
739 | } | ||
740 | |||
741 | customer = wbcir_rc6cells_to_byte(data); | ||
742 | |||
743 | if (customer & 0x80) { | ||
744 | /* 15 bit customer value */ | ||
745 | customer <<= 8; | ||
746 | customer |= wbcir_rc6cells_to_byte(data); | ||
747 | } | ||
748 | } | ||
749 | |||
750 | /* Address */ | ||
751 | address = wbcir_rc6cells_to_byte(data); | ||
752 | if (mode == 6) { | ||
753 | toggle = address >> 7; | ||
754 | address &= 0x7F; | ||
755 | } | ||
756 | |||
757 | /* Command */ | ||
758 | command = wbcir_rc6cells_to_byte(data); | ||
759 | |||
760 | /* Create scancode */ | ||
761 | scancode = command; | ||
762 | scancode |= address << 8; | ||
763 | scancode |= customer << 16; | ||
764 | |||
765 | /* Last sanity check */ | ||
766 | if (data->irdata_error) { | ||
767 | dev_dbg(dev, "RC6 - Cell error(s)\n"); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " | ||
772 | "toggle %u mode %u scan 0x%08X\n", | ||
773 | address, | ||
774 | command, | ||
775 | customer, | ||
776 | (unsigned int)toggle, | ||
777 | (unsigned int)mode, | ||
778 | scancode); | ||
779 | |||
780 | wbcir_keydown(data, scancode, toggle); | ||
781 | } | ||
782 | |||
783 | static void | ||
784 | wbcir_parse_rc5(struct device *dev, struct wbcir_data *data) | ||
785 | { | ||
786 | /* | ||
787 | * Bits are manchester coded as follows: | ||
788 | * cell1 + cell0 = logic "0" | ||
789 | * cell0 + cell1 = logic "1" | ||
790 | * (i.e. the reverse of RC6) | ||
791 | * | ||
792 | * Start bit 1 - "1" - discarded | ||
793 | * Start bit 2 - Must be inverted to get command bit 6 | ||
794 | * Toggle bit | ||
795 | * Address Bit 4 - 0 | ||
796 | * Command Bit 5 - 0 | ||
797 | */ | ||
798 | u8 toggle; | ||
799 | u8 address; | ||
800 | u8 command; | ||
801 | u32 scancode; | ||
802 | |||
803 | /* Start bit 1 */ | ||
804 | if (!get_bits(data, 1)) { | ||
805 | dev_dbg(dev, "RC5 - Invalid start bit\n"); | ||
806 | return; | ||
807 | } | ||
808 | |||
809 | /* Start bit 2 */ | ||
810 | if (!wbcir_get_rc5bits(data, 1)) | ||
811 | command = 0x40; | ||
812 | else | ||
813 | command = 0x00; | ||
814 | |||
815 | toggle = wbcir_get_rc5bits(data, 1); | ||
816 | address = wbcir_get_rc5bits(data, 5); | ||
817 | command |= wbcir_get_rc5bits(data, 6); | ||
818 | scancode = address << 7 | command; | ||
819 | |||
820 | /* Last sanity check */ | ||
821 | if (data->irdata_error) { | ||
822 | dev_dbg(dev, "RC5 - Invalid message\n"); | ||
823 | return; | ||
824 | } | ||
825 | |||
826 | dev_dbg(dev, "IR-RC5 ad %u cm %u t %u s %u\n", | ||
827 | (unsigned int)address, | ||
828 | (unsigned int)command, | ||
829 | (unsigned int)toggle, | ||
830 | (unsigned int)scancode); | ||
831 | |||
832 | wbcir_keydown(data, scancode, toggle); | ||
833 | } | ||
834 | |||
835 | static void | ||
836 | wbcir_parse_nec(struct device *dev, struct wbcir_data *data) | ||
837 | { | ||
838 | /* | ||
839 | * Each bit represents 560 us. | ||
840 | * | ||
841 | * Leader - 9 ms burst | ||
842 | * Gap - 4.5 ms silence | ||
843 | * Address1 bit 0 - 7 - Address 1 | ||
844 | * Address2 bit 0 - 7 - Address 2 | ||
845 | * Command1 bit 0 - 7 - Command 1 | ||
846 | * Command2 bit 0 - 7 - Command 2 | ||
847 | * | ||
848 | * Note the bit order! | ||
849 | * | ||
850 | * With the old NEC protocol, Address2 was the inverse of Address1 | ||
851 | * and Command2 was the inverse of Command1 and were used as | ||
852 | * an error check. | ||
853 | * | ||
854 | * With NEC extended, Address1 is the LSB of the Address and | ||
855 | * Address2 is the MSB, Command parsing remains unchanged. | ||
856 | * | ||
857 | * A repeat message is coded as: | ||
858 | * Leader - 9 ms burst | ||
859 | * Gap - 2.25 ms silence | ||
860 | * Repeat - 560 us active | ||
861 | */ | ||
862 | u8 address1; | ||
863 | u8 address2; | ||
864 | u8 command1; | ||
865 | u8 command2; | ||
866 | u16 address; | ||
867 | u32 scancode; | ||
868 | |||
869 | /* Leader mark */ | ||
870 | while (get_bits(data, 1) && !data->irdata_error) | ||
871 | /* Do nothing */; | ||
872 | |||
873 | /* Leader space */ | ||
874 | if (get_bits(data, 4)) { | ||
875 | dev_dbg(dev, "NEC - Invalid leader space\n"); | ||
876 | return; | ||
877 | } | ||
878 | |||
879 | /* Repeat? */ | ||
880 | if (get_bits(data, 1)) { | ||
881 | if (!data->keypressed) { | ||
882 | dev_dbg(dev, "NEC - Stray repeat message\n"); | ||
883 | return; | ||
884 | } | ||
885 | |||
886 | dev_dbg(dev, "IR-NEC repeat s %u\n", | ||
887 | (unsigned int)data->last_scancode); | ||
888 | |||
889 | wbcir_keydown(data, data->last_scancode, data->last_toggle); | ||
890 | return; | ||
891 | } | ||
892 | |||
893 | /* Remaining leader space */ | ||
894 | if (get_bits(data, 3)) { | ||
895 | dev_dbg(dev, "NEC - Invalid leader space\n"); | ||
896 | return; | ||
897 | } | ||
898 | |||
899 | address1 = bitrev8(get_bits(data, 8)); | ||
900 | address2 = bitrev8(get_bits(data, 8)); | ||
901 | command1 = bitrev8(get_bits(data, 8)); | ||
902 | command2 = bitrev8(get_bits(data, 8)); | ||
903 | |||
904 | /* Sanity check */ | ||
905 | if (data->irdata_error) { | ||
906 | dev_dbg(dev, "NEC - Invalid message\n"); | ||
907 | return; | ||
908 | } | ||
909 | |||
910 | /* Check command validity */ | ||
911 | if (command1 != ~command2) { | ||
912 | dev_dbg(dev, "NEC - Command bytes mismatch\n"); | ||
913 | return; | ||
914 | } | ||
915 | |||
916 | /* Check for extended NEC protocol */ | ||
917 | address = address1; | ||
918 | if (address1 != ~address2) | ||
919 | address |= address2 << 8; | ||
920 | |||
921 | scancode = address << 8 | command1; | ||
922 | |||
923 | dev_dbg(dev, "IR-NEC ad %u cm %u s %u\n", | ||
924 | (unsigned int)address, | ||
925 | (unsigned int)command1, | ||
926 | (unsigned int)scancode); | ||
927 | |||
928 | wbcir_keydown(data, scancode, !data->last_toggle); | ||
929 | } | ||
930 | |||
931 | |||
932 | |||
933 | /***************************************************************************** | ||
934 | * | ||
935 | * INTERRUPT FUNCTIONS | ||
936 | * | ||
937 | *****************************************************************************/ | ||
938 | |||
939 | static irqreturn_t | ||
940 | wbcir_irq_handler(int irqno, void *cookie) | ||
941 | { | ||
942 | struct pnp_dev *device = cookie; | ||
943 | struct wbcir_data *data = pnp_get_drvdata(device); | ||
944 | struct device *dev = &device->dev; | ||
945 | u8 status; | ||
946 | unsigned long flags; | ||
947 | u8 irdata[8]; | ||
948 | int i; | ||
949 | unsigned int hw; | ||
950 | |||
951 | spin_lock_irqsave(&wbcir_lock, flags); | ||
952 | |||
953 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
954 | |||
955 | status = inb(data->sbase + WBCIR_REG_SP3_EIR); | ||
956 | |||
957 | if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) { | ||
958 | spin_unlock_irqrestore(&wbcir_lock, flags); | ||
959 | return IRQ_NONE; | ||
960 | } | ||
961 | |||
962 | if (status & WBCIR_IRQ_ERR) | ||
963 | data->irdata_error = 1; | ||
964 | |||
965 | if (!(status & WBCIR_IRQ_RX)) | ||
966 | goto out; | ||
967 | |||
968 | /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ | ||
969 | insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8); | ||
970 | |||
971 | for (i = 0; i < sizeof(irdata); i++) { | ||
972 | hw = hweight8(irdata[i]); | ||
973 | if (hw > 4) | ||
974 | add_irdata_bit(data, 0); | ||
975 | else | ||
976 | add_irdata_bit(data, 1); | ||
977 | |||
978 | if (hw == 8) | ||
979 | data->idle_count++; | ||
980 | else | ||
981 | data->idle_count = 0; | ||
982 | } | ||
983 | |||
984 | if (data->idle_count > WBCIR_MAX_IDLE_BYTES) { | ||
985 | /* Set RXINACTIVE... */ | ||
986 | outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR); | ||
987 | |||
988 | /* ...and drain the FIFO */ | ||
989 | while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) | ||
990 | inb(data->sbase + WBCIR_REG_SP3_RXDATA); | ||
991 | |||
992 | dev_dbg(dev, "IRDATA:\n"); | ||
993 | for (i = 0; i < data->irdata_count; i += BITS_PER_LONG) | ||
994 | dev_dbg(dev, "0x%08lX\n", data->irdata[i/BITS_PER_LONG]); | ||
995 | |||
996 | switch (protocol) { | ||
997 | case IR_PROTOCOL_RC5: | ||
998 | wbcir_parse_rc5(dev, data); | ||
999 | break; | ||
1000 | case IR_PROTOCOL_RC6: | ||
1001 | wbcir_parse_rc6(dev, data); | ||
1002 | break; | ||
1003 | case IR_PROTOCOL_NEC: | ||
1004 | wbcir_parse_nec(dev, data); | ||
1005 | break; | ||
1006 | } | ||
1007 | |||
1008 | wbcir_reset_irdata(data); | ||
1009 | } | ||
1010 | |||
1011 | out: | ||
1012 | spin_unlock_irqrestore(&wbcir_lock, flags); | ||
1013 | return IRQ_HANDLED; | ||
1014 | } | ||
1015 | |||
1016 | |||
1017 | |||
1018 | /***************************************************************************** | ||
1019 | * | ||
1020 | * SETUP/INIT/SUSPEND/RESUME FUNCTIONS | ||
1021 | * | ||
1022 | *****************************************************************************/ | ||
1023 | |||
1024 | static void | ||
1025 | wbcir_shutdown(struct pnp_dev *device) | ||
1026 | { | ||
1027 | struct device *dev = &device->dev; | ||
1028 | struct wbcir_data *data = pnp_get_drvdata(device); | ||
1029 | int do_wake = 1; | ||
1030 | u8 match[11]; | ||
1031 | u8 mask[11]; | ||
1032 | u8 rc6_csl = 0; | ||
1033 | int i; | ||
1034 | |||
1035 | memset(match, 0, sizeof(match)); | ||
1036 | memset(mask, 0, sizeof(mask)); | ||
1037 | |||
1038 | if (wake_sc == INVALID_SCANCODE || !device_may_wakeup(dev)) { | ||
1039 | do_wake = 0; | ||
1040 | goto finish; | ||
1041 | } | ||
1042 | |||
1043 | switch (protocol) { | ||
1044 | case IR_PROTOCOL_RC5: | ||
1045 | if (wake_sc > 0xFFF) { | ||
1046 | do_wake = 0; | ||
1047 | dev_err(dev, "RC5 - Invalid wake scancode\n"); | ||
1048 | break; | ||
1049 | } | ||
1050 | |||
1051 | /* Mask = 13 bits, ex toggle */ | ||
1052 | mask[0] = 0xFF; | ||
1053 | mask[1] = 0x17; | ||
1054 | |||
1055 | match[0] = (wake_sc & 0x003F); /* 6 command bits */ | ||
1056 | match[0] |= (wake_sc & 0x0180) >> 1; /* 2 address bits */ | ||
1057 | match[1] = (wake_sc & 0x0E00) >> 9; /* 3 address bits */ | ||
1058 | if (!(wake_sc & 0x0040)) /* 2nd start bit */ | ||
1059 | match[1] |= 0x10; | ||
1060 | |||
1061 | break; | ||
1062 | |||
1063 | case IR_PROTOCOL_NEC: | ||
1064 | if (wake_sc > 0xFFFFFF) { | ||
1065 | do_wake = 0; | ||
1066 | dev_err(dev, "NEC - Invalid wake scancode\n"); | ||
1067 | break; | ||
1068 | } | ||
1069 | |||
1070 | mask[0] = mask[1] = mask[2] = mask[3] = 0xFF; | ||
1071 | |||
1072 | match[1] = bitrev8((wake_sc & 0xFF)); | ||
1073 | match[0] = ~match[1]; | ||
1074 | |||
1075 | match[3] = bitrev8((wake_sc & 0xFF00) >> 8); | ||
1076 | if (wake_sc > 0xFFFF) | ||
1077 | match[2] = bitrev8((wake_sc & 0xFF0000) >> 16); | ||
1078 | else | ||
1079 | match[2] = ~match[3]; | ||
1080 | |||
1081 | break; | ||
1082 | |||
1083 | case IR_PROTOCOL_RC6: | ||
1084 | |||
1085 | if (wake_rc6mode == 0) { | ||
1086 | if (wake_sc > 0xFFFF) { | ||
1087 | do_wake = 0; | ||
1088 | dev_err(dev, "RC6 - Invalid wake scancode\n"); | ||
1089 | break; | ||
1090 | } | ||
1091 | |||
1092 | /* Command */ | ||
1093 | match[0] = wbcir_to_rc6cells(wake_sc >> 0); | ||
1094 | mask[0] = 0xFF; | ||
1095 | match[1] = wbcir_to_rc6cells(wake_sc >> 4); | ||
1096 | mask[1] = 0xFF; | ||
1097 | |||
1098 | /* Address */ | ||
1099 | match[2] = wbcir_to_rc6cells(wake_sc >> 8); | ||
1100 | mask[2] = 0xFF; | ||
1101 | match[3] = wbcir_to_rc6cells(wake_sc >> 12); | ||
1102 | mask[3] = 0xFF; | ||
1103 | |||
1104 | /* Header */ | ||
1105 | match[4] = 0x50; /* mode1 = mode0 = 0, ignore toggle */ | ||
1106 | mask[4] = 0xF0; | ||
1107 | match[5] = 0x09; /* start bit = 1, mode2 = 0 */ | ||
1108 | mask[5] = 0x0F; | ||
1109 | |||
1110 | rc6_csl = 44; | ||
1111 | |||
1112 | } else if (wake_rc6mode == 6) { | ||
1113 | i = 0; | ||
1114 | |||
1115 | /* Command */ | ||
1116 | match[i] = wbcir_to_rc6cells(wake_sc >> 0); | ||
1117 | mask[i++] = 0xFF; | ||
1118 | match[i] = wbcir_to_rc6cells(wake_sc >> 4); | ||
1119 | mask[i++] = 0xFF; | ||
1120 | |||
1121 | /* Address + Toggle */ | ||
1122 | match[i] = wbcir_to_rc6cells(wake_sc >> 8); | ||
1123 | mask[i++] = 0xFF; | ||
1124 | match[i] = wbcir_to_rc6cells(wake_sc >> 12); | ||
1125 | mask[i++] = 0x3F; | ||
1126 | |||
1127 | /* Customer bits 7 - 0 */ | ||
1128 | match[i] = wbcir_to_rc6cells(wake_sc >> 16); | ||
1129 | mask[i++] = 0xFF; | ||
1130 | match[i] = wbcir_to_rc6cells(wake_sc >> 20); | ||
1131 | mask[i++] = 0xFF; | ||
1132 | |||
1133 | if (wake_sc & 0x80000000) { | ||
1134 | /* Customer range bit and bits 15 - 8 */ | ||
1135 | match[i] = wbcir_to_rc6cells(wake_sc >> 24); | ||
1136 | mask[i++] = 0xFF; | ||
1137 | match[i] = wbcir_to_rc6cells(wake_sc >> 28); | ||
1138 | mask[i++] = 0xFF; | ||
1139 | rc6_csl = 76; | ||
1140 | } else if (wake_sc <= 0x007FFFFF) { | ||
1141 | rc6_csl = 60; | ||
1142 | } else { | ||
1143 | do_wake = 0; | ||
1144 | dev_err(dev, "RC6 - Invalid wake scancode\n"); | ||
1145 | break; | ||
1146 | } | ||
1147 | |||
1148 | /* Header */ | ||
1149 | match[i] = 0x93; /* mode1 = mode0 = 1, submode = 0 */ | ||
1150 | mask[i++] = 0xFF; | ||
1151 | match[i] = 0x0A; /* start bit = 1, mode2 = 1 */ | ||
1152 | mask[i++] = 0x0F; | ||
1153 | |||
1154 | } else { | ||
1155 | do_wake = 0; | ||
1156 | dev_err(dev, "RC6 - Invalid wake mode\n"); | ||
1157 | } | ||
1158 | |||
1159 | break; | ||
1160 | |||
1161 | default: | ||
1162 | do_wake = 0; | ||
1163 | break; | ||
1164 | } | ||
1165 | |||
1166 | finish: | ||
1167 | if (do_wake) { | ||
1168 | /* Set compare and compare mask */ | ||
1169 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_INDEX, | ||
1170 | WBCIR_REGSEL_COMPARE | WBCIR_REG_ADDR0, | ||
1171 | 0x3F); | ||
1172 | outsb(data->wbase + WBCIR_REG_WCEIR_DATA, match, 11); | ||
1173 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_INDEX, | ||
1174 | WBCIR_REGSEL_MASK | WBCIR_REG_ADDR0, | ||
1175 | 0x3F); | ||
1176 | outsb(data->wbase + WBCIR_REG_WCEIR_DATA, mask, 11); | ||
1177 | |||
1178 | /* RC6 Compare String Len */ | ||
1179 | outb(rc6_csl, data->wbase + WBCIR_REG_WCEIR_CSL); | ||
1180 | |||
1181 | /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ | ||
1182 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); | ||
1183 | |||
1184 | /* Clear BUFF_EN, Clear END_EN, Set MATCH_EN */ | ||
1185 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x01, 0x07); | ||
1186 | |||
1187 | /* Set CEIR_EN */ | ||
1188 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x01, 0x01); | ||
1189 | |||
1190 | } else { | ||
1191 | /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ | ||
1192 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); | ||
1193 | |||
1194 | /* Clear CEIR_EN */ | ||
1195 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); | ||
1196 | } | ||
1197 | |||
1198 | /* Disable interrupts */ | ||
1199 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1200 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | ||
1201 | |||
1202 | /* | ||
1203 | * ACPI will set the HW disable bit for SP3 which means that the | ||
1204 | * output signals are left in an undefined state which may cause | ||
1205 | * spurious interrupts which we need to ignore until the hardware | ||
1206 | * is reinitialized. | ||
1207 | */ | ||
1208 | disable_irq(data->irq); | ||
1209 | } | ||
1210 | |||
1211 | static int | ||
1212 | wbcir_suspend(struct pnp_dev *device, pm_message_t state) | ||
1213 | { | ||
1214 | wbcir_shutdown(device); | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | static void | ||
1219 | wbcir_init_hw(struct wbcir_data *data) | ||
1220 | { | ||
1221 | u8 tmp; | ||
1222 | |||
1223 | /* Disable interrupts */ | ||
1224 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1225 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | ||
1226 | |||
1227 | /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ | ||
1228 | tmp = protocol << 4; | ||
1229 | if (invert) | ||
1230 | tmp |= 0x08; | ||
1231 | outb(tmp, data->wbase + WBCIR_REG_WCEIR_CTL); | ||
1232 | |||
1233 | /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ | ||
1234 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); | ||
1235 | |||
1236 | /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ | ||
1237 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); | ||
1238 | |||
1239 | /* Set RC5 cell time to correspond to 36 kHz */ | ||
1240 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CFG1, 0x4A, 0x7F); | ||
1241 | |||
1242 | /* Set IRTX_INV */ | ||
1243 | if (invert) | ||
1244 | outb(0x04, data->ebase + WBCIR_REG_ECEIR_CCTL); | ||
1245 | else | ||
1246 | outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL); | ||
1247 | |||
1248 | /* | ||
1249 | * Clear IR LED, set SP3 clock to 24Mhz | ||
1250 | * set SP3_IRRX_SW to binary 01, helpfully not documented | ||
1251 | */ | ||
1252 | outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); | ||
1253 | |||
1254 | /* Enable extended mode */ | ||
1255 | wbcir_select_bank(data, WBCIR_BANK_2); | ||
1256 | outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); | ||
1257 | |||
1258 | /* | ||
1259 | * Configure baud generator, IR data will be sampled at | ||
1260 | * a bitrate of: (24Mhz * prescaler) / (divisor * 16). | ||
1261 | * | ||
1262 | * The ECIR registers include a flag to change the | ||
1263 | * 24Mhz clock freq to 48Mhz. | ||
1264 | * | ||
1265 | * It's not documented in the specs, but fifo levels | ||
1266 | * other than 16 seems to be unsupported. | ||
1267 | */ | ||
1268 | |||
1269 | /* prescaler 1.0, tx/rx fifo lvl 16 */ | ||
1270 | outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); | ||
1271 | |||
1272 | /* Set baud divisor to generate one byte per bit/cell */ | ||
1273 | switch (protocol) { | ||
1274 | case IR_PROTOCOL_RC5: | ||
1275 | outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1276 | break; | ||
1277 | case IR_PROTOCOL_RC6: | ||
1278 | outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1279 | break; | ||
1280 | case IR_PROTOCOL_NEC: | ||
1281 | outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1282 | break; | ||
1283 | } | ||
1284 | outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); | ||
1285 | |||
1286 | /* Set CEIR mode */ | ||
1287 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1288 | outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); | ||
1289 | inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ | ||
1290 | inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ | ||
1291 | |||
1292 | /* Disable RX demod, run-length encoding/decoding, set freq span */ | ||
1293 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1294 | outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); | ||
1295 | |||
1296 | /* Disable timer */ | ||
1297 | wbcir_select_bank(data, WBCIR_BANK_4); | ||
1298 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); | ||
1299 | |||
1300 | /* Enable MSR interrupt, Clear AUX_IRX */ | ||
1301 | wbcir_select_bank(data, WBCIR_BANK_5); | ||
1302 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); | ||
1303 | |||
1304 | /* Disable CRC */ | ||
1305 | wbcir_select_bank(data, WBCIR_BANK_6); | ||
1306 | outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); | ||
1307 | |||
1308 | /* Set RX/TX (de)modulation freq, not really used */ | ||
1309 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1310 | outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); | ||
1311 | outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); | ||
1312 | |||
1313 | /* Set invert and pin direction */ | ||
1314 | if (invert) | ||
1315 | outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1316 | else | ||
1317 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1318 | |||
1319 | /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ | ||
1320 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1321 | outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); | ||
1322 | |||
1323 | /* Clear AUX status bits */ | ||
1324 | outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); | ||
1325 | |||
1326 | /* Enable interrupts */ | ||
1327 | wbcir_reset_irdata(data); | ||
1328 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); | ||
1329 | } | ||
1330 | |||
1331 | static int | ||
1332 | wbcir_resume(struct pnp_dev *device) | ||
1333 | { | ||
1334 | struct wbcir_data *data = pnp_get_drvdata(device); | ||
1335 | |||
1336 | wbcir_init_hw(data); | ||
1337 | enable_irq(data->irq); | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | static int __devinit | ||
1343 | wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) | ||
1344 | { | ||
1345 | struct device *dev = &device->dev; | ||
1346 | struct wbcir_data *data; | ||
1347 | int err; | ||
1348 | |||
1349 | if (!(pnp_port_len(device, 0) == EHFUNC_IOMEM_LEN && | ||
1350 | pnp_port_len(device, 1) == WAKEUP_IOMEM_LEN && | ||
1351 | pnp_port_len(device, 2) == SP_IOMEM_LEN)) { | ||
1352 | dev_err(dev, "Invalid resources\n"); | ||
1353 | return -ENODEV; | ||
1354 | } | ||
1355 | |||
1356 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
1357 | if (!data) { | ||
1358 | err = -ENOMEM; | ||
1359 | goto exit; | ||
1360 | } | ||
1361 | |||
1362 | pnp_set_drvdata(device, data); | ||
1363 | |||
1364 | data->ebase = pnp_port_start(device, 0); | ||
1365 | data->wbase = pnp_port_start(device, 1); | ||
1366 | data->sbase = pnp_port_start(device, 2); | ||
1367 | data->irq = pnp_irq(device, 0); | ||
1368 | |||
1369 | if (data->wbase == 0 || data->ebase == 0 || | ||
1370 | data->sbase == 0 || data->irq == 0) { | ||
1371 | err = -ENODEV; | ||
1372 | dev_err(dev, "Invalid resources\n"); | ||
1373 | goto exit_free_data; | ||
1374 | } | ||
1375 | |||
1376 | dev_dbg(&device->dev, "Found device " | ||
1377 | "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", | ||
1378 | data->wbase, data->ebase, data->sbase, data->irq); | ||
1379 | |||
1380 | if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { | ||
1381 | dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", | ||
1382 | data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); | ||
1383 | err = -EBUSY; | ||
1384 | goto exit_free_data; | ||
1385 | } | ||
1386 | |||
1387 | if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { | ||
1388 | dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", | ||
1389 | data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); | ||
1390 | err = -EBUSY; | ||
1391 | goto exit_release_wbase; | ||
1392 | } | ||
1393 | |||
1394 | if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { | ||
1395 | dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", | ||
1396 | data->sbase, data->sbase + SP_IOMEM_LEN - 1); | ||
1397 | err = -EBUSY; | ||
1398 | goto exit_release_ebase; | ||
1399 | } | ||
1400 | |||
1401 | err = request_irq(data->irq, wbcir_irq_handler, | ||
1402 | IRQF_DISABLED, DRVNAME, device); | ||
1403 | if (err) { | ||
1404 | dev_err(dev, "Failed to claim IRQ %u\n", data->irq); | ||
1405 | err = -EBUSY; | ||
1406 | goto exit_release_sbase; | ||
1407 | } | ||
1408 | |||
1409 | led_trigger_register_simple("cir-tx", &data->txtrigger); | ||
1410 | if (!data->txtrigger) { | ||
1411 | err = -ENOMEM; | ||
1412 | goto exit_free_irq; | ||
1413 | } | ||
1414 | |||
1415 | led_trigger_register_simple("cir-rx", &data->rxtrigger); | ||
1416 | if (!data->rxtrigger) { | ||
1417 | err = -ENOMEM; | ||
1418 | goto exit_unregister_txtrigger; | ||
1419 | } | ||
1420 | |||
1421 | data->led.name = "cir::activity"; | ||
1422 | data->led.default_trigger = "cir-rx"; | ||
1423 | data->led.brightness_set = wbcir_led_brightness_set; | ||
1424 | data->led.brightness_get = wbcir_led_brightness_get; | ||
1425 | err = led_classdev_register(&device->dev, &data->led); | ||
1426 | if (err) | ||
1427 | goto exit_unregister_rxtrigger; | ||
1428 | |||
1429 | data->input_dev = input_allocate_device(); | ||
1430 | if (!data->input_dev) { | ||
1431 | err = -ENOMEM; | ||
1432 | goto exit_unregister_led; | ||
1433 | } | ||
1434 | |||
1435 | data->input_dev->evbit[0] = BIT(EV_KEY); | ||
1436 | data->input_dev->name = WBCIR_NAME; | ||
1437 | data->input_dev->phys = "wbcir/cir0"; | ||
1438 | data->input_dev->id.bustype = BUS_HOST; | ||
1439 | data->input_dev->id.vendor = PCI_VENDOR_ID_WINBOND; | ||
1440 | data->input_dev->id.product = WBCIR_ID_FAMILY; | ||
1441 | data->input_dev->id.version = WBCIR_ID_CHIP; | ||
1442 | data->input_dev->getkeycode = wbcir_getkeycode; | ||
1443 | data->input_dev->setkeycode = wbcir_setkeycode; | ||
1444 | input_set_capability(data->input_dev, EV_MSC, MSC_SCAN); | ||
1445 | input_set_drvdata(data->input_dev, data); | ||
1446 | |||
1447 | err = input_register_device(data->input_dev); | ||
1448 | if (err) | ||
1449 | goto exit_free_input; | ||
1450 | |||
1451 | data->last_scancode = INVALID_SCANCODE; | ||
1452 | INIT_LIST_HEAD(&data->keytable); | ||
1453 | setup_timer(&data->timer_keyup, wbcir_keyup, (unsigned long)data); | ||
1454 | |||
1455 | /* Load default keymaps */ | ||
1456 | if (protocol == IR_PROTOCOL_RC6) { | ||
1457 | int i; | ||
1458 | for (i = 0; i < ARRAY_SIZE(rc6_def_keymap); i++) { | ||
1459 | err = wbcir_setkeycode(data->input_dev, | ||
1460 | (int)rc6_def_keymap[i].scancode, | ||
1461 | (int)rc6_def_keymap[i].keycode); | ||
1462 | if (err) | ||
1463 | goto exit_unregister_keys; | ||
1464 | } | ||
1465 | } | ||
1466 | |||
1467 | device_init_wakeup(&device->dev, 1); | ||
1468 | |||
1469 | wbcir_init_hw(data); | ||
1470 | |||
1471 | return 0; | ||
1472 | |||
1473 | exit_unregister_keys: | ||
1474 | if (!list_empty(&data->keytable)) { | ||
1475 | struct wbcir_keyentry *key; | ||
1476 | struct wbcir_keyentry *keytmp; | ||
1477 | |||
1478 | list_for_each_entry_safe(key, keytmp, &data->keytable, list) { | ||
1479 | list_del(&key->list); | ||
1480 | kfree(key); | ||
1481 | } | ||
1482 | } | ||
1483 | input_unregister_device(data->input_dev); | ||
1484 | /* Can't call input_free_device on an unregistered device */ | ||
1485 | data->input_dev = NULL; | ||
1486 | exit_free_input: | ||
1487 | input_free_device(data->input_dev); | ||
1488 | exit_unregister_led: | ||
1489 | led_classdev_unregister(&data->led); | ||
1490 | exit_unregister_rxtrigger: | ||
1491 | led_trigger_unregister_simple(data->rxtrigger); | ||
1492 | exit_unregister_txtrigger: | ||
1493 | led_trigger_unregister_simple(data->txtrigger); | ||
1494 | exit_free_irq: | ||
1495 | free_irq(data->irq, device); | ||
1496 | exit_release_sbase: | ||
1497 | release_region(data->sbase, SP_IOMEM_LEN); | ||
1498 | exit_release_ebase: | ||
1499 | release_region(data->ebase, EHFUNC_IOMEM_LEN); | ||
1500 | exit_release_wbase: | ||
1501 | release_region(data->wbase, WAKEUP_IOMEM_LEN); | ||
1502 | exit_free_data: | ||
1503 | kfree(data); | ||
1504 | pnp_set_drvdata(device, NULL); | ||
1505 | exit: | ||
1506 | return err; | ||
1507 | } | ||
1508 | |||
1509 | static void __devexit | ||
1510 | wbcir_remove(struct pnp_dev *device) | ||
1511 | { | ||
1512 | struct wbcir_data *data = pnp_get_drvdata(device); | ||
1513 | struct wbcir_keyentry *key; | ||
1514 | struct wbcir_keyentry *keytmp; | ||
1515 | |||
1516 | /* Disable interrupts */ | ||
1517 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1518 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | ||
1519 | |||
1520 | del_timer_sync(&data->timer_keyup); | ||
1521 | |||
1522 | free_irq(data->irq, device); | ||
1523 | |||
1524 | /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ | ||
1525 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); | ||
1526 | |||
1527 | /* Clear CEIR_EN */ | ||
1528 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); | ||
1529 | |||
1530 | /* Clear BUFF_EN, END_EN, MATCH_EN */ | ||
1531 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); | ||
1532 | |||
1533 | /* This will generate a keyup event if necessary */ | ||
1534 | input_unregister_device(data->input_dev); | ||
1535 | |||
1536 | led_trigger_unregister_simple(data->rxtrigger); | ||
1537 | led_trigger_unregister_simple(data->txtrigger); | ||
1538 | led_classdev_unregister(&data->led); | ||
1539 | |||
1540 | /* This is ok since &data->led isn't actually used */ | ||
1541 | wbcir_led_brightness_set(&data->led, LED_OFF); | ||
1542 | |||
1543 | release_region(data->wbase, WAKEUP_IOMEM_LEN); | ||
1544 | release_region(data->ebase, EHFUNC_IOMEM_LEN); | ||
1545 | release_region(data->sbase, SP_IOMEM_LEN); | ||
1546 | |||
1547 | list_for_each_entry_safe(key, keytmp, &data->keytable, list) { | ||
1548 | list_del(&key->list); | ||
1549 | kfree(key); | ||
1550 | } | ||
1551 | |||
1552 | kfree(data); | ||
1553 | |||
1554 | pnp_set_drvdata(device, NULL); | ||
1555 | } | ||
1556 | |||
1557 | static const struct pnp_device_id wbcir_ids[] = { | ||
1558 | { "WEC1022", 0 }, | ||
1559 | { "", 0 } | ||
1560 | }; | ||
1561 | MODULE_DEVICE_TABLE(pnp, wbcir_ids); | ||
1562 | |||
1563 | static struct pnp_driver wbcir_driver = { | ||
1564 | .name = WBCIR_NAME, | ||
1565 | .id_table = wbcir_ids, | ||
1566 | .probe = wbcir_probe, | ||
1567 | .remove = __devexit_p(wbcir_remove), | ||
1568 | .suspend = wbcir_suspend, | ||
1569 | .resume = wbcir_resume, | ||
1570 | .shutdown = wbcir_shutdown | ||
1571 | }; | ||
1572 | |||
1573 | static int __init | ||
1574 | wbcir_init(void) | ||
1575 | { | ||
1576 | int ret; | ||
1577 | |||
1578 | switch (protocol) { | ||
1579 | case IR_PROTOCOL_RC5: | ||
1580 | case IR_PROTOCOL_NEC: | ||
1581 | case IR_PROTOCOL_RC6: | ||
1582 | break; | ||
1583 | default: | ||
1584 | printk(KERN_ERR DRVNAME ": Invalid protocol argument\n"); | ||
1585 | return -EINVAL; | ||
1586 | } | ||
1587 | |||
1588 | ret = pnp_register_driver(&wbcir_driver); | ||
1589 | if (ret) | ||
1590 | printk(KERN_ERR DRVNAME ": Unable to register driver\n"); | ||
1591 | |||
1592 | return ret; | ||
1593 | } | ||
1594 | |||
1595 | static void __exit | ||
1596 | wbcir_exit(void) | ||
1597 | { | ||
1598 | pnp_unregister_driver(&wbcir_driver); | ||
1599 | } | ||
1600 | |||
1601 | MODULE_AUTHOR("David Härdeman <david@hardeman.nu>"); | ||
1602 | MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver"); | ||
1603 | MODULE_LICENSE("GPL"); | ||
1604 | |||
1605 | module_init(wbcir_init); | ||
1606 | module_exit(wbcir_exit); | ||
1607 | |||
1608 | |||
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 12501de0c5cd..52b419348983 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -274,7 +274,7 @@ static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = { | |||
274 | { KE_BLUETOOTH, 0x30 }, /* Fn+F10 */ | 274 | { KE_BLUETOOTH, 0x30 }, /* Fn+F10 */ |
275 | { KE_KEY, 0x31, {KEY_MAIL} }, /* mail button */ | 275 | { KE_KEY, 0x31, {KEY_MAIL} }, /* mail button */ |
276 | { KE_KEY, 0x36, {KEY_WWW} }, /* www button */ | 276 | { KE_KEY, 0x36, {KEY_WWW} }, /* www button */ |
277 | { KE_WIFI, 0x78 }, /* satelite dish button */ | 277 | { KE_WIFI, 0x78 }, /* satellite dish button */ |
278 | { KE_END, 0 } | 278 | { KE_END, 0 } |
279 | }; | 279 | }; |
280 | 280 | ||
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index ebb11907d402..62bae99424e6 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c | |||
@@ -11,11 +11,7 @@ | |||
11 | * more details. | 11 | * more details. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
15 | * TODO: | ||
16 | * | ||
17 | * Switch to grant tables together with xen-fbfront.c. | ||
18 | */ | ||
19 | 15 | ||
20 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
21 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
@@ -28,6 +24,8 @@ | |||
28 | #include <xen/xen.h> | 24 | #include <xen/xen.h> |
29 | #include <xen/events.h> | 25 | #include <xen/events.h> |
30 | #include <xen/page.h> | 26 | #include <xen/page.h> |
27 | #include <xen/grant_table.h> | ||
28 | #include <xen/interface/grant_table.h> | ||
31 | #include <xen/interface/io/fbif.h> | 29 | #include <xen/interface/io/fbif.h> |
32 | #include <xen/interface/io/kbdif.h> | 30 | #include <xen/interface/io/kbdif.h> |
33 | #include <xen/xenbus.h> | 31 | #include <xen/xenbus.h> |
@@ -36,6 +34,7 @@ struct xenkbd_info { | |||
36 | struct input_dev *kbd; | 34 | struct input_dev *kbd; |
37 | struct input_dev *ptr; | 35 | struct input_dev *ptr; |
38 | struct xenkbd_page *page; | 36 | struct xenkbd_page *page; |
37 | int gref; | ||
39 | int irq; | 38 | int irq; |
40 | struct xenbus_device *xbdev; | 39 | struct xenbus_device *xbdev; |
41 | char phys[32]; | 40 | char phys[32]; |
@@ -84,9 +83,8 @@ static irqreturn_t input_handler(int rq, void *dev_id) | |||
84 | input_report_key(dev, event->key.keycode, | 83 | input_report_key(dev, event->key.keycode, |
85 | event->key.pressed); | 84 | event->key.pressed); |
86 | else | 85 | else |
87 | printk(KERN_WARNING | 86 | pr_warning("unhandled keycode 0x%x\n", |
88 | "xenkbd: unhandled keycode 0x%x\n", | 87 | event->key.keycode); |
89 | event->key.keycode); | ||
90 | break; | 88 | break; |
91 | case XENKBD_TYPE_POS: | 89 | case XENKBD_TYPE_POS: |
92 | input_report_abs(dev, ABS_X, event->pos.abs_x); | 90 | input_report_abs(dev, ABS_X, event->pos.abs_x); |
@@ -109,7 +107,7 @@ static irqreturn_t input_handler(int rq, void *dev_id) | |||
109 | static int __devinit xenkbd_probe(struct xenbus_device *dev, | 107 | static int __devinit xenkbd_probe(struct xenbus_device *dev, |
110 | const struct xenbus_device_id *id) | 108 | const struct xenbus_device_id *id) |
111 | { | 109 | { |
112 | int ret, i; | 110 | int ret, i, abs; |
113 | struct xenkbd_info *info; | 111 | struct xenkbd_info *info; |
114 | struct input_dev *kbd, *ptr; | 112 | struct input_dev *kbd, *ptr; |
115 | 113 | ||
@@ -121,12 +119,18 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev, | |||
121 | dev_set_drvdata(&dev->dev, info); | 119 | dev_set_drvdata(&dev->dev, info); |
122 | info->xbdev = dev; | 120 | info->xbdev = dev; |
123 | info->irq = -1; | 121 | info->irq = -1; |
122 | info->gref = -1; | ||
124 | snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename); | 123 | snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename); |
125 | 124 | ||
126 | info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); | 125 | info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); |
127 | if (!info->page) | 126 | if (!info->page) |
128 | goto error_nomem; | 127 | goto error_nomem; |
129 | 128 | ||
129 | if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-abs-pointer", "%d", &abs) < 0) | ||
130 | abs = 0; | ||
131 | if (abs) | ||
132 | xenbus_printf(XBT_NIL, dev->nodename, "request-abs-pointer", "1"); | ||
133 | |||
130 | /* keyboard */ | 134 | /* keyboard */ |
131 | kbd = input_allocate_device(); | 135 | kbd = input_allocate_device(); |
132 | if (!kbd) | 136 | if (!kbd) |
@@ -136,11 +140,12 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev, | |||
136 | kbd->id.bustype = BUS_PCI; | 140 | kbd->id.bustype = BUS_PCI; |
137 | kbd->id.vendor = 0x5853; | 141 | kbd->id.vendor = 0x5853; |
138 | kbd->id.product = 0xffff; | 142 | kbd->id.product = 0xffff; |
139 | kbd->evbit[0] = BIT(EV_KEY); | 143 | |
144 | __set_bit(EV_KEY, kbd->evbit); | ||
140 | for (i = KEY_ESC; i < KEY_UNKNOWN; i++) | 145 | for (i = KEY_ESC; i < KEY_UNKNOWN; i++) |
141 | set_bit(i, kbd->keybit); | 146 | __set_bit(i, kbd->keybit); |
142 | for (i = KEY_OK; i < KEY_MAX; i++) | 147 | for (i = KEY_OK; i < KEY_MAX; i++) |
143 | set_bit(i, kbd->keybit); | 148 | __set_bit(i, kbd->keybit); |
144 | 149 | ||
145 | ret = input_register_device(kbd); | 150 | ret = input_register_device(kbd); |
146 | if (ret) { | 151 | if (ret) { |
@@ -159,12 +164,20 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev, | |||
159 | ptr->id.bustype = BUS_PCI; | 164 | ptr->id.bustype = BUS_PCI; |
160 | ptr->id.vendor = 0x5853; | 165 | ptr->id.vendor = 0x5853; |
161 | ptr->id.product = 0xfffe; | 166 | ptr->id.product = 0xfffe; |
162 | ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); | 167 | |
168 | if (abs) { | ||
169 | __set_bit(EV_ABS, ptr->evbit); | ||
170 | input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); | ||
171 | input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); | ||
172 | } else { | ||
173 | input_set_capability(ptr, EV_REL, REL_X); | ||
174 | input_set_capability(ptr, EV_REL, REL_Y); | ||
175 | } | ||
176 | input_set_capability(ptr, EV_REL, REL_WHEEL); | ||
177 | |||
178 | __set_bit(EV_KEY, ptr->evbit); | ||
163 | for (i = BTN_LEFT; i <= BTN_TASK; i++) | 179 | for (i = BTN_LEFT; i <= BTN_TASK; i++) |
164 | set_bit(i, ptr->keybit); | 180 | __set_bit(i, ptr->keybit); |
165 | ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL); | ||
166 | input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0); | ||
167 | input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0); | ||
168 | 181 | ||
169 | ret = input_register_device(ptr); | 182 | ret = input_register_device(ptr); |
170 | if (ret) { | 183 | if (ret) { |
@@ -217,15 +230,20 @@ static int xenkbd_connect_backend(struct xenbus_device *dev, | |||
217 | int ret, evtchn; | 230 | int ret, evtchn; |
218 | struct xenbus_transaction xbt; | 231 | struct xenbus_transaction xbt; |
219 | 232 | ||
233 | ret = gnttab_grant_foreign_access(dev->otherend_id, | ||
234 | virt_to_mfn(info->page), 0); | ||
235 | if (ret < 0) | ||
236 | return ret; | ||
237 | info->gref = ret; | ||
238 | |||
220 | ret = xenbus_alloc_evtchn(dev, &evtchn); | 239 | ret = xenbus_alloc_evtchn(dev, &evtchn); |
221 | if (ret) | 240 | if (ret) |
222 | return ret; | 241 | goto error_grant; |
223 | ret = bind_evtchn_to_irqhandler(evtchn, input_handler, | 242 | ret = bind_evtchn_to_irqhandler(evtchn, input_handler, |
224 | 0, dev->devicetype, info); | 243 | 0, dev->devicetype, info); |
225 | if (ret < 0) { | 244 | if (ret < 0) { |
226 | xenbus_free_evtchn(dev, evtchn); | ||
227 | xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); | 245 | xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); |
228 | return ret; | 246 | goto error_evtchan; |
229 | } | 247 | } |
230 | info->irq = ret; | 248 | info->irq = ret; |
231 | 249 | ||
@@ -233,12 +251,15 @@ static int xenkbd_connect_backend(struct xenbus_device *dev, | |||
233 | ret = xenbus_transaction_start(&xbt); | 251 | ret = xenbus_transaction_start(&xbt); |
234 | if (ret) { | 252 | if (ret) { |
235 | xenbus_dev_fatal(dev, ret, "starting transaction"); | 253 | xenbus_dev_fatal(dev, ret, "starting transaction"); |
236 | return ret; | 254 | goto error_irqh; |
237 | } | 255 | } |
238 | ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", | 256 | ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", |
239 | virt_to_mfn(info->page)); | 257 | virt_to_mfn(info->page)); |
240 | if (ret) | 258 | if (ret) |
241 | goto error_xenbus; | 259 | goto error_xenbus; |
260 | ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref); | ||
261 | if (ret) | ||
262 | goto error_xenbus; | ||
242 | ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", | 263 | ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", |
243 | evtchn); | 264 | evtchn); |
244 | if (ret) | 265 | if (ret) |
@@ -248,7 +269,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev, | |||
248 | if (ret == -EAGAIN) | 269 | if (ret == -EAGAIN) |
249 | goto again; | 270 | goto again; |
250 | xenbus_dev_fatal(dev, ret, "completing transaction"); | 271 | xenbus_dev_fatal(dev, ret, "completing transaction"); |
251 | return ret; | 272 | goto error_irqh; |
252 | } | 273 | } |
253 | 274 | ||
254 | xenbus_switch_state(dev, XenbusStateInitialised); | 275 | xenbus_switch_state(dev, XenbusStateInitialised); |
@@ -257,6 +278,14 @@ static int xenkbd_connect_backend(struct xenbus_device *dev, | |||
257 | error_xenbus: | 278 | error_xenbus: |
258 | xenbus_transaction_end(xbt, 1); | 279 | xenbus_transaction_end(xbt, 1); |
259 | xenbus_dev_fatal(dev, ret, "writing xenstore"); | 280 | xenbus_dev_fatal(dev, ret, "writing xenstore"); |
281 | error_irqh: | ||
282 | unbind_from_irqhandler(info->irq, info); | ||
283 | info->irq = -1; | ||
284 | error_evtchan: | ||
285 | xenbus_free_evtchn(dev, evtchn); | ||
286 | error_grant: | ||
287 | gnttab_end_foreign_access_ref(info->gref, 0); | ||
288 | info->gref = -1; | ||
260 | return ret; | 289 | return ret; |
261 | } | 290 | } |
262 | 291 | ||
@@ -265,6 +294,9 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *info) | |||
265 | if (info->irq >= 0) | 294 | if (info->irq >= 0) |
266 | unbind_from_irqhandler(info->irq, info); | 295 | unbind_from_irqhandler(info->irq, info); |
267 | info->irq = -1; | 296 | info->irq = -1; |
297 | if (info->gref >= 0) | ||
298 | gnttab_end_foreign_access_ref(info->gref, 0); | ||
299 | info->gref = -1; | ||
268 | } | 300 | } |
269 | 301 | ||
270 | static void xenkbd_backend_changed(struct xenbus_device *dev, | 302 | static void xenkbd_backend_changed(struct xenbus_device *dev, |
@@ -276,6 +308,8 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, | |||
276 | switch (backend_state) { | 308 | switch (backend_state) { |
277 | case XenbusStateInitialising: | 309 | case XenbusStateInitialising: |
278 | case XenbusStateInitialised: | 310 | case XenbusStateInitialised: |
311 | case XenbusStateReconfiguring: | ||
312 | case XenbusStateReconfigured: | ||
279 | case XenbusStateUnknown: | 313 | case XenbusStateUnknown: |
280 | case XenbusStateClosed: | 314 | case XenbusStateClosed: |
281 | break; | 315 | break; |
@@ -290,9 +324,9 @@ InitWait: | |||
290 | ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, | 324 | ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, |
291 | "request-abs-pointer", "1"); | 325 | "request-abs-pointer", "1"); |
292 | if (ret) | 326 | if (ret) |
293 | printk(KERN_WARNING | 327 | pr_warning("xenkbd: can't request abs-pointer"); |
294 | "xenkbd: can't request abs-pointer"); | ||
295 | } | 328 | } |
329 | |||
296 | xenbus_switch_state(dev, XenbusStateConnected); | 330 | xenbus_switch_state(dev, XenbusStateConnected); |
297 | break; | 331 | break; |
298 | 332 | ||
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index c714ca2407f8..9c1e6ee83531 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -30,6 +30,7 @@ config MOUSE_PS2 | |||
30 | <http://w1.894.telia.com/~u89404340/touchpad/index.html> | 30 | <http://w1.894.telia.com/~u89404340/touchpad/index.html> |
31 | and a new version of GPM at: | 31 | and a new version of GPM at: |
32 | <http://www.geocities.com/dt_or/gpm/gpm.html> | 32 | <http://www.geocities.com/dt_or/gpm/gpm.html> |
33 | <http://xorg.freedesktop.org/archive/individual/driver/> | ||
33 | to take advantage of the advanced features of the touchpad. | 34 | to take advantage of the advanced features of the touchpad. |
34 | 35 | ||
35 | If unsure, say Y. | 36 | If unsure, say Y. |
@@ -38,7 +39,7 @@ config MOUSE_PS2 | |||
38 | module will be called psmouse. | 39 | module will be called psmouse. |
39 | 40 | ||
40 | config MOUSE_PS2_ALPS | 41 | config MOUSE_PS2_ALPS |
41 | bool "ALPS PS/2 mouse protocol extension" if EMBEDDED | 42 | bool "ALPS PS/2 mouse protocol extension" if EXPERT |
42 | default y | 43 | default y |
43 | depends on MOUSE_PS2 | 44 | depends on MOUSE_PS2 |
44 | help | 45 | help |
@@ -48,7 +49,7 @@ config MOUSE_PS2_ALPS | |||
48 | If unsure, say Y. | 49 | If unsure, say Y. |
49 | 50 | ||
50 | config MOUSE_PS2_LOGIPS2PP | 51 | config MOUSE_PS2_LOGIPS2PP |
51 | bool "Logitech PS/2++ mouse protocol extension" if EMBEDDED | 52 | bool "Logitech PS/2++ mouse protocol extension" if EXPERT |
52 | default y | 53 | default y |
53 | depends on MOUSE_PS2 | 54 | depends on MOUSE_PS2 |
54 | help | 55 | help |
@@ -58,7 +59,7 @@ config MOUSE_PS2_LOGIPS2PP | |||
58 | If unsure, say Y. | 59 | If unsure, say Y. |
59 | 60 | ||
60 | config MOUSE_PS2_SYNAPTICS | 61 | config MOUSE_PS2_SYNAPTICS |
61 | bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED | 62 | bool "Synaptics PS/2 mouse protocol extension" if EXPERT |
62 | default y | 63 | default y |
63 | depends on MOUSE_PS2 | 64 | depends on MOUSE_PS2 |
64 | help | 65 | help |
@@ -68,7 +69,7 @@ config MOUSE_PS2_SYNAPTICS | |||
68 | If unsure, say Y. | 69 | If unsure, say Y. |
69 | 70 | ||
70 | config MOUSE_PS2_LIFEBOOK | 71 | config MOUSE_PS2_LIFEBOOK |
71 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED | 72 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT |
72 | default y | 73 | default y |
73 | depends on MOUSE_PS2 && X86 && DMI | 74 | depends on MOUSE_PS2 && X86 && DMI |
74 | help | 75 | help |
@@ -78,7 +79,7 @@ config MOUSE_PS2_LIFEBOOK | |||
78 | If unsure, say Y. | 79 | If unsure, say Y. |
79 | 80 | ||
80 | config MOUSE_PS2_TRACKPOINT | 81 | config MOUSE_PS2_TRACKPOINT |
81 | bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED | 82 | bool "IBM Trackpoint PS/2 mouse protocol extension" if EXPERT |
82 | default y | 83 | default y |
83 | depends on MOUSE_PS2 | 84 | depends on MOUSE_PS2 |
84 | help | 85 | help |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index a9cf76831634..b77f9991278e 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -630,7 +630,7 @@ static void atp_complete_geyser_3_4(struct urb *urb) | |||
630 | /* Just update the base values (i.e. touchpad in untouched state) */ | 630 | /* Just update the base values (i.e. touchpad in untouched state) */ |
631 | if (dev->data[dev->info->datalen - 1] & ATP_STATUS_BASE_UPDATE) { | 631 | if (dev->data[dev->info->datalen - 1] & ATP_STATUS_BASE_UPDATE) { |
632 | 632 | ||
633 | dprintk(KERN_DEBUG "appletouch: updated base values\n"); | 633 | dprintk("appletouch: updated base values\n"); |
634 | 634 | ||
635 | memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); | 635 | memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); |
636 | goto exit; | 636 | goto exit; |
diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c index adf45b3040e9..5c4a692bf73a 100644 --- a/drivers/input/mouse/atarimouse.c +++ b/drivers/input/mouse/atarimouse.c | |||
@@ -77,15 +77,15 @@ static void atamouse_interrupt(char *buf) | |||
77 | #endif | 77 | #endif |
78 | 78 | ||
79 | /* only relative events get here */ | 79 | /* only relative events get here */ |
80 | dx = buf[1]; | 80 | dx = buf[1]; |
81 | dy = -buf[2]; | 81 | dy = buf[2]; |
82 | 82 | ||
83 | input_report_rel(atamouse_dev, REL_X, dx); | 83 | input_report_rel(atamouse_dev, REL_X, dx); |
84 | input_report_rel(atamouse_dev, REL_Y, dy); | 84 | input_report_rel(atamouse_dev, REL_Y, dy); |
85 | 85 | ||
86 | input_report_key(atamouse_dev, BTN_LEFT, buttons & 0x1); | 86 | input_report_key(atamouse_dev, BTN_LEFT, buttons & 0x4); |
87 | input_report_key(atamouse_dev, BTN_MIDDLE, buttons & 0x2); | 87 | input_report_key(atamouse_dev, BTN_MIDDLE, buttons & 0x2); |
88 | input_report_key(atamouse_dev, BTN_RIGHT, buttons & 0x4); | 88 | input_report_key(atamouse_dev, BTN_RIGHT, buttons & 0x1); |
89 | 89 | ||
90 | input_sync(atamouse_dev); | 90 | input_sync(atamouse_dev); |
91 | 91 | ||
@@ -108,7 +108,7 @@ static int atamouse_open(struct input_dev *dev) | |||
108 | static void atamouse_close(struct input_dev *dev) | 108 | static void atamouse_close(struct input_dev *dev) |
109 | { | 109 | { |
110 | ikbd_mouse_disable(); | 110 | ikbd_mouse_disable(); |
111 | atari_mouse_interrupt_hook = NULL; | 111 | atari_input_mouse_interrupt_hook = NULL; |
112 | } | 112 | } |
113 | 113 | ||
114 | static int __init atamouse_init(void) | 114 | static int __init atamouse_init(void) |
@@ -118,8 +118,9 @@ static int __init atamouse_init(void) | |||
118 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP)) | 118 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP)) |
119 | return -ENODEV; | 119 | return -ENODEV; |
120 | 120 | ||
121 | if (!atari_keyb_init()) | 121 | error = atari_keyb_init(); |
122 | return -ENODEV; | 122 | if (error) |
123 | return error; | ||
123 | 124 | ||
124 | atamouse_dev = input_allocate_device(); | 125 | atamouse_dev = input_allocate_device(); |
125 | if (!atamouse_dev) | 126 | if (!atamouse_dev) |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index b95231763911..3126983c004a 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -55,6 +55,18 @@ | |||
55 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 | 55 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 |
56 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 | 56 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 |
57 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 | 57 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 |
58 | /* MacbookAir3,2 (unibody), aka wellspring5 */ | ||
59 | #define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f | ||
60 | #define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240 | ||
61 | #define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241 | ||
62 | /* MacbookAir3,1 (unibody), aka wellspring4 */ | ||
63 | #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 | ||
64 | #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 | ||
65 | #define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 | ||
66 | /* Macbook8 (unibody, March 2011) */ | ||
67 | #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 | ||
68 | #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 | ||
69 | #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 | ||
58 | 70 | ||
59 | #define BCM5974_DEVICE(prod) { \ | 71 | #define BCM5974_DEVICE(prod) { \ |
60 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ | 72 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
@@ -80,6 +92,18 @@ static const struct usb_device_id bcm5974_table[] = { | |||
80 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), | 92 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), |
81 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), | 93 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), |
82 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), | 94 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), |
95 | /* MacbookAir3,2 */ | ||
96 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI), | ||
97 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ISO), | ||
98 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_JIS), | ||
99 | /* MacbookAir3,1 */ | ||
100 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), | ||
101 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), | ||
102 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), | ||
103 | /* MacbookPro8 */ | ||
104 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI), | ||
105 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ISO), | ||
106 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), | ||
83 | /* Terminating entry */ | 107 | /* Terminating entry */ |
84 | {} | 108 | {} |
85 | }; | 109 | }; |
@@ -234,6 +258,42 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
234 | { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, | 258 | { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, |
235 | { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } | 259 | { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } |
236 | }, | 260 | }, |
261 | { | ||
262 | USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, | ||
263 | USB_DEVICE_ID_APPLE_WELLSPRING4_ISO, | ||
264 | USB_DEVICE_ID_APPLE_WELLSPRING4_JIS, | ||
265 | HAS_INTEGRATED_BUTTON, | ||
266 | 0x84, sizeof(struct bt_data), | ||
267 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | ||
268 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | ||
269 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | ||
270 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, | ||
271 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } | ||
272 | }, | ||
273 | { | ||
274 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, | ||
275 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO, | ||
276 | USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS, | ||
277 | HAS_INTEGRATED_BUTTON, | ||
278 | 0x84, sizeof(struct bt_data), | ||
279 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | ||
280 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | ||
281 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | ||
282 | { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, | ||
283 | { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } | ||
284 | }, | ||
285 | { | ||
286 | USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, | ||
287 | USB_DEVICE_ID_APPLE_WELLSPRING5_ISO, | ||
288 | USB_DEVICE_ID_APPLE_WELLSPRING5_JIS, | ||
289 | HAS_INTEGRATED_BUTTON, | ||
290 | 0x84, sizeof(struct bt_data), | ||
291 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | ||
292 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | ||
293 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | ||
294 | { DIM_X, DIM_X / SN_COORD, -4415, 5050 }, | ||
295 | { DIM_Y, DIM_Y / SN_COORD, -55, 6680 } | ||
296 | }, | ||
237 | {} | 297 | {} |
238 | }; | 298 | }; |
239 | 299 | ||
@@ -390,10 +450,6 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
390 | ptest = int2bound(&c->p, raw_p); | 450 | ptest = int2bound(&c->p, raw_p); |
391 | origin = raw2int(f->origin); | 451 | origin = raw2int(f->origin); |
392 | 452 | ||
393 | /* set the integrated button if applicable */ | ||
394 | if (c->tp_type == TYPE2) | ||
395 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
396 | |||
397 | /* while tracking finger still valid, count all fingers */ | 453 | /* while tracking finger still valid, count all fingers */ |
398 | if (ptest > PRESSURE_LOW && origin) { | 454 | if (ptest > PRESSURE_LOW && origin) { |
399 | abs_p = ptest; | 455 | abs_p = ptest; |
@@ -412,6 +468,10 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
412 | } | 468 | } |
413 | } | 469 | } |
414 | 470 | ||
471 | /* set the integrated button if applicable */ | ||
472 | if (c->tp_type == TYPE2) | ||
473 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
474 | |||
415 | if (dev->fingers < nmin) | 475 | if (dev->fingers < nmin) |
416 | dev->fingers = nmin; | 476 | dev->fingers = nmin; |
417 | if (dev->fingers > nmax) | 477 | if (dev->fingers > nmax) |
@@ -579,7 +639,7 @@ exit: | |||
579 | * device, resulting in trackpad malfunction under certain | 639 | * device, resulting in trackpad malfunction under certain |
580 | * circumstances. To get around this problem, there is at least one | 640 | * circumstances. To get around this problem, there is at least one |
581 | * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to | 641 | * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to |
582 | * recieve a reset_resume request rather than the normal resume. | 642 | * receive a reset_resume request rather than the normal resume. |
583 | * Since the implementation of reset_resume is equal to mode switch | 643 | * Since the implementation of reset_resume is equal to mode switch |
584 | * plus start_traffic, it seems easier to always do the switch when | 644 | * plus start_traffic, it seems easier to always do the switch when |
585 | * starting traffic on the device. | 645 | * starting traffic on the device. |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 48311204ba51..32503565faf9 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/input/mt.h> | ||
19 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
20 | #include <linux/libps2.h> | 21 | #include <linux/libps2.h> |
21 | #include "psmouse.h" | 22 | #include "psmouse.h" |
@@ -242,15 +243,37 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
242 | input_sync(dev); | 243 | input_sync(dev); |
243 | } | 244 | } |
244 | 245 | ||
246 | static void elantech_set_slot(struct input_dev *dev, int slot, bool active, | ||
247 | unsigned int x, unsigned int y) | ||
248 | { | ||
249 | input_mt_slot(dev, slot); | ||
250 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | ||
251 | if (active) { | ||
252 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
253 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | /* x1 < x2 and y1 < y2 when two fingers, x = y = 0 when not pressed */ | ||
258 | static void elantech_report_semi_mt_data(struct input_dev *dev, | ||
259 | unsigned int num_fingers, | ||
260 | unsigned int x1, unsigned int y1, | ||
261 | unsigned int x2, unsigned int y2) | ||
262 | { | ||
263 | elantech_set_slot(dev, 0, num_fingers != 0, x1, y1); | ||
264 | elantech_set_slot(dev, 1, num_fingers == 2, x2, y2); | ||
265 | } | ||
266 | |||
245 | /* | 267 | /* |
246 | * Interpret complete data packets and report absolute mode input events for | 268 | * Interpret complete data packets and report absolute mode input events for |
247 | * hardware version 2. (6 byte packets) | 269 | * hardware version 2. (6 byte packets) |
248 | */ | 270 | */ |
249 | static void elantech_report_absolute_v2(struct psmouse *psmouse) | 271 | static void elantech_report_absolute_v2(struct psmouse *psmouse) |
250 | { | 272 | { |
273 | struct elantech_data *etd = psmouse->private; | ||
251 | struct input_dev *dev = psmouse->dev; | 274 | struct input_dev *dev = psmouse->dev; |
252 | unsigned char *packet = psmouse->packet; | 275 | unsigned char *packet = psmouse->packet; |
253 | int fingers, x1, y1, x2, y2; | 276 | unsigned int fingers, x1 = 0, y1 = 0, x2 = 0, y2 = 0, width = 0, pres = 0; |
254 | 277 | ||
255 | /* byte 0: n1 n0 . . . . R L */ | 278 | /* byte 0: n1 n0 . . . . R L */ |
256 | fingers = (packet[0] & 0xc0) >> 6; | 279 | fingers = (packet[0] & 0xc0) >> 6; |
@@ -270,14 +293,18 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
270 | * byte 1: . . . . . x10 x9 x8 | 293 | * byte 1: . . . . . x10 x9 x8 |
271 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 | 294 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 |
272 | */ | 295 | */ |
273 | input_report_abs(dev, ABS_X, | 296 | x1 = ((packet[1] & 0x07) << 8) | packet[2]; |
274 | ((packet[1] & 0x07) << 8) | packet[2]); | ||
275 | /* | 297 | /* |
276 | * byte 4: . . . . . . y9 y8 | 298 | * byte 4: . . . . . . y9 y8 |
277 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | 299 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 |
278 | */ | 300 | */ |
279 | input_report_abs(dev, ABS_Y, | 301 | y1 = ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]); |
280 | ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5])); | 302 | |
303 | input_report_abs(dev, ABS_X, x1); | ||
304 | input_report_abs(dev, ABS_Y, y1); | ||
305 | |||
306 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); | ||
307 | width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4); | ||
281 | break; | 308 | break; |
282 | 309 | ||
283 | case 2: | 310 | case 2: |
@@ -303,23 +330,24 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
303 | */ | 330 | */ |
304 | input_report_abs(dev, ABS_X, x1 << 2); | 331 | input_report_abs(dev, ABS_X, x1 << 2); |
305 | input_report_abs(dev, ABS_Y, y1 << 2); | 332 | input_report_abs(dev, ABS_Y, y1 << 2); |
306 | /* | 333 | |
307 | * For compatibility with the proprietary X Elantech driver | 334 | /* Unknown so just report sensible values */ |
308 | * report both coordinates as hat coordinates | 335 | pres = 127; |
309 | */ | 336 | width = 7; |
310 | input_report_abs(dev, ABS_HAT0X, x1); | ||
311 | input_report_abs(dev, ABS_HAT0Y, y1); | ||
312 | input_report_abs(dev, ABS_HAT1X, x2); | ||
313 | input_report_abs(dev, ABS_HAT1Y, y2); | ||
314 | break; | 337 | break; |
315 | } | 338 | } |
316 | 339 | ||
340 | elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | ||
317 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 341 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
318 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | 342 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); |
319 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | 343 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); |
320 | input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); | 344 | input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); |
321 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 345 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
322 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 346 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
347 | if (etd->reports_pressure) { | ||
348 | input_report_abs(dev, ABS_PRESSURE, pres); | ||
349 | input_report_abs(dev, ABS_TOOL_WIDTH, width); | ||
350 | } | ||
323 | 351 | ||
324 | input_sync(dev); | 352 | input_sync(dev); |
325 | } | 353 | } |
@@ -478,10 +506,16 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
478 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | 506 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); |
479 | input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); | 507 | input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); |
480 | input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); | 508 | input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); |
481 | input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0); | 509 | if (etd->reports_pressure) { |
482 | input_set_abs_params(dev, ABS_HAT0Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0); | 510 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, |
483 | input_set_abs_params(dev, ABS_HAT1X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0); | 511 | ETP_PMAX_V2, 0, 0); |
484 | input_set_abs_params(dev, ABS_HAT1Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0); | 512 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, |
513 | ETP_WMAX_V2, 0, 0); | ||
514 | } | ||
515 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | ||
516 | input_mt_init_slots(dev, 2); | ||
517 | input_set_abs_params(dev, ABS_MT_POSITION_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); | ||
518 | input_set_abs_params(dev, ABS_MT_POSITION_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); | ||
485 | break; | 519 | break; |
486 | } | 520 | } |
487 | } | 521 | } |
@@ -699,7 +733,7 @@ int elantech_init(struct psmouse *psmouse) | |||
699 | 733 | ||
700 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); | 734 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); |
701 | if (!etd) | 735 | if (!etd) |
702 | return -1; | 736 | return -ENOMEM; |
703 | 737 | ||
704 | etd->parity[0] = 1; | 738 | etd->parity[0] = 1; |
705 | for (i = 1; i < 256; i++) | 739 | for (i = 1; i < 256; i++) |
@@ -725,6 +759,10 @@ int elantech_init(struct psmouse *psmouse) | |||
725 | etd->debug = 1; | 759 | etd->debug = 1; |
726 | /* Don't know how to do parity checking for version 2 */ | 760 | /* Don't know how to do parity checking for version 2 */ |
727 | etd->paritycheck = 0; | 761 | etd->paritycheck = 0; |
762 | |||
763 | if (etd->fw_version >= 0x020800) | ||
764 | etd->reports_pressure = true; | ||
765 | |||
728 | } else { | 766 | } else { |
729 | etd->hw_version = 1; | 767 | etd->hw_version = 1; |
730 | etd->paritycheck = 1; | 768 | etd->paritycheck = 1; |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index aa4aac5d2198..fabb2b99615c 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -77,6 +77,11 @@ | |||
77 | #define ETP_YMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2) | 77 | #define ETP_YMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2) |
78 | #define ETP_YMAX_V2 ( 768 - ETP_EDGE_FUZZ_V2) | 78 | #define ETP_YMAX_V2 ( 768 - ETP_EDGE_FUZZ_V2) |
79 | 79 | ||
80 | #define ETP_PMIN_V2 0 | ||
81 | #define ETP_PMAX_V2 255 | ||
82 | #define ETP_WMIN_V2 0 | ||
83 | #define ETP_WMAX_V2 15 | ||
84 | |||
80 | /* | 85 | /* |
81 | * For two finger touches the coordinate of each finger gets reported | 86 | * For two finger touches the coordinate of each finger gets reported |
82 | * separately but with reduced resolution. | 87 | * separately but with reduced resolution. |
@@ -102,6 +107,7 @@ struct elantech_data { | |||
102 | unsigned char capabilities; | 107 | unsigned char capabilities; |
103 | bool paritycheck; | 108 | bool paritycheck; |
104 | bool jumpy_cursor; | 109 | bool jumpy_cursor; |
110 | bool reports_pressure; | ||
105 | unsigned char hw_version; | 111 | unsigned char hw_version; |
106 | unsigned int fw_version; | 112 | unsigned int fw_version; |
107 | unsigned int single_finger_reports; | 113 | unsigned int single_finger_reports; |
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 1d2205b24800..95577c15ae56 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include "psmouse.h" | 40 | #include "psmouse.h" |
41 | #include "hgpk.h" | 41 | #include "hgpk.h" |
42 | 42 | ||
43 | #define ILLEGAL_XY 999999 | ||
44 | |||
43 | static bool tpdebug; | 45 | static bool tpdebug; |
44 | module_param(tpdebug, bool, 0644); | 46 | module_param(tpdebug, bool, 0644); |
45 | MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); | 47 | MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); |
@@ -47,48 +49,150 @@ MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); | |||
47 | static int recalib_delta = 100; | 49 | static int recalib_delta = 100; |
48 | module_param(recalib_delta, int, 0644); | 50 | module_param(recalib_delta, int, 0644); |
49 | MODULE_PARM_DESC(recalib_delta, | 51 | MODULE_PARM_DESC(recalib_delta, |
50 | "packets containing a delta this large will cause a recalibration."); | 52 | "packets containing a delta this large will be discarded, and a " |
53 | "recalibration may be scheduled."); | ||
51 | 54 | ||
52 | static int jumpy_delay = 1000; | 55 | static int jumpy_delay = 20; |
53 | module_param(jumpy_delay, int, 0644); | 56 | module_param(jumpy_delay, int, 0644); |
54 | MODULE_PARM_DESC(jumpy_delay, | 57 | MODULE_PARM_DESC(jumpy_delay, |
55 | "delay (ms) before recal after jumpiness detected"); | 58 | "delay (ms) before recal after jumpiness detected"); |
56 | 59 | ||
57 | static int spew_delay = 1000; | 60 | static int spew_delay = 1; |
58 | module_param(spew_delay, int, 0644); | 61 | module_param(spew_delay, int, 0644); |
59 | MODULE_PARM_DESC(spew_delay, | 62 | MODULE_PARM_DESC(spew_delay, |
60 | "delay (ms) before recal after packet spew detected"); | 63 | "delay (ms) before recal after packet spew detected"); |
61 | 64 | ||
62 | static int recal_guard_time = 2000; | 65 | static int recal_guard_time; |
63 | module_param(recal_guard_time, int, 0644); | 66 | module_param(recal_guard_time, int, 0644); |
64 | MODULE_PARM_DESC(recal_guard_time, | 67 | MODULE_PARM_DESC(recal_guard_time, |
65 | "interval (ms) during which recal will be restarted if packet received"); | 68 | "interval (ms) during which recal will be restarted if packet received"); |
66 | 69 | ||
67 | static int post_interrupt_delay = 1000; | 70 | static int post_interrupt_delay = 40; |
68 | module_param(post_interrupt_delay, int, 0644); | 71 | module_param(post_interrupt_delay, int, 0644); |
69 | MODULE_PARM_DESC(post_interrupt_delay, | 72 | MODULE_PARM_DESC(post_interrupt_delay, |
70 | "delay (ms) before recal after recal interrupt detected"); | 73 | "delay (ms) before recal after recal interrupt detected"); |
71 | 74 | ||
75 | static bool autorecal = true; | ||
76 | module_param(autorecal, bool, 0644); | ||
77 | MODULE_PARM_DESC(autorecal, "enable recalibration in the driver"); | ||
78 | |||
79 | static char hgpk_mode_name[16]; | ||
80 | module_param_string(hgpk_mode, hgpk_mode_name, sizeof(hgpk_mode_name), 0644); | ||
81 | MODULE_PARM_DESC(hgpk_mode, | ||
82 | "default hgpk mode: mouse, glidesensor or pentablet"); | ||
83 | |||
84 | static int hgpk_default_mode = HGPK_MODE_MOUSE; | ||
85 | |||
86 | static const char * const hgpk_mode_names[] = { | ||
87 | [HGPK_MODE_MOUSE] = "Mouse", | ||
88 | [HGPK_MODE_GLIDESENSOR] = "GlideSensor", | ||
89 | [HGPK_MODE_PENTABLET] = "PenTablet", | ||
90 | }; | ||
91 | |||
92 | static int hgpk_mode_from_name(const char *buf, int len) | ||
93 | { | ||
94 | int i; | ||
95 | |||
96 | for (i = 0; i < ARRAY_SIZE(hgpk_mode_names); i++) { | ||
97 | const char *name = hgpk_mode_names[i]; | ||
98 | if (strlen(name) == len && !strncasecmp(name, buf, len)) | ||
99 | return i; | ||
100 | } | ||
101 | |||
102 | return HGPK_MODE_INVALID; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * see if new value is within 20% of half of old value | ||
107 | */ | ||
108 | static int approx_half(int curr, int prev) | ||
109 | { | ||
110 | int belowhalf, abovehalf; | ||
111 | |||
112 | if (curr < 5 || prev < 5) | ||
113 | return 0; | ||
114 | |||
115 | belowhalf = (prev * 8) / 20; | ||
116 | abovehalf = (prev * 12) / 20; | ||
117 | |||
118 | return belowhalf < curr && curr <= abovehalf; | ||
119 | } | ||
120 | |||
72 | /* | 121 | /* |
73 | * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" | 122 | * Throw out oddly large delta packets, and any that immediately follow whose |
74 | * above the pad and still have it send packets. This causes a jump cursor | 123 | * values are each approximately half of the previous. It seems that the ALPS |
75 | * when one places their finger on the pad. We can probably detect the | 124 | * firmware emits errant packets, and they get averaged out slowly. |
76 | * jump as we see a large deltas (>= 100px). In mouse mode, I've been | ||
77 | * unable to even come close to 100px deltas during normal usage, so I think | ||
78 | * this threshold is safe. If a large delta occurs, trigger a recalibration. | ||
79 | */ | 125 | */ |
80 | static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y) | 126 | static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) |
81 | { | 127 | { |
82 | struct hgpk_data *priv = psmouse->private; | 128 | struct hgpk_data *priv = psmouse->private; |
129 | int avx, avy; | ||
130 | bool do_recal = false; | ||
131 | |||
132 | avx = abs(x); | ||
133 | avy = abs(y); | ||
134 | |||
135 | /* discard if too big, or half that but > 4 times the prev delta */ | ||
136 | if (avx > recalib_delta || | ||
137 | (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) { | ||
138 | hgpk_err(psmouse, "detected %dpx jump in x\n", x); | ||
139 | priv->xbigj = avx; | ||
140 | } else if (approx_half(avx, priv->xbigj)) { | ||
141 | hgpk_err(psmouse, "detected secondary %dpx jump in x\n", x); | ||
142 | priv->xbigj = avx; | ||
143 | priv->xsaw_secondary++; | ||
144 | } else { | ||
145 | if (priv->xbigj && priv->xsaw_secondary > 1) | ||
146 | do_recal = true; | ||
147 | priv->xbigj = 0; | ||
148 | priv->xsaw_secondary = 0; | ||
149 | } | ||
150 | |||
151 | if (avy > recalib_delta || | ||
152 | (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) { | ||
153 | hgpk_err(psmouse, "detected %dpx jump in y\n", y); | ||
154 | priv->ybigj = avy; | ||
155 | } else if (approx_half(avy, priv->ybigj)) { | ||
156 | hgpk_err(psmouse, "detected secondary %dpx jump in y\n", y); | ||
157 | priv->ybigj = avy; | ||
158 | priv->ysaw_secondary++; | ||
159 | } else { | ||
160 | if (priv->ybigj && priv->ysaw_secondary > 1) | ||
161 | do_recal = true; | ||
162 | priv->ybigj = 0; | ||
163 | priv->ysaw_secondary = 0; | ||
164 | } | ||
83 | 165 | ||
84 | if (abs(x) > recalib_delta || abs(y) > recalib_delta) { | 166 | priv->xlast = avx; |
85 | hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n", | 167 | priv->ylast = avy; |
86 | recalib_delta, x, y); | 168 | |
87 | /* My car gets forty rods to the hogshead and that's the | 169 | if (do_recal && jumpy_delay) { |
88 | * way I likes it! */ | 170 | hgpk_err(psmouse, "scheduling recalibration\n"); |
89 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 171 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
90 | msecs_to_jiffies(jumpy_delay)); | 172 | msecs_to_jiffies(jumpy_delay)); |
91 | } | 173 | } |
174 | |||
175 | return priv->xbigj || priv->ybigj; | ||
176 | } | ||
177 | |||
178 | static void hgpk_reset_spew_detection(struct hgpk_data *priv) | ||
179 | { | ||
180 | priv->spew_count = 0; | ||
181 | priv->dupe_count = 0; | ||
182 | priv->x_tally = 0; | ||
183 | priv->y_tally = 0; | ||
184 | priv->spew_flag = NO_SPEW; | ||
185 | } | ||
186 | |||
187 | static void hgpk_reset_hack_state(struct psmouse *psmouse) | ||
188 | { | ||
189 | struct hgpk_data *priv = psmouse->private; | ||
190 | |||
191 | priv->abs_x = priv->abs_y = -1; | ||
192 | priv->xlast = priv->ylast = ILLEGAL_XY; | ||
193 | priv->xbigj = priv->ybigj = 0; | ||
194 | priv->xsaw_secondary = priv->ysaw_secondary = 0; | ||
195 | hgpk_reset_spew_detection(priv); | ||
92 | } | 196 | } |
93 | 197 | ||
94 | /* | 198 | /* |
@@ -116,20 +220,57 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, | |||
116 | if (l || r) | 220 | if (l || r) |
117 | return; | 221 | return; |
118 | 222 | ||
223 | /* don't track spew if the workaround feature has been turned off */ | ||
224 | if (!spew_delay) | ||
225 | return; | ||
226 | |||
227 | if (abs(x) > 3 || abs(y) > 3) { | ||
228 | /* no spew, or spew ended */ | ||
229 | hgpk_reset_spew_detection(priv); | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | /* Keep a tally of the overall delta to the cursor position caused by | ||
234 | * the spew */ | ||
119 | priv->x_tally += x; | 235 | priv->x_tally += x; |
120 | priv->y_tally += y; | 236 | priv->y_tally += y; |
121 | 237 | ||
122 | if (++priv->count > 100) { | 238 | switch (priv->spew_flag) { |
239 | case NO_SPEW: | ||
240 | /* we're not spewing, but this packet might be the start */ | ||
241 | priv->spew_flag = MAYBE_SPEWING; | ||
242 | |||
243 | /* fall-through */ | ||
244 | |||
245 | case MAYBE_SPEWING: | ||
246 | priv->spew_count++; | ||
247 | |||
248 | if (priv->spew_count < SPEW_WATCH_COUNT) | ||
249 | break; | ||
250 | |||
251 | /* excessive spew detected, request recalibration */ | ||
252 | priv->spew_flag = SPEW_DETECTED; | ||
253 | |||
254 | /* fall-through */ | ||
255 | |||
256 | case SPEW_DETECTED: | ||
257 | /* only recalibrate when the overall delta to the cursor | ||
258 | * is really small. if the spew is causing significant cursor | ||
259 | * movement, it is probably a case of the user moving the | ||
260 | * cursor very slowly across the screen. */ | ||
123 | if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { | 261 | if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { |
124 | hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n", | 262 | hgpk_err(psmouse, "packet spew detected (%d,%d)\n", |
125 | priv->x_tally, priv->y_tally); | 263 | priv->x_tally, priv->y_tally); |
264 | priv->spew_flag = RECALIBRATING; | ||
126 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 265 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
127 | msecs_to_jiffies(spew_delay)); | 266 | msecs_to_jiffies(spew_delay)); |
128 | } | 267 | } |
129 | /* reset every 100 packets */ | 268 | |
130 | priv->count = 0; | 269 | break; |
131 | priv->x_tally = 0; | 270 | case RECALIBRATING: |
132 | priv->y_tally = 0; | 271 | /* we already detected a spew and requested a recalibration, |
272 | * just wait for the queue to kick into action. */ | ||
273 | break; | ||
133 | } | 274 | } |
134 | } | 275 | } |
135 | 276 | ||
@@ -143,25 +284,168 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, | |||
143 | * swr/swl are the left/right buttons. | 284 | * swr/swl are the left/right buttons. |
144 | * x-neg/y-neg are the x and y delta negative bits | 285 | * x-neg/y-neg are the x and y delta negative bits |
145 | * x-over/y-over are the x and y overflow bits | 286 | * x-over/y-over are the x and y overflow bits |
287 | * | ||
288 | * --- | ||
289 | * | ||
290 | * HGPK Advanced Mode - single-mode format | ||
291 | * | ||
292 | * byte 0(PT): 1 1 0 0 1 1 1 1 | ||
293 | * byte 0(GS): 1 1 1 1 1 1 1 1 | ||
294 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 | ||
295 | * byte 2(PT): 0 0 x9 x8 x7 ? pt-dsw 0 | ||
296 | * byte 2(GS): 0 x10 x9 x8 x7 ? gs-dsw pt-dsw | ||
297 | * byte 3: 0 y9 y8 y7 1 0 swr swl | ||
298 | * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 | ||
299 | * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 | ||
300 | * | ||
301 | * ?'s are not defined in the protocol spec, may vary between models. | ||
302 | * | ||
303 | * swr/swl are the left/right buttons. | ||
304 | * | ||
305 | * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a | ||
306 | * pen/finger | ||
146 | */ | 307 | */ |
147 | static int hgpk_validate_byte(unsigned char *packet) | 308 | static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet) |
148 | { | 309 | { |
149 | return (packet[0] & 0x0C) != 0x08; | 310 | struct hgpk_data *priv = psmouse->private; |
311 | int pktcnt = psmouse->pktcnt; | ||
312 | bool valid; | ||
313 | |||
314 | switch (priv->mode) { | ||
315 | case HGPK_MODE_MOUSE: | ||
316 | valid = (packet[0] & 0x0C) == 0x08; | ||
317 | break; | ||
318 | |||
319 | case HGPK_MODE_GLIDESENSOR: | ||
320 | valid = pktcnt == 1 ? | ||
321 | packet[0] == HGPK_GS : !(packet[pktcnt - 1] & 0x80); | ||
322 | break; | ||
323 | |||
324 | case HGPK_MODE_PENTABLET: | ||
325 | valid = pktcnt == 1 ? | ||
326 | packet[0] == HGPK_PT : !(packet[pktcnt - 1] & 0x80); | ||
327 | break; | ||
328 | |||
329 | default: | ||
330 | valid = false; | ||
331 | break; | ||
332 | } | ||
333 | |||
334 | if (!valid) | ||
335 | hgpk_dbg(psmouse, | ||
336 | "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n", | ||
337 | priv->mode, pktcnt, | ||
338 | psmouse->packet[0], psmouse->packet[1], | ||
339 | psmouse->packet[2], psmouse->packet[3], | ||
340 | psmouse->packet[4], psmouse->packet[5]); | ||
341 | |||
342 | return valid; | ||
150 | } | 343 | } |
151 | 344 | ||
152 | static void hgpk_process_packet(struct psmouse *psmouse) | 345 | static void hgpk_process_advanced_packet(struct psmouse *psmouse) |
153 | { | 346 | { |
154 | struct input_dev *dev = psmouse->dev; | 347 | struct hgpk_data *priv = psmouse->private; |
348 | struct input_dev *idev = psmouse->dev; | ||
155 | unsigned char *packet = psmouse->packet; | 349 | unsigned char *packet = psmouse->packet; |
156 | int x, y, left, right; | 350 | int down = !!(packet[2] & 2); |
351 | int left = !!(packet[3] & 1); | ||
352 | int right = !!(packet[3] & 2); | ||
353 | int x = packet[1] | ((packet[2] & 0x78) << 4); | ||
354 | int y = packet[4] | ((packet[3] & 0x70) << 3); | ||
355 | |||
356 | if (priv->mode == HGPK_MODE_GLIDESENSOR) { | ||
357 | int pt_down = !!(packet[2] & 1); | ||
358 | int finger_down = !!(packet[2] & 2); | ||
359 | int z = packet[5]; | ||
360 | |||
361 | input_report_abs(idev, ABS_PRESSURE, z); | ||
362 | if (tpdebug) | ||
363 | hgpk_dbg(psmouse, "pd=%d fd=%d z=%d", | ||
364 | pt_down, finger_down, z); | ||
365 | } else { | ||
366 | /* | ||
367 | * PenTablet mode does not report pressure, so we don't | ||
368 | * report it here | ||
369 | */ | ||
370 | if (tpdebug) | ||
371 | hgpk_dbg(psmouse, "pd=%d ", down); | ||
372 | } | ||
373 | |||
374 | if (tpdebug) | ||
375 | hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); | ||
376 | |||
377 | input_report_key(idev, BTN_TOUCH, down); | ||
378 | input_report_key(idev, BTN_LEFT, left); | ||
379 | input_report_key(idev, BTN_RIGHT, right); | ||
380 | |||
381 | /* | ||
382 | * If this packet says that the finger was removed, reset our position | ||
383 | * tracking so that we don't erroneously detect a jump on next press. | ||
384 | */ | ||
385 | if (!down) { | ||
386 | hgpk_reset_hack_state(psmouse); | ||
387 | goto done; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * Weed out duplicate packets (we get quite a few, and they mess up | ||
392 | * our jump detection) | ||
393 | */ | ||
394 | if (x == priv->abs_x && y == priv->abs_y) { | ||
395 | if (++priv->dupe_count > SPEW_WATCH_COUNT) { | ||
396 | if (tpdebug) | ||
397 | hgpk_dbg(psmouse, "hard spew detected\n"); | ||
398 | priv->spew_flag = RECALIBRATING; | ||
399 | psmouse_queue_work(psmouse, &priv->recalib_wq, | ||
400 | msecs_to_jiffies(spew_delay)); | ||
401 | } | ||
402 | goto done; | ||
403 | } | ||
157 | 404 | ||
158 | left = packet[0] & 1; | 405 | /* not a duplicate, continue with position reporting */ |
159 | right = (packet[0] >> 1) & 1; | 406 | priv->dupe_count = 0; |
407 | |||
408 | /* Don't apply hacks in PT mode, it seems reliable */ | ||
409 | if (priv->mode != HGPK_MODE_PENTABLET && priv->abs_x != -1) { | ||
410 | int x_diff = priv->abs_x - x; | ||
411 | int y_diff = priv->abs_y - y; | ||
412 | if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) { | ||
413 | if (tpdebug) | ||
414 | hgpk_dbg(psmouse, "discarding\n"); | ||
415 | goto done; | ||
416 | } | ||
417 | hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff); | ||
418 | } | ||
160 | 419 | ||
161 | x = packet[1] - ((packet[0] << 4) & 0x100); | 420 | input_report_abs(idev, ABS_X, x); |
162 | y = ((packet[0] << 3) & 0x100) - packet[2]; | 421 | input_report_abs(idev, ABS_Y, y); |
422 | priv->abs_x = x; | ||
423 | priv->abs_y = y; | ||
424 | |||
425 | done: | ||
426 | input_sync(idev); | ||
427 | } | ||
428 | |||
429 | static void hgpk_process_simple_packet(struct psmouse *psmouse) | ||
430 | { | ||
431 | struct input_dev *dev = psmouse->dev; | ||
432 | unsigned char *packet = psmouse->packet; | ||
433 | int left = packet[0] & 1; | ||
434 | int right = (packet[0] >> 1) & 1; | ||
435 | int x = packet[1] - ((packet[0] << 4) & 0x100); | ||
436 | int y = ((packet[0] << 3) & 0x100) - packet[2]; | ||
437 | |||
438 | if (packet[0] & 0xc0) | ||
439 | hgpk_dbg(psmouse, | ||
440 | "overflow -- 0x%02x 0x%02x 0x%02x\n", | ||
441 | packet[0], packet[1], packet[2]); | ||
442 | |||
443 | if (hgpk_discard_decay_hack(psmouse, x, y)) { | ||
444 | if (tpdebug) | ||
445 | hgpk_dbg(psmouse, "discarding\n"); | ||
446 | return; | ||
447 | } | ||
163 | 448 | ||
164 | hgpk_jumpy_hack(psmouse, x, y); | ||
165 | hgpk_spewing_hack(psmouse, left, right, x, y); | 449 | hgpk_spewing_hack(psmouse, left, right, x, y); |
166 | 450 | ||
167 | if (tpdebug) | 451 | if (tpdebug) |
@@ -180,15 +464,14 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) | |||
180 | { | 464 | { |
181 | struct hgpk_data *priv = psmouse->private; | 465 | struct hgpk_data *priv = psmouse->private; |
182 | 466 | ||
183 | if (hgpk_validate_byte(psmouse->packet)) { | 467 | if (!hgpk_is_byte_valid(psmouse, psmouse->packet)) |
184 | hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n", | ||
185 | __func__, psmouse->pktcnt, psmouse->packet[0], | ||
186 | psmouse->packet[1], psmouse->packet[2]); | ||
187 | return PSMOUSE_BAD_DATA; | 468 | return PSMOUSE_BAD_DATA; |
188 | } | ||
189 | 469 | ||
190 | if (psmouse->pktcnt >= psmouse->pktsize) { | 470 | if (psmouse->pktcnt >= psmouse->pktsize) { |
191 | hgpk_process_packet(psmouse); | 471 | if (priv->mode == HGPK_MODE_MOUSE) |
472 | hgpk_process_simple_packet(psmouse); | ||
473 | else | ||
474 | hgpk_process_advanced_packet(psmouse); | ||
192 | return PSMOUSE_FULL_PACKET; | 475 | return PSMOUSE_FULL_PACKET; |
193 | } | 476 | } |
194 | 477 | ||
@@ -210,33 +493,176 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) | |||
210 | return PSMOUSE_GOOD_DATA; | 493 | return PSMOUSE_GOOD_DATA; |
211 | } | 494 | } |
212 | 495 | ||
496 | static int hgpk_select_mode(struct psmouse *psmouse) | ||
497 | { | ||
498 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
499 | struct hgpk_data *priv = psmouse->private; | ||
500 | int i; | ||
501 | int cmd; | ||
502 | |||
503 | /* | ||
504 | * 4 disables to enable advanced mode | ||
505 | * then 3 0xf2 bytes as the preamble for GS/PT selection | ||
506 | */ | ||
507 | const int advanced_init[] = { | ||
508 | PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE, | ||
509 | PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE, | ||
510 | 0xf2, 0xf2, 0xf2, | ||
511 | }; | ||
512 | |||
513 | switch (priv->mode) { | ||
514 | case HGPK_MODE_MOUSE: | ||
515 | psmouse->pktsize = 3; | ||
516 | break; | ||
517 | |||
518 | case HGPK_MODE_GLIDESENSOR: | ||
519 | case HGPK_MODE_PENTABLET: | ||
520 | psmouse->pktsize = 6; | ||
521 | |||
522 | /* Switch to 'Advanced mode.', four disables in a row. */ | ||
523 | for (i = 0; i < ARRAY_SIZE(advanced_init); i++) | ||
524 | if (ps2_command(ps2dev, NULL, advanced_init[i])) | ||
525 | return -EIO; | ||
526 | |||
527 | /* select between GlideSensor (mouse) or PenTablet */ | ||
528 | cmd = priv->mode == HGPK_MODE_GLIDESENSOR ? | ||
529 | PSMOUSE_CMD_SETSCALE11 : PSMOUSE_CMD_SETSCALE21; | ||
530 | |||
531 | if (ps2_command(ps2dev, NULL, cmd)) | ||
532 | return -EIO; | ||
533 | break; | ||
534 | |||
535 | default: | ||
536 | return -EINVAL; | ||
537 | } | ||
538 | |||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | static void hgpk_setup_input_device(struct input_dev *input, | ||
543 | struct input_dev *old_input, | ||
544 | enum hgpk_mode mode) | ||
545 | { | ||
546 | if (old_input) { | ||
547 | input->name = old_input->name; | ||
548 | input->phys = old_input->phys; | ||
549 | input->id = old_input->id; | ||
550 | input->dev.parent = old_input->dev.parent; | ||
551 | } | ||
552 | |||
553 | memset(input->evbit, 0, sizeof(input->evbit)); | ||
554 | memset(input->relbit, 0, sizeof(input->relbit)); | ||
555 | memset(input->keybit, 0, sizeof(input->keybit)); | ||
556 | |||
557 | /* All modes report left and right buttons */ | ||
558 | __set_bit(EV_KEY, input->evbit); | ||
559 | __set_bit(BTN_LEFT, input->keybit); | ||
560 | __set_bit(BTN_RIGHT, input->keybit); | ||
561 | |||
562 | switch (mode) { | ||
563 | case HGPK_MODE_MOUSE: | ||
564 | __set_bit(EV_REL, input->evbit); | ||
565 | __set_bit(REL_X, input->relbit); | ||
566 | __set_bit(REL_Y, input->relbit); | ||
567 | break; | ||
568 | |||
569 | case HGPK_MODE_GLIDESENSOR: | ||
570 | __set_bit(BTN_TOUCH, input->keybit); | ||
571 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
572 | |||
573 | __set_bit(EV_ABS, input->evbit); | ||
574 | |||
575 | /* GlideSensor has pressure sensor, PenTablet does not */ | ||
576 | input_set_abs_params(input, ABS_PRESSURE, 0, 15, 0, 0); | ||
577 | |||
578 | /* From device specs */ | ||
579 | input_set_abs_params(input, ABS_X, 0, 399, 0, 0); | ||
580 | input_set_abs_params(input, ABS_Y, 0, 290, 0, 0); | ||
581 | |||
582 | /* Calculated by hand based on usable size (52mm x 38mm) */ | ||
583 | input_abs_set_res(input, ABS_X, 8); | ||
584 | input_abs_set_res(input, ABS_Y, 8); | ||
585 | break; | ||
586 | |||
587 | case HGPK_MODE_PENTABLET: | ||
588 | __set_bit(BTN_TOUCH, input->keybit); | ||
589 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
590 | |||
591 | __set_bit(EV_ABS, input->evbit); | ||
592 | |||
593 | /* From device specs */ | ||
594 | input_set_abs_params(input, ABS_X, 0, 999, 0, 0); | ||
595 | input_set_abs_params(input, ABS_Y, 5, 239, 0, 0); | ||
596 | |||
597 | /* Calculated by hand based on usable size (156mm x 38mm) */ | ||
598 | input_abs_set_res(input, ABS_X, 6); | ||
599 | input_abs_set_res(input, ABS_Y, 8); | ||
600 | break; | ||
601 | |||
602 | default: | ||
603 | BUG(); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate) | ||
608 | { | ||
609 | int err; | ||
610 | |||
611 | psmouse_reset(psmouse); | ||
612 | |||
613 | if (recalibrate) { | ||
614 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
615 | |||
616 | /* send the recalibrate request */ | ||
617 | if (ps2_command(ps2dev, NULL, 0xf5) || | ||
618 | ps2_command(ps2dev, NULL, 0xf5) || | ||
619 | ps2_command(ps2dev, NULL, 0xe6) || | ||
620 | ps2_command(ps2dev, NULL, 0xf5)) { | ||
621 | return -1; | ||
622 | } | ||
623 | |||
624 | /* according to ALPS, 150mS is required for recalibration */ | ||
625 | msleep(150); | ||
626 | } | ||
627 | |||
628 | err = hgpk_select_mode(psmouse); | ||
629 | if (err) { | ||
630 | hgpk_err(psmouse, "failed to select mode\n"); | ||
631 | return err; | ||
632 | } | ||
633 | |||
634 | hgpk_reset_hack_state(psmouse); | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | |||
213 | static int hgpk_force_recalibrate(struct psmouse *psmouse) | 639 | static int hgpk_force_recalibrate(struct psmouse *psmouse) |
214 | { | 640 | { |
215 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 641 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
216 | struct hgpk_data *priv = psmouse->private; | 642 | struct hgpk_data *priv = psmouse->private; |
643 | int err; | ||
217 | 644 | ||
218 | /* C-series touchpads added the recalibrate command */ | 645 | /* C-series touchpads added the recalibrate command */ |
219 | if (psmouse->model < HGPK_MODEL_C) | 646 | if (psmouse->model < HGPK_MODEL_C) |
220 | return 0; | 647 | return 0; |
221 | 648 | ||
649 | if (!autorecal) { | ||
650 | hgpk_dbg(psmouse, "recalibrations disabled, ignoring\n"); | ||
651 | return 0; | ||
652 | } | ||
653 | |||
654 | hgpk_dbg(psmouse, "recalibrating touchpad..\n"); | ||
655 | |||
222 | /* we don't want to race with the irq handler, nor with resyncs */ | 656 | /* we don't want to race with the irq handler, nor with resyncs */ |
223 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | 657 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
224 | 658 | ||
225 | /* start by resetting the device */ | 659 | /* start by resetting the device */ |
226 | psmouse_reset(psmouse); | 660 | err = hgpk_reset_device(psmouse, true); |
227 | 661 | if (err) | |
228 | /* send the recalibrate request */ | 662 | return err; |
229 | if (ps2_command(ps2dev, NULL, 0xf5) || | ||
230 | ps2_command(ps2dev, NULL, 0xf5) || | ||
231 | ps2_command(ps2dev, NULL, 0xe6) || | ||
232 | ps2_command(ps2dev, NULL, 0xf5)) { | ||
233 | return -1; | ||
234 | } | ||
235 | |||
236 | /* according to ALPS, 150mS is required for recalibration */ | ||
237 | msleep(150); | ||
238 | 663 | ||
239 | /* XXX: If a finger is down during this delay, recalibration will | 664 | /* |
665 | * XXX: If a finger is down during this delay, recalibration will | ||
240 | * detect capacitance incorrectly. This is a hardware bug, and | 666 | * detect capacitance incorrectly. This is a hardware bug, and |
241 | * we don't have a good way to deal with it. The 2s window stuff | 667 | * we don't have a good way to deal with it. The 2s window stuff |
242 | * (below) is our best option for now. | 668 | * (below) is our best option for now. |
@@ -247,25 +673,35 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) | |||
247 | 673 | ||
248 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 674 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
249 | 675 | ||
250 | /* After we recalibrate, we shouldn't get any packets for 2s. If | 676 | if (tpdebug) |
251 | * we do, it's likely that someone's finger was on the touchpad. | 677 | hgpk_dbg(psmouse, "touchpad reactivated\n"); |
252 | * If someone's finger *was* on the touchpad, it's probably | 678 | |
253 | * miscalibrated. So, we should schedule another recalibration | 679 | /* |
680 | * If we get packets right away after recalibrating, it's likely | ||
681 | * that a finger was on the touchpad. If so, it's probably | ||
682 | * miscalibrated, so we optionally schedule another. | ||
254 | */ | 683 | */ |
255 | priv->recalib_window = jiffies + msecs_to_jiffies(recal_guard_time); | 684 | if (recal_guard_time) |
685 | priv->recalib_window = jiffies + | ||
686 | msecs_to_jiffies(recal_guard_time); | ||
256 | 687 | ||
257 | return 0; | 688 | return 0; |
258 | } | 689 | } |
259 | 690 | ||
260 | /* | 691 | /* |
261 | * This kills power to the touchpad; according to ALPS, current consumption | 692 | * This puts the touchpad in a power saving mode; according to ALPS, current |
262 | * goes down to 50uA after running this. To turn power back on, we drive | 693 | * consumption goes down to 50uA after running this. To turn power back on, |
263 | * MS-DAT low. | 694 | * we drive MS-DAT low. Measuring with a 1mA resolution ammeter says that |
695 | * the current on the SUS_3.3V rail drops from 3mA or 4mA to 0 when we do this. | ||
696 | * | ||
697 | * We have no formal spec that details this operation -- the low-power | ||
698 | * sequence came from a long-lost email trail. | ||
264 | */ | 699 | */ |
265 | static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | 700 | static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable) |
266 | { | 701 | { |
267 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 702 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
268 | int timeo; | 703 | int timeo; |
704 | int err; | ||
269 | 705 | ||
270 | /* Added on D-series touchpads */ | 706 | /* Added on D-series touchpads */ |
271 | if (psmouse->model < HGPK_MODEL_D) | 707 | if (psmouse->model < HGPK_MODEL_D) |
@@ -279,24 +715,27 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | |||
279 | * the controller. Once we get an ACK back from it, it | 715 | * the controller. Once we get an ACK back from it, it |
280 | * means we can continue with the touchpad re-init. ALPS | 716 | * means we can continue with the touchpad re-init. ALPS |
281 | * tells us that 1s should be long enough, so set that as | 717 | * tells us that 1s should be long enough, so set that as |
282 | * the upper bound. | 718 | * the upper bound. (in practice, it takes about 3 loops.) |
283 | */ | 719 | */ |
284 | for (timeo = 20; timeo > 0; timeo--) { | 720 | for (timeo = 20; timeo > 0; timeo--) { |
285 | if (!ps2_sendbyte(&psmouse->ps2dev, | 721 | if (!ps2_sendbyte(&psmouse->ps2dev, |
286 | PSMOUSE_CMD_DISABLE, 20)) | 722 | PSMOUSE_CMD_DISABLE, 20)) |
287 | break; | 723 | break; |
288 | msleep(50); | 724 | msleep(25); |
289 | } | 725 | } |
290 | 726 | ||
291 | psmouse_reset(psmouse); | 727 | err = hgpk_reset_device(psmouse, false); |
728 | if (err) { | ||
729 | hgpk_err(psmouse, "Failed to reset device!\n"); | ||
730 | return err; | ||
731 | } | ||
292 | 732 | ||
293 | /* should be all set, enable the touchpad */ | 733 | /* should be all set, enable the touchpad */ |
294 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); | 734 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
295 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 735 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
296 | 736 | hgpk_dbg(psmouse, "Touchpad powered up.\n"); | |
297 | } else { | 737 | } else { |
298 | hgpk_dbg(psmouse, "Powering off touchpad.\n"); | 738 | hgpk_dbg(psmouse, "Powering off touchpad.\n"); |
299 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
300 | 739 | ||
301 | if (ps2_command(ps2dev, NULL, 0xec) || | 740 | if (ps2_command(ps2dev, NULL, 0xec) || |
302 | ps2_command(ps2dev, NULL, 0xec) || | 741 | ps2_command(ps2dev, NULL, 0xec) || |
@@ -304,6 +743,8 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | |||
304 | return -1; | 743 | return -1; |
305 | } | 744 | } |
306 | 745 | ||
746 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
747 | |||
307 | /* probably won't see an ACK, the touchpad will be off */ | 748 | /* probably won't see an ACK, the touchpad will be off */ |
308 | ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); | 749 | ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); |
309 | } | 750 | } |
@@ -319,17 +760,20 @@ static int hgpk_poll(struct psmouse *psmouse) | |||
319 | 760 | ||
320 | static int hgpk_reconnect(struct psmouse *psmouse) | 761 | static int hgpk_reconnect(struct psmouse *psmouse) |
321 | { | 762 | { |
322 | /* During suspend/resume the ps2 rails remain powered. We don't want | 763 | struct hgpk_data *priv = psmouse->private; |
764 | |||
765 | /* | ||
766 | * During suspend/resume the ps2 rails remain powered. We don't want | ||
323 | * to do a reset because it's flush data out of buffers; however, | 767 | * to do a reset because it's flush data out of buffers; however, |
324 | * earlier prototypes (B1) had some brokenness that required a reset. */ | 768 | * earlier prototypes (B1) had some brokenness that required a reset. |
769 | */ | ||
325 | if (olpc_board_at_least(olpc_board(0xb2))) | 770 | if (olpc_board_at_least(olpc_board(0xb2))) |
326 | if (psmouse->ps2dev.serio->dev.power.power_state.event != | 771 | if (psmouse->ps2dev.serio->dev.power.power_state.event != |
327 | PM_EVENT_ON) | 772 | PM_EVENT_ON) |
328 | return 0; | 773 | return 0; |
329 | 774 | ||
330 | psmouse_reset(psmouse); | 775 | priv->powered = 1; |
331 | 776 | return hgpk_reset_device(psmouse, false); | |
332 | return 0; | ||
333 | } | 777 | } |
334 | 778 | ||
335 | static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf) | 779 | static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf) |
@@ -355,7 +799,7 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, | |||
355 | * hgpk_toggle_power will deal w/ state so | 799 | * hgpk_toggle_power will deal w/ state so |
356 | * we're not racing w/ irq | 800 | * we're not racing w/ irq |
357 | */ | 801 | */ |
358 | err = hgpk_toggle_power(psmouse, value); | 802 | err = hgpk_toggle_powersave(psmouse, value); |
359 | if (!err) | 803 | if (!err) |
360 | priv->powered = value; | 804 | priv->powered = value; |
361 | } | 805 | } |
@@ -366,6 +810,65 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, | |||
366 | __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, | 810 | __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, |
367 | hgpk_show_powered, hgpk_set_powered, false); | 811 | hgpk_show_powered, hgpk_set_powered, false); |
368 | 812 | ||
813 | static ssize_t attr_show_mode(struct psmouse *psmouse, void *data, char *buf) | ||
814 | { | ||
815 | struct hgpk_data *priv = psmouse->private; | ||
816 | |||
817 | return sprintf(buf, "%s\n", hgpk_mode_names[priv->mode]); | ||
818 | } | ||
819 | |||
820 | static ssize_t attr_set_mode(struct psmouse *psmouse, void *data, | ||
821 | const char *buf, size_t len) | ||
822 | { | ||
823 | struct hgpk_data *priv = psmouse->private; | ||
824 | enum hgpk_mode old_mode = priv->mode; | ||
825 | enum hgpk_mode new_mode = hgpk_mode_from_name(buf, len); | ||
826 | struct input_dev *old_dev = psmouse->dev; | ||
827 | struct input_dev *new_dev; | ||
828 | int err; | ||
829 | |||
830 | if (new_mode == HGPK_MODE_INVALID) | ||
831 | return -EINVAL; | ||
832 | |||
833 | if (old_mode == new_mode) | ||
834 | return len; | ||
835 | |||
836 | new_dev = input_allocate_device(); | ||
837 | if (!new_dev) | ||
838 | return -ENOMEM; | ||
839 | |||
840 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | ||
841 | |||
842 | /* Switch device into the new mode */ | ||
843 | priv->mode = new_mode; | ||
844 | err = hgpk_reset_device(psmouse, false); | ||
845 | if (err) | ||
846 | goto err_try_restore; | ||
847 | |||
848 | hgpk_setup_input_device(new_dev, old_dev, new_mode); | ||
849 | |||
850 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
851 | |||
852 | err = input_register_device(new_dev); | ||
853 | if (err) | ||
854 | goto err_try_restore; | ||
855 | |||
856 | psmouse->dev = new_dev; | ||
857 | input_unregister_device(old_dev); | ||
858 | |||
859 | return len; | ||
860 | |||
861 | err_try_restore: | ||
862 | input_free_device(new_dev); | ||
863 | priv->mode = old_mode; | ||
864 | hgpk_reset_device(psmouse, false); | ||
865 | |||
866 | return err; | ||
867 | } | ||
868 | |||
869 | PSMOUSE_DEFINE_ATTR(hgpk_mode, S_IWUSR | S_IRUGO, NULL, | ||
870 | attr_show_mode, attr_set_mode); | ||
871 | |||
369 | static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse, | 872 | static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse, |
370 | void *data, char *buf) | 873 | void *data, char *buf) |
371 | { | 874 | { |
@@ -401,6 +904,8 @@ static void hgpk_disconnect(struct psmouse *psmouse) | |||
401 | 904 | ||
402 | device_remove_file(&psmouse->ps2dev.serio->dev, | 905 | device_remove_file(&psmouse->ps2dev.serio->dev, |
403 | &psmouse_attr_powered.dattr); | 906 | &psmouse_attr_powered.dattr); |
907 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
908 | &psmouse_attr_hgpk_mode.dattr); | ||
404 | 909 | ||
405 | if (psmouse->model >= HGPK_MODEL_C) | 910 | if (psmouse->model >= HGPK_MODEL_C) |
406 | device_remove_file(&psmouse->ps2dev.serio->dev, | 911 | device_remove_file(&psmouse->ps2dev.serio->dev, |
@@ -416,14 +921,13 @@ static void hgpk_recalib_work(struct work_struct *work) | |||
416 | struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); | 921 | struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); |
417 | struct psmouse *psmouse = priv->psmouse; | 922 | struct psmouse *psmouse = priv->psmouse; |
418 | 923 | ||
419 | hgpk_dbg(psmouse, "recalibrating touchpad..\n"); | ||
420 | |||
421 | if (hgpk_force_recalibrate(psmouse)) | 924 | if (hgpk_force_recalibrate(psmouse)) |
422 | hgpk_err(psmouse, "recalibration failed!\n"); | 925 | hgpk_err(psmouse, "recalibration failed!\n"); |
423 | } | 926 | } |
424 | 927 | ||
425 | static int hgpk_register(struct psmouse *psmouse) | 928 | static int hgpk_register(struct psmouse *psmouse) |
426 | { | 929 | { |
930 | struct hgpk_data *priv = psmouse->private; | ||
427 | int err; | 931 | int err; |
428 | 932 | ||
429 | /* register handlers */ | 933 | /* register handlers */ |
@@ -431,13 +935,14 @@ static int hgpk_register(struct psmouse *psmouse) | |||
431 | psmouse->poll = hgpk_poll; | 935 | psmouse->poll = hgpk_poll; |
432 | psmouse->disconnect = hgpk_disconnect; | 936 | psmouse->disconnect = hgpk_disconnect; |
433 | psmouse->reconnect = hgpk_reconnect; | 937 | psmouse->reconnect = hgpk_reconnect; |
434 | psmouse->pktsize = 3; | ||
435 | 938 | ||
436 | /* Disable the idle resync. */ | 939 | /* Disable the idle resync. */ |
437 | psmouse->resync_time = 0; | 940 | psmouse->resync_time = 0; |
438 | /* Reset after a lot of bad bytes. */ | 941 | /* Reset after a lot of bad bytes. */ |
439 | psmouse->resetafter = 1024; | 942 | psmouse->resetafter = 1024; |
440 | 943 | ||
944 | hgpk_setup_input_device(psmouse->dev, NULL, priv->mode); | ||
945 | |||
441 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 946 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
442 | &psmouse_attr_powered.dattr); | 947 | &psmouse_attr_powered.dattr); |
443 | if (err) { | 948 | if (err) { |
@@ -445,6 +950,13 @@ static int hgpk_register(struct psmouse *psmouse) | |||
445 | return err; | 950 | return err; |
446 | } | 951 | } |
447 | 952 | ||
953 | err = device_create_file(&psmouse->ps2dev.serio->dev, | ||
954 | &psmouse_attr_hgpk_mode.dattr); | ||
955 | if (err) { | ||
956 | hgpk_err(psmouse, "Failed creating 'hgpk_mode' sysfs node\n"); | ||
957 | goto err_remove_powered; | ||
958 | } | ||
959 | |||
448 | /* C-series touchpads added the recalibrate command */ | 960 | /* C-series touchpads added the recalibrate command */ |
449 | if (psmouse->model >= HGPK_MODEL_C) { | 961 | if (psmouse->model >= HGPK_MODEL_C) { |
450 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 962 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
@@ -452,30 +964,40 @@ static int hgpk_register(struct psmouse *psmouse) | |||
452 | if (err) { | 964 | if (err) { |
453 | hgpk_err(psmouse, | 965 | hgpk_err(psmouse, |
454 | "Failed creating 'recalibrate' sysfs node\n"); | 966 | "Failed creating 'recalibrate' sysfs node\n"); |
455 | device_remove_file(&psmouse->ps2dev.serio->dev, | 967 | goto err_remove_mode; |
456 | &psmouse_attr_powered.dattr); | ||
457 | return err; | ||
458 | } | 968 | } |
459 | } | 969 | } |
460 | 970 | ||
461 | return 0; | 971 | return 0; |
972 | |||
973 | err_remove_mode: | ||
974 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
975 | &psmouse_attr_hgpk_mode.dattr); | ||
976 | err_remove_powered: | ||
977 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
978 | &psmouse_attr_powered.dattr); | ||
979 | return err; | ||
462 | } | 980 | } |
463 | 981 | ||
464 | int hgpk_init(struct psmouse *psmouse) | 982 | int hgpk_init(struct psmouse *psmouse) |
465 | { | 983 | { |
466 | struct hgpk_data *priv; | 984 | struct hgpk_data *priv; |
467 | int err = -ENOMEM; | 985 | int err; |
468 | 986 | ||
469 | priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL); | 987 | priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL); |
470 | if (!priv) | 988 | if (!priv) { |
989 | err = -ENOMEM; | ||
471 | goto alloc_fail; | 990 | goto alloc_fail; |
991 | } | ||
472 | 992 | ||
473 | psmouse->private = priv; | 993 | psmouse->private = priv; |
994 | |||
474 | priv->psmouse = psmouse; | 995 | priv->psmouse = psmouse; |
475 | priv->powered = true; | 996 | priv->powered = true; |
997 | priv->mode = hgpk_default_mode; | ||
476 | INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); | 998 | INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); |
477 | 999 | ||
478 | err = psmouse_reset(psmouse); | 1000 | err = hgpk_reset_device(psmouse, false); |
479 | if (err) | 1001 | if (err) |
480 | goto init_fail; | 1002 | goto init_fail; |
481 | 1003 | ||
@@ -531,3 +1053,14 @@ int hgpk_detect(struct psmouse *psmouse, bool set_properties) | |||
531 | 1053 | ||
532 | return 0; | 1054 | return 0; |
533 | } | 1055 | } |
1056 | |||
1057 | void hgpk_module_init(void) | ||
1058 | { | ||
1059 | hgpk_default_mode = hgpk_mode_from_name(hgpk_mode_name, | ||
1060 | strlen(hgpk_mode_name)); | ||
1061 | if (hgpk_default_mode == HGPK_MODE_INVALID) { | ||
1062 | hgpk_default_mode = HGPK_MODE_MOUSE; | ||
1063 | strlcpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE], | ||
1064 | sizeof(hgpk_mode_name)); | ||
1065 | } | ||
1066 | } | ||
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h index d61cfd3ee9cb..311c0e87fcbf 100644 --- a/drivers/input/mouse/hgpk.h +++ b/drivers/input/mouse/hgpk.h | |||
@@ -5,6 +5,9 @@ | |||
5 | #ifndef _HGPK_H | 5 | #ifndef _HGPK_H |
6 | #define _HGPK_H | 6 | #define _HGPK_H |
7 | 7 | ||
8 | #define HGPK_GS 0xff /* The GlideSensor */ | ||
9 | #define HGPK_PT 0xcf /* The PenTablet */ | ||
10 | |||
8 | enum hgpk_model_t { | 11 | enum hgpk_model_t { |
9 | HGPK_MODEL_PREA = 0x0a, /* pre-B1s */ | 12 | HGPK_MODEL_PREA = 0x0a, /* pre-B1s */ |
10 | HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */ | 13 | HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */ |
@@ -13,12 +16,34 @@ enum hgpk_model_t { | |||
13 | HGPK_MODEL_D = 0x50, /* C1, mass production */ | 16 | HGPK_MODEL_D = 0x50, /* C1, mass production */ |
14 | }; | 17 | }; |
15 | 18 | ||
19 | enum hgpk_spew_flag { | ||
20 | NO_SPEW, | ||
21 | MAYBE_SPEWING, | ||
22 | SPEW_DETECTED, | ||
23 | RECALIBRATING, | ||
24 | }; | ||
25 | |||
26 | #define SPEW_WATCH_COUNT 42 /* at 12ms/packet, this is 1/2 second */ | ||
27 | |||
28 | enum hgpk_mode { | ||
29 | HGPK_MODE_MOUSE, | ||
30 | HGPK_MODE_GLIDESENSOR, | ||
31 | HGPK_MODE_PENTABLET, | ||
32 | HGPK_MODE_INVALID | ||
33 | }; | ||
34 | |||
16 | struct hgpk_data { | 35 | struct hgpk_data { |
17 | struct psmouse *psmouse; | 36 | struct psmouse *psmouse; |
37 | enum hgpk_mode mode; | ||
18 | bool powered; | 38 | bool powered; |
19 | int count, x_tally, y_tally; /* hardware workaround stuff */ | 39 | enum hgpk_spew_flag spew_flag; |
40 | int spew_count, x_tally, y_tally; /* spew detection */ | ||
20 | unsigned long recalib_window; | 41 | unsigned long recalib_window; |
21 | struct delayed_work recalib_wq; | 42 | struct delayed_work recalib_wq; |
43 | int abs_x, abs_y; | ||
44 | int dupe_count; | ||
45 | int xbigj, ybigj, xlast, ylast; /* jumpiness detection */ | ||
46 | int xsaw_secondary, ysaw_secondary; /* jumpiness detection */ | ||
22 | }; | 47 | }; |
23 | 48 | ||
24 | #define hgpk_dbg(psmouse, format, arg...) \ | 49 | #define hgpk_dbg(psmouse, format, arg...) \ |
@@ -33,9 +58,13 @@ struct hgpk_data { | |||
33 | dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) | 58 | dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) |
34 | 59 | ||
35 | #ifdef CONFIG_MOUSE_PS2_OLPC | 60 | #ifdef CONFIG_MOUSE_PS2_OLPC |
61 | void hgpk_module_init(void); | ||
36 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); | 62 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); |
37 | int hgpk_init(struct psmouse *psmouse); | 63 | int hgpk_init(struct psmouse *psmouse); |
38 | #else | 64 | #else |
65 | static inline void hgpk_module_init(void) | ||
66 | { | ||
67 | } | ||
39 | static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties) | 68 | static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties) |
40 | { | 69 | { |
41 | return -ENODEV; | 70 | return -ENODEV; |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 73a7af2542a8..3f74baee102b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -1584,10 +1584,10 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1584 | if (!new_dev) | 1584 | if (!new_dev) |
1585 | return -ENOMEM; | 1585 | return -ENOMEM; |
1586 | 1586 | ||
1587 | while (serio->child) { | 1587 | while (!list_empty(&serio->children)) { |
1588 | if (++retry > 3) { | 1588 | if (++retry > 3) { |
1589 | printk(KERN_WARNING | 1589 | printk(KERN_WARNING |
1590 | "psmouse: failed to destroy child port, " | 1590 | "psmouse: failed to destroy children ports, " |
1591 | "protocol change aborted.\n"); | 1591 | "protocol change aborted.\n"); |
1592 | input_free_device(new_dev); | 1592 | input_free_device(new_dev); |
1593 | return -EIO; | 1593 | return -EIO; |
@@ -1711,6 +1711,7 @@ static int __init psmouse_init(void) | |||
1711 | 1711 | ||
1712 | lifebook_module_init(); | 1712 | lifebook_module_init(); |
1713 | synaptics_module_init(); | 1713 | synaptics_module_init(); |
1714 | hgpk_module_init(); | ||
1714 | 1715 | ||
1715 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); | 1716 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); |
1716 | if (!kpsmoused_wq) { | 1717 | if (!kpsmoused_wq) { |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 96b70a43515f..e06e045bf907 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/dmi.h> | 27 | #include <linux/dmi.h> |
28 | #include <linux/input.h> | 28 | #include <linux/input/mt.h> |
29 | #include <linux/serio.h> | 29 | #include <linux/serio.h> |
30 | #include <linux/libps2.h> | 30 | #include <linux/libps2.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
@@ -279,6 +279,25 @@ static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate) | |||
279 | synaptics_mode_cmd(psmouse, priv->mode); | 279 | synaptics_mode_cmd(psmouse, priv->mode); |
280 | } | 280 | } |
281 | 281 | ||
282 | static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) | ||
283 | { | ||
284 | static unsigned char param = 0xc8; | ||
285 | struct synaptics_data *priv = psmouse->private; | ||
286 | |||
287 | if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | ||
288 | return 0; | ||
289 | |||
290 | if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) | ||
291 | return -1; | ||
292 | if (ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE)) | ||
293 | return -1; | ||
294 | |||
295 | /* Advanced gesture mode also sends multi finger data */ | ||
296 | priv->capabilities |= BIT(1); | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
282 | /***************************************************************************** | 301 | /***************************************************************************** |
283 | * Synaptics pass-through PS/2 port support | 302 | * Synaptics pass-through PS/2 port support |
284 | ****************************************************************************/ | 303 | ****************************************************************************/ |
@@ -294,7 +313,29 @@ static int synaptics_pt_write(struct serio *serio, unsigned char c) | |||
294 | return 0; | 313 | return 0; |
295 | } | 314 | } |
296 | 315 | ||
297 | static inline int synaptics_is_pt_packet(unsigned char *buf) | 316 | static int synaptics_pt_start(struct serio *serio) |
317 | { | ||
318 | struct psmouse *parent = serio_get_drvdata(serio->parent); | ||
319 | struct synaptics_data *priv = parent->private; | ||
320 | |||
321 | serio_pause_rx(parent->ps2dev.serio); | ||
322 | priv->pt_port = serio; | ||
323 | serio_continue_rx(parent->ps2dev.serio); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static void synaptics_pt_stop(struct serio *serio) | ||
329 | { | ||
330 | struct psmouse *parent = serio_get_drvdata(serio->parent); | ||
331 | struct synaptics_data *priv = parent->private; | ||
332 | |||
333 | serio_pause_rx(parent->ps2dev.serio); | ||
334 | priv->pt_port = NULL; | ||
335 | serio_continue_rx(parent->ps2dev.serio); | ||
336 | } | ||
337 | |||
338 | static int synaptics_is_pt_packet(unsigned char *buf) | ||
298 | { | 339 | { |
299 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; | 340 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; |
300 | } | 341 | } |
@@ -315,9 +356,8 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet | |||
315 | 356 | ||
316 | static void synaptics_pt_activate(struct psmouse *psmouse) | 357 | static void synaptics_pt_activate(struct psmouse *psmouse) |
317 | { | 358 | { |
318 | struct serio *ptport = psmouse->ps2dev.serio->child; | ||
319 | struct psmouse *child = serio_get_drvdata(ptport); | ||
320 | struct synaptics_data *priv = psmouse->private; | 359 | struct synaptics_data *priv = psmouse->private; |
360 | struct psmouse *child = serio_get_drvdata(priv->pt_port); | ||
321 | 361 | ||
322 | /* adjust the touchpad to child's choice of protocol */ | 362 | /* adjust the touchpad to child's choice of protocol */ |
323 | if (child) { | 363 | if (child) { |
@@ -345,6 +385,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
345 | strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); | 385 | strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); |
346 | strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); | 386 | strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); |
347 | serio->write = synaptics_pt_write; | 387 | serio->write = synaptics_pt_write; |
388 | serio->start = synaptics_pt_start; | ||
389 | serio->stop = synaptics_pt_stop; | ||
348 | serio->parent = psmouse->ps2dev.serio; | 390 | serio->parent = psmouse->ps2dev.serio; |
349 | 391 | ||
350 | psmouse->pt_activate = synaptics_pt_activate; | 392 | psmouse->pt_activate = synaptics_pt_activate; |
@@ -357,7 +399,9 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
357 | * Functions to interpret the absolute mode packets | 399 | * Functions to interpret the absolute mode packets |
358 | ****************************************************************************/ | 400 | ****************************************************************************/ |
359 | 401 | ||
360 | static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw) | 402 | static int synaptics_parse_hw_state(const unsigned char buf[], |
403 | struct synaptics_data *priv, | ||
404 | struct synaptics_hw_state *hw) | ||
361 | { | 405 | { |
362 | memset(hw, 0, sizeof(struct synaptics_hw_state)); | 406 | memset(hw, 0, sizeof(struct synaptics_hw_state)); |
363 | 407 | ||
@@ -374,6 +418,14 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data | |||
374 | ((buf[0] & 0x04) >> 1) | | 418 | ((buf[0] & 0x04) >> 1) | |
375 | ((buf[3] & 0x04) >> 2)); | 419 | ((buf[3] & 0x04) >> 2)); |
376 | 420 | ||
421 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { | ||
422 | /* Gesture packet: (x, y, z) at half resolution */ | ||
423 | priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | ||
424 | priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | ||
425 | priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
426 | return 1; | ||
427 | } | ||
428 | |||
377 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 429 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
378 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 430 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
379 | 431 | ||
@@ -429,6 +481,36 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data | |||
429 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 481 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
430 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 482 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
431 | } | 483 | } |
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y) | ||
489 | { | ||
490 | input_mt_slot(dev, slot); | ||
491 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | ||
492 | if (active) { | ||
493 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
494 | input_report_abs(dev, ABS_MT_POSITION_Y, | ||
495 | YMAX_NOMINAL + YMIN_NOMINAL - y); | ||
496 | } | ||
497 | } | ||
498 | |||
499 | static void synaptics_report_semi_mt_data(struct input_dev *dev, | ||
500 | const struct synaptics_hw_state *a, | ||
501 | const struct synaptics_hw_state *b, | ||
502 | int num_fingers) | ||
503 | { | ||
504 | if (num_fingers >= 2) { | ||
505 | set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y)); | ||
506 | set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y)); | ||
507 | } else if (num_fingers == 1) { | ||
508 | set_slot(dev, 0, true, a->x, a->y); | ||
509 | set_slot(dev, 1, false, 0, 0); | ||
510 | } else { | ||
511 | set_slot(dev, 0, false, 0, 0); | ||
512 | set_slot(dev, 1, false, 0, 0); | ||
513 | } | ||
432 | } | 514 | } |
433 | 515 | ||
434 | /* | 516 | /* |
@@ -443,7 +525,8 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
443 | int finger_width; | 525 | int finger_width; |
444 | int i; | 526 | int i; |
445 | 527 | ||
446 | synaptics_parse_hw_state(psmouse->packet, priv, &hw); | 528 | if (synaptics_parse_hw_state(psmouse->packet, priv, &hw)) |
529 | return; | ||
447 | 530 | ||
448 | if (hw.scroll) { | 531 | if (hw.scroll) { |
449 | priv->scroll += hw.scroll; | 532 | priv->scroll += hw.scroll; |
@@ -465,7 +548,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
465 | return; | 548 | return; |
466 | } | 549 | } |
467 | 550 | ||
468 | if (hw.z > 0) { | 551 | if (hw.z > 0 && hw.x > 1) { |
469 | num_fingers = 1; | 552 | num_fingers = 1; |
470 | finger_width = 5; | 553 | finger_width = 5; |
471 | if (SYN_CAP_EXTENDED(priv->capabilities)) { | 554 | if (SYN_CAP_EXTENDED(priv->capabilities)) { |
@@ -489,6 +572,9 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
489 | finger_width = 0; | 572 | finger_width = 0; |
490 | } | 573 | } |
491 | 574 | ||
575 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | ||
576 | synaptics_report_semi_mt_data(dev, &hw, &priv->mt, num_fingers); | ||
577 | |||
492 | /* Post events | 578 | /* Post events |
493 | * BTN_TOUCH has to be first as mousedev relies on it when doing | 579 | * BTN_TOUCH has to be first as mousedev relies on it when doing |
494 | * absolute -> relative conversion | 580 | * absolute -> relative conversion |
@@ -496,7 +582,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
496 | if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1); | 582 | if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1); |
497 | if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0); | 583 | if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0); |
498 | 584 | ||
499 | if (hw.z > 0) { | 585 | if (num_fingers > 0) { |
500 | input_report_abs(dev, ABS_X, hw.x); | 586 | input_report_abs(dev, ABS_X, hw.x); |
501 | input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y); | 587 | input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y); |
502 | } | 588 | } |
@@ -578,9 +664,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
578 | if (unlikely(priv->pkt_type == SYN_NEWABS)) | 664 | if (unlikely(priv->pkt_type == SYN_NEWABS)) |
579 | priv->pkt_type = synaptics_detect_pkt_type(psmouse); | 665 | priv->pkt_type = synaptics_detect_pkt_type(psmouse); |
580 | 666 | ||
581 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) { | 667 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && |
582 | if (psmouse->ps2dev.serio->child) | 668 | synaptics_is_pt_packet(psmouse->packet)) { |
583 | synaptics_pass_pt_packet(psmouse->ps2dev.serio->child, psmouse->packet); | 669 | if (priv->pt_port) |
670 | synaptics_pass_pt_packet(priv->pt_port, psmouse->packet); | ||
584 | } else | 671 | } else |
585 | synaptics_process_packet(psmouse); | 672 | synaptics_process_packet(psmouse); |
586 | 673 | ||
@@ -598,6 +685,8 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
598 | { | 685 | { |
599 | int i; | 686 | int i; |
600 | 687 | ||
688 | __set_bit(INPUT_PROP_POINTER, dev->propbit); | ||
689 | |||
601 | __set_bit(EV_ABS, dev->evbit); | 690 | __set_bit(EV_ABS, dev->evbit); |
602 | input_set_abs_params(dev, ABS_X, | 691 | input_set_abs_params(dev, ABS_X, |
603 | XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); | 692 | XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); |
@@ -605,6 +694,15 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
605 | YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); | 694 | YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); |
606 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 695 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
607 | 696 | ||
697 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | ||
698 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | ||
699 | input_mt_init_slots(dev, 2); | ||
700 | input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL, | ||
701 | priv->x_max ?: XMAX_NOMINAL, 0, 0); | ||
702 | input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL, | ||
703 | priv->y_max ?: YMAX_NOMINAL, 0, 0); | ||
704 | } | ||
705 | |||
608 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | 706 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
609 | input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); | 707 | input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); |
610 | 708 | ||
@@ -639,6 +737,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
639 | input_abs_set_res(dev, ABS_Y, priv->y_res); | 737 | input_abs_set_res(dev, ABS_Y, priv->y_res); |
640 | 738 | ||
641 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 739 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
740 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); | ||
642 | /* Clickpads report only left button */ | 741 | /* Clickpads report only left button */ |
643 | __clear_bit(BTN_RIGHT, dev->keybit); | 742 | __clear_bit(BTN_RIGHT, dev->keybit); |
644 | __clear_bit(BTN_MIDDLE, dev->keybit); | 743 | __clear_bit(BTN_MIDDLE, dev->keybit); |
@@ -656,25 +755,46 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
656 | { | 755 | { |
657 | struct synaptics_data *priv = psmouse->private; | 756 | struct synaptics_data *priv = psmouse->private; |
658 | struct synaptics_data old_priv = *priv; | 757 | struct synaptics_data old_priv = *priv; |
758 | int retry = 0; | ||
759 | int error; | ||
659 | 760 | ||
660 | psmouse_reset(psmouse); | 761 | do { |
762 | psmouse_reset(psmouse); | ||
763 | error = synaptics_detect(psmouse, 0); | ||
764 | } while (error && ++retry < 3); | ||
661 | 765 | ||
662 | if (synaptics_detect(psmouse, 0)) | 766 | if (error) |
663 | return -1; | 767 | return -1; |
664 | 768 | ||
769 | if (retry > 1) | ||
770 | printk(KERN_DEBUG "Synaptics reconnected after %d tries\n", | ||
771 | retry); | ||
772 | |||
665 | if (synaptics_query_hardware(psmouse)) { | 773 | if (synaptics_query_hardware(psmouse)) { |
666 | printk(KERN_ERR "Unable to query Synaptics hardware.\n"); | 774 | printk(KERN_ERR "Unable to query Synaptics hardware.\n"); |
667 | return -1; | 775 | return -1; |
668 | } | 776 | } |
669 | 777 | ||
778 | if (synaptics_set_absolute_mode(psmouse)) { | ||
779 | printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); | ||
780 | return -1; | ||
781 | } | ||
782 | |||
783 | if (synaptics_set_advanced_gesture_mode(psmouse)) { | ||
784 | printk(KERN_ERR "Advanced gesture mode reconnect failed.\n"); | ||
785 | return -1; | ||
786 | } | ||
787 | |||
670 | if (old_priv.identity != priv->identity || | 788 | if (old_priv.identity != priv->identity || |
671 | old_priv.model_id != priv->model_id || | 789 | old_priv.model_id != priv->model_id || |
672 | old_priv.capabilities != priv->capabilities || | 790 | old_priv.capabilities != priv->capabilities || |
673 | old_priv.ext_cap != priv->ext_cap) | 791 | old_priv.ext_cap != priv->ext_cap) { |
674 | return -1; | 792 | printk(KERN_ERR "Synaptics hardware appears to be different: " |
675 | 793 | "id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n", | |
676 | if (synaptics_set_absolute_mode(psmouse)) { | 794 | old_priv.identity, priv->identity, |
677 | printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); | 795 | old_priv.model_id, priv->model_id, |
796 | old_priv.capabilities, priv->capabilities, | ||
797 | old_priv.ext_cap, priv->ext_cap); | ||
678 | return -1; | 798 | return -1; |
679 | } | 799 | } |
680 | 800 | ||
@@ -716,22 +836,52 @@ static const struct dmi_system_id __initconst toshiba_dmi_table[] = { | |||
716 | }, | 836 | }, |
717 | 837 | ||
718 | }, | 838 | }, |
839 | #endif | ||
719 | { } | 840 | { } |
841 | }; | ||
842 | |||
843 | static bool broken_olpc_ec; | ||
844 | |||
845 | static const struct dmi_system_id __initconst olpc_dmi_table[] = { | ||
846 | #if defined(CONFIG_DMI) && defined(CONFIG_OLPC) | ||
847 | { | ||
848 | /* OLPC XO-1 or XO-1.5 */ | ||
849 | .matches = { | ||
850 | DMI_MATCH(DMI_SYS_VENDOR, "OLPC"), | ||
851 | DMI_MATCH(DMI_PRODUCT_NAME, "XO"), | ||
852 | }, | ||
853 | }, | ||
720 | #endif | 854 | #endif |
855 | { } | ||
721 | }; | 856 | }; |
722 | 857 | ||
723 | void __init synaptics_module_init(void) | 858 | void __init synaptics_module_init(void) |
724 | { | 859 | { |
725 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | 860 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); |
861 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); | ||
726 | } | 862 | } |
727 | 863 | ||
728 | int synaptics_init(struct psmouse *psmouse) | 864 | int synaptics_init(struct psmouse *psmouse) |
729 | { | 865 | { |
730 | struct synaptics_data *priv; | 866 | struct synaptics_data *priv; |
731 | 867 | ||
868 | /* | ||
869 | * The OLPC XO has issues with Synaptics' absolute mode; similarly to | ||
870 | * the HGPK, it quickly degrades and the hardware becomes jumpy and | ||
871 | * overly sensitive. Not only that, but the constant packet spew | ||
872 | * (even at a lowered 40pps rate) overloads the EC such that key | ||
873 | * presses on the keyboard are missed. Given all of that, don't | ||
874 | * even attempt to use Synaptics mode. Relative mode seems to work | ||
875 | * just fine. | ||
876 | */ | ||
877 | if (broken_olpc_ec) { | ||
878 | printk(KERN_INFO "synaptics: OLPC XO detected, not enabling Synaptics protocol.\n"); | ||
879 | return -ENODEV; | ||
880 | } | ||
881 | |||
732 | psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); | 882 | psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); |
733 | if (!priv) | 883 | if (!priv) |
734 | return -1; | 884 | return -ENOMEM; |
735 | 885 | ||
736 | psmouse_reset(psmouse); | 886 | psmouse_reset(psmouse); |
737 | 887 | ||
@@ -745,6 +895,11 @@ int synaptics_init(struct psmouse *psmouse) | |||
745 | goto init_fail; | 895 | goto init_fail; |
746 | } | 896 | } |
747 | 897 | ||
898 | if (synaptics_set_advanced_gesture_mode(psmouse)) { | ||
899 | printk(KERN_ERR "Advanced gesture mode init failed.\n"); | ||
900 | goto init_fail; | ||
901 | } | ||
902 | |||
748 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 903 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
749 | 904 | ||
750 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", | 905 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", |
@@ -778,8 +933,8 @@ int synaptics_init(struct psmouse *psmouse) | |||
778 | 933 | ||
779 | /* | 934 | /* |
780 | * Toshiba's KBC seems to have trouble handling data from | 935 | * Toshiba's KBC seems to have trouble handling data from |
781 | * Synaptics as full rate, switch to lower rate which is roughly | 936 | * Synaptics at full rate. Switch to a lower rate (roughly |
782 | * thye same as rate of standard PS/2 mouse. | 937 | * the same rate as a standard PS/2 mouse). |
783 | */ | 938 | */ |
784 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { | 939 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { |
785 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", | 940 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index b6aa7d20d8a3..7453938bf5ef 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -51,8 +51,33 @@ | |||
51 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) | 51 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) |
52 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) | 52 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) |
53 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) | 53 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) |
54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) | 54 | |
55 | /* | ||
56 | * The following describes response for the 0x0c query. | ||
57 | * | ||
58 | * byte mask name meaning | ||
59 | * ---- ---- ------- ------------ | ||
60 | * 1 0x01 adjustable threshold capacitive button sensitivity | ||
61 | * can be adjusted | ||
62 | * 1 0x02 report max query 0x0d gives max coord reported | ||
63 | * 1 0x04 clearpad sensor is ClearPad product | ||
64 | * 1 0x08 advanced gesture not particularly meaningful | ||
65 | * 1 0x10 clickpad bit 0 1-button ClickPad | ||
66 | * 1 0x60 multifinger mode identifies firmware finger counting | ||
67 | * (not reporting!) algorithm. | ||
68 | * Not particularly meaningful | ||
69 | * 1 0x80 covered pad W clipped to 14, 15 == pad mostly covered | ||
70 | * 2 0x01 clickpad bit 1 2-button ClickPad | ||
71 | * 2 0x02 deluxe LED controls touchpad support LED commands | ||
72 | * ala multimedia control bar | ||
73 | * 2 0x04 reduced filtering firmware does less filtering on | ||
74 | * position data, driver should watch | ||
75 | * for noise. | ||
76 | */ | ||
77 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ | ||
78 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ | ||
55 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) | 79 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) |
80 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) | ||
56 | 81 | ||
57 | /* synaptics modes query bits */ | 82 | /* synaptics modes query bits */ |
58 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 83 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
@@ -110,6 +135,10 @@ struct synaptics_data { | |||
110 | unsigned char pkt_type; /* packet type - old, new, etc */ | 135 | unsigned char pkt_type; /* packet type - old, new, etc */ |
111 | unsigned char mode; /* current mode byte */ | 136 | unsigned char mode; /* current mode byte */ |
112 | int scroll; | 137 | int scroll; |
138 | |||
139 | struct serio *pt_port; /* Pass-through serio port */ | ||
140 | |||
141 | struct synaptics_hw_state mt; /* current gesture packet */ | ||
113 | }; | 142 | }; |
114 | 143 | ||
115 | void synaptics_module_init(void); | 144 | void synaptics_module_init(void); |
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index 0ae62f0bcb32..cba3c84d2f21 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/pm.h> | ||
21 | 22 | ||
22 | #define DRIVER_NAME "synaptics_i2c" | 23 | #define DRIVER_NAME "synaptics_i2c" |
23 | /* maximum product id is 15 characters */ | 24 | /* maximum product id is 15 characters */ |
@@ -461,7 +462,7 @@ static void synaptics_i2c_work_handler(struct work_struct *work) | |||
461 | * While interrupt driven, there is no real need to poll the device. | 462 | * While interrupt driven, there is no real need to poll the device. |
462 | * But touchpads are very sensitive, so there could be errors | 463 | * But touchpads are very sensitive, so there could be errors |
463 | * related to physical environment and the attention line isn't | 464 | * related to physical environment and the attention line isn't |
464 | * neccesarily asserted. In such case we can lose the touchpad. | 465 | * necessarily asserted. In such case we can lose the touchpad. |
465 | * We poll the device once in THREAD_IRQ_SLEEP_SECS and | 466 | * We poll the device once in THREAD_IRQ_SLEEP_SECS and |
466 | * if error is detected, we try to reset and reconfigure the touchpad. | 467 | * if error is detected, we try to reset and reconfigure the touchpad. |
467 | */ | 468 | */ |
@@ -619,8 +620,9 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client) | |||
619 | } | 620 | } |
620 | 621 | ||
621 | #ifdef CONFIG_PM | 622 | #ifdef CONFIG_PM |
622 | static int synaptics_i2c_suspend(struct i2c_client *client, pm_message_t mesg) | 623 | static int synaptics_i2c_suspend(struct device *dev) |
623 | { | 624 | { |
625 | struct i2c_client *client = to_i2c_client(dev); | ||
624 | struct synaptics_i2c *touch = i2c_get_clientdata(client); | 626 | struct synaptics_i2c *touch = i2c_get_clientdata(client); |
625 | 627 | ||
626 | cancel_delayed_work_sync(&touch->dwork); | 628 | cancel_delayed_work_sync(&touch->dwork); |
@@ -631,9 +633,10 @@ static int synaptics_i2c_suspend(struct i2c_client *client, pm_message_t mesg) | |||
631 | return 0; | 633 | return 0; |
632 | } | 634 | } |
633 | 635 | ||
634 | static int synaptics_i2c_resume(struct i2c_client *client) | 636 | static int synaptics_i2c_resume(struct device *dev) |
635 | { | 637 | { |
636 | int ret; | 638 | int ret; |
639 | struct i2c_client *client = to_i2c_client(dev); | ||
637 | struct synaptics_i2c *touch = i2c_get_clientdata(client); | 640 | struct synaptics_i2c *touch = i2c_get_clientdata(client); |
638 | 641 | ||
639 | ret = synaptics_i2c_reset_config(client); | 642 | ret = synaptics_i2c_reset_config(client); |
@@ -645,11 +648,11 @@ static int synaptics_i2c_resume(struct i2c_client *client) | |||
645 | 648 | ||
646 | return 0; | 649 | return 0; |
647 | } | 650 | } |
648 | #else | ||
649 | #define synaptics_i2c_suspend NULL | ||
650 | #define synaptics_i2c_resume NULL | ||
651 | #endif | 651 | #endif |
652 | 652 | ||
653 | static SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend, | ||
654 | synaptics_i2c_resume); | ||
655 | |||
653 | static const struct i2c_device_id synaptics_i2c_id_table[] = { | 656 | static const struct i2c_device_id synaptics_i2c_id_table[] = { |
654 | { "synaptics_i2c", 0 }, | 657 | { "synaptics_i2c", 0 }, |
655 | { }, | 658 | { }, |
@@ -660,13 +663,12 @@ static struct i2c_driver synaptics_i2c_driver = { | |||
660 | .driver = { | 663 | .driver = { |
661 | .name = DRIVER_NAME, | 664 | .name = DRIVER_NAME, |
662 | .owner = THIS_MODULE, | 665 | .owner = THIS_MODULE, |
666 | .pm = &synaptics_i2c_pm, | ||
663 | }, | 667 | }, |
664 | 668 | ||
665 | .probe = synaptics_i2c_probe, | 669 | .probe = synaptics_i2c_probe, |
666 | .remove = __devexit_p(synaptics_i2c_remove), | 670 | .remove = __devexit_p(synaptics_i2c_remove), |
667 | 671 | ||
668 | .suspend = synaptics_i2c_suspend, | ||
669 | .resume = synaptics_i2c_resume, | ||
670 | .id_table = synaptics_i2c_id_table, | 672 | .id_table = synaptics_i2c_id_table, |
671 | }; | 673 | }; |
672 | 674 | ||
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c index 88121c59c3cc..1fd8f5e192f9 100644 --- a/drivers/input/mouse/touchkit_ps2.c +++ b/drivers/input/mouse/touchkit_ps2.c | |||
@@ -21,8 +21,8 @@ | |||
21 | * | 21 | * |
22 | * Based upon touchkitusb.c | 22 | * Based upon touchkitusb.c |
23 | * | 23 | * |
24 | * Vendor documentation is available in support section of: | 24 | * Vendor documentation is available at: |
25 | * http://www.egalax.com.tw/ | 25 | * http://home.eeti.com.tw/web20/drivers/Software%20Programming%20Guide_v2.0.pdf |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 0643e49ca603..54b2fa892e19 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -303,7 +303,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
303 | 303 | ||
304 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); | 304 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); |
305 | if (!psmouse->private) | 305 | if (!psmouse->private) |
306 | return -1; | 306 | return -ENOMEM; |
307 | 307 | ||
308 | psmouse->vendor = "IBM"; | 308 | psmouse->vendor = "IBM"; |
309 | psmouse->name = "TrackPoint"; | 309 | psmouse->name = "TrackPoint"; |
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index bf2c0c80d6cc..eb9a3cfbeefa 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -334,7 +334,7 @@ static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse) | |||
334 | * M: manufacturer location code | 334 | * M: manufacturer location code |
335 | * R: revision code | 335 | * R: revision code |
336 | * E: Error code. If it's in the range of 0x00..0x1f, only some | 336 | * E: Error code. If it's in the range of 0x00..0x1f, only some |
337 | * minor problem occured. Errors >= 0x20 are considered bad | 337 | * minor problem occurred. Errors >= 0x20 are considered bad |
338 | * and the device may not work properly... | 338 | * and the device may not work properly... |
339 | * D: <0010> == mouse, <0100> == tablet | 339 | * D: <0010> == mouse, <0100> == tablet |
340 | */ | 340 | */ |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index d528a2dba064..0110b5a3a167 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -9,6 +9,8 @@ | |||
9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
13 | |||
12 | #define MOUSEDEV_MINOR_BASE 32 | 14 | #define MOUSEDEV_MINOR_BASE 32 |
13 | #define MOUSEDEV_MINORS 32 | 15 | #define MOUSEDEV_MINORS 32 |
14 | #define MOUSEDEV_MIX 31 | 16 | #define MOUSEDEV_MIX 31 |
@@ -185,7 +187,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, | |||
185 | if (size == 0) | 187 | if (size == 0) |
186 | size = xres ? : 1; | 188 | size = xres ? : 1; |
187 | 189 | ||
188 | clamp(value, min, max); | 190 | value = clamp(value, min, max); |
189 | 191 | ||
190 | mousedev->packet.x = ((value - min) * xres) / size; | 192 | mousedev->packet.x = ((value - min) * xres) / size; |
191 | mousedev->packet.abs_event = 1; | 193 | mousedev->packet.abs_event = 1; |
@@ -199,7 +201,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, | |||
199 | if (size == 0) | 201 | if (size == 0) |
200 | size = yres ? : 1; | 202 | size = yres ? : 1; |
201 | 203 | ||
202 | clamp(value, min, max); | 204 | value = clamp(value, min, max); |
203 | 205 | ||
204 | mousedev->packet.y = yres - ((value - min) * yres) / size; | 206 | mousedev->packet.y = yres - ((value - min) * yres) / size; |
205 | mousedev->packet.abs_event = 1; | 207 | mousedev->packet.abs_event = 1; |
@@ -506,7 +508,6 @@ static void mousedev_attach_client(struct mousedev *mousedev, | |||
506 | spin_lock(&mousedev->client_lock); | 508 | spin_lock(&mousedev->client_lock); |
507 | list_add_tail_rcu(&client->node, &mousedev->client_list); | 509 | list_add_tail_rcu(&client->node, &mousedev->client_list); |
508 | spin_unlock(&mousedev->client_lock); | 510 | spin_unlock(&mousedev->client_lock); |
509 | synchronize_rcu(); | ||
510 | } | 511 | } |
511 | 512 | ||
512 | static void mousedev_detach_client(struct mousedev *mousedev, | 513 | static void mousedev_detach_client(struct mousedev *mousedev, |
@@ -792,6 +793,7 @@ static const struct file_operations mousedev_fops = { | |||
792 | .open = mousedev_open, | 793 | .open = mousedev_open, |
793 | .release = mousedev_release, | 794 | .release = mousedev_release, |
794 | .fasync = mousedev_fasync, | 795 | .fasync = mousedev_fasync, |
796 | .llseek = noop_llseek, | ||
795 | }; | 797 | }; |
796 | 798 | ||
797 | static int mousedev_install_chrdev(struct mousedev *mousedev) | 799 | static int mousedev_install_chrdev(struct mousedev *mousedev) |
@@ -866,7 +868,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
866 | spin_lock_init(&mousedev->client_lock); | 868 | spin_lock_init(&mousedev->client_lock); |
867 | mutex_init(&mousedev->mutex); | 869 | mutex_init(&mousedev->mutex); |
868 | lockdep_set_subclass(&mousedev->mutex, | 870 | lockdep_set_subclass(&mousedev->mutex, |
869 | minor == MOUSEDEV_MIX ? MOUSEDEV_MIX : 0); | 871 | minor == MOUSEDEV_MIX ? SINGLE_DEPTH_NESTING : 0); |
870 | init_waitqueue_head(&mousedev->wait); | 872 | init_waitqueue_head(&mousedev->wait); |
871 | 873 | ||
872 | if (minor == MOUSEDEV_MIX) | 874 | if (minor == MOUSEDEV_MIX) |
@@ -976,7 +978,7 @@ static int mousedev_connect(struct input_handler *handler, | |||
976 | break; | 978 | break; |
977 | 979 | ||
978 | if (minor == MOUSEDEV_MINORS) { | 980 | if (minor == MOUSEDEV_MINORS) { |
979 | printk(KERN_ERR "mousedev: no more free mousedev devices\n"); | 981 | pr_err("no more free mousedev devices\n"); |
980 | return -ENFILE; | 982 | return -ENFILE; |
981 | } | 983 | } |
982 | 984 | ||
@@ -1086,13 +1088,13 @@ static int __init mousedev_init(void) | |||
1086 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 1088 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
1087 | error = misc_register(&psaux_mouse); | 1089 | error = misc_register(&psaux_mouse); |
1088 | if (error) | 1090 | if (error) |
1089 | printk(KERN_WARNING "mice: could not register psaux device, " | 1091 | pr_warning("could not register psaux device, error: %d\n", |
1090 | "error: %d\n", error); | 1092 | error); |
1091 | else | 1093 | else |
1092 | psaux_registered = 1; | 1094 | psaux_registered = 1; |
1093 | #endif | 1095 | #endif |
1094 | 1096 | ||
1095 | printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n"); | 1097 | pr_info("PS/2 mouse device common for all mice\n"); |
1096 | 1098 | ||
1097 | return 0; | 1099 | return 0; |
1098 | } | 1100 | } |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 3bfe8fafc6ad..55f2c2293ec6 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -2,7 +2,7 @@ | |||
2 | # Input core configuration | 2 | # Input core configuration |
3 | # | 3 | # |
4 | config SERIO | 4 | config SERIO |
5 | tristate "Serial I/O support" if EMBEDDED || !X86 | 5 | tristate "Serial I/O support" if EXPERT || !X86 |
6 | default y | 6 | default y |
7 | help | 7 | help |
8 | Say Yes here if you have any input device that uses serial I/O to | 8 | Say Yes here if you have any input device that uses serial I/O to |
@@ -19,7 +19,7 @@ config SERIO | |||
19 | if SERIO | 19 | if SERIO |
20 | 20 | ||
21 | config SERIO_I8042 | 21 | config SERIO_I8042 |
22 | tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 | 22 | tristate "i8042 PC Keyboard controller" if EXPERT || !X86 |
23 | default y | 23 | default y |
24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ | 24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ |
25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN | 25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN |
@@ -168,7 +168,7 @@ config SERIO_MACEPS2 | |||
168 | module will be called maceps2. | 168 | module will be called maceps2. |
169 | 169 | ||
170 | config SERIO_LIBPS2 | 170 | config SERIO_LIBPS2 |
171 | tristate "PS/2 driver library" if EMBEDDED | 171 | tristate "PS/2 driver library" if EXPERT |
172 | depends on SERIO_I8042 || SERIO_I8042=n | 172 | depends on SERIO_I8042 || SERIO_I8042=n |
173 | help | 173 | help |
174 | Say Y here if you are using a driver for device connected | 174 | Say Y here if you are using a driver for device connected |
@@ -214,7 +214,6 @@ config SERIO_AMS_DELTA | |||
214 | tristate "Amstrad Delta (E3) mailboard support" | 214 | tristate "Amstrad Delta (E3) mailboard support" |
215 | depends on MACH_AMS_DELTA | 215 | depends on MACH_AMS_DELTA |
216 | default y | 216 | default y |
217 | select AMS_DELTA_FIQ | ||
218 | ---help--- | 217 | ---help--- |
219 | Say Y here if you have an E3 and want to use its mailboard, | 218 | Say Y here if you have an E3 and want to use its mailboard, |
220 | or any standard AT keyboard connected to the mailboard port. | 219 | or any standard AT keyboard connected to the mailboard port. |
@@ -226,4 +225,13 @@ config SERIO_AMS_DELTA | |||
226 | To compile this driver as a module, choose M here; | 225 | To compile this driver as a module, choose M here; |
227 | the module will be called ams_delta_serio. | 226 | the module will be called ams_delta_serio. |
228 | 227 | ||
228 | config SERIO_PS2MULT | ||
229 | tristate "TQC PS/2 multiplexer" | ||
230 | help | ||
231 | Say Y here if you have the PS/2 line multiplexer like the one | ||
232 | present on TQC boards. | ||
233 | |||
234 | To compile this driver as a module, choose M here: the | ||
235 | module will be called ps2mult. | ||
236 | |||
229 | endif | 237 | endif |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 84c80bf7185e..dbbe37616c92 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o | |||
18 | obj-$(CONFIG_HP_SDC) += hp_sdc.o | 18 | obj-$(CONFIG_HP_SDC) += hp_sdc.o |
19 | obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o | 19 | obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o |
20 | obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o | 20 | obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o |
21 | obj-$(CONFIG_SERIO_PS2MULT) += ps2mult.o | ||
21 | obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o | 22 | obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o |
22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o | 23 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o |
23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o | 24 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o |
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index 7998560a1904..d363dc4571a3 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/of.h> | ||
22 | 23 | ||
23 | #define DRV_NAME "altera_ps2" | 24 | #define DRV_NAME "altera_ps2" |
24 | 25 | ||
@@ -173,6 +174,16 @@ static int __devexit altera_ps2_remove(struct platform_device *pdev) | |||
173 | return 0; | 174 | return 0; |
174 | } | 175 | } |
175 | 176 | ||
177 | #ifdef CONFIG_OF | ||
178 | static const struct of_device_id altera_ps2_match[] = { | ||
179 | { .compatible = "ALTR,ps2-1.0", }, | ||
180 | {}, | ||
181 | }; | ||
182 | MODULE_DEVICE_TABLE(of, altera_ps2_match); | ||
183 | #else /* CONFIG_OF */ | ||
184 | #define altera_ps2_match NULL | ||
185 | #endif /* CONFIG_OF */ | ||
186 | |||
176 | /* | 187 | /* |
177 | * Our device driver structure | 188 | * Our device driver structure |
178 | */ | 189 | */ |
@@ -182,6 +193,7 @@ static struct platform_driver altera_ps2_driver = { | |||
182 | .driver = { | 193 | .driver = { |
183 | .name = DRV_NAME, | 194 | .name = DRV_NAME, |
184 | .owner = THIS_MODULE, | 195 | .owner = THIS_MODULE, |
196 | .of_match_table = altera_ps2_match, | ||
185 | }, | 197 | }, |
186 | }; | 198 | }; |
187 | 199 | ||
@@ -189,13 +201,12 @@ static int __init altera_ps2_init(void) | |||
189 | { | 201 | { |
190 | return platform_driver_register(&altera_ps2_driver); | 202 | return platform_driver_register(&altera_ps2_driver); |
191 | } | 203 | } |
204 | module_init(altera_ps2_init); | ||
192 | 205 | ||
193 | static void __exit altera_ps2_exit(void) | 206 | static void __exit altera_ps2_exit(void) |
194 | { | 207 | { |
195 | platform_driver_unregister(&altera_ps2_driver); | 208 | platform_driver_unregister(&altera_ps2_driver); |
196 | } | 209 | } |
197 | |||
198 | module_init(altera_ps2_init); | ||
199 | module_exit(altera_ps2_exit); | 210 | module_exit(altera_ps2_exit); |
200 | 211 | ||
201 | MODULE_DESCRIPTION("Altera University Program PS2 controller driver"); | 212 | MODULE_DESCRIPTION("Altera University Program PS2 controller driver"); |
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 92563a681d65..12abc50508e5 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c | |||
@@ -107,7 +107,8 @@ static void amba_kmi_close(struct serio *io) | |||
107 | clk_disable(kmi->clk); | 107 | clk_disable(kmi->clk); |
108 | } | 108 | } |
109 | 109 | ||
110 | static int __devinit amba_kmi_probe(struct amba_device *dev, struct amba_id *id) | 110 | static int __devinit amba_kmi_probe(struct amba_device *dev, |
111 | const struct amba_id *id) | ||
111 | { | 112 | { |
112 | struct amba_kmi_port *kmi; | 113 | struct amba_kmi_port *kmi; |
113 | struct serio *io; | 114 | struct serio *io; |
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 8f1770e1e08b..4b2a42f9f0bb 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c | |||
@@ -149,7 +149,7 @@ static int __init ams_delta_serio_init(void) | |||
149 | * at FIQ level, switch back from edge to simple interrupt handler | 149 | * at FIQ level, switch back from edge to simple interrupt handler |
150 | * to avoid bad interaction. | 150 | * to avoid bad interaction. |
151 | */ | 151 | */ |
152 | set_irq_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), | 152 | irq_set_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), |
153 | handle_simple_irq); | 153 | handle_simple_irq); |
154 | 154 | ||
155 | serio_register_port(ams_delta_serio); | 155 | serio_register_port(ams_delta_serio); |
@@ -172,6 +172,5 @@ static void __exit ams_delta_serio_exit(void) | |||
172 | free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0); | 172 | free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0); |
173 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); | 173 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); |
174 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); | 174 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); |
175 | kfree(ams_delta_serio); | ||
176 | } | 175 | } |
177 | module_exit(ams_delta_serio_exit); | 176 | module_exit(ams_delta_serio_exit); |
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 4a3084695c00..852816567241 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c | |||
@@ -111,9 +111,11 @@ static void ct82c710_close(struct serio *serio) | |||
111 | static int ct82c710_open(struct serio *serio) | 111 | static int ct82c710_open(struct serio *serio) |
112 | { | 112 | { |
113 | unsigned char status; | 113 | unsigned char status; |
114 | int err; | ||
114 | 115 | ||
115 | if (request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL)) | 116 | err = request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL); |
116 | return -1; | 117 | if (err) |
118 | return err; | ||
117 | 119 | ||
118 | status = inb_p(CT82C710_STATUS); | 120 | status = inb_p(CT82C710_STATUS); |
119 | 121 | ||
@@ -131,7 +133,7 @@ static int ct82c710_open(struct serio *serio) | |||
131 | status &= ~(CT82C710_ENABLE | CT82C710_INTS_ON); | 133 | status &= ~(CT82C710_ENABLE | CT82C710_INTS_ON); |
132 | outb_p(status, CT82C710_STATUS); | 134 | outb_p(status, CT82C710_STATUS); |
133 | free_irq(CT82C710_IRQ, NULL); | 135 | free_irq(CT82C710_IRQ, NULL); |
134 | return -1; | 136 | return -EBUSY; |
135 | } | 137 | } |
136 | 138 | ||
137 | return 0; | 139 | return 0; |
@@ -191,6 +193,9 @@ static int __devinit ct82c710_probe(struct platform_device *dev) | |||
191 | 193 | ||
192 | serio_register_port(ct82c710_port); | 194 | serio_register_port(ct82c710_port); |
193 | 195 | ||
196 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", | ||
197 | (unsigned long long)CT82C710_DATA, CT82C710_IRQ); | ||
198 | |||
194 | return 0; | 199 | return 0; |
195 | } | 200 | } |
196 | 201 | ||
@@ -237,11 +242,6 @@ static int __init ct82c710_init(void) | |||
237 | if (error) | 242 | if (error) |
238 | goto err_free_device; | 243 | goto err_free_device; |
239 | 244 | ||
240 | serio_register_port(ct82c710_port); | ||
241 | |||
242 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", | ||
243 | (unsigned long long)CT82C710_DATA, CT82C710_IRQ); | ||
244 | |||
245 | return 0; | 245 | return 0; |
246 | 246 | ||
247 | err_free_device: | 247 | err_free_device: |
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 3c287dd879d3..4225f5d6b15f 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c | |||
@@ -358,7 +358,7 @@ static int __devinit gscps2_probe(struct parisc_device *dev) | |||
358 | gscps2_reset(ps2port); | 358 | gscps2_reset(ps2port); |
359 | ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f; | 359 | ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f; |
360 | 360 | ||
361 | snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s", | 361 | snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s", |
362 | (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); | 362 | (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); |
363 | strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); | 363 | strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); |
364 | serio->id.type = SERIO_8042; | 364 | serio->id.type = SERIO_8042; |
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index c92f4edfee7b..bfd3865d886b 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -915,15 +915,15 @@ int hil_mlc_register(hil_mlc *mlc) | |||
915 | mlc->ostarted = 0; | 915 | mlc->ostarted = 0; |
916 | 916 | ||
917 | rwlock_init(&mlc->lock); | 917 | rwlock_init(&mlc->lock); |
918 | init_MUTEX(&mlc->osem); | 918 | sema_init(&mlc->osem, 1); |
919 | 919 | ||
920 | init_MUTEX(&mlc->isem); | 920 | sema_init(&mlc->isem, 1); |
921 | mlc->icount = -1; | 921 | mlc->icount = -1; |
922 | mlc->imatch = 0; | 922 | mlc->imatch = 0; |
923 | 923 | ||
924 | mlc->opercnt = 0; | 924 | mlc->opercnt = 0; |
925 | 925 | ||
926 | init_MUTEX_LOCKED(&(mlc->csem)); | 926 | sema_init(&(mlc->csem), 0); |
927 | 927 | ||
928 | hil_mlc_clear_di_scratch(mlc); | 928 | hil_mlc_clear_di_scratch(mlc); |
929 | hil_mlc_clear_di_map(mlc, 0); | 929 | hil_mlc_clear_di_map(mlc, 0); |
@@ -932,6 +932,11 @@ int hil_mlc_register(hil_mlc *mlc) | |||
932 | hil_mlc_copy_di_scratch(mlc, i); | 932 | hil_mlc_copy_di_scratch(mlc, i); |
933 | mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); | 933 | mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); |
934 | mlc->serio[i] = mlc_serio; | 934 | mlc->serio[i] = mlc_serio; |
935 | if (!mlc->serio[i]) { | ||
936 | for (; i >= 0; i--) | ||
937 | kfree(mlc->serio[i]); | ||
938 | return -ENOMEM; | ||
939 | } | ||
935 | snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); | 940 | snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); |
936 | snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); | 941 | snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); |
937 | mlc_serio->id = hil_mlc_serio_id; | 942 | mlc_serio->id = hil_mlc_serio_id; |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index bcc2d30ec245..42206205e4f5 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -905,7 +905,7 @@ static int __init hp_sdc_init(void) | |||
905 | ts_sync[1] = 0x0f; | 905 | ts_sync[1] = 0x0f; |
906 | ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0; | 906 | ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0; |
907 | t_sync.act.semaphore = &s_sync; | 907 | t_sync.act.semaphore = &s_sync; |
908 | init_MUTEX_LOCKED(&s_sync); | 908 | sema_init(&s_sync, 0); |
909 | hp_sdc_enqueue_transaction(&t_sync); | 909 | hp_sdc_enqueue_transaction(&t_sync); |
910 | down(&s_sync); /* Wait for t_sync to complete */ | 910 | down(&s_sync); /* Wait for t_sync to complete */ |
911 | 911 | ||
@@ -955,7 +955,7 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d) | |||
955 | INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); | 955 | INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); |
956 | 956 | ||
957 | ret = hp_sdc_init(); | 957 | ret = hp_sdc_init(); |
958 | /* after successfull initialization give SDC some time to settle | 958 | /* after successful initialization give SDC some time to settle |
959 | * and then load the hp_sdc_mlc upper layer driver */ | 959 | * and then load the hp_sdc_mlc upper layer driver */ |
960 | if (!ret) | 960 | if (!ret) |
961 | schedule_delayed_work(&moduleloader_work, | 961 | schedule_delayed_work(&moduleloader_work, |
@@ -1039,7 +1039,7 @@ static int __init hp_sdc_register(void) | |||
1039 | return hp_sdc.dev_err; | 1039 | return hp_sdc.dev_err; |
1040 | } | 1040 | } |
1041 | 1041 | ||
1042 | init_MUTEX_LOCKED(&tq_init_sem); | 1042 | sema_init(&tq_init_sem, 0); |
1043 | 1043 | ||
1044 | tq_init.actidx = 0; | 1044 | tq_init.actidx = 0; |
1045 | tq_init.idx = 1; | 1045 | tq_init.idx = 1; |
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index 7d2b820ef58d..d50f0678bf47 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c | |||
@@ -305,6 +305,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc) | |||
305 | static int __init hp_sdc_mlc_init(void) | 305 | static int __init hp_sdc_mlc_init(void) |
306 | { | 306 | { |
307 | hil_mlc *mlc = &hp_sdc_mlc; | 307 | hil_mlc *mlc = &hp_sdc_mlc; |
308 | int err; | ||
308 | 309 | ||
309 | #ifdef __mc68000__ | 310 | #ifdef __mc68000__ |
310 | if (!MACH_IS_HP300) | 311 | if (!MACH_IS_HP300) |
@@ -323,22 +324,21 @@ static int __init hp_sdc_mlc_init(void) | |||
323 | mlc->out = &hp_sdc_mlc_out; | 324 | mlc->out = &hp_sdc_mlc_out; |
324 | mlc->priv = &hp_sdc_mlc_priv; | 325 | mlc->priv = &hp_sdc_mlc_priv; |
325 | 326 | ||
326 | if (hil_mlc_register(mlc)) { | 327 | err = hil_mlc_register(mlc); |
328 | if (err) { | ||
327 | printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); | 329 | printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); |
328 | goto err0; | 330 | return err; |
329 | } | 331 | } |
330 | 332 | ||
331 | if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { | 333 | if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { |
332 | printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); | 334 | printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); |
333 | goto err1; | 335 | if (hil_mlc_unregister(mlc)) |
336 | printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" | ||
337 | "This is bad. Could cause an oops.\n"); | ||
338 | return -EBUSY; | ||
334 | } | 339 | } |
340 | |||
335 | return 0; | 341 | return 0; |
336 | err1: | ||
337 | if (hil_mlc_unregister(mlc)) | ||
338 | printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" | ||
339 | "This is bad. Could cause an oops.\n"); | ||
340 | err0: | ||
341 | return -EBUSY; | ||
342 | } | 342 | } |
343 | 343 | ||
344 | static void __exit hp_sdc_mlc_exit(void) | 344 | static void __exit hp_sdc_mlc_exit(void) |
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index c5cc4508d6df..395a9af3adcd 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h | |||
@@ -49,7 +49,7 @@ static inline void i8042_write_command(int val) | |||
49 | #define OBP_PS2MS_NAME1 "kdmouse" | 49 | #define OBP_PS2MS_NAME1 "kdmouse" |
50 | #define OBP_PS2MS_NAME2 "mouse" | 50 | #define OBP_PS2MS_NAME2 "mouse" |
51 | 51 | ||
52 | static int __devinit sparc_i8042_probe(struct platform_device *op, const struct of_device_id *match) | 52 | static int __devinit sparc_i8042_probe(struct platform_device *op) |
53 | { | 53 | { |
54 | struct device_node *dp = op->dev.of_node; | 54 | struct device_node *dp = op->dev.of_node; |
55 | 55 | ||
@@ -95,7 +95,7 @@ static const struct of_device_id sparc_i8042_match[] = { | |||
95 | }; | 95 | }; |
96 | MODULE_DEVICE_TABLE(of, sparc_i8042_match); | 96 | MODULE_DEVICE_TABLE(of, sparc_i8042_match); |
97 | 97 | ||
98 | static struct of_platform_driver sparc_i8042_driver = { | 98 | static struct platform_driver sparc_i8042_driver = { |
99 | .driver = { | 99 | .driver = { |
100 | .name = "i8042", | 100 | .name = "i8042", |
101 | .owner = THIS_MODULE, | 101 | .owner = THIS_MODULE, |
@@ -116,7 +116,7 @@ static int __init i8042_platform_init(void) | |||
116 | if (!kbd_iobase) | 116 | if (!kbd_iobase) |
117 | return -ENODEV; | 117 | return -ENODEV; |
118 | } else { | 118 | } else { |
119 | int err = of_register_platform_driver(&sparc_i8042_driver); | 119 | int err = platform_driver_register(&sparc_i8042_driver); |
120 | if (err) | 120 | if (err) |
121 | return err; | 121 | return err; |
122 | 122 | ||
@@ -140,7 +140,7 @@ static inline void i8042_platform_exit(void) | |||
140 | struct device_node *root = of_find_node_by_path("/"); | 140 | struct device_node *root = of_find_node_by_path("/"); |
141 | 141 | ||
142 | if (strcmp(root->name, "SUNW,JavaStation-1")) | 142 | if (strcmp(root->name, "SUNW,JavaStation-1")) |
143 | of_unregister_platform_driver(&sparc_i8042_driver); | 143 | platform_driver_unregister(&sparc_i8042_driver); |
144 | } | 144 | } |
145 | 145 | ||
146 | #else /* !CONFIG_PCI */ | 146 | #else /* !CONFIG_PCI */ |
diff --git a/drivers/input/serio/i8042-unicore32io.h b/drivers/input/serio/i8042-unicore32io.h new file mode 100644 index 000000000000..73f5cc124a36 --- /dev/null +++ b/drivers/input/serio/i8042-unicore32io.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Code specific to PKUnity SoC and UniCore ISA | ||
3 | * | ||
4 | * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> | ||
5 | * Copyright (C) 2001-2011 Guan Xuetao | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #ifndef _I8042_UNICORE32_H | ||
12 | #define _I8042_UNICORE32_H | ||
13 | |||
14 | #include <mach/hardware.h> | ||
15 | |||
16 | /* | ||
17 | * Names. | ||
18 | */ | ||
19 | #define I8042_KBD_PHYS_DESC "isa0060/serio0" | ||
20 | #define I8042_AUX_PHYS_DESC "isa0060/serio1" | ||
21 | #define I8042_MUX_PHYS_DESC "isa0060/serio%d" | ||
22 | |||
23 | /* | ||
24 | * IRQs. | ||
25 | */ | ||
26 | #define I8042_KBD_IRQ IRQ_PS2_KBD | ||
27 | #define I8042_AUX_IRQ IRQ_PS2_AUX | ||
28 | |||
29 | /* | ||
30 | * Register numbers. | ||
31 | */ | ||
32 | #define I8042_COMMAND_REG PS2_COMMAND | ||
33 | #define I8042_STATUS_REG PS2_STATUS | ||
34 | #define I8042_DATA_REG PS2_DATA | ||
35 | |||
36 | #define I8042_REGION_START (resource_size_t)(PS2_DATA) | ||
37 | #define I8042_REGION_SIZE (resource_size_t)(16) | ||
38 | |||
39 | static inline int i8042_read_data(void) | ||
40 | { | ||
41 | return readb(I8042_DATA_REG); | ||
42 | } | ||
43 | |||
44 | static inline int i8042_read_status(void) | ||
45 | { | ||
46 | return readb(I8042_STATUS_REG); | ||
47 | } | ||
48 | |||
49 | static inline void i8042_write_data(int val) | ||
50 | { | ||
51 | writeb(val, I8042_DATA_REG); | ||
52 | } | ||
53 | |||
54 | static inline void i8042_write_command(int val) | ||
55 | { | ||
56 | writeb(val, I8042_COMMAND_REG); | ||
57 | } | ||
58 | |||
59 | static inline int i8042_platform_init(void) | ||
60 | { | ||
61 | if (!request_mem_region(I8042_REGION_START, I8042_REGION_SIZE, "i8042")) | ||
62 | return -EBUSY; | ||
63 | |||
64 | i8042_reset = 1; | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static inline void i8042_platform_exit(void) | ||
69 | { | ||
70 | release_mem_region(I8042_REGION_START, I8042_REGION_SIZE); | ||
71 | } | ||
72 | |||
73 | #endif /* _I8042_UNICORE32_H */ | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index ed7ad7416b24..bb9f5d31f0d0 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -351,6 +351,17 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | |||
351 | }, | 351 | }, |
352 | }, | 352 | }, |
353 | { | 353 | { |
354 | /* | ||
355 | * Most (all?) VAIOs do not have external PS/2 ports nor | ||
356 | * they implement active multiplexing properly, and | ||
357 | * MUX discovery usually messes up keyboard/touchpad. | ||
358 | */ | ||
359 | .matches = { | ||
360 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
361 | DMI_MATCH(DMI_BOARD_NAME, "VAIO"), | ||
362 | }, | ||
363 | }, | ||
364 | { | ||
354 | /* Amoi M636/A737 */ | 365 | /* Amoi M636/A737 */ |
355 | .matches = { | 366 | .matches = { |
356 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), | 367 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), |
@@ -413,6 +424,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | |||
413 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), | 424 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), |
414 | }, | 425 | }, |
415 | }, | 426 | }, |
427 | { | ||
428 | /* Dell Vostro V13 */ | ||
429 | .matches = { | ||
430 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
431 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), | ||
432 | }, | ||
433 | }, | ||
416 | { } | 434 | { } |
417 | }; | 435 | }; |
418 | 436 | ||
@@ -534,6 +552,17 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { | |||
534 | }; | 552 | }; |
535 | #endif | 553 | #endif |
536 | 554 | ||
555 | static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { | ||
556 | { | ||
557 | /* Dell Vostro V13 */ | ||
558 | .matches = { | ||
559 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
560 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), | ||
561 | }, | ||
562 | }, | ||
563 | { } | ||
564 | }; | ||
565 | |||
537 | /* | 566 | /* |
538 | * Some Wistron based laptops need us to explicitly enable the 'Dritek | 567 | * Some Wistron based laptops need us to explicitly enable the 'Dritek |
539 | * keyboard extension' to make their extra keys start generating scancodes. | 568 | * keyboard extension' to make their extra keys start generating scancodes. |
@@ -542,6 +571,13 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { | |||
542 | */ | 571 | */ |
543 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { | 572 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { |
544 | { | 573 | { |
574 | /* Acer Aspire 5100 */ | ||
575 | .matches = { | ||
576 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
577 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), | ||
578 | }, | ||
579 | }, | ||
580 | { | ||
545 | /* Acer Aspire 5610 */ | 581 | /* Acer Aspire 5610 */ |
546 | .matches = { | 582 | .matches = { |
547 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 583 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -741,7 +777,7 @@ static int __init i8042_pnp_init(void) | |||
741 | #endif | 777 | #endif |
742 | 778 | ||
743 | if (i8042_nopnp) { | 779 | if (i8042_nopnp) { |
744 | printk(KERN_INFO "i8042: PNP detection disabled\n"); | 780 | pr_info("PNP detection disabled\n"); |
745 | return 0; | 781 | return 0; |
746 | } | 782 | } |
747 | 783 | ||
@@ -758,7 +794,7 @@ static int __init i8042_pnp_init(void) | |||
758 | #if defined(__ia64__) | 794 | #if defined(__ia64__) |
759 | return -ENODEV; | 795 | return -ENODEV; |
760 | #else | 796 | #else |
761 | printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n"); | 797 | pr_info("PNP: No PS/2 controller found. Probing ports directly.\n"); |
762 | return 0; | 798 | return 0; |
763 | #endif | 799 | #endif |
764 | } | 800 | } |
@@ -770,7 +806,7 @@ static int __init i8042_pnp_init(void) | |||
770 | snprintf(aux_irq_str, sizeof(aux_irq_str), | 806 | snprintf(aux_irq_str, sizeof(aux_irq_str), |
771 | "%d", i8042_pnp_aux_irq); | 807 | "%d", i8042_pnp_aux_irq); |
772 | 808 | ||
773 | printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", | 809 | pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", |
774 | i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", | 810 | i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", |
775 | i8042_pnp_aux_name, | 811 | i8042_pnp_aux_name, |
776 | i8042_pnp_data_reg, i8042_pnp_command_reg, | 812 | i8042_pnp_data_reg, i8042_pnp_command_reg, |
@@ -787,9 +823,7 @@ static int __init i8042_pnp_init(void) | |||
787 | if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && | 823 | if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && |
788 | i8042_pnp_data_reg != i8042_data_reg) || | 824 | i8042_pnp_data_reg != i8042_data_reg) || |
789 | !i8042_pnp_data_reg) { | 825 | !i8042_pnp_data_reg) { |
790 | printk(KERN_WARNING | 826 | pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n", |
791 | "PNP: PS/2 controller has invalid data port %#x; " | ||
792 | "using default %#x\n", | ||
793 | i8042_pnp_data_reg, i8042_data_reg); | 827 | i8042_pnp_data_reg, i8042_data_reg); |
794 | i8042_pnp_data_reg = i8042_data_reg; | 828 | i8042_pnp_data_reg = i8042_data_reg; |
795 | pnp_data_busted = true; | 829 | pnp_data_busted = true; |
@@ -798,33 +832,27 @@ static int __init i8042_pnp_init(void) | |||
798 | if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && | 832 | if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && |
799 | i8042_pnp_command_reg != i8042_command_reg) || | 833 | i8042_pnp_command_reg != i8042_command_reg) || |
800 | !i8042_pnp_command_reg) { | 834 | !i8042_pnp_command_reg) { |
801 | printk(KERN_WARNING | 835 | pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n", |
802 | "PNP: PS/2 controller has invalid command port %#x; " | ||
803 | "using default %#x\n", | ||
804 | i8042_pnp_command_reg, i8042_command_reg); | 836 | i8042_pnp_command_reg, i8042_command_reg); |
805 | i8042_pnp_command_reg = i8042_command_reg; | 837 | i8042_pnp_command_reg = i8042_command_reg; |
806 | pnp_data_busted = true; | 838 | pnp_data_busted = true; |
807 | } | 839 | } |
808 | 840 | ||
809 | if (!i8042_nokbd && !i8042_pnp_kbd_irq) { | 841 | if (!i8042_nokbd && !i8042_pnp_kbd_irq) { |
810 | printk(KERN_WARNING | 842 | pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n", |
811 | "PNP: PS/2 controller doesn't have KBD irq; " | 843 | i8042_kbd_irq); |
812 | "using default %d\n", i8042_kbd_irq); | ||
813 | i8042_pnp_kbd_irq = i8042_kbd_irq; | 844 | i8042_pnp_kbd_irq = i8042_kbd_irq; |
814 | pnp_data_busted = true; | 845 | pnp_data_busted = true; |
815 | } | 846 | } |
816 | 847 | ||
817 | if (!i8042_noaux && !i8042_pnp_aux_irq) { | 848 | if (!i8042_noaux && !i8042_pnp_aux_irq) { |
818 | if (!pnp_data_busted && i8042_pnp_kbd_irq) { | 849 | if (!pnp_data_busted && i8042_pnp_kbd_irq) { |
819 | printk(KERN_WARNING | 850 | pr_warn("PNP: PS/2 appears to have AUX port disabled, " |
820 | "PNP: PS/2 appears to have AUX port disabled, " | 851 | "if this is incorrect please boot with i8042.nopnp\n"); |
821 | "if this is incorrect please boot with " | ||
822 | "i8042.nopnp\n"); | ||
823 | i8042_noaux = true; | 852 | i8042_noaux = true; |
824 | } else { | 853 | } else { |
825 | printk(KERN_WARNING | 854 | pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n", |
826 | "PNP: PS/2 controller doesn't have AUX irq; " | 855 | i8042_aux_irq); |
827 | "using default %d\n", i8042_aux_irq); | ||
828 | i8042_pnp_aux_irq = i8042_aux_irq; | 856 | i8042_pnp_aux_irq = i8042_aux_irq; |
829 | } | 857 | } |
830 | } | 858 | } |
@@ -886,6 +914,9 @@ static int __init i8042_platform_init(void) | |||
886 | if (dmi_check_system(i8042_dmi_nomux_table)) | 914 | if (dmi_check_system(i8042_dmi_nomux_table)) |
887 | i8042_nomux = true; | 915 | i8042_nomux = true; |
888 | 916 | ||
917 | if (dmi_check_system(i8042_dmi_notimeout_table)) | ||
918 | i8042_notimeout = true; | ||
919 | |||
889 | if (dmi_check_system(i8042_dmi_dritek_table)) | 920 | if (dmi_check_system(i8042_dmi_dritek_table)) |
890 | i8042_dritek = true; | 921 | i8042_dritek = true; |
891 | #endif /* CONFIG_X86 */ | 922 | #endif /* CONFIG_X86 */ |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index f58513160480..d37a48e099d0 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -10,6 +10,8 @@ | |||
10 | * the Free Software Foundation. | 10 | * the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
14 | |||
13 | #include <linux/types.h> | 15 | #include <linux/types.h> |
14 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
@@ -61,6 +63,10 @@ static bool i8042_noloop; | |||
61 | module_param_named(noloop, i8042_noloop, bool, 0); | 63 | module_param_named(noloop, i8042_noloop, bool, 0); |
62 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); | 64 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); |
63 | 65 | ||
66 | static bool i8042_notimeout; | ||
67 | module_param_named(notimeout, i8042_notimeout, bool, 0); | ||
68 | MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042"); | ||
69 | |||
64 | #ifdef CONFIG_X86 | 70 | #ifdef CONFIG_X86 |
65 | static bool i8042_dritek; | 71 | static bool i8042_dritek; |
66 | module_param_named(dritek, i8042_dritek, bool, 0); | 72 | module_param_named(dritek, i8042_dritek, bool, 0); |
@@ -225,8 +231,8 @@ static int i8042_flush(void) | |||
225 | udelay(50); | 231 | udelay(50); |
226 | data = i8042_read_data(); | 232 | data = i8042_read_data(); |
227 | i++; | 233 | i++; |
228 | dbg("%02x <- i8042 (flush, %s)", data, | 234 | dbg("%02x <- i8042 (flush, %s)\n", |
229 | str & I8042_STR_AUXDATA ? "aux" : "kbd"); | 235 | data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); |
230 | } | 236 | } |
231 | 237 | ||
232 | spin_unlock_irqrestore(&i8042_lock, flags); | 238 | spin_unlock_irqrestore(&i8042_lock, flags); |
@@ -253,32 +259,32 @@ static int __i8042_command(unsigned char *param, int command) | |||
253 | if (error) | 259 | if (error) |
254 | return error; | 260 | return error; |
255 | 261 | ||
256 | dbg("%02x -> i8042 (command)", command & 0xff); | 262 | dbg("%02x -> i8042 (command)\n", command & 0xff); |
257 | i8042_write_command(command & 0xff); | 263 | i8042_write_command(command & 0xff); |
258 | 264 | ||
259 | for (i = 0; i < ((command >> 12) & 0xf); i++) { | 265 | for (i = 0; i < ((command >> 12) & 0xf); i++) { |
260 | error = i8042_wait_write(); | 266 | error = i8042_wait_write(); |
261 | if (error) | 267 | if (error) |
262 | return error; | 268 | return error; |
263 | dbg("%02x -> i8042 (parameter)", param[i]); | 269 | dbg("%02x -> i8042 (parameter)\n", param[i]); |
264 | i8042_write_data(param[i]); | 270 | i8042_write_data(param[i]); |
265 | } | 271 | } |
266 | 272 | ||
267 | for (i = 0; i < ((command >> 8) & 0xf); i++) { | 273 | for (i = 0; i < ((command >> 8) & 0xf); i++) { |
268 | error = i8042_wait_read(); | 274 | error = i8042_wait_read(); |
269 | if (error) { | 275 | if (error) { |
270 | dbg(" -- i8042 (timeout)"); | 276 | dbg(" -- i8042 (timeout)\n"); |
271 | return error; | 277 | return error; |
272 | } | 278 | } |
273 | 279 | ||
274 | if (command == I8042_CMD_AUX_LOOP && | 280 | if (command == I8042_CMD_AUX_LOOP && |
275 | !(i8042_read_status() & I8042_STR_AUXDATA)) { | 281 | !(i8042_read_status() & I8042_STR_AUXDATA)) { |
276 | dbg(" -- i8042 (auxerr)"); | 282 | dbg(" -- i8042 (auxerr)\n"); |
277 | return -1; | 283 | return -1; |
278 | } | 284 | } |
279 | 285 | ||
280 | param[i] = i8042_read_data(); | 286 | param[i] = i8042_read_data(); |
281 | dbg("%02x <- i8042 (return)", param[i]); | 287 | dbg("%02x <- i8042 (return)\n", param[i]); |
282 | } | 288 | } |
283 | 289 | ||
284 | return 0; | 290 | return 0; |
@@ -309,7 +315,7 @@ static int i8042_kbd_write(struct serio *port, unsigned char c) | |||
309 | spin_lock_irqsave(&i8042_lock, flags); | 315 | spin_lock_irqsave(&i8042_lock, flags); |
310 | 316 | ||
311 | if (!(retval = i8042_wait_write())) { | 317 | if (!(retval = i8042_wait_write())) { |
312 | dbg("%02x -> i8042 (kbd-data)", c); | 318 | dbg("%02x -> i8042 (kbd-data)\n", c); |
313 | i8042_write_data(c); | 319 | i8042_write_data(c); |
314 | } | 320 | } |
315 | 321 | ||
@@ -355,17 +361,14 @@ static void i8042_port_close(struct serio *serio) | |||
355 | 361 | ||
356 | i8042_ctr &= ~irq_bit; | 362 | i8042_ctr &= ~irq_bit; |
357 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) | 363 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) |
358 | printk(KERN_WARNING | 364 | pr_warn("Can't write CTR while closing %s port\n", port_name); |
359 | "i8042.c: Can't write CTR while closing %s port.\n", | ||
360 | port_name); | ||
361 | 365 | ||
362 | udelay(50); | 366 | udelay(50); |
363 | 367 | ||
364 | i8042_ctr &= ~disable_bit; | 368 | i8042_ctr &= ~disable_bit; |
365 | i8042_ctr |= irq_bit; | 369 | i8042_ctr |= irq_bit; |
366 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) | 370 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) |
367 | printk(KERN_ERR "i8042.c: Can't reactivate %s port.\n", | 371 | pr_err("Can't reactivate %s port\n", port_name); |
368 | port_name); | ||
369 | 372 | ||
370 | /* | 373 | /* |
371 | * See if there is any data appeared while we were messing with | 374 | * See if there is any data appeared while we were messing with |
@@ -456,7 +459,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
456 | str = i8042_read_status(); | 459 | str = i8042_read_status(); |
457 | if (unlikely(~str & I8042_STR_OBF)) { | 460 | if (unlikely(~str & I8042_STR_OBF)) { |
458 | spin_unlock_irqrestore(&i8042_lock, flags); | 461 | spin_unlock_irqrestore(&i8042_lock, flags); |
459 | if (irq) dbg("Interrupt %d, without any data", irq); | 462 | if (irq) |
463 | dbg("Interrupt %d, without any data\n", irq); | ||
460 | ret = 0; | 464 | ret = 0; |
461 | goto out; | 465 | goto out; |
462 | } | 466 | } |
@@ -469,7 +473,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
469 | 473 | ||
470 | dfl = 0; | 474 | dfl = 0; |
471 | if (str & I8042_STR_MUXERR) { | 475 | if (str & I8042_STR_MUXERR) { |
472 | dbg("MUX error, status is %02x, data is %02x", str, data); | 476 | dbg("MUX error, status is %02x, data is %02x\n", |
477 | str, data); | ||
473 | /* | 478 | /* |
474 | * When MUXERR condition is signalled the data register can only contain | 479 | * When MUXERR condition is signalled the data register can only contain |
475 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately | 480 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately |
@@ -503,7 +508,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
503 | } else { | 508 | } else { |
504 | 509 | ||
505 | dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | | 510 | dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | |
506 | ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0); | 511 | ((str & I8042_STR_TIMEOUT && !i8042_notimeout) ? SERIO_TIMEOUT : 0); |
507 | 512 | ||
508 | port_no = (str & I8042_STR_AUXDATA) ? | 513 | port_no = (str & I8042_STR_AUXDATA) ? |
509 | I8042_AUX_PORT_NO : I8042_KBD_PORT_NO; | 514 | I8042_AUX_PORT_NO : I8042_KBD_PORT_NO; |
@@ -512,7 +517,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
512 | port = &i8042_ports[port_no]; | 517 | port = &i8042_ports[port_no]; |
513 | serio = port->exists ? port->serio : NULL; | 518 | serio = port->exists ? port->serio : NULL; |
514 | 519 | ||
515 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)", | 520 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)\n", |
516 | data, port_no, irq, | 521 | data, port_no, irq, |
517 | dfl & SERIO_PARITY ? ", bad parity" : "", | 522 | dfl & SERIO_PARITY ? ", bad parity" : "", |
518 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); | 523 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); |
@@ -540,7 +545,7 @@ static int i8042_enable_kbd_port(void) | |||
540 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 545 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
541 | i8042_ctr &= ~I8042_CTR_KBDINT; | 546 | i8042_ctr &= ~I8042_CTR_KBDINT; |
542 | i8042_ctr |= I8042_CTR_KBDDIS; | 547 | i8042_ctr |= I8042_CTR_KBDDIS; |
543 | printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n"); | 548 | pr_err("Failed to enable KBD port\n"); |
544 | return -EIO; | 549 | return -EIO; |
545 | } | 550 | } |
546 | 551 | ||
@@ -559,7 +564,7 @@ static int i8042_enable_aux_port(void) | |||
559 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 564 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
560 | i8042_ctr &= ~I8042_CTR_AUXINT; | 565 | i8042_ctr &= ~I8042_CTR_AUXINT; |
561 | i8042_ctr |= I8042_CTR_AUXDIS; | 566 | i8042_ctr |= I8042_CTR_AUXDIS; |
562 | printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n"); | 567 | pr_err("Failed to enable AUX port\n"); |
563 | return -EIO; | 568 | return -EIO; |
564 | } | 569 | } |
565 | 570 | ||
@@ -641,7 +646,7 @@ static int __init i8042_check_mux(void) | |||
641 | if (i8042_set_mux_mode(true, &mux_version)) | 646 | if (i8042_set_mux_mode(true, &mux_version)) |
642 | return -1; | 647 | return -1; |
643 | 648 | ||
644 | printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n", | 649 | pr_info("Detected active multiplexing controller, rev %d.%d\n", |
645 | (mux_version >> 4) & 0xf, mux_version & 0xf); | 650 | (mux_version >> 4) & 0xf, mux_version & 0xf); |
646 | 651 | ||
647 | /* | 652 | /* |
@@ -651,7 +656,7 @@ static int __init i8042_check_mux(void) | |||
651 | i8042_ctr &= ~I8042_CTR_AUXINT; | 656 | i8042_ctr &= ~I8042_CTR_AUXINT; |
652 | 657 | ||
653 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 658 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
654 | printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n"); | 659 | pr_err("Failed to disable AUX port, can't use MUX\n"); |
655 | return -EIO; | 660 | return -EIO; |
656 | } | 661 | } |
657 | 662 | ||
@@ -676,8 +681,8 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id) | |||
676 | str = i8042_read_status(); | 681 | str = i8042_read_status(); |
677 | if (str & I8042_STR_OBF) { | 682 | if (str & I8042_STR_OBF) { |
678 | data = i8042_read_data(); | 683 | data = i8042_read_data(); |
679 | dbg("%02x <- i8042 (aux_test_irq, %s)", | 684 | dbg("%02x <- i8042 (aux_test_irq, %s)\n", |
680 | data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); | 685 | data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); |
681 | if (i8042_irq_being_tested && | 686 | if (i8042_irq_being_tested && |
682 | data == 0xa5 && (str & I8042_STR_AUXDATA)) | 687 | data == 0xa5 && (str & I8042_STR_AUXDATA)) |
683 | complete(&i8042_aux_irq_delivered); | 688 | complete(&i8042_aux_irq_delivered); |
@@ -770,8 +775,8 @@ static int __init i8042_check_aux(void) | |||
770 | */ | 775 | */ |
771 | 776 | ||
772 | if (i8042_toggle_aux(false)) { | 777 | if (i8042_toggle_aux(false)) { |
773 | printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); | 778 | pr_warn("Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); |
774 | printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n"); | 779 | pr_warn("If AUX port is really absent please use the 'i8042.noaux' option\n"); |
775 | } | 780 | } |
776 | 781 | ||
777 | if (i8042_toggle_aux(true)) | 782 | if (i8042_toggle_aux(true)) |
@@ -819,7 +824,7 @@ static int __init i8042_check_aux(void) | |||
819 | * AUX IRQ was never delivered so we need to flush the controller to | 824 | * AUX IRQ was never delivered so we need to flush the controller to |
820 | * get rid of the byte we put there; otherwise keyboard may not work. | 825 | * get rid of the byte we put there; otherwise keyboard may not work. |
821 | */ | 826 | */ |
822 | dbg(" -- i8042 (aux irq test timeout)"); | 827 | dbg(" -- i8042 (aux irq test timeout)\n"); |
823 | i8042_flush(); | 828 | i8042_flush(); |
824 | retval = -1; | 829 | retval = -1; |
825 | } | 830 | } |
@@ -845,7 +850,7 @@ static int __init i8042_check_aux(void) | |||
845 | static int i8042_controller_check(void) | 850 | static int i8042_controller_check(void) |
846 | { | 851 | { |
847 | if (i8042_flush() == I8042_BUFFER_SIZE) { | 852 | if (i8042_flush() == I8042_BUFFER_SIZE) { |
848 | printk(KERN_ERR "i8042.c: No controller found.\n"); | 853 | pr_err("No controller found\n"); |
849 | return -ENODEV; | 854 | return -ENODEV; |
850 | } | 855 | } |
851 | 856 | ||
@@ -864,15 +869,15 @@ static int i8042_controller_selftest(void) | |||
864 | do { | 869 | do { |
865 | 870 | ||
866 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | 871 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { |
867 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | 872 | pr_err("i8042 controller selftest timeout\n"); |
868 | return -ENODEV; | 873 | return -ENODEV; |
869 | } | 874 | } |
870 | 875 | ||
871 | if (param == I8042_RET_CTL_TEST) | 876 | if (param == I8042_RET_CTL_TEST) |
872 | return 0; | 877 | return 0; |
873 | 878 | ||
874 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | 879 | dbg("i8042 controller selftest: %#x != %#x\n", |
875 | param, I8042_RET_CTL_TEST); | 880 | param, I8042_RET_CTL_TEST); |
876 | msleep(50); | 881 | msleep(50); |
877 | } while (i++ < 5); | 882 | } while (i++ < 5); |
878 | 883 | ||
@@ -883,10 +888,10 @@ static int i8042_controller_selftest(void) | |||
883 | * and user will still get a working keyboard. This is especially | 888 | * and user will still get a working keyboard. This is especially |
884 | * important on netbooks. On other arches we trust hardware more. | 889 | * important on netbooks. On other arches we trust hardware more. |
885 | */ | 890 | */ |
886 | printk(KERN_INFO | 891 | pr_info("giving up on controller selftest, continuing anyway...\n"); |
887 | "i8042: giving up on controller selftest, continuing anyway...\n"); | ||
888 | return 0; | 892 | return 0; |
889 | #else | 893 | #else |
894 | pr_err("i8042 controller selftest failed\n"); | ||
890 | return -EIO; | 895 | return -EIO; |
891 | #endif | 896 | #endif |
892 | } | 897 | } |
@@ -909,8 +914,7 @@ static int i8042_controller_init(void) | |||
909 | 914 | ||
910 | do { | 915 | do { |
911 | if (n >= 10) { | 916 | if (n >= 10) { |
912 | printk(KERN_ERR | 917 | pr_err("Unable to get stable CTR read\n"); |
913 | "i8042.c: Unable to get stable CTR read.\n"); | ||
914 | return -EIO; | 918 | return -EIO; |
915 | } | 919 | } |
916 | 920 | ||
@@ -918,8 +922,7 @@ static int i8042_controller_init(void) | |||
918 | udelay(50); | 922 | udelay(50); |
919 | 923 | ||
920 | if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { | 924 | if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { |
921 | printk(KERN_ERR | 925 | pr_err("Can't read CTR while initializing i8042\n"); |
922 | "i8042.c: Can't read CTR while initializing i8042.\n"); | ||
923 | return -EIO; | 926 | return -EIO; |
924 | } | 927 | } |
925 | 928 | ||
@@ -943,7 +946,7 @@ static int i8042_controller_init(void) | |||
943 | if (i8042_unlock) | 946 | if (i8042_unlock) |
944 | i8042_ctr |= I8042_CTR_IGNKEYLOCK; | 947 | i8042_ctr |= I8042_CTR_IGNKEYLOCK; |
945 | else | 948 | else |
946 | printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n"); | 949 | pr_warn("Warning: Keylock active\n"); |
947 | } | 950 | } |
948 | spin_unlock_irqrestore(&i8042_lock, flags); | 951 | spin_unlock_irqrestore(&i8042_lock, flags); |
949 | 952 | ||
@@ -970,7 +973,7 @@ static int i8042_controller_init(void) | |||
970 | */ | 973 | */ |
971 | 974 | ||
972 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 975 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
973 | printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n"); | 976 | pr_err("Can't write CTR while initializing i8042\n"); |
974 | return -EIO; | 977 | return -EIO; |
975 | } | 978 | } |
976 | 979 | ||
@@ -1000,7 +1003,7 @@ static void i8042_controller_reset(void) | |||
1000 | i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); | 1003 | i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); |
1001 | 1004 | ||
1002 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) | 1005 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) |
1003 | printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n"); | 1006 | pr_warn("Can't write CTR while resetting\n"); |
1004 | 1007 | ||
1005 | /* | 1008 | /* |
1006 | * Disable MUX mode if present. | 1009 | * Disable MUX mode if present. |
@@ -1021,7 +1024,7 @@ static void i8042_controller_reset(void) | |||
1021 | */ | 1024 | */ |
1022 | 1025 | ||
1023 | if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) | 1026 | if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) |
1024 | printk(KERN_WARNING "i8042.c: Can't restore CTR.\n"); | 1027 | pr_warn("Can't restore CTR\n"); |
1025 | } | 1028 | } |
1026 | 1029 | ||
1027 | 1030 | ||
@@ -1045,14 +1048,14 @@ static long i8042_panic_blink(int state) | |||
1045 | led = (state) ? 0x01 | 0x04 : 0; | 1048 | led = (state) ? 0x01 | 0x04 : 0; |
1046 | while (i8042_read_status() & I8042_STR_IBF) | 1049 | while (i8042_read_status() & I8042_STR_IBF) |
1047 | DELAY; | 1050 | DELAY; |
1048 | dbg("%02x -> i8042 (panic blink)", 0xed); | 1051 | dbg("%02x -> i8042 (panic blink)\n", 0xed); |
1049 | i8042_suppress_kbd_ack = 2; | 1052 | i8042_suppress_kbd_ack = 2; |
1050 | i8042_write_data(0xed); /* set leds */ | 1053 | i8042_write_data(0xed); /* set leds */ |
1051 | DELAY; | 1054 | DELAY; |
1052 | while (i8042_read_status() & I8042_STR_IBF) | 1055 | while (i8042_read_status() & I8042_STR_IBF) |
1053 | DELAY; | 1056 | DELAY; |
1054 | DELAY; | 1057 | DELAY; |
1055 | dbg("%02x -> i8042 (panic blink)", led); | 1058 | dbg("%02x -> i8042 (panic blink)\n", led); |
1056 | i8042_write_data(led); | 1059 | i8042_write_data(led); |
1057 | DELAY; | 1060 | DELAY; |
1058 | return delay; | 1061 | return delay; |
@@ -1063,14 +1066,12 @@ static long i8042_panic_blink(int state) | |||
1063 | #ifdef CONFIG_X86 | 1066 | #ifdef CONFIG_X86 |
1064 | static void i8042_dritek_enable(void) | 1067 | static void i8042_dritek_enable(void) |
1065 | { | 1068 | { |
1066 | char param = 0x90; | 1069 | unsigned char param = 0x90; |
1067 | int error; | 1070 | int error; |
1068 | 1071 | ||
1069 | error = i8042_command(¶m, 0x1059); | 1072 | error = i8042_command(¶m, 0x1059); |
1070 | if (error) | 1073 | if (error) |
1071 | printk(KERN_WARNING | 1074 | pr_warn("Failed to enable DRITEK extension: %d\n", error); |
1072 | "Failed to enable DRITEK extension: %d\n", | ||
1073 | error); | ||
1074 | } | 1075 | } |
1075 | #endif | 1076 | #endif |
1076 | 1077 | ||
@@ -1105,10 +1106,10 @@ static int i8042_controller_resume(bool force_reset) | |||
1105 | i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; | 1106 | i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; |
1106 | i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); | 1107 | i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); |
1107 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 1108 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
1108 | printk(KERN_WARNING "i8042: Can't write CTR to resume, retrying...\n"); | 1109 | pr_warn("Can't write CTR to resume, retrying...\n"); |
1109 | msleep(50); | 1110 | msleep(50); |
1110 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 1111 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
1111 | printk(KERN_ERR "i8042: CTR write retry failed\n"); | 1112 | pr_err("CTR write retry failed\n"); |
1112 | return -EIO; | 1113 | return -EIO; |
1113 | } | 1114 | } |
1114 | } | 1115 | } |
@@ -1121,9 +1122,7 @@ static int i8042_controller_resume(bool force_reset) | |||
1121 | 1122 | ||
1122 | if (i8042_mux_present) { | 1123 | if (i8042_mux_present) { |
1123 | if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports()) | 1124 | if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports()) |
1124 | printk(KERN_WARNING | 1125 | pr_warn("failed to resume active multiplexor, mouse won't work\n"); |
1125 | "i8042: failed to resume active multiplexor, " | ||
1126 | "mouse won't work.\n"); | ||
1127 | } else if (i8042_ports[I8042_AUX_PORT_NO].serio) | 1126 | } else if (i8042_ports[I8042_AUX_PORT_NO].serio) |
1128 | i8042_enable_aux_port(); | 1127 | i8042_enable_aux_port(); |
1129 | 1128 | ||
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index cbc1beb66574..3452708fbe3b 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #include "i8042-sparcio.h" | 26 | #include "i8042-sparcio.h" |
27 | #elif defined(CONFIG_X86) || defined(CONFIG_IA64) | 27 | #elif defined(CONFIG_X86) || defined(CONFIG_IA64) |
28 | #include "i8042-x86ia64io.h" | 28 | #include "i8042-x86ia64io.h" |
29 | #elif defined(CONFIG_UNICORE32) | ||
30 | #include "i8042-unicore32io.h" | ||
29 | #else | 31 | #else |
30 | #include "i8042-io.h" | 32 | #include "i8042-io.h" |
31 | #endif | 33 | #endif |
@@ -89,15 +91,19 @@ | |||
89 | #ifdef DEBUG | 91 | #ifdef DEBUG |
90 | static unsigned long i8042_start_time; | 92 | static unsigned long i8042_start_time; |
91 | #define dbg_init() do { i8042_start_time = jiffies; } while (0) | 93 | #define dbg_init() do { i8042_start_time = jiffies; } while (0) |
92 | #define dbg(format, arg...) \ | 94 | #define dbg(format, arg...) \ |
93 | do { \ | 95 | do { \ |
94 | if (i8042_debug) \ | 96 | if (i8042_debug) \ |
95 | printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" , \ | 97 | printk(KERN_DEBUG KBUILD_MODNAME ": [%d] " format, \ |
96 | ## arg, (int) (jiffies - i8042_start_time)); \ | 98 | (int) (jiffies - i8042_start_time), ##arg); \ |
97 | } while (0) | 99 | } while (0) |
98 | #else | 100 | #else |
99 | #define dbg_init() do { } while (0) | 101 | #define dbg_init() do { } while (0) |
100 | #define dbg(format, arg...) do {} while (0) | 102 | #define dbg(format, arg...) \ |
103 | do { \ | ||
104 | if (0) \ | ||
105 | printk(KERN_DEBUG pr_fmt(format), ##arg); \ | ||
106 | } while (0) | ||
101 | #endif | 107 | #endif |
102 | 108 | ||
103 | #endif /* _I8042_H */ | 109 | #endif /* _I8042_H */ |
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c new file mode 100644 index 000000000000..15aa81c9f1fb --- /dev/null +++ b/drivers/input/serio/ps2mult.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * TQC PS/2 Multiplexer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Dmitry Eremin-Solenikov | ||
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 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/serio.h> | ||
16 | |||
17 | MODULE_AUTHOR("Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>"); | ||
18 | MODULE_DESCRIPTION("TQC PS/2 Multiplexer driver"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | #define PS2MULT_KB_SELECTOR 0xA0 | ||
22 | #define PS2MULT_MS_SELECTOR 0xA1 | ||
23 | #define PS2MULT_ESCAPE 0x7D | ||
24 | #define PS2MULT_BSYNC 0x7E | ||
25 | #define PS2MULT_SESSION_START 0x55 | ||
26 | #define PS2MULT_SESSION_END 0x56 | ||
27 | |||
28 | struct ps2mult_port { | ||
29 | struct serio *serio; | ||
30 | unsigned char sel; | ||
31 | bool registered; | ||
32 | }; | ||
33 | |||
34 | #define PS2MULT_NUM_PORTS 2 | ||
35 | #define PS2MULT_KBD_PORT 0 | ||
36 | #define PS2MULT_MOUSE_PORT 1 | ||
37 | |||
38 | struct ps2mult { | ||
39 | struct serio *mx_serio; | ||
40 | struct ps2mult_port ports[PS2MULT_NUM_PORTS]; | ||
41 | |||
42 | spinlock_t lock; | ||
43 | struct ps2mult_port *in_port; | ||
44 | struct ps2mult_port *out_port; | ||
45 | bool escape; | ||
46 | }; | ||
47 | |||
48 | /* First MUST come PS2MULT_NUM_PORTS selectors */ | ||
49 | static const unsigned char ps2mult_controls[] = { | ||
50 | PS2MULT_KB_SELECTOR, PS2MULT_MS_SELECTOR, | ||
51 | PS2MULT_ESCAPE, PS2MULT_BSYNC, | ||
52 | PS2MULT_SESSION_START, PS2MULT_SESSION_END, | ||
53 | }; | ||
54 | |||
55 | static const struct serio_device_id ps2mult_serio_ids[] = { | ||
56 | { | ||
57 | .type = SERIO_RS232, | ||
58 | .proto = SERIO_PS2MULT, | ||
59 | .id = SERIO_ANY, | ||
60 | .extra = SERIO_ANY, | ||
61 | }, | ||
62 | { 0 } | ||
63 | }; | ||
64 | |||
65 | MODULE_DEVICE_TABLE(serio, ps2mult_serio_ids); | ||
66 | |||
67 | static void ps2mult_select_port(struct ps2mult *psm, struct ps2mult_port *port) | ||
68 | { | ||
69 | struct serio *mx_serio = psm->mx_serio; | ||
70 | |||
71 | serio_write(mx_serio, port->sel); | ||
72 | psm->out_port = port; | ||
73 | dev_dbg(&mx_serio->dev, "switched to sel %02x\n", port->sel); | ||
74 | } | ||
75 | |||
76 | static int ps2mult_serio_write(struct serio *serio, unsigned char data) | ||
77 | { | ||
78 | struct serio *mx_port = serio->parent; | ||
79 | struct ps2mult *psm = serio_get_drvdata(mx_port); | ||
80 | struct ps2mult_port *port = serio->port_data; | ||
81 | bool need_escape; | ||
82 | unsigned long flags; | ||
83 | |||
84 | spin_lock_irqsave(&psm->lock, flags); | ||
85 | |||
86 | if (psm->out_port != port) | ||
87 | ps2mult_select_port(psm, port); | ||
88 | |||
89 | need_escape = memchr(ps2mult_controls, data, sizeof(ps2mult_controls)); | ||
90 | |||
91 | dev_dbg(&serio->dev, | ||
92 | "write: %s%02x\n", need_escape ? "ESC " : "", data); | ||
93 | |||
94 | if (need_escape) | ||
95 | serio_write(mx_port, PS2MULT_ESCAPE); | ||
96 | |||
97 | serio_write(mx_port, data); | ||
98 | |||
99 | spin_unlock_irqrestore(&psm->lock, flags); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int ps2mult_serio_start(struct serio *serio) | ||
105 | { | ||
106 | struct ps2mult *psm = serio_get_drvdata(serio->parent); | ||
107 | struct ps2mult_port *port = serio->port_data; | ||
108 | unsigned long flags; | ||
109 | |||
110 | spin_lock_irqsave(&psm->lock, flags); | ||
111 | port->registered = true; | ||
112 | spin_unlock_irqrestore(&psm->lock, flags); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static void ps2mult_serio_stop(struct serio *serio) | ||
118 | { | ||
119 | struct ps2mult *psm = serio_get_drvdata(serio->parent); | ||
120 | struct ps2mult_port *port = serio->port_data; | ||
121 | unsigned long flags; | ||
122 | |||
123 | spin_lock_irqsave(&psm->lock, flags); | ||
124 | port->registered = false; | ||
125 | spin_unlock_irqrestore(&psm->lock, flags); | ||
126 | } | ||
127 | |||
128 | static int ps2mult_create_port(struct ps2mult *psm, int i) | ||
129 | { | ||
130 | struct serio *mx_serio = psm->mx_serio; | ||
131 | struct serio *serio; | ||
132 | |||
133 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
134 | if (!serio) | ||
135 | return -ENOMEM; | ||
136 | |||
137 | strlcpy(serio->name, "TQC PS/2 Multiplexer", sizeof(serio->name)); | ||
138 | snprintf(serio->phys, sizeof(serio->phys), | ||
139 | "%s/port%d", mx_serio->phys, i); | ||
140 | serio->id.type = SERIO_8042; | ||
141 | serio->write = ps2mult_serio_write; | ||
142 | serio->start = ps2mult_serio_start; | ||
143 | serio->stop = ps2mult_serio_stop; | ||
144 | serio->parent = psm->mx_serio; | ||
145 | serio->port_data = &psm->ports[i]; | ||
146 | |||
147 | psm->ports[i].serio = serio; | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static void ps2mult_reset(struct ps2mult *psm) | ||
153 | { | ||
154 | unsigned long flags; | ||
155 | |||
156 | spin_lock_irqsave(&psm->lock, flags); | ||
157 | |||
158 | serio_write(psm->mx_serio, PS2MULT_SESSION_END); | ||
159 | serio_write(psm->mx_serio, PS2MULT_SESSION_START); | ||
160 | |||
161 | ps2mult_select_port(psm, &psm->ports[PS2MULT_KBD_PORT]); | ||
162 | |||
163 | spin_unlock_irqrestore(&psm->lock, flags); | ||
164 | } | ||
165 | |||
166 | static int ps2mult_connect(struct serio *serio, struct serio_driver *drv) | ||
167 | { | ||
168 | struct ps2mult *psm; | ||
169 | int i; | ||
170 | int error; | ||
171 | |||
172 | if (!serio->write) | ||
173 | return -EINVAL; | ||
174 | |||
175 | psm = kzalloc(sizeof(*psm), GFP_KERNEL); | ||
176 | if (!psm) | ||
177 | return -ENOMEM; | ||
178 | |||
179 | spin_lock_init(&psm->lock); | ||
180 | psm->mx_serio = serio; | ||
181 | |||
182 | for (i = 0; i < PS2MULT_NUM_PORTS; i++) { | ||
183 | psm->ports[i].sel = ps2mult_controls[i]; | ||
184 | error = ps2mult_create_port(psm, i); | ||
185 | if (error) | ||
186 | goto err_out; | ||
187 | } | ||
188 | |||
189 | psm->in_port = psm->out_port = &psm->ports[PS2MULT_KBD_PORT]; | ||
190 | |||
191 | serio_set_drvdata(serio, psm); | ||
192 | error = serio_open(serio, drv); | ||
193 | if (error) | ||
194 | goto err_out; | ||
195 | |||
196 | ps2mult_reset(psm); | ||
197 | |||
198 | for (i = 0; i < PS2MULT_NUM_PORTS; i++) { | ||
199 | struct serio *s = psm->ports[i].serio; | ||
200 | |||
201 | dev_info(&serio->dev, "%s port at %s\n", s->name, serio->phys); | ||
202 | serio_register_port(s); | ||
203 | } | ||
204 | |||
205 | return 0; | ||
206 | |||
207 | err_out: | ||
208 | while (--i >= 0) | ||
209 | kfree(psm->ports[i].serio); | ||
210 | kfree(psm); | ||
211 | return error; | ||
212 | } | ||
213 | |||
214 | static void ps2mult_disconnect(struct serio *serio) | ||
215 | { | ||
216 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
217 | |||
218 | /* Note that serio core already take care of children ports */ | ||
219 | serio_write(serio, PS2MULT_SESSION_END); | ||
220 | serio_close(serio); | ||
221 | kfree(psm); | ||
222 | |||
223 | serio_set_drvdata(serio, NULL); | ||
224 | } | ||
225 | |||
226 | static int ps2mult_reconnect(struct serio *serio) | ||
227 | { | ||
228 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
229 | |||
230 | ps2mult_reset(psm); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static irqreturn_t ps2mult_interrupt(struct serio *serio, | ||
236 | unsigned char data, unsigned int dfl) | ||
237 | { | ||
238 | struct ps2mult *psm = serio_get_drvdata(serio); | ||
239 | struct ps2mult_port *in_port; | ||
240 | unsigned long flags; | ||
241 | |||
242 | dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, dfl); | ||
243 | |||
244 | spin_lock_irqsave(&psm->lock, flags); | ||
245 | |||
246 | if (psm->escape) { | ||
247 | psm->escape = false; | ||
248 | in_port = psm->in_port; | ||
249 | if (in_port->registered) | ||
250 | serio_interrupt(in_port->serio, data, dfl); | ||
251 | goto out; | ||
252 | } | ||
253 | |||
254 | switch (data) { | ||
255 | case PS2MULT_ESCAPE: | ||
256 | dev_dbg(&serio->dev, "ESCAPE\n"); | ||
257 | psm->escape = true; | ||
258 | break; | ||
259 | |||
260 | case PS2MULT_BSYNC: | ||
261 | dev_dbg(&serio->dev, "BSYNC\n"); | ||
262 | psm->in_port = psm->out_port; | ||
263 | break; | ||
264 | |||
265 | case PS2MULT_SESSION_START: | ||
266 | dev_dbg(&serio->dev, "SS\n"); | ||
267 | break; | ||
268 | |||
269 | case PS2MULT_SESSION_END: | ||
270 | dev_dbg(&serio->dev, "SE\n"); | ||
271 | break; | ||
272 | |||
273 | case PS2MULT_KB_SELECTOR: | ||
274 | dev_dbg(&serio->dev, "KB\n"); | ||
275 | psm->in_port = &psm->ports[PS2MULT_KBD_PORT]; | ||
276 | break; | ||
277 | |||
278 | case PS2MULT_MS_SELECTOR: | ||
279 | dev_dbg(&serio->dev, "MS\n"); | ||
280 | psm->in_port = &psm->ports[PS2MULT_MOUSE_PORT]; | ||
281 | break; | ||
282 | |||
283 | default: | ||
284 | in_port = psm->in_port; | ||
285 | if (in_port->registered) | ||
286 | serio_interrupt(in_port->serio, data, dfl); | ||
287 | break; | ||
288 | } | ||
289 | |||
290 | out: | ||
291 | spin_unlock_irqrestore(&psm->lock, flags); | ||
292 | return IRQ_HANDLED; | ||
293 | } | ||
294 | |||
295 | static struct serio_driver ps2mult_drv = { | ||
296 | .driver = { | ||
297 | .name = "ps2mult", | ||
298 | }, | ||
299 | .description = "TQC PS/2 Multiplexer driver", | ||
300 | .id_table = ps2mult_serio_ids, | ||
301 | .interrupt = ps2mult_interrupt, | ||
302 | .connect = ps2mult_connect, | ||
303 | .disconnect = ps2mult_disconnect, | ||
304 | .reconnect = ps2mult_reconnect, | ||
305 | }; | ||
306 | |||
307 | static int __init ps2mult_init(void) | ||
308 | { | ||
309 | return serio_register_driver(&ps2mult_drv); | ||
310 | } | ||
311 | |||
312 | static void __exit ps2mult_exit(void) | ||
313 | { | ||
314 | serio_unregister_driver(&ps2mult_drv); | ||
315 | } | ||
316 | |||
317 | module_init(ps2mult_init); | ||
318 | module_exit(ps2mult_exit); | ||
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 9da6fbcaaa7e..7ec3c97dc1b9 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c | |||
@@ -90,7 +90,7 @@ static int rpckbd_open(struct serio *port) | |||
90 | 90 | ||
91 | if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) { | 91 | if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) { |
92 | printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); | 92 | printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); |
93 | free_irq(IRQ_KEYBOARDRX, NULL); | 93 | free_irq(IRQ_KEYBOARDRX, port); |
94 | return -EBUSY; | 94 | return -EBUSY; |
95 | } | 95 | } |
96 | 96 | ||
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index c3b626e9eae7..ba70058e2be3 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -32,12 +32,10 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/serio.h> | 33 | #include <linux/serio.h> |
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/wait.h> | ||
36 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
37 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
38 | #include <linux/kthread.h> | 37 | #include <linux/workqueue.h> |
39 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
40 | #include <linux/freezer.h> | ||
41 | 39 | ||
42 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 40 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
43 | MODULE_DESCRIPTION("Serio abstraction core"); | 41 | MODULE_DESCRIPTION("Serio abstraction core"); |
@@ -45,7 +43,7 @@ MODULE_LICENSE("GPL"); | |||
45 | 43 | ||
46 | /* | 44 | /* |
47 | * serio_mutex protects entire serio subsystem and is taken every time | 45 | * serio_mutex protects entire serio subsystem and is taken every time |
48 | * serio port or driver registrered or unregistered. | 46 | * serio port or driver registered or unregistered. |
49 | */ | 47 | */ |
50 | static DEFINE_MUTEX(serio_mutex); | 48 | static DEFINE_MUTEX(serio_mutex); |
51 | 49 | ||
@@ -56,7 +54,7 @@ static struct bus_type serio_bus; | |||
56 | static void serio_add_port(struct serio *serio); | 54 | static void serio_add_port(struct serio *serio); |
57 | static int serio_reconnect_port(struct serio *serio); | 55 | static int serio_reconnect_port(struct serio *serio); |
58 | static void serio_disconnect_port(struct serio *serio); | 56 | static void serio_disconnect_port(struct serio *serio); |
59 | static void serio_reconnect_chain(struct serio *serio); | 57 | static void serio_reconnect_subtree(struct serio *serio); |
60 | static void serio_attach_driver(struct serio_driver *drv); | 58 | static void serio_attach_driver(struct serio_driver *drv); |
61 | 59 | ||
62 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) | 60 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) |
@@ -152,7 +150,7 @@ static void serio_find_driver(struct serio *serio) | |||
152 | enum serio_event_type { | 150 | enum serio_event_type { |
153 | SERIO_RESCAN_PORT, | 151 | SERIO_RESCAN_PORT, |
154 | SERIO_RECONNECT_PORT, | 152 | SERIO_RECONNECT_PORT, |
155 | SERIO_RECONNECT_CHAIN, | 153 | SERIO_RECONNECT_SUBTREE, |
156 | SERIO_REGISTER_PORT, | 154 | SERIO_REGISTER_PORT, |
157 | SERIO_ATTACH_DRIVER, | 155 | SERIO_ATTACH_DRIVER, |
158 | }; | 156 | }; |
@@ -166,58 +164,22 @@ struct serio_event { | |||
166 | 164 | ||
167 | static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */ | 165 | static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */ |
168 | static LIST_HEAD(serio_event_list); | 166 | static LIST_HEAD(serio_event_list); |
169 | static DECLARE_WAIT_QUEUE_HEAD(serio_wait); | ||
170 | static struct task_struct *serio_task; | ||
171 | 167 | ||
172 | static int serio_queue_event(void *object, struct module *owner, | 168 | static struct serio_event *serio_get_event(void) |
173 | enum serio_event_type event_type) | ||
174 | { | 169 | { |
170 | struct serio_event *event = NULL; | ||
175 | unsigned long flags; | 171 | unsigned long flags; |
176 | struct serio_event *event; | ||
177 | int retval = 0; | ||
178 | 172 | ||
179 | spin_lock_irqsave(&serio_event_lock, flags); | 173 | spin_lock_irqsave(&serio_event_lock, flags); |
180 | 174 | ||
181 | /* | 175 | if (!list_empty(&serio_event_list)) { |
182 | * Scan event list for the other events for the same serio port, | 176 | event = list_first_entry(&serio_event_list, |
183 | * starting with the most recent one. If event is the same we | 177 | struct serio_event, node); |
184 | * do not need add new one. If event is of different type we | 178 | list_del_init(&event->node); |
185 | * need to add this event and should not look further because | ||
186 | * we need to preseve sequence of distinct events. | ||
187 | */ | ||
188 | list_for_each_entry_reverse(event, &serio_event_list, node) { | ||
189 | if (event->object == object) { | ||
190 | if (event->type == event_type) | ||
191 | goto out; | ||
192 | break; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); | ||
197 | if (!event) { | ||
198 | pr_err("Not enough memory to queue event %d\n", event_type); | ||
199 | retval = -ENOMEM; | ||
200 | goto out; | ||
201 | } | ||
202 | |||
203 | if (!try_module_get(owner)) { | ||
204 | pr_warning("Can't get module reference, dropping event %d\n", | ||
205 | event_type); | ||
206 | kfree(event); | ||
207 | retval = -EINVAL; | ||
208 | goto out; | ||
209 | } | 179 | } |
210 | 180 | ||
211 | event->type = event_type; | ||
212 | event->object = object; | ||
213 | event->owner = owner; | ||
214 | |||
215 | list_add_tail(&event->node, &serio_event_list); | ||
216 | wake_up(&serio_wait); | ||
217 | |||
218 | out: | ||
219 | spin_unlock_irqrestore(&serio_event_lock, flags); | 181 | spin_unlock_irqrestore(&serio_event_lock, flags); |
220 | return retval; | 182 | return event; |
221 | } | 183 | } |
222 | 184 | ||
223 | static void serio_free_event(struct serio_event *event) | 185 | static void serio_free_event(struct serio_event *event) |
@@ -226,7 +188,8 @@ static void serio_free_event(struct serio_event *event) | |||
226 | kfree(event); | 188 | kfree(event); |
227 | } | 189 | } |
228 | 190 | ||
229 | static void serio_remove_duplicate_events(struct serio_event *event) | 191 | static void serio_remove_duplicate_events(void *object, |
192 | enum serio_event_type type) | ||
230 | { | 193 | { |
231 | struct serio_event *e, *next; | 194 | struct serio_event *e, *next; |
232 | unsigned long flags; | 195 | unsigned long flags; |
@@ -234,13 +197,13 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
234 | spin_lock_irqsave(&serio_event_lock, flags); | 197 | spin_lock_irqsave(&serio_event_lock, flags); |
235 | 198 | ||
236 | list_for_each_entry_safe(e, next, &serio_event_list, node) { | 199 | list_for_each_entry_safe(e, next, &serio_event_list, node) { |
237 | if (event->object == e->object) { | 200 | if (object == e->object) { |
238 | /* | 201 | /* |
239 | * If this event is of different type we should not | 202 | * If this event is of different type we should not |
240 | * look further - we only suppress duplicate events | 203 | * look further - we only suppress duplicate events |
241 | * that were sent back-to-back. | 204 | * that were sent back-to-back. |
242 | */ | 205 | */ |
243 | if (event->type != e->type) | 206 | if (type != e->type) |
244 | break; | 207 | break; |
245 | 208 | ||
246 | list_del_init(&e->node); | 209 | list_del_init(&e->node); |
@@ -251,25 +214,7 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
251 | spin_unlock_irqrestore(&serio_event_lock, flags); | 214 | spin_unlock_irqrestore(&serio_event_lock, flags); |
252 | } | 215 | } |
253 | 216 | ||
254 | 217 | static void serio_handle_event(struct work_struct *work) | |
255 | static struct serio_event *serio_get_event(void) | ||
256 | { | ||
257 | struct serio_event *event = NULL; | ||
258 | unsigned long flags; | ||
259 | |||
260 | spin_lock_irqsave(&serio_event_lock, flags); | ||
261 | |||
262 | if (!list_empty(&serio_event_list)) { | ||
263 | event = list_first_entry(&serio_event_list, | ||
264 | struct serio_event, node); | ||
265 | list_del_init(&event->node); | ||
266 | } | ||
267 | |||
268 | spin_unlock_irqrestore(&serio_event_lock, flags); | ||
269 | return event; | ||
270 | } | ||
271 | |||
272 | static void serio_handle_event(void) | ||
273 | { | 218 | { |
274 | struct serio_event *event; | 219 | struct serio_event *event; |
275 | 220 | ||
@@ -292,8 +237,8 @@ static void serio_handle_event(void) | |||
292 | serio_find_driver(event->object); | 237 | serio_find_driver(event->object); |
293 | break; | 238 | break; |
294 | 239 | ||
295 | case SERIO_RECONNECT_CHAIN: | 240 | case SERIO_RECONNECT_SUBTREE: |
296 | serio_reconnect_chain(event->object); | 241 | serio_reconnect_subtree(event->object); |
297 | break; | 242 | break; |
298 | 243 | ||
299 | case SERIO_ATTACH_DRIVER: | 244 | case SERIO_ATTACH_DRIVER: |
@@ -301,13 +246,66 @@ static void serio_handle_event(void) | |||
301 | break; | 246 | break; |
302 | } | 247 | } |
303 | 248 | ||
304 | serio_remove_duplicate_events(event); | 249 | serio_remove_duplicate_events(event->object, event->type); |
305 | serio_free_event(event); | 250 | serio_free_event(event); |
306 | } | 251 | } |
307 | 252 | ||
308 | mutex_unlock(&serio_mutex); | 253 | mutex_unlock(&serio_mutex); |
309 | } | 254 | } |
310 | 255 | ||
256 | static DECLARE_WORK(serio_event_work, serio_handle_event); | ||
257 | |||
258 | static int serio_queue_event(void *object, struct module *owner, | ||
259 | enum serio_event_type event_type) | ||
260 | { | ||
261 | unsigned long flags; | ||
262 | struct serio_event *event; | ||
263 | int retval = 0; | ||
264 | |||
265 | spin_lock_irqsave(&serio_event_lock, flags); | ||
266 | |||
267 | /* | ||
268 | * Scan event list for the other events for the same serio port, | ||
269 | * starting with the most recent one. If event is the same we | ||
270 | * do not need add new one. If event is of different type we | ||
271 | * need to add this event and should not look further because | ||
272 | * we need to preseve sequence of distinct events. | ||
273 | */ | ||
274 | list_for_each_entry_reverse(event, &serio_event_list, node) { | ||
275 | if (event->object == object) { | ||
276 | if (event->type == event_type) | ||
277 | goto out; | ||
278 | break; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); | ||
283 | if (!event) { | ||
284 | pr_err("Not enough memory to queue event %d\n", event_type); | ||
285 | retval = -ENOMEM; | ||
286 | goto out; | ||
287 | } | ||
288 | |||
289 | if (!try_module_get(owner)) { | ||
290 | pr_warning("Can't get module reference, dropping event %d\n", | ||
291 | event_type); | ||
292 | kfree(event); | ||
293 | retval = -EINVAL; | ||
294 | goto out; | ||
295 | } | ||
296 | |||
297 | event->type = event_type; | ||
298 | event->object = object; | ||
299 | event->owner = owner; | ||
300 | |||
301 | list_add_tail(&event->node, &serio_event_list); | ||
302 | queue_work(system_long_wq, &serio_event_work); | ||
303 | |||
304 | out: | ||
305 | spin_unlock_irqrestore(&serio_event_lock, flags); | ||
306 | return retval; | ||
307 | } | ||
308 | |||
311 | /* | 309 | /* |
312 | * Remove all events that have been submitted for a given | 310 | * Remove all events that have been submitted for a given |
313 | * object, be it serio port or driver. | 311 | * object, be it serio port or driver. |
@@ -330,12 +328,10 @@ static void serio_remove_pending_events(void *object) | |||
330 | } | 328 | } |
331 | 329 | ||
332 | /* | 330 | /* |
333 | * Destroy child serio port (if any) that has not been fully registered yet. | 331 | * Locate child serio port (if any) that has not been fully registered yet. |
334 | * | 332 | * |
335 | * Note that we rely on the fact that port can have only one child and therefore | 333 | * Children are registered by driver's connect() handler so there can't be a |
336 | * only one child registration request can be pending. Additionally, children | 334 | * grandchild pending registration together with a child. |
337 | * are registered by driver's connect() handler so there can't be a grandchild | ||
338 | * pending registration together with a child. | ||
339 | */ | 335 | */ |
340 | static struct serio *serio_get_pending_child(struct serio *parent) | 336 | static struct serio *serio_get_pending_child(struct serio *parent) |
341 | { | 337 | { |
@@ -359,18 +355,6 @@ static struct serio *serio_get_pending_child(struct serio *parent) | |||
359 | return child; | 355 | return child; |
360 | } | 356 | } |
361 | 357 | ||
362 | static int serio_thread(void *nothing) | ||
363 | { | ||
364 | do { | ||
365 | serio_handle_event(); | ||
366 | wait_event_interruptible(serio_wait, | ||
367 | kthread_should_stop() || !list_empty(&serio_event_list)); | ||
368 | } while (!kthread_should_stop()); | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | |||
374 | /* | 358 | /* |
375 | * Serio port operations | 359 | * Serio port operations |
376 | */ | 360 | */ |
@@ -449,14 +433,16 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * | |||
449 | if (!strncmp(buf, "none", count)) { | 433 | if (!strncmp(buf, "none", count)) { |
450 | serio_disconnect_port(serio); | 434 | serio_disconnect_port(serio); |
451 | } else if (!strncmp(buf, "reconnect", count)) { | 435 | } else if (!strncmp(buf, "reconnect", count)) { |
452 | serio_reconnect_chain(serio); | 436 | serio_reconnect_subtree(serio); |
453 | } else if (!strncmp(buf, "rescan", count)) { | 437 | } else if (!strncmp(buf, "rescan", count)) { |
454 | serio_disconnect_port(serio); | 438 | serio_disconnect_port(serio); |
455 | serio_find_driver(serio); | 439 | serio_find_driver(serio); |
440 | serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); | ||
456 | } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { | 441 | } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { |
457 | serio_disconnect_port(serio); | 442 | serio_disconnect_port(serio); |
458 | error = serio_bind_driver(serio, to_serio_driver(drv)); | 443 | error = serio_bind_driver(serio, to_serio_driver(drv)); |
459 | put_driver(drv); | 444 | put_driver(drv); |
445 | serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); | ||
460 | } else { | 446 | } else { |
461 | error = -EINVAL; | 447 | error = -EINVAL; |
462 | } | 448 | } |
@@ -516,6 +502,8 @@ static void serio_init_port(struct serio *serio) | |||
516 | __module_get(THIS_MODULE); | 502 | __module_get(THIS_MODULE); |
517 | 503 | ||
518 | INIT_LIST_HEAD(&serio->node); | 504 | INIT_LIST_HEAD(&serio->node); |
505 | INIT_LIST_HEAD(&serio->child_node); | ||
506 | INIT_LIST_HEAD(&serio->children); | ||
519 | spin_lock_init(&serio->lock); | 507 | spin_lock_init(&serio->lock); |
520 | mutex_init(&serio->drv_mutex); | 508 | mutex_init(&serio->drv_mutex); |
521 | device_initialize(&serio->dev); | 509 | device_initialize(&serio->dev); |
@@ -538,12 +526,13 @@ static void serio_init_port(struct serio *serio) | |||
538 | */ | 526 | */ |
539 | static void serio_add_port(struct serio *serio) | 527 | static void serio_add_port(struct serio *serio) |
540 | { | 528 | { |
529 | struct serio *parent = serio->parent; | ||
541 | int error; | 530 | int error; |
542 | 531 | ||
543 | if (serio->parent) { | 532 | if (parent) { |
544 | serio_pause_rx(serio->parent); | 533 | serio_pause_rx(parent); |
545 | serio->parent->child = serio; | 534 | list_add_tail(&serio->child_node, &parent->children); |
546 | serio_continue_rx(serio->parent); | 535 | serio_continue_rx(parent); |
547 | } | 536 | } |
548 | 537 | ||
549 | list_add_tail(&serio->node, &serio_list); | 538 | list_add_tail(&serio->node, &serio_list); |
@@ -559,15 +548,14 @@ static void serio_add_port(struct serio *serio) | |||
559 | } | 548 | } |
560 | 549 | ||
561 | /* | 550 | /* |
562 | * serio_destroy_port() completes deregistration process and removes | 551 | * serio_destroy_port() completes unregistration process and removes |
563 | * port from the system | 552 | * port from the system |
564 | */ | 553 | */ |
565 | static void serio_destroy_port(struct serio *serio) | 554 | static void serio_destroy_port(struct serio *serio) |
566 | { | 555 | { |
567 | struct serio *child; | 556 | struct serio *child; |
568 | 557 | ||
569 | child = serio_get_pending_child(serio); | 558 | while ((child = serio_get_pending_child(serio)) != NULL) { |
570 | if (child) { | ||
571 | serio_remove_pending_events(child); | 559 | serio_remove_pending_events(child); |
572 | put_device(&child->dev); | 560 | put_device(&child->dev); |
573 | } | 561 | } |
@@ -577,7 +565,7 @@ static void serio_destroy_port(struct serio *serio) | |||
577 | 565 | ||
578 | if (serio->parent) { | 566 | if (serio->parent) { |
579 | serio_pause_rx(serio->parent); | 567 | serio_pause_rx(serio->parent); |
580 | serio->parent->child = NULL; | 568 | list_del_init(&serio->child_node); |
581 | serio_continue_rx(serio->parent); | 569 | serio_continue_rx(serio->parent); |
582 | serio->parent = NULL; | 570 | serio->parent = NULL; |
583 | } | 571 | } |
@@ -609,46 +597,82 @@ static int serio_reconnect_port(struct serio *serio) | |||
609 | } | 597 | } |
610 | 598 | ||
611 | /* | 599 | /* |
612 | * Reconnect serio port and all its children (re-initialize attached devices) | 600 | * Reconnect serio port and all its children (re-initialize attached |
601 | * devices). | ||
613 | */ | 602 | */ |
614 | static void serio_reconnect_chain(struct serio *serio) | 603 | static void serio_reconnect_subtree(struct serio *root) |
615 | { | 604 | { |
605 | struct serio *s = root; | ||
606 | int error; | ||
607 | |||
616 | do { | 608 | do { |
617 | if (serio_reconnect_port(serio)) { | 609 | error = serio_reconnect_port(s); |
618 | /* Ok, old children are now gone, we are done */ | 610 | if (!error) { |
619 | break; | 611 | /* |
612 | * Reconnect was successful, move on to do the | ||
613 | * first child. | ||
614 | */ | ||
615 | if (!list_empty(&s->children)) { | ||
616 | s = list_first_entry(&s->children, | ||
617 | struct serio, child_node); | ||
618 | continue; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * Either it was a leaf node or reconnect failed and it | ||
624 | * became a leaf node. Continue reconnecting starting with | ||
625 | * the next sibling of the parent node. | ||
626 | */ | ||
627 | while (s != root) { | ||
628 | struct serio *parent = s->parent; | ||
629 | |||
630 | if (!list_is_last(&s->child_node, &parent->children)) { | ||
631 | s = list_entry(s->child_node.next, | ||
632 | struct serio, child_node); | ||
633 | break; | ||
634 | } | ||
635 | |||
636 | s = parent; | ||
620 | } | 637 | } |
621 | serio = serio->child; | 638 | } while (s != root); |
622 | } while (serio); | ||
623 | } | 639 | } |
624 | 640 | ||
625 | /* | 641 | /* |
626 | * serio_disconnect_port() unbinds a port from its driver. As a side effect | 642 | * serio_disconnect_port() unbinds a port from its driver. As a side effect |
627 | * all child ports are unbound and destroyed. | 643 | * all children ports are unbound and destroyed. |
628 | */ | 644 | */ |
629 | static void serio_disconnect_port(struct serio *serio) | 645 | static void serio_disconnect_port(struct serio *serio) |
630 | { | 646 | { |
631 | struct serio *s, *parent; | 647 | struct serio *s = serio; |
648 | |||
649 | /* | ||
650 | * Children ports should be disconnected and destroyed | ||
651 | * first; we travel the tree in depth-first order. | ||
652 | */ | ||
653 | while (!list_empty(&serio->children)) { | ||
654 | |||
655 | /* Locate a leaf */ | ||
656 | while (!list_empty(&s->children)) | ||
657 | s = list_first_entry(&s->children, | ||
658 | struct serio, child_node); | ||
632 | 659 | ||
633 | if (serio->child) { | ||
634 | /* | 660 | /* |
635 | * Children ports should be disconnected and destroyed | 661 | * Prune this leaf node unless it is the one we |
636 | * first, staring with the leaf one, since we don't want | 662 | * started with. |
637 | * to do recursion | ||
638 | */ | 663 | */ |
639 | for (s = serio; s->child; s = s->child) | 664 | if (s != serio) { |
640 | /* empty */; | 665 | struct serio *parent = s->parent; |
641 | |||
642 | do { | ||
643 | parent = s->parent; | ||
644 | 666 | ||
645 | device_release_driver(&s->dev); | 667 | device_release_driver(&s->dev); |
646 | serio_destroy_port(s); | 668 | serio_destroy_port(s); |
647 | } while ((s = parent) != serio); | 669 | |
670 | s = parent; | ||
671 | } | ||
648 | } | 672 | } |
649 | 673 | ||
650 | /* | 674 | /* |
651 | * Ok, no children left, now disconnect this port | 675 | * OK, no children left, now disconnect this port. |
652 | */ | 676 | */ |
653 | device_release_driver(&serio->dev); | 677 | device_release_driver(&serio->dev); |
654 | } | 678 | } |
@@ -661,7 +685,7 @@ EXPORT_SYMBOL(serio_rescan); | |||
661 | 685 | ||
662 | void serio_reconnect(struct serio *serio) | 686 | void serio_reconnect(struct serio *serio) |
663 | { | 687 | { |
664 | serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN); | 688 | serio_queue_event(serio, NULL, SERIO_RECONNECT_SUBTREE); |
665 | } | 689 | } |
666 | EXPORT_SYMBOL(serio_reconnect); | 690 | EXPORT_SYMBOL(serio_reconnect); |
667 | 691 | ||
@@ -689,14 +713,16 @@ void serio_unregister_port(struct serio *serio) | |||
689 | EXPORT_SYMBOL(serio_unregister_port); | 713 | EXPORT_SYMBOL(serio_unregister_port); |
690 | 714 | ||
691 | /* | 715 | /* |
692 | * Safely unregisters child port if one is present. | 716 | * Safely unregisters children ports if they are present. |
693 | */ | 717 | */ |
694 | void serio_unregister_child_port(struct serio *serio) | 718 | void serio_unregister_child_port(struct serio *serio) |
695 | { | 719 | { |
720 | struct serio *s, *next; | ||
721 | |||
696 | mutex_lock(&serio_mutex); | 722 | mutex_lock(&serio_mutex); |
697 | if (serio->child) { | 723 | list_for_each_entry_safe(s, next, &serio->children, child_node) { |
698 | serio_disconnect_port(serio->child); | 724 | serio_disconnect_port(s); |
699 | serio_destroy_port(serio->child); | 725 | serio_destroy_port(s); |
700 | } | 726 | } |
701 | mutex_unlock(&serio_mutex); | 727 | mutex_unlock(&serio_mutex); |
702 | } | 728 | } |
@@ -1003,21 +1029,18 @@ static int __init serio_init(void) | |||
1003 | return error; | 1029 | return error; |
1004 | } | 1030 | } |
1005 | 1031 | ||
1006 | serio_task = kthread_run(serio_thread, NULL, "kseriod"); | ||
1007 | if (IS_ERR(serio_task)) { | ||
1008 | bus_unregister(&serio_bus); | ||
1009 | error = PTR_ERR(serio_task); | ||
1010 | pr_err("Failed to start kseriod, error: %d\n", error); | ||
1011 | return error; | ||
1012 | } | ||
1013 | |||
1014 | return 0; | 1032 | return 0; |
1015 | } | 1033 | } |
1016 | 1034 | ||
1017 | static void __exit serio_exit(void) | 1035 | static void __exit serio_exit(void) |
1018 | { | 1036 | { |
1019 | bus_unregister(&serio_bus); | 1037 | bus_unregister(&serio_bus); |
1020 | kthread_stop(serio_task); | 1038 | |
1039 | /* | ||
1040 | * There should not be any outstanding events but work may | ||
1041 | * still be scheduled so simply cancel it. | ||
1042 | */ | ||
1043 | cancel_work_sync(&serio_event_work); | ||
1021 | } | 1044 | } |
1022 | 1045 | ||
1023 | subsys_initcall(serio_init); | 1046 | subsys_initcall(serio_init); |
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 998664854440..b7ba4597f7f0 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/poll.h> | 14 | #include <linux/poll.h> |
16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
17 | #include <linux/serio.h> | 16 | #include <linux/serio.h> |
@@ -243,6 +242,7 @@ static const struct file_operations serio_raw_fops = { | |||
243 | .write = serio_raw_write, | 242 | .write = serio_raw_write, |
244 | .poll = serio_raw_poll, | 243 | .poll = serio_raw_poll, |
245 | .fasync = serio_raw_fasync, | 244 | .fasync = serio_raw_fasync, |
245 | .llseek = noop_llseek, | ||
246 | }; | 246 | }; |
247 | 247 | ||
248 | 248 | ||
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 6d345112bcb7..8755f5f3ad37 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -116,14 +116,15 @@ static void serport_ldisc_close(struct tty_struct *tty) | |||
116 | 116 | ||
117 | /* | 117 | /* |
118 | * serport_ldisc_receive() is called by the low level tty driver when characters | 118 | * serport_ldisc_receive() is called by the low level tty driver when characters |
119 | * are ready for us. We forward the characters, one by one to the 'interrupt' | 119 | * are ready for us. We forward the characters and flags, one by one to the |
120 | * routine. | 120 | * 'interrupt' routine. |
121 | */ | 121 | */ |
122 | 122 | ||
123 | static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) | 123 | static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) |
124 | { | 124 | { |
125 | struct serport *serport = (struct serport*) tty->disc_data; | 125 | struct serport *serport = (struct serport*) tty->disc_data; |
126 | unsigned long flags; | 126 | unsigned long flags; |
127 | unsigned int ch_flags; | ||
127 | int i; | 128 | int i; |
128 | 129 | ||
129 | spin_lock_irqsave(&serport->lock, flags); | 130 | spin_lock_irqsave(&serport->lock, flags); |
@@ -131,8 +132,23 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c | |||
131 | if (!test_bit(SERPORT_ACTIVE, &serport->flags)) | 132 | if (!test_bit(SERPORT_ACTIVE, &serport->flags)) |
132 | goto out; | 133 | goto out; |
133 | 134 | ||
134 | for (i = 0; i < count; i++) | 135 | for (i = 0; i < count; i++) { |
135 | serio_interrupt(serport->serio, cp[i], 0); | 136 | switch (fp[i]) { |
137 | case TTY_FRAME: | ||
138 | ch_flags = SERIO_FRAME; | ||
139 | break; | ||
140 | |||
141 | case TTY_PARITY: | ||
142 | ch_flags = SERIO_PARITY; | ||
143 | break; | ||
144 | |||
145 | default: | ||
146 | ch_flags = 0; | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | serio_interrupt(serport->serio, cp[i], ch_flags); | ||
151 | } | ||
136 | 152 | ||
137 | out: | 153 | out: |
138 | spin_unlock_irqrestore(&serport->lock, flags); | 154 | spin_unlock_irqrestore(&serport->lock, flags); |
@@ -165,6 +181,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u | |||
165 | serio->open = serport_serio_open; | 181 | serio->open = serport_serio_open; |
166 | serio->close = serport_serio_close; | 182 | serio->close = serport_serio_close; |
167 | serio->port_data = serport; | 183 | serio->port_data = serport; |
184 | serio->dev.parent = tty->dev; | ||
168 | 185 | ||
169 | serio_register_port(serport->serio); | 186 | serio_register_port(serport->serio); |
170 | printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name)); | 187 | printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name)); |
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index bb14449fb022..80baa53da5b1 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c | |||
@@ -225,15 +225,14 @@ static void sxps2_close(struct serio *pserio) | |||
225 | /** | 225 | /** |
226 | * xps2_of_probe - probe method for the PS/2 device. | 226 | * xps2_of_probe - probe method for the PS/2 device. |
227 | * @of_dev: pointer to OF device structure | 227 | * @of_dev: pointer to OF device structure |
228 | * @match: pointer to the stucture used for matching a device | 228 | * @match: pointer to the structure used for matching a device |
229 | * | 229 | * |
230 | * This function probes the PS/2 device in the device tree. | 230 | * This function probes the PS/2 device in the device tree. |
231 | * It initializes the driver data structure and the hardware. | 231 | * It initializes the driver data structure and the hardware. |
232 | * It returns 0, if the driver is bound to the PS/2 device, or a negative | 232 | * It returns 0, if the driver is bound to the PS/2 device, or a negative |
233 | * value if there is an error. | 233 | * value if there is an error. |
234 | */ | 234 | */ |
235 | static int __devinit xps2_of_probe(struct platform_device *ofdev, | 235 | static int __devinit xps2_of_probe(struct platform_device *ofdev) |
236 | const struct of_device_id *match) | ||
237 | { | 236 | { |
238 | struct resource r_irq; /* Interrupt resources */ | 237 | struct resource r_irq; /* Interrupt resources */ |
239 | struct resource r_mem; /* IO mem resources */ | 238 | struct resource r_mem; /* IO mem resources */ |
@@ -361,7 +360,7 @@ static const struct of_device_id xps2_of_match[] __devinitconst = { | |||
361 | }; | 360 | }; |
362 | MODULE_DEVICE_TABLE(of, xps2_of_match); | 361 | MODULE_DEVICE_TABLE(of, xps2_of_match); |
363 | 362 | ||
364 | static struct of_platform_driver xps2_of_driver = { | 363 | static struct platform_driver xps2_of_driver = { |
365 | .driver = { | 364 | .driver = { |
366 | .name = DRIVER_NAME, | 365 | .name = DRIVER_NAME, |
367 | .owner = THIS_MODULE, | 366 | .owner = THIS_MODULE, |
@@ -373,12 +372,12 @@ static struct of_platform_driver xps2_of_driver = { | |||
373 | 372 | ||
374 | static int __init xps2_init(void) | 373 | static int __init xps2_init(void) |
375 | { | 374 | { |
376 | return of_register_platform_driver(&xps2_of_driver); | 375 | return platform_driver_register(&xps2_of_driver); |
377 | } | 376 | } |
378 | 377 | ||
379 | static void __exit xps2_cleanup(void) | 378 | static void __exit xps2_cleanup(void) |
380 | { | 379 | { |
381 | of_unregister_platform_driver(&xps2_of_driver); | 380 | platform_driver_unregister(&xps2_of_driver); |
382 | } | 381 | } |
383 | 382 | ||
384 | module_init(xps2_init); | 383 | module_init(xps2_init); |
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index 014248344763..fdb6a3976f94 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c | |||
@@ -22,6 +22,37 @@ MODULE_DESCRIPTION("Generic support for sparse keymaps"); | |||
22 | MODULE_LICENSE("GPL v2"); | 22 | MODULE_LICENSE("GPL v2"); |
23 | MODULE_VERSION("0.1"); | 23 | MODULE_VERSION("0.1"); |
24 | 24 | ||
25 | static unsigned int sparse_keymap_get_key_index(struct input_dev *dev, | ||
26 | const struct key_entry *k) | ||
27 | { | ||
28 | struct key_entry *key; | ||
29 | unsigned int idx = 0; | ||
30 | |||
31 | for (key = dev->keycode; key->type != KE_END; key++) { | ||
32 | if (key->type == KE_KEY) { | ||
33 | if (key == k) | ||
34 | break; | ||
35 | idx++; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | return idx; | ||
40 | } | ||
41 | |||
42 | static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev, | ||
43 | unsigned int index) | ||
44 | { | ||
45 | struct key_entry *key; | ||
46 | unsigned int key_cnt = 0; | ||
47 | |||
48 | for (key = dev->keycode; key->type != KE_END; key++) | ||
49 | if (key->type == KE_KEY) | ||
50 | if (key_cnt++ == index) | ||
51 | return key; | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | |||
25 | /** | 56 | /** |
26 | * sparse_keymap_entry_from_scancode - perform sparse keymap lookup | 57 | * sparse_keymap_entry_from_scancode - perform sparse keymap lookup |
27 | * @dev: Input device using sparse keymap | 58 | * @dev: Input device using sparse keymap |
@@ -64,16 +95,36 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, | |||
64 | } | 95 | } |
65 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); | 96 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); |
66 | 97 | ||
98 | static struct key_entry *sparse_keymap_locate(struct input_dev *dev, | ||
99 | const struct input_keymap_entry *ke) | ||
100 | { | ||
101 | struct key_entry *key; | ||
102 | unsigned int scancode; | ||
103 | |||
104 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) | ||
105 | key = sparse_keymap_entry_by_index(dev, ke->index); | ||
106 | else if (input_scancode_to_scalar(ke, &scancode) == 0) | ||
107 | key = sparse_keymap_entry_from_scancode(dev, scancode); | ||
108 | else | ||
109 | key = NULL; | ||
110 | |||
111 | return key; | ||
112 | } | ||
113 | |||
67 | static int sparse_keymap_getkeycode(struct input_dev *dev, | 114 | static int sparse_keymap_getkeycode(struct input_dev *dev, |
68 | unsigned int scancode, | 115 | struct input_keymap_entry *ke) |
69 | unsigned int *keycode) | ||
70 | { | 116 | { |
71 | const struct key_entry *key; | 117 | const struct key_entry *key; |
72 | 118 | ||
73 | if (dev->keycode) { | 119 | if (dev->keycode) { |
74 | key = sparse_keymap_entry_from_scancode(dev, scancode); | 120 | key = sparse_keymap_locate(dev, ke); |
75 | if (key && key->type == KE_KEY) { | 121 | if (key && key->type == KE_KEY) { |
76 | *keycode = key->keycode; | 122 | ke->keycode = key->keycode; |
123 | if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) | ||
124 | ke->index = | ||
125 | sparse_keymap_get_key_index(dev, key); | ||
126 | ke->len = sizeof(key->code); | ||
127 | memcpy(ke->scancode, &key->code, sizeof(key->code)); | ||
77 | return 0; | 128 | return 0; |
78 | } | 129 | } |
79 | } | 130 | } |
@@ -82,20 +133,19 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, | |||
82 | } | 133 | } |
83 | 134 | ||
84 | static int sparse_keymap_setkeycode(struct input_dev *dev, | 135 | static int sparse_keymap_setkeycode(struct input_dev *dev, |
85 | unsigned int scancode, | 136 | const struct input_keymap_entry *ke, |
86 | unsigned int keycode) | 137 | unsigned int *old_keycode) |
87 | { | 138 | { |
88 | struct key_entry *key; | 139 | struct key_entry *key; |
89 | int old_keycode; | ||
90 | 140 | ||
91 | if (dev->keycode) { | 141 | if (dev->keycode) { |
92 | key = sparse_keymap_entry_from_scancode(dev, scancode); | 142 | key = sparse_keymap_locate(dev, ke); |
93 | if (key && key->type == KE_KEY) { | 143 | if (key && key->type == KE_KEY) { |
94 | old_keycode = key->keycode; | 144 | *old_keycode = key->keycode; |
95 | key->keycode = keycode; | 145 | key->keycode = ke->keycode; |
96 | set_bit(keycode, dev->keybit); | 146 | set_bit(ke->keycode, dev->keybit); |
97 | if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) | 147 | if (!sparse_keymap_entry_from_keycode(dev, *old_keycode)) |
98 | clear_bit(old_keycode, dev->keybit); | 148 | clear_bit(*old_keycode, dev->keybit); |
99 | return 0; | 149 | return 0; |
100 | } | 150 | } |
101 | } | 151 | } |
@@ -151,12 +201,19 @@ int sparse_keymap_setup(struct input_dev *dev, | |||
151 | break; | 201 | break; |
152 | 202 | ||
153 | case KE_SW: | 203 | case KE_SW: |
204 | case KE_VSW: | ||
154 | __set_bit(EV_SW, dev->evbit); | 205 | __set_bit(EV_SW, dev->evbit); |
155 | __set_bit(entry->sw.code, dev->swbit); | 206 | __set_bit(entry->sw.code, dev->swbit); |
156 | break; | 207 | break; |
157 | } | 208 | } |
158 | } | 209 | } |
159 | 210 | ||
211 | if (test_bit(EV_KEY, dev->evbit)) { | ||
212 | __set_bit(KEY_UNKNOWN, dev->keybit); | ||
213 | __set_bit(EV_MSC, dev->evbit); | ||
214 | __set_bit(MSC_SCAN, dev->mscbit); | ||
215 | } | ||
216 | |||
160 | dev->keycode = map; | 217 | dev->keycode = map; |
161 | dev->keycodemax = map_size; | 218 | dev->keycodemax = map_size; |
162 | dev->getkeycode = sparse_keymap_getkeycode; | 219 | dev->getkeycode = sparse_keymap_getkeycode; |
@@ -167,7 +224,6 @@ int sparse_keymap_setup(struct input_dev *dev, | |||
167 | err_out: | 224 | err_out: |
168 | kfree(map); | 225 | kfree(map); |
169 | return error; | 226 | return error; |
170 | |||
171 | } | 227 | } |
172 | EXPORT_SYMBOL(sparse_keymap_setup); | 228 | EXPORT_SYMBOL(sparse_keymap_setup); |
173 | 229 | ||
@@ -218,6 +274,7 @@ void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *k | |||
218 | { | 274 | { |
219 | switch (ke->type) { | 275 | switch (ke->type) { |
220 | case KE_KEY: | 276 | case KE_KEY: |
277 | input_event(dev, EV_MSC, MSC_SCAN, ke->code); | ||
221 | input_report_key(dev, ke->keycode, value); | 278 | input_report_key(dev, ke->keycode, value); |
222 | input_sync(dev); | 279 | input_sync(dev); |
223 | if (value && autorelease) { | 280 | if (value && autorelease) { |
@@ -255,12 +312,19 @@ bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code, | |||
255 | { | 312 | { |
256 | const struct key_entry *ke = | 313 | const struct key_entry *ke = |
257 | sparse_keymap_entry_from_scancode(dev, code); | 314 | sparse_keymap_entry_from_scancode(dev, code); |
315 | struct key_entry unknown_ke; | ||
258 | 316 | ||
259 | if (ke) { | 317 | if (ke) { |
260 | sparse_keymap_report_entry(dev, ke, value, autorelease); | 318 | sparse_keymap_report_entry(dev, ke, value, autorelease); |
261 | return true; | 319 | return true; |
262 | } | 320 | } |
263 | 321 | ||
322 | /* Report an unknown key event as a debugging aid */ | ||
323 | unknown_ke.type = KE_KEY; | ||
324 | unknown_ke.code = code; | ||
325 | unknown_ke.keycode = KEY_UNKNOWN; | ||
326 | sparse_keymap_report_entry(dev, &unknown_ke, value, true); | ||
327 | |||
264 | return false; | 328 | return false; |
265 | } | 329 | } |
266 | EXPORT_SYMBOL(sparse_keymap_report_event); | 330 | EXPORT_SYMBOL(sparse_keymap_report_event); |
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index effb49ea24aa..58a87755b936 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig | |||
@@ -49,6 +49,17 @@ config TABLET_USB_GTCO | |||
49 | To compile this driver as a module, choose M here: the | 49 | To compile this driver as a module, choose M here: the |
50 | module will be called gtco. | 50 | module will be called gtco. |
51 | 51 | ||
52 | config TABLET_USB_HANWANG | ||
53 | tristate "Hanwang Art Master III tablet support (USB)" | ||
54 | depends on USB_ARCH_HAS_HCD | ||
55 | select USB | ||
56 | help | ||
57 | Say Y here if you want to use the USB version of the Hanwang Art | ||
58 | Master III tablet. | ||
59 | |||
60 | To compile this driver as a module, choose M here: the | ||
61 | module will be called hanwang. | ||
62 | |||
52 | config TABLET_USB_KBTAB | 63 | config TABLET_USB_KBTAB |
53 | tristate "KB Gear JamStudio tablet support (USB)" | 64 | tristate "KB Gear JamStudio tablet support (USB)" |
54 | depends on USB_ARCH_HAS_HCD | 65 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/input/tablet/Makefile b/drivers/input/tablet/Makefile index ce8b9a9cfa40..3f6c25220638 100644 --- a/drivers/input/tablet/Makefile +++ b/drivers/input/tablet/Makefile | |||
@@ -8,5 +8,6 @@ wacom-objs := wacom_wac.o wacom_sys.o | |||
8 | obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o | 8 | obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o |
9 | obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o | 9 | obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o |
10 | obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o | 10 | obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o |
11 | obj-$(CONFIG_TABLET_USB_HANWANG) += hanwang.o | ||
11 | obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o | 12 | obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o |
12 | obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o | 13 | obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o |
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index aea9a9399a36..d94f7e9aa997 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c | |||
@@ -229,12 +229,13 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ | |||
229 | 229 | ||
230 | err = input_register_device(acecad->input); | 230 | err = input_register_device(acecad->input); |
231 | if (err) | 231 | if (err) |
232 | goto fail2; | 232 | goto fail3; |
233 | 233 | ||
234 | usb_set_intfdata(intf, acecad); | 234 | usb_set_intfdata(intf, acecad); |
235 | 235 | ||
236 | return 0; | 236 | return 0; |
237 | 237 | ||
238 | fail3: usb_free_urb(acecad->irq); | ||
238 | fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); | 239 | fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); |
239 | fail1: input_free_device(input_dev); | 240 | fail1: input_free_device(input_dev); |
240 | kfree(acecad); | 241 | kfree(acecad); |
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 57b25b84d1fc..0a619c558bfb 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
@@ -1097,7 +1097,7 @@ store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const | |||
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | static DEVICE_ATTR(pointer_mode, | 1099 | static DEVICE_ATTR(pointer_mode, |
1100 | S_IRUGO | S_IWUGO, | 1100 | S_IRUGO | S_IWUSR, |
1101 | show_tabletPointerMode, store_tabletPointerMode); | 1101 | show_tabletPointerMode, store_tabletPointerMode); |
1102 | 1102 | ||
1103 | /*********************************************************************** | 1103 | /*********************************************************************** |
@@ -1134,7 +1134,7 @@ store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, co | |||
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | static DEVICE_ATTR(coordinate_mode, | 1136 | static DEVICE_ATTR(coordinate_mode, |
1137 | S_IRUGO | S_IWUGO, | 1137 | S_IRUGO | S_IWUSR, |
1138 | show_tabletCoordinateMode, store_tabletCoordinateMode); | 1138 | show_tabletCoordinateMode, store_tabletCoordinateMode); |
1139 | 1139 | ||
1140 | /*********************************************************************** | 1140 | /*********************************************************************** |
@@ -1176,7 +1176,7 @@ store_tabletToolMode(struct device *dev, struct device_attribute *attr, const ch | |||
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | static DEVICE_ATTR(tool_mode, | 1178 | static DEVICE_ATTR(tool_mode, |
1179 | S_IRUGO | S_IWUGO, | 1179 | S_IRUGO | S_IWUSR, |
1180 | show_tabletToolMode, store_tabletToolMode); | 1180 | show_tabletToolMode, store_tabletToolMode); |
1181 | 1181 | ||
1182 | /*********************************************************************** | 1182 | /*********************************************************************** |
@@ -1219,7 +1219,7 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char | |||
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | static DEVICE_ATTR(xtilt, | 1221 | static DEVICE_ATTR(xtilt, |
1222 | S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt); | 1222 | S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt); |
1223 | 1223 | ||
1224 | /*********************************************************************** | 1224 | /*********************************************************************** |
1225 | * support routines for the 'ytilt' file. Note that this file | 1225 | * support routines for the 'ytilt' file. Note that this file |
@@ -1261,7 +1261,7 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char | |||
1261 | } | 1261 | } |
1262 | 1262 | ||
1263 | static DEVICE_ATTR(ytilt, | 1263 | static DEVICE_ATTR(ytilt, |
1264 | S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt); | 1264 | S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt); |
1265 | 1265 | ||
1266 | /*********************************************************************** | 1266 | /*********************************************************************** |
1267 | * support routines for the 'jitter' file. Note that this file | 1267 | * support routines for the 'jitter' file. Note that this file |
@@ -1288,7 +1288,7 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const | |||
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | static DEVICE_ATTR(jitter, | 1290 | static DEVICE_ATTR(jitter, |
1291 | S_IRUGO | S_IWUGO, | 1291 | S_IRUGO | S_IWUSR, |
1292 | show_tabletJitterDelay, store_tabletJitterDelay); | 1292 | show_tabletJitterDelay, store_tabletJitterDelay); |
1293 | 1293 | ||
1294 | /*********************************************************************** | 1294 | /*********************************************************************** |
@@ -1317,7 +1317,7 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, | |||
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | static DEVICE_ATTR(delay, | 1319 | static DEVICE_ATTR(delay, |
1320 | S_IRUGO | S_IWUGO, | 1320 | S_IRUGO | S_IWUSR, |
1321 | show_tabletProgrammableDelay, store_tabletProgrammableDelay); | 1321 | show_tabletProgrammableDelay, store_tabletProgrammableDelay); |
1322 | 1322 | ||
1323 | /*********************************************************************** | 1323 | /*********************************************************************** |
@@ -1406,7 +1406,7 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const | |||
1406 | } | 1406 | } |
1407 | 1407 | ||
1408 | static DEVICE_ATTR(stylus_upper, | 1408 | static DEVICE_ATTR(stylus_upper, |
1409 | S_IRUGO | S_IWUGO, | 1409 | S_IRUGO | S_IWUSR, |
1410 | show_tabletStylusUpper, store_tabletStylusUpper); | 1410 | show_tabletStylusUpper, store_tabletStylusUpper); |
1411 | 1411 | ||
1412 | /*********************************************************************** | 1412 | /*********************************************************************** |
@@ -1437,7 +1437,7 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const | |||
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | static DEVICE_ATTR(stylus_lower, | 1439 | static DEVICE_ATTR(stylus_lower, |
1440 | S_IRUGO | S_IWUGO, | 1440 | S_IRUGO | S_IWUSR, |
1441 | show_tabletStylusLower, store_tabletStylusLower); | 1441 | show_tabletStylusLower, store_tabletStylusLower); |
1442 | 1442 | ||
1443 | /*********************************************************************** | 1443 | /*********************************************************************** |
@@ -1475,7 +1475,7 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c | |||
1475 | } | 1475 | } |
1476 | 1476 | ||
1477 | static DEVICE_ATTR(mouse_left, | 1477 | static DEVICE_ATTR(mouse_left, |
1478 | S_IRUGO | S_IWUGO, | 1478 | S_IRUGO | S_IWUSR, |
1479 | show_tabletMouseLeft, store_tabletMouseLeft); | 1479 | show_tabletMouseLeft, store_tabletMouseLeft); |
1480 | 1480 | ||
1481 | /*********************************************************************** | 1481 | /*********************************************************************** |
@@ -1505,7 +1505,7 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const | |||
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | static DEVICE_ATTR(mouse_middle, | 1507 | static DEVICE_ATTR(mouse_middle, |
1508 | S_IRUGO | S_IWUGO, | 1508 | S_IRUGO | S_IWUSR, |
1509 | show_tabletMouseMiddle, store_tabletMouseMiddle); | 1509 | show_tabletMouseMiddle, store_tabletMouseMiddle); |
1510 | 1510 | ||
1511 | /*********************************************************************** | 1511 | /*********************************************************************** |
@@ -1535,7 +1535,7 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const | |||
1535 | } | 1535 | } |
1536 | 1536 | ||
1537 | static DEVICE_ATTR(mouse_right, | 1537 | static DEVICE_ATTR(mouse_right, |
1538 | S_IRUGO | S_IWUGO, | 1538 | S_IRUGO | S_IWUSR, |
1539 | show_tabletMouseRight, store_tabletMouseRight); | 1539 | show_tabletMouseRight, store_tabletMouseRight); |
1540 | 1540 | ||
1541 | /*********************************************************************** | 1541 | /*********************************************************************** |
@@ -1567,7 +1567,7 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char | |||
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | static DEVICE_ATTR(wheel, | 1569 | static DEVICE_ATTR(wheel, |
1570 | S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel); | 1570 | S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel); |
1571 | 1571 | ||
1572 | /*********************************************************************** | 1572 | /*********************************************************************** |
1573 | * support routines for the 'execute' file. Note that this file | 1573 | * support routines for the 'execute' file. Note that this file |
@@ -1600,7 +1600,7 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha | |||
1600 | } | 1600 | } |
1601 | 1601 | ||
1602 | static DEVICE_ATTR(execute, | 1602 | static DEVICE_ATTR(execute, |
1603 | S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute); | 1603 | S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute); |
1604 | 1604 | ||
1605 | /*********************************************************************** | 1605 | /*********************************************************************** |
1606 | * support routines for the 'odm_code' file. Note that this file | 1606 | * support routines for the 'odm_code' file. Note that this file |
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c new file mode 100644 index 000000000000..6504b627b234 --- /dev/null +++ b/drivers/input/tablet/hanwang.c | |||
@@ -0,0 +1,446 @@ | |||
1 | /* | ||
2 | * USB Hanwang tablet support | ||
3 | * | ||
4 | * Copyright (c) 2010 Xing Wei <weixing@hanwang.com.cn> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/usb/input.h> | ||
31 | |||
32 | #define DRIVER_AUTHOR "Xing Wei <weixing@hanwang.com.cn>" | ||
33 | #define DRIVER_DESC "USB Hanwang tablet driver" | ||
34 | #define DRIVER_LICENSE "GPL" | ||
35 | |||
36 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
37 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
38 | MODULE_LICENSE(DRIVER_LICENSE); | ||
39 | |||
40 | #define USB_VENDOR_ID_HANWANG 0x0b57 | ||
41 | #define HANWANG_TABLET_INT_CLASS 0x0003 | ||
42 | #define HANWANG_TABLET_INT_SUB_CLASS 0x0001 | ||
43 | #define HANWANG_TABLET_INT_PROTOCOL 0x0002 | ||
44 | |||
45 | #define ART_MASTER_PKGLEN_MAX 10 | ||
46 | |||
47 | /* device IDs */ | ||
48 | #define STYLUS_DEVICE_ID 0x02 | ||
49 | #define TOUCH_DEVICE_ID 0x03 | ||
50 | #define CURSOR_DEVICE_ID 0x06 | ||
51 | #define ERASER_DEVICE_ID 0x0A | ||
52 | #define PAD_DEVICE_ID 0x0F | ||
53 | |||
54 | /* match vendor and interface info */ | ||
55 | #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \ | ||
56 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR \ | ||
57 | | USB_DEVICE_ID_MATCH_INT_INFO, \ | ||
58 | .idVendor = (vend), \ | ||
59 | .bInterfaceClass = (cl), \ | ||
60 | .bInterfaceSubClass = (sc), \ | ||
61 | .bInterfaceProtocol = (pr) | ||
62 | |||
63 | enum hanwang_tablet_type { | ||
64 | HANWANG_ART_MASTER_III, | ||
65 | HANWANG_ART_MASTER_HD, | ||
66 | }; | ||
67 | |||
68 | struct hanwang { | ||
69 | unsigned char *data; | ||
70 | dma_addr_t data_dma; | ||
71 | struct input_dev *dev; | ||
72 | struct usb_device *usbdev; | ||
73 | struct urb *irq; | ||
74 | const struct hanwang_features *features; | ||
75 | unsigned int current_tool; | ||
76 | unsigned int current_id; | ||
77 | char name[64]; | ||
78 | char phys[32]; | ||
79 | }; | ||
80 | |||
81 | struct hanwang_features { | ||
82 | unsigned short pid; | ||
83 | char *name; | ||
84 | enum hanwang_tablet_type type; | ||
85 | int pkg_len; | ||
86 | int max_x; | ||
87 | int max_y; | ||
88 | int max_tilt_x; | ||
89 | int max_tilt_y; | ||
90 | int max_pressure; | ||
91 | }; | ||
92 | |||
93 | static const struct hanwang_features features_array[] = { | ||
94 | { 0x8528, "Hanwang Art Master III 0906", HANWANG_ART_MASTER_III, | ||
95 | ART_MASTER_PKGLEN_MAX, 0x5757, 0x3692, 0x3f, 0x7f, 2048 }, | ||
96 | { 0x8529, "Hanwang Art Master III 0604", HANWANG_ART_MASTER_III, | ||
97 | ART_MASTER_PKGLEN_MAX, 0x3d84, 0x2672, 0x3f, 0x7f, 2048 }, | ||
98 | { 0x852a, "Hanwang Art Master III 1308", HANWANG_ART_MASTER_III, | ||
99 | ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 }, | ||
100 | { 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD, | ||
101 | ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 }, | ||
102 | }; | ||
103 | |||
104 | static const int hw_eventtypes[] = { | ||
105 | EV_KEY, EV_ABS, EV_MSC, | ||
106 | }; | ||
107 | |||
108 | static const int hw_absevents[] = { | ||
109 | ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, | ||
110 | ABS_RX, ABS_RY, ABS_PRESSURE, ABS_MISC, | ||
111 | }; | ||
112 | |||
113 | static const int hw_btnevents[] = { | ||
114 | BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, | ||
115 | BTN_TOOL_MOUSE, BTN_TOOL_FINGER, | ||
116 | BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8, | ||
117 | }; | ||
118 | |||
119 | static const int hw_mscevents[] = { | ||
120 | MSC_SERIAL, | ||
121 | }; | ||
122 | |||
123 | static void hanwang_parse_packet(struct hanwang *hanwang) | ||
124 | { | ||
125 | unsigned char *data = hanwang->data; | ||
126 | struct input_dev *input_dev = hanwang->dev; | ||
127 | struct usb_device *dev = hanwang->usbdev; | ||
128 | enum hanwang_tablet_type type = hanwang->features->type; | ||
129 | int i; | ||
130 | u16 x, y, p; | ||
131 | |||
132 | switch (data[0]) { | ||
133 | case 0x02: /* data packet */ | ||
134 | switch (data[1]) { | ||
135 | case 0x80: /* tool prox out */ | ||
136 | hanwang->current_id = 0; | ||
137 | input_report_key(input_dev, hanwang->current_tool, 0); | ||
138 | break; | ||
139 | |||
140 | case 0xc2: /* first time tool prox in */ | ||
141 | switch (data[3] & 0xf0) { | ||
142 | case 0x20: /* art_master III */ | ||
143 | case 0x30: /* art_master_HD */ | ||
144 | hanwang->current_id = STYLUS_DEVICE_ID; | ||
145 | hanwang->current_tool = BTN_TOOL_PEN; | ||
146 | input_report_key(input_dev, BTN_TOOL_PEN, 1); | ||
147 | break; | ||
148 | case 0xa0: /* art_master III */ | ||
149 | case 0xb0: /* art_master_HD */ | ||
150 | hanwang->current_id = ERASER_DEVICE_ID; | ||
151 | hanwang->current_tool = BTN_TOOL_RUBBER; | ||
152 | input_report_key(input_dev, BTN_TOOL_RUBBER, 1); | ||
153 | break; | ||
154 | default: | ||
155 | hanwang->current_id = 0; | ||
156 | dev_dbg(&dev->dev, | ||
157 | "unknown tablet tool %02x ", data[0]); | ||
158 | break; | ||
159 | } | ||
160 | break; | ||
161 | |||
162 | default: /* tool data packet */ | ||
163 | x = (data[2] << 8) | data[3]; | ||
164 | y = (data[4] << 8) | data[5]; | ||
165 | |||
166 | switch (type) { | ||
167 | case HANWANG_ART_MASTER_III: | ||
168 | p = (data[6] << 3) | | ||
169 | ((data[7] & 0xc0) >> 5) | | ||
170 | (data[1] & 0x01); | ||
171 | break; | ||
172 | |||
173 | case HANWANG_ART_MASTER_HD: | ||
174 | p = (data[7] >> 6) | (data[6] << 2); | ||
175 | break; | ||
176 | |||
177 | default: | ||
178 | p = 0; | ||
179 | break; | ||
180 | } | ||
181 | |||
182 | input_report_abs(input_dev, ABS_X, | ||
183 | le16_to_cpup((__le16 *)&x)); | ||
184 | input_report_abs(input_dev, ABS_Y, | ||
185 | le16_to_cpup((__le16 *)&y)); | ||
186 | input_report_abs(input_dev, ABS_PRESSURE, | ||
187 | le16_to_cpup((__le16 *)&p)); | ||
188 | input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f); | ||
189 | input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f); | ||
190 | input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02); | ||
191 | input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04); | ||
192 | break; | ||
193 | } | ||
194 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
195 | input_event(input_dev, EV_MSC, MSC_SERIAL, | ||
196 | hanwang->features->pid); | ||
197 | break; | ||
198 | |||
199 | case 0x0c: | ||
200 | /* roll wheel */ | ||
201 | hanwang->current_id = PAD_DEVICE_ID; | ||
202 | |||
203 | switch (type) { | ||
204 | case HANWANG_ART_MASTER_III: | ||
205 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
206 | data[2] || data[3]); | ||
207 | input_report_abs(input_dev, ABS_WHEEL, data[1]); | ||
208 | input_report_key(input_dev, BTN_0, data[2]); | ||
209 | for (i = 0; i < 8; i++) | ||
210 | input_report_key(input_dev, | ||
211 | BTN_1 + i, data[3] & (1 << i)); | ||
212 | break; | ||
213 | |||
214 | case HANWANG_ART_MASTER_HD: | ||
215 | input_report_key(input_dev, BTN_TOOL_FINGER, data[1] || | ||
216 | data[2] || data[3] || data[4] || | ||
217 | data[5] || data[6]); | ||
218 | input_report_abs(input_dev, ABS_RX, | ||
219 | ((data[1] & 0x1f) << 8) | data[2]); | ||
220 | input_report_abs(input_dev, ABS_RY, | ||
221 | ((data[3] & 0x1f) << 8) | data[4]); | ||
222 | input_report_key(input_dev, BTN_0, data[5] & 0x01); | ||
223 | for (i = 0; i < 4; i++) { | ||
224 | input_report_key(input_dev, | ||
225 | BTN_1 + i, data[5] & (1 << i)); | ||
226 | input_report_key(input_dev, | ||
227 | BTN_5 + i, data[6] & (1 << i)); | ||
228 | } | ||
229 | break; | ||
230 | } | ||
231 | |||
232 | input_report_abs(input_dev, ABS_MISC, hanwang->current_id); | ||
233 | input_event(input_dev, EV_MSC, MSC_SERIAL, 0xffffffff); | ||
234 | break; | ||
235 | |||
236 | default: | ||
237 | dev_dbg(&dev->dev, "error packet %02x ", data[0]); | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | input_sync(input_dev); | ||
242 | } | ||
243 | |||
244 | static void hanwang_irq(struct urb *urb) | ||
245 | { | ||
246 | struct hanwang *hanwang = urb->context; | ||
247 | struct usb_device *dev = hanwang->usbdev; | ||
248 | int retval; | ||
249 | |||
250 | switch (urb->status) { | ||
251 | case 0: | ||
252 | /* success */; | ||
253 | hanwang_parse_packet(hanwang); | ||
254 | break; | ||
255 | case -ECONNRESET: | ||
256 | case -ENOENT: | ||
257 | case -ESHUTDOWN: | ||
258 | /* this urb is terminated, clean up */ | ||
259 | dev_err(&dev->dev, "%s - urb shutting down with status: %d", | ||
260 | __func__, urb->status); | ||
261 | return; | ||
262 | default: | ||
263 | dev_err(&dev->dev, "%s - nonzero urb status received: %d", | ||
264 | __func__, urb->status); | ||
265 | break; | ||
266 | } | ||
267 | |||
268 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
269 | if (retval) | ||
270 | dev_err(&dev->dev, "%s - usb_submit_urb failed with result %d", | ||
271 | __func__, retval); | ||
272 | } | ||
273 | |||
274 | static int hanwang_open(struct input_dev *dev) | ||
275 | { | ||
276 | struct hanwang *hanwang = input_get_drvdata(dev); | ||
277 | |||
278 | hanwang->irq->dev = hanwang->usbdev; | ||
279 | if (usb_submit_urb(hanwang->irq, GFP_KERNEL)) | ||
280 | return -EIO; | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static void hanwang_close(struct input_dev *dev) | ||
286 | { | ||
287 | struct hanwang *hanwang = input_get_drvdata(dev); | ||
288 | |||
289 | usb_kill_urb(hanwang->irq); | ||
290 | } | ||
291 | |||
292 | static bool get_features(struct usb_device *dev, struct hanwang *hanwang) | ||
293 | { | ||
294 | int i; | ||
295 | |||
296 | for (i = 0; i < ARRAY_SIZE(features_array); i++) { | ||
297 | if (le16_to_cpu(dev->descriptor.idProduct) == | ||
298 | features_array[i].pid) { | ||
299 | hanwang->features = &features_array[i]; | ||
300 | return true; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | return false; | ||
305 | } | ||
306 | |||
307 | |||
308 | static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
309 | { | ||
310 | struct usb_device *dev = interface_to_usbdev(intf); | ||
311 | struct usb_endpoint_descriptor *endpoint; | ||
312 | struct hanwang *hanwang; | ||
313 | struct input_dev *input_dev; | ||
314 | int error; | ||
315 | int i; | ||
316 | |||
317 | hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL); | ||
318 | input_dev = input_allocate_device(); | ||
319 | if (!hanwang || !input_dev) { | ||
320 | error = -ENOMEM; | ||
321 | goto fail1; | ||
322 | } | ||
323 | |||
324 | if (!get_features(dev, hanwang)) { | ||
325 | error = -ENXIO; | ||
326 | goto fail1; | ||
327 | } | ||
328 | |||
329 | hanwang->data = usb_alloc_coherent(dev, hanwang->features->pkg_len, | ||
330 | GFP_KERNEL, &hanwang->data_dma); | ||
331 | if (!hanwang->data) { | ||
332 | error = -ENOMEM; | ||
333 | goto fail1; | ||
334 | } | ||
335 | |||
336 | hanwang->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
337 | if (!hanwang->irq) { | ||
338 | error = -ENOMEM; | ||
339 | goto fail2; | ||
340 | } | ||
341 | |||
342 | hanwang->usbdev = dev; | ||
343 | hanwang->dev = input_dev; | ||
344 | |||
345 | usb_make_path(dev, hanwang->phys, sizeof(hanwang->phys)); | ||
346 | strlcat(hanwang->phys, "/input0", sizeof(hanwang->phys)); | ||
347 | |||
348 | strlcpy(hanwang->name, hanwang->features->name, sizeof(hanwang->name)); | ||
349 | input_dev->name = hanwang->name; | ||
350 | input_dev->phys = hanwang->phys; | ||
351 | usb_to_input_id(dev, &input_dev->id); | ||
352 | input_dev->dev.parent = &intf->dev; | ||
353 | |||
354 | input_set_drvdata(input_dev, hanwang); | ||
355 | |||
356 | input_dev->open = hanwang_open; | ||
357 | input_dev->close = hanwang_close; | ||
358 | |||
359 | for (i = 0; i < ARRAY_SIZE(hw_eventtypes); ++i) | ||
360 | __set_bit(hw_eventtypes[i], input_dev->evbit); | ||
361 | |||
362 | for (i = 0; i < ARRAY_SIZE(hw_absevents); ++i) | ||
363 | __set_bit(hw_absevents[i], input_dev->absbit); | ||
364 | |||
365 | for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i) | ||
366 | __set_bit(hw_btnevents[i], input_dev->keybit); | ||
367 | |||
368 | for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i) | ||
369 | __set_bit(hw_mscevents[i], input_dev->mscbit); | ||
370 | |||
371 | input_set_abs_params(input_dev, ABS_X, | ||
372 | 0, hanwang->features->max_x, 4, 0); | ||
373 | input_set_abs_params(input_dev, ABS_Y, | ||
374 | 0, hanwang->features->max_y, 4, 0); | ||
375 | input_set_abs_params(input_dev, ABS_TILT_X, | ||
376 | 0, hanwang->features->max_tilt_x, 0, 0); | ||
377 | input_set_abs_params(input_dev, ABS_TILT_Y, | ||
378 | 0, hanwang->features->max_tilt_y, 0, 0); | ||
379 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
380 | 0, hanwang->features->max_pressure, 0, 0); | ||
381 | |||
382 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | ||
383 | usb_fill_int_urb(hanwang->irq, dev, | ||
384 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | ||
385 | hanwang->data, hanwang->features->pkg_len, | ||
386 | hanwang_irq, hanwang, endpoint->bInterval); | ||
387 | hanwang->irq->transfer_dma = hanwang->data_dma; | ||
388 | hanwang->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
389 | |||
390 | error = input_register_device(hanwang->dev); | ||
391 | if (error) | ||
392 | goto fail3; | ||
393 | |||
394 | usb_set_intfdata(intf, hanwang); | ||
395 | |||
396 | return 0; | ||
397 | |||
398 | fail3: usb_free_urb(hanwang->irq); | ||
399 | fail2: usb_free_coherent(dev, hanwang->features->pkg_len, | ||
400 | hanwang->data, hanwang->data_dma); | ||
401 | fail1: input_free_device(input_dev); | ||
402 | kfree(hanwang); | ||
403 | return error; | ||
404 | |||
405 | } | ||
406 | |||
407 | static void hanwang_disconnect(struct usb_interface *intf) | ||
408 | { | ||
409 | struct hanwang *hanwang = usb_get_intfdata(intf); | ||
410 | |||
411 | input_unregister_device(hanwang->dev); | ||
412 | usb_free_urb(hanwang->irq); | ||
413 | usb_free_coherent(interface_to_usbdev(intf), | ||
414 | hanwang->features->pkg_len, hanwang->data, | ||
415 | hanwang->data_dma); | ||
416 | kfree(hanwang); | ||
417 | usb_set_intfdata(intf, NULL); | ||
418 | } | ||
419 | |||
420 | static const struct usb_device_id hanwang_ids[] = { | ||
421 | { HANWANG_TABLET_DEVICE(USB_VENDOR_ID_HANWANG, HANWANG_TABLET_INT_CLASS, | ||
422 | HANWANG_TABLET_INT_SUB_CLASS, HANWANG_TABLET_INT_PROTOCOL) }, | ||
423 | {} | ||
424 | }; | ||
425 | |||
426 | MODULE_DEVICE_TABLE(usb, hanwang_ids); | ||
427 | |||
428 | static struct usb_driver hanwang_driver = { | ||
429 | .name = "hanwang", | ||
430 | .probe = hanwang_probe, | ||
431 | .disconnect = hanwang_disconnect, | ||
432 | .id_table = hanwang_ids, | ||
433 | }; | ||
434 | |||
435 | static int __init hanwang_init(void) | ||
436 | { | ||
437 | return usb_register(&hanwang_driver); | ||
438 | } | ||
439 | |||
440 | static void __exit hanwang_exit(void) | ||
441 | { | ||
442 | usb_deregister(&hanwang_driver); | ||
443 | } | ||
444 | |||
445 | module_init(hanwang_init); | ||
446 | module_exit(hanwang_exit); | ||
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 284dfaab6b8c..23317bd09c82 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -103,6 +103,7 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
103 | MODULE_LICENSE(DRIVER_LICENSE); | 103 | MODULE_LICENSE(DRIVER_LICENSE); |
104 | 104 | ||
105 | #define USB_VENDOR_ID_WACOM 0x056a | 105 | #define USB_VENDOR_ID_WACOM 0x056a |
106 | #define USB_VENDOR_ID_LENOVO 0x17ef | ||
106 | 107 | ||
107 | struct wacom { | 108 | struct wacom { |
108 | dma_addr_t data_dma; | 109 | dma_addr_t data_dma; |
@@ -118,6 +119,7 @@ struct wacom { | |||
118 | extern const struct usb_device_id wacom_ids[]; | 119 | extern const struct usb_device_id wacom_ids[]; |
119 | 120 | ||
120 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); | 121 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); |
122 | void wacom_setup_device_quirks(struct wacom_features *features); | ||
121 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 123 | void wacom_setup_input_capabilities(struct input_dev *input_dev, |
122 | struct wacom_wac *wacom_wac); | 124 | struct wacom_wac *wacom_wac); |
123 | #endif | 125 | #endif |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b35876ee6908..449c0a46dbac 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -120,14 +120,16 @@ static int wacom_open(struct input_dev *dev) | |||
120 | 120 | ||
121 | out: | 121 | out: |
122 | mutex_unlock(&wacom->lock); | 122 | mutex_unlock(&wacom->lock); |
123 | if (retval) | 123 | usb_autopm_put_interface(wacom->intf); |
124 | usb_autopm_put_interface(wacom->intf); | ||
125 | return retval; | 124 | return retval; |
126 | } | 125 | } |
127 | 126 | ||
128 | static void wacom_close(struct input_dev *dev) | 127 | static void wacom_close(struct input_dev *dev) |
129 | { | 128 | { |
130 | struct wacom *wacom = input_get_drvdata(dev); | 129 | struct wacom *wacom = input_get_drvdata(dev); |
130 | int autopm_error; | ||
131 | |||
132 | autopm_error = usb_autopm_get_interface(wacom->intf); | ||
131 | 133 | ||
132 | mutex_lock(&wacom->lock); | 134 | mutex_lock(&wacom->lock); |
133 | usb_kill_urb(wacom->irq); | 135 | usb_kill_urb(wacom->irq); |
@@ -135,7 +137,8 @@ static void wacom_close(struct input_dev *dev) | |||
135 | wacom->intf->needs_remote_wakeup = 0; | 137 | wacom->intf->needs_remote_wakeup = 0; |
136 | mutex_unlock(&wacom->lock); | 138 | mutex_unlock(&wacom->lock); |
137 | 139 | ||
138 | usb_autopm_put_interface(wacom->intf); | 140 | if (!autopm_error) |
141 | usb_autopm_put_interface(wacom->intf); | ||
139 | } | 142 | } |
140 | 143 | ||
141 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | 144 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, |
@@ -190,23 +193,36 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
190 | case HID_USAGE_X: | 193 | case HID_USAGE_X: |
191 | if (usage == WCM_DESKTOP) { | 194 | if (usage == WCM_DESKTOP) { |
192 | if (finger) { | 195 | if (finger) { |
193 | features->device_type = BTN_TOOL_DOUBLETAP; | 196 | features->device_type = BTN_TOOL_FINGER; |
194 | if (features->type == TABLETPC2FG) { | 197 | if (features->type == TABLETPC2FG) { |
195 | /* need to reset back */ | 198 | /* need to reset back */ |
196 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 199 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
197 | features->device_type = BTN_TOOL_TRIPLETAP; | 200 | features->device_type = BTN_TOOL_DOUBLETAP; |
201 | } | ||
202 | if (features->type == BAMBOO_PT) { | ||
203 | /* need to reset back */ | ||
204 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | ||
205 | features->device_type = BTN_TOOL_DOUBLETAP; | ||
206 | features->x_phy = | ||
207 | get_unaligned_le16(&report[i + 5]); | ||
208 | features->x_max = | ||
209 | get_unaligned_le16(&report[i + 8]); | ||
210 | i += 15; | ||
211 | } else { | ||
212 | features->x_max = | ||
213 | get_unaligned_le16(&report[i + 3]); | ||
214 | features->x_phy = | ||
215 | get_unaligned_le16(&report[i + 6]); | ||
216 | features->unit = report[i + 9]; | ||
217 | features->unitExpo = report[i + 11]; | ||
218 | i += 12; | ||
198 | } | 219 | } |
199 | features->x_max = | ||
200 | get_unaligned_le16(&report[i + 3]); | ||
201 | features->x_phy = | ||
202 | get_unaligned_le16(&report[i + 6]); | ||
203 | features->unit = report[i + 9]; | ||
204 | features->unitExpo = report[i + 11]; | ||
205 | i += 12; | ||
206 | } else if (pen) { | 220 | } else if (pen) { |
207 | /* penabled only accepts exact bytes of data */ | 221 | /* penabled only accepts exact bytes of data */ |
208 | if (features->type == TABLETPC2FG) | 222 | if (features->type == TABLETPC2FG) |
209 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | 223 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
224 | if (features->type == BAMBOO_PT) | ||
225 | features->pktlen = WACOM_PKGLEN_BBFUN; | ||
210 | features->device_type = BTN_TOOL_PEN; | 226 | features->device_type = BTN_TOOL_PEN; |
211 | features->x_max = | 227 | features->x_max = |
212 | get_unaligned_le16(&report[i + 3]); | 228 | get_unaligned_le16(&report[i + 3]); |
@@ -225,16 +241,25 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
225 | case HID_USAGE_Y: | 241 | case HID_USAGE_Y: |
226 | if (usage == WCM_DESKTOP) { | 242 | if (usage == WCM_DESKTOP) { |
227 | if (finger) { | 243 | if (finger) { |
228 | features->device_type = BTN_TOOL_DOUBLETAP; | 244 | features->device_type = BTN_TOOL_FINGER; |
229 | if (features->type == TABLETPC2FG) { | 245 | if (features->type == TABLETPC2FG) { |
230 | /* need to reset back */ | 246 | /* need to reset back */ |
231 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 247 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
232 | features->device_type = BTN_TOOL_TRIPLETAP; | 248 | features->device_type = BTN_TOOL_DOUBLETAP; |
233 | features->y_max = | 249 | features->y_max = |
234 | get_unaligned_le16(&report[i + 3]); | 250 | get_unaligned_le16(&report[i + 3]); |
235 | features->y_phy = | 251 | features->y_phy = |
236 | get_unaligned_le16(&report[i + 6]); | 252 | get_unaligned_le16(&report[i + 6]); |
237 | i += 7; | 253 | i += 7; |
254 | } else if (features->type == BAMBOO_PT) { | ||
255 | /* need to reset back */ | ||
256 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | ||
257 | features->device_type = BTN_TOOL_DOUBLETAP; | ||
258 | features->y_phy = | ||
259 | get_unaligned_le16(&report[i + 3]); | ||
260 | features->y_max = | ||
261 | get_unaligned_le16(&report[i + 6]); | ||
262 | i += 12; | ||
238 | } else { | 263 | } else { |
239 | features->y_max = | 264 | features->y_max = |
240 | features->x_max; | 265 | features->x_max; |
@@ -246,6 +271,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
246 | /* penabled only accepts exact bytes of data */ | 271 | /* penabled only accepts exact bytes of data */ |
247 | if (features->type == TABLETPC2FG) | 272 | if (features->type == TABLETPC2FG) |
248 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | 273 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
274 | if (features->type == BAMBOO_PT) | ||
275 | features->pktlen = WACOM_PKGLEN_BBFUN; | ||
249 | features->device_type = BTN_TOOL_PEN; | 276 | features->device_type = BTN_TOOL_PEN; |
250 | features->y_max = | 277 | features->y_max = |
251 | get_unaligned_le16(&report[i + 3]); | 278 | get_unaligned_le16(&report[i + 3]); |
@@ -296,8 +323,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
296 | if (!rep_data) | 323 | if (!rep_data) |
297 | return error; | 324 | return error; |
298 | 325 | ||
299 | /* ask to report tablet data if it is 2FGT or not a Tablet PC */ | 326 | /* ask to report tablet data if it is 2FGT Tablet PC or |
300 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | 327 | * not a Tablet PC */ |
328 | if (features->type == TABLETPC2FG) { | ||
301 | do { | 329 | do { |
302 | rep_data[0] = 3; | 330 | rep_data[0] = 3; |
303 | rep_data[1] = 4; | 331 | rep_data[1] = 4; |
@@ -309,7 +337,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
309 | WAC_HID_FEATURE_REPORT, report_id, | 337 | WAC_HID_FEATURE_REPORT, report_id, |
310 | rep_data, 3); | 338 | rep_data, 3); |
311 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); | 339 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); |
312 | } else if (features->type != TABLETPC && features->type != TABLETPC2FG) { | 340 | } else if (features->type != TABLETPC) { |
313 | do { | 341 | do { |
314 | rep_data[0] = 2; | 342 | rep_data[0] = 2; |
315 | rep_data[1] = 2; | 343 | rep_data[1] = 2; |
@@ -334,11 +362,16 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
334 | struct usb_host_interface *interface = intf->cur_altsetting; | 362 | struct usb_host_interface *interface = intf->cur_altsetting; |
335 | struct hid_descriptor *hid_desc; | 363 | struct hid_descriptor *hid_desc; |
336 | 364 | ||
337 | /* default device to penabled */ | 365 | /* default features */ |
338 | features->device_type = BTN_TOOL_PEN; | 366 | features->device_type = BTN_TOOL_PEN; |
339 | 367 | features->x_fuzz = 4; | |
340 | /* only Tablet PCs need to retrieve the info */ | 368 | features->y_fuzz = 4; |
341 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) | 369 | features->pressure_fuzz = 0; |
370 | features->distance_fuzz = 0; | ||
371 | |||
372 | /* only Tablet PCs and Bamboo P&T need to retrieve the info */ | ||
373 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && | ||
374 | (features->type != BAMBOO_PT)) | ||
342 | goto out; | 375 | goto out; |
343 | 376 | ||
344 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | 377 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { |
@@ -353,12 +386,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
353 | if (error) | 386 | if (error) |
354 | goto out; | 387 | goto out; |
355 | 388 | ||
356 | /* touch device found but size is not defined. use default */ | ||
357 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
358 | features->x_max = 1023; | ||
359 | features->y_max = 1023; | ||
360 | } | ||
361 | |||
362 | out: | 389 | out: |
363 | return error; | 390 | return error; |
364 | } | 391 | } |
@@ -492,11 +519,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
492 | /* Retrieve the physical and logical size for OEM devices */ | 519 | /* Retrieve the physical and logical size for OEM devices */ |
493 | error = wacom_retrieve_hid_descriptor(intf, features); | 520 | error = wacom_retrieve_hid_descriptor(intf, features); |
494 | if (error) | 521 | if (error) |
495 | goto fail2; | 522 | goto fail3; |
523 | |||
524 | wacom_setup_device_quirks(features); | ||
496 | 525 | ||
497 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); | 526 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
498 | 527 | ||
499 | if (features->type == TABLETPC || features->type == TABLETPC2FG) { | 528 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { |
500 | /* Append the device type to the name */ | 529 | /* Append the device type to the name */ |
501 | strlcat(wacom_wac->name, | 530 | strlcat(wacom_wac->name, |
502 | features->device_type == BTN_TOOL_PEN ? | 531 | features->device_type == BTN_TOOL_PEN ? |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 47fd7a041c52..08ba5ad9c9be 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -14,6 +14,15 @@ | |||
14 | 14 | ||
15 | #include "wacom_wac.h" | 15 | #include "wacom_wac.h" |
16 | #include "wacom.h" | 16 | #include "wacom.h" |
17 | #include <linux/input/mt.h> | ||
18 | |||
19 | /* resolution for penabled devices */ | ||
20 | #define WACOM_PL_RES 20 | ||
21 | #define WACOM_PENPRTN_RES 40 | ||
22 | #define WACOM_VOLITO_RES 50 | ||
23 | #define WACOM_GRAPHIRE_RES 80 | ||
24 | #define WACOM_INTUOS_RES 100 | ||
25 | #define WACOM_INTUOS3_RES 200 | ||
17 | 26 | ||
18 | static int wacom_penpartner_irq(struct wacom_wac *wacom) | 27 | static int wacom_penpartner_irq(struct wacom_wac *wacom) |
19 | { | 28 | { |
@@ -674,187 +683,234 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
674 | return 1; | 683 | return 1; |
675 | } | 684 | } |
676 | 685 | ||
677 | 686 | static int wacom_tpc_mt_touch(struct wacom_wac *wacom) | |
678 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx) | ||
679 | { | 687 | { |
680 | struct input_dev *input = wacom->input; | 688 | struct input_dev *input = wacom->input; |
681 | int finger = idx + 1; | 689 | unsigned char *data = wacom->data; |
682 | int x = le16_to_cpup((__le16 *)&data[finger * 2]) & 0x7fff; | 690 | int contact_with_no_pen_down_count = 0; |
683 | int y = le16_to_cpup((__le16 *)&data[4 + finger * 2]) & 0x7fff; | 691 | int i; |
684 | 692 | ||
685 | /* | 693 | for (i = 0; i < 2; i++) { |
686 | * Work around input core suppressing "duplicate" events since | 694 | int p = data[1] & (1 << i); |
687 | * we are abusing ABS_X/ABS_Y to transmit multi-finger data. | 695 | bool touch = p && !wacom->shared->stylus_in_proximity; |
688 | * This should go away once we switch to true multitouch | ||
689 | * protocol. | ||
690 | */ | ||
691 | if (wacom->last_finger != finger) { | ||
692 | if (x == input_abs_get_val(input, ABS_X)) | ||
693 | x++; | ||
694 | 696 | ||
695 | if (y == input_abs_get_val(input, ABS_Y)) | 697 | input_mt_slot(input, i); |
696 | y++; | 698 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
699 | if (touch) { | ||
700 | int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff; | ||
701 | int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff; | ||
702 | |||
703 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
704 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
705 | contact_with_no_pen_down_count++; | ||
706 | } | ||
697 | } | 707 | } |
698 | 708 | ||
699 | input_report_abs(input, ABS_X, x); | 709 | /* keep touch state for pen event */ |
700 | input_report_abs(input, ABS_Y, y); | 710 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); |
701 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
702 | input_report_key(input, wacom->tool[finger], 1); | ||
703 | if (!idx) | ||
704 | input_report_key(input, BTN_TOUCH, 1); | ||
705 | input_event(input, EV_MSC, MSC_SERIAL, finger); | ||
706 | input_sync(input); | ||
707 | 711 | ||
708 | wacom->last_finger = finger; | 712 | input_mt_report_pointer_emulation(input, true); |
709 | } | ||
710 | 713 | ||
711 | static void wacom_tpc_touch_out(struct wacom_wac *wacom, int idx) | 714 | return 1; |
712 | { | ||
713 | struct input_dev *input = wacom->input; | ||
714 | int finger = idx + 1; | ||
715 | |||
716 | input_report_abs(input, ABS_X, 0); | ||
717 | input_report_abs(input, ABS_Y, 0); | ||
718 | input_report_abs(input, ABS_MISC, 0); | ||
719 | input_report_key(input, wacom->tool[finger], 0); | ||
720 | if (!idx) | ||
721 | input_report_key(input, BTN_TOUCH, 0); | ||
722 | input_event(input, EV_MSC, MSC_SERIAL, finger); | ||
723 | input_sync(input); | ||
724 | } | 715 | } |
725 | 716 | ||
726 | static void wacom_tpc_touch_in(struct wacom_wac *wacom, size_t len) | 717 | static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) |
727 | { | 718 | { |
728 | char *data = wacom->data; | 719 | char *data = wacom->data; |
729 | struct input_dev *input = wacom->input; | 720 | struct input_dev *input = wacom->input; |
721 | bool prox; | ||
722 | int x = 0, y = 0; | ||
730 | 723 | ||
731 | wacom->tool[1] = BTN_TOOL_DOUBLETAP; | 724 | if (!wacom->shared->stylus_in_proximity) { |
732 | wacom->id[0] = TOUCH_DEVICE_ID; | 725 | if (len == WACOM_PKGLEN_TPC1FG) { |
733 | wacom->tool[2] = BTN_TOOL_TRIPLETAP; | 726 | prox = data[0] & 0x01; |
727 | x = get_unaligned_le16(&data[1]); | ||
728 | y = get_unaligned_le16(&data[3]); | ||
729 | } else { /* with capacity */ | ||
730 | prox = data[1] & 0x01; | ||
731 | x = le16_to_cpup((__le16 *)&data[2]); | ||
732 | y = le16_to_cpup((__le16 *)&data[4]); | ||
733 | } | ||
734 | } else | ||
735 | /* force touch out when pen is in prox */ | ||
736 | prox = 0; | ||
734 | 737 | ||
735 | if (len != WACOM_PKGLEN_TPC1FG) { | 738 | if (prox) { |
739 | input_report_abs(input, ABS_X, x); | ||
740 | input_report_abs(input, ABS_Y, y); | ||
741 | } | ||
742 | input_report_key(input, BTN_TOUCH, prox); | ||
736 | 743 | ||
737 | switch (data[0]) { | 744 | /* keep touch state for pen events */ |
745 | wacom->shared->touch_down = prox; | ||
738 | 746 | ||
739 | case WACOM_REPORT_TPC1FG: | 747 | return 1; |
740 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); | 748 | } |
741 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); | ||
742 | input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6])); | ||
743 | input_report_key(input, BTN_TOUCH, le16_to_cpup((__le16 *)&data[6])); | ||
744 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
745 | input_report_key(input, wacom->tool[1], 1); | ||
746 | input_sync(input); | ||
747 | break; | ||
748 | 749 | ||
749 | case WACOM_REPORT_TPC2FG: | 750 | static int wacom_tpc_pen(struct wacom_wac *wacom) |
750 | if (data[1] & 0x01) | 751 | { |
751 | wacom_tpc_finger_in(wacom, data, 0); | 752 | struct wacom_features *features = &wacom->features; |
752 | else if (wacom->id[1] & 0x01) | 753 | char *data = wacom->data; |
753 | wacom_tpc_touch_out(wacom, 0); | 754 | struct input_dev *input = wacom->input; |
755 | int pressure; | ||
756 | bool prox = data[1] & 0x20; | ||
754 | 757 | ||
755 | if (data[1] & 0x02) | 758 | if (!wacom->shared->stylus_in_proximity) /* first in prox */ |
756 | wacom_tpc_finger_in(wacom, data, 1); | 759 | /* Going into proximity select tool */ |
757 | else if (wacom->id[1] & 0x02) | 760 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
758 | wacom_tpc_touch_out(wacom, 1); | 761 | |
759 | break; | 762 | /* keep pen state for touch events */ |
760 | } | 763 | wacom->shared->stylus_in_proximity = prox; |
761 | } else { | 764 | |
762 | input_report_abs(input, ABS_X, get_unaligned_le16(&data[1])); | 765 | /* send pen events only when touch is up or forced out */ |
763 | input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3])); | 766 | if (!wacom->shared->touch_down) { |
764 | input_report_key(input, BTN_TOUCH, 1); | 767 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); |
765 | input_report_abs(input, ABS_MISC, wacom->id[1]); | 768 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); |
766 | input_report_key(input, wacom->tool[1], 1); | 769 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); |
767 | input_sync(input); | 770 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); |
771 | pressure = ((data[7] & 0x01) << 8) | data[6]; | ||
772 | if (pressure < 0) | ||
773 | pressure = features->pressure_max + pressure + 1; | ||
774 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
775 | input_report_key(input, BTN_TOUCH, data[1] & 0x05); | ||
776 | input_report_key(input, wacom->tool[0], prox); | ||
777 | return 1; | ||
768 | } | 778 | } |
779 | |||
780 | return 0; | ||
769 | } | 781 | } |
770 | 782 | ||
771 | static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | 783 | static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) |
772 | { | 784 | { |
773 | struct wacom_features *features = &wacom->features; | ||
774 | char *data = wacom->data; | 785 | char *data = wacom->data; |
775 | struct input_dev *input = wacom->input; | ||
776 | int prox = 0, pressure; | ||
777 | int retval = 0; | ||
778 | 786 | ||
779 | dbg("wacom_tpc_irq: received report #%d", data[0]); | 787 | dbg("wacom_tpc_irq: received report #%d", data[0]); |
780 | 788 | ||
781 | if (len == WACOM_PKGLEN_TPC1FG || /* single touch */ | 789 | if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG) |
782 | data[0] == WACOM_REPORT_TPC1FG || /* single touch */ | 790 | return wacom_tpc_single_touch(wacom, len); |
783 | data[0] == WACOM_REPORT_TPC2FG) { /* 2FG touch */ | 791 | else if (data[0] == WACOM_REPORT_TPC2FG) |
792 | return wacom_tpc_mt_touch(wacom); | ||
793 | else if (data[0] == WACOM_REPORT_PENABLED) | ||
794 | return wacom_tpc_pen(wacom); | ||
784 | 795 | ||
785 | if (wacom->shared->stylus_in_proximity) { | 796 | return 0; |
786 | if (wacom->id[1] & 0x01) | 797 | } |
787 | wacom_tpc_touch_out(wacom, 0); | ||
788 | 798 | ||
789 | if (wacom->id[1] & 0x02) | 799 | static int wacom_bpt_touch(struct wacom_wac *wacom) |
790 | wacom_tpc_touch_out(wacom, 1); | 800 | { |
801 | struct wacom_features *features = &wacom->features; | ||
802 | struct input_dev *input = wacom->input; | ||
803 | unsigned char *data = wacom->data; | ||
804 | int i; | ||
791 | 805 | ||
792 | wacom->id[1] = 0; | 806 | for (i = 0; i < 2; i++) { |
793 | return 0; | 807 | int p = data[9 * i + 2]; |
794 | } | 808 | bool touch = p && !wacom->shared->stylus_in_proximity; |
795 | 809 | ||
796 | if (len == WACOM_PKGLEN_TPC1FG) { /* with touch */ | 810 | input_mt_slot(input, i); |
797 | prox = data[0] & 0x01; | 811 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
798 | } else { /* with capacity */ | 812 | /* |
799 | if (data[0] == WACOM_REPORT_TPC1FG) | 813 | * Touch events need to be disabled while stylus is |
800 | /* single touch */ | 814 | * in proximity because user's hand is resting on touchpad |
801 | prox = data[1] & 0x01; | 815 | * and sending unwanted events. User expects tablet buttons |
802 | else | 816 | * to continue working though. |
803 | /* 2FG touch data */ | 817 | */ |
804 | prox = data[1] & 0x03; | 818 | if (touch) { |
819 | int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; | ||
820 | int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; | ||
821 | if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { | ||
822 | x <<= 5; | ||
823 | y <<= 5; | ||
824 | } | ||
825 | input_report_abs(input, ABS_MT_PRESSURE, p); | ||
826 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
827 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
805 | } | 828 | } |
829 | } | ||
806 | 830 | ||
807 | if (prox) { | 831 | input_mt_report_pointer_emulation(input, true); |
808 | if (!wacom->id[1]) | ||
809 | wacom->last_finger = 1; | ||
810 | wacom_tpc_touch_in(wacom, len); | ||
811 | } else { | ||
812 | if (data[0] == WACOM_REPORT_TPC2FG) { | ||
813 | /* 2FGT out-prox */ | ||
814 | if (wacom->id[1] & 0x01) | ||
815 | wacom_tpc_touch_out(wacom, 0); | ||
816 | 832 | ||
817 | if (wacom->id[1] & 0x02) | 833 | input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); |
818 | wacom_tpc_touch_out(wacom, 1); | 834 | input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); |
819 | } else | 835 | input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0); |
820 | /* one finger touch */ | 836 | input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0); |
821 | wacom_tpc_touch_out(wacom, 0); | ||
822 | 837 | ||
823 | wacom->id[0] = 0; | 838 | input_sync(input); |
824 | } | 839 | |
825 | /* keep prox bit to send proper out-prox event */ | 840 | return 0; |
826 | wacom->id[1] = prox; | 841 | } |
827 | } else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */ | 842 | |
828 | prox = data[1] & 0x20; | 843 | static int wacom_bpt_pen(struct wacom_wac *wacom) |
829 | 844 | { | |
830 | if (!wacom->shared->stylus_in_proximity) { /* first in prox */ | 845 | struct input_dev *input = wacom->input; |
831 | /* Going into proximity select tool */ | 846 | unsigned char *data = wacom->data; |
832 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 847 | int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; |
833 | if (wacom->tool[0] == BTN_TOOL_PEN) | ||
834 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
835 | else | ||
836 | wacom->id[0] = ERASER_DEVICE_ID; | ||
837 | 848 | ||
849 | /* | ||
850 | * Similar to Graphire protocol, data[1] & 0x20 is proximity and | ||
851 | * data[1] & 0x18 is tool ID. 0x30 is safety check to ignore | ||
852 | * 2 unused tool ID's. | ||
853 | */ | ||
854 | prox = (data[1] & 0x30) == 0x30; | ||
855 | |||
856 | /* | ||
857 | * All reports shared between PEN and RUBBER tool must be | ||
858 | * forced to a known starting value (zero) when transitioning to | ||
859 | * out-of-prox. | ||
860 | * | ||
861 | * If not reset then, to userspace, it will look like lost events | ||
862 | * if new tool comes in-prox with same values as previous tool sent. | ||
863 | * | ||
864 | * Hardware does report zero in most out-of-prox cases but not all. | ||
865 | */ | ||
866 | if (prox) { | ||
867 | if (!wacom->shared->stylus_in_proximity) { | ||
868 | if (data[1] & 0x08) { | ||
869 | wacom->tool[0] = BTN_TOOL_RUBBER; | ||
870 | wacom->id[0] = ERASER_DEVICE_ID; | ||
871 | } else { | ||
872 | wacom->tool[0] = BTN_TOOL_PEN; | ||
873 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
874 | } | ||
838 | wacom->shared->stylus_in_proximity = true; | 875 | wacom->shared->stylus_in_proximity = true; |
839 | } | 876 | } |
840 | input_report_key(input, BTN_STYLUS, data[1] & 0x02); | 877 | x = le16_to_cpup((__le16 *)&data[2]); |
841 | input_report_key(input, BTN_STYLUS2, data[1] & 0x10); | 878 | y = le16_to_cpup((__le16 *)&data[4]); |
842 | input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); | 879 | p = le16_to_cpup((__le16 *)&data[6]); |
843 | input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); | 880 | d = data[8]; |
844 | pressure = ((data[7] & 0x01) << 8) | data[6]; | 881 | pen = data[1] & 0x01; |
845 | if (pressure < 0) | 882 | btn1 = data[1] & 0x02; |
846 | pressure = features->pressure_max + pressure + 1; | 883 | btn2 = data[1] & 0x04; |
847 | input_report_abs(input, ABS_PRESSURE, pressure); | ||
848 | input_report_key(input, BTN_TOUCH, data[1] & 0x05); | ||
849 | if (!prox) { /* out-prox */ | ||
850 | wacom->id[0] = 0; | ||
851 | wacom->shared->stylus_in_proximity = false; | ||
852 | } | ||
853 | input_report_key(input, wacom->tool[0], prox); | ||
854 | input_report_abs(input, ABS_MISC, wacom->id[0]); | ||
855 | retval = 1; | ||
856 | } | 884 | } |
857 | return retval; | 885 | |
886 | input_report_key(input, BTN_TOUCH, pen); | ||
887 | input_report_key(input, BTN_STYLUS, btn1); | ||
888 | input_report_key(input, BTN_STYLUS2, btn2); | ||
889 | |||
890 | input_report_abs(input, ABS_X, x); | ||
891 | input_report_abs(input, ABS_Y, y); | ||
892 | input_report_abs(input, ABS_PRESSURE, p); | ||
893 | input_report_abs(input, ABS_DISTANCE, d); | ||
894 | |||
895 | if (!prox) { | ||
896 | wacom->id[0] = 0; | ||
897 | wacom->shared->stylus_in_proximity = false; | ||
898 | } | ||
899 | |||
900 | input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ | ||
901 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ | ||
902 | |||
903 | return 1; | ||
904 | } | ||
905 | |||
906 | static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) | ||
907 | { | ||
908 | if (len == WACOM_PKGLEN_BBTOUCH) | ||
909 | return wacom_bpt_touch(wacom); | ||
910 | else if (len == WACOM_PKGLEN_BBFUN) | ||
911 | return wacom_bpt_pen(wacom); | ||
912 | |||
913 | return 0; | ||
858 | } | 914 | } |
859 | 915 | ||
860 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | 916 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) |
@@ -902,6 +958,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
902 | sync = wacom_tpc_irq(wacom_wac, len); | 958 | sync = wacom_tpc_irq(wacom_wac, len); |
903 | break; | 959 | break; |
904 | 960 | ||
961 | case BAMBOO_PT: | ||
962 | sync = wacom_bpt_irq(wacom_wac, len); | ||
963 | break; | ||
964 | |||
905 | default: | 965 | default: |
906 | sync = false; | 966 | sync = false; |
907 | break; | 967 | break; |
@@ -911,26 +971,17 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
911 | input_sync(wacom_wac->input); | 971 | input_sync(wacom_wac->input); |
912 | } | 972 | } |
913 | 973 | ||
914 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | 974 | static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) |
915 | { | 975 | { |
916 | struct input_dev *input_dev = wacom_wac->input; | 976 | struct input_dev *input_dev = wacom_wac->input; |
917 | 977 | ||
918 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | 978 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); |
919 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | ||
920 | |||
921 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
922 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
923 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
924 | __set_bit(BTN_SIDE, input_dev->keybit); | ||
925 | __set_bit(BTN_EXTRA, input_dev->keybit); | ||
926 | 979 | ||
927 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 980 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
928 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | 981 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
929 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); | ||
930 | __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); | 982 | __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); |
931 | __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); | 983 | __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); |
932 | __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); | 984 | __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); |
933 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); | ||
934 | __set_bit(BTN_STYLUS, input_dev->keybit); | 985 | __set_bit(BTN_STYLUS, input_dev->keybit); |
935 | __set_bit(BTN_STYLUS2, input_dev->keybit); | 986 | __set_bit(BTN_STYLUS2, input_dev->keybit); |
936 | 987 | ||
@@ -939,10 +990,62 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | |||
939 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); | 990 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); |
940 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); | 991 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); |
941 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); | 992 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); |
993 | } | ||
994 | |||
995 | static void wacom_setup_intuos(struct wacom_wac *wacom_wac) | ||
996 | { | ||
997 | struct input_dev *input_dev = wacom_wac->input; | ||
998 | |||
999 | input_set_capability(input_dev, EV_REL, REL_WHEEL); | ||
1000 | |||
1001 | wacom_setup_cintiq(wacom_wac); | ||
1002 | |||
1003 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
1004 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
1005 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
1006 | __set_bit(BTN_SIDE, input_dev->keybit); | ||
1007 | __set_bit(BTN_EXTRA, input_dev->keybit); | ||
1008 | __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); | ||
1009 | __set_bit(BTN_TOOL_LENS, input_dev->keybit); | ||
1010 | |||
942 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); | 1011 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); |
943 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); | 1012 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); |
944 | } | 1013 | } |
945 | 1014 | ||
1015 | void wacom_setup_device_quirks(struct wacom_features *features) | ||
1016 | { | ||
1017 | |||
1018 | /* touch device found but size is not defined. use default */ | ||
1019 | if (features->device_type == BTN_TOOL_FINGER && !features->x_max) { | ||
1020 | features->x_max = 1023; | ||
1021 | features->y_max = 1023; | ||
1022 | } | ||
1023 | |||
1024 | /* these device have multiple inputs */ | ||
1025 | if (features->type == TABLETPC || features->type == TABLETPC2FG || | ||
1026 | features->type == BAMBOO_PT) | ||
1027 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | ||
1028 | |||
1029 | /* quirks for bamboo touch */ | ||
1030 | if (features->type == BAMBOO_PT && | ||
1031 | features->device_type == BTN_TOOL_DOUBLETAP) { | ||
1032 | features->x_max <<= 5; | ||
1033 | features->y_max <<= 5; | ||
1034 | features->x_fuzz <<= 5; | ||
1035 | features->y_fuzz <<= 5; | ||
1036 | features->pressure_max = 256; | ||
1037 | features->pressure_fuzz = 16; | ||
1038 | features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; | ||
1039 | } | ||
1040 | } | ||
1041 | |||
1042 | static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | ||
1043 | unsigned int physical_max) | ||
1044 | { | ||
1045 | /* Touch physical dimensions are in 100th of mm */ | ||
1046 | return (logical_max * 100) / physical_max; | ||
1047 | } | ||
1048 | |||
946 | void wacom_setup_input_capabilities(struct input_dev *input_dev, | 1049 | void wacom_setup_input_capabilities(struct input_dev *input_dev, |
947 | struct wacom_wac *wacom_wac) | 1050 | struct wacom_wac *wacom_wac) |
948 | { | 1051 | { |
@@ -953,9 +1056,25 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
953 | 1056 | ||
954 | __set_bit(BTN_TOUCH, input_dev->keybit); | 1057 | __set_bit(BTN_TOUCH, input_dev->keybit); |
955 | 1058 | ||
956 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); | 1059 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, |
957 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); | 1060 | features->x_fuzz, 0); |
958 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); | 1061 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, |
1062 | features->y_fuzz, 0); | ||
1063 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, | ||
1064 | features->pressure_fuzz, 0); | ||
1065 | |||
1066 | if (features->device_type == BTN_TOOL_PEN) { | ||
1067 | /* penabled devices have fixed resolution for each model */ | ||
1068 | input_abs_set_res(input_dev, ABS_X, features->x_resolution); | ||
1069 | input_abs_set_res(input_dev, ABS_Y, features->y_resolution); | ||
1070 | } else { | ||
1071 | input_abs_set_res(input_dev, ABS_X, | ||
1072 | wacom_calculate_touch_res(features->x_max, | ||
1073 | features->x_phy)); | ||
1074 | input_abs_set_res(input_dev, ABS_Y, | ||
1075 | wacom_calculate_touch_res(features->y_max, | ||
1076 | features->y_phy)); | ||
1077 | } | ||
959 | 1078 | ||
960 | __set_bit(ABS_MISC, input_dev->absbit); | 1079 | __set_bit(ABS_MISC, input_dev->absbit); |
961 | 1080 | ||
@@ -1005,9 +1124,19 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1005 | __set_bit(BTN_9, input_dev->keybit); | 1124 | __set_bit(BTN_9, input_dev->keybit); |
1006 | /* fall through */ | 1125 | /* fall through */ |
1007 | 1126 | ||
1127 | case CINTIQ: | ||
1128 | for (i = 0; i < 8; i++) | ||
1129 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
1130 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1131 | |||
1132 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | ||
1133 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | ||
1134 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
1135 | wacom_setup_cintiq(wacom_wac); | ||
1136 | break; | ||
1137 | |||
1008 | case INTUOS3: | 1138 | case INTUOS3: |
1009 | case INTUOS3L: | 1139 | case INTUOS3L: |
1010 | case CINTIQ: | ||
1011 | __set_bit(BTN_4, input_dev->keybit); | 1140 | __set_bit(BTN_4, input_dev->keybit); |
1012 | __set_bit(BTN_5, input_dev->keybit); | 1141 | __set_bit(BTN_5, input_dev->keybit); |
1013 | __set_bit(BTN_6, input_dev->keybit); | 1142 | __set_bit(BTN_6, input_dev->keybit); |
@@ -1048,19 +1177,20 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1048 | break; | 1177 | break; |
1049 | 1178 | ||
1050 | case TABLETPC2FG: | 1179 | case TABLETPC2FG: |
1051 | if (features->device_type == BTN_TOOL_TRIPLETAP) { | 1180 | if (features->device_type == BTN_TOOL_DOUBLETAP) { |
1052 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 1181 | |
1053 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | 1182 | input_mt_init_slots(input_dev, 2); |
1183 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, | ||
1184 | 0, MT_TOOL_MAX, 0, 0); | ||
1185 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1186 | 0, features->x_max, 0, 0); | ||
1187 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1188 | 0, features->y_max, 0, 0); | ||
1054 | } | 1189 | } |
1055 | /* fall through */ | 1190 | /* fall through */ |
1056 | 1191 | ||
1057 | case TABLETPC: | 1192 | case TABLETPC: |
1058 | if (features->device_type == BTN_TOOL_DOUBLETAP || | 1193 | __clear_bit(ABS_MISC, input_dev->absbit); |
1059 | features->device_type == BTN_TOOL_TRIPLETAP) { | ||
1060 | input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0); | ||
1061 | input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0); | ||
1062 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1063 | } | ||
1064 | 1194 | ||
1065 | if (features->device_type != BTN_TOOL_PEN) | 1195 | if (features->device_type != BTN_TOOL_PEN) |
1066 | break; /* no need to process stylus stuff */ | 1196 | break; /* no need to process stylus stuff */ |
@@ -1078,148 +1208,285 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1078 | case PENPARTNER: | 1208 | case PENPARTNER: |
1079 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 1209 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
1080 | break; | 1210 | break; |
1211 | |||
1212 | case BAMBOO_PT: | ||
1213 | __clear_bit(ABS_MISC, input_dev->absbit); | ||
1214 | |||
1215 | if (features->device_type == BTN_TOOL_DOUBLETAP) { | ||
1216 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
1217 | __set_bit(BTN_FORWARD, input_dev->keybit); | ||
1218 | __set_bit(BTN_BACK, input_dev->keybit); | ||
1219 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
1220 | |||
1221 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1222 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1223 | |||
1224 | input_mt_init_slots(input_dev, 2); | ||
1225 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1226 | 0, features->x_max, | ||
1227 | features->x_fuzz, 0); | ||
1228 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1229 | 0, features->y_max, | ||
1230 | features->y_fuzz, 0); | ||
1231 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | ||
1232 | 0, features->pressure_max, | ||
1233 | features->pressure_fuzz, 0); | ||
1234 | } else if (features->device_type == BTN_TOOL_PEN) { | ||
1235 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | ||
1236 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | ||
1237 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
1238 | __set_bit(BTN_STYLUS2, input_dev->keybit); | ||
1239 | } | ||
1240 | break; | ||
1081 | } | 1241 | } |
1082 | } | 1242 | } |
1083 | 1243 | ||
1084 | static const struct wacom_features wacom_features_0x00 = | 1244 | static const struct wacom_features wacom_features_0x00 = |
1085 | { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }; | 1245 | { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, |
1246 | 0, PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; | ||
1086 | static const struct wacom_features wacom_features_0x10 = | 1247 | static const struct wacom_features wacom_features_0x10 = |
1087 | { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; | 1248 | { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, |
1249 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1088 | static const struct wacom_features wacom_features_0x11 = | 1250 | static const struct wacom_features wacom_features_0x11 = |
1089 | { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; | 1251 | { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, |
1252 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1090 | static const struct wacom_features wacom_features_0x12 = | 1253 | static const struct wacom_features wacom_features_0x12 = |
1091 | { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }; | 1254 | { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, |
1255 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1092 | static const struct wacom_features wacom_features_0x13 = | 1256 | static const struct wacom_features wacom_features_0x13 = |
1093 | { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }; | 1257 | { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, |
1258 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1094 | static const struct wacom_features wacom_features_0x14 = | 1259 | static const struct wacom_features wacom_features_0x14 = |
1095 | { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; | 1260 | { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, |
1261 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1096 | static const struct wacom_features wacom_features_0x15 = | 1262 | static const struct wacom_features wacom_features_0x15 = |
1097 | { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }; | 1263 | { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, |
1264 | 63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1098 | static const struct wacom_features wacom_features_0x16 = | 1265 | static const struct wacom_features wacom_features_0x16 = |
1099 | { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }; | 1266 | { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, |
1267 | 63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1100 | static const struct wacom_features wacom_features_0x17 = | 1268 | static const struct wacom_features wacom_features_0x17 = |
1101 | { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; | 1269 | { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, |
1270 | 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1102 | static const struct wacom_features wacom_features_0x18 = | 1271 | static const struct wacom_features wacom_features_0x18 = |
1103 | { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }; | 1272 | { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, |
1273 | 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1104 | static const struct wacom_features wacom_features_0x19 = | 1274 | static const struct wacom_features wacom_features_0x19 = |
1105 | { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; | 1275 | { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, |
1276 | 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; | ||
1106 | static const struct wacom_features wacom_features_0x60 = | 1277 | static const struct wacom_features wacom_features_0x60 = |
1107 | { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | 1278 | { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, |
1279 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1108 | static const struct wacom_features wacom_features_0x61 = | 1280 | static const struct wacom_features wacom_features_0x61 = |
1109 | { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }; | 1281 | { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, |
1282 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1110 | static const struct wacom_features wacom_features_0x62 = | 1283 | static const struct wacom_features wacom_features_0x62 = |
1111 | { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | 1284 | { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, |
1285 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1112 | static const struct wacom_features wacom_features_0x63 = | 1286 | static const struct wacom_features wacom_features_0x63 = |
1113 | { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }; | 1287 | { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, |
1288 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1114 | static const struct wacom_features wacom_features_0x64 = | 1289 | static const struct wacom_features wacom_features_0x64 = |
1115 | { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }; | 1290 | { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, |
1291 | 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; | ||
1116 | static const struct wacom_features wacom_features_0x65 = | 1292 | static const struct wacom_features wacom_features_0x65 = |
1117 | { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; | 1293 | { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, |
1294 | 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1118 | static const struct wacom_features wacom_features_0x69 = | 1295 | static const struct wacom_features wacom_features_0x69 = |
1119 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; | 1296 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, |
1297 | 63, GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; | ||
1120 | static const struct wacom_features wacom_features_0x20 = | 1298 | static const struct wacom_features wacom_features_0x20 = |
1121 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; | 1299 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, |
1300 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1122 | static const struct wacom_features wacom_features_0x21 = | 1301 | static const struct wacom_features wacom_features_0x21 = |
1123 | { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | 1302 | { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
1303 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1124 | static const struct wacom_features wacom_features_0x22 = | 1304 | static const struct wacom_features wacom_features_0x22 = |
1125 | { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; | 1305 | { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, |
1306 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1126 | static const struct wacom_features wacom_features_0x23 = | 1307 | static const struct wacom_features wacom_features_0x23 = |
1127 | { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; | 1308 | { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, |
1309 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1128 | static const struct wacom_features wacom_features_0x24 = | 1310 | static const struct wacom_features wacom_features_0x24 = |
1129 | { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; | 1311 | { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, |
1312 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1130 | static const struct wacom_features wacom_features_0x30 = | 1313 | static const struct wacom_features wacom_features_0x30 = |
1131 | { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }; | 1314 | { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, |
1315 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1132 | static const struct wacom_features wacom_features_0x31 = | 1316 | static const struct wacom_features wacom_features_0x31 = |
1133 | { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }; | 1317 | { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, |
1318 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1134 | static const struct wacom_features wacom_features_0x32 = | 1319 | static const struct wacom_features wacom_features_0x32 = |
1135 | { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }; | 1320 | { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, |
1321 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1136 | static const struct wacom_features wacom_features_0x33 = | 1322 | static const struct wacom_features wacom_features_0x33 = |
1137 | { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }; | 1323 | { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, |
1324 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1138 | static const struct wacom_features wacom_features_0x34 = | 1325 | static const struct wacom_features wacom_features_0x34 = |
1139 | { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }; | 1326 | { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, |
1327 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1140 | static const struct wacom_features wacom_features_0x35 = | 1328 | static const struct wacom_features wacom_features_0x35 = |
1141 | { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }; | 1329 | { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, |
1330 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1142 | static const struct wacom_features wacom_features_0x37 = | 1331 | static const struct wacom_features wacom_features_0x37 = |
1143 | { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }; | 1332 | { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, |
1333 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1144 | static const struct wacom_features wacom_features_0x38 = | 1334 | static const struct wacom_features wacom_features_0x38 = |
1145 | { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; | 1335 | { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, |
1336 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1146 | static const struct wacom_features wacom_features_0x39 = | 1337 | static const struct wacom_features wacom_features_0x39 = |
1147 | { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }; | 1338 | { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, |
1339 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1148 | static const struct wacom_features wacom_features_0xC4 = | 1340 | static const struct wacom_features wacom_features_0xC4 = |
1149 | { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; | 1341 | { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, |
1342 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1150 | static const struct wacom_features wacom_features_0xC0 = | 1343 | static const struct wacom_features wacom_features_0xC0 = |
1151 | { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; | 1344 | { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, |
1345 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1152 | static const struct wacom_features wacom_features_0xC2 = | 1346 | static const struct wacom_features wacom_features_0xC2 = |
1153 | { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; | 1347 | { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, |
1348 | 0, PL, WACOM_PL_RES, WACOM_PL_RES }; | ||
1154 | static const struct wacom_features wacom_features_0x03 = | 1349 | static const struct wacom_features wacom_features_0x03 = |
1155 | { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }; | 1350 | { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, |
1351 | 0, PTU, WACOM_PL_RES, WACOM_PL_RES }; | ||
1156 | static const struct wacom_features wacom_features_0x41 = | 1352 | static const struct wacom_features wacom_features_0x41 = |
1157 | { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; | 1353 | { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, |
1354 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1158 | static const struct wacom_features wacom_features_0x42 = | 1355 | static const struct wacom_features wacom_features_0x42 = |
1159 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | 1356 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
1357 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1160 | static const struct wacom_features wacom_features_0x43 = | 1358 | static const struct wacom_features wacom_features_0x43 = |
1161 | { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; | 1359 | { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, |
1360 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1162 | static const struct wacom_features wacom_features_0x44 = | 1361 | static const struct wacom_features wacom_features_0x44 = |
1163 | { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; | 1362 | { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, |
1363 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1164 | static const struct wacom_features wacom_features_0x45 = | 1364 | static const struct wacom_features wacom_features_0x45 = |
1165 | { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; | 1365 | { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, |
1366 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1166 | static const struct wacom_features wacom_features_0xB0 = | 1367 | static const struct wacom_features wacom_features_0xB0 = |
1167 | { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }; | 1368 | { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, |
1369 | 63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1168 | static const struct wacom_features wacom_features_0xB1 = | 1370 | static const struct wacom_features wacom_features_0xB1 = |
1169 | { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }; | 1371 | { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, |
1372 | 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1170 | static const struct wacom_features wacom_features_0xB2 = | 1373 | static const struct wacom_features wacom_features_0xB2 = |
1171 | { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }; | 1374 | { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, |
1375 | 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1172 | static const struct wacom_features wacom_features_0xB3 = | 1376 | static const struct wacom_features wacom_features_0xB3 = |
1173 | { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }; | 1377 | { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, |
1378 | 63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1174 | static const struct wacom_features wacom_features_0xB4 = | 1379 | static const struct wacom_features wacom_features_0xB4 = |
1175 | { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }; | 1380 | { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, |
1381 | 63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1176 | static const struct wacom_features wacom_features_0xB5 = | 1382 | static const struct wacom_features wacom_features_0xB5 = |
1177 | { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }; | 1383 | { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, |
1384 | 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1178 | static const struct wacom_features wacom_features_0xB7 = | 1385 | static const struct wacom_features wacom_features_0xB7 = |
1179 | { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }; | 1386 | { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, |
1387 | 63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1180 | static const struct wacom_features wacom_features_0xB8 = | 1388 | static const struct wacom_features wacom_features_0xB8 = |
1181 | { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }; | 1389 | { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, |
1390 | 63, INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1182 | static const struct wacom_features wacom_features_0xB9 = | 1391 | static const struct wacom_features wacom_features_0xB9 = |
1183 | { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }; | 1392 | { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, |
1393 | 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1184 | static const struct wacom_features wacom_features_0xBA = | 1394 | static const struct wacom_features wacom_features_0xBA = |
1185 | { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; | 1395 | { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, |
1396 | 63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1186 | static const struct wacom_features wacom_features_0xBB = | 1397 | static const struct wacom_features wacom_features_0xBB = |
1187 | { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; | 1398 | { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, |
1399 | 63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1188 | static const struct wacom_features wacom_features_0xBC = | 1400 | static const struct wacom_features wacom_features_0xBC = |
1189 | { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, 63, INTUOS4 }; | 1401 | { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, |
1402 | 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1190 | static const struct wacom_features wacom_features_0x3F = | 1403 | static const struct wacom_features wacom_features_0x3F = |
1191 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; | 1404 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, |
1405 | 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1192 | static const struct wacom_features wacom_features_0xC5 = | 1406 | static const struct wacom_features wacom_features_0xC5 = |
1193 | { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }; | 1407 | { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, |
1408 | 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1194 | static const struct wacom_features wacom_features_0xC6 = | 1409 | static const struct wacom_features wacom_features_0xC6 = |
1195 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; | 1410 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, |
1411 | 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1196 | static const struct wacom_features wacom_features_0xC7 = | 1412 | static const struct wacom_features wacom_features_0xC7 = |
1197 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; | 1413 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, |
1414 | 0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1198 | static const struct wacom_features wacom_features_0xCE = | 1415 | static const struct wacom_features wacom_features_0xCE = |
1199 | { "Wacom DTU2231", WACOM_PKGLEN_GRAPHIRE, 47864, 27011, 511, 0, DTU }; | 1416 | { "Wacom DTU2231", WACOM_PKGLEN_GRAPHIRE, 47864, 27011, 511, |
1417 | 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1200 | static const struct wacom_features wacom_features_0xF0 = | 1418 | static const struct wacom_features wacom_features_0xF0 = |
1201 | { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, 0, DTU }; | 1419 | { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, |
1420 | 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1202 | static const struct wacom_features wacom_features_0xCC = | 1421 | static const struct wacom_features wacom_features_0xCC = |
1203 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, 63, WACOM_21UX2 }; | 1422 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, |
1423 | 63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1204 | static const struct wacom_features wacom_features_0x90 = | 1424 | static const struct wacom_features wacom_features_0x90 = |
1205 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 1425 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
1426 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1206 | static const struct wacom_features wacom_features_0x93 = | 1427 | static const struct wacom_features wacom_features_0x93 = |
1207 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 1428 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
1429 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1208 | static const struct wacom_features wacom_features_0x9A = | 1430 | static const struct wacom_features wacom_features_0x9A = |
1209 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 1431 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
1432 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1210 | static const struct wacom_features wacom_features_0x9F = | 1433 | static const struct wacom_features wacom_features_0x9F = |
1211 | { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 1434 | { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
1435 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1212 | static const struct wacom_features wacom_features_0xE2 = | 1436 | static const struct wacom_features wacom_features_0xE2 = |
1213 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; | 1437 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, |
1438 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1214 | static const struct wacom_features wacom_features_0xE3 = | 1439 | static const struct wacom_features wacom_features_0xE3 = |
1215 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; | 1440 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, |
1441 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1442 | static const struct wacom_features wacom_features_0xE6 = | ||
1443 | { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, | ||
1444 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1216 | static const struct wacom_features wacom_features_0x47 = | 1445 | static const struct wacom_features wacom_features_0x47 = |
1217 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | 1446 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
1447 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1448 | static const struct wacom_features wacom_features_0xD0 = | ||
1449 | { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1450 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1451 | static const struct wacom_features wacom_features_0xD1 = | ||
1452 | { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1453 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1454 | static const struct wacom_features wacom_features_0xD2 = | ||
1455 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1456 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1457 | static const struct wacom_features wacom_features_0xD3 = | ||
1458 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, | ||
1459 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1460 | static const struct wacom_features wacom_features_0xD4 = | ||
1461 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, | ||
1462 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1463 | static const struct wacom_features wacom_features_0xD6 = | ||
1464 | { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1465 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1466 | static const struct wacom_features wacom_features_0xD7 = | ||
1467 | { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1468 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1469 | static const struct wacom_features wacom_features_0xD8 = | ||
1470 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, | ||
1471 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1472 | static const struct wacom_features wacom_features_0xDA = | ||
1473 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | ||
1474 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1475 | static struct wacom_features wacom_features_0xDB = | ||
1476 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, | ||
1477 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1478 | static const struct wacom_features wacom_features_0x6004 = | ||
1479 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, | ||
1480 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1218 | 1481 | ||
1219 | #define USB_DEVICE_WACOM(prod) \ | 1482 | #define USB_DEVICE_WACOM(prod) \ |
1220 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 1483 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
1221 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | 1484 | .driver_info = (kernel_ulong_t)&wacom_features_##prod |
1222 | 1485 | ||
1486 | #define USB_DEVICE_LENOVO(prod) \ | ||
1487 | USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ | ||
1488 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | ||
1489 | |||
1223 | const struct usb_device_id wacom_ids[] = { | 1490 | const struct usb_device_id wacom_ids[] = { |
1224 | { USB_DEVICE_WACOM(0x00) }, | 1491 | { USB_DEVICE_WACOM(0x00) }, |
1225 | { USB_DEVICE_WACOM(0x10) }, | 1492 | { USB_DEVICE_WACOM(0x10) }, |
@@ -1279,6 +1546,16 @@ const struct usb_device_id wacom_ids[] = { | |||
1279 | { USB_DEVICE_WACOM(0xC6) }, | 1546 | { USB_DEVICE_WACOM(0xC6) }, |
1280 | { USB_DEVICE_WACOM(0xC7) }, | 1547 | { USB_DEVICE_WACOM(0xC7) }, |
1281 | { USB_DEVICE_WACOM(0xCE) }, | 1548 | { USB_DEVICE_WACOM(0xCE) }, |
1549 | { USB_DEVICE_WACOM(0xD0) }, | ||
1550 | { USB_DEVICE_WACOM(0xD1) }, | ||
1551 | { USB_DEVICE_WACOM(0xD2) }, | ||
1552 | { USB_DEVICE_WACOM(0xD3) }, | ||
1553 | { USB_DEVICE_WACOM(0xD4) }, | ||
1554 | { USB_DEVICE_WACOM(0xD6) }, | ||
1555 | { USB_DEVICE_WACOM(0xD7) }, | ||
1556 | { USB_DEVICE_WACOM(0xD8) }, | ||
1557 | { USB_DEVICE_WACOM(0xDA) }, | ||
1558 | { USB_DEVICE_WACOM(0xDB) }, | ||
1282 | { USB_DEVICE_WACOM(0xF0) }, | 1559 | { USB_DEVICE_WACOM(0xF0) }, |
1283 | { USB_DEVICE_WACOM(0xCC) }, | 1560 | { USB_DEVICE_WACOM(0xCC) }, |
1284 | { USB_DEVICE_WACOM(0x90) }, | 1561 | { USB_DEVICE_WACOM(0x90) }, |
@@ -1287,7 +1564,9 @@ const struct usb_device_id wacom_ids[] = { | |||
1287 | { USB_DEVICE_WACOM(0x9F) }, | 1564 | { USB_DEVICE_WACOM(0x9F) }, |
1288 | { USB_DEVICE_WACOM(0xE2) }, | 1565 | { USB_DEVICE_WACOM(0xE2) }, |
1289 | { USB_DEVICE_WACOM(0xE3) }, | 1566 | { USB_DEVICE_WACOM(0xE3) }, |
1567 | { USB_DEVICE_WACOM(0xE6) }, | ||
1290 | { USB_DEVICE_WACOM(0x47) }, | 1568 | { USB_DEVICE_WACOM(0x47) }, |
1569 | { USB_DEVICE_LENOVO(0x6004) }, | ||
1291 | { } | 1570 | { } |
1292 | }; | 1571 | }; |
1293 | MODULE_DEVICE_TABLE(usb, wacom_ids); | 1572 | MODULE_DEVICE_TABLE(usb, wacom_ids); |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 99e1a54cd305..53eb71b68330 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define WACOM_PKGLEN_INTUOS 10 | 21 | #define WACOM_PKGLEN_INTUOS 10 |
22 | #define WACOM_PKGLEN_TPC1FG 5 | 22 | #define WACOM_PKGLEN_TPC1FG 5 |
23 | #define WACOM_PKGLEN_TPC2FG 14 | 23 | #define WACOM_PKGLEN_TPC2FG 14 |
24 | #define WACOM_PKGLEN_BBTOUCH 20 | ||
24 | 25 | ||
25 | /* device IDs */ | 26 | /* device IDs */ |
26 | #define STYLUS_DEVICE_ID 0x02 | 27 | #define STYLUS_DEVICE_ID 0x02 |
@@ -37,6 +38,10 @@ | |||
37 | #define WACOM_REPORT_TPC1FG 6 | 38 | #define WACOM_REPORT_TPC1FG 6 |
38 | #define WACOM_REPORT_TPC2FG 13 | 39 | #define WACOM_REPORT_TPC2FG 13 |
39 | 40 | ||
41 | /* device quirks */ | ||
42 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 | ||
43 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 | ||
44 | |||
40 | enum { | 45 | enum { |
41 | PENPARTNER = 0, | 46 | PENPARTNER = 0, |
42 | GRAPHIRE, | 47 | GRAPHIRE, |
@@ -44,6 +49,7 @@ enum { | |||
44 | PTU, | 49 | PTU, |
45 | PL, | 50 | PL, |
46 | DTU, | 51 | DTU, |
52 | BAMBOO_PT, | ||
47 | INTUOS, | 53 | INTUOS, |
48 | INTUOS3S, | 54 | INTUOS3S, |
49 | INTUOS3, | 55 | INTUOS3, |
@@ -68,24 +74,31 @@ struct wacom_features { | |||
68 | int pressure_max; | 74 | int pressure_max; |
69 | int distance_max; | 75 | int distance_max; |
70 | int type; | 76 | int type; |
77 | int x_resolution; | ||
78 | int y_resolution; | ||
71 | int device_type; | 79 | int device_type; |
72 | int x_phy; | 80 | int x_phy; |
73 | int y_phy; | 81 | int y_phy; |
74 | unsigned char unit; | 82 | unsigned char unit; |
75 | unsigned char unitExpo; | 83 | unsigned char unitExpo; |
84 | int x_fuzz; | ||
85 | int y_fuzz; | ||
86 | int pressure_fuzz; | ||
87 | int distance_fuzz; | ||
88 | unsigned quirks; | ||
76 | }; | 89 | }; |
77 | 90 | ||
78 | struct wacom_shared { | 91 | struct wacom_shared { |
79 | bool stylus_in_proximity; | 92 | bool stylus_in_proximity; |
93 | bool touch_down; | ||
80 | }; | 94 | }; |
81 | 95 | ||
82 | struct wacom_wac { | 96 | struct wacom_wac { |
83 | char name[64]; | 97 | char name[64]; |
84 | unsigned char *data; | 98 | unsigned char *data; |
85 | int tool[3]; | 99 | int tool[2]; |
86 | int id[3]; | 100 | int id[2]; |
87 | __u32 serial[2]; | 101 | __u32 serial[2]; |
88 | int last_finger; | ||
89 | struct wacom_features features; | 102 | struct wacom_features features; |
90 | struct wacom_shared *shared; | 103 | struct wacom_shared *shared; |
91 | struct input_dev *input; | 104 | struct input_dev *input; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 0069d9703fda..cabd9e54863f 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -86,6 +86,18 @@ config TOUCHSCREEN_AD7879_SPI | |||
86 | To compile this driver as a module, choose M here: the | 86 | To compile this driver as a module, choose M here: the |
87 | module will be called ad7879-spi. | 87 | module will be called ad7879-spi. |
88 | 88 | ||
89 | config TOUCHSCREEN_ATMEL_MXT | ||
90 | tristate "Atmel mXT I2C Touchscreen" | ||
91 | depends on I2C | ||
92 | help | ||
93 | Say Y here if you have Atmel mXT series I2C touchscreen, | ||
94 | such as AT42QT602240/ATMXT224, connected to your system. | ||
95 | |||
96 | If unsure, say N. | ||
97 | |||
98 | To compile this driver as a module, choose M here: the | ||
99 | module will be called atmel_mxt_ts. | ||
100 | |||
89 | config TOUCHSCREEN_BITSY | 101 | config TOUCHSCREEN_BITSY |
90 | tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" | 102 | tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" |
91 | depends on SA1100_BITSY | 103 | depends on SA1100_BITSY |
@@ -98,6 +110,18 @@ config TOUCHSCREEN_BITSY | |||
98 | To compile this driver as a module, choose M here: the | 110 | To compile this driver as a module, choose M here: the |
99 | module will be called h3600_ts_input. | 111 | module will be called h3600_ts_input. |
100 | 112 | ||
113 | config TOUCHSCREEN_BU21013 | ||
114 | tristate "BU21013 based touch panel controllers" | ||
115 | depends on I2C | ||
116 | help | ||
117 | Say Y here if you have a bu21013 touchscreen connected to | ||
118 | your system. | ||
119 | |||
120 | If unsure, say N. | ||
121 | |||
122 | To compile this driver as a module, choose M here: the | ||
123 | module will be called bu21013_ts. | ||
124 | |||
101 | config TOUCHSCREEN_CY8CTMG110 | 125 | config TOUCHSCREEN_CY8CTMG110 |
102 | tristate "cy8ctmg110 touchscreen" | 126 | tristate "cy8ctmg110 touchscreen" |
103 | depends on I2C | 127 | depends on I2C |
@@ -214,6 +238,28 @@ config TOUCHSCREEN_WACOM_W8001 | |||
214 | To compile this driver as a module, choose M here: the | 238 | To compile this driver as a module, choose M here: the |
215 | module will be called wacom_w8001. | 239 | module will be called wacom_w8001. |
216 | 240 | ||
241 | config TOUCHSCREEN_LPC32XX | ||
242 | tristate "LPC32XX touchscreen controller" | ||
243 | depends on ARCH_LPC32XX | ||
244 | help | ||
245 | Say Y here if you have a LPC32XX device and want | ||
246 | to support the built-in touchscreen. | ||
247 | |||
248 | To compile this driver as a module, choose M here: the | ||
249 | module will be called lpc32xx_ts. | ||
250 | |||
251 | config TOUCHSCREEN_MAX11801 | ||
252 | tristate "MAX11801 based touchscreens" | ||
253 | depends on I2C | ||
254 | help | ||
255 | Say Y here if you have a MAX11801 based touchscreen | ||
256 | controller. | ||
257 | |||
258 | If unsure, say N. | ||
259 | |||
260 | To compile this driver as a module, choose M here: the | ||
261 | module will be called max11801_ts. | ||
262 | |||
217 | config TOUCHSCREEN_MCS5000 | 263 | config TOUCHSCREEN_MCS5000 |
218 | tristate "MELFAS MCS-5000 touchscreen" | 264 | tristate "MELFAS MCS-5000 touchscreen" |
219 | depends on I2C | 265 | depends on I2C |
@@ -250,6 +296,18 @@ config TOUCHSCREEN_INEXIO | |||
250 | To compile this driver as a module, choose M here: the | 296 | To compile this driver as a module, choose M here: the |
251 | module will be called inexio. | 297 | module will be called inexio. |
252 | 298 | ||
299 | config TOUCHSCREEN_INTEL_MID | ||
300 | tristate "Intel MID platform resistive touchscreen" | ||
301 | depends on INTEL_SCU_IPC | ||
302 | help | ||
303 | Say Y here if you have a Intel MID based touchscreen in | ||
304 | your system. | ||
305 | |||
306 | If unsure, say N. | ||
307 | |||
308 | To compile this driver as a module, choose M here: the | ||
309 | module will be called intel_mid_touch. | ||
310 | |||
253 | config TOUCHSCREEN_MK712 | 311 | config TOUCHSCREEN_MK712 |
254 | tristate "ICS MicroClock MK712 touchscreen" | 312 | tristate "ICS MicroClock MK712 touchscreen" |
255 | help | 313 | help |
@@ -305,18 +363,6 @@ config TOUCHSCREEN_PENMOUNT | |||
305 | To compile this driver as a module, choose M here: the | 363 | To compile this driver as a module, choose M here: the |
306 | module will be called penmount. | 364 | module will be called penmount. |
307 | 365 | ||
308 | config TOUCHSCREEN_QT602240 | ||
309 | tristate "QT602240 I2C Touchscreen" | ||
310 | depends on I2C | ||
311 | help | ||
312 | Say Y here if you have the AT42QT602240/ATMXT224 I2C touchscreen | ||
313 | connected to your system. | ||
314 | |||
315 | If unsure, say N. | ||
316 | |||
317 | To compile this driver as a module, choose M here: the | ||
318 | module will be called qt602240_ts. | ||
319 | |||
320 | config TOUCHSCREEN_MIGOR | 366 | config TOUCHSCREEN_MIGOR |
321 | tristate "Renesas MIGO-R touchscreen" | 367 | tristate "Renesas MIGO-R touchscreen" |
322 | depends on SH_MIGOR && I2C | 368 | depends on SH_MIGOR && I2C |
@@ -328,6 +374,15 @@ config TOUCHSCREEN_MIGOR | |||
328 | To compile this driver as a module, choose M here: the | 374 | To compile this driver as a module, choose M here: the |
329 | module will be called migor_ts. | 375 | module will be called migor_ts. |
330 | 376 | ||
377 | config TOUCHSCREEN_TNETV107X | ||
378 | tristate "TI TNETV107X touchscreen support" | ||
379 | depends on ARCH_DAVINCI_TNETV107X | ||
380 | help | ||
381 | Say Y here if you want to use the TNETV107X touchscreen. | ||
382 | |||
383 | To compile this driver as a module, choose M here: the | ||
384 | module will be called tnetv107x-ts. | ||
385 | |||
331 | config TOUCHSCREEN_TOUCHRIGHT | 386 | config TOUCHSCREEN_TOUCHRIGHT |
332 | tristate "Touchright serial touchscreen" | 387 | tristate "Touchright serial touchscreen" |
333 | select SERIO | 388 | select SERIO |
@@ -380,6 +435,16 @@ config TOUCHSCREEN_UCB1400 | |||
380 | To compile this driver as a module, choose M here: the | 435 | To compile this driver as a module, choose M here: the |
381 | module will be called ucb1400_ts. | 436 | module will be called ucb1400_ts. |
382 | 437 | ||
438 | config TOUCHSCREEN_WM831X | ||
439 | tristate "Support for WM831x touchscreen controllers" | ||
440 | depends on MFD_WM831X | ||
441 | help | ||
442 | This enables support for the touchscreen controller on the WM831x | ||
443 | series of PMICs. | ||
444 | |||
445 | To compile this driver as a module, choose M here: the | ||
446 | module will be called wm831x-ts. | ||
447 | |||
383 | config TOUCHSCREEN_WM97XX | 448 | config TOUCHSCREEN_WM97XX |
384 | tristate "Support for WM97xx AC97 touchscreen controllers" | 449 | tristate "Support for WM97xx AC97 touchscreen controllers" |
385 | depends on AC97_BUS | 450 | depends on AC97_BUS |
@@ -497,62 +562,62 @@ config TOUCHSCREEN_MC13783 | |||
497 | 562 | ||
498 | config TOUCHSCREEN_USB_EGALAX | 563 | config TOUCHSCREEN_USB_EGALAX |
499 | default y | 564 | default y |
500 | bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED | 565 | bool "eGalax, eTurboTouch CT-410/510/700 device support" if EXPERT |
501 | depends on TOUCHSCREEN_USB_COMPOSITE | 566 | depends on TOUCHSCREEN_USB_COMPOSITE |
502 | 567 | ||
503 | config TOUCHSCREEN_USB_PANJIT | 568 | config TOUCHSCREEN_USB_PANJIT |
504 | default y | 569 | default y |
505 | bool "PanJit device support" if EMBEDDED | 570 | bool "PanJit device support" if EXPERT |
506 | depends on TOUCHSCREEN_USB_COMPOSITE | 571 | depends on TOUCHSCREEN_USB_COMPOSITE |
507 | 572 | ||
508 | config TOUCHSCREEN_USB_3M | 573 | config TOUCHSCREEN_USB_3M |
509 | default y | 574 | default y |
510 | bool "3M/Microtouch EX II series device support" if EMBEDDED | 575 | bool "3M/Microtouch EX II series device support" if EXPERT |
511 | depends on TOUCHSCREEN_USB_COMPOSITE | 576 | depends on TOUCHSCREEN_USB_COMPOSITE |
512 | 577 | ||
513 | config TOUCHSCREEN_USB_ITM | 578 | config TOUCHSCREEN_USB_ITM |
514 | default y | 579 | default y |
515 | bool "ITM device support" if EMBEDDED | 580 | bool "ITM device support" if EXPERT |
516 | depends on TOUCHSCREEN_USB_COMPOSITE | 581 | depends on TOUCHSCREEN_USB_COMPOSITE |
517 | 582 | ||
518 | config TOUCHSCREEN_USB_ETURBO | 583 | config TOUCHSCREEN_USB_ETURBO |
519 | default y | 584 | default y |
520 | bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED | 585 | bool "eTurboTouch (non-eGalax compatible) device support" if EXPERT |
521 | depends on TOUCHSCREEN_USB_COMPOSITE | 586 | depends on TOUCHSCREEN_USB_COMPOSITE |
522 | 587 | ||
523 | config TOUCHSCREEN_USB_GUNZE | 588 | config TOUCHSCREEN_USB_GUNZE |
524 | default y | 589 | default y |
525 | bool "Gunze AHL61 device support" if EMBEDDED | 590 | bool "Gunze AHL61 device support" if EXPERT |
526 | depends on TOUCHSCREEN_USB_COMPOSITE | 591 | depends on TOUCHSCREEN_USB_COMPOSITE |
527 | 592 | ||
528 | config TOUCHSCREEN_USB_DMC_TSC10 | 593 | config TOUCHSCREEN_USB_DMC_TSC10 |
529 | default y | 594 | default y |
530 | bool "DMC TSC-10/25 device support" if EMBEDDED | 595 | bool "DMC TSC-10/25 device support" if EXPERT |
531 | depends on TOUCHSCREEN_USB_COMPOSITE | 596 | depends on TOUCHSCREEN_USB_COMPOSITE |
532 | 597 | ||
533 | config TOUCHSCREEN_USB_IRTOUCH | 598 | config TOUCHSCREEN_USB_IRTOUCH |
534 | default y | 599 | default y |
535 | bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED | 600 | bool "IRTOUCHSYSTEMS/UNITOP device support" if EXPERT |
536 | depends on TOUCHSCREEN_USB_COMPOSITE | 601 | depends on TOUCHSCREEN_USB_COMPOSITE |
537 | 602 | ||
538 | config TOUCHSCREEN_USB_IDEALTEK | 603 | config TOUCHSCREEN_USB_IDEALTEK |
539 | default y | 604 | default y |
540 | bool "IdealTEK URTC1000 device support" if EMBEDDED | 605 | bool "IdealTEK URTC1000 device support" if EXPERT |
541 | depends on TOUCHSCREEN_USB_COMPOSITE | 606 | depends on TOUCHSCREEN_USB_COMPOSITE |
542 | 607 | ||
543 | config TOUCHSCREEN_USB_GENERAL_TOUCH | 608 | config TOUCHSCREEN_USB_GENERAL_TOUCH |
544 | default y | 609 | default y |
545 | bool "GeneralTouch Touchscreen device support" if EMBEDDED | 610 | bool "GeneralTouch Touchscreen device support" if EXPERT |
546 | depends on TOUCHSCREEN_USB_COMPOSITE | 611 | depends on TOUCHSCREEN_USB_COMPOSITE |
547 | 612 | ||
548 | config TOUCHSCREEN_USB_GOTOP | 613 | config TOUCHSCREEN_USB_GOTOP |
549 | default y | 614 | default y |
550 | bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED | 615 | bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EXPERT |
551 | depends on TOUCHSCREEN_USB_COMPOSITE | 616 | depends on TOUCHSCREEN_USB_COMPOSITE |
552 | 617 | ||
553 | config TOUCHSCREEN_USB_JASTEC | 618 | config TOUCHSCREEN_USB_JASTEC |
554 | default y | 619 | default y |
555 | bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EMBEDDED | 620 | bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EXPERT |
556 | depends on TOUCHSCREEN_USB_COMPOSITE | 621 | depends on TOUCHSCREEN_USB_COMPOSITE |
557 | 622 | ||
558 | config TOUCHSCREEN_USB_E2I | 623 | config TOUCHSCREEN_USB_E2I |
@@ -562,17 +627,17 @@ config TOUCHSCREEN_USB_E2I | |||
562 | 627 | ||
563 | config TOUCHSCREEN_USB_ZYTRONIC | 628 | config TOUCHSCREEN_USB_ZYTRONIC |
564 | default y | 629 | default y |
565 | bool "Zytronic controller" if EMBEDDED | 630 | bool "Zytronic controller" if EXPERT |
566 | depends on TOUCHSCREEN_USB_COMPOSITE | 631 | depends on TOUCHSCREEN_USB_COMPOSITE |
567 | 632 | ||
568 | config TOUCHSCREEN_USB_ETT_TC45USB | 633 | config TOUCHSCREEN_USB_ETT_TC45USB |
569 | default y | 634 | default y |
570 | bool "ET&T USB series TC4UM/TC5UH touchscreen controler support" if EMBEDDED | 635 | bool "ET&T USB series TC4UM/TC5UH touchscreen controller support" if EXPERT |
571 | depends on TOUCHSCREEN_USB_COMPOSITE | 636 | depends on TOUCHSCREEN_USB_COMPOSITE |
572 | 637 | ||
573 | config TOUCHSCREEN_USB_NEXIO | 638 | config TOUCHSCREEN_USB_NEXIO |
574 | default y | 639 | default y |
575 | bool "NEXIO/iNexio device support" if EMBEDDED | 640 | bool "NEXIO/iNexio device support" if EXPERT |
576 | depends on TOUCHSCREEN_USB_COMPOSITE | 641 | depends on TOUCHSCREEN_USB_COMPOSITE |
577 | 642 | ||
578 | config TOUCHSCREEN_TOUCHIT213 | 643 | config TOUCHSCREEN_TOUCHIT213 |
@@ -586,6 +651,17 @@ config TOUCHSCREEN_TOUCHIT213 | |||
586 | To compile this driver as a module, choose M here: the | 651 | To compile this driver as a module, choose M here: the |
587 | module will be called touchit213. | 652 | module will be called touchit213. |
588 | 653 | ||
654 | config TOUCHSCREEN_TSC2005 | ||
655 | tristate "TSC2005 based touchscreens" | ||
656 | depends on SPI_MASTER && GENERIC_HARDIRQS | ||
657 | help | ||
658 | Say Y here if you have a TSC2005 based touchscreen. | ||
659 | |||
660 | If unsure, say N. | ||
661 | |||
662 | To compile this driver as a module, choose M here: the | ||
663 | module will be called tsc2005. | ||
664 | |||
589 | config TOUCHSCREEN_TSC2007 | 665 | config TOUCHSCREEN_TSC2007 |
590 | tristate "TSC2007 based touchscreens" | 666 | tristate "TSC2007 based touchscreens" |
591 | depends on I2C | 667 | depends on I2C |
@@ -616,17 +692,17 @@ config TOUCHSCREEN_PCAP | |||
616 | To compile this driver as a module, choose M here: the | 692 | To compile this driver as a module, choose M here: the |
617 | module will be called pcap_ts. | 693 | module will be called pcap_ts. |
618 | 694 | ||
619 | config TOUCHSCREEN_TPS6507X | 695 | config TOUCHSCREEN_ST1232 |
620 | tristate "TPS6507x based touchscreens" | 696 | tristate "Sitronix ST1232 touchscreen controllers" |
621 | depends on I2C | 697 | depends on I2C |
622 | help | 698 | help |
623 | Say Y here if you have a TPS6507x based touchscreen | 699 | Say Y here if you want to support Sitronix ST1232 |
624 | controller. | 700 | touchscreen controller. |
625 | 701 | ||
626 | If unsure, say N. | 702 | If unsure, say N. |
627 | 703 | ||
628 | To compile this driver as a module, choose M here: the | 704 | To compile this driver as a module, choose M here: the |
629 | module will be called tps6507x_ts. | 705 | module will be called st1232_ts. |
630 | 706 | ||
631 | config TOUCHSCREEN_STMPE | 707 | config TOUCHSCREEN_STMPE |
632 | tristate "STMicroelectronics STMPE touchscreens" | 708 | tristate "STMicroelectronics STMPE touchscreens" |
@@ -638,4 +714,16 @@ config TOUCHSCREEN_STMPE | |||
638 | To compile this driver as a module, choose M here: the | 714 | To compile this driver as a module, choose M here: the |
639 | module will be called stmpe-ts. | 715 | module will be called stmpe-ts. |
640 | 716 | ||
717 | config TOUCHSCREEN_TPS6507X | ||
718 | tristate "TPS6507x based touchscreens" | ||
719 | depends on I2C | ||
720 | help | ||
721 | Say Y here if you have a TPS6507x based touchscreen | ||
722 | controller. | ||
723 | |||
724 | If unsure, say N. | ||
725 | |||
726 | To compile this driver as a module, choose M here: the | ||
727 | module will be called tps6507x_ts. | ||
728 | |||
641 | endif | 729 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 28217e1dcafd..282d6f76ae26 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -12,8 +12,10 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o | |||
12 | obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o | 12 | obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o |
13 | obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o | 13 | obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o |
14 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | 14 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o |
15 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o | ||
15 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o | 16 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o |
16 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 17 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
18 | obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o | ||
17 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o | 19 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o |
18 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o | 20 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o |
19 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o | 21 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o |
@@ -23,6 +25,9 @@ obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | |||
23 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 25 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
24 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 26 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
25 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | 27 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o |
28 | obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o | ||
29 | obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o | ||
30 | obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o | ||
26 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o | 31 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o |
27 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o | 32 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o |
28 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o | 33 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o |
@@ -34,15 +39,18 @@ obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o | |||
34 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o | 39 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o |
35 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | 40 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o |
36 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o | 41 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o |
37 | obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o | ||
38 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o | 42 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o |
43 | obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o | ||
39 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o | 44 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o |
45 | obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o | ||
40 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o | 46 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o |
41 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o | 47 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o |
42 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o | 48 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o |
49 | obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o | ||
43 | obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o | 50 | obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o |
44 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o | 51 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o |
45 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o | 52 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o |
53 | obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o | ||
46 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o | 54 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o |
47 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o | 55 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o |
48 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o | 56 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o |
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 5f0221cffef9..714d4e0f9f95 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/input.h> | 42 | #include <linux/input.h> |
43 | #include <linux/interrupt.h> | 43 | #include <linux/interrupt.h> |
44 | #include <linux/pm.h> | ||
44 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
45 | #include <linux/spi/spi.h> | 46 | #include <linux/spi/spi.h> |
46 | #include <linux/spi/ad7877.h> | 47 | #include <linux/spi/ad7877.h> |
@@ -191,13 +192,12 @@ struct ad7877 { | |||
191 | struct spi_message msg; | 192 | struct spi_message msg; |
192 | 193 | ||
193 | struct mutex mutex; | 194 | struct mutex mutex; |
194 | unsigned disabled:1; /* P: mutex */ | 195 | bool disabled; /* P: mutex */ |
195 | unsigned gpio3:1; /* P: mutex */ | 196 | bool gpio3; /* P: mutex */ |
196 | unsigned gpio4:1; /* P: mutex */ | 197 | bool gpio4; /* P: mutex */ |
197 | 198 | ||
198 | spinlock_t lock; | 199 | spinlock_t lock; |
199 | struct timer_list timer; /* P: lock */ | 200 | struct timer_list timer; /* P: lock */ |
200 | unsigned pending:1; /* P: lock */ | ||
201 | 201 | ||
202 | /* | 202 | /* |
203 | * DMA (thus cache coherency maintenance) requires the | 203 | * DMA (thus cache coherency maintenance) requires the |
@@ -206,8 +206,8 @@ struct ad7877 { | |||
206 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; | 206 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; |
207 | }; | 207 | }; |
208 | 208 | ||
209 | static int gpio3; | 209 | static bool gpio3; |
210 | module_param(gpio3, int, 0); | 210 | module_param(gpio3, bool, 0); |
211 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); | 211 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); |
212 | 212 | ||
213 | /* | 213 | /* |
@@ -230,6 +230,7 @@ static int ad7877_read(struct spi_device *spi, u16 reg) | |||
230 | AD7877_READADD(reg)); | 230 | AD7877_READADD(reg)); |
231 | req->xfer[0].tx_buf = &req->command; | 231 | req->xfer[0].tx_buf = &req->command; |
232 | req->xfer[0].len = 2; | 232 | req->xfer[0].len = 2; |
233 | req->xfer[0].cs_change = 1; | ||
233 | 234 | ||
234 | req->xfer[1].rx_buf = &req->sample; | 235 | req->xfer[1].rx_buf = &req->sample; |
235 | req->xfer[1].len = 2; | 236 | req->xfer[1].len = 2; |
@@ -295,20 +296,25 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) | |||
295 | 296 | ||
296 | req->xfer[0].tx_buf = &req->reset; | 297 | req->xfer[0].tx_buf = &req->reset; |
297 | req->xfer[0].len = 2; | 298 | req->xfer[0].len = 2; |
299 | req->xfer[0].cs_change = 1; | ||
298 | 300 | ||
299 | req->xfer[1].tx_buf = &req->ref_on; | 301 | req->xfer[1].tx_buf = &req->ref_on; |
300 | req->xfer[1].len = 2; | 302 | req->xfer[1].len = 2; |
301 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | 303 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; |
304 | req->xfer[1].cs_change = 1; | ||
302 | 305 | ||
303 | req->xfer[2].tx_buf = &req->command; | 306 | req->xfer[2].tx_buf = &req->command; |
304 | req->xfer[2].len = 2; | 307 | req->xfer[2].len = 2; |
305 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; | 308 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; |
309 | req->xfer[2].cs_change = 1; | ||
306 | 310 | ||
307 | req->xfer[3].rx_buf = &req->sample; | 311 | req->xfer[3].rx_buf = &req->sample; |
308 | req->xfer[3].len = 2; | 312 | req->xfer[3].len = 2; |
313 | req->xfer[3].cs_change = 1; | ||
309 | 314 | ||
310 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ | 315 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ |
311 | req->xfer[4].len = 2; | 316 | req->xfer[4].len = 2; |
317 | req->xfer[4].cs_change = 1; | ||
312 | 318 | ||
313 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ | 319 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ |
314 | req->xfer[5].len = 2; | 320 | req->xfer[5].len = 2; |
@@ -327,7 +333,7 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) | |||
327 | return status ? : sample; | 333 | return status ? : sample; |
328 | } | 334 | } |
329 | 335 | ||
330 | static void ad7877_rx(struct ad7877 *ts) | 336 | static int ad7877_process_data(struct ad7877 *ts) |
331 | { | 337 | { |
332 | struct input_dev *input_dev = ts->input; | 338 | struct input_dev *input_dev = ts->input; |
333 | unsigned Rt; | 339 | unsigned Rt; |
@@ -354,11 +360,25 @@ static void ad7877_rx(struct ad7877 *ts) | |||
354 | Rt /= z1; | 360 | Rt /= z1; |
355 | Rt = (Rt + 2047) >> 12; | 361 | Rt = (Rt + 2047) >> 12; |
356 | 362 | ||
363 | /* | ||
364 | * Sample found inconsistent, pressure is beyond | ||
365 | * the maximum. Don't report it to user space. | ||
366 | */ | ||
367 | if (Rt > ts->pressure_max) | ||
368 | return -EINVAL; | ||
369 | |||
370 | if (!timer_pending(&ts->timer)) | ||
371 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
372 | |||
357 | input_report_abs(input_dev, ABS_X, x); | 373 | input_report_abs(input_dev, ABS_X, x); |
358 | input_report_abs(input_dev, ABS_Y, y); | 374 | input_report_abs(input_dev, ABS_Y, y); |
359 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | 375 | input_report_abs(input_dev, ABS_PRESSURE, Rt); |
360 | input_sync(input_dev); | 376 | input_sync(input_dev); |
377 | |||
378 | return 0; | ||
361 | } | 379 | } |
380 | |||
381 | return -EINVAL; | ||
362 | } | 382 | } |
363 | 383 | ||
364 | static inline void ad7877_ts_event_release(struct ad7877 *ts) | 384 | static inline void ad7877_ts_event_release(struct ad7877 *ts) |
@@ -366,72 +386,56 @@ static inline void ad7877_ts_event_release(struct ad7877 *ts) | |||
366 | struct input_dev *input_dev = ts->input; | 386 | struct input_dev *input_dev = ts->input; |
367 | 387 | ||
368 | input_report_abs(input_dev, ABS_PRESSURE, 0); | 388 | input_report_abs(input_dev, ABS_PRESSURE, 0); |
389 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
369 | input_sync(input_dev); | 390 | input_sync(input_dev); |
370 | } | 391 | } |
371 | 392 | ||
372 | static void ad7877_timer(unsigned long handle) | 393 | static void ad7877_timer(unsigned long handle) |
373 | { | 394 | { |
374 | struct ad7877 *ts = (void *)handle; | 395 | struct ad7877 *ts = (void *)handle; |
396 | unsigned long flags; | ||
375 | 397 | ||
398 | spin_lock_irqsave(&ts->lock, flags); | ||
376 | ad7877_ts_event_release(ts); | 399 | ad7877_ts_event_release(ts); |
400 | spin_unlock_irqrestore(&ts->lock, flags); | ||
377 | } | 401 | } |
378 | 402 | ||
379 | static irqreturn_t ad7877_irq(int irq, void *handle) | 403 | static irqreturn_t ad7877_irq(int irq, void *handle) |
380 | { | 404 | { |
381 | struct ad7877 *ts = handle; | 405 | struct ad7877 *ts = handle; |
382 | unsigned long flags; | 406 | unsigned long flags; |
383 | int status; | 407 | int error; |
384 | 408 | ||
385 | /* | 409 | error = spi_sync(ts->spi, &ts->msg); |
386 | * The repeated conversion sequencer controlled by TMR kicked off | 410 | if (error) { |
387 | * too fast. We ignore the last and process the sample sequence | 411 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", error); |
388 | * currently in the queue. It can't be older than 9.4ms, and we | 412 | goto out; |
389 | * need to avoid that ts->msg doesn't get issued twice while in work. | 413 | } |
390 | */ | ||
391 | 414 | ||
392 | spin_lock_irqsave(&ts->lock, flags); | 415 | spin_lock_irqsave(&ts->lock, flags); |
393 | if (!ts->pending) { | 416 | error = ad7877_process_data(ts); |
394 | ts->pending = 1; | 417 | if (!error) |
395 | 418 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | |
396 | status = spi_async(ts->spi, &ts->msg); | ||
397 | if (status) | ||
398 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", status); | ||
399 | } | ||
400 | spin_unlock_irqrestore(&ts->lock, flags); | 419 | spin_unlock_irqrestore(&ts->lock, flags); |
401 | 420 | ||
421 | out: | ||
402 | return IRQ_HANDLED; | 422 | return IRQ_HANDLED; |
403 | } | 423 | } |
404 | 424 | ||
405 | static void ad7877_callback(void *_ts) | ||
406 | { | ||
407 | struct ad7877 *ts = _ts; | ||
408 | |||
409 | spin_lock_irq(&ts->lock); | ||
410 | |||
411 | ad7877_rx(ts); | ||
412 | ts->pending = 0; | ||
413 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | ||
414 | |||
415 | spin_unlock_irq(&ts->lock); | ||
416 | } | ||
417 | |||
418 | static void ad7877_disable(struct ad7877 *ts) | 425 | static void ad7877_disable(struct ad7877 *ts) |
419 | { | 426 | { |
420 | mutex_lock(&ts->mutex); | 427 | mutex_lock(&ts->mutex); |
421 | 428 | ||
422 | if (!ts->disabled) { | 429 | if (!ts->disabled) { |
423 | ts->disabled = 1; | 430 | ts->disabled = true; |
424 | disable_irq(ts->spi->irq); | 431 | disable_irq(ts->spi->irq); |
425 | 432 | ||
426 | /* Wait for spi_async callback */ | ||
427 | while (ts->pending) | ||
428 | msleep(1); | ||
429 | |||
430 | if (del_timer_sync(&ts->timer)) | 433 | if (del_timer_sync(&ts->timer)) |
431 | ad7877_ts_event_release(ts); | 434 | ad7877_ts_event_release(ts); |
432 | } | 435 | } |
433 | 436 | ||
434 | /* we know the chip's in lowpower mode since we always | 437 | /* |
438 | * We know the chip's in lowpower mode since we always | ||
435 | * leave it that way after every request | 439 | * leave it that way after every request |
436 | */ | 440 | */ |
437 | 441 | ||
@@ -443,7 +447,7 @@ static void ad7877_enable(struct ad7877 *ts) | |||
443 | mutex_lock(&ts->mutex); | 447 | mutex_lock(&ts->mutex); |
444 | 448 | ||
445 | if (ts->disabled) { | 449 | if (ts->disabled) { |
446 | ts->disabled = 0; | 450 | ts->disabled = false; |
447 | enable_irq(ts->spi->irq); | 451 | enable_irq(ts->spi->irq); |
448 | } | 452 | } |
449 | 453 | ||
@@ -453,7 +457,7 @@ static void ad7877_enable(struct ad7877 *ts) | |||
453 | #define SHOW(name) static ssize_t \ | 457 | #define SHOW(name) static ssize_t \ |
454 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | 458 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ |
455 | { \ | 459 | { \ |
456 | struct ad7877 *ts = dev_get_drvdata(dev); \ | 460 | struct ad7877 *ts = dev_get_drvdata(dev); \ |
457 | ssize_t v = ad7877_read_adc(ts->spi, \ | 461 | ssize_t v = ad7877_read_adc(ts->spi, \ |
458 | AD7877_READ_CHAN(name)); \ | 462 | AD7877_READ_CHAN(name)); \ |
459 | if (v < 0) \ | 463 | if (v < 0) \ |
@@ -473,7 +477,7 @@ SHOW(temp2) | |||
473 | static ssize_t ad7877_disable_show(struct device *dev, | 477 | static ssize_t ad7877_disable_show(struct device *dev, |
474 | struct device_attribute *attr, char *buf) | 478 | struct device_attribute *attr, char *buf) |
475 | { | 479 | { |
476 | struct ad7877 *ts = dev_get_drvdata(dev); | 480 | struct ad7877 *ts = dev_get_drvdata(dev); |
477 | 481 | ||
478 | return sprintf(buf, "%u\n", ts->disabled); | 482 | return sprintf(buf, "%u\n", ts->disabled); |
479 | } | 483 | } |
@@ -503,7 +507,7 @@ static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store); | |||
503 | static ssize_t ad7877_dac_show(struct device *dev, | 507 | static ssize_t ad7877_dac_show(struct device *dev, |
504 | struct device_attribute *attr, char *buf) | 508 | struct device_attribute *attr, char *buf) |
505 | { | 509 | { |
506 | struct ad7877 *ts = dev_get_drvdata(dev); | 510 | struct ad7877 *ts = dev_get_drvdata(dev); |
507 | 511 | ||
508 | return sprintf(buf, "%u\n", ts->dac); | 512 | return sprintf(buf, "%u\n", ts->dac); |
509 | } | 513 | } |
@@ -533,7 +537,7 @@ static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store); | |||
533 | static ssize_t ad7877_gpio3_show(struct device *dev, | 537 | static ssize_t ad7877_gpio3_show(struct device *dev, |
534 | struct device_attribute *attr, char *buf) | 538 | struct device_attribute *attr, char *buf) |
535 | { | 539 | { |
536 | struct ad7877 *ts = dev_get_drvdata(dev); | 540 | struct ad7877 *ts = dev_get_drvdata(dev); |
537 | 541 | ||
538 | return sprintf(buf, "%u\n", ts->gpio3); | 542 | return sprintf(buf, "%u\n", ts->gpio3); |
539 | } | 543 | } |
@@ -564,7 +568,7 @@ static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store); | |||
564 | static ssize_t ad7877_gpio4_show(struct device *dev, | 568 | static ssize_t ad7877_gpio4_show(struct device *dev, |
565 | struct device_attribute *attr, char *buf) | 569 | struct device_attribute *attr, char *buf) |
566 | { | 570 | { |
567 | struct ad7877 *ts = dev_get_drvdata(dev); | 571 | struct ad7877 *ts = dev_get_drvdata(dev); |
568 | 572 | ||
569 | return sprintf(buf, "%u\n", ts->gpio4); | 573 | return sprintf(buf, "%u\n", ts->gpio4); |
570 | } | 574 | } |
@@ -597,16 +601,35 @@ static struct attribute *ad7877_attributes[] = { | |||
597 | &dev_attr_temp2.attr, | 601 | &dev_attr_temp2.attr, |
598 | &dev_attr_aux1.attr, | 602 | &dev_attr_aux1.attr, |
599 | &dev_attr_aux2.attr, | 603 | &dev_attr_aux2.attr, |
604 | &dev_attr_aux3.attr, | ||
600 | &dev_attr_bat1.attr, | 605 | &dev_attr_bat1.attr, |
601 | &dev_attr_bat2.attr, | 606 | &dev_attr_bat2.attr, |
602 | &dev_attr_disable.attr, | 607 | &dev_attr_disable.attr, |
603 | &dev_attr_dac.attr, | 608 | &dev_attr_dac.attr, |
609 | &dev_attr_gpio3.attr, | ||
604 | &dev_attr_gpio4.attr, | 610 | &dev_attr_gpio4.attr, |
605 | NULL | 611 | NULL |
606 | }; | 612 | }; |
607 | 613 | ||
614 | static mode_t ad7877_attr_is_visible(struct kobject *kobj, | ||
615 | struct attribute *attr, int n) | ||
616 | { | ||
617 | mode_t mode = attr->mode; | ||
618 | |||
619 | if (attr == &dev_attr_aux3.attr) { | ||
620 | if (gpio3) | ||
621 | mode = 0; | ||
622 | } else if (attr == &dev_attr_gpio3.attr) { | ||
623 | if (!gpio3) | ||
624 | mode = 0; | ||
625 | } | ||
626 | |||
627 | return mode; | ||
628 | } | ||
629 | |||
608 | static const struct attribute_group ad7877_attr_group = { | 630 | static const struct attribute_group ad7877_attr_group = { |
609 | .attrs = ad7877_attributes, | 631 | .is_visible = ad7877_attr_is_visible, |
632 | .attrs = ad7877_attributes, | ||
610 | }; | 633 | }; |
611 | 634 | ||
612 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | 635 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) |
@@ -635,22 +658,25 @@ static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | |||
635 | 658 | ||
636 | spi_message_init(m); | 659 | spi_message_init(m); |
637 | 660 | ||
638 | m->complete = ad7877_callback; | ||
639 | m->context = ts; | 661 | m->context = ts; |
640 | 662 | ||
641 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; | 663 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; |
642 | ts->xfer[0].len = 2; | 664 | ts->xfer[0].len = 2; |
665 | ts->xfer[0].cs_change = 1; | ||
643 | 666 | ||
644 | spi_message_add_tail(&ts->xfer[0], m); | 667 | spi_message_add_tail(&ts->xfer[0], m); |
645 | 668 | ||
646 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ | 669 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ |
647 | ts->xfer[1].len = 2; | 670 | ts->xfer[1].len = 2; |
671 | ts->xfer[1].cs_change = 1; | ||
648 | 672 | ||
649 | spi_message_add_tail(&ts->xfer[1], m); | 673 | spi_message_add_tail(&ts->xfer[1], m); |
650 | 674 | ||
651 | for (i = 0; i < 11; i++) { | 675 | for (i = 0; i < AD7877_NR_SENSE; i++) { |
652 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; | 676 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; |
653 | ts->xfer[i + 2].len = 2; | 677 | ts->xfer[i + 2].len = 2; |
678 | if (i < (AD7877_NR_SENSE - 1)) | ||
679 | ts->xfer[i + 2].cs_change = 1; | ||
654 | spi_message_add_tail(&ts->xfer[i + 2], m); | 680 | spi_message_add_tail(&ts->xfer[i + 2], m); |
655 | } | 681 | } |
656 | } | 682 | } |
@@ -718,6 +744,8 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
718 | input_dev->phys = ts->phys; | 744 | input_dev->phys = ts->phys; |
719 | input_dev->dev.parent = &spi->dev; | 745 | input_dev->dev.parent = &spi->dev; |
720 | 746 | ||
747 | __set_bit(EV_KEY, input_dev->evbit); | ||
748 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
721 | __set_bit(EV_ABS, input_dev->evbit); | 749 | __set_bit(EV_ABS, input_dev->evbit); |
722 | __set_bit(ABS_X, input_dev->absbit); | 750 | __set_bit(ABS_X, input_dev->absbit); |
723 | __set_bit(ABS_Y, input_dev->absbit); | 751 | __set_bit(ABS_Y, input_dev->absbit); |
@@ -752,8 +780,9 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
752 | 780 | ||
753 | /* Request AD7877 /DAV GPIO interrupt */ | 781 | /* Request AD7877 /DAV GPIO interrupt */ |
754 | 782 | ||
755 | err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING, | 783 | err = request_threaded_irq(spi->irq, NULL, ad7877_irq, |
756 | spi->dev.driver->name, ts); | 784 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
785 | spi->dev.driver->name, ts); | ||
757 | if (err) { | 786 | if (err) { |
758 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 787 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
759 | goto err_free_mem; | 788 | goto err_free_mem; |
@@ -763,20 +792,12 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
763 | if (err) | 792 | if (err) |
764 | goto err_free_irq; | 793 | goto err_free_irq; |
765 | 794 | ||
766 | err = device_create_file(&spi->dev, | ||
767 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
768 | if (err) | ||
769 | goto err_remove_attr_group; | ||
770 | |||
771 | err = input_register_device(input_dev); | 795 | err = input_register_device(input_dev); |
772 | if (err) | 796 | if (err) |
773 | goto err_remove_attr; | 797 | goto err_remove_attr_group; |
774 | 798 | ||
775 | return 0; | 799 | return 0; |
776 | 800 | ||
777 | err_remove_attr: | ||
778 | device_remove_file(&spi->dev, | ||
779 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
780 | err_remove_attr_group: | 801 | err_remove_attr_group: |
781 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | 802 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); |
782 | err_free_irq: | 803 | err_free_irq: |
@@ -790,11 +811,9 @@ err_free_mem: | |||
790 | 811 | ||
791 | static int __devexit ad7877_remove(struct spi_device *spi) | 812 | static int __devexit ad7877_remove(struct spi_device *spi) |
792 | { | 813 | { |
793 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | 814 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); |
794 | 815 | ||
795 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | 816 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); |
796 | device_remove_file(&spi->dev, | ||
797 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
798 | 817 | ||
799 | ad7877_disable(ts); | 818 | ad7877_disable(ts); |
800 | free_irq(ts->spi->irq, ts); | 819 | free_irq(ts->spi->irq, ts); |
@@ -808,39 +827,37 @@ static int __devexit ad7877_remove(struct spi_device *spi) | |||
808 | return 0; | 827 | return 0; |
809 | } | 828 | } |
810 | 829 | ||
811 | #ifdef CONFIG_PM | 830 | #ifdef CONFIG_PM_SLEEP |
812 | static int ad7877_suspend(struct spi_device *spi, pm_message_t message) | 831 | static int ad7877_suspend(struct device *dev) |
813 | { | 832 | { |
814 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | 833 | struct ad7877 *ts = dev_get_drvdata(dev); |
815 | 834 | ||
816 | ad7877_disable(ts); | 835 | ad7877_disable(ts); |
817 | 836 | ||
818 | return 0; | 837 | return 0; |
819 | } | 838 | } |
820 | 839 | ||
821 | static int ad7877_resume(struct spi_device *spi) | 840 | static int ad7877_resume(struct device *dev) |
822 | { | 841 | { |
823 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | 842 | struct ad7877 *ts = dev_get_drvdata(dev); |
824 | 843 | ||
825 | ad7877_enable(ts); | 844 | ad7877_enable(ts); |
826 | 845 | ||
827 | return 0; | 846 | return 0; |
828 | } | 847 | } |
829 | #else | ||
830 | #define ad7877_suspend NULL | ||
831 | #define ad7877_resume NULL | ||
832 | #endif | 848 | #endif |
833 | 849 | ||
850 | static SIMPLE_DEV_PM_OPS(ad7877_pm, ad7877_suspend, ad7877_resume); | ||
851 | |||
834 | static struct spi_driver ad7877_driver = { | 852 | static struct spi_driver ad7877_driver = { |
835 | .driver = { | 853 | .driver = { |
836 | .name = "ad7877", | 854 | .name = "ad7877", |
837 | .bus = &spi_bus_type, | 855 | .bus = &spi_bus_type, |
838 | .owner = THIS_MODULE, | 856 | .owner = THIS_MODULE, |
857 | .pm = &ad7877_pm, | ||
839 | }, | 858 | }, |
840 | .probe = ad7877_probe, | 859 | .probe = ad7877_probe, |
841 | .remove = __devexit_p(ad7877_remove), | 860 | .remove = __devexit_p(ad7877_remove), |
842 | .suspend = ad7877_suspend, | ||
843 | .resume = ad7877_resume, | ||
844 | }; | 861 | }; |
845 | 862 | ||
846 | static int __init ad7877_init(void) | 863 | static int __init ad7877_init(void) |
diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c index d82a38ee9a3e..4e4e58cec6c8 100644 --- a/drivers/input/touchscreen/ad7879-i2c.c +++ b/drivers/input/touchscreen/ad7879-i2c.c | |||
@@ -10,14 +10,16 @@ | |||
10 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/pm.h> | ||
13 | 14 | ||
14 | #include "ad7879.h" | 15 | #include "ad7879.h" |
15 | 16 | ||
16 | #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ | 17 | #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ |
17 | 18 | ||
18 | #ifdef CONFIG_PM | 19 | #ifdef CONFIG_PM |
19 | static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) | 20 | static int ad7879_i2c_suspend(struct device *dev) |
20 | { | 21 | { |
22 | struct i2c_client *client = to_i2c_client(dev); | ||
21 | struct ad7879 *ts = i2c_get_clientdata(client); | 23 | struct ad7879 *ts = i2c_get_clientdata(client); |
22 | 24 | ||
23 | ad7879_suspend(ts); | 25 | ad7879_suspend(ts); |
@@ -25,17 +27,17 @@ static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) | |||
25 | return 0; | 27 | return 0; |
26 | } | 28 | } |
27 | 29 | ||
28 | static int ad7879_i2c_resume(struct i2c_client *client) | 30 | static int ad7879_i2c_resume(struct device *dev) |
29 | { | 31 | { |
32 | struct i2c_client *client = to_i2c_client(dev); | ||
30 | struct ad7879 *ts = i2c_get_clientdata(client); | 33 | struct ad7879 *ts = i2c_get_clientdata(client); |
31 | 34 | ||
32 | ad7879_resume(ts); | 35 | ad7879_resume(ts); |
33 | 36 | ||
34 | return 0; | 37 | return 0; |
35 | } | 38 | } |
36 | #else | 39 | |
37 | # define ad7879_i2c_suspend NULL | 40 | static SIMPLE_DEV_PM_OPS(ad7879_i2c_pm, ad7879_i2c_suspend, ad7879_i2c_resume); |
38 | # define ad7879_i2c_resume NULL | ||
39 | #endif | 41 | #endif |
40 | 42 | ||
41 | /* All registers are word-sized. | 43 | /* All registers are word-sized. |
@@ -117,11 +119,12 @@ static struct i2c_driver ad7879_i2c_driver = { | |||
117 | .driver = { | 119 | .driver = { |
118 | .name = "ad7879", | 120 | .name = "ad7879", |
119 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
122 | #ifdef CONFIG_PM | ||
123 | .pm = &ad7879_i2c_pm, | ||
124 | #endif | ||
120 | }, | 125 | }, |
121 | .probe = ad7879_i2c_probe, | 126 | .probe = ad7879_i2c_probe, |
122 | .remove = __devexit_p(ad7879_i2c_remove), | 127 | .remove = __devexit_p(ad7879_i2c_remove), |
123 | .suspend = ad7879_i2c_suspend, | ||
124 | .resume = ad7879_i2c_resume, | ||
125 | .id_table = ad7879_id, | 128 | .id_table = ad7879_id, |
126 | }; | 129 | }; |
127 | 130 | ||
diff --git a/drivers/input/touchscreen/ad7879-spi.c b/drivers/input/touchscreen/ad7879-spi.c index 59c6e68c4325..ddf732f3cafc 100644 --- a/drivers/input/touchscreen/ad7879-spi.c +++ b/drivers/input/touchscreen/ad7879-spi.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/input.h> /* BUS_SPI */ | 9 | #include <linux/input.h> /* BUS_SPI */ |
10 | #include <linux/pm.h> | ||
10 | #include <linux/spi/spi.h> | 11 | #include <linux/spi/spi.h> |
11 | 12 | ||
12 | #include "ad7879.h" | 13 | #include "ad7879.h" |
@@ -20,9 +21,10 @@ | |||
20 | #define AD7879_WRITECMD(reg) (AD7879_CMD(reg)) | 21 | #define AD7879_WRITECMD(reg) (AD7879_CMD(reg)) |
21 | #define AD7879_READCMD(reg) (AD7879_CMD(reg) | AD7879_CMD_READ) | 22 | #define AD7879_READCMD(reg) (AD7879_CMD(reg) | AD7879_CMD_READ) |
22 | 23 | ||
23 | #ifdef CONFIG_PM | 24 | #ifdef CONFIG_PM_SLEEP |
24 | static int ad7879_spi_suspend(struct spi_device *spi, pm_message_t message) | 25 | static int ad7879_spi_suspend(struct device *dev) |
25 | { | 26 | { |
27 | struct spi_device *spi = to_spi_device(dev); | ||
26 | struct ad7879 *ts = spi_get_drvdata(spi); | 28 | struct ad7879 *ts = spi_get_drvdata(spi); |
27 | 29 | ||
28 | ad7879_suspend(ts); | 30 | ad7879_suspend(ts); |
@@ -30,19 +32,19 @@ static int ad7879_spi_suspend(struct spi_device *spi, pm_message_t message) | |||
30 | return 0; | 32 | return 0; |
31 | } | 33 | } |
32 | 34 | ||
33 | static int ad7879_spi_resume(struct spi_device *spi) | 35 | static int ad7879_spi_resume(struct device *dev) |
34 | { | 36 | { |
37 | struct spi_device *spi = to_spi_device(dev); | ||
35 | struct ad7879 *ts = spi_get_drvdata(spi); | 38 | struct ad7879 *ts = spi_get_drvdata(spi); |
36 | 39 | ||
37 | ad7879_resume(ts); | 40 | ad7879_resume(ts); |
38 | 41 | ||
39 | return 0; | 42 | return 0; |
40 | } | 43 | } |
41 | #else | ||
42 | # define ad7879_spi_suspend NULL | ||
43 | # define ad7879_spi_resume NULL | ||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | static SIMPLE_DEV_PM_OPS(ad7879_spi_pm, ad7879_spi_suspend, ad7879_spi_resume); | ||
47 | |||
46 | /* | 48 | /* |
47 | * ad7879_read/write are only used for initial setup and for sysfs controls. | 49 | * ad7879_read/write are only used for initial setup and for sysfs controls. |
48 | * The main traffic is done in ad7879_collect(). | 50 | * The main traffic is done in ad7879_collect(). |
@@ -173,11 +175,10 @@ static struct spi_driver ad7879_spi_driver = { | |||
173 | .name = "ad7879", | 175 | .name = "ad7879", |
174 | .bus = &spi_bus_type, | 176 | .bus = &spi_bus_type, |
175 | .owner = THIS_MODULE, | 177 | .owner = THIS_MODULE, |
178 | .pm = &ad7879_spi_pm, | ||
176 | }, | 179 | }, |
177 | .probe = ad7879_spi_probe, | 180 | .probe = ad7879_spi_probe, |
178 | .remove = __devexit_p(ad7879_spi_remove), | 181 | .remove = __devexit_p(ad7879_spi_remove), |
179 | .suspend = ad7879_spi_suspend, | ||
180 | .resume = ad7879_spi_resume, | ||
181 | }; | 182 | }; |
182 | 183 | ||
183 | static int __init ad7879_spi_init(void) | 184 | static int __init ad7879_spi_init(void) |
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index ba6f0bd1e762..bc3b5187f3a3 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -129,6 +129,9 @@ struct ad7879 { | |||
129 | u16 cmd_crtl1; | 129 | u16 cmd_crtl1; |
130 | u16 cmd_crtl2; | 130 | u16 cmd_crtl2; |
131 | u16 cmd_crtl3; | 131 | u16 cmd_crtl3; |
132 | int x; | ||
133 | int y; | ||
134 | int Rt; | ||
132 | }; | 135 | }; |
133 | 136 | ||
134 | static int ad7879_read(struct ad7879 *ts, u8 reg) | 137 | static int ad7879_read(struct ad7879 *ts, u8 reg) |
@@ -175,13 +178,32 @@ static int ad7879_report(struct ad7879 *ts) | |||
175 | Rt /= z1; | 178 | Rt /= z1; |
176 | Rt = (Rt + 2047) >> 12; | 179 | Rt = (Rt + 2047) >> 12; |
177 | 180 | ||
178 | if (!timer_pending(&ts->timer)) | 181 | /* |
182 | * Sample found inconsistent, pressure is beyond | ||
183 | * the maximum. Don't report it to user space. | ||
184 | */ | ||
185 | if (Rt > ts->pressure_max) | ||
186 | return -EINVAL; | ||
187 | |||
188 | /* | ||
189 | * Note that we delay reporting events by one sample. | ||
190 | * This is done to avoid reporting last sample of the | ||
191 | * touch sequence, which may be incomplete if finger | ||
192 | * leaves the surface before last reading is taken. | ||
193 | */ | ||
194 | if (timer_pending(&ts->timer)) { | ||
195 | /* Touch continues */ | ||
179 | input_report_key(input_dev, BTN_TOUCH, 1); | 196 | input_report_key(input_dev, BTN_TOUCH, 1); |
197 | input_report_abs(input_dev, ABS_X, ts->x); | ||
198 | input_report_abs(input_dev, ABS_Y, ts->y); | ||
199 | input_report_abs(input_dev, ABS_PRESSURE, ts->Rt); | ||
200 | input_sync(input_dev); | ||
201 | } | ||
202 | |||
203 | ts->x = x; | ||
204 | ts->y = y; | ||
205 | ts->Rt = Rt; | ||
180 | 206 | ||
181 | input_report_abs(input_dev, ABS_X, x); | ||
182 | input_report_abs(input_dev, ABS_Y, y); | ||
183 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | ||
184 | input_sync(input_dev); | ||
185 | return 0; | 207 | return 0; |
186 | } | 208 | } |
187 | 209 | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 16031933a8f6..5196861b86ef 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -17,13 +17,16 @@ | |||
17 | * it under the terms of the GNU General Public License version 2 as | 17 | * it under the terms of the GNU General Public License version 2 as |
18 | * published by the Free Software Foundation. | 18 | * published by the Free Software Foundation. |
19 | */ | 19 | */ |
20 | #include <linux/types.h> | ||
20 | #include <linux/hwmon.h> | 21 | #include <linux/hwmon.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/sched.h> | ||
23 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
24 | #include <linux/input.h> | 26 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
26 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pm.h> | ||
27 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
28 | #include <linux/spi/spi.h> | 31 | #include <linux/spi/spi.h> |
29 | #include <linux/spi/ads7846.h> | 32 | #include <linux/spi/ads7846.h> |
@@ -52,22 +55,23 @@ | |||
52 | * files. | 55 | * files. |
53 | */ | 56 | */ |
54 | 57 | ||
55 | #define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */ | 58 | #define TS_POLL_DELAY 1 /* ms delay before the first sample */ |
56 | #define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */ | 59 | #define TS_POLL_PERIOD 5 /* ms delay between samples */ |
57 | 60 | ||
58 | /* this driver doesn't aim at the peak continuous sample rate */ | 61 | /* this driver doesn't aim at the peak continuous sample rate */ |
59 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) | 62 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) |
60 | 63 | ||
61 | struct ts_event { | 64 | struct ts_event { |
62 | /* For portability, we can't read 12 bit values using SPI (which | 65 | /* |
63 | * would make the controller deliver them as native byteorder u16 | 66 | * For portability, we can't read 12 bit values using SPI (which |
67 | * would make the controller deliver them as native byte order u16 | ||
64 | * with msbs zeroed). Instead, we read them as two 8-bit values, | 68 | * with msbs zeroed). Instead, we read them as two 8-bit values, |
65 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. | 69 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. |
66 | */ | 70 | */ |
67 | u16 x; | 71 | u16 x; |
68 | u16 y; | 72 | u16 y; |
69 | u16 z1, z2; | 73 | u16 z1, z2; |
70 | int ignore; | 74 | bool ignore; |
71 | u8 x_buf[3]; | 75 | u8 x_buf[3]; |
72 | u8 y_buf[3]; | 76 | u8 y_buf[3]; |
73 | }; | 77 | }; |
@@ -105,13 +109,17 @@ struct ads7846 { | |||
105 | u16 pressure_max; | 109 | u16 pressure_max; |
106 | 110 | ||
107 | bool swap_xy; | 111 | bool swap_xy; |
112 | bool use_internal; | ||
108 | 113 | ||
109 | struct ads7846_packet *packet; | 114 | struct ads7846_packet *packet; |
110 | 115 | ||
111 | struct spi_transfer xfer[18]; | 116 | struct spi_transfer xfer[18]; |
112 | struct spi_message msg[5]; | 117 | struct spi_message msg[5]; |
113 | struct spi_message *last_msg; | 118 | int msg_count; |
114 | int msg_idx; | 119 | wait_queue_head_t wait; |
120 | |||
121 | bool pendown; | ||
122 | |||
115 | int read_cnt; | 123 | int read_cnt; |
116 | int read_rep; | 124 | int read_rep; |
117 | int last_read; | 125 | int last_read; |
@@ -122,14 +130,10 @@ struct ads7846 { | |||
122 | 130 | ||
123 | u16 penirq_recheck_delay_usecs; | 131 | u16 penirq_recheck_delay_usecs; |
124 | 132 | ||
125 | spinlock_t lock; | 133 | struct mutex lock; |
126 | struct hrtimer timer; | 134 | bool stopped; /* P: lock */ |
127 | unsigned pendown:1; /* P: lock */ | 135 | bool disabled; /* P: lock */ |
128 | unsigned pending:1; /* P: lock */ | 136 | bool suspended; /* P: lock */ |
129 | // FIXME remove "irq_disabled" | ||
130 | unsigned irq_disabled:1; /* P: lock */ | ||
131 | unsigned disabled:1; | ||
132 | unsigned is_suspended:1; | ||
133 | 137 | ||
134 | int (*filter)(void *data, int data_idx, int *val); | 138 | int (*filter)(void *data, int data_idx, int *val); |
135 | void *filter_data; | 139 | void *filter_data; |
@@ -165,7 +169,7 @@ struct ads7846 { | |||
165 | #define ADS_12_BIT (0 << 3) | 169 | #define ADS_12_BIT (0 << 3) |
166 | #define ADS_SER (1 << 2) /* non-differential */ | 170 | #define ADS_SER (1 << 2) /* non-differential */ |
167 | #define ADS_DFR (0 << 2) /* differential */ | 171 | #define ADS_DFR (0 << 2) /* differential */ |
168 | #define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */ | 172 | #define ADS_PD10_PDOWN (0 << 0) /* low power mode + penirq */ |
169 | #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ | 173 | #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ |
170 | #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ | 174 | #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ |
171 | #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ | 175 | #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ |
@@ -193,6 +197,78 @@ struct ads7846 { | |||
193 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) | 197 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) |
194 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) | 198 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) |
195 | 199 | ||
200 | /* Must be called with ts->lock held */ | ||
201 | static void ads7846_stop(struct ads7846 *ts) | ||
202 | { | ||
203 | if (!ts->disabled && !ts->suspended) { | ||
204 | /* Signal IRQ thread to stop polling and disable the handler. */ | ||
205 | ts->stopped = true; | ||
206 | mb(); | ||
207 | wake_up(&ts->wait); | ||
208 | disable_irq(ts->spi->irq); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /* Must be called with ts->lock held */ | ||
213 | static void ads7846_restart(struct ads7846 *ts) | ||
214 | { | ||
215 | if (!ts->disabled && !ts->suspended) { | ||
216 | /* Tell IRQ thread that it may poll the device. */ | ||
217 | ts->stopped = false; | ||
218 | mb(); | ||
219 | enable_irq(ts->spi->irq); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* Must be called with ts->lock held */ | ||
224 | static void __ads7846_disable(struct ads7846 *ts) | ||
225 | { | ||
226 | ads7846_stop(ts); | ||
227 | regulator_disable(ts->reg); | ||
228 | |||
229 | /* | ||
230 | * We know the chip's in low power mode since we always | ||
231 | * leave it that way after every request | ||
232 | */ | ||
233 | } | ||
234 | |||
235 | /* Must be called with ts->lock held */ | ||
236 | static void __ads7846_enable(struct ads7846 *ts) | ||
237 | { | ||
238 | regulator_enable(ts->reg); | ||
239 | ads7846_restart(ts); | ||
240 | } | ||
241 | |||
242 | static void ads7846_disable(struct ads7846 *ts) | ||
243 | { | ||
244 | mutex_lock(&ts->lock); | ||
245 | |||
246 | if (!ts->disabled) { | ||
247 | |||
248 | if (!ts->suspended) | ||
249 | __ads7846_disable(ts); | ||
250 | |||
251 | ts->disabled = true; | ||
252 | } | ||
253 | |||
254 | mutex_unlock(&ts->lock); | ||
255 | } | ||
256 | |||
257 | static void ads7846_enable(struct ads7846 *ts) | ||
258 | { | ||
259 | mutex_lock(&ts->lock); | ||
260 | |||
261 | if (ts->disabled) { | ||
262 | |||
263 | ts->disabled = false; | ||
264 | |||
265 | if (!ts->suspended) | ||
266 | __ads7846_enable(ts); | ||
267 | } | ||
268 | |||
269 | mutex_unlock(&ts->lock); | ||
270 | } | ||
271 | |||
196 | /*--------------------------------------------------------------------------*/ | 272 | /*--------------------------------------------------------------------------*/ |
197 | 273 | ||
198 | /* | 274 | /* |
@@ -206,46 +282,41 @@ struct ser_req { | |||
206 | u8 command; | 282 | u8 command; |
207 | u8 ref_off; | 283 | u8 ref_off; |
208 | u16 scratch; | 284 | u16 scratch; |
209 | __be16 sample; | ||
210 | struct spi_message msg; | 285 | struct spi_message msg; |
211 | struct spi_transfer xfer[6]; | 286 | struct spi_transfer xfer[6]; |
287 | /* | ||
288 | * DMA (thus cache coherency maintenance) requires the | ||
289 | * transfer buffers to live in their own cache lines. | ||
290 | */ | ||
291 | __be16 sample ____cacheline_aligned; | ||
212 | }; | 292 | }; |
213 | 293 | ||
214 | struct ads7845_ser_req { | 294 | struct ads7845_ser_req { |
215 | u8 command[3]; | 295 | u8 command[3]; |
216 | u8 pwrdown[3]; | ||
217 | u8 sample[3]; | ||
218 | struct spi_message msg; | 296 | struct spi_message msg; |
219 | struct spi_transfer xfer[2]; | 297 | struct spi_transfer xfer[2]; |
298 | /* | ||
299 | * DMA (thus cache coherency maintenance) requires the | ||
300 | * transfer buffers to live in their own cache lines. | ||
301 | */ | ||
302 | u8 sample[3] ____cacheline_aligned; | ||
220 | }; | 303 | }; |
221 | 304 | ||
222 | static void ads7846_enable(struct ads7846 *ts); | ||
223 | static void ads7846_disable(struct ads7846 *ts); | ||
224 | |||
225 | static int device_suspended(struct device *dev) | ||
226 | { | ||
227 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
228 | return ts->is_suspended || ts->disabled; | ||
229 | } | ||
230 | |||
231 | static int ads7846_read12_ser(struct device *dev, unsigned command) | 305 | static int ads7846_read12_ser(struct device *dev, unsigned command) |
232 | { | 306 | { |
233 | struct spi_device *spi = to_spi_device(dev); | 307 | struct spi_device *spi = to_spi_device(dev); |
234 | struct ads7846 *ts = dev_get_drvdata(dev); | 308 | struct ads7846 *ts = dev_get_drvdata(dev); |
235 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 309 | struct ser_req *req; |
236 | int status; | 310 | int status; |
237 | int use_internal; | ||
238 | 311 | ||
312 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
239 | if (!req) | 313 | if (!req) |
240 | return -ENOMEM; | 314 | return -ENOMEM; |
241 | 315 | ||
242 | spi_message_init(&req->msg); | 316 | spi_message_init(&req->msg); |
243 | 317 | ||
244 | /* FIXME boards with ads7846 might use external vref instead ... */ | ||
245 | use_internal = (ts->model == 7846); | ||
246 | |||
247 | /* maybe turn on internal vREF, and let it settle */ | 318 | /* maybe turn on internal vREF, and let it settle */ |
248 | if (use_internal) { | 319 | if (ts->use_internal) { |
249 | req->ref_on = REF_ON; | 320 | req->ref_on = REF_ON; |
250 | req->xfer[0].tx_buf = &req->ref_on; | 321 | req->xfer[0].tx_buf = &req->ref_on; |
251 | req->xfer[0].len = 1; | 322 | req->xfer[0].len = 1; |
@@ -257,8 +328,14 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
257 | /* for 1uF, settle for 800 usec; no cap, 100 usec. */ | 328 | /* for 1uF, settle for 800 usec; no cap, 100 usec. */ |
258 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | 329 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; |
259 | spi_message_add_tail(&req->xfer[1], &req->msg); | 330 | spi_message_add_tail(&req->xfer[1], &req->msg); |
331 | |||
332 | /* Enable reference voltage */ | ||
333 | command |= ADS_PD10_REF_ON; | ||
260 | } | 334 | } |
261 | 335 | ||
336 | /* Enable ADC in every case */ | ||
337 | command |= ADS_PD10_ADC_ON; | ||
338 | |||
262 | /* take sample */ | 339 | /* take sample */ |
263 | req->command = (u8) command; | 340 | req->command = (u8) command; |
264 | req->xfer[2].tx_buf = &req->command; | 341 | req->xfer[2].tx_buf = &req->command; |
@@ -282,11 +359,11 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
282 | CS_CHANGE(req->xfer[5]); | 359 | CS_CHANGE(req->xfer[5]); |
283 | spi_message_add_tail(&req->xfer[5], &req->msg); | 360 | spi_message_add_tail(&req->xfer[5], &req->msg); |
284 | 361 | ||
285 | ts->irq_disabled = 1; | 362 | mutex_lock(&ts->lock); |
286 | disable_irq(spi->irq); | 363 | ads7846_stop(ts); |
287 | status = spi_sync(spi, &req->msg); | 364 | status = spi_sync(spi, &req->msg); |
288 | ts->irq_disabled = 0; | 365 | ads7846_restart(ts); |
289 | enable_irq(spi->irq); | 366 | mutex_unlock(&ts->lock); |
290 | 367 | ||
291 | if (status == 0) { | 368 | if (status == 0) { |
292 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ | 369 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ |
@@ -301,11 +378,12 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
301 | 378 | ||
302 | static int ads7845_read12_ser(struct device *dev, unsigned command) | 379 | static int ads7845_read12_ser(struct device *dev, unsigned command) |
303 | { | 380 | { |
304 | struct spi_device *spi = to_spi_device(dev); | 381 | struct spi_device *spi = to_spi_device(dev); |
305 | struct ads7846 *ts = dev_get_drvdata(dev); | 382 | struct ads7846 *ts = dev_get_drvdata(dev); |
306 | struct ads7845_ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 383 | struct ads7845_ser_req *req; |
307 | int status; | 384 | int status; |
308 | 385 | ||
386 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
309 | if (!req) | 387 | if (!req) |
310 | return -ENOMEM; | 388 | return -ENOMEM; |
311 | 389 | ||
@@ -317,11 +395,11 @@ static int ads7845_read12_ser(struct device *dev, unsigned command) | |||
317 | req->xfer[0].len = 3; | 395 | req->xfer[0].len = 3; |
318 | spi_message_add_tail(&req->xfer[0], &req->msg); | 396 | spi_message_add_tail(&req->xfer[0], &req->msg); |
319 | 397 | ||
320 | ts->irq_disabled = 1; | 398 | mutex_lock(&ts->lock); |
321 | disable_irq(spi->irq); | 399 | ads7846_stop(ts); |
322 | status = spi_sync(spi, &req->msg); | 400 | status = spi_sync(spi, &req->msg); |
323 | ts->irq_disabled = 0; | 401 | ads7846_restart(ts); |
324 | enable_irq(spi->irq); | 402 | mutex_unlock(&ts->lock); |
325 | 403 | ||
326 | if (status == 0) { | 404 | if (status == 0) { |
327 | /* BE12 value, then padding */ | 405 | /* BE12 value, then padding */ |
@@ -341,7 +419,7 @@ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | |||
341 | { \ | 419 | { \ |
342 | struct ads7846 *ts = dev_get_drvdata(dev); \ | 420 | struct ads7846 *ts = dev_get_drvdata(dev); \ |
343 | ssize_t v = ads7846_read12_ser(dev, \ | 421 | ssize_t v = ads7846_read12_ser(dev, \ |
344 | READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \ | 422 | READ_12BIT_SER(var)); \ |
345 | if (v < 0) \ | 423 | if (v < 0) \ |
346 | return v; \ | 424 | return v; \ |
347 | return sprintf(buf, "%u\n", adjust(ts, v)); \ | 425 | return sprintf(buf, "%u\n", adjust(ts, v)); \ |
@@ -374,6 +452,7 @@ static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) | |||
374 | /* external resistors may scale vAUX into 0..vREF */ | 452 | /* external resistors may scale vAUX into 0..vREF */ |
375 | retval *= ts->vref_mv; | 453 | retval *= ts->vref_mv; |
376 | retval = retval >> 12; | 454 | retval = retval >> 12; |
455 | |||
377 | return retval; | 456 | return retval; |
378 | } | 457 | } |
379 | 458 | ||
@@ -384,13 +463,13 @@ static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v) | |||
384 | /* ads7846 has a resistor ladder to scale this signal down */ | 463 | /* ads7846 has a resistor ladder to scale this signal down */ |
385 | if (ts->model == 7846) | 464 | if (ts->model == 7846) |
386 | retval *= 4; | 465 | retval *= 4; |
466 | |||
387 | return retval; | 467 | return retval; |
388 | } | 468 | } |
389 | 469 | ||
390 | SHOW(in0_input, vaux, vaux_adjust) | 470 | SHOW(in0_input, vaux, vaux_adjust) |
391 | SHOW(in1_input, vbatt, vbatt_adjust) | 471 | SHOW(in1_input, vbatt, vbatt_adjust) |
392 | 472 | ||
393 | |||
394 | static struct attribute *ads7846_attributes[] = { | 473 | static struct attribute *ads7846_attributes[] = { |
395 | &dev_attr_temp0.attr, | 474 | &dev_attr_temp0.attr, |
396 | &dev_attr_temp1.attr, | 475 | &dev_attr_temp1.attr, |
@@ -433,6 +512,7 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) | |||
433 | if (!ts->vref_mv) { | 512 | if (!ts->vref_mv) { |
434 | dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); | 513 | dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); |
435 | ts->vref_mv = 2500; | 514 | ts->vref_mv = 2500; |
515 | ts->use_internal = true; | ||
436 | } | 516 | } |
437 | break; | 517 | break; |
438 | case 7845: | 518 | case 7845: |
@@ -498,17 +578,12 @@ static inline void ads784x_hwmon_unregister(struct spi_device *spi, | |||
498 | } | 578 | } |
499 | #endif | 579 | #endif |
500 | 580 | ||
501 | static int is_pen_down(struct device *dev) | ||
502 | { | ||
503 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
504 | |||
505 | return ts->pendown; | ||
506 | } | ||
507 | |||
508 | static ssize_t ads7846_pen_down_show(struct device *dev, | 581 | static ssize_t ads7846_pen_down_show(struct device *dev, |
509 | struct device_attribute *attr, char *buf) | 582 | struct device_attribute *attr, char *buf) |
510 | { | 583 | { |
511 | return sprintf(buf, "%u\n", is_pen_down(dev)); | 584 | struct ads7846 *ts = dev_get_drvdata(dev); |
585 | |||
586 | return sprintf(buf, "%u\n", ts->pendown); | ||
512 | } | 587 | } |
513 | 588 | ||
514 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | 589 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); |
@@ -516,7 +591,7 @@ static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | |||
516 | static ssize_t ads7846_disable_show(struct device *dev, | 591 | static ssize_t ads7846_disable_show(struct device *dev, |
517 | struct device_attribute *attr, char *buf) | 592 | struct device_attribute *attr, char *buf) |
518 | { | 593 | { |
519 | struct ads7846 *ts = dev_get_drvdata(dev); | 594 | struct ads7846 *ts = dev_get_drvdata(dev); |
520 | 595 | ||
521 | return sprintf(buf, "%u\n", ts->disabled); | 596 | return sprintf(buf, "%u\n", ts->disabled); |
522 | } | 597 | } |
@@ -531,15 +606,11 @@ static ssize_t ads7846_disable_store(struct device *dev, | |||
531 | if (strict_strtoul(buf, 10, &i)) | 606 | if (strict_strtoul(buf, 10, &i)) |
532 | return -EINVAL; | 607 | return -EINVAL; |
533 | 608 | ||
534 | spin_lock_irq(&ts->lock); | ||
535 | |||
536 | if (i) | 609 | if (i) |
537 | ads7846_disable(ts); | 610 | ads7846_disable(ts); |
538 | else | 611 | else |
539 | ads7846_enable(ts); | 612 | ads7846_enable(ts); |
540 | 613 | ||
541 | spin_unlock_irq(&ts->lock); | ||
542 | |||
543 | return count; | 614 | return count; |
544 | } | 615 | } |
545 | 616 | ||
@@ -569,23 +640,141 @@ static void null_wait_for_sync(void) | |||
569 | { | 640 | { |
570 | } | 641 | } |
571 | 642 | ||
572 | /* | 643 | static int ads7846_debounce_filter(void *ads, int data_idx, int *val) |
573 | * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, | 644 | { |
574 | * to retrieve touchscreen status. | 645 | struct ads7846 *ts = ads; |
575 | * | 646 | |
576 | * The SPI transfer completion callback does the real work. It reports | 647 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { |
577 | * touchscreen events and reactivates the timer (or IRQ) as appropriate. | 648 | /* Start over collecting consistent readings. */ |
578 | */ | 649 | ts->read_rep = 0; |
650 | /* | ||
651 | * Repeat it, if this was the first read or the read | ||
652 | * wasn't consistent enough. | ||
653 | */ | ||
654 | if (ts->read_cnt < ts->debounce_max) { | ||
655 | ts->last_read = *val; | ||
656 | ts->read_cnt++; | ||
657 | return ADS7846_FILTER_REPEAT; | ||
658 | } else { | ||
659 | /* | ||
660 | * Maximum number of debouncing reached and still | ||
661 | * not enough number of consistent readings. Abort | ||
662 | * the whole sample, repeat it in the next sampling | ||
663 | * period. | ||
664 | */ | ||
665 | ts->read_cnt = 0; | ||
666 | return ADS7846_FILTER_IGNORE; | ||
667 | } | ||
668 | } else { | ||
669 | if (++ts->read_rep > ts->debounce_rep) { | ||
670 | /* | ||
671 | * Got a good reading for this coordinate, | ||
672 | * go for the next one. | ||
673 | */ | ||
674 | ts->read_cnt = 0; | ||
675 | ts->read_rep = 0; | ||
676 | return ADS7846_FILTER_OK; | ||
677 | } else { | ||
678 | /* Read more values that are consistent. */ | ||
679 | ts->read_cnt++; | ||
680 | return ADS7846_FILTER_REPEAT; | ||
681 | } | ||
682 | } | ||
683 | } | ||
684 | |||
685 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | ||
686 | { | ||
687 | return ADS7846_FILTER_OK; | ||
688 | } | ||
689 | |||
690 | static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m) | ||
691 | { | ||
692 | struct spi_transfer *t = | ||
693 | list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
694 | |||
695 | if (ts->model == 7845) { | ||
696 | return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; | ||
697 | } else { | ||
698 | /* | ||
699 | * adjust: on-wire is a must-ignore bit, a BE12 value, then | ||
700 | * padding; built from two 8 bit values written msb-first. | ||
701 | */ | ||
702 | return be16_to_cpup((__be16 *)t->rx_buf) >> 3; | ||
703 | } | ||
704 | } | ||
705 | |||
706 | static void ads7846_update_value(struct spi_message *m, int val) | ||
707 | { | ||
708 | struct spi_transfer *t = | ||
709 | list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
579 | 710 | ||
580 | static void ads7846_rx(void *ads) | 711 | *(u16 *)t->rx_buf = val; |
712 | } | ||
713 | |||
714 | static void ads7846_read_state(struct ads7846 *ts) | ||
581 | { | 715 | { |
582 | struct ads7846 *ts = ads; | 716 | struct ads7846_packet *packet = ts->packet; |
583 | struct ads7846_packet *packet = ts->packet; | 717 | struct spi_message *m; |
584 | unsigned Rt; | 718 | int msg_idx = 0; |
585 | u16 x, y, z1, z2; | 719 | int val; |
720 | int action; | ||
721 | int error; | ||
586 | 722 | ||
587 | /* ads7846_rx_val() did in-place conversion (including byteswap) from | 723 | while (msg_idx < ts->msg_count) { |
588 | * on-the-wire format as part of debouncing to get stable readings. | 724 | |
725 | ts->wait_for_sync(); | ||
726 | |||
727 | m = &ts->msg[msg_idx]; | ||
728 | error = spi_sync(ts->spi, m); | ||
729 | if (error) { | ||
730 | dev_err(&ts->spi->dev, "spi_async --> %d\n", error); | ||
731 | packet->tc.ignore = true; | ||
732 | return; | ||
733 | } | ||
734 | |||
735 | /* | ||
736 | * Last message is power down request, no need to convert | ||
737 | * or filter the value. | ||
738 | */ | ||
739 | if (msg_idx < ts->msg_count - 1) { | ||
740 | |||
741 | val = ads7846_get_value(ts, m); | ||
742 | |||
743 | action = ts->filter(ts->filter_data, msg_idx, &val); | ||
744 | switch (action) { | ||
745 | case ADS7846_FILTER_REPEAT: | ||
746 | continue; | ||
747 | |||
748 | case ADS7846_FILTER_IGNORE: | ||
749 | packet->tc.ignore = true; | ||
750 | msg_idx = ts->msg_count - 1; | ||
751 | continue; | ||
752 | |||
753 | case ADS7846_FILTER_OK: | ||
754 | ads7846_update_value(m, val); | ||
755 | packet->tc.ignore = false; | ||
756 | msg_idx++; | ||
757 | break; | ||
758 | |||
759 | default: | ||
760 | BUG(); | ||
761 | } | ||
762 | } else { | ||
763 | msg_idx++; | ||
764 | } | ||
765 | } | ||
766 | } | ||
767 | |||
768 | static void ads7846_report_state(struct ads7846 *ts) | ||
769 | { | ||
770 | struct ads7846_packet *packet = ts->packet; | ||
771 | unsigned int Rt; | ||
772 | u16 x, y, z1, z2; | ||
773 | |||
774 | /* | ||
775 | * ads7846_get_value() does in-place conversion (including byte swap) | ||
776 | * from on-the-wire format as part of debouncing to get stable | ||
777 | * readings. | ||
589 | */ | 778 | */ |
590 | if (ts->model == 7845) { | 779 | if (ts->model == 7845) { |
591 | x = *(u16 *)packet->tc.x_buf; | 780 | x = *(u16 *)packet->tc.x_buf; |
@@ -623,19 +812,19 @@ static void ads7846_rx(void *ads) | |||
623 | Rt = 0; | 812 | Rt = 0; |
624 | } | 813 | } |
625 | 814 | ||
626 | /* Sample found inconsistent by debouncing or pressure is beyond | 815 | /* |
816 | * Sample found inconsistent by debouncing or pressure is beyond | ||
627 | * the maximum. Don't report it to user space, repeat at least | 817 | * the maximum. Don't report it to user space, repeat at least |
628 | * once more the measurement | 818 | * once more the measurement |
629 | */ | 819 | */ |
630 | if (packet->tc.ignore || Rt > ts->pressure_max) { | 820 | if (packet->tc.ignore || Rt > ts->pressure_max) { |
631 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", | 821 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", |
632 | packet->tc.ignore, Rt); | 822 | packet->tc.ignore, Rt); |
633 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
634 | HRTIMER_MODE_REL); | ||
635 | return; | 823 | return; |
636 | } | 824 | } |
637 | 825 | ||
638 | /* Maybe check the pendown state before reporting. This discards | 826 | /* |
827 | * Maybe check the pendown state before reporting. This discards | ||
639 | * false readings when the pen is lifted. | 828 | * false readings when the pen is lifted. |
640 | */ | 829 | */ |
641 | if (ts->penirq_recheck_delay_usecs) { | 830 | if (ts->penirq_recheck_delay_usecs) { |
@@ -644,8 +833,9 @@ static void ads7846_rx(void *ads) | |||
644 | Rt = 0; | 833 | Rt = 0; |
645 | } | 834 | } |
646 | 835 | ||
647 | /* NOTE: We can't rely on the pressure to determine the pen down | 836 | /* |
648 | * state, even this controller has a pressure sensor. The pressure | 837 | * NOTE: We can't rely on the pressure to determine the pen down |
838 | * state, even this controller has a pressure sensor. The pressure | ||
649 | * value can fluctuate for quite a while after lifting the pen and | 839 | * value can fluctuate for quite a while after lifting the pen and |
650 | * in some cases may not even settle at the expected value. | 840 | * in some cases may not even settle at the expected value. |
651 | * | 841 | * |
@@ -655,15 +845,15 @@ static void ads7846_rx(void *ads) | |||
655 | if (Rt) { | 845 | if (Rt) { |
656 | struct input_dev *input = ts->input; | 846 | struct input_dev *input = ts->input; |
657 | 847 | ||
848 | if (ts->swap_xy) | ||
849 | swap(x, y); | ||
850 | |||
658 | if (!ts->pendown) { | 851 | if (!ts->pendown) { |
659 | input_report_key(input, BTN_TOUCH, 1); | 852 | input_report_key(input, BTN_TOUCH, 1); |
660 | ts->pendown = 1; | 853 | ts->pendown = true; |
661 | dev_vdbg(&ts->spi->dev, "DOWN\n"); | 854 | dev_vdbg(&ts->spi->dev, "DOWN\n"); |
662 | } | 855 | } |
663 | 856 | ||
664 | if (ts->swap_xy) | ||
665 | swap(x, y); | ||
666 | |||
667 | input_report_abs(input, ABS_X, x); | 857 | input_report_abs(input, ABS_X, x); |
668 | input_report_abs(input, ABS_Y, y); | 858 | input_report_abs(input, ABS_Y, y); |
669 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); | 859 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); |
@@ -671,407 +861,161 @@ static void ads7846_rx(void *ads) | |||
671 | input_sync(input); | 861 | input_sync(input); |
672 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); | 862 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); |
673 | } | 863 | } |
674 | |||
675 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
676 | HRTIMER_MODE_REL); | ||
677 | } | 864 | } |
678 | 865 | ||
679 | static int ads7846_debounce(void *ads, int data_idx, int *val) | 866 | static irqreturn_t ads7846_hard_irq(int irq, void *handle) |
680 | { | 867 | { |
681 | struct ads7846 *ts = ads; | 868 | struct ads7846 *ts = handle; |
682 | 869 | ||
683 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { | 870 | return get_pendown_state(ts) ? IRQ_WAKE_THREAD : IRQ_HANDLED; |
684 | /* Start over collecting consistent readings. */ | ||
685 | ts->read_rep = 0; | ||
686 | /* Repeat it, if this was the first read or the read | ||
687 | * wasn't consistent enough. */ | ||
688 | if (ts->read_cnt < ts->debounce_max) { | ||
689 | ts->last_read = *val; | ||
690 | ts->read_cnt++; | ||
691 | return ADS7846_FILTER_REPEAT; | ||
692 | } else { | ||
693 | /* Maximum number of debouncing reached and still | ||
694 | * not enough number of consistent readings. Abort | ||
695 | * the whole sample, repeat it in the next sampling | ||
696 | * period. | ||
697 | */ | ||
698 | ts->read_cnt = 0; | ||
699 | return ADS7846_FILTER_IGNORE; | ||
700 | } | ||
701 | } else { | ||
702 | if (++ts->read_rep > ts->debounce_rep) { | ||
703 | /* Got a good reading for this coordinate, | ||
704 | * go for the next one. */ | ||
705 | ts->read_cnt = 0; | ||
706 | ts->read_rep = 0; | ||
707 | return ADS7846_FILTER_OK; | ||
708 | } else { | ||
709 | /* Read more values that are consistent. */ | ||
710 | ts->read_cnt++; | ||
711 | return ADS7846_FILTER_REPEAT; | ||
712 | } | ||
713 | } | ||
714 | } | 871 | } |
715 | 872 | ||
716 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | ||
717 | { | ||
718 | return ADS7846_FILTER_OK; | ||
719 | } | ||
720 | 873 | ||
721 | static void ads7846_rx_val(void *ads) | 874 | static irqreturn_t ads7846_irq(int irq, void *handle) |
722 | { | 875 | { |
723 | struct ads7846 *ts = ads; | 876 | struct ads7846 *ts = handle; |
724 | struct ads7846_packet *packet = ts->packet; | ||
725 | struct spi_message *m; | ||
726 | struct spi_transfer *t; | ||
727 | int val; | ||
728 | int action; | ||
729 | int status; | ||
730 | |||
731 | m = &ts->msg[ts->msg_idx]; | ||
732 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
733 | 877 | ||
734 | if (ts->model == 7845) { | 878 | /* Start with a small delay before checking pendown state */ |
735 | val = be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; | 879 | msleep(TS_POLL_DELAY); |
736 | } else { | ||
737 | /* adjust: on-wire is a must-ignore bit, a BE12 value, then | ||
738 | * padding; built from two 8 bit values written msb-first. | ||
739 | */ | ||
740 | val = be16_to_cpup((__be16 *)t->rx_buf) >> 3; | ||
741 | } | ||
742 | 880 | ||
743 | action = ts->filter(ts->filter_data, ts->msg_idx, &val); | 881 | while (!ts->stopped && get_pendown_state(ts)) { |
744 | switch (action) { | ||
745 | case ADS7846_FILTER_REPEAT: | ||
746 | break; | ||
747 | case ADS7846_FILTER_IGNORE: | ||
748 | packet->tc.ignore = 1; | ||
749 | /* Last message will contain ads7846_rx() as the | ||
750 | * completion function. | ||
751 | */ | ||
752 | m = ts->last_msg; | ||
753 | break; | ||
754 | case ADS7846_FILTER_OK: | ||
755 | *(u16 *)t->rx_buf = val; | ||
756 | packet->tc.ignore = 0; | ||
757 | m = &ts->msg[++ts->msg_idx]; | ||
758 | break; | ||
759 | default: | ||
760 | BUG(); | ||
761 | } | ||
762 | ts->wait_for_sync(); | ||
763 | status = spi_async(ts->spi, m); | ||
764 | if (status) | ||
765 | dev_err(&ts->spi->dev, "spi_async --> %d\n", | ||
766 | status); | ||
767 | } | ||
768 | 882 | ||
769 | static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) | 883 | /* pen is down, continue with the measurement */ |
770 | { | 884 | ads7846_read_state(ts); |
771 | struct ads7846 *ts = container_of(handle, struct ads7846, timer); | ||
772 | int status = 0; | ||
773 | 885 | ||
774 | spin_lock(&ts->lock); | 886 | if (!ts->stopped) |
887 | ads7846_report_state(ts); | ||
775 | 888 | ||
776 | if (unlikely(!get_pendown_state(ts) || | 889 | wait_event_timeout(ts->wait, ts->stopped, |
777 | device_suspended(&ts->spi->dev))) { | 890 | msecs_to_jiffies(TS_POLL_PERIOD)); |
778 | if (ts->pendown) { | 891 | } |
779 | struct input_dev *input = ts->input; | ||
780 | 892 | ||
781 | input_report_key(input, BTN_TOUCH, 0); | 893 | if (ts->pendown) { |
782 | input_report_abs(input, ABS_PRESSURE, 0); | 894 | struct input_dev *input = ts->input; |
783 | input_sync(input); | ||
784 | 895 | ||
785 | ts->pendown = 0; | 896 | input_report_key(input, BTN_TOUCH, 0); |
786 | dev_vdbg(&ts->spi->dev, "UP\n"); | 897 | input_report_abs(input, ABS_PRESSURE, 0); |
787 | } | 898 | input_sync(input); |
788 | 899 | ||
789 | /* measurement cycle ended */ | 900 | ts->pendown = false; |
790 | if (!device_suspended(&ts->spi->dev)) { | 901 | dev_vdbg(&ts->spi->dev, "UP\n"); |
791 | ts->irq_disabled = 0; | ||
792 | enable_irq(ts->spi->irq); | ||
793 | } | ||
794 | ts->pending = 0; | ||
795 | } else { | ||
796 | /* pen is still down, continue with the measurement */ | ||
797 | ts->msg_idx = 0; | ||
798 | ts->wait_for_sync(); | ||
799 | status = spi_async(ts->spi, &ts->msg[0]); | ||
800 | if (status) | ||
801 | dev_err(&ts->spi->dev, "spi_async --> %d\n", status); | ||
802 | } | 902 | } |
803 | 903 | ||
804 | spin_unlock(&ts->lock); | 904 | return IRQ_HANDLED; |
805 | return HRTIMER_NORESTART; | ||
806 | } | 905 | } |
807 | 906 | ||
808 | static irqreturn_t ads7846_irq(int irq, void *handle) | 907 | #ifdef CONFIG_PM_SLEEP |
908 | static int ads7846_suspend(struct device *dev) | ||
809 | { | 909 | { |
810 | struct ads7846 *ts = handle; | 910 | struct ads7846 *ts = dev_get_drvdata(dev); |
811 | unsigned long flags; | ||
812 | |||
813 | spin_lock_irqsave(&ts->lock, flags); | ||
814 | if (likely(get_pendown_state(ts))) { | ||
815 | if (!ts->irq_disabled) { | ||
816 | /* The ARM do_simple_IRQ() dispatcher doesn't act | ||
817 | * like the other dispatchers: it will report IRQs | ||
818 | * even after they've been disabled. We work around | ||
819 | * that here. (The "generic irq" framework may help...) | ||
820 | */ | ||
821 | ts->irq_disabled = 1; | ||
822 | disable_irq_nosync(ts->spi->irq); | ||
823 | ts->pending = 1; | ||
824 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), | ||
825 | HRTIMER_MODE_REL); | ||
826 | } | ||
827 | } | ||
828 | spin_unlock_irqrestore(&ts->lock, flags); | ||
829 | 911 | ||
830 | return IRQ_HANDLED; | 912 | mutex_lock(&ts->lock); |
831 | } | ||
832 | 913 | ||
833 | /*--------------------------------------------------------------------------*/ | 914 | if (!ts->suspended) { |
834 | 915 | ||
835 | /* Must be called with ts->lock held */ | 916 | if (!ts->disabled) |
836 | static void ads7846_disable(struct ads7846 *ts) | 917 | __ads7846_disable(ts); |
837 | { | ||
838 | if (ts->disabled) | ||
839 | return; | ||
840 | 918 | ||
841 | ts->disabled = 1; | 919 | if (device_may_wakeup(&ts->spi->dev)) |
920 | enable_irq_wake(ts->spi->irq); | ||
842 | 921 | ||
843 | /* are we waiting for IRQ, or polling? */ | 922 | ts->suspended = true; |
844 | if (!ts->pending) { | ||
845 | ts->irq_disabled = 1; | ||
846 | disable_irq(ts->spi->irq); | ||
847 | } else { | ||
848 | /* the timer will run at least once more, and | ||
849 | * leave everything in a clean state, IRQ disabled | ||
850 | */ | ||
851 | while (ts->pending) { | ||
852 | spin_unlock_irq(&ts->lock); | ||
853 | msleep(1); | ||
854 | spin_lock_irq(&ts->lock); | ||
855 | } | ||
856 | } | 923 | } |
857 | 924 | ||
858 | regulator_disable(ts->reg); | 925 | mutex_unlock(&ts->lock); |
859 | 926 | ||
860 | /* we know the chip's in lowpower mode since we always | 927 | return 0; |
861 | * leave it that way after every request | ||
862 | */ | ||
863 | } | 928 | } |
864 | 929 | ||
865 | /* Must be called with ts->lock held */ | 930 | static int ads7846_resume(struct device *dev) |
866 | static void ads7846_enable(struct ads7846 *ts) | ||
867 | { | 931 | { |
868 | if (!ts->disabled) | 932 | struct ads7846 *ts = dev_get_drvdata(dev); |
869 | return; | ||
870 | |||
871 | regulator_enable(ts->reg); | ||
872 | 933 | ||
873 | ts->disabled = 0; | 934 | mutex_lock(&ts->lock); |
874 | ts->irq_disabled = 0; | ||
875 | enable_irq(ts->spi->irq); | ||
876 | } | ||
877 | 935 | ||
878 | static int ads7846_suspend(struct spi_device *spi, pm_message_t message) | 936 | if (ts->suspended) { |
879 | { | ||
880 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | ||
881 | 937 | ||
882 | spin_lock_irq(&ts->lock); | 938 | ts->suspended = false; |
883 | 939 | ||
884 | ts->is_suspended = 1; | 940 | if (device_may_wakeup(&ts->spi->dev)) |
885 | ads7846_disable(ts); | 941 | disable_irq_wake(ts->spi->irq); |
886 | 942 | ||
887 | spin_unlock_irq(&ts->lock); | 943 | if (!ts->disabled) |
944 | __ads7846_enable(ts); | ||
945 | } | ||
888 | 946 | ||
889 | if (device_may_wakeup(&ts->spi->dev)) | 947 | mutex_unlock(&ts->lock); |
890 | enable_irq_wake(ts->spi->irq); | ||
891 | 948 | ||
892 | return 0; | 949 | return 0; |
893 | |||
894 | } | 950 | } |
951 | #endif | ||
895 | 952 | ||
896 | static int ads7846_resume(struct spi_device *spi) | 953 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); |
897 | { | ||
898 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | ||
899 | |||
900 | if (device_may_wakeup(&ts->spi->dev)) | ||
901 | disable_irq_wake(ts->spi->irq); | ||
902 | |||
903 | spin_lock_irq(&ts->lock); | ||
904 | |||
905 | ts->is_suspended = 0; | ||
906 | ads7846_enable(ts); | ||
907 | |||
908 | spin_unlock_irq(&ts->lock); | ||
909 | |||
910 | return 0; | ||
911 | } | ||
912 | 954 | ||
913 | static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) | 955 | static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) |
914 | { | 956 | { |
915 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 957 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
916 | int err; | 958 | int err; |
917 | 959 | ||
918 | /* REVISIT when the irq can be triggered active-low, or if for some | 960 | /* |
961 | * REVISIT when the irq can be triggered active-low, or if for some | ||
919 | * reason the touchscreen isn't hooked up, we don't need to access | 962 | * reason the touchscreen isn't hooked up, we don't need to access |
920 | * the pendown state. | 963 | * the pendown state. |
921 | */ | 964 | */ |
922 | if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) { | ||
923 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); | ||
924 | return -EINVAL; | ||
925 | } | ||
926 | 965 | ||
927 | if (pdata->get_pendown_state) { | 966 | if (pdata->get_pendown_state) { |
928 | ts->get_pendown_state = pdata->get_pendown_state; | 967 | ts->get_pendown_state = pdata->get_pendown_state; |
929 | return 0; | 968 | } else if (gpio_is_valid(pdata->gpio_pendown)) { |
930 | } | ||
931 | 969 | ||
932 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); | 970 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); |
933 | if (err) { | 971 | if (err) { |
934 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", | 972 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", |
935 | pdata->gpio_pendown); | 973 | pdata->gpio_pendown); |
936 | return err; | 974 | return err; |
937 | } | 975 | } |
938 | 976 | err = gpio_direction_input(pdata->gpio_pendown); | |
939 | ts->gpio_pendown = pdata->gpio_pendown; | 977 | if (err) { |
940 | return 0; | 978 | dev_err(&spi->dev, "failed to setup pendown GPIO%d\n", |
941 | } | 979 | pdata->gpio_pendown); |
942 | 980 | gpio_free(pdata->gpio_pendown); | |
943 | static int __devinit ads7846_probe(struct spi_device *spi) | 981 | return err; |
944 | { | 982 | } |
945 | struct ads7846 *ts; | ||
946 | struct ads7846_packet *packet; | ||
947 | struct input_dev *input_dev; | ||
948 | const struct ads7846_platform_data *pdata = spi->dev.platform_data; | ||
949 | struct spi_message *m; | ||
950 | struct spi_transfer *x; | ||
951 | unsigned long irq_flags; | ||
952 | int vref; | ||
953 | int err; | ||
954 | |||
955 | if (!spi->irq) { | ||
956 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
957 | return -ENODEV; | ||
958 | } | ||
959 | 983 | ||
960 | if (!pdata) { | 984 | ts->gpio_pendown = pdata->gpio_pendown; |
961 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
962 | return -ENODEV; | ||
963 | } | ||
964 | 985 | ||
965 | /* don't exceed max specified sample rate */ | 986 | } else { |
966 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | 987 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); |
967 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
968 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | ||
969 | return -EINVAL; | 988 | return -EINVAL; |
970 | } | 989 | } |
971 | 990 | ||
972 | /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except | 991 | return 0; |
973 | * that even if the hardware can do that, the SPI controller driver | 992 | } |
974 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | ||
975 | */ | ||
976 | spi->bits_per_word = 8; | ||
977 | spi->mode = SPI_MODE_0; | ||
978 | err = spi_setup(spi); | ||
979 | if (err < 0) | ||
980 | return err; | ||
981 | |||
982 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); | ||
983 | packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); | ||
984 | input_dev = input_allocate_device(); | ||
985 | if (!ts || !packet || !input_dev) { | ||
986 | err = -ENOMEM; | ||
987 | goto err_free_mem; | ||
988 | } | ||
989 | |||
990 | dev_set_drvdata(&spi->dev, ts); | ||
991 | |||
992 | ts->packet = packet; | ||
993 | ts->spi = spi; | ||
994 | ts->input = input_dev; | ||
995 | ts->vref_mv = pdata->vref_mv; | ||
996 | ts->swap_xy = pdata->swap_xy; | ||
997 | |||
998 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
999 | ts->timer.function = ads7846_timer; | ||
1000 | |||
1001 | spin_lock_init(&ts->lock); | ||
1002 | |||
1003 | ts->model = pdata->model ? : 7846; | ||
1004 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
1005 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
1006 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
1007 | |||
1008 | if (pdata->filter != NULL) { | ||
1009 | if (pdata->filter_init != NULL) { | ||
1010 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
1011 | if (err < 0) | ||
1012 | goto err_free_mem; | ||
1013 | } | ||
1014 | ts->filter = pdata->filter; | ||
1015 | ts->filter_cleanup = pdata->filter_cleanup; | ||
1016 | } else if (pdata->debounce_max) { | ||
1017 | ts->debounce_max = pdata->debounce_max; | ||
1018 | if (ts->debounce_max < 2) | ||
1019 | ts->debounce_max = 2; | ||
1020 | ts->debounce_tol = pdata->debounce_tol; | ||
1021 | ts->debounce_rep = pdata->debounce_rep; | ||
1022 | ts->filter = ads7846_debounce; | ||
1023 | ts->filter_data = ts; | ||
1024 | } else | ||
1025 | ts->filter = ads7846_no_filter; | ||
1026 | |||
1027 | err = setup_pendown(spi, ts); | ||
1028 | if (err) | ||
1029 | goto err_cleanup_filter; | ||
1030 | |||
1031 | if (pdata->penirq_recheck_delay_usecs) | ||
1032 | ts->penirq_recheck_delay_usecs = | ||
1033 | pdata->penirq_recheck_delay_usecs; | ||
1034 | |||
1035 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | ||
1036 | |||
1037 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
1038 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
1039 | |||
1040 | input_dev->name = ts->name; | ||
1041 | input_dev->phys = ts->phys; | ||
1042 | input_dev->dev.parent = &spi->dev; | ||
1043 | |||
1044 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1045 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
1046 | input_set_abs_params(input_dev, ABS_X, | ||
1047 | pdata->x_min ? : 0, | ||
1048 | pdata->x_max ? : MAX_12BIT, | ||
1049 | 0, 0); | ||
1050 | input_set_abs_params(input_dev, ABS_Y, | ||
1051 | pdata->y_min ? : 0, | ||
1052 | pdata->y_max ? : MAX_12BIT, | ||
1053 | 0, 0); | ||
1054 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1055 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
1056 | 993 | ||
1057 | vref = pdata->keep_vref_on; | 994 | /* |
995 | * Set up the transfers to read touchscreen state; this assumes we | ||
996 | * use formula #2 for pressure, not #3. | ||
997 | */ | ||
998 | static void __devinit ads7846_setup_spi_msg(struct ads7846 *ts, | ||
999 | const struct ads7846_platform_data *pdata) | ||
1000 | { | ||
1001 | struct spi_message *m = &ts->msg[0]; | ||
1002 | struct spi_transfer *x = ts->xfer; | ||
1003 | struct ads7846_packet *packet = ts->packet; | ||
1004 | int vref = pdata->keep_vref_on; | ||
1058 | 1005 | ||
1059 | if (ts->model == 7873) { | 1006 | if (ts->model == 7873) { |
1060 | /* The AD7873 is almost identical to the ADS7846 | 1007 | /* |
1008 | * The AD7873 is almost identical to the ADS7846 | ||
1061 | * keep VREF off during differential/ratiometric | 1009 | * keep VREF off during differential/ratiometric |
1062 | * conversion modes | 1010 | * conversion modes. |
1063 | */ | 1011 | */ |
1064 | ts->model = 7846; | 1012 | ts->model = 7846; |
1065 | vref = 0; | 1013 | vref = 0; |
1066 | } | 1014 | } |
1067 | 1015 | ||
1068 | /* set up the transfers to read touchscreen state; this assumes we | 1016 | ts->msg_count = 1; |
1069 | * use formula #2 for pressure, not #3. | ||
1070 | */ | ||
1071 | m = &ts->msg[0]; | ||
1072 | x = ts->xfer; | ||
1073 | |||
1074 | spi_message_init(m); | 1017 | spi_message_init(m); |
1018 | m->context = ts; | ||
1075 | 1019 | ||
1076 | if (ts->model == 7845) { | 1020 | if (ts->model == 7845) { |
1077 | packet->read_y_cmd[0] = READ_Y(vref); | 1021 | packet->read_y_cmd[0] = READ_Y(vref); |
@@ -1094,7 +1038,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1094 | spi_message_add_tail(x, m); | 1038 | spi_message_add_tail(x, m); |
1095 | } | 1039 | } |
1096 | 1040 | ||
1097 | /* the first sample after switching drivers can be low quality; | 1041 | /* |
1042 | * The first sample after switching drivers can be low quality; | ||
1098 | * optionally discard it, using a second one after the signals | 1043 | * optionally discard it, using a second one after the signals |
1099 | * have had enough time to stabilize. | 1044 | * have had enough time to stabilize. |
1100 | */ | 1045 | */ |
@@ -1112,11 +1057,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1112 | spi_message_add_tail(x, m); | 1057 | spi_message_add_tail(x, m); |
1113 | } | 1058 | } |
1114 | 1059 | ||
1115 | m->complete = ads7846_rx_val; | 1060 | ts->msg_count++; |
1116 | m->context = ts; | ||
1117 | |||
1118 | m++; | 1061 | m++; |
1119 | spi_message_init(m); | 1062 | spi_message_init(m); |
1063 | m->context = ts; | ||
1120 | 1064 | ||
1121 | if (ts->model == 7845) { | 1065 | if (ts->model == 7845) { |
1122 | x++; | 1066 | x++; |
@@ -1156,13 +1100,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1156 | spi_message_add_tail(x, m); | 1100 | spi_message_add_tail(x, m); |
1157 | } | 1101 | } |
1158 | 1102 | ||
1159 | m->complete = ads7846_rx_val; | ||
1160 | m->context = ts; | ||
1161 | |||
1162 | /* turn y+ off, x- on; we'll use formula #2 */ | 1103 | /* turn y+ off, x- on; we'll use formula #2 */ |
1163 | if (ts->model == 7846) { | 1104 | if (ts->model == 7846) { |
1105 | ts->msg_count++; | ||
1164 | m++; | 1106 | m++; |
1165 | spi_message_init(m); | 1107 | spi_message_init(m); |
1108 | m->context = ts; | ||
1166 | 1109 | ||
1167 | x++; | 1110 | x++; |
1168 | packet->read_z1 = READ_Z1(vref); | 1111 | packet->read_z1 = READ_Z1(vref); |
@@ -1190,11 +1133,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1190 | spi_message_add_tail(x, m); | 1133 | spi_message_add_tail(x, m); |
1191 | } | 1134 | } |
1192 | 1135 | ||
1193 | m->complete = ads7846_rx_val; | 1136 | ts->msg_count++; |
1194 | m->context = ts; | ||
1195 | |||
1196 | m++; | 1137 | m++; |
1197 | spi_message_init(m); | 1138 | spi_message_init(m); |
1139 | m->context = ts; | ||
1198 | 1140 | ||
1199 | x++; | 1141 | x++; |
1200 | packet->read_z2 = READ_Z2(vref); | 1142 | packet->read_z2 = READ_Z2(vref); |
@@ -1221,14 +1163,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1221 | x->len = 2; | 1163 | x->len = 2; |
1222 | spi_message_add_tail(x, m); | 1164 | spi_message_add_tail(x, m); |
1223 | } | 1165 | } |
1224 | |||
1225 | m->complete = ads7846_rx_val; | ||
1226 | m->context = ts; | ||
1227 | } | 1166 | } |
1228 | 1167 | ||
1229 | /* power down */ | 1168 | /* power down */ |
1169 | ts->msg_count++; | ||
1230 | m++; | 1170 | m++; |
1231 | spi_message_init(m); | 1171 | spi_message_init(m); |
1172 | m->context = ts; | ||
1232 | 1173 | ||
1233 | if (ts->model == 7845) { | 1174 | if (ts->model == 7845) { |
1234 | x++; | 1175 | x++; |
@@ -1251,11 +1192,119 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1251 | 1192 | ||
1252 | CS_CHANGE(*x); | 1193 | CS_CHANGE(*x); |
1253 | spi_message_add_tail(x, m); | 1194 | spi_message_add_tail(x, m); |
1195 | } | ||
1254 | 1196 | ||
1255 | m->complete = ads7846_rx; | 1197 | static int __devinit ads7846_probe(struct spi_device *spi) |
1256 | m->context = ts; | 1198 | { |
1199 | struct ads7846 *ts; | ||
1200 | struct ads7846_packet *packet; | ||
1201 | struct input_dev *input_dev; | ||
1202 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | ||
1203 | unsigned long irq_flags; | ||
1204 | int err; | ||
1205 | |||
1206 | if (!spi->irq) { | ||
1207 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
1208 | return -ENODEV; | ||
1209 | } | ||
1210 | |||
1211 | if (!pdata) { | ||
1212 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
1213 | return -ENODEV; | ||
1214 | } | ||
1215 | |||
1216 | /* don't exceed max specified sample rate */ | ||
1217 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | ||
1218 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
1219 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | ||
1220 | return -EINVAL; | ||
1221 | } | ||
1222 | |||
1223 | /* We'd set TX word size 8 bits and RX word size to 13 bits ... except | ||
1224 | * that even if the hardware can do that, the SPI controller driver | ||
1225 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | ||
1226 | */ | ||
1227 | spi->bits_per_word = 8; | ||
1228 | spi->mode = SPI_MODE_0; | ||
1229 | err = spi_setup(spi); | ||
1230 | if (err < 0) | ||
1231 | return err; | ||
1232 | |||
1233 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); | ||
1234 | packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); | ||
1235 | input_dev = input_allocate_device(); | ||
1236 | if (!ts || !packet || !input_dev) { | ||
1237 | err = -ENOMEM; | ||
1238 | goto err_free_mem; | ||
1239 | } | ||
1240 | |||
1241 | dev_set_drvdata(&spi->dev, ts); | ||
1242 | |||
1243 | ts->packet = packet; | ||
1244 | ts->spi = spi; | ||
1245 | ts->input = input_dev; | ||
1246 | ts->vref_mv = pdata->vref_mv; | ||
1247 | ts->swap_xy = pdata->swap_xy; | ||
1248 | |||
1249 | mutex_init(&ts->lock); | ||
1250 | init_waitqueue_head(&ts->wait); | ||
1251 | |||
1252 | ts->model = pdata->model ? : 7846; | ||
1253 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
1254 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
1255 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
1256 | |||
1257 | if (pdata->filter != NULL) { | ||
1258 | if (pdata->filter_init != NULL) { | ||
1259 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
1260 | if (err < 0) | ||
1261 | goto err_free_mem; | ||
1262 | } | ||
1263 | ts->filter = pdata->filter; | ||
1264 | ts->filter_cleanup = pdata->filter_cleanup; | ||
1265 | } else if (pdata->debounce_max) { | ||
1266 | ts->debounce_max = pdata->debounce_max; | ||
1267 | if (ts->debounce_max < 2) | ||
1268 | ts->debounce_max = 2; | ||
1269 | ts->debounce_tol = pdata->debounce_tol; | ||
1270 | ts->debounce_rep = pdata->debounce_rep; | ||
1271 | ts->filter = ads7846_debounce_filter; | ||
1272 | ts->filter_data = ts; | ||
1273 | } else { | ||
1274 | ts->filter = ads7846_no_filter; | ||
1275 | } | ||
1276 | |||
1277 | err = ads7846_setup_pendown(spi, ts); | ||
1278 | if (err) | ||
1279 | goto err_cleanup_filter; | ||
1280 | |||
1281 | if (pdata->penirq_recheck_delay_usecs) | ||
1282 | ts->penirq_recheck_delay_usecs = | ||
1283 | pdata->penirq_recheck_delay_usecs; | ||
1284 | |||
1285 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | ||
1286 | |||
1287 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
1288 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
1289 | |||
1290 | input_dev->name = ts->name; | ||
1291 | input_dev->phys = ts->phys; | ||
1292 | input_dev->dev.parent = &spi->dev; | ||
1293 | |||
1294 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1295 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
1296 | input_set_abs_params(input_dev, ABS_X, | ||
1297 | pdata->x_min ? : 0, | ||
1298 | pdata->x_max ? : MAX_12BIT, | ||
1299 | 0, 0); | ||
1300 | input_set_abs_params(input_dev, ABS_Y, | ||
1301 | pdata->y_min ? : 0, | ||
1302 | pdata->y_max ? : MAX_12BIT, | ||
1303 | 0, 0); | ||
1304 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1305 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
1257 | 1306 | ||
1258 | ts->last_msg = m; | 1307 | ads7846_setup_spi_msg(ts, pdata); |
1259 | 1308 | ||
1260 | ts->reg = regulator_get(&spi->dev, "vcc"); | 1309 | ts->reg = regulator_get(&spi->dev, "vcc"); |
1261 | if (IS_ERR(ts->reg)) { | 1310 | if (IS_ERR(ts->reg)) { |
@@ -1271,16 +1320,17 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1271 | } | 1320 | } |
1272 | 1321 | ||
1273 | irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; | 1322 | irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; |
1323 | irq_flags |= IRQF_ONESHOT; | ||
1274 | 1324 | ||
1275 | err = request_irq(spi->irq, ads7846_irq, irq_flags, | 1325 | err = request_threaded_irq(spi->irq, ads7846_hard_irq, ads7846_irq, |
1276 | spi->dev.driver->name, ts); | 1326 | irq_flags, spi->dev.driver->name, ts); |
1277 | |||
1278 | if (err && !pdata->irq_flags) { | 1327 | if (err && !pdata->irq_flags) { |
1279 | dev_info(&spi->dev, | 1328 | dev_info(&spi->dev, |
1280 | "trying pin change workaround on irq %d\n", spi->irq); | 1329 | "trying pin change workaround on irq %d\n", spi->irq); |
1281 | err = request_irq(spi->irq, ads7846_irq, | 1330 | irq_flags |= IRQF_TRIGGER_RISING; |
1282 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 1331 | err = request_threaded_irq(spi->irq, |
1283 | spi->dev.driver->name, ts); | 1332 | ads7846_hard_irq, ads7846_irq, |
1333 | irq_flags, spi->dev.driver->name, ts); | ||
1284 | } | 1334 | } |
1285 | 1335 | ||
1286 | if (err) { | 1336 | if (err) { |
@@ -1294,14 +1344,14 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1294 | 1344 | ||
1295 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); | 1345 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); |
1296 | 1346 | ||
1297 | /* take a first sample, leaving nPENIRQ active and vREF off; avoid | 1347 | /* |
1348 | * Take a first sample, leaving nPENIRQ active and vREF off; avoid | ||
1298 | * the touchscreen, in case it's not connected. | 1349 | * the touchscreen, in case it's not connected. |
1299 | */ | 1350 | */ |
1300 | if (ts->model == 7845) | 1351 | if (ts->model == 7845) |
1301 | ads7845_read12_ser(&spi->dev, PWRDOWN); | 1352 | ads7845_read12_ser(&spi->dev, PWRDOWN); |
1302 | else | 1353 | else |
1303 | (void) ads7846_read12_ser(&spi->dev, | 1354 | (void) ads7846_read12_ser(&spi->dev, READ_12BIT_SER(vaux)); |
1304 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); | ||
1305 | 1355 | ||
1306 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); | 1356 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); |
1307 | if (err) | 1357 | if (err) |
@@ -1326,7 +1376,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1326 | err_put_regulator: | 1376 | err_put_regulator: |
1327 | regulator_put(ts->reg); | 1377 | regulator_put(ts->reg); |
1328 | err_free_gpio: | 1378 | err_free_gpio: |
1329 | if (ts->gpio_pendown != -1) | 1379 | if (!ts->get_pendown_state) |
1330 | gpio_free(ts->gpio_pendown); | 1380 | gpio_free(ts->gpio_pendown); |
1331 | err_cleanup_filter: | 1381 | err_cleanup_filter: |
1332 | if (ts->filter_cleanup) | 1382 | if (ts->filter_cleanup) |
@@ -1340,26 +1390,29 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1340 | 1390 | ||
1341 | static int __devexit ads7846_remove(struct spi_device *spi) | 1391 | static int __devexit ads7846_remove(struct spi_device *spi) |
1342 | { | 1392 | { |
1343 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 1393 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
1344 | 1394 | ||
1345 | device_init_wakeup(&spi->dev, false); | 1395 | device_init_wakeup(&spi->dev, false); |
1346 | 1396 | ||
1347 | ads784x_hwmon_unregister(spi, ts); | ||
1348 | input_unregister_device(ts->input); | ||
1349 | |||
1350 | ads7846_suspend(spi, PMSG_SUSPEND); | ||
1351 | |||
1352 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); | 1397 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); |
1353 | 1398 | ||
1399 | ads7846_disable(ts); | ||
1354 | free_irq(ts->spi->irq, ts); | 1400 | free_irq(ts->spi->irq, ts); |
1355 | /* suspend left the IRQ disabled */ | 1401 | |
1356 | enable_irq(ts->spi->irq); | 1402 | input_unregister_device(ts->input); |
1403 | |||
1404 | ads784x_hwmon_unregister(spi, ts); | ||
1357 | 1405 | ||
1358 | regulator_disable(ts->reg); | 1406 | regulator_disable(ts->reg); |
1359 | regulator_put(ts->reg); | 1407 | regulator_put(ts->reg); |
1360 | 1408 | ||
1361 | if (ts->gpio_pendown != -1) | 1409 | if (!ts->get_pendown_state) { |
1410 | /* | ||
1411 | * If we are not using specialized pendown method we must | ||
1412 | * have been relying on gpio we set up ourselves. | ||
1413 | */ | ||
1362 | gpio_free(ts->gpio_pendown); | 1414 | gpio_free(ts->gpio_pendown); |
1415 | } | ||
1363 | 1416 | ||
1364 | if (ts->filter_cleanup) | 1417 | if (ts->filter_cleanup) |
1365 | ts->filter_cleanup(ts->filter_data); | 1418 | ts->filter_cleanup(ts->filter_data); |
@@ -1368,6 +1421,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
1368 | kfree(ts); | 1421 | kfree(ts); |
1369 | 1422 | ||
1370 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 1423 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |
1424 | |||
1371 | return 0; | 1425 | return 0; |
1372 | } | 1426 | } |
1373 | 1427 | ||
@@ -1376,11 +1430,10 @@ static struct spi_driver ads7846_driver = { | |||
1376 | .name = "ads7846", | 1430 | .name = "ads7846", |
1377 | .bus = &spi_bus_type, | 1431 | .bus = &spi_bus_type, |
1378 | .owner = THIS_MODULE, | 1432 | .owner = THIS_MODULE, |
1433 | .pm = &ads7846_pm, | ||
1379 | }, | 1434 | }, |
1380 | .probe = ads7846_probe, | 1435 | .probe = ads7846_probe, |
1381 | .remove = __devexit_p(ads7846_remove), | 1436 | .remove = __devexit_p(ads7846_remove), |
1382 | .suspend = ads7846_suspend, | ||
1383 | .resume = ads7846_resume, | ||
1384 | }; | 1437 | }; |
1385 | 1438 | ||
1386 | static int __init ads7846_init(void) | 1439 | static int __init ads7846_init(void) |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c new file mode 100644 index 000000000000..1e61387c73ca --- /dev/null +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -0,0 +1,1243 @@ | |||
1 | /* | ||
2 | * Atmel maXTouch Touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/firmware.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/i2c/atmel_mxt_ts.h> | ||
20 | #include <linux/input/mt.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | /* Version */ | ||
25 | #define MXT_VER_20 20 | ||
26 | #define MXT_VER_21 21 | ||
27 | #define MXT_VER_22 22 | ||
28 | |||
29 | /* Slave addresses */ | ||
30 | #define MXT_APP_LOW 0x4a | ||
31 | #define MXT_APP_HIGH 0x4b | ||
32 | #define MXT_BOOT_LOW 0x24 | ||
33 | #define MXT_BOOT_HIGH 0x25 | ||
34 | |||
35 | /* Firmware */ | ||
36 | #define MXT_FW_NAME "maxtouch.fw" | ||
37 | |||
38 | /* Registers */ | ||
39 | #define MXT_FAMILY_ID 0x00 | ||
40 | #define MXT_VARIANT_ID 0x01 | ||
41 | #define MXT_VERSION 0x02 | ||
42 | #define MXT_BUILD 0x03 | ||
43 | #define MXT_MATRIX_X_SIZE 0x04 | ||
44 | #define MXT_MATRIX_Y_SIZE 0x05 | ||
45 | #define MXT_OBJECT_NUM 0x06 | ||
46 | #define MXT_OBJECT_START 0x07 | ||
47 | |||
48 | #define MXT_OBJECT_SIZE 6 | ||
49 | |||
50 | /* Object types */ | ||
51 | #define MXT_DEBUG_DIAGNOSTIC 37 | ||
52 | #define MXT_GEN_MESSAGE 5 | ||
53 | #define MXT_GEN_COMMAND 6 | ||
54 | #define MXT_GEN_POWER 7 | ||
55 | #define MXT_GEN_ACQUIRE 8 | ||
56 | #define MXT_TOUCH_MULTI 9 | ||
57 | #define MXT_TOUCH_KEYARRAY 15 | ||
58 | #define MXT_TOUCH_PROXIMITY 23 | ||
59 | #define MXT_PROCI_GRIPFACE 20 | ||
60 | #define MXT_PROCG_NOISE 22 | ||
61 | #define MXT_PROCI_ONETOUCH 24 | ||
62 | #define MXT_PROCI_TWOTOUCH 27 | ||
63 | #define MXT_PROCI_GRIP 40 | ||
64 | #define MXT_PROCI_PALM 41 | ||
65 | #define MXT_SPT_COMMSCONFIG 18 | ||
66 | #define MXT_SPT_GPIOPWM 19 | ||
67 | #define MXT_SPT_SELFTEST 25 | ||
68 | #define MXT_SPT_CTECONFIG 28 | ||
69 | #define MXT_SPT_USERDATA 38 | ||
70 | #define MXT_SPT_DIGITIZER 43 | ||
71 | #define MXT_SPT_MESSAGECOUNT 44 | ||
72 | |||
73 | /* MXT_GEN_COMMAND field */ | ||
74 | #define MXT_COMMAND_RESET 0 | ||
75 | #define MXT_COMMAND_BACKUPNV 1 | ||
76 | #define MXT_COMMAND_CALIBRATE 2 | ||
77 | #define MXT_COMMAND_REPORTALL 3 | ||
78 | #define MXT_COMMAND_DIAGNOSTIC 5 | ||
79 | |||
80 | /* MXT_GEN_POWER field */ | ||
81 | #define MXT_POWER_IDLEACQINT 0 | ||
82 | #define MXT_POWER_ACTVACQINT 1 | ||
83 | #define MXT_POWER_ACTV2IDLETO 2 | ||
84 | |||
85 | /* MXT_GEN_ACQUIRE field */ | ||
86 | #define MXT_ACQUIRE_CHRGTIME 0 | ||
87 | #define MXT_ACQUIRE_TCHDRIFT 2 | ||
88 | #define MXT_ACQUIRE_DRIFTST 3 | ||
89 | #define MXT_ACQUIRE_TCHAUTOCAL 4 | ||
90 | #define MXT_ACQUIRE_SYNC 5 | ||
91 | #define MXT_ACQUIRE_ATCHCALST 6 | ||
92 | #define MXT_ACQUIRE_ATCHCALSTHR 7 | ||
93 | |||
94 | /* MXT_TOUCH_MULTI field */ | ||
95 | #define MXT_TOUCH_CTRL 0 | ||
96 | #define MXT_TOUCH_XORIGIN 1 | ||
97 | #define MXT_TOUCH_YORIGIN 2 | ||
98 | #define MXT_TOUCH_XSIZE 3 | ||
99 | #define MXT_TOUCH_YSIZE 4 | ||
100 | #define MXT_TOUCH_BLEN 6 | ||
101 | #define MXT_TOUCH_TCHTHR 7 | ||
102 | #define MXT_TOUCH_TCHDI 8 | ||
103 | #define MXT_TOUCH_ORIENT 9 | ||
104 | #define MXT_TOUCH_MOVHYSTI 11 | ||
105 | #define MXT_TOUCH_MOVHYSTN 12 | ||
106 | #define MXT_TOUCH_NUMTOUCH 14 | ||
107 | #define MXT_TOUCH_MRGHYST 15 | ||
108 | #define MXT_TOUCH_MRGTHR 16 | ||
109 | #define MXT_TOUCH_AMPHYST 17 | ||
110 | #define MXT_TOUCH_XRANGE_LSB 18 | ||
111 | #define MXT_TOUCH_XRANGE_MSB 19 | ||
112 | #define MXT_TOUCH_YRANGE_LSB 20 | ||
113 | #define MXT_TOUCH_YRANGE_MSB 21 | ||
114 | #define MXT_TOUCH_XLOCLIP 22 | ||
115 | #define MXT_TOUCH_XHICLIP 23 | ||
116 | #define MXT_TOUCH_YLOCLIP 24 | ||
117 | #define MXT_TOUCH_YHICLIP 25 | ||
118 | #define MXT_TOUCH_XEDGECTRL 26 | ||
119 | #define MXT_TOUCH_XEDGEDIST 27 | ||
120 | #define MXT_TOUCH_YEDGECTRL 28 | ||
121 | #define MXT_TOUCH_YEDGEDIST 29 | ||
122 | #define MXT_TOUCH_JUMPLIMIT 30 | ||
123 | |||
124 | /* MXT_PROCI_GRIPFACE field */ | ||
125 | #define MXT_GRIPFACE_CTRL 0 | ||
126 | #define MXT_GRIPFACE_XLOGRIP 1 | ||
127 | #define MXT_GRIPFACE_XHIGRIP 2 | ||
128 | #define MXT_GRIPFACE_YLOGRIP 3 | ||
129 | #define MXT_GRIPFACE_YHIGRIP 4 | ||
130 | #define MXT_GRIPFACE_MAXTCHS 5 | ||
131 | #define MXT_GRIPFACE_SZTHR1 7 | ||
132 | #define MXT_GRIPFACE_SZTHR2 8 | ||
133 | #define MXT_GRIPFACE_SHPTHR1 9 | ||
134 | #define MXT_GRIPFACE_SHPTHR2 10 | ||
135 | #define MXT_GRIPFACE_SUPEXTTO 11 | ||
136 | |||
137 | /* MXT_PROCI_NOISE field */ | ||
138 | #define MXT_NOISE_CTRL 0 | ||
139 | #define MXT_NOISE_OUTFLEN 1 | ||
140 | #define MXT_NOISE_GCAFUL_LSB 3 | ||
141 | #define MXT_NOISE_GCAFUL_MSB 4 | ||
142 | #define MXT_NOISE_GCAFLL_LSB 5 | ||
143 | #define MXT_NOISE_GCAFLL_MSB 6 | ||
144 | #define MXT_NOISE_ACTVGCAFVALID 7 | ||
145 | #define MXT_NOISE_NOISETHR 8 | ||
146 | #define MXT_NOISE_FREQHOPSCALE 10 | ||
147 | #define MXT_NOISE_FREQ0 11 | ||
148 | #define MXT_NOISE_FREQ1 12 | ||
149 | #define MXT_NOISE_FREQ2 13 | ||
150 | #define MXT_NOISE_FREQ3 14 | ||
151 | #define MXT_NOISE_FREQ4 15 | ||
152 | #define MXT_NOISE_IDLEGCAFVALID 16 | ||
153 | |||
154 | /* MXT_SPT_COMMSCONFIG */ | ||
155 | #define MXT_COMMS_CTRL 0 | ||
156 | #define MXT_COMMS_CMD 1 | ||
157 | |||
158 | /* MXT_SPT_CTECONFIG field */ | ||
159 | #define MXT_CTE_CTRL 0 | ||
160 | #define MXT_CTE_CMD 1 | ||
161 | #define MXT_CTE_MODE 2 | ||
162 | #define MXT_CTE_IDLEGCAFDEPTH 3 | ||
163 | #define MXT_CTE_ACTVGCAFDEPTH 4 | ||
164 | #define MXT_CTE_VOLTAGE 5 | ||
165 | |||
166 | #define MXT_VOLTAGE_DEFAULT 2700000 | ||
167 | #define MXT_VOLTAGE_STEP 10000 | ||
168 | |||
169 | /* Define for MXT_GEN_COMMAND */ | ||
170 | #define MXT_BOOT_VALUE 0xa5 | ||
171 | #define MXT_BACKUP_VALUE 0x55 | ||
172 | #define MXT_BACKUP_TIME 25 /* msec */ | ||
173 | #define MXT_RESET_TIME 65 /* msec */ | ||
174 | |||
175 | #define MXT_FWRESET_TIME 175 /* msec */ | ||
176 | |||
177 | /* Command to unlock bootloader */ | ||
178 | #define MXT_UNLOCK_CMD_MSB 0xaa | ||
179 | #define MXT_UNLOCK_CMD_LSB 0xdc | ||
180 | |||
181 | /* Bootloader mode status */ | ||
182 | #define MXT_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */ | ||
183 | #define MXT_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */ | ||
184 | #define MXT_FRAME_CRC_CHECK 0x02 | ||
185 | #define MXT_FRAME_CRC_FAIL 0x03 | ||
186 | #define MXT_FRAME_CRC_PASS 0x04 | ||
187 | #define MXT_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */ | ||
188 | #define MXT_BOOT_STATUS_MASK 0x3f | ||
189 | |||
190 | /* Touch status */ | ||
191 | #define MXT_SUPPRESS (1 << 1) | ||
192 | #define MXT_AMP (1 << 2) | ||
193 | #define MXT_VECTOR (1 << 3) | ||
194 | #define MXT_MOVE (1 << 4) | ||
195 | #define MXT_RELEASE (1 << 5) | ||
196 | #define MXT_PRESS (1 << 6) | ||
197 | #define MXT_DETECT (1 << 7) | ||
198 | |||
199 | /* Touch orient bits */ | ||
200 | #define MXT_XY_SWITCH (1 << 0) | ||
201 | #define MXT_X_INVERT (1 << 1) | ||
202 | #define MXT_Y_INVERT (1 << 2) | ||
203 | |||
204 | /* Touchscreen absolute values */ | ||
205 | #define MXT_MAX_AREA 0xff | ||
206 | |||
207 | #define MXT_MAX_FINGER 10 | ||
208 | |||
209 | struct mxt_info { | ||
210 | u8 family_id; | ||
211 | u8 variant_id; | ||
212 | u8 version; | ||
213 | u8 build; | ||
214 | u8 matrix_xsize; | ||
215 | u8 matrix_ysize; | ||
216 | u8 object_num; | ||
217 | }; | ||
218 | |||
219 | struct mxt_object { | ||
220 | u8 type; | ||
221 | u16 start_address; | ||
222 | u8 size; | ||
223 | u8 instances; | ||
224 | u8 num_report_ids; | ||
225 | |||
226 | /* to map object and message */ | ||
227 | u8 max_reportid; | ||
228 | }; | ||
229 | |||
230 | struct mxt_message { | ||
231 | u8 reportid; | ||
232 | u8 message[7]; | ||
233 | u8 checksum; | ||
234 | }; | ||
235 | |||
236 | struct mxt_finger { | ||
237 | int status; | ||
238 | int x; | ||
239 | int y; | ||
240 | int area; | ||
241 | }; | ||
242 | |||
243 | /* Each client has this additional data */ | ||
244 | struct mxt_data { | ||
245 | struct i2c_client *client; | ||
246 | struct input_dev *input_dev; | ||
247 | const struct mxt_platform_data *pdata; | ||
248 | struct mxt_object *object_table; | ||
249 | struct mxt_info info; | ||
250 | struct mxt_finger finger[MXT_MAX_FINGER]; | ||
251 | unsigned int irq; | ||
252 | unsigned int max_x; | ||
253 | unsigned int max_y; | ||
254 | }; | ||
255 | |||
256 | static bool mxt_object_readable(unsigned int type) | ||
257 | { | ||
258 | switch (type) { | ||
259 | case MXT_GEN_MESSAGE: | ||
260 | case MXT_GEN_COMMAND: | ||
261 | case MXT_GEN_POWER: | ||
262 | case MXT_GEN_ACQUIRE: | ||
263 | case MXT_TOUCH_MULTI: | ||
264 | case MXT_TOUCH_KEYARRAY: | ||
265 | case MXT_TOUCH_PROXIMITY: | ||
266 | case MXT_PROCI_GRIPFACE: | ||
267 | case MXT_PROCG_NOISE: | ||
268 | case MXT_PROCI_ONETOUCH: | ||
269 | case MXT_PROCI_TWOTOUCH: | ||
270 | case MXT_PROCI_GRIP: | ||
271 | case MXT_PROCI_PALM: | ||
272 | case MXT_SPT_COMMSCONFIG: | ||
273 | case MXT_SPT_GPIOPWM: | ||
274 | case MXT_SPT_SELFTEST: | ||
275 | case MXT_SPT_CTECONFIG: | ||
276 | case MXT_SPT_USERDATA: | ||
277 | return true; | ||
278 | default: | ||
279 | return false; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | static bool mxt_object_writable(unsigned int type) | ||
284 | { | ||
285 | switch (type) { | ||
286 | case MXT_GEN_COMMAND: | ||
287 | case MXT_GEN_POWER: | ||
288 | case MXT_GEN_ACQUIRE: | ||
289 | case MXT_TOUCH_MULTI: | ||
290 | case MXT_TOUCH_KEYARRAY: | ||
291 | case MXT_TOUCH_PROXIMITY: | ||
292 | case MXT_PROCI_GRIPFACE: | ||
293 | case MXT_PROCG_NOISE: | ||
294 | case MXT_PROCI_ONETOUCH: | ||
295 | case MXT_PROCI_TWOTOUCH: | ||
296 | case MXT_PROCI_GRIP: | ||
297 | case MXT_PROCI_PALM: | ||
298 | case MXT_SPT_GPIOPWM: | ||
299 | case MXT_SPT_SELFTEST: | ||
300 | case MXT_SPT_CTECONFIG: | ||
301 | return true; | ||
302 | default: | ||
303 | return false; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | static void mxt_dump_message(struct device *dev, | ||
308 | struct mxt_message *message) | ||
309 | { | ||
310 | dev_dbg(dev, "reportid:\t0x%x\n", message->reportid); | ||
311 | dev_dbg(dev, "message1:\t0x%x\n", message->message[0]); | ||
312 | dev_dbg(dev, "message2:\t0x%x\n", message->message[1]); | ||
313 | dev_dbg(dev, "message3:\t0x%x\n", message->message[2]); | ||
314 | dev_dbg(dev, "message4:\t0x%x\n", message->message[3]); | ||
315 | dev_dbg(dev, "message5:\t0x%x\n", message->message[4]); | ||
316 | dev_dbg(dev, "message6:\t0x%x\n", message->message[5]); | ||
317 | dev_dbg(dev, "message7:\t0x%x\n", message->message[6]); | ||
318 | dev_dbg(dev, "checksum:\t0x%x\n", message->checksum); | ||
319 | } | ||
320 | |||
321 | static int mxt_check_bootloader(struct i2c_client *client, | ||
322 | unsigned int state) | ||
323 | { | ||
324 | u8 val; | ||
325 | |||
326 | recheck: | ||
327 | if (i2c_master_recv(client, &val, 1) != 1) { | ||
328 | dev_err(&client->dev, "%s: i2c recv failed\n", __func__); | ||
329 | return -EIO; | ||
330 | } | ||
331 | |||
332 | switch (state) { | ||
333 | case MXT_WAITING_BOOTLOAD_CMD: | ||
334 | case MXT_WAITING_FRAME_DATA: | ||
335 | val &= ~MXT_BOOT_STATUS_MASK; | ||
336 | break; | ||
337 | case MXT_FRAME_CRC_PASS: | ||
338 | if (val == MXT_FRAME_CRC_CHECK) | ||
339 | goto recheck; | ||
340 | break; | ||
341 | default: | ||
342 | return -EINVAL; | ||
343 | } | ||
344 | |||
345 | if (val != state) { | ||
346 | dev_err(&client->dev, "Unvalid bootloader mode state\n"); | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int mxt_unlock_bootloader(struct i2c_client *client) | ||
354 | { | ||
355 | u8 buf[2]; | ||
356 | |||
357 | buf[0] = MXT_UNLOCK_CMD_LSB; | ||
358 | buf[1] = MXT_UNLOCK_CMD_MSB; | ||
359 | |||
360 | if (i2c_master_send(client, buf, 2) != 2) { | ||
361 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
362 | return -EIO; | ||
363 | } | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int mxt_fw_write(struct i2c_client *client, | ||
369 | const u8 *data, unsigned int frame_size) | ||
370 | { | ||
371 | if (i2c_master_send(client, data, frame_size) != frame_size) { | ||
372 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
373 | return -EIO; | ||
374 | } | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int __mxt_read_reg(struct i2c_client *client, | ||
380 | u16 reg, u16 len, void *val) | ||
381 | { | ||
382 | struct i2c_msg xfer[2]; | ||
383 | u8 buf[2]; | ||
384 | |||
385 | buf[0] = reg & 0xff; | ||
386 | buf[1] = (reg >> 8) & 0xff; | ||
387 | |||
388 | /* Write register */ | ||
389 | xfer[0].addr = client->addr; | ||
390 | xfer[0].flags = 0; | ||
391 | xfer[0].len = 2; | ||
392 | xfer[0].buf = buf; | ||
393 | |||
394 | /* Read data */ | ||
395 | xfer[1].addr = client->addr; | ||
396 | xfer[1].flags = I2C_M_RD; | ||
397 | xfer[1].len = len; | ||
398 | xfer[1].buf = val; | ||
399 | |||
400 | if (i2c_transfer(client->adapter, xfer, 2) != 2) { | ||
401 | dev_err(&client->dev, "%s: i2c transfer failed\n", __func__); | ||
402 | return -EIO; | ||
403 | } | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val) | ||
409 | { | ||
410 | return __mxt_read_reg(client, reg, 1, val); | ||
411 | } | ||
412 | |||
413 | static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val) | ||
414 | { | ||
415 | u8 buf[3]; | ||
416 | |||
417 | buf[0] = reg & 0xff; | ||
418 | buf[1] = (reg >> 8) & 0xff; | ||
419 | buf[2] = val; | ||
420 | |||
421 | if (i2c_master_send(client, buf, 3) != 3) { | ||
422 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
423 | return -EIO; | ||
424 | } | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int mxt_read_object_table(struct i2c_client *client, | ||
430 | u16 reg, u8 *object_buf) | ||
431 | { | ||
432 | return __mxt_read_reg(client, reg, MXT_OBJECT_SIZE, | ||
433 | object_buf); | ||
434 | } | ||
435 | |||
436 | static struct mxt_object * | ||
437 | mxt_get_object(struct mxt_data *data, u8 type) | ||
438 | { | ||
439 | struct mxt_object *object; | ||
440 | int i; | ||
441 | |||
442 | for (i = 0; i < data->info.object_num; i++) { | ||
443 | object = data->object_table + i; | ||
444 | if (object->type == type) | ||
445 | return object; | ||
446 | } | ||
447 | |||
448 | dev_err(&data->client->dev, "Invalid object type\n"); | ||
449 | return NULL; | ||
450 | } | ||
451 | |||
452 | static int mxt_read_message(struct mxt_data *data, | ||
453 | struct mxt_message *message) | ||
454 | { | ||
455 | struct mxt_object *object; | ||
456 | u16 reg; | ||
457 | |||
458 | object = mxt_get_object(data, MXT_GEN_MESSAGE); | ||
459 | if (!object) | ||
460 | return -EINVAL; | ||
461 | |||
462 | reg = object->start_address; | ||
463 | return __mxt_read_reg(data->client, reg, | ||
464 | sizeof(struct mxt_message), message); | ||
465 | } | ||
466 | |||
467 | static int mxt_read_object(struct mxt_data *data, | ||
468 | u8 type, u8 offset, u8 *val) | ||
469 | { | ||
470 | struct mxt_object *object; | ||
471 | u16 reg; | ||
472 | |||
473 | object = mxt_get_object(data, type); | ||
474 | if (!object) | ||
475 | return -EINVAL; | ||
476 | |||
477 | reg = object->start_address; | ||
478 | return __mxt_read_reg(data->client, reg + offset, 1, val); | ||
479 | } | ||
480 | |||
481 | static int mxt_write_object(struct mxt_data *data, | ||
482 | u8 type, u8 offset, u8 val) | ||
483 | { | ||
484 | struct mxt_object *object; | ||
485 | u16 reg; | ||
486 | |||
487 | object = mxt_get_object(data, type); | ||
488 | if (!object) | ||
489 | return -EINVAL; | ||
490 | |||
491 | reg = object->start_address; | ||
492 | return mxt_write_reg(data->client, reg + offset, val); | ||
493 | } | ||
494 | |||
495 | static void mxt_input_report(struct mxt_data *data, int single_id) | ||
496 | { | ||
497 | struct mxt_finger *finger = data->finger; | ||
498 | struct input_dev *input_dev = data->input_dev; | ||
499 | int status = finger[single_id].status; | ||
500 | int finger_num = 0; | ||
501 | int id; | ||
502 | |||
503 | for (id = 0; id < MXT_MAX_FINGER; id++) { | ||
504 | if (!finger[id].status) | ||
505 | continue; | ||
506 | |||
507 | input_mt_slot(input_dev, id); | ||
508 | input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, | ||
509 | finger[id].status != MXT_RELEASE); | ||
510 | |||
511 | if (finger[id].status != MXT_RELEASE) { | ||
512 | finger_num++; | ||
513 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, | ||
514 | finger[id].area); | ||
515 | input_report_abs(input_dev, ABS_MT_POSITION_X, | ||
516 | finger[id].x); | ||
517 | input_report_abs(input_dev, ABS_MT_POSITION_Y, | ||
518 | finger[id].y); | ||
519 | } else { | ||
520 | finger[id].status = 0; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | input_report_key(input_dev, BTN_TOUCH, finger_num > 0); | ||
525 | |||
526 | if (status != MXT_RELEASE) { | ||
527 | input_report_abs(input_dev, ABS_X, finger[single_id].x); | ||
528 | input_report_abs(input_dev, ABS_Y, finger[single_id].y); | ||
529 | } | ||
530 | |||
531 | input_sync(input_dev); | ||
532 | } | ||
533 | |||
534 | static void mxt_input_touchevent(struct mxt_data *data, | ||
535 | struct mxt_message *message, int id) | ||
536 | { | ||
537 | struct mxt_finger *finger = data->finger; | ||
538 | struct device *dev = &data->client->dev; | ||
539 | u8 status = message->message[0]; | ||
540 | int x; | ||
541 | int y; | ||
542 | int area; | ||
543 | |||
544 | /* Check the touch is present on the screen */ | ||
545 | if (!(status & MXT_DETECT)) { | ||
546 | if (status & MXT_RELEASE) { | ||
547 | dev_dbg(dev, "[%d] released\n", id); | ||
548 | |||
549 | finger[id].status = MXT_RELEASE; | ||
550 | mxt_input_report(data, id); | ||
551 | } | ||
552 | return; | ||
553 | } | ||
554 | |||
555 | /* Check only AMP detection */ | ||
556 | if (!(status & (MXT_PRESS | MXT_MOVE))) | ||
557 | return; | ||
558 | |||
559 | x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf); | ||
560 | y = (message->message[2] << 4) | ((message->message[3] & 0xf)); | ||
561 | if (data->max_x < 1024) | ||
562 | x = x >> 2; | ||
563 | if (data->max_y < 1024) | ||
564 | y = y >> 2; | ||
565 | |||
566 | area = message->message[4]; | ||
567 | |||
568 | dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, | ||
569 | status & MXT_MOVE ? "moved" : "pressed", | ||
570 | x, y, area); | ||
571 | |||
572 | finger[id].status = status & MXT_MOVE ? | ||
573 | MXT_MOVE : MXT_PRESS; | ||
574 | finger[id].x = x; | ||
575 | finger[id].y = y; | ||
576 | finger[id].area = area; | ||
577 | |||
578 | mxt_input_report(data, id); | ||
579 | } | ||
580 | |||
581 | static irqreturn_t mxt_interrupt(int irq, void *dev_id) | ||
582 | { | ||
583 | struct mxt_data *data = dev_id; | ||
584 | struct mxt_message message; | ||
585 | struct mxt_object *object; | ||
586 | struct device *dev = &data->client->dev; | ||
587 | int id; | ||
588 | u8 reportid; | ||
589 | u8 max_reportid; | ||
590 | u8 min_reportid; | ||
591 | |||
592 | do { | ||
593 | if (mxt_read_message(data, &message)) { | ||
594 | dev_err(dev, "Failed to read message\n"); | ||
595 | goto end; | ||
596 | } | ||
597 | |||
598 | reportid = message.reportid; | ||
599 | |||
600 | /* whether reportid is thing of MXT_TOUCH_MULTI */ | ||
601 | object = mxt_get_object(data, MXT_TOUCH_MULTI); | ||
602 | if (!object) | ||
603 | goto end; | ||
604 | |||
605 | max_reportid = object->max_reportid; | ||
606 | min_reportid = max_reportid - object->num_report_ids + 1; | ||
607 | id = reportid - min_reportid; | ||
608 | |||
609 | if (reportid >= min_reportid && reportid <= max_reportid) | ||
610 | mxt_input_touchevent(data, &message, id); | ||
611 | else | ||
612 | mxt_dump_message(dev, &message); | ||
613 | } while (reportid != 0xff); | ||
614 | |||
615 | end: | ||
616 | return IRQ_HANDLED; | ||
617 | } | ||
618 | |||
619 | static int mxt_check_reg_init(struct mxt_data *data) | ||
620 | { | ||
621 | const struct mxt_platform_data *pdata = data->pdata; | ||
622 | struct mxt_object *object; | ||
623 | struct device *dev = &data->client->dev; | ||
624 | int index = 0; | ||
625 | int i, j, config_offset; | ||
626 | |||
627 | if (!pdata->config) { | ||
628 | dev_dbg(dev, "No cfg data defined, skipping reg init\n"); | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | for (i = 0; i < data->info.object_num; i++) { | ||
633 | object = data->object_table + i; | ||
634 | |||
635 | if (!mxt_object_writable(object->type)) | ||
636 | continue; | ||
637 | |||
638 | for (j = 0; j < object->size + 1; j++) { | ||
639 | config_offset = index + j; | ||
640 | if (config_offset > pdata->config_length) { | ||
641 | dev_err(dev, "Not enough config data!\n"); | ||
642 | return -EINVAL; | ||
643 | } | ||
644 | mxt_write_object(data, object->type, j, | ||
645 | pdata->config[config_offset]); | ||
646 | } | ||
647 | index += object->size + 1; | ||
648 | } | ||
649 | |||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static int mxt_make_highchg(struct mxt_data *data) | ||
654 | { | ||
655 | struct device *dev = &data->client->dev; | ||
656 | struct mxt_message message; | ||
657 | int count = 10; | ||
658 | int error; | ||
659 | |||
660 | /* Read dummy message to make high CHG pin */ | ||
661 | do { | ||
662 | error = mxt_read_message(data, &message); | ||
663 | if (error) | ||
664 | return error; | ||
665 | } while (message.reportid != 0xff && --count); | ||
666 | |||
667 | if (!count) { | ||
668 | dev_err(dev, "CHG pin isn't cleared\n"); | ||
669 | return -EBUSY; | ||
670 | } | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | static void mxt_handle_pdata(struct mxt_data *data) | ||
676 | { | ||
677 | const struct mxt_platform_data *pdata = data->pdata; | ||
678 | u8 voltage; | ||
679 | |||
680 | /* Set touchscreen lines */ | ||
681 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_XSIZE, | ||
682 | pdata->x_line); | ||
683 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_YSIZE, | ||
684 | pdata->y_line); | ||
685 | |||
686 | /* Set touchscreen orient */ | ||
687 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_ORIENT, | ||
688 | pdata->orient); | ||
689 | |||
690 | /* Set touchscreen burst length */ | ||
691 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
692 | MXT_TOUCH_BLEN, pdata->blen); | ||
693 | |||
694 | /* Set touchscreen threshold */ | ||
695 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
696 | MXT_TOUCH_TCHTHR, pdata->threshold); | ||
697 | |||
698 | /* Set touchscreen resolution */ | ||
699 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
700 | MXT_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff); | ||
701 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
702 | MXT_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8); | ||
703 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
704 | MXT_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff); | ||
705 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
706 | MXT_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8); | ||
707 | |||
708 | /* Set touchscreen voltage */ | ||
709 | if (pdata->voltage) { | ||
710 | if (pdata->voltage < MXT_VOLTAGE_DEFAULT) { | ||
711 | voltage = (MXT_VOLTAGE_DEFAULT - pdata->voltage) / | ||
712 | MXT_VOLTAGE_STEP; | ||
713 | voltage = 0xff - voltage + 1; | ||
714 | } else | ||
715 | voltage = (pdata->voltage - MXT_VOLTAGE_DEFAULT) / | ||
716 | MXT_VOLTAGE_STEP; | ||
717 | |||
718 | mxt_write_object(data, MXT_SPT_CTECONFIG, | ||
719 | MXT_CTE_VOLTAGE, voltage); | ||
720 | } | ||
721 | } | ||
722 | |||
723 | static int mxt_get_info(struct mxt_data *data) | ||
724 | { | ||
725 | struct i2c_client *client = data->client; | ||
726 | struct mxt_info *info = &data->info; | ||
727 | int error; | ||
728 | u8 val; | ||
729 | |||
730 | error = mxt_read_reg(client, MXT_FAMILY_ID, &val); | ||
731 | if (error) | ||
732 | return error; | ||
733 | info->family_id = val; | ||
734 | |||
735 | error = mxt_read_reg(client, MXT_VARIANT_ID, &val); | ||
736 | if (error) | ||
737 | return error; | ||
738 | info->variant_id = val; | ||
739 | |||
740 | error = mxt_read_reg(client, MXT_VERSION, &val); | ||
741 | if (error) | ||
742 | return error; | ||
743 | info->version = val; | ||
744 | |||
745 | error = mxt_read_reg(client, MXT_BUILD, &val); | ||
746 | if (error) | ||
747 | return error; | ||
748 | info->build = val; | ||
749 | |||
750 | error = mxt_read_reg(client, MXT_OBJECT_NUM, &val); | ||
751 | if (error) | ||
752 | return error; | ||
753 | info->object_num = val; | ||
754 | |||
755 | return 0; | ||
756 | } | ||
757 | |||
758 | static int mxt_get_object_table(struct mxt_data *data) | ||
759 | { | ||
760 | int error; | ||
761 | int i; | ||
762 | u16 reg; | ||
763 | u8 reportid = 0; | ||
764 | u8 buf[MXT_OBJECT_SIZE]; | ||
765 | |||
766 | for (i = 0; i < data->info.object_num; i++) { | ||
767 | struct mxt_object *object = data->object_table + i; | ||
768 | |||
769 | reg = MXT_OBJECT_START + MXT_OBJECT_SIZE * i; | ||
770 | error = mxt_read_object_table(data->client, reg, buf); | ||
771 | if (error) | ||
772 | return error; | ||
773 | |||
774 | object->type = buf[0]; | ||
775 | object->start_address = (buf[2] << 8) | buf[1]; | ||
776 | object->size = buf[3]; | ||
777 | object->instances = buf[4]; | ||
778 | object->num_report_ids = buf[5]; | ||
779 | |||
780 | if (object->num_report_ids) { | ||
781 | reportid += object->num_report_ids * | ||
782 | (object->instances + 1); | ||
783 | object->max_reportid = reportid; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static int mxt_initialize(struct mxt_data *data) | ||
791 | { | ||
792 | struct i2c_client *client = data->client; | ||
793 | struct mxt_info *info = &data->info; | ||
794 | int error; | ||
795 | u8 val; | ||
796 | |||
797 | error = mxt_get_info(data); | ||
798 | if (error) | ||
799 | return error; | ||
800 | |||
801 | data->object_table = kcalloc(info->object_num, | ||
802 | sizeof(struct mxt_object), | ||
803 | GFP_KERNEL); | ||
804 | if (!data->object_table) { | ||
805 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
806 | return -ENOMEM; | ||
807 | } | ||
808 | |||
809 | /* Get object table information */ | ||
810 | error = mxt_get_object_table(data); | ||
811 | if (error) | ||
812 | return error; | ||
813 | |||
814 | /* Check register init values */ | ||
815 | error = mxt_check_reg_init(data); | ||
816 | if (error) | ||
817 | return error; | ||
818 | |||
819 | mxt_handle_pdata(data); | ||
820 | |||
821 | /* Backup to memory */ | ||
822 | mxt_write_object(data, MXT_GEN_COMMAND, | ||
823 | MXT_COMMAND_BACKUPNV, | ||
824 | MXT_BACKUP_VALUE); | ||
825 | msleep(MXT_BACKUP_TIME); | ||
826 | |||
827 | /* Soft reset */ | ||
828 | mxt_write_object(data, MXT_GEN_COMMAND, | ||
829 | MXT_COMMAND_RESET, 1); | ||
830 | msleep(MXT_RESET_TIME); | ||
831 | |||
832 | /* Update matrix size at info struct */ | ||
833 | error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val); | ||
834 | if (error) | ||
835 | return error; | ||
836 | info->matrix_xsize = val; | ||
837 | |||
838 | error = mxt_read_reg(client, MXT_MATRIX_Y_SIZE, &val); | ||
839 | if (error) | ||
840 | return error; | ||
841 | info->matrix_ysize = val; | ||
842 | |||
843 | dev_info(&client->dev, | ||
844 | "Family ID: %d Variant ID: %d Version: %d Build: %d\n", | ||
845 | info->family_id, info->variant_id, info->version, | ||
846 | info->build); | ||
847 | |||
848 | dev_info(&client->dev, | ||
849 | "Matrix X Size: %d Matrix Y Size: %d Object Num: %d\n", | ||
850 | info->matrix_xsize, info->matrix_ysize, | ||
851 | info->object_num); | ||
852 | |||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | static void mxt_calc_resolution(struct mxt_data *data) | ||
857 | { | ||
858 | unsigned int max_x = data->pdata->x_size - 1; | ||
859 | unsigned int max_y = data->pdata->y_size - 1; | ||
860 | |||
861 | if (data->pdata->orient & MXT_XY_SWITCH) { | ||
862 | data->max_x = max_y; | ||
863 | data->max_y = max_x; | ||
864 | } else { | ||
865 | data->max_x = max_x; | ||
866 | data->max_y = max_y; | ||
867 | } | ||
868 | } | ||
869 | |||
870 | static ssize_t mxt_object_show(struct device *dev, | ||
871 | struct device_attribute *attr, char *buf) | ||
872 | { | ||
873 | struct mxt_data *data = dev_get_drvdata(dev); | ||
874 | struct mxt_object *object; | ||
875 | int count = 0; | ||
876 | int i, j; | ||
877 | int error; | ||
878 | u8 val; | ||
879 | |||
880 | for (i = 0; i < data->info.object_num; i++) { | ||
881 | object = data->object_table + i; | ||
882 | |||
883 | count += sprintf(buf + count, | ||
884 | "Object Table Element %d(Type %d)\n", | ||
885 | i + 1, object->type); | ||
886 | |||
887 | if (!mxt_object_readable(object->type)) { | ||
888 | count += sprintf(buf + count, "\n"); | ||
889 | continue; | ||
890 | } | ||
891 | |||
892 | for (j = 0; j < object->size + 1; j++) { | ||
893 | error = mxt_read_object(data, | ||
894 | object->type, j, &val); | ||
895 | if (error) | ||
896 | return error; | ||
897 | |||
898 | count += sprintf(buf + count, | ||
899 | " Byte %d: 0x%x (%d)\n", j, val, val); | ||
900 | } | ||
901 | |||
902 | count += sprintf(buf + count, "\n"); | ||
903 | } | ||
904 | |||
905 | return count; | ||
906 | } | ||
907 | |||
908 | static int mxt_load_fw(struct device *dev, const char *fn) | ||
909 | { | ||
910 | struct mxt_data *data = dev_get_drvdata(dev); | ||
911 | struct i2c_client *client = data->client; | ||
912 | const struct firmware *fw = NULL; | ||
913 | unsigned int frame_size; | ||
914 | unsigned int pos = 0; | ||
915 | int ret; | ||
916 | |||
917 | ret = request_firmware(&fw, fn, dev); | ||
918 | if (ret) { | ||
919 | dev_err(dev, "Unable to open firmware %s\n", fn); | ||
920 | return ret; | ||
921 | } | ||
922 | |||
923 | /* Change to the bootloader mode */ | ||
924 | mxt_write_object(data, MXT_GEN_COMMAND, | ||
925 | MXT_COMMAND_RESET, MXT_BOOT_VALUE); | ||
926 | msleep(MXT_RESET_TIME); | ||
927 | |||
928 | /* Change to slave address of bootloader */ | ||
929 | if (client->addr == MXT_APP_LOW) | ||
930 | client->addr = MXT_BOOT_LOW; | ||
931 | else | ||
932 | client->addr = MXT_BOOT_HIGH; | ||
933 | |||
934 | ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD); | ||
935 | if (ret) | ||
936 | goto out; | ||
937 | |||
938 | /* Unlock bootloader */ | ||
939 | mxt_unlock_bootloader(client); | ||
940 | |||
941 | while (pos < fw->size) { | ||
942 | ret = mxt_check_bootloader(client, | ||
943 | MXT_WAITING_FRAME_DATA); | ||
944 | if (ret) | ||
945 | goto out; | ||
946 | |||
947 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); | ||
948 | |||
949 | /* We should add 2 at frame size as the the firmware data is not | ||
950 | * included the CRC bytes. | ||
951 | */ | ||
952 | frame_size += 2; | ||
953 | |||
954 | /* Write one frame to device */ | ||
955 | mxt_fw_write(client, fw->data + pos, frame_size); | ||
956 | |||
957 | ret = mxt_check_bootloader(client, | ||
958 | MXT_FRAME_CRC_PASS); | ||
959 | if (ret) | ||
960 | goto out; | ||
961 | |||
962 | pos += frame_size; | ||
963 | |||
964 | dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); | ||
965 | } | ||
966 | |||
967 | out: | ||
968 | release_firmware(fw); | ||
969 | |||
970 | /* Change to slave address of application */ | ||
971 | if (client->addr == MXT_BOOT_LOW) | ||
972 | client->addr = MXT_APP_LOW; | ||
973 | else | ||
974 | client->addr = MXT_APP_HIGH; | ||
975 | |||
976 | return ret; | ||
977 | } | ||
978 | |||
979 | static ssize_t mxt_update_fw_store(struct device *dev, | ||
980 | struct device_attribute *attr, | ||
981 | const char *buf, size_t count) | ||
982 | { | ||
983 | struct mxt_data *data = dev_get_drvdata(dev); | ||
984 | int error; | ||
985 | |||
986 | disable_irq(data->irq); | ||
987 | |||
988 | error = mxt_load_fw(dev, MXT_FW_NAME); | ||
989 | if (error) { | ||
990 | dev_err(dev, "The firmware update failed(%d)\n", error); | ||
991 | count = error; | ||
992 | } else { | ||
993 | dev_dbg(dev, "The firmware update succeeded\n"); | ||
994 | |||
995 | /* Wait for reset */ | ||
996 | msleep(MXT_FWRESET_TIME); | ||
997 | |||
998 | kfree(data->object_table); | ||
999 | data->object_table = NULL; | ||
1000 | |||
1001 | mxt_initialize(data); | ||
1002 | } | ||
1003 | |||
1004 | enable_irq(data->irq); | ||
1005 | |||
1006 | error = mxt_make_highchg(data); | ||
1007 | if (error) | ||
1008 | return error; | ||
1009 | |||
1010 | return count; | ||
1011 | } | ||
1012 | |||
1013 | static DEVICE_ATTR(object, 0444, mxt_object_show, NULL); | ||
1014 | static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store); | ||
1015 | |||
1016 | static struct attribute *mxt_attrs[] = { | ||
1017 | &dev_attr_object.attr, | ||
1018 | &dev_attr_update_fw.attr, | ||
1019 | NULL | ||
1020 | }; | ||
1021 | |||
1022 | static const struct attribute_group mxt_attr_group = { | ||
1023 | .attrs = mxt_attrs, | ||
1024 | }; | ||
1025 | |||
1026 | static void mxt_start(struct mxt_data *data) | ||
1027 | { | ||
1028 | /* Touch enable */ | ||
1029 | mxt_write_object(data, | ||
1030 | MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0x83); | ||
1031 | } | ||
1032 | |||
1033 | static void mxt_stop(struct mxt_data *data) | ||
1034 | { | ||
1035 | /* Touch disable */ | ||
1036 | mxt_write_object(data, | ||
1037 | MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0); | ||
1038 | } | ||
1039 | |||
1040 | static int mxt_input_open(struct input_dev *dev) | ||
1041 | { | ||
1042 | struct mxt_data *data = input_get_drvdata(dev); | ||
1043 | |||
1044 | mxt_start(data); | ||
1045 | |||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | static void mxt_input_close(struct input_dev *dev) | ||
1050 | { | ||
1051 | struct mxt_data *data = input_get_drvdata(dev); | ||
1052 | |||
1053 | mxt_stop(data); | ||
1054 | } | ||
1055 | |||
1056 | static int __devinit mxt_probe(struct i2c_client *client, | ||
1057 | const struct i2c_device_id *id) | ||
1058 | { | ||
1059 | const struct mxt_platform_data *pdata = client->dev.platform_data; | ||
1060 | struct mxt_data *data; | ||
1061 | struct input_dev *input_dev; | ||
1062 | int error; | ||
1063 | |||
1064 | if (!pdata) | ||
1065 | return -EINVAL; | ||
1066 | |||
1067 | data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL); | ||
1068 | input_dev = input_allocate_device(); | ||
1069 | if (!data || !input_dev) { | ||
1070 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
1071 | error = -ENOMEM; | ||
1072 | goto err_free_mem; | ||
1073 | } | ||
1074 | |||
1075 | input_dev->name = "Atmel maXTouch Touchscreen"; | ||
1076 | input_dev->id.bustype = BUS_I2C; | ||
1077 | input_dev->dev.parent = &client->dev; | ||
1078 | input_dev->open = mxt_input_open; | ||
1079 | input_dev->close = mxt_input_close; | ||
1080 | |||
1081 | data->client = client; | ||
1082 | data->input_dev = input_dev; | ||
1083 | data->pdata = pdata; | ||
1084 | data->irq = client->irq; | ||
1085 | |||
1086 | mxt_calc_resolution(data); | ||
1087 | |||
1088 | __set_bit(EV_ABS, input_dev->evbit); | ||
1089 | __set_bit(EV_KEY, input_dev->evbit); | ||
1090 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1091 | |||
1092 | /* For single touch */ | ||
1093 | input_set_abs_params(input_dev, ABS_X, | ||
1094 | 0, data->max_x, 0, 0); | ||
1095 | input_set_abs_params(input_dev, ABS_Y, | ||
1096 | 0, data->max_y, 0, 0); | ||
1097 | |||
1098 | /* For multi touch */ | ||
1099 | input_mt_init_slots(input_dev, MXT_MAX_FINGER); | ||
1100 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
1101 | 0, MXT_MAX_AREA, 0, 0); | ||
1102 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1103 | 0, data->max_x, 0, 0); | ||
1104 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1105 | 0, data->max_y, 0, 0); | ||
1106 | |||
1107 | input_set_drvdata(input_dev, data); | ||
1108 | i2c_set_clientdata(client, data); | ||
1109 | |||
1110 | error = mxt_initialize(data); | ||
1111 | if (error) | ||
1112 | goto err_free_object; | ||
1113 | |||
1114 | error = request_threaded_irq(client->irq, NULL, mxt_interrupt, | ||
1115 | pdata->irqflags, client->dev.driver->name, data); | ||
1116 | if (error) { | ||
1117 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
1118 | goto err_free_object; | ||
1119 | } | ||
1120 | |||
1121 | error = mxt_make_highchg(data); | ||
1122 | if (error) | ||
1123 | goto err_free_irq; | ||
1124 | |||
1125 | error = input_register_device(input_dev); | ||
1126 | if (error) | ||
1127 | goto err_free_irq; | ||
1128 | |||
1129 | error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); | ||
1130 | if (error) | ||
1131 | goto err_unregister_device; | ||
1132 | |||
1133 | return 0; | ||
1134 | |||
1135 | err_unregister_device: | ||
1136 | input_unregister_device(input_dev); | ||
1137 | input_dev = NULL; | ||
1138 | err_free_irq: | ||
1139 | free_irq(client->irq, data); | ||
1140 | err_free_object: | ||
1141 | kfree(data->object_table); | ||
1142 | err_free_mem: | ||
1143 | input_free_device(input_dev); | ||
1144 | kfree(data); | ||
1145 | return error; | ||
1146 | } | ||
1147 | |||
1148 | static int __devexit mxt_remove(struct i2c_client *client) | ||
1149 | { | ||
1150 | struct mxt_data *data = i2c_get_clientdata(client); | ||
1151 | |||
1152 | sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); | ||
1153 | free_irq(data->irq, data); | ||
1154 | input_unregister_device(data->input_dev); | ||
1155 | kfree(data->object_table); | ||
1156 | kfree(data); | ||
1157 | |||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1161 | #ifdef CONFIG_PM | ||
1162 | static int mxt_suspend(struct device *dev) | ||
1163 | { | ||
1164 | struct i2c_client *client = to_i2c_client(dev); | ||
1165 | struct mxt_data *data = i2c_get_clientdata(client); | ||
1166 | struct input_dev *input_dev = data->input_dev; | ||
1167 | |||
1168 | mutex_lock(&input_dev->mutex); | ||
1169 | |||
1170 | if (input_dev->users) | ||
1171 | mxt_stop(data); | ||
1172 | |||
1173 | mutex_unlock(&input_dev->mutex); | ||
1174 | |||
1175 | return 0; | ||
1176 | } | ||
1177 | |||
1178 | static int mxt_resume(struct device *dev) | ||
1179 | { | ||
1180 | struct i2c_client *client = to_i2c_client(dev); | ||
1181 | struct mxt_data *data = i2c_get_clientdata(client); | ||
1182 | struct input_dev *input_dev = data->input_dev; | ||
1183 | |||
1184 | /* Soft reset */ | ||
1185 | mxt_write_object(data, MXT_GEN_COMMAND, | ||
1186 | MXT_COMMAND_RESET, 1); | ||
1187 | |||
1188 | msleep(MXT_RESET_TIME); | ||
1189 | |||
1190 | mutex_lock(&input_dev->mutex); | ||
1191 | |||
1192 | if (input_dev->users) | ||
1193 | mxt_start(data); | ||
1194 | |||
1195 | mutex_unlock(&input_dev->mutex); | ||
1196 | |||
1197 | return 0; | ||
1198 | } | ||
1199 | |||
1200 | static const struct dev_pm_ops mxt_pm_ops = { | ||
1201 | .suspend = mxt_suspend, | ||
1202 | .resume = mxt_resume, | ||
1203 | }; | ||
1204 | #endif | ||
1205 | |||
1206 | static const struct i2c_device_id mxt_id[] = { | ||
1207 | { "qt602240_ts", 0 }, | ||
1208 | { "atmel_mxt_ts", 0 }, | ||
1209 | { "mXT224", 0 }, | ||
1210 | { } | ||
1211 | }; | ||
1212 | MODULE_DEVICE_TABLE(i2c, mxt_id); | ||
1213 | |||
1214 | static struct i2c_driver mxt_driver = { | ||
1215 | .driver = { | ||
1216 | .name = "atmel_mxt_ts", | ||
1217 | .owner = THIS_MODULE, | ||
1218 | #ifdef CONFIG_PM | ||
1219 | .pm = &mxt_pm_ops, | ||
1220 | #endif | ||
1221 | }, | ||
1222 | .probe = mxt_probe, | ||
1223 | .remove = __devexit_p(mxt_remove), | ||
1224 | .id_table = mxt_id, | ||
1225 | }; | ||
1226 | |||
1227 | static int __init mxt_init(void) | ||
1228 | { | ||
1229 | return i2c_add_driver(&mxt_driver); | ||
1230 | } | ||
1231 | |||
1232 | static void __exit mxt_exit(void) | ||
1233 | { | ||
1234 | i2c_del_driver(&mxt_driver); | ||
1235 | } | ||
1236 | |||
1237 | module_init(mxt_init); | ||
1238 | module_exit(mxt_exit); | ||
1239 | |||
1240 | /* Module information */ | ||
1241 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
1242 | MODULE_DESCRIPTION("Atmel maXTouch Touchscreen driver"); | ||
1243 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c index 3d9b5166ebe9..432c69be6ac6 100644 --- a/drivers/input/touchscreen/atmel_tsadcc.c +++ b/drivers/input/touchscreen/atmel_tsadcc.c | |||
@@ -317,7 +317,7 @@ err_unmap_regs: | |||
317 | err_release_mem: | 317 | err_release_mem: |
318 | release_mem_region(res->start, resource_size(res)); | 318 | release_mem_region(res->start, resource_size(res)); |
319 | err_free_dev: | 319 | err_free_dev: |
320 | input_free_device(ts_dev->input); | 320 | input_free_device(input_dev); |
321 | err_free_mem: | 321 | err_free_mem: |
322 | kfree(ts_dev); | 322 | kfree(ts_dev); |
323 | return err; | 323 | return err; |
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c new file mode 100644 index 000000000000..1507ce108d5b --- /dev/null +++ b/drivers/input/touchscreen/bu21013_ts.c | |||
@@ -0,0 +1,681 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson | ||
4 | * License terms:GNU General Public License (GPL) version 2 | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/workqueue.h> | ||
12 | #include <linux/input.h> | ||
13 | #include <linux/input/bu21013.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/regulator/consumer.h> | ||
16 | |||
17 | #define PEN_DOWN_INTR 0 | ||
18 | #define MAX_FINGERS 2 | ||
19 | #define RESET_DELAY 30 | ||
20 | #define PENUP_TIMEOUT (10) | ||
21 | #define DELTA_MIN 16 | ||
22 | #define MASK_BITS 0x03 | ||
23 | #define SHIFT_8 8 | ||
24 | #define SHIFT_2 2 | ||
25 | #define LENGTH_OF_BUFFER 11 | ||
26 | #define I2C_RETRY_COUNT 5 | ||
27 | |||
28 | #define BU21013_SENSORS_BTN_0_7_REG 0x70 | ||
29 | #define BU21013_SENSORS_BTN_8_15_REG 0x71 | ||
30 | #define BU21013_SENSORS_BTN_16_23_REG 0x72 | ||
31 | #define BU21013_X1_POS_MSB_REG 0x73 | ||
32 | #define BU21013_X1_POS_LSB_REG 0x74 | ||
33 | #define BU21013_Y1_POS_MSB_REG 0x75 | ||
34 | #define BU21013_Y1_POS_LSB_REG 0x76 | ||
35 | #define BU21013_X2_POS_MSB_REG 0x77 | ||
36 | #define BU21013_X2_POS_LSB_REG 0x78 | ||
37 | #define BU21013_Y2_POS_MSB_REG 0x79 | ||
38 | #define BU21013_Y2_POS_LSB_REG 0x7A | ||
39 | #define BU21013_INT_CLR_REG 0xE8 | ||
40 | #define BU21013_INT_MODE_REG 0xE9 | ||
41 | #define BU21013_GAIN_REG 0xEA | ||
42 | #define BU21013_OFFSET_MODE_REG 0xEB | ||
43 | #define BU21013_XY_EDGE_REG 0xEC | ||
44 | #define BU21013_RESET_REG 0xED | ||
45 | #define BU21013_CALIB_REG 0xEE | ||
46 | #define BU21013_DONE_REG 0xEF | ||
47 | #define BU21013_SENSOR_0_7_REG 0xF0 | ||
48 | #define BU21013_SENSOR_8_15_REG 0xF1 | ||
49 | #define BU21013_SENSOR_16_23_REG 0xF2 | ||
50 | #define BU21013_POS_MODE1_REG 0xF3 | ||
51 | #define BU21013_POS_MODE2_REG 0xF4 | ||
52 | #define BU21013_CLK_MODE_REG 0xF5 | ||
53 | #define BU21013_IDLE_REG 0xFA | ||
54 | #define BU21013_FILTER_REG 0xFB | ||
55 | #define BU21013_TH_ON_REG 0xFC | ||
56 | #define BU21013_TH_OFF_REG 0xFD | ||
57 | |||
58 | |||
59 | #define BU21013_RESET_ENABLE 0x01 | ||
60 | |||
61 | #define BU21013_SENSORS_EN_0_7 0x3F | ||
62 | #define BU21013_SENSORS_EN_8_15 0xFC | ||
63 | #define BU21013_SENSORS_EN_16_23 0x1F | ||
64 | |||
65 | #define BU21013_POS_MODE1_0 0x02 | ||
66 | #define BU21013_POS_MODE1_1 0x04 | ||
67 | #define BU21013_POS_MODE1_2 0x08 | ||
68 | |||
69 | #define BU21013_POS_MODE2_ZERO 0x01 | ||
70 | #define BU21013_POS_MODE2_AVG1 0x02 | ||
71 | #define BU21013_POS_MODE2_AVG2 0x04 | ||
72 | #define BU21013_POS_MODE2_EN_XY 0x08 | ||
73 | #define BU21013_POS_MODE2_EN_RAW 0x10 | ||
74 | #define BU21013_POS_MODE2_MULTI 0x80 | ||
75 | |||
76 | #define BU21013_CLK_MODE_DIV 0x01 | ||
77 | #define BU21013_CLK_MODE_EXT 0x02 | ||
78 | #define BU21013_CLK_MODE_CALIB 0x80 | ||
79 | |||
80 | #define BU21013_IDLET_0 0x01 | ||
81 | #define BU21013_IDLET_1 0x02 | ||
82 | #define BU21013_IDLET_2 0x04 | ||
83 | #define BU21013_IDLET_3 0x08 | ||
84 | #define BU21013_IDLE_INTERMIT_EN 0x10 | ||
85 | |||
86 | #define BU21013_DELTA_0_6 0x7F | ||
87 | #define BU21013_FILTER_EN 0x80 | ||
88 | |||
89 | #define BU21013_INT_MODE_LEVEL 0x00 | ||
90 | #define BU21013_INT_MODE_EDGE 0x01 | ||
91 | |||
92 | #define BU21013_GAIN_0 0x01 | ||
93 | #define BU21013_GAIN_1 0x02 | ||
94 | #define BU21013_GAIN_2 0x04 | ||
95 | |||
96 | #define BU21013_OFFSET_MODE_DEFAULT 0x00 | ||
97 | #define BU21013_OFFSET_MODE_MOVE 0x01 | ||
98 | #define BU21013_OFFSET_MODE_DISABLE 0x02 | ||
99 | |||
100 | #define BU21013_TH_ON_0 0x01 | ||
101 | #define BU21013_TH_ON_1 0x02 | ||
102 | #define BU21013_TH_ON_2 0x04 | ||
103 | #define BU21013_TH_ON_3 0x08 | ||
104 | #define BU21013_TH_ON_4 0x10 | ||
105 | #define BU21013_TH_ON_5 0x20 | ||
106 | #define BU21013_TH_ON_6 0x40 | ||
107 | #define BU21013_TH_ON_7 0x80 | ||
108 | #define BU21013_TH_ON_MAX 0xFF | ||
109 | |||
110 | #define BU21013_TH_OFF_0 0x01 | ||
111 | #define BU21013_TH_OFF_1 0x02 | ||
112 | #define BU21013_TH_OFF_2 0x04 | ||
113 | #define BU21013_TH_OFF_3 0x08 | ||
114 | #define BU21013_TH_OFF_4 0x10 | ||
115 | #define BU21013_TH_OFF_5 0x20 | ||
116 | #define BU21013_TH_OFF_6 0x40 | ||
117 | #define BU21013_TH_OFF_7 0x80 | ||
118 | #define BU21013_TH_OFF_MAX 0xFF | ||
119 | |||
120 | #define BU21013_X_EDGE_0 0x01 | ||
121 | #define BU21013_X_EDGE_1 0x02 | ||
122 | #define BU21013_X_EDGE_2 0x04 | ||
123 | #define BU21013_X_EDGE_3 0x08 | ||
124 | #define BU21013_Y_EDGE_0 0x10 | ||
125 | #define BU21013_Y_EDGE_1 0x20 | ||
126 | #define BU21013_Y_EDGE_2 0x40 | ||
127 | #define BU21013_Y_EDGE_3 0x80 | ||
128 | |||
129 | #define BU21013_DONE 0x01 | ||
130 | #define BU21013_NUMBER_OF_X_SENSORS (6) | ||
131 | #define BU21013_NUMBER_OF_Y_SENSORS (11) | ||
132 | |||
133 | #define DRIVER_TP "bu21013_tp" | ||
134 | |||
135 | /** | ||
136 | * struct bu21013_ts_data - touch panel data structure | ||
137 | * @client: pointer to the i2c client | ||
138 | * @wait: variable to wait_queue_head_t structure | ||
139 | * @touch_stopped: touch stop flag | ||
140 | * @chip: pointer to the touch panel controller | ||
141 | * @in_dev: pointer to the input device structure | ||
142 | * @intr_pin: interrupt pin value | ||
143 | * @regulator: pointer to the Regulator used for touch screen | ||
144 | * | ||
145 | * Touch panel device data structure | ||
146 | */ | ||
147 | struct bu21013_ts_data { | ||
148 | struct i2c_client *client; | ||
149 | wait_queue_head_t wait; | ||
150 | bool touch_stopped; | ||
151 | const struct bu21013_platform_device *chip; | ||
152 | struct input_dev *in_dev; | ||
153 | unsigned int intr_pin; | ||
154 | struct regulator *regulator; | ||
155 | }; | ||
156 | |||
157 | /** | ||
158 | * bu21013_read_block_data(): read the touch co-ordinates | ||
159 | * @data: bu21013_ts_data structure pointer | ||
160 | * @buf: byte pointer | ||
161 | * | ||
162 | * Read the touch co-ordinates using i2c read block into buffer | ||
163 | * and returns integer. | ||
164 | */ | ||
165 | static int bu21013_read_block_data(struct bu21013_ts_data *data, u8 *buf) | ||
166 | { | ||
167 | int ret, i; | ||
168 | |||
169 | for (i = 0; i < I2C_RETRY_COUNT; i++) { | ||
170 | ret = i2c_smbus_read_i2c_block_data | ||
171 | (data->client, BU21013_SENSORS_BTN_0_7_REG, | ||
172 | LENGTH_OF_BUFFER, buf); | ||
173 | if (ret == LENGTH_OF_BUFFER) | ||
174 | return 0; | ||
175 | } | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * bu21013_do_touch_report(): Get the touch co-ordinates | ||
181 | * @data: bu21013_ts_data structure pointer | ||
182 | * | ||
183 | * Get the touch co-ordinates from touch sensor registers and writes | ||
184 | * into device structure and returns integer. | ||
185 | */ | ||
186 | static int bu21013_do_touch_report(struct bu21013_ts_data *data) | ||
187 | { | ||
188 | u8 buf[LENGTH_OF_BUFFER]; | ||
189 | unsigned int pos_x[2], pos_y[2]; | ||
190 | bool has_x_sensors, has_y_sensors; | ||
191 | int finger_down_count = 0; | ||
192 | int i; | ||
193 | |||
194 | if (data == NULL) | ||
195 | return -EINVAL; | ||
196 | |||
197 | if (bu21013_read_block_data(data, buf) < 0) | ||
198 | return -EINVAL; | ||
199 | |||
200 | has_x_sensors = hweight32(buf[0] & BU21013_SENSORS_EN_0_7); | ||
201 | has_y_sensors = hweight32(((buf[1] & BU21013_SENSORS_EN_8_15) | | ||
202 | ((buf[2] & BU21013_SENSORS_EN_16_23) << SHIFT_8)) >> SHIFT_2); | ||
203 | if (!has_x_sensors || !has_y_sensors) | ||
204 | return 0; | ||
205 | |||
206 | for (i = 0; i < MAX_FINGERS; i++) { | ||
207 | const u8 *p = &buf[4 * i + 3]; | ||
208 | unsigned int x = p[0] << SHIFT_2 | (p[1] & MASK_BITS); | ||
209 | unsigned int y = p[2] << SHIFT_2 | (p[3] & MASK_BITS); | ||
210 | if (x == 0 || y == 0) | ||
211 | continue; | ||
212 | pos_x[finger_down_count] = x; | ||
213 | pos_y[finger_down_count] = y; | ||
214 | finger_down_count++; | ||
215 | } | ||
216 | |||
217 | if (finger_down_count) { | ||
218 | if (finger_down_count == 2 && | ||
219 | (abs(pos_x[0] - pos_x[1]) < DELTA_MIN || | ||
220 | abs(pos_y[0] - pos_y[1]) < DELTA_MIN)) { | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | for (i = 0; i < finger_down_count; i++) { | ||
225 | if (data->chip->x_flip) | ||
226 | pos_x[i] = data->chip->touch_x_max - pos_x[i]; | ||
227 | if (data->chip->y_flip) | ||
228 | pos_y[i] = data->chip->touch_y_max - pos_y[i]; | ||
229 | |||
230 | input_report_abs(data->in_dev, | ||
231 | ABS_MT_POSITION_X, pos_x[i]); | ||
232 | input_report_abs(data->in_dev, | ||
233 | ABS_MT_POSITION_Y, pos_y[i]); | ||
234 | input_mt_sync(data->in_dev); | ||
235 | } | ||
236 | } else | ||
237 | input_mt_sync(data->in_dev); | ||
238 | |||
239 | input_sync(data->in_dev); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | /** | ||
244 | * bu21013_gpio_irq() - gpio thread function for touch interrupt | ||
245 | * @irq: irq value | ||
246 | * @device_data: void pointer | ||
247 | * | ||
248 | * This gpio thread function for touch interrupt | ||
249 | * and returns irqreturn_t. | ||
250 | */ | ||
251 | static irqreturn_t bu21013_gpio_irq(int irq, void *device_data) | ||
252 | { | ||
253 | struct bu21013_ts_data *data = device_data; | ||
254 | struct i2c_client *i2c = data->client; | ||
255 | int retval; | ||
256 | |||
257 | do { | ||
258 | retval = bu21013_do_touch_report(data); | ||
259 | if (retval < 0) { | ||
260 | dev_err(&i2c->dev, "bu21013_do_touch_report failed\n"); | ||
261 | return IRQ_NONE; | ||
262 | } | ||
263 | |||
264 | data->intr_pin = data->chip->irq_read_val(); | ||
265 | if (data->intr_pin == PEN_DOWN_INTR) | ||
266 | wait_event_timeout(data->wait, data->touch_stopped, | ||
267 | msecs_to_jiffies(2)); | ||
268 | } while (!data->intr_pin && !data->touch_stopped); | ||
269 | |||
270 | return IRQ_HANDLED; | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * bu21013_init_chip() - power on sequence for the bu21013 controller | ||
275 | * @data: device structure pointer | ||
276 | * | ||
277 | * This function is used to power on | ||
278 | * the bu21013 controller and returns integer. | ||
279 | */ | ||
280 | static int bu21013_init_chip(struct bu21013_ts_data *data) | ||
281 | { | ||
282 | int retval; | ||
283 | struct i2c_client *i2c = data->client; | ||
284 | |||
285 | retval = i2c_smbus_write_byte_data(i2c, BU21013_RESET_REG, | ||
286 | BU21013_RESET_ENABLE); | ||
287 | if (retval < 0) { | ||
288 | dev_err(&i2c->dev, "BU21013_RESET reg write failed\n"); | ||
289 | return retval; | ||
290 | } | ||
291 | msleep(RESET_DELAY); | ||
292 | |||
293 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_0_7_REG, | ||
294 | BU21013_SENSORS_EN_0_7); | ||
295 | if (retval < 0) { | ||
296 | dev_err(&i2c->dev, "BU21013_SENSOR_0_7 reg write failed\n"); | ||
297 | return retval; | ||
298 | } | ||
299 | |||
300 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_8_15_REG, | ||
301 | BU21013_SENSORS_EN_8_15); | ||
302 | if (retval < 0) { | ||
303 | dev_err(&i2c->dev, "BU21013_SENSOR_8_15 reg write failed\n"); | ||
304 | return retval; | ||
305 | } | ||
306 | |||
307 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_16_23_REG, | ||
308 | BU21013_SENSORS_EN_16_23); | ||
309 | if (retval < 0) { | ||
310 | dev_err(&i2c->dev, "BU21013_SENSOR_16_23 reg write failed\n"); | ||
311 | return retval; | ||
312 | } | ||
313 | |||
314 | retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE1_REG, | ||
315 | (BU21013_POS_MODE1_0 | BU21013_POS_MODE1_1)); | ||
316 | if (retval < 0) { | ||
317 | dev_err(&i2c->dev, "BU21013_POS_MODE1 reg write failed\n"); | ||
318 | return retval; | ||
319 | } | ||
320 | |||
321 | retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE2_REG, | ||
322 | (BU21013_POS_MODE2_ZERO | BU21013_POS_MODE2_AVG1 | | ||
323 | BU21013_POS_MODE2_AVG2 | BU21013_POS_MODE2_EN_RAW | | ||
324 | BU21013_POS_MODE2_MULTI)); | ||
325 | if (retval < 0) { | ||
326 | dev_err(&i2c->dev, "BU21013_POS_MODE2 reg write failed\n"); | ||
327 | return retval; | ||
328 | } | ||
329 | |||
330 | if (data->chip->ext_clk) | ||
331 | retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG, | ||
332 | (BU21013_CLK_MODE_EXT | BU21013_CLK_MODE_CALIB)); | ||
333 | else | ||
334 | retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG, | ||
335 | (BU21013_CLK_MODE_DIV | BU21013_CLK_MODE_CALIB)); | ||
336 | if (retval < 0) { | ||
337 | dev_err(&i2c->dev, "BU21013_CLK_MODE reg write failed\n"); | ||
338 | return retval; | ||
339 | } | ||
340 | |||
341 | retval = i2c_smbus_write_byte_data(i2c, BU21013_IDLE_REG, | ||
342 | (BU21013_IDLET_0 | BU21013_IDLE_INTERMIT_EN)); | ||
343 | if (retval < 0) { | ||
344 | dev_err(&i2c->dev, "BU21013_IDLE reg write failed\n"); | ||
345 | return retval; | ||
346 | } | ||
347 | |||
348 | retval = i2c_smbus_write_byte_data(i2c, BU21013_INT_MODE_REG, | ||
349 | BU21013_INT_MODE_LEVEL); | ||
350 | if (retval < 0) { | ||
351 | dev_err(&i2c->dev, "BU21013_INT_MODE reg write failed\n"); | ||
352 | return retval; | ||
353 | } | ||
354 | |||
355 | retval = i2c_smbus_write_byte_data(i2c, BU21013_FILTER_REG, | ||
356 | (BU21013_DELTA_0_6 | | ||
357 | BU21013_FILTER_EN)); | ||
358 | if (retval < 0) { | ||
359 | dev_err(&i2c->dev, "BU21013_FILTER reg write failed\n"); | ||
360 | return retval; | ||
361 | } | ||
362 | |||
363 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_ON_REG, | ||
364 | BU21013_TH_ON_5); | ||
365 | if (retval < 0) { | ||
366 | dev_err(&i2c->dev, "BU21013_TH_ON reg write failed\n"); | ||
367 | return retval; | ||
368 | } | ||
369 | |||
370 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG, | ||
371 | BU21013_TH_OFF_4 | BU21013_TH_OFF_3); | ||
372 | if (retval < 0) { | ||
373 | dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n"); | ||
374 | return retval; | ||
375 | } | ||
376 | |||
377 | retval = i2c_smbus_write_byte_data(i2c, BU21013_GAIN_REG, | ||
378 | (BU21013_GAIN_0 | BU21013_GAIN_1)); | ||
379 | if (retval < 0) { | ||
380 | dev_err(&i2c->dev, "BU21013_GAIN reg write failed\n"); | ||
381 | return retval; | ||
382 | } | ||
383 | |||
384 | retval = i2c_smbus_write_byte_data(i2c, BU21013_OFFSET_MODE_REG, | ||
385 | BU21013_OFFSET_MODE_DEFAULT); | ||
386 | if (retval < 0) { | ||
387 | dev_err(&i2c->dev, "BU21013_OFFSET_MODE reg write failed\n"); | ||
388 | return retval; | ||
389 | } | ||
390 | |||
391 | retval = i2c_smbus_write_byte_data(i2c, BU21013_XY_EDGE_REG, | ||
392 | (BU21013_X_EDGE_0 | BU21013_X_EDGE_2 | | ||
393 | BU21013_Y_EDGE_1 | BU21013_Y_EDGE_3)); | ||
394 | if (retval < 0) { | ||
395 | dev_err(&i2c->dev, "BU21013_XY_EDGE reg write failed\n"); | ||
396 | return retval; | ||
397 | } | ||
398 | |||
399 | retval = i2c_smbus_write_byte_data(i2c, BU21013_DONE_REG, | ||
400 | BU21013_DONE); | ||
401 | if (retval < 0) { | ||
402 | dev_err(&i2c->dev, "BU21013_REG_DONE reg write failed\n"); | ||
403 | return retval; | ||
404 | } | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | /** | ||
410 | * bu21013_free_irq() - frees IRQ registered for touchscreen | ||
411 | * @bu21013_data: device structure pointer | ||
412 | * | ||
413 | * This function signals interrupt thread to stop processing and | ||
414 | * frees interrupt. | ||
415 | */ | ||
416 | static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data) | ||
417 | { | ||
418 | bu21013_data->touch_stopped = true; | ||
419 | wake_up(&bu21013_data->wait); | ||
420 | free_irq(bu21013_data->chip->irq, bu21013_data); | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * bu21013_probe() - initializes the i2c-client touchscreen driver | ||
425 | * @client: i2c client structure pointer | ||
426 | * @id: i2c device id pointer | ||
427 | * | ||
428 | * This function used to initializes the i2c-client touchscreen | ||
429 | * driver and returns integer. | ||
430 | */ | ||
431 | static int __devinit bu21013_probe(struct i2c_client *client, | ||
432 | const struct i2c_device_id *id) | ||
433 | { | ||
434 | struct bu21013_ts_data *bu21013_data; | ||
435 | struct input_dev *in_dev; | ||
436 | const struct bu21013_platform_device *pdata = | ||
437 | client->dev.platform_data; | ||
438 | int error; | ||
439 | |||
440 | if (!i2c_check_functionality(client->adapter, | ||
441 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
442 | dev_err(&client->dev, "i2c smbus byte data not supported\n"); | ||
443 | return -EIO; | ||
444 | } | ||
445 | |||
446 | if (!pdata) { | ||
447 | dev_err(&client->dev, "platform data not defined\n"); | ||
448 | return -EINVAL; | ||
449 | } | ||
450 | |||
451 | bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL); | ||
452 | in_dev = input_allocate_device(); | ||
453 | if (!bu21013_data || !in_dev) { | ||
454 | dev_err(&client->dev, "device memory alloc failed\n"); | ||
455 | error = -ENOMEM; | ||
456 | goto err_free_mem; | ||
457 | } | ||
458 | |||
459 | bu21013_data->in_dev = in_dev; | ||
460 | bu21013_data->chip = pdata; | ||
461 | bu21013_data->client = client; | ||
462 | |||
463 | bu21013_data->regulator = regulator_get(&client->dev, "V-TOUCH"); | ||
464 | if (IS_ERR(bu21013_data->regulator)) { | ||
465 | dev_err(&client->dev, "regulator_get failed\n"); | ||
466 | error = PTR_ERR(bu21013_data->regulator); | ||
467 | goto err_free_mem; | ||
468 | } | ||
469 | |||
470 | error = regulator_enable(bu21013_data->regulator); | ||
471 | if (error < 0) { | ||
472 | dev_err(&client->dev, "regulator enable failed\n"); | ||
473 | goto err_put_regulator; | ||
474 | } | ||
475 | |||
476 | bu21013_data->touch_stopped = false; | ||
477 | init_waitqueue_head(&bu21013_data->wait); | ||
478 | |||
479 | /* configure the gpio pins */ | ||
480 | if (pdata->cs_en) { | ||
481 | error = pdata->cs_en(pdata->cs_pin); | ||
482 | if (error < 0) { | ||
483 | dev_err(&client->dev, "chip init failed\n"); | ||
484 | goto err_disable_regulator; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | /* configure the touch panel controller */ | ||
489 | error = bu21013_init_chip(bu21013_data); | ||
490 | if (error) { | ||
491 | dev_err(&client->dev, "error in bu21013 config\n"); | ||
492 | goto err_cs_disable; | ||
493 | } | ||
494 | |||
495 | /* register the device to input subsystem */ | ||
496 | in_dev->name = DRIVER_TP; | ||
497 | in_dev->id.bustype = BUS_I2C; | ||
498 | in_dev->dev.parent = &client->dev; | ||
499 | |||
500 | __set_bit(EV_SYN, in_dev->evbit); | ||
501 | __set_bit(EV_KEY, in_dev->evbit); | ||
502 | __set_bit(EV_ABS, in_dev->evbit); | ||
503 | |||
504 | input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0, | ||
505 | pdata->touch_x_max, 0, 0); | ||
506 | input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0, | ||
507 | pdata->touch_y_max, 0, 0); | ||
508 | input_set_drvdata(in_dev, bu21013_data); | ||
509 | |||
510 | error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq, | ||
511 | IRQF_TRIGGER_FALLING | IRQF_SHARED, | ||
512 | DRIVER_TP, bu21013_data); | ||
513 | if (error) { | ||
514 | dev_err(&client->dev, "request irq %d failed\n", pdata->irq); | ||
515 | goto err_cs_disable; | ||
516 | } | ||
517 | |||
518 | error = input_register_device(in_dev); | ||
519 | if (error) { | ||
520 | dev_err(&client->dev, "failed to register input device\n"); | ||
521 | goto err_free_irq; | ||
522 | } | ||
523 | |||
524 | device_init_wakeup(&client->dev, pdata->wakeup); | ||
525 | i2c_set_clientdata(client, bu21013_data); | ||
526 | |||
527 | return 0; | ||
528 | |||
529 | err_free_irq: | ||
530 | bu21013_free_irq(bu21013_data); | ||
531 | err_cs_disable: | ||
532 | pdata->cs_dis(pdata->cs_pin); | ||
533 | err_disable_regulator: | ||
534 | regulator_disable(bu21013_data->regulator); | ||
535 | err_put_regulator: | ||
536 | regulator_put(bu21013_data->regulator); | ||
537 | err_free_mem: | ||
538 | input_free_device(in_dev); | ||
539 | kfree(bu21013_data); | ||
540 | |||
541 | return error; | ||
542 | } | ||
543 | /** | ||
544 | * bu21013_remove() - removes the i2c-client touchscreen driver | ||
545 | * @client: i2c client structure pointer | ||
546 | * | ||
547 | * This function uses to remove the i2c-client | ||
548 | * touchscreen driver and returns integer. | ||
549 | */ | ||
550 | static int __devexit bu21013_remove(struct i2c_client *client) | ||
551 | { | ||
552 | struct bu21013_ts_data *bu21013_data = i2c_get_clientdata(client); | ||
553 | |||
554 | bu21013_free_irq(bu21013_data); | ||
555 | |||
556 | bu21013_data->chip->cs_dis(bu21013_data->chip->cs_pin); | ||
557 | |||
558 | input_unregister_device(bu21013_data->in_dev); | ||
559 | |||
560 | regulator_disable(bu21013_data->regulator); | ||
561 | regulator_put(bu21013_data->regulator); | ||
562 | |||
563 | kfree(bu21013_data); | ||
564 | |||
565 | device_init_wakeup(&client->dev, false); | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | #ifdef CONFIG_PM | ||
571 | /** | ||
572 | * bu21013_suspend() - suspend the touch screen controller | ||
573 | * @dev: pointer to device structure | ||
574 | * | ||
575 | * This function is used to suspend the | ||
576 | * touch panel controller and returns integer | ||
577 | */ | ||
578 | static int bu21013_suspend(struct device *dev) | ||
579 | { | ||
580 | struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev); | ||
581 | struct i2c_client *client = bu21013_data->client; | ||
582 | |||
583 | bu21013_data->touch_stopped = true; | ||
584 | if (device_may_wakeup(&client->dev)) | ||
585 | enable_irq_wake(bu21013_data->chip->irq); | ||
586 | else | ||
587 | disable_irq(bu21013_data->chip->irq); | ||
588 | |||
589 | regulator_disable(bu21013_data->regulator); | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * bu21013_resume() - resume the touch screen controller | ||
596 | * @dev: pointer to device structure | ||
597 | * | ||
598 | * This function is used to resume the touch panel | ||
599 | * controller and returns integer. | ||
600 | */ | ||
601 | static int bu21013_resume(struct device *dev) | ||
602 | { | ||
603 | struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev); | ||
604 | struct i2c_client *client = bu21013_data->client; | ||
605 | int retval; | ||
606 | |||
607 | retval = regulator_enable(bu21013_data->regulator); | ||
608 | if (retval < 0) { | ||
609 | dev_err(&client->dev, "bu21013 regulator enable failed\n"); | ||
610 | return retval; | ||
611 | } | ||
612 | |||
613 | retval = bu21013_init_chip(bu21013_data); | ||
614 | if (retval < 0) { | ||
615 | dev_err(&client->dev, "bu21013 controller config failed\n"); | ||
616 | return retval; | ||
617 | } | ||
618 | |||
619 | bu21013_data->touch_stopped = false; | ||
620 | |||
621 | if (device_may_wakeup(&client->dev)) | ||
622 | disable_irq_wake(bu21013_data->chip->irq); | ||
623 | else | ||
624 | enable_irq(bu21013_data->chip->irq); | ||
625 | |||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static const struct dev_pm_ops bu21013_dev_pm_ops = { | ||
630 | .suspend = bu21013_suspend, | ||
631 | .resume = bu21013_resume, | ||
632 | }; | ||
633 | #endif | ||
634 | |||
635 | static const struct i2c_device_id bu21013_id[] = { | ||
636 | { DRIVER_TP, 0 }, | ||
637 | { } | ||
638 | }; | ||
639 | MODULE_DEVICE_TABLE(i2c, bu21013_id); | ||
640 | |||
641 | static struct i2c_driver bu21013_driver = { | ||
642 | .driver = { | ||
643 | .name = DRIVER_TP, | ||
644 | .owner = THIS_MODULE, | ||
645 | #ifdef CONFIG_PM | ||
646 | .pm = &bu21013_dev_pm_ops, | ||
647 | #endif | ||
648 | }, | ||
649 | .probe = bu21013_probe, | ||
650 | .remove = __devexit_p(bu21013_remove), | ||
651 | .id_table = bu21013_id, | ||
652 | }; | ||
653 | |||
654 | /** | ||
655 | * bu21013_init() - initializes the bu21013 touchscreen driver | ||
656 | * | ||
657 | * This function used to initializes the bu21013 | ||
658 | * touchscreen driver and returns integer. | ||
659 | */ | ||
660 | static int __init bu21013_init(void) | ||
661 | { | ||
662 | return i2c_add_driver(&bu21013_driver); | ||
663 | } | ||
664 | |||
665 | /** | ||
666 | * bu21013_exit() - de-initializes the bu21013 touchscreen driver | ||
667 | * | ||
668 | * This function uses to de-initializes the bu21013 | ||
669 | * touchscreen driver and returns none. | ||
670 | */ | ||
671 | static void __exit bu21013_exit(void) | ||
672 | { | ||
673 | i2c_del_driver(&bu21013_driver); | ||
674 | } | ||
675 | |||
676 | module_init(bu21013_init); | ||
677 | module_exit(bu21013_exit); | ||
678 | |||
679 | MODULE_LICENSE("GPL v2"); | ||
680 | MODULE_AUTHOR("Naveen Kumar G <naveen.gaddipati@stericsson.com>"); | ||
681 | MODULE_DESCRIPTION("bu21013 touch screen controller driver"); | ||
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 5ec0946938fe..a93c5c26ab3f 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
@@ -206,9 +206,9 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client, | |||
206 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 206 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
207 | 207 | ||
208 | input_set_abs_params(input_dev, ABS_X, | 208 | input_set_abs_params(input_dev, ABS_X, |
209 | CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 0, 0); | 209 | CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0); |
210 | input_set_abs_params(input_dev, ABS_Y, | 210 | input_set_abs_params(input_dev, ABS_Y, |
211 | CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 0, 0); | 211 | CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0); |
212 | 212 | ||
213 | if (ts->reset_pin) { | 213 | if (ts->reset_pin) { |
214 | err = gpio_request(ts->reset_pin, NULL); | 214 | err = gpio_request(ts->reset_pin, NULL); |
@@ -280,8 +280,9 @@ err_free_mem: | |||
280 | } | 280 | } |
281 | 281 | ||
282 | #ifdef CONFIG_PM | 282 | #ifdef CONFIG_PM |
283 | static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) | 283 | static int cy8ctmg110_suspend(struct device *dev) |
284 | { | 284 | { |
285 | struct i2c_client *client = to_i2c_client(dev); | ||
285 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | 286 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); |
286 | 287 | ||
287 | if (device_may_wakeup(&client->dev)) | 288 | if (device_may_wakeup(&client->dev)) |
@@ -293,8 +294,9 @@ static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) | |||
293 | return 0; | 294 | return 0; |
294 | } | 295 | } |
295 | 296 | ||
296 | static int cy8ctmg110_resume(struct i2c_client *client) | 297 | static int cy8ctmg110_resume(struct device *dev) |
297 | { | 298 | { |
299 | struct i2c_client *client = to_i2c_client(dev); | ||
298 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | 300 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); |
299 | 301 | ||
300 | if (device_may_wakeup(&client->dev)) | 302 | if (device_may_wakeup(&client->dev)) |
@@ -305,6 +307,8 @@ static int cy8ctmg110_resume(struct i2c_client *client) | |||
305 | } | 307 | } |
306 | return 0; | 308 | return 0; |
307 | } | 309 | } |
310 | |||
311 | static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); | ||
308 | #endif | 312 | #endif |
309 | 313 | ||
310 | static int __devexit cy8ctmg110_remove(struct i2c_client *client) | 314 | static int __devexit cy8ctmg110_remove(struct i2c_client *client) |
@@ -335,14 +339,13 @@ static struct i2c_driver cy8ctmg110_driver = { | |||
335 | .driver = { | 339 | .driver = { |
336 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
337 | .name = CY8CTMG110_DRIVER_NAME, | 341 | .name = CY8CTMG110_DRIVER_NAME, |
342 | #ifdef CONFIG_PM | ||
343 | .pm = &cy8ctmg110_pm, | ||
344 | #endif | ||
338 | }, | 345 | }, |
339 | .id_table = cy8ctmg110_idtable, | 346 | .id_table = cy8ctmg110_idtable, |
340 | .probe = cy8ctmg110_probe, | 347 | .probe = cy8ctmg110_probe, |
341 | .remove = __devexit_p(cy8ctmg110_remove), | 348 | .remove = __devexit_p(cy8ctmg110_remove), |
342 | #ifdef CONFIG_PM | ||
343 | .suspend = cy8ctmg110_suspend, | ||
344 | .resume = cy8ctmg110_resume, | ||
345 | #endif | ||
346 | }; | 349 | }; |
347 | 350 | ||
348 | static int __init cy8ctmg110_init(void) | 351 | static int __init cy8ctmg110_init(void) |
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 7a3a916f84a8..7f8f538a9806 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
@@ -261,8 +261,9 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
261 | } | 261 | } |
262 | 262 | ||
263 | #ifdef CONFIG_PM | 263 | #ifdef CONFIG_PM |
264 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 264 | static int eeti_ts_suspend(struct device *dev) |
265 | { | 265 | { |
266 | struct i2c_client *client = to_i2c_client(dev); | ||
266 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 267 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
267 | struct input_dev *input_dev = priv->input; | 268 | struct input_dev *input_dev = priv->input; |
268 | 269 | ||
@@ -279,8 +280,9 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
279 | return 0; | 280 | return 0; |
280 | } | 281 | } |
281 | 282 | ||
282 | static int eeti_ts_resume(struct i2c_client *client) | 283 | static int eeti_ts_resume(struct device *dev) |
283 | { | 284 | { |
285 | struct i2c_client *client = to_i2c_client(dev); | ||
284 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 286 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
285 | struct input_dev *input_dev = priv->input; | 287 | struct input_dev *input_dev = priv->input; |
286 | 288 | ||
@@ -296,9 +298,8 @@ static int eeti_ts_resume(struct i2c_client *client) | |||
296 | 298 | ||
297 | return 0; | 299 | return 0; |
298 | } | 300 | } |
299 | #else | 301 | |
300 | #define eeti_ts_suspend NULL | 302 | static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); |
301 | #define eeti_ts_resume NULL | ||
302 | #endif | 303 | #endif |
303 | 304 | ||
304 | static const struct i2c_device_id eeti_ts_id[] = { | 305 | static const struct i2c_device_id eeti_ts_id[] = { |
@@ -310,11 +311,12 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id); | |||
310 | static struct i2c_driver eeti_ts_driver = { | 311 | static struct i2c_driver eeti_ts_driver = { |
311 | .driver = { | 312 | .driver = { |
312 | .name = "eeti_ts", | 313 | .name = "eeti_ts", |
314 | #ifdef CONFIG_PM | ||
315 | .pm = &eeti_ts_pm, | ||
316 | #endif | ||
313 | }, | 317 | }, |
314 | .probe = eeti_ts_probe, | 318 | .probe = eeti_ts_probe, |
315 | .remove = __devexit_p(eeti_ts_remove), | 319 | .remove = __devexit_p(eeti_ts_remove), |
316 | .suspend = eeti_ts_suspend, | ||
317 | .resume = eeti_ts_resume, | ||
318 | .id_table = eeti_ts_id, | 320 | .id_table = eeti_ts_id, |
319 | }; | 321 | }; |
320 | 322 | ||
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index b4d7f63deff1..211811ae5525 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -62,7 +62,7 @@ MODULE_LICENSE("GPL"); | |||
62 | Programmer has no control over these numbers. | 62 | Programmer has no control over these numbers. |
63 | TODO there are holes - specifically 1,7,0x0a | 63 | TODO there are holes - specifically 1,7,0x0a |
64 | */ | 64 | */ |
65 | #define VERSION_ID 0 /* Get Version (request/respose) */ | 65 | #define VERSION_ID 0 /* Get Version (request/response) */ |
66 | #define KEYBD_ID 2 /* Keyboard (event) */ | 66 | #define KEYBD_ID 2 /* Keyboard (event) */ |
67 | #define TOUCHS_ID 3 /* Touch Screen (event)*/ | 67 | #define TOUCHS_ID 3 /* Touch Screen (event)*/ |
68 | #define EEPROM_READ_ID 4 /* (request/response) */ | 68 | #define EEPROM_READ_ID 4 /* (request/response) */ |
@@ -396,34 +396,37 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) | |||
396 | set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE); | 396 | set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE); |
397 | 397 | ||
398 | if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, | 398 | if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, |
399 | IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) { | 399 | IRQF_SHARED | IRQF_DISABLED, "h3600_action", ts->dev)) { |
400 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); | 400 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); |
401 | err = -EBUSY; | 401 | err = -EBUSY; |
402 | goto fail2; | 402 | goto fail1; |
403 | } | 403 | } |
404 | 404 | ||
405 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, | 405 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, |
406 | IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) { | 406 | IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", ts->dev)) { |
407 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); | 407 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); |
408 | err = -EBUSY; | 408 | err = -EBUSY; |
409 | goto fail3; | 409 | goto fail2; |
410 | } | 410 | } |
411 | 411 | ||
412 | serio_set_drvdata(serio, ts); | 412 | serio_set_drvdata(serio, ts); |
413 | 413 | ||
414 | err = serio_open(serio, drv); | 414 | err = serio_open(serio, drv); |
415 | if (err) | 415 | if (err) |
416 | return err; | 416 | goto fail3; |
417 | 417 | ||
418 | //h3600_flite_control(1, 25); /* default brightness */ | 418 | //h3600_flite_control(1, 25); /* default brightness */ |
419 | input_register_device(ts->dev); | 419 | err = input_register_device(ts->dev); |
420 | if (err) | ||
421 | goto fail4; | ||
420 | 422 | ||
421 | return 0; | 423 | return 0; |
422 | 424 | ||
423 | fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | 425 | fail4: serio_close(serio); |
426 | fail3: serio_set_drvdata(serio, NULL); | ||
427 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | ||
424 | fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); | 428 | fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); |
425 | fail1: serio_set_drvdata(serio, NULL); | 429 | fail1: input_free_device(input_dev); |
426 | input_free_device(input_dev); | ||
427 | kfree(ts); | 430 | kfree(ts); |
428 | return err; | 431 | return err; |
429 | } | 432 | } |
@@ -436,8 +439,8 @@ static void h3600ts_disconnect(struct serio *serio) | |||
436 | { | 439 | { |
437 | struct h3600_dev *ts = serio_get_drvdata(serio); | 440 | struct h3600_dev *ts = serio_get_drvdata(serio); |
438 | 441 | ||
439 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); | 442 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); |
440 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev); | 443 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); |
441 | input_get_device(ts->dev); | 444 | input_get_device(ts->dev); |
442 | input_unregister_device(ts->dev); | 445 | input_unregister_device(ts->dev); |
443 | serio_close(serio); | 446 | serio_close(serio); |
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index a89700e7ace4..dd4e8f020b99 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
@@ -28,29 +28,29 @@ static void do_softint(struct work_struct *work) | |||
28 | u8 scpdr; | 28 | u8 scpdr; |
29 | int touched = 0; | 29 | int touched = 0; |
30 | 30 | ||
31 | if (ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN) { | 31 | if (__raw_readb(PHDR) & PHDR_TS_PEN_DOWN) { |
32 | scpdr = ctrl_inb(SCPDR); | 32 | scpdr = __raw_readb(SCPDR); |
33 | scpdr |= SCPDR_TS_SCAN_ENABLE; | 33 | scpdr |= SCPDR_TS_SCAN_ENABLE; |
34 | scpdr &= ~SCPDR_TS_SCAN_Y; | 34 | scpdr &= ~SCPDR_TS_SCAN_Y; |
35 | ctrl_outb(scpdr, SCPDR); | 35 | __raw_writeb(scpdr, SCPDR); |
36 | udelay(30); | 36 | udelay(30); |
37 | 37 | ||
38 | absy = adc_single(ADC_CHANNEL_TS_Y); | 38 | absy = adc_single(ADC_CHANNEL_TS_Y); |
39 | 39 | ||
40 | scpdr = ctrl_inb(SCPDR); | 40 | scpdr = __raw_readb(SCPDR); |
41 | scpdr |= SCPDR_TS_SCAN_Y; | 41 | scpdr |= SCPDR_TS_SCAN_Y; |
42 | scpdr &= ~SCPDR_TS_SCAN_X; | 42 | scpdr &= ~SCPDR_TS_SCAN_X; |
43 | ctrl_outb(scpdr, SCPDR); | 43 | __raw_writeb(scpdr, SCPDR); |
44 | udelay(30); | 44 | udelay(30); |
45 | 45 | ||
46 | absx = adc_single(ADC_CHANNEL_TS_X); | 46 | absx = adc_single(ADC_CHANNEL_TS_X); |
47 | 47 | ||
48 | scpdr = ctrl_inb(SCPDR); | 48 | scpdr = __raw_readb(SCPDR); |
49 | scpdr |= SCPDR_TS_SCAN_X; | 49 | scpdr |= SCPDR_TS_SCAN_X; |
50 | scpdr &= ~SCPDR_TS_SCAN_ENABLE; | 50 | scpdr &= ~SCPDR_TS_SCAN_ENABLE; |
51 | ctrl_outb(scpdr, SCPDR); | 51 | __raw_writeb(scpdr, SCPDR); |
52 | udelay(100); | 52 | udelay(100); |
53 | touched = ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN; | 53 | touched = __raw_readb(PHDR) & PHDR_TS_PEN_DOWN; |
54 | } | 54 | } |
55 | 55 | ||
56 | if (touched) { | 56 | if (touched) { |
@@ -107,8 +107,7 @@ static int __init hp680_ts_init(void) | |||
107 | return 0; | 107 | return 0; |
108 | 108 | ||
109 | fail2: free_irq(HP680_TS_IRQ, NULL); | 109 | fail2: free_irq(HP680_TS_IRQ, NULL); |
110 | cancel_delayed_work(&work); | 110 | cancel_delayed_work_sync(&work); |
111 | flush_scheduled_work(); | ||
112 | fail1: input_free_device(hp680_ts_dev); | 111 | fail1: input_free_device(hp680_ts_dev); |
113 | return err; | 112 | return err; |
114 | } | 113 | } |
@@ -116,8 +115,7 @@ static int __init hp680_ts_init(void) | |||
116 | static void __exit hp680_ts_exit(void) | 115 | static void __exit hp680_ts_exit(void) |
117 | { | 116 | { |
118 | free_irq(HP680_TS_IRQ, NULL); | 117 | free_irq(HP680_TS_IRQ, NULL); |
119 | cancel_delayed_work(&work); | 118 | cancel_delayed_work_sync(&work); |
120 | flush_scheduled_work(); | ||
121 | input_unregister_device(hp680_ts_dev); | 119 | input_unregister_device(hp680_ts_dev); |
122 | } | 120 | } |
123 | 121 | ||
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c new file mode 100644 index 000000000000..66c96bfc5522 --- /dev/null +++ b/drivers/input/touchscreen/intel-mid-touch.c | |||
@@ -0,0 +1,687 @@ | |||
1 | /* | ||
2 | * Intel MID Resistive Touch Screen Driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Intel Corp | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
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 as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * | ||
21 | * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com) | ||
22 | * Ramesh Agarwal (ramesh.agarwal@intel.com) | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | * | ||
25 | * TODO: | ||
26 | * review conversion of r/m/w sequences | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/err.h> | ||
34 | #include <linux/param.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/irq.h> | ||
38 | #include <linux/delay.h> | ||
39 | #include <asm/intel_scu_ipc.h> | ||
40 | |||
41 | /* PMIC Interrupt registers */ | ||
42 | #define PMIC_REG_ID1 0x00 /* PMIC ID1 register */ | ||
43 | |||
44 | /* PMIC Interrupt registers */ | ||
45 | #define PMIC_REG_INT 0x04 /* PMIC interrupt register */ | ||
46 | #define PMIC_REG_MINT 0x05 /* PMIC interrupt mask register */ | ||
47 | |||
48 | /* ADC Interrupt registers */ | ||
49 | #define PMIC_REG_ADCINT 0x5F /* ADC interrupt register */ | ||
50 | #define PMIC_REG_MADCINT 0x60 /* ADC interrupt mask register */ | ||
51 | |||
52 | /* ADC Control registers */ | ||
53 | #define PMIC_REG_ADCCNTL1 0x61 /* ADC control register */ | ||
54 | |||
55 | /* ADC Channel Selection registers */ | ||
56 | #define PMICADDR0 0xA4 | ||
57 | #define END_OF_CHANNEL 0x1F | ||
58 | |||
59 | /* ADC Result register */ | ||
60 | #define PMIC_REG_ADCSNS0H 0x64 | ||
61 | |||
62 | /* ADC channels for touch screen */ | ||
63 | #define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */ | ||
64 | #define MRST_TS_CHAN11 0xB /* Touch screen X- connection */ | ||
65 | #define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */ | ||
66 | #define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */ | ||
67 | |||
68 | /* Touch screen channel BIAS constants */ | ||
69 | #define MRST_XBIAS 0x20 | ||
70 | #define MRST_YBIAS 0x40 | ||
71 | #define MRST_ZBIAS 0x80 | ||
72 | |||
73 | /* Touch screen coordinates */ | ||
74 | #define MRST_X_MIN 10 | ||
75 | #define MRST_X_MAX 1024 | ||
76 | #define MRST_X_FUZZ 5 | ||
77 | #define MRST_Y_MIN 10 | ||
78 | #define MRST_Y_MAX 1024 | ||
79 | #define MRST_Y_FUZZ 5 | ||
80 | #define MRST_PRESSURE_MIN 0 | ||
81 | #define MRST_PRESSURE_NOMINAL 50 | ||
82 | #define MRST_PRESSURE_MAX 100 | ||
83 | |||
84 | #define WAIT_ADC_COMPLETION 10 /* msec */ | ||
85 | |||
86 | /* PMIC ADC round robin delays */ | ||
87 | #define ADC_LOOP_DELAY0 0x0 /* Continuous loop */ | ||
88 | #define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */ | ||
89 | |||
90 | /* PMIC Vendor Identifiers */ | ||
91 | #define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */ | ||
92 | #define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */ | ||
93 | #define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */ | ||
94 | #define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */ | ||
95 | |||
96 | /* Touch screen device structure */ | ||
97 | struct mrstouch_dev { | ||
98 | struct device *dev; /* device associated with touch screen */ | ||
99 | struct input_dev *input; | ||
100 | char phys[32]; | ||
101 | u16 asr; /* Address selection register */ | ||
102 | int irq; | ||
103 | unsigned int vendor; /* PMIC vendor */ | ||
104 | unsigned int rev; /* PMIC revision */ | ||
105 | |||
106 | int (*read_prepare)(struct mrstouch_dev *tsdev); | ||
107 | int (*read)(struct mrstouch_dev *tsdev, u16 *x, u16 *y, u16 *z); | ||
108 | int (*read_finish)(struct mrstouch_dev *tsdev); | ||
109 | }; | ||
110 | |||
111 | |||
112 | /*************************** NEC and Maxim Interface ************************/ | ||
113 | |||
114 | static int mrstouch_nec_adc_read_prepare(struct mrstouch_dev *tsdev) | ||
115 | { | ||
116 | return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0, 0x20); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Enables PENDET interrupt. | ||
121 | */ | ||
122 | static int mrstouch_nec_adc_read_finish(struct mrstouch_dev *tsdev) | ||
123 | { | ||
124 | int err; | ||
125 | |||
126 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x20, 0x20); | ||
127 | if (!err) | ||
128 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, 0, 0x05); | ||
129 | |||
130 | return err; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Reads PMIC ADC touch screen result | ||
135 | * Reads ADC storage registers for higher 7 and lower 3 bits and | ||
136 | * converts the two readings into a single value and turns off gain bit | ||
137 | */ | ||
138 | static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm) | ||
139 | { | ||
140 | int err; | ||
141 | u16 result; | ||
142 | u32 res; | ||
143 | |||
144 | result = PMIC_REG_ADCSNS0H + offset; | ||
145 | |||
146 | if (chan == MRST_TS_CHAN12) | ||
147 | result += 4; | ||
148 | |||
149 | err = intel_scu_ipc_ioread32(result, &res); | ||
150 | if (err) | ||
151 | return err; | ||
152 | |||
153 | /* Mash the bits up */ | ||
154 | |||
155 | *vp = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
156 | *vp |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
157 | *vp &= 0x3FF; | ||
158 | |||
159 | res >>= 16; | ||
160 | |||
161 | *vm = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
162 | *vm |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
163 | *vm &= 0x3FF; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Enables X, Y and Z bias values | ||
170 | * Enables YPYM for X channels and XPXM for Y channels | ||
171 | */ | ||
172 | static int mrstouch_ts_bias_set(uint offset, uint bias) | ||
173 | { | ||
174 | int count; | ||
175 | u16 chan, start; | ||
176 | u16 reg[4]; | ||
177 | u8 data[4]; | ||
178 | |||
179 | chan = PMICADDR0 + offset; | ||
180 | start = MRST_TS_CHAN10; | ||
181 | |||
182 | for (count = 0; count <= 3; count++) { | ||
183 | reg[count] = chan++; | ||
184 | data[count] = bias | (start + count); | ||
185 | } | ||
186 | |||
187 | return intel_scu_ipc_writev(reg, data, 4); | ||
188 | } | ||
189 | |||
190 | /* To read touch screen channel values */ | ||
191 | static int mrstouch_nec_adc_read(struct mrstouch_dev *tsdev, | ||
192 | u16 *x, u16 *y, u16 *z) | ||
193 | { | ||
194 | int err; | ||
195 | u16 xm, ym, zm; | ||
196 | |||
197 | /* configure Y bias for X channels */ | ||
198 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_YBIAS); | ||
199 | if (err) | ||
200 | goto ipc_error; | ||
201 | |||
202 | msleep(WAIT_ADC_COMPLETION); | ||
203 | |||
204 | /* read x+ and x- channels */ | ||
205 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, x, &xm); | ||
206 | if (err) | ||
207 | goto ipc_error; | ||
208 | |||
209 | /* configure x bias for y channels */ | ||
210 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_XBIAS); | ||
211 | if (err) | ||
212 | goto ipc_error; | ||
213 | |||
214 | msleep(WAIT_ADC_COMPLETION); | ||
215 | |||
216 | /* read y+ and y- channels */ | ||
217 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, y, &ym); | ||
218 | if (err) | ||
219 | goto ipc_error; | ||
220 | |||
221 | /* configure z bias for x and y channels */ | ||
222 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_ZBIAS); | ||
223 | if (err) | ||
224 | goto ipc_error; | ||
225 | |||
226 | msleep(WAIT_ADC_COMPLETION); | ||
227 | |||
228 | /* read z+ and z- channels */ | ||
229 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, z, &zm); | ||
230 | if (err) | ||
231 | goto ipc_error; | ||
232 | |||
233 | return 0; | ||
234 | |||
235 | ipc_error: | ||
236 | dev_err(tsdev->dev, "ipc error during adc read\n"); | ||
237 | return err; | ||
238 | } | ||
239 | |||
240 | |||
241 | /*************************** Freescale Interface ************************/ | ||
242 | |||
243 | static int mrstouch_fs_adc_read_prepare(struct mrstouch_dev *tsdev) | ||
244 | { | ||
245 | int err, count; | ||
246 | u16 chan; | ||
247 | u16 reg[5]; | ||
248 | u8 data[5]; | ||
249 | |||
250 | /* Stop the ADC */ | ||
251 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02); | ||
252 | if (err) | ||
253 | goto ipc_error; | ||
254 | |||
255 | chan = PMICADDR0 + tsdev->asr; | ||
256 | |||
257 | /* Set X BIAS */ | ||
258 | for (count = 0; count <= 3; count++) { | ||
259 | reg[count] = chan++; | ||
260 | data[count] = 0x2A; | ||
261 | } | ||
262 | reg[count] = chan++; /* Dummy */ | ||
263 | data[count] = 0; | ||
264 | |||
265 | err = intel_scu_ipc_writev(reg, data, 5); | ||
266 | if (err) | ||
267 | goto ipc_error; | ||
268 | |||
269 | msleep(WAIT_ADC_COMPLETION); | ||
270 | |||
271 | /* Set Y BIAS */ | ||
272 | for (count = 0; count <= 3; count++) { | ||
273 | reg[count] = chan++; | ||
274 | data[count] = 0x4A; | ||
275 | } | ||
276 | reg[count] = chan++; /* Dummy */ | ||
277 | data[count] = 0; | ||
278 | |||
279 | err = intel_scu_ipc_writev(reg, data, 5); | ||
280 | if (err) | ||
281 | goto ipc_error; | ||
282 | |||
283 | msleep(WAIT_ADC_COMPLETION); | ||
284 | |||
285 | /* Set Z BIAS */ | ||
286 | err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A); | ||
287 | if (err) | ||
288 | goto ipc_error; | ||
289 | |||
290 | msleep(WAIT_ADC_COMPLETION); | ||
291 | |||
292 | return 0; | ||
293 | |||
294 | ipc_error: | ||
295 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
296 | return err; | ||
297 | } | ||
298 | |||
299 | static int mrstouch_fs_adc_read(struct mrstouch_dev *tsdev, | ||
300 | u16 *x, u16 *y, u16 *z) | ||
301 | { | ||
302 | int err; | ||
303 | u16 result; | ||
304 | u16 reg[4]; | ||
305 | u8 data[4]; | ||
306 | |||
307 | result = PMIC_REG_ADCSNS0H + tsdev->asr; | ||
308 | |||
309 | reg[0] = result + 4; | ||
310 | reg[1] = result + 5; | ||
311 | reg[2] = result + 16; | ||
312 | reg[3] = result + 17; | ||
313 | |||
314 | err = intel_scu_ipc_readv(reg, data, 4); | ||
315 | if (err) | ||
316 | goto ipc_error; | ||
317 | |||
318 | *x = data[0] << 3; /* Higher 7 bits */ | ||
319 | *x |= data[1] & 0x7; /* Lower 3 bits */ | ||
320 | *x &= 0x3FF; | ||
321 | |||
322 | *y = data[2] << 3; /* Higher 7 bits */ | ||
323 | *y |= data[3] & 0x7; /* Lower 3 bits */ | ||
324 | *y &= 0x3FF; | ||
325 | |||
326 | /* Read Z value */ | ||
327 | reg[0] = result + 28; | ||
328 | reg[1] = result + 29; | ||
329 | |||
330 | err = intel_scu_ipc_readv(reg, data, 4); | ||
331 | if (err) | ||
332 | goto ipc_error; | ||
333 | |||
334 | *z = data[0] << 3; /* Higher 7 bits */ | ||
335 | *z |= data[1] & 0x7; /* Lower 3 bits */ | ||
336 | *z &= 0x3FF; | ||
337 | |||
338 | return 0; | ||
339 | |||
340 | ipc_error: | ||
341 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
342 | return err; | ||
343 | } | ||
344 | |||
345 | static int mrstouch_fs_adc_read_finish(struct mrstouch_dev *tsdev) | ||
346 | { | ||
347 | int err, count; | ||
348 | u16 chan; | ||
349 | u16 reg[5]; | ||
350 | u8 data[5]; | ||
351 | |||
352 | /* Clear all TS channels */ | ||
353 | chan = PMICADDR0 + tsdev->asr; | ||
354 | for (count = 0; count <= 4; count++) { | ||
355 | reg[count] = chan++; | ||
356 | data[count] = 0; | ||
357 | } | ||
358 | err = intel_scu_ipc_writev(reg, data, 5); | ||
359 | if (err) | ||
360 | goto ipc_error; | ||
361 | |||
362 | for (count = 0; count <= 4; count++) { | ||
363 | reg[count] = chan++; | ||
364 | data[count] = 0; | ||
365 | } | ||
366 | err = intel_scu_ipc_writev(reg, data, 5); | ||
367 | if (err) | ||
368 | goto ipc_error; | ||
369 | |||
370 | err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000); | ||
371 | if (err) | ||
372 | goto ipc_error; | ||
373 | |||
374 | /* Start ADC */ | ||
375 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02); | ||
376 | if (err) | ||
377 | goto ipc_error; | ||
378 | |||
379 | return 0; | ||
380 | |||
381 | ipc_error: | ||
382 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
383 | return err; | ||
384 | } | ||
385 | |||
386 | static void mrstouch_report_event(struct input_dev *input, | ||
387 | unsigned int x, unsigned int y, unsigned int z) | ||
388 | { | ||
389 | if (z > MRST_PRESSURE_NOMINAL) { | ||
390 | /* Pen touched, report button touch and coordinates */ | ||
391 | input_report_key(input, BTN_TOUCH, 1); | ||
392 | input_report_abs(input, ABS_X, x); | ||
393 | input_report_abs(input, ABS_Y, y); | ||
394 | } else { | ||
395 | input_report_key(input, BTN_TOUCH, 0); | ||
396 | } | ||
397 | |||
398 | input_report_abs(input, ABS_PRESSURE, z); | ||
399 | input_sync(input); | ||
400 | } | ||
401 | |||
402 | /* PENDET interrupt handler */ | ||
403 | static irqreturn_t mrstouch_pendet_irq(int irq, void *dev_id) | ||
404 | { | ||
405 | struct mrstouch_dev *tsdev = dev_id; | ||
406 | u16 x, y, z; | ||
407 | |||
408 | /* | ||
409 | * Should we lower thread priority? Probably not, since we are | ||
410 | * not spinning but sleeping... | ||
411 | */ | ||
412 | |||
413 | if (tsdev->read_prepare(tsdev)) | ||
414 | goto out; | ||
415 | |||
416 | do { | ||
417 | if (tsdev->read(tsdev, &x, &y, &z)) | ||
418 | break; | ||
419 | |||
420 | mrstouch_report_event(tsdev->input, x, y, z); | ||
421 | } while (z > MRST_PRESSURE_NOMINAL); | ||
422 | |||
423 | tsdev->read_finish(tsdev); | ||
424 | |||
425 | out: | ||
426 | return IRQ_HANDLED; | ||
427 | } | ||
428 | |||
429 | /* Utility to read PMIC ID */ | ||
430 | static int __devinit mrstouch_read_pmic_id(uint *vendor, uint *rev) | ||
431 | { | ||
432 | int err; | ||
433 | u8 r; | ||
434 | |||
435 | err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r); | ||
436 | if (err) | ||
437 | return err; | ||
438 | |||
439 | *vendor = r & 0x7; | ||
440 | *rev = (r >> 3) & 0x7; | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Parse ADC channels to find end of the channel configured by other ADC user | ||
447 | * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels | ||
448 | */ | ||
449 | static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev) | ||
450 | { | ||
451 | int err, i, found; | ||
452 | u8 r8; | ||
453 | |||
454 | found = -1; | ||
455 | |||
456 | for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) { | ||
457 | if (found >= 0) | ||
458 | break; | ||
459 | |||
460 | err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8); | ||
461 | if (err) | ||
462 | return err; | ||
463 | |||
464 | if (r8 == END_OF_CHANNEL) { | ||
465 | found = i; | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | if (found < 0) | ||
470 | return 0; | ||
471 | |||
472 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
473 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 18)) | ||
474 | return -ENOSPC; | ||
475 | } else { | ||
476 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 4)) | ||
477 | return -ENOSPC; | ||
478 | } | ||
479 | return found; | ||
480 | } | ||
481 | |||
482 | |||
483 | /* | ||
484 | * Writes touch screen channels to ADC address selection registers | ||
485 | */ | ||
486 | static int __devinit mrstouch_ts_chan_set(uint offset) | ||
487 | { | ||
488 | u16 chan; | ||
489 | |||
490 | int ret, count; | ||
491 | |||
492 | chan = PMICADDR0 + offset; | ||
493 | for (count = 0; count <= 3; count++) { | ||
494 | ret = intel_scu_ipc_iowrite8(chan++, MRST_TS_CHAN10 + count); | ||
495 | if (ret) | ||
496 | return ret; | ||
497 | } | ||
498 | return intel_scu_ipc_iowrite8(chan++, END_OF_CHANNEL); | ||
499 | } | ||
500 | |||
501 | /* Initialize ADC */ | ||
502 | static int __devinit mrstouch_adc_init(struct mrstouch_dev *tsdev) | ||
503 | { | ||
504 | int err, start; | ||
505 | u8 ra, rm; | ||
506 | |||
507 | err = mrstouch_read_pmic_id(&tsdev->vendor, &tsdev->rev); | ||
508 | if (err) { | ||
509 | dev_err(tsdev->dev, "Unable to read PMIC id\n"); | ||
510 | return err; | ||
511 | } | ||
512 | |||
513 | switch (tsdev->vendor) { | ||
514 | case PMIC_VENDOR_NEC: | ||
515 | case PMIC_VENDOR_MAXIM: | ||
516 | tsdev->read_prepare = mrstouch_nec_adc_read_prepare; | ||
517 | tsdev->read = mrstouch_nec_adc_read; | ||
518 | tsdev->read_finish = mrstouch_nec_adc_read_finish; | ||
519 | break; | ||
520 | |||
521 | case PMIC_VENDOR_FS: | ||
522 | tsdev->read_prepare = mrstouch_fs_adc_read_prepare; | ||
523 | tsdev->read = mrstouch_fs_adc_read; | ||
524 | tsdev->read_finish = mrstouch_fs_adc_read_finish; | ||
525 | break; | ||
526 | |||
527 | default: | ||
528 | dev_err(tsdev->dev, | ||
529 | "Unsupported touchscreen: %d\n", tsdev->vendor); | ||
530 | return -ENXIO; | ||
531 | } | ||
532 | |||
533 | start = mrstouch_chan_parse(tsdev); | ||
534 | if (start < 0) { | ||
535 | dev_err(tsdev->dev, "Unable to parse channels\n"); | ||
536 | return start; | ||
537 | } | ||
538 | |||
539 | tsdev->asr = start; | ||
540 | |||
541 | /* | ||
542 | * ADC power on, start, enable PENDET and set loop delay | ||
543 | * ADC loop delay is set to 4.5 ms approximately | ||
544 | * Loop delay more than this results in jitter in adc readings | ||
545 | * Setting loop delay to 0 (continuous loop) in MAXIM stops PENDET | ||
546 | * interrupt generation sometimes. | ||
547 | */ | ||
548 | |||
549 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
550 | ra = 0xE0 | ADC_LOOP_DELAY0; | ||
551 | rm = 0x5; | ||
552 | } else { | ||
553 | /* NEC and MAXIm not consistent with loop delay 0 */ | ||
554 | ra = 0xE0 | ADC_LOOP_DELAY1; | ||
555 | rm = 0x0; | ||
556 | |||
557 | /* configure touch screen channels */ | ||
558 | err = mrstouch_ts_chan_set(tsdev->asr); | ||
559 | if (err) | ||
560 | return err; | ||
561 | } | ||
562 | |||
563 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7); | ||
564 | if (err) | ||
565 | return err; | ||
566 | |||
567 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03); | ||
568 | if (err) | ||
569 | return err; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | |||
575 | /* Probe function for touch screen driver */ | ||
576 | static int __devinit mrstouch_probe(struct platform_device *pdev) | ||
577 | { | ||
578 | struct mrstouch_dev *tsdev; | ||
579 | struct input_dev *input; | ||
580 | int err; | ||
581 | int irq; | ||
582 | |||
583 | irq = platform_get_irq(pdev, 0); | ||
584 | if (irq < 0) { | ||
585 | dev_err(&pdev->dev, "no interrupt assigned\n"); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL); | ||
590 | input = input_allocate_device(); | ||
591 | if (!tsdev || !input) { | ||
592 | dev_err(&pdev->dev, "unable to allocate memory\n"); | ||
593 | err = -ENOMEM; | ||
594 | goto err_free_mem; | ||
595 | } | ||
596 | |||
597 | tsdev->dev = &pdev->dev; | ||
598 | tsdev->input = input; | ||
599 | tsdev->irq = irq; | ||
600 | |||
601 | snprintf(tsdev->phys, sizeof(tsdev->phys), | ||
602 | "%s/input0", dev_name(tsdev->dev)); | ||
603 | |||
604 | err = mrstouch_adc_init(tsdev); | ||
605 | if (err) { | ||
606 | dev_err(&pdev->dev, "ADC initialization failed\n"); | ||
607 | goto err_free_mem; | ||
608 | } | ||
609 | |||
610 | input->name = "mrst_touchscreen"; | ||
611 | input->phys = tsdev->phys; | ||
612 | input->dev.parent = tsdev->dev; | ||
613 | |||
614 | input->id.vendor = tsdev->vendor; | ||
615 | input->id.version = tsdev->rev; | ||
616 | |||
617 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
618 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
619 | |||
620 | input_set_abs_params(tsdev->input, ABS_X, | ||
621 | MRST_X_MIN, MRST_X_MAX, MRST_X_FUZZ, 0); | ||
622 | input_set_abs_params(tsdev->input, ABS_Y, | ||
623 | MRST_Y_MIN, MRST_Y_MAX, MRST_Y_FUZZ, 0); | ||
624 | input_set_abs_params(tsdev->input, ABS_PRESSURE, | ||
625 | MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); | ||
626 | |||
627 | err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq, | ||
628 | 0, "mrstouch", tsdev); | ||
629 | if (err) { | ||
630 | dev_err(tsdev->dev, "unable to allocate irq\n"); | ||
631 | goto err_free_mem; | ||
632 | } | ||
633 | |||
634 | err = input_register_device(tsdev->input); | ||
635 | if (err) { | ||
636 | dev_err(tsdev->dev, "unable to register input device\n"); | ||
637 | goto err_free_irq; | ||
638 | } | ||
639 | |||
640 | platform_set_drvdata(pdev, tsdev); | ||
641 | return 0; | ||
642 | |||
643 | err_free_irq: | ||
644 | free_irq(tsdev->irq, tsdev); | ||
645 | err_free_mem: | ||
646 | input_free_device(input); | ||
647 | kfree(tsdev); | ||
648 | return err; | ||
649 | } | ||
650 | |||
651 | static int __devexit mrstouch_remove(struct platform_device *pdev) | ||
652 | { | ||
653 | struct mrstouch_dev *tsdev = platform_get_drvdata(pdev); | ||
654 | |||
655 | free_irq(tsdev->irq, tsdev); | ||
656 | input_unregister_device(tsdev->input); | ||
657 | kfree(tsdev); | ||
658 | |||
659 | platform_set_drvdata(pdev, NULL); | ||
660 | |||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static struct platform_driver mrstouch_driver = { | ||
665 | .driver = { | ||
666 | .name = "pmic_touch", | ||
667 | .owner = THIS_MODULE, | ||
668 | }, | ||
669 | .probe = mrstouch_probe, | ||
670 | .remove = __devexit_p(mrstouch_remove), | ||
671 | }; | ||
672 | |||
673 | static int __init mrstouch_init(void) | ||
674 | { | ||
675 | return platform_driver_register(&mrstouch_driver); | ||
676 | } | ||
677 | module_init(mrstouch_init); | ||
678 | |||
679 | static void __exit mrstouch_exit(void) | ||
680 | { | ||
681 | platform_driver_unregister(&mrstouch_driver); | ||
682 | } | ||
683 | module_exit(mrstouch_exit); | ||
684 | |||
685 | MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com"); | ||
686 | MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver"); | ||
687 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c new file mode 100644 index 000000000000..dcf803f5a1f7 --- /dev/null +++ b/drivers/input/touchscreen/lpc32xx_ts.c | |||
@@ -0,0 +1,411 @@ | |||
1 | /* | ||
2 | * LPC32xx built-in touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 NXP Semiconductors | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/slab.h> | ||
25 | |||
26 | /* | ||
27 | * Touchscreen controller register offsets | ||
28 | */ | ||
29 | #define LPC32XX_TSC_STAT 0x00 | ||
30 | #define LPC32XX_TSC_SEL 0x04 | ||
31 | #define LPC32XX_TSC_CON 0x08 | ||
32 | #define LPC32XX_TSC_FIFO 0x0C | ||
33 | #define LPC32XX_TSC_DTR 0x10 | ||
34 | #define LPC32XX_TSC_RTR 0x14 | ||
35 | #define LPC32XX_TSC_UTR 0x18 | ||
36 | #define LPC32XX_TSC_TTR 0x1C | ||
37 | #define LPC32XX_TSC_DXP 0x20 | ||
38 | #define LPC32XX_TSC_MIN_X 0x24 | ||
39 | #define LPC32XX_TSC_MAX_X 0x28 | ||
40 | #define LPC32XX_TSC_MIN_Y 0x2C | ||
41 | #define LPC32XX_TSC_MAX_Y 0x30 | ||
42 | #define LPC32XX_TSC_AUX_UTR 0x34 | ||
43 | #define LPC32XX_TSC_AUX_MIN 0x38 | ||
44 | #define LPC32XX_TSC_AUX_MAX 0x3C | ||
45 | |||
46 | #define LPC32XX_TSC_STAT_FIFO_OVRRN (1 << 8) | ||
47 | #define LPC32XX_TSC_STAT_FIFO_EMPTY (1 << 7) | ||
48 | |||
49 | #define LPC32XX_TSC_SEL_DEFVAL 0x0284 | ||
50 | |||
51 | #define LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 (0x1 << 11) | ||
52 | #define LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(s) ((10 - (s)) << 7) | ||
53 | #define LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(s) ((10 - (s)) << 4) | ||
54 | #define LPC32XX_TSC_ADCCON_POWER_UP (1 << 2) | ||
55 | #define LPC32XX_TSC_ADCCON_AUTO_EN (1 << 0) | ||
56 | |||
57 | #define LPC32XX_TSC_FIFO_TS_P_LEVEL (1 << 31) | ||
58 | #define LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(x) (((x) & 0x03FF0000) >> 16) | ||
59 | #define LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(y) ((y) & 0x000003FF) | ||
60 | |||
61 | #define LPC32XX_TSC_ADCDAT_VALUE_MASK 0x000003FF | ||
62 | |||
63 | #define LPC32XX_TSC_MIN_XY_VAL 0x0 | ||
64 | #define LPC32XX_TSC_MAX_XY_VAL 0x3FF | ||
65 | |||
66 | #define MOD_NAME "ts-lpc32xx" | ||
67 | |||
68 | #define tsc_readl(dev, reg) \ | ||
69 | __raw_readl((dev)->tsc_base + (reg)) | ||
70 | #define tsc_writel(dev, reg, val) \ | ||
71 | __raw_writel((val), (dev)->tsc_base + (reg)) | ||
72 | |||
73 | struct lpc32xx_tsc { | ||
74 | struct input_dev *dev; | ||
75 | void __iomem *tsc_base; | ||
76 | int irq; | ||
77 | struct clk *clk; | ||
78 | }; | ||
79 | |||
80 | static void lpc32xx_fifo_clear(struct lpc32xx_tsc *tsc) | ||
81 | { | ||
82 | while (!(tsc_readl(tsc, LPC32XX_TSC_STAT) & | ||
83 | LPC32XX_TSC_STAT_FIFO_EMPTY)) | ||
84 | tsc_readl(tsc, LPC32XX_TSC_FIFO); | ||
85 | } | ||
86 | |||
87 | static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id) | ||
88 | { | ||
89 | u32 tmp, rv[4], xs[4], ys[4]; | ||
90 | int idx; | ||
91 | struct lpc32xx_tsc *tsc = dev_id; | ||
92 | struct input_dev *input = tsc->dev; | ||
93 | |||
94 | tmp = tsc_readl(tsc, LPC32XX_TSC_STAT); | ||
95 | |||
96 | if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) { | ||
97 | /* FIFO overflow - throw away samples */ | ||
98 | lpc32xx_fifo_clear(tsc); | ||
99 | return IRQ_HANDLED; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Gather and normalize 4 samples. Pen-up events may have less | ||
104 | * than 4 samples, but its ok to pop 4 and let the last sample | ||
105 | * pen status check drop the samples. | ||
106 | */ | ||
107 | idx = 0; | ||
108 | while (idx < 4 && | ||
109 | !(tsc_readl(tsc, LPC32XX_TSC_STAT) & | ||
110 | LPC32XX_TSC_STAT_FIFO_EMPTY)) { | ||
111 | tmp = tsc_readl(tsc, LPC32XX_TSC_FIFO); | ||
112 | xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - | ||
113 | LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp); | ||
114 | ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - | ||
115 | LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp); | ||
116 | rv[idx] = tmp; | ||
117 | idx++; | ||
118 | } | ||
119 | |||
120 | /* Data is only valid if pen is still down in last sample */ | ||
121 | if (!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL) && idx == 4) { | ||
122 | /* Use average of 2nd and 3rd sample for position */ | ||
123 | input_report_abs(input, ABS_X, (xs[1] + xs[2]) / 2); | ||
124 | input_report_abs(input, ABS_Y, (ys[1] + ys[2]) / 2); | ||
125 | input_report_key(input, BTN_TOUCH, 1); | ||
126 | } else { | ||
127 | input_report_key(input, BTN_TOUCH, 0); | ||
128 | } | ||
129 | |||
130 | input_sync(input); | ||
131 | |||
132 | return IRQ_HANDLED; | ||
133 | } | ||
134 | |||
135 | static void lpc32xx_stop_tsc(struct lpc32xx_tsc *tsc) | ||
136 | { | ||
137 | /* Disable auto mode */ | ||
138 | tsc_writel(tsc, LPC32XX_TSC_CON, | ||
139 | tsc_readl(tsc, LPC32XX_TSC_CON) & | ||
140 | ~LPC32XX_TSC_ADCCON_AUTO_EN); | ||
141 | |||
142 | clk_disable(tsc->clk); | ||
143 | } | ||
144 | |||
145 | static void lpc32xx_setup_tsc(struct lpc32xx_tsc *tsc) | ||
146 | { | ||
147 | u32 tmp; | ||
148 | |||
149 | clk_enable(tsc->clk); | ||
150 | |||
151 | tmp = tsc_readl(tsc, LPC32XX_TSC_CON) & ~LPC32XX_TSC_ADCCON_POWER_UP; | ||
152 | |||
153 | /* Set the TSC FIFO depth to 4 samples @ 10-bits per sample (max) */ | ||
154 | tmp = LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 | | ||
155 | LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(10) | | ||
156 | LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(10); | ||
157 | tsc_writel(tsc, LPC32XX_TSC_CON, tmp); | ||
158 | |||
159 | /* These values are all preset */ | ||
160 | tsc_writel(tsc, LPC32XX_TSC_SEL, LPC32XX_TSC_SEL_DEFVAL); | ||
161 | tsc_writel(tsc, LPC32XX_TSC_MIN_X, LPC32XX_TSC_MIN_XY_VAL); | ||
162 | tsc_writel(tsc, LPC32XX_TSC_MAX_X, LPC32XX_TSC_MAX_XY_VAL); | ||
163 | tsc_writel(tsc, LPC32XX_TSC_MIN_Y, LPC32XX_TSC_MIN_XY_VAL); | ||
164 | tsc_writel(tsc, LPC32XX_TSC_MAX_Y, LPC32XX_TSC_MAX_XY_VAL); | ||
165 | |||
166 | /* Aux support is not used */ | ||
167 | tsc_writel(tsc, LPC32XX_TSC_AUX_UTR, 0); | ||
168 | tsc_writel(tsc, LPC32XX_TSC_AUX_MIN, 0); | ||
169 | tsc_writel(tsc, LPC32XX_TSC_AUX_MAX, 0); | ||
170 | |||
171 | /* | ||
172 | * Set sample rate to about 240Hz per X/Y pair. A single measurement | ||
173 | * consists of 4 pairs which gives about a 60Hz sample rate based on | ||
174 | * a stable 32768Hz clock source. Values are in clocks. | ||
175 | * Rate is (32768 / (RTR + XCONV + RTR + YCONV + DXP + TTR + UTR) / 4 | ||
176 | */ | ||
177 | tsc_writel(tsc, LPC32XX_TSC_RTR, 0x2); | ||
178 | tsc_writel(tsc, LPC32XX_TSC_DTR, 0x2); | ||
179 | tsc_writel(tsc, LPC32XX_TSC_TTR, 0x10); | ||
180 | tsc_writel(tsc, LPC32XX_TSC_DXP, 0x4); | ||
181 | tsc_writel(tsc, LPC32XX_TSC_UTR, 88); | ||
182 | |||
183 | lpc32xx_fifo_clear(tsc); | ||
184 | |||
185 | /* Enable automatic ts event capture */ | ||
186 | tsc_writel(tsc, LPC32XX_TSC_CON, tmp | LPC32XX_TSC_ADCCON_AUTO_EN); | ||
187 | } | ||
188 | |||
189 | static int lpc32xx_ts_open(struct input_dev *dev) | ||
190 | { | ||
191 | struct lpc32xx_tsc *tsc = input_get_drvdata(dev); | ||
192 | |||
193 | lpc32xx_setup_tsc(tsc); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static void lpc32xx_ts_close(struct input_dev *dev) | ||
199 | { | ||
200 | struct lpc32xx_tsc *tsc = input_get_drvdata(dev); | ||
201 | |||
202 | lpc32xx_stop_tsc(tsc); | ||
203 | } | ||
204 | |||
205 | static int __devinit lpc32xx_ts_probe(struct platform_device *pdev) | ||
206 | { | ||
207 | struct lpc32xx_tsc *tsc; | ||
208 | struct input_dev *input; | ||
209 | struct resource *res; | ||
210 | resource_size_t size; | ||
211 | int irq; | ||
212 | int error; | ||
213 | |||
214 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
215 | if (!res) { | ||
216 | dev_err(&pdev->dev, "Can't get memory resource\n"); | ||
217 | return -ENOENT; | ||
218 | } | ||
219 | |||
220 | irq = platform_get_irq(pdev, 0); | ||
221 | if (irq < 0) { | ||
222 | dev_err(&pdev->dev, "Can't get interrupt resource\n"); | ||
223 | return irq; | ||
224 | } | ||
225 | |||
226 | tsc = kzalloc(sizeof(*tsc), GFP_KERNEL); | ||
227 | input = input_allocate_device(); | ||
228 | if (!tsc || !input) { | ||
229 | dev_err(&pdev->dev, "failed allocating memory\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | tsc->dev = input; | ||
235 | tsc->irq = irq; | ||
236 | |||
237 | size = resource_size(res); | ||
238 | |||
239 | if (!request_mem_region(res->start, size, pdev->name)) { | ||
240 | dev_err(&pdev->dev, "TSC registers are not free\n"); | ||
241 | error = -EBUSY; | ||
242 | goto err_free_mem; | ||
243 | } | ||
244 | |||
245 | tsc->tsc_base = ioremap(res->start, size); | ||
246 | if (!tsc->tsc_base) { | ||
247 | dev_err(&pdev->dev, "Can't map memory\n"); | ||
248 | error = -ENOMEM; | ||
249 | goto err_release_mem; | ||
250 | } | ||
251 | |||
252 | tsc->clk = clk_get(&pdev->dev, NULL); | ||
253 | if (IS_ERR(tsc->clk)) { | ||
254 | dev_err(&pdev->dev, "failed getting clock\n"); | ||
255 | error = PTR_ERR(tsc->clk); | ||
256 | goto err_unmap; | ||
257 | } | ||
258 | |||
259 | input->name = MOD_NAME; | ||
260 | input->phys = "lpc32xx/input0"; | ||
261 | input->id.bustype = BUS_HOST; | ||
262 | input->id.vendor = 0x0001; | ||
263 | input->id.product = 0x0002; | ||
264 | input->id.version = 0x0100; | ||
265 | input->dev.parent = &pdev->dev; | ||
266 | input->open = lpc32xx_ts_open; | ||
267 | input->close = lpc32xx_ts_close; | ||
268 | |||
269 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
270 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
271 | input_set_abs_params(input, ABS_X, LPC32XX_TSC_MIN_XY_VAL, | ||
272 | LPC32XX_TSC_MAX_XY_VAL, 0, 0); | ||
273 | input_set_abs_params(input, ABS_Y, LPC32XX_TSC_MIN_XY_VAL, | ||
274 | LPC32XX_TSC_MAX_XY_VAL, 0, 0); | ||
275 | |||
276 | input_set_drvdata(input, tsc); | ||
277 | |||
278 | error = request_irq(tsc->irq, lpc32xx_ts_interrupt, | ||
279 | IRQF_DISABLED, pdev->name, tsc); | ||
280 | if (error) { | ||
281 | dev_err(&pdev->dev, "failed requesting interrupt\n"); | ||
282 | goto err_put_clock; | ||
283 | } | ||
284 | |||
285 | error = input_register_device(input); | ||
286 | if (error) { | ||
287 | dev_err(&pdev->dev, "failed registering input device\n"); | ||
288 | goto err_free_irq; | ||
289 | } | ||
290 | |||
291 | platform_set_drvdata(pdev, tsc); | ||
292 | device_init_wakeup(&pdev->dev, 1); | ||
293 | |||
294 | return 0; | ||
295 | |||
296 | err_free_irq: | ||
297 | free_irq(tsc->irq, tsc); | ||
298 | err_put_clock: | ||
299 | clk_put(tsc->clk); | ||
300 | err_unmap: | ||
301 | iounmap(tsc->tsc_base); | ||
302 | err_release_mem: | ||
303 | release_mem_region(res->start, size); | ||
304 | err_free_mem: | ||
305 | input_free_device(input); | ||
306 | kfree(tsc); | ||
307 | |||
308 | return error; | ||
309 | } | ||
310 | |||
311 | static int __devexit lpc32xx_ts_remove(struct platform_device *pdev) | ||
312 | { | ||
313 | struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev); | ||
314 | struct resource *res; | ||
315 | |||
316 | device_init_wakeup(&pdev->dev, 0); | ||
317 | free_irq(tsc->irq, tsc); | ||
318 | |||
319 | input_unregister_device(tsc->dev); | ||
320 | |||
321 | clk_put(tsc->clk); | ||
322 | |||
323 | iounmap(tsc->tsc_base); | ||
324 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
325 | release_mem_region(res->start, resource_size(res)); | ||
326 | |||
327 | kfree(tsc); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | #ifdef CONFIG_PM | ||
333 | static int lpc32xx_ts_suspend(struct device *dev) | ||
334 | { | ||
335 | struct lpc32xx_tsc *tsc = dev_get_drvdata(dev); | ||
336 | struct input_dev *input = tsc->dev; | ||
337 | |||
338 | /* | ||
339 | * Suspend and resume can be called when the device hasn't been | ||
340 | * enabled. If there are no users that have the device open, then | ||
341 | * avoid calling the TSC stop and start functions as the TSC | ||
342 | * isn't yet clocked. | ||
343 | */ | ||
344 | mutex_lock(&input->mutex); | ||
345 | |||
346 | if (input->users) { | ||
347 | if (device_may_wakeup(dev)) | ||
348 | enable_irq_wake(tsc->irq); | ||
349 | else | ||
350 | lpc32xx_stop_tsc(tsc); | ||
351 | } | ||
352 | |||
353 | mutex_unlock(&input->mutex); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int lpc32xx_ts_resume(struct device *dev) | ||
359 | { | ||
360 | struct lpc32xx_tsc *tsc = dev_get_drvdata(dev); | ||
361 | struct input_dev *input = tsc->dev; | ||
362 | |||
363 | mutex_lock(&input->mutex); | ||
364 | |||
365 | if (input->users) { | ||
366 | if (device_may_wakeup(dev)) | ||
367 | disable_irq_wake(tsc->irq); | ||
368 | else | ||
369 | lpc32xx_setup_tsc(tsc); | ||
370 | } | ||
371 | |||
372 | mutex_unlock(&input->mutex); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static const struct dev_pm_ops lpc32xx_ts_pm_ops = { | ||
378 | .suspend = lpc32xx_ts_suspend, | ||
379 | .resume = lpc32xx_ts_resume, | ||
380 | }; | ||
381 | #define LPC32XX_TS_PM_OPS (&lpc32xx_ts_pm_ops) | ||
382 | #else | ||
383 | #define LPC32XX_TS_PM_OPS NULL | ||
384 | #endif | ||
385 | |||
386 | static struct platform_driver lpc32xx_ts_driver = { | ||
387 | .probe = lpc32xx_ts_probe, | ||
388 | .remove = __devexit_p(lpc32xx_ts_remove), | ||
389 | .driver = { | ||
390 | .name = MOD_NAME, | ||
391 | .owner = THIS_MODULE, | ||
392 | .pm = LPC32XX_TS_PM_OPS, | ||
393 | }, | ||
394 | }; | ||
395 | |||
396 | static int __init lpc32xx_ts_init(void) | ||
397 | { | ||
398 | return platform_driver_register(&lpc32xx_ts_driver); | ||
399 | } | ||
400 | module_init(lpc32xx_ts_init); | ||
401 | |||
402 | static void __exit lpc32xx_ts_exit(void) | ||
403 | { | ||
404 | platform_driver_unregister(&lpc32xx_ts_driver); | ||
405 | } | ||
406 | module_exit(lpc32xx_ts_exit); | ||
407 | |||
408 | MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com"); | ||
409 | MODULE_DESCRIPTION("LPC32XX TSC Driver"); | ||
410 | MODULE_LICENSE("GPL"); | ||
411 | MODULE_ALIAS("platform:lpc32xx_ts"); | ||
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index b6b8b1c7ecea..3242e7076258 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c | |||
@@ -219,7 +219,7 @@ static int wm97xx_acc_startup(struct wm97xx *wm) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | wm->pen_irq = gpio_to_irq(irq); | 221 | wm->pen_irq = gpio_to_irq(irq); |
222 | set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH); | 222 | irq_set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH); |
223 | } else /* pen irq not supported */ | 223 | } else /* pen irq not supported */ |
224 | pen_int = 0; | 224 | pen_int = 0; |
225 | 225 | ||
diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c new file mode 100644 index 000000000000..4f2713d92791 --- /dev/null +++ b/drivers/input/touchscreen/max11801_ts.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | * Driver for MAXI MAX11801 - A Resistive touch screen controller with | ||
3 | * i2c interface | ||
4 | * | ||
5 | * Copyright (C) 2011 Freescale Semiconductor, Inc. | ||
6 | * Author: Zhang Jiejing <jiejing.zhang@freescale.com> | ||
7 | * | ||
8 | * Based on mcs5000_ts.c | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License. | ||
13 | */ | ||
14 | |||
15 | /* | ||
16 | * This driver aims to support the series of MAXI touch chips max11801 | ||
17 | * through max11803. The main difference between these 4 chips can be | ||
18 | * found in the table below: | ||
19 | * ----------------------------------------------------- | ||
20 | * | CHIP | AUTO MODE SUPPORT(FIFO) | INTERFACE | | ||
21 | * |----------------------------------------------------| | ||
22 | * | max11800 | YES | SPI | | ||
23 | * | max11801 | YES | I2C | | ||
24 | * | max11802 | NO | SPI | | ||
25 | * | max11803 | NO | I2C | | ||
26 | * ------------------------------------------------------ | ||
27 | * | ||
28 | * Currently, this driver only supports max11801. | ||
29 | * | ||
30 | * Data Sheet: | ||
31 | * http://www.maxim-ic.com/datasheet/index.mvp/id/5943 | ||
32 | */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/i2c.h> | ||
37 | #include <linux/interrupt.h> | ||
38 | #include <linux/input.h> | ||
39 | #include <linux/slab.h> | ||
40 | #include <linux/bitops.h> | ||
41 | |||
42 | /* Register Address define */ | ||
43 | #define GENERNAL_STATUS_REG 0x00 | ||
44 | #define GENERNAL_CONF_REG 0x01 | ||
45 | #define MESURE_RES_CONF_REG 0x02 | ||
46 | #define MESURE_AVER_CONF_REG 0x03 | ||
47 | #define ADC_SAMPLE_TIME_CONF_REG 0x04 | ||
48 | #define PANEL_SETUPTIME_CONF_REG 0x05 | ||
49 | #define DELAY_CONVERSION_CONF_REG 0x06 | ||
50 | #define TOUCH_DETECT_PULLUP_CONF_REG 0x07 | ||
51 | #define AUTO_MODE_TIME_CONF_REG 0x08 /* only for max11800/max11801 */ | ||
52 | #define APERTURE_CONF_REG 0x09 /* only for max11800/max11801 */ | ||
53 | #define AUX_MESURE_CONF_REG 0x0a | ||
54 | #define OP_MODE_CONF_REG 0x0b | ||
55 | |||
56 | /* FIFO is found only in max11800 and max11801 */ | ||
57 | #define FIFO_RD_CMD (0x50 << 1) | ||
58 | #define MAX11801_FIFO_INT (1 << 2) | ||
59 | #define MAX11801_FIFO_OVERFLOW (1 << 3) | ||
60 | |||
61 | #define XY_BUFSIZE 4 | ||
62 | #define XY_BUF_OFFSET 4 | ||
63 | |||
64 | #define MAX11801_MAX_X 0xfff | ||
65 | #define MAX11801_MAX_Y 0xfff | ||
66 | |||
67 | #define MEASURE_TAG_OFFSET 2 | ||
68 | #define MEASURE_TAG_MASK (3 << MEASURE_TAG_OFFSET) | ||
69 | #define EVENT_TAG_OFFSET 0 | ||
70 | #define EVENT_TAG_MASK (3 << EVENT_TAG_OFFSET) | ||
71 | #define MEASURE_X_TAG (0 << MEASURE_TAG_OFFSET) | ||
72 | #define MEASURE_Y_TAG (1 << MEASURE_TAG_OFFSET) | ||
73 | |||
74 | /* These are the state of touch event state machine */ | ||
75 | enum { | ||
76 | EVENT_INIT, | ||
77 | EVENT_MIDDLE, | ||
78 | EVENT_RELEASE, | ||
79 | EVENT_FIFO_END | ||
80 | }; | ||
81 | |||
82 | struct max11801_data { | ||
83 | struct i2c_client *client; | ||
84 | struct input_dev *input_dev; | ||
85 | }; | ||
86 | |||
87 | static u8 read_register(struct i2c_client *client, int addr) | ||
88 | { | ||
89 | /* XXX: The chip ignores LSB of register address */ | ||
90 | return i2c_smbus_read_byte_data(client, addr << 1); | ||
91 | } | ||
92 | |||
93 | static int max11801_write_reg(struct i2c_client *client, int addr, int data) | ||
94 | { | ||
95 | /* XXX: The chip ignores LSB of register address */ | ||
96 | return i2c_smbus_write_byte_data(client, addr << 1, data); | ||
97 | } | ||
98 | |||
99 | static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id) | ||
100 | { | ||
101 | struct max11801_data *data = dev_id; | ||
102 | struct i2c_client *client = data->client; | ||
103 | int status, i, ret; | ||
104 | u8 buf[XY_BUFSIZE]; | ||
105 | int x = -1; | ||
106 | int y = -1; | ||
107 | |||
108 | status = read_register(data->client, GENERNAL_STATUS_REG); | ||
109 | |||
110 | if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) { | ||
111 | status = read_register(data->client, GENERNAL_STATUS_REG); | ||
112 | |||
113 | ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD, | ||
114 | XY_BUFSIZE, buf); | ||
115 | |||
116 | /* | ||
117 | * We should get 4 bytes buffer that contains X,Y | ||
118 | * and event tag | ||
119 | */ | ||
120 | if (ret < XY_BUFSIZE) | ||
121 | goto out; | ||
122 | |||
123 | for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) { | ||
124 | if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG) | ||
125 | x = (buf[i] << XY_BUF_OFFSET) + | ||
126 | (buf[i + 1] >> XY_BUF_OFFSET); | ||
127 | else if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG) | ||
128 | y = (buf[i] << XY_BUF_OFFSET) + | ||
129 | (buf[i + 1] >> XY_BUF_OFFSET); | ||
130 | } | ||
131 | |||
132 | if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK)) | ||
133 | goto out; | ||
134 | |||
135 | switch (buf[1] & EVENT_TAG_MASK) { | ||
136 | case EVENT_INIT: | ||
137 | /* fall through */ | ||
138 | case EVENT_MIDDLE: | ||
139 | input_report_abs(data->input_dev, ABS_X, x); | ||
140 | input_report_abs(data->input_dev, ABS_Y, y); | ||
141 | input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1); | ||
142 | input_sync(data->input_dev); | ||
143 | break; | ||
144 | |||
145 | case EVENT_RELEASE: | ||
146 | input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0); | ||
147 | input_sync(data->input_dev); | ||
148 | break; | ||
149 | |||
150 | case EVENT_FIFO_END: | ||
151 | break; | ||
152 | } | ||
153 | } | ||
154 | out: | ||
155 | return IRQ_HANDLED; | ||
156 | } | ||
157 | |||
158 | static void __devinit max11801_ts_phy_init(struct max11801_data *data) | ||
159 | { | ||
160 | struct i2c_client *client = data->client; | ||
161 | |||
162 | /* Average X,Y, take 16 samples, average eight media sample */ | ||
163 | max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff); | ||
164 | /* X,Y panel setup time set to 20us */ | ||
165 | max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11); | ||
166 | /* Rough pullup time (2uS), Fine pullup time (10us) */ | ||
167 | max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10); | ||
168 | /* Auto mode init period = 5ms , scan period = 5ms*/ | ||
169 | max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa); | ||
170 | /* Aperture X,Y set to +- 4LSB */ | ||
171 | max11801_write_reg(client, APERTURE_CONF_REG, 0x33); | ||
172 | /* Enable Power, enable Automode, enable Aperture, enable Average X,Y */ | ||
173 | max11801_write_reg(client, OP_MODE_CONF_REG, 0x36); | ||
174 | } | ||
175 | |||
176 | static int __devinit max11801_ts_probe(struct i2c_client *client, | ||
177 | const struct i2c_device_id *id) | ||
178 | { | ||
179 | struct max11801_data *data; | ||
180 | struct input_dev *input_dev; | ||
181 | int error; | ||
182 | |||
183 | data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL); | ||
184 | input_dev = input_allocate_device(); | ||
185 | if (!data || !input_dev) { | ||
186 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
187 | error = -ENOMEM; | ||
188 | goto err_free_mem; | ||
189 | } | ||
190 | |||
191 | data->client = client; | ||
192 | data->input_dev = input_dev; | ||
193 | |||
194 | input_dev->name = "max11801_ts"; | ||
195 | input_dev->id.bustype = BUS_I2C; | ||
196 | input_dev->dev.parent = &client->dev; | ||
197 | |||
198 | __set_bit(EV_ABS, input_dev->evbit); | ||
199 | __set_bit(EV_KEY, input_dev->evbit); | ||
200 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
201 | input_set_abs_params(input_dev, ABS_X, 0, MAX11801_MAX_X, 0, 0); | ||
202 | input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0); | ||
203 | input_set_drvdata(input_dev, data); | ||
204 | |||
205 | max11801_ts_phy_init(data); | ||
206 | |||
207 | error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt, | ||
208 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
209 | "max11801_ts", data); | ||
210 | if (error) { | ||
211 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
212 | goto err_free_mem; | ||
213 | } | ||
214 | |||
215 | error = input_register_device(data->input_dev); | ||
216 | if (error) | ||
217 | goto err_free_irq; | ||
218 | |||
219 | i2c_set_clientdata(client, data); | ||
220 | return 0; | ||
221 | |||
222 | err_free_irq: | ||
223 | free_irq(client->irq, data); | ||
224 | err_free_mem: | ||
225 | input_free_device(input_dev); | ||
226 | kfree(data); | ||
227 | return error; | ||
228 | } | ||
229 | |||
230 | static __devexit int max11801_ts_remove(struct i2c_client *client) | ||
231 | { | ||
232 | struct max11801_data *data = i2c_get_clientdata(client); | ||
233 | |||
234 | free_irq(client->irq, data); | ||
235 | input_unregister_device(data->input_dev); | ||
236 | kfree(data); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static const struct i2c_device_id max11801_ts_id[] = { | ||
242 | {"max11801", 0}, | ||
243 | { } | ||
244 | }; | ||
245 | MODULE_DEVICE_TABLE(i2c, max11801_ts_id); | ||
246 | |||
247 | static struct i2c_driver max11801_ts_driver = { | ||
248 | .driver = { | ||
249 | .name = "max11801_ts", | ||
250 | .owner = THIS_MODULE, | ||
251 | }, | ||
252 | .id_table = max11801_ts_id, | ||
253 | .probe = max11801_ts_probe, | ||
254 | .remove = __devexit_p(max11801_ts_remove), | ||
255 | }; | ||
256 | |||
257 | static int __init max11801_ts_init(void) | ||
258 | { | ||
259 | return i2c_add_driver(&max11801_ts_driver); | ||
260 | } | ||
261 | |||
262 | static void __exit max11801_ts_exit(void) | ||
263 | { | ||
264 | i2c_del_driver(&max11801_ts_driver); | ||
265 | } | ||
266 | |||
267 | module_init(max11801_ts_init); | ||
268 | module_exit(max11801_ts_exit); | ||
269 | |||
270 | MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>"); | ||
271 | MODULE_DESCRIPTION("Touchscreen driver for MAXI MAX11801 controller"); | ||
272 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 6ee9940aaf5b..2d84c80ceb66 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c | |||
@@ -261,25 +261,27 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client) | |||
261 | } | 261 | } |
262 | 262 | ||
263 | #ifdef CONFIG_PM | 263 | #ifdef CONFIG_PM |
264 | static int mcs5000_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 264 | static int mcs5000_ts_suspend(struct device *dev) |
265 | { | 265 | { |
266 | struct i2c_client *client = to_i2c_client(dev); | ||
267 | |||
266 | /* Touch sleep mode */ | 268 | /* Touch sleep mode */ |
267 | i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); | 269 | i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); |
268 | 270 | ||
269 | return 0; | 271 | return 0; |
270 | } | 272 | } |
271 | 273 | ||
272 | static int mcs5000_ts_resume(struct i2c_client *client) | 274 | static int mcs5000_ts_resume(struct device *dev) |
273 | { | 275 | { |
276 | struct i2c_client *client = to_i2c_client(dev); | ||
274 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | 277 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); |
275 | 278 | ||
276 | mcs5000_ts_phys_init(data); | 279 | mcs5000_ts_phys_init(data); |
277 | 280 | ||
278 | return 0; | 281 | return 0; |
279 | } | 282 | } |
280 | #else | 283 | |
281 | #define mcs5000_ts_suspend NULL | 284 | static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume); |
282 | #define mcs5000_ts_resume NULL | ||
283 | #endif | 285 | #endif |
284 | 286 | ||
285 | static const struct i2c_device_id mcs5000_ts_id[] = { | 287 | static const struct i2c_device_id mcs5000_ts_id[] = { |
@@ -291,10 +293,11 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); | |||
291 | static struct i2c_driver mcs5000_ts_driver = { | 293 | static struct i2c_driver mcs5000_ts_driver = { |
292 | .probe = mcs5000_ts_probe, | 294 | .probe = mcs5000_ts_probe, |
293 | .remove = __devexit_p(mcs5000_ts_remove), | 295 | .remove = __devexit_p(mcs5000_ts_remove), |
294 | .suspend = mcs5000_ts_suspend, | ||
295 | .resume = mcs5000_ts_resume, | ||
296 | .driver = { | 296 | .driver = { |
297 | .name = "mcs5000_ts", | 297 | .name = "mcs5000_ts", |
298 | #ifdef CONFIG_PM | ||
299 | .pm = &mcs5000_ts_pm, | ||
300 | #endif | ||
298 | }, | 301 | }, |
299 | .id_table = mcs5000_ts_id, | 302 | .id_table = mcs5000_ts_id, |
300 | }; | 303 | }; |
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index defe5dd3627c..5803bd0c1cca 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/pm.h> | ||
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
@@ -226,8 +227,9 @@ static int migor_ts_remove(struct i2c_client *client) | |||
226 | return 0; | 227 | return 0; |
227 | } | 228 | } |
228 | 229 | ||
229 | static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 230 | static int migor_ts_suspend(struct device *dev) |
230 | { | 231 | { |
232 | struct i2c_client *client = to_i2c_client(dev); | ||
231 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | 233 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); |
232 | 234 | ||
233 | if (device_may_wakeup(&client->dev)) | 235 | if (device_may_wakeup(&client->dev)) |
@@ -236,8 +238,9 @@ static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
236 | return 0; | 238 | return 0; |
237 | } | 239 | } |
238 | 240 | ||
239 | static int migor_ts_resume(struct i2c_client *client) | 241 | static int migor_ts_resume(struct device *dev) |
240 | { | 242 | { |
243 | struct i2c_client *client = to_i2c_client(dev); | ||
241 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | 244 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); |
242 | 245 | ||
243 | if (device_may_wakeup(&client->dev)) | 246 | if (device_may_wakeup(&client->dev)) |
@@ -246,6 +249,8 @@ static int migor_ts_resume(struct i2c_client *client) | |||
246 | return 0; | 249 | return 0; |
247 | } | 250 | } |
248 | 251 | ||
252 | static SIMPLE_DEV_PM_OPS(migor_ts_pm, migor_ts_suspend, migor_ts_resume); | ||
253 | |||
249 | static const struct i2c_device_id migor_ts_id[] = { | 254 | static const struct i2c_device_id migor_ts_id[] = { |
250 | { "migor_ts", 0 }, | 255 | { "migor_ts", 0 }, |
251 | { } | 256 | { } |
@@ -255,11 +260,10 @@ MODULE_DEVICE_TABLE(i2c, migor_ts); | |||
255 | static struct i2c_driver migor_ts_driver = { | 260 | static struct i2c_driver migor_ts_driver = { |
256 | .driver = { | 261 | .driver = { |
257 | .name = "migor_ts", | 262 | .name = "migor_ts", |
263 | .pm = &migor_ts_pm, | ||
258 | }, | 264 | }, |
259 | .probe = migor_ts_probe, | 265 | .probe = migor_ts_probe, |
260 | .remove = migor_ts_remove, | 266 | .remove = migor_ts_remove, |
261 | .suspend = migor_ts_suspend, | ||
262 | .resume = migor_ts_resume, | ||
263 | .id_table = migor_ts_id, | 267 | .id_table = migor_ts_id, |
264 | }; | 268 | }; |
265 | 269 | ||
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index efd3aebaba5f..36e57deacd03 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * found in Gateway AOL Connected Touchpad computers. | 17 | * found in Gateway AOL Connected Touchpad computers. |
18 | * | 18 | * |
19 | * Documentation for ICS MK712 can be found at: | 19 | * Documentation for ICS MK712 can be found at: |
20 | * http://www.icst.com/pdf/mk712.pdf | 20 | * http://www.idt.com/products/getDoc.cfm?docID=18713923 |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* | 23 | /* |
diff --git a/drivers/input/touchscreen/qt602240_ts.c b/drivers/input/touchscreen/qt602240_ts.c deleted file mode 100644 index 66b26ad3032a..000000000000 --- a/drivers/input/touchscreen/qt602240_ts.c +++ /dev/null | |||
@@ -1,1401 +0,0 @@ | |||
1 | /* | ||
2 | * AT42QT602240/ATMXT224 Touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/firmware.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/i2c/qt602240_ts.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | /* Version */ | ||
25 | #define QT602240_VER_20 20 | ||
26 | #define QT602240_VER_21 21 | ||
27 | #define QT602240_VER_22 22 | ||
28 | |||
29 | /* Slave addresses */ | ||
30 | #define QT602240_APP_LOW 0x4a | ||
31 | #define QT602240_APP_HIGH 0x4b | ||
32 | #define QT602240_BOOT_LOW 0x24 | ||
33 | #define QT602240_BOOT_HIGH 0x25 | ||
34 | |||
35 | /* Firmware */ | ||
36 | #define QT602240_FW_NAME "qt602240.fw" | ||
37 | |||
38 | /* Registers */ | ||
39 | #define QT602240_FAMILY_ID 0x00 | ||
40 | #define QT602240_VARIANT_ID 0x01 | ||
41 | #define QT602240_VERSION 0x02 | ||
42 | #define QT602240_BUILD 0x03 | ||
43 | #define QT602240_MATRIX_X_SIZE 0x04 | ||
44 | #define QT602240_MATRIX_Y_SIZE 0x05 | ||
45 | #define QT602240_OBJECT_NUM 0x06 | ||
46 | #define QT602240_OBJECT_START 0x07 | ||
47 | |||
48 | #define QT602240_OBJECT_SIZE 6 | ||
49 | |||
50 | /* Object types */ | ||
51 | #define QT602240_DEBUG_DIAGNOSTIC 37 | ||
52 | #define QT602240_GEN_MESSAGE 5 | ||
53 | #define QT602240_GEN_COMMAND 6 | ||
54 | #define QT602240_GEN_POWER 7 | ||
55 | #define QT602240_GEN_ACQUIRE 8 | ||
56 | #define QT602240_TOUCH_MULTI 9 | ||
57 | #define QT602240_TOUCH_KEYARRAY 15 | ||
58 | #define QT602240_TOUCH_PROXIMITY 23 | ||
59 | #define QT602240_PROCI_GRIPFACE 20 | ||
60 | #define QT602240_PROCG_NOISE 22 | ||
61 | #define QT602240_PROCI_ONETOUCH 24 | ||
62 | #define QT602240_PROCI_TWOTOUCH 27 | ||
63 | #define QT602240_SPT_COMMSCONFIG 18 /* firmware ver 21 over */ | ||
64 | #define QT602240_SPT_GPIOPWM 19 | ||
65 | #define QT602240_SPT_SELFTEST 25 | ||
66 | #define QT602240_SPT_CTECONFIG 28 | ||
67 | #define QT602240_SPT_USERDATA 38 /* firmware ver 21 over */ | ||
68 | |||
69 | /* QT602240_GEN_COMMAND field */ | ||
70 | #define QT602240_COMMAND_RESET 0 | ||
71 | #define QT602240_COMMAND_BACKUPNV 1 | ||
72 | #define QT602240_COMMAND_CALIBRATE 2 | ||
73 | #define QT602240_COMMAND_REPORTALL 3 | ||
74 | #define QT602240_COMMAND_DIAGNOSTIC 5 | ||
75 | |||
76 | /* QT602240_GEN_POWER field */ | ||
77 | #define QT602240_POWER_IDLEACQINT 0 | ||
78 | #define QT602240_POWER_ACTVACQINT 1 | ||
79 | #define QT602240_POWER_ACTV2IDLETO 2 | ||
80 | |||
81 | /* QT602240_GEN_ACQUIRE field */ | ||
82 | #define QT602240_ACQUIRE_CHRGTIME 0 | ||
83 | #define QT602240_ACQUIRE_TCHDRIFT 2 | ||
84 | #define QT602240_ACQUIRE_DRIFTST 3 | ||
85 | #define QT602240_ACQUIRE_TCHAUTOCAL 4 | ||
86 | #define QT602240_ACQUIRE_SYNC 5 | ||
87 | #define QT602240_ACQUIRE_ATCHCALST 6 | ||
88 | #define QT602240_ACQUIRE_ATCHCALSTHR 7 | ||
89 | |||
90 | /* QT602240_TOUCH_MULTI field */ | ||
91 | #define QT602240_TOUCH_CTRL 0 | ||
92 | #define QT602240_TOUCH_XORIGIN 1 | ||
93 | #define QT602240_TOUCH_YORIGIN 2 | ||
94 | #define QT602240_TOUCH_XSIZE 3 | ||
95 | #define QT602240_TOUCH_YSIZE 4 | ||
96 | #define QT602240_TOUCH_BLEN 6 | ||
97 | #define QT602240_TOUCH_TCHTHR 7 | ||
98 | #define QT602240_TOUCH_TCHDI 8 | ||
99 | #define QT602240_TOUCH_ORIENT 9 | ||
100 | #define QT602240_TOUCH_MOVHYSTI 11 | ||
101 | #define QT602240_TOUCH_MOVHYSTN 12 | ||
102 | #define QT602240_TOUCH_NUMTOUCH 14 | ||
103 | #define QT602240_TOUCH_MRGHYST 15 | ||
104 | #define QT602240_TOUCH_MRGTHR 16 | ||
105 | #define QT602240_TOUCH_AMPHYST 17 | ||
106 | #define QT602240_TOUCH_XRANGE_LSB 18 | ||
107 | #define QT602240_TOUCH_XRANGE_MSB 19 | ||
108 | #define QT602240_TOUCH_YRANGE_LSB 20 | ||
109 | #define QT602240_TOUCH_YRANGE_MSB 21 | ||
110 | #define QT602240_TOUCH_XLOCLIP 22 | ||
111 | #define QT602240_TOUCH_XHICLIP 23 | ||
112 | #define QT602240_TOUCH_YLOCLIP 24 | ||
113 | #define QT602240_TOUCH_YHICLIP 25 | ||
114 | #define QT602240_TOUCH_XEDGECTRL 26 | ||
115 | #define QT602240_TOUCH_XEDGEDIST 27 | ||
116 | #define QT602240_TOUCH_YEDGECTRL 28 | ||
117 | #define QT602240_TOUCH_YEDGEDIST 29 | ||
118 | #define QT602240_TOUCH_JUMPLIMIT 30 /* firmware ver 22 over */ | ||
119 | |||
120 | /* QT602240_PROCI_GRIPFACE field */ | ||
121 | #define QT602240_GRIPFACE_CTRL 0 | ||
122 | #define QT602240_GRIPFACE_XLOGRIP 1 | ||
123 | #define QT602240_GRIPFACE_XHIGRIP 2 | ||
124 | #define QT602240_GRIPFACE_YLOGRIP 3 | ||
125 | #define QT602240_GRIPFACE_YHIGRIP 4 | ||
126 | #define QT602240_GRIPFACE_MAXTCHS 5 | ||
127 | #define QT602240_GRIPFACE_SZTHR1 7 | ||
128 | #define QT602240_GRIPFACE_SZTHR2 8 | ||
129 | #define QT602240_GRIPFACE_SHPTHR1 9 | ||
130 | #define QT602240_GRIPFACE_SHPTHR2 10 | ||
131 | #define QT602240_GRIPFACE_SUPEXTTO 11 | ||
132 | |||
133 | /* QT602240_PROCI_NOISE field */ | ||
134 | #define QT602240_NOISE_CTRL 0 | ||
135 | #define QT602240_NOISE_OUTFLEN 1 | ||
136 | #define QT602240_NOISE_GCAFUL_LSB 3 | ||
137 | #define QT602240_NOISE_GCAFUL_MSB 4 | ||
138 | #define QT602240_NOISE_GCAFLL_LSB 5 | ||
139 | #define QT602240_NOISE_GCAFLL_MSB 6 | ||
140 | #define QT602240_NOISE_ACTVGCAFVALID 7 | ||
141 | #define QT602240_NOISE_NOISETHR 8 | ||
142 | #define QT602240_NOISE_FREQHOPSCALE 10 | ||
143 | #define QT602240_NOISE_FREQ0 11 | ||
144 | #define QT602240_NOISE_FREQ1 12 | ||
145 | #define QT602240_NOISE_FREQ2 13 | ||
146 | #define QT602240_NOISE_FREQ3 14 | ||
147 | #define QT602240_NOISE_FREQ4 15 | ||
148 | #define QT602240_NOISE_IDLEGCAFVALID 16 | ||
149 | |||
150 | /* QT602240_SPT_COMMSCONFIG */ | ||
151 | #define QT602240_COMMS_CTRL 0 | ||
152 | #define QT602240_COMMS_CMD 1 | ||
153 | |||
154 | /* QT602240_SPT_CTECONFIG field */ | ||
155 | #define QT602240_CTE_CTRL 0 | ||
156 | #define QT602240_CTE_CMD 1 | ||
157 | #define QT602240_CTE_MODE 2 | ||
158 | #define QT602240_CTE_IDLEGCAFDEPTH 3 | ||
159 | #define QT602240_CTE_ACTVGCAFDEPTH 4 | ||
160 | #define QT602240_CTE_VOLTAGE 5 /* firmware ver 21 over */ | ||
161 | |||
162 | #define QT602240_VOLTAGE_DEFAULT 2700000 | ||
163 | #define QT602240_VOLTAGE_STEP 10000 | ||
164 | |||
165 | /* Define for QT602240_GEN_COMMAND */ | ||
166 | #define QT602240_BOOT_VALUE 0xa5 | ||
167 | #define QT602240_BACKUP_VALUE 0x55 | ||
168 | #define QT602240_BACKUP_TIME 25 /* msec */ | ||
169 | #define QT602240_RESET_TIME 65 /* msec */ | ||
170 | |||
171 | #define QT602240_FWRESET_TIME 175 /* msec */ | ||
172 | |||
173 | /* Command to unlock bootloader */ | ||
174 | #define QT602240_UNLOCK_CMD_MSB 0xaa | ||
175 | #define QT602240_UNLOCK_CMD_LSB 0xdc | ||
176 | |||
177 | /* Bootloader mode status */ | ||
178 | #define QT602240_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */ | ||
179 | #define QT602240_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */ | ||
180 | #define QT602240_FRAME_CRC_CHECK 0x02 | ||
181 | #define QT602240_FRAME_CRC_FAIL 0x03 | ||
182 | #define QT602240_FRAME_CRC_PASS 0x04 | ||
183 | #define QT602240_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */ | ||
184 | #define QT602240_BOOT_STATUS_MASK 0x3f | ||
185 | |||
186 | /* Touch status */ | ||
187 | #define QT602240_SUPPRESS (1 << 1) | ||
188 | #define QT602240_AMP (1 << 2) | ||
189 | #define QT602240_VECTOR (1 << 3) | ||
190 | #define QT602240_MOVE (1 << 4) | ||
191 | #define QT602240_RELEASE (1 << 5) | ||
192 | #define QT602240_PRESS (1 << 6) | ||
193 | #define QT602240_DETECT (1 << 7) | ||
194 | |||
195 | /* Touchscreen absolute values */ | ||
196 | #define QT602240_MAX_XC 0x3ff | ||
197 | #define QT602240_MAX_YC 0x3ff | ||
198 | #define QT602240_MAX_AREA 0xff | ||
199 | |||
200 | #define QT602240_MAX_FINGER 10 | ||
201 | |||
202 | /* Initial register values recommended from chip vendor */ | ||
203 | static const u8 init_vals_ver_20[] = { | ||
204 | /* QT602240_GEN_COMMAND(6) */ | ||
205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
206 | /* QT602240_GEN_POWER(7) */ | ||
207 | 0x20, 0xff, 0x32, | ||
208 | /* QT602240_GEN_ACQUIRE(8) */ | ||
209 | 0x08, 0x05, 0x05, 0x00, 0x00, 0x00, 0x05, 0x14, | ||
210 | /* QT602240_TOUCH_MULTI(9) */ | ||
211 | 0x00, 0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
212 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
213 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x64, | ||
214 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
215 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
216 | 0x00, | ||
217 | /* QT602240_SPT_GPIOPWM(19) */ | ||
218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
219 | 0x00, 0x00, | ||
220 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
221 | 0x00, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x1e, 0x14, 0x04, | ||
222 | 0x1e, 0x00, | ||
223 | /* QT602240_PROCG_NOISE(22) */ | ||
224 | 0x05, 0x00, 0x00, 0x19, 0x00, 0xe7, 0xff, 0x04, 0x32, 0x00, | ||
225 | 0x01, 0x0a, 0x0f, 0x14, 0x00, 0x00, 0xe8, | ||
226 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
228 | 0x00, 0x00, 0x00, | ||
229 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
230 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
232 | /* QT602240_SPT_SELFTEST(25) */ | ||
233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
234 | 0x00, 0x00, 0x00, 0x00, | ||
235 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
237 | /* QT602240_SPT_CTECONFIG(28) */ | ||
238 | 0x00, 0x00, 0x00, 0x04, 0x08, | ||
239 | }; | ||
240 | |||
241 | static const u8 init_vals_ver_21[] = { | ||
242 | /* QT602240_GEN_COMMAND(6) */ | ||
243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
244 | /* QT602240_GEN_POWER(7) */ | ||
245 | 0x20, 0xff, 0x32, | ||
246 | /* QT602240_GEN_ACQUIRE(8) */ | ||
247 | 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, | ||
248 | /* QT602240_TOUCH_MULTI(9) */ | ||
249 | 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
250 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
252 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
254 | 0x00, | ||
255 | /* QT602240_SPT_GPIOPWM(19) */ | ||
256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
258 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
259 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, | ||
260 | 0x0f, 0x0a, | ||
261 | /* QT602240_PROCG_NOISE(22) */ | ||
262 | 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, | ||
263 | 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, | ||
264 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
266 | 0x00, 0x00, 0x00, | ||
267 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
268 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
269 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
270 | /* QT602240_SPT_SELFTEST(25) */ | ||
271 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
272 | 0x00, 0x00, 0x00, 0x00, | ||
273 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
274 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
275 | /* QT602240_SPT_CTECONFIG(28) */ | ||
276 | 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, | ||
277 | }; | ||
278 | |||
279 | static const u8 init_vals_ver_22[] = { | ||
280 | /* QT602240_GEN_COMMAND(6) */ | ||
281 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
282 | /* QT602240_GEN_POWER(7) */ | ||
283 | 0x20, 0xff, 0x32, | ||
284 | /* QT602240_GEN_ACQUIRE(8) */ | ||
285 | 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, | ||
286 | /* QT602240_TOUCH_MULTI(9) */ | ||
287 | 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
288 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
289 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
290 | 0x00, | ||
291 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
292 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
293 | 0x00, | ||
294 | /* QT602240_SPT_GPIOPWM(19) */ | ||
295 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
296 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
297 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
298 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, | ||
299 | 0x0f, 0x0a, | ||
300 | /* QT602240_PROCG_NOISE(22) */ | ||
301 | 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, | ||
302 | 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, | ||
303 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
304 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
305 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
306 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
307 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
308 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
309 | /* QT602240_SPT_SELFTEST(25) */ | ||
310 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
311 | 0x00, 0x00, 0x00, 0x00, | ||
312 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
313 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
314 | /* QT602240_SPT_CTECONFIG(28) */ | ||
315 | 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, | ||
316 | }; | ||
317 | |||
318 | struct qt602240_info { | ||
319 | u8 family_id; | ||
320 | u8 variant_id; | ||
321 | u8 version; | ||
322 | u8 build; | ||
323 | u8 matrix_xsize; | ||
324 | u8 matrix_ysize; | ||
325 | u8 object_num; | ||
326 | }; | ||
327 | |||
328 | struct qt602240_object { | ||
329 | u8 type; | ||
330 | u16 start_address; | ||
331 | u8 size; | ||
332 | u8 instances; | ||
333 | u8 num_report_ids; | ||
334 | |||
335 | /* to map object and message */ | ||
336 | u8 max_reportid; | ||
337 | }; | ||
338 | |||
339 | struct qt602240_message { | ||
340 | u8 reportid; | ||
341 | u8 message[7]; | ||
342 | u8 checksum; | ||
343 | }; | ||
344 | |||
345 | struct qt602240_finger { | ||
346 | int status; | ||
347 | int x; | ||
348 | int y; | ||
349 | int area; | ||
350 | }; | ||
351 | |||
352 | /* Each client has this additional data */ | ||
353 | struct qt602240_data { | ||
354 | struct i2c_client *client; | ||
355 | struct input_dev *input_dev; | ||
356 | const struct qt602240_platform_data *pdata; | ||
357 | struct qt602240_object *object_table; | ||
358 | struct qt602240_info info; | ||
359 | struct qt602240_finger finger[QT602240_MAX_FINGER]; | ||
360 | unsigned int irq; | ||
361 | }; | ||
362 | |||
363 | static bool qt602240_object_readable(unsigned int type) | ||
364 | { | ||
365 | switch (type) { | ||
366 | case QT602240_GEN_MESSAGE: | ||
367 | case QT602240_GEN_COMMAND: | ||
368 | case QT602240_GEN_POWER: | ||
369 | case QT602240_GEN_ACQUIRE: | ||
370 | case QT602240_TOUCH_MULTI: | ||
371 | case QT602240_TOUCH_KEYARRAY: | ||
372 | case QT602240_TOUCH_PROXIMITY: | ||
373 | case QT602240_PROCI_GRIPFACE: | ||
374 | case QT602240_PROCG_NOISE: | ||
375 | case QT602240_PROCI_ONETOUCH: | ||
376 | case QT602240_PROCI_TWOTOUCH: | ||
377 | case QT602240_SPT_COMMSCONFIG: | ||
378 | case QT602240_SPT_GPIOPWM: | ||
379 | case QT602240_SPT_SELFTEST: | ||
380 | case QT602240_SPT_CTECONFIG: | ||
381 | case QT602240_SPT_USERDATA: | ||
382 | return true; | ||
383 | default: | ||
384 | return false; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | static bool qt602240_object_writable(unsigned int type) | ||
389 | { | ||
390 | switch (type) { | ||
391 | case QT602240_GEN_COMMAND: | ||
392 | case QT602240_GEN_POWER: | ||
393 | case QT602240_GEN_ACQUIRE: | ||
394 | case QT602240_TOUCH_MULTI: | ||
395 | case QT602240_TOUCH_KEYARRAY: | ||
396 | case QT602240_TOUCH_PROXIMITY: | ||
397 | case QT602240_PROCI_GRIPFACE: | ||
398 | case QT602240_PROCG_NOISE: | ||
399 | case QT602240_PROCI_ONETOUCH: | ||
400 | case QT602240_PROCI_TWOTOUCH: | ||
401 | case QT602240_SPT_GPIOPWM: | ||
402 | case QT602240_SPT_SELFTEST: | ||
403 | case QT602240_SPT_CTECONFIG: | ||
404 | return true; | ||
405 | default: | ||
406 | return false; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void qt602240_dump_message(struct device *dev, | ||
411 | struct qt602240_message *message) | ||
412 | { | ||
413 | dev_dbg(dev, "reportid:\t0x%x\n", message->reportid); | ||
414 | dev_dbg(dev, "message1:\t0x%x\n", message->message[0]); | ||
415 | dev_dbg(dev, "message2:\t0x%x\n", message->message[1]); | ||
416 | dev_dbg(dev, "message3:\t0x%x\n", message->message[2]); | ||
417 | dev_dbg(dev, "message4:\t0x%x\n", message->message[3]); | ||
418 | dev_dbg(dev, "message5:\t0x%x\n", message->message[4]); | ||
419 | dev_dbg(dev, "message6:\t0x%x\n", message->message[5]); | ||
420 | dev_dbg(dev, "message7:\t0x%x\n", message->message[6]); | ||
421 | dev_dbg(dev, "checksum:\t0x%x\n", message->checksum); | ||
422 | } | ||
423 | |||
424 | static int qt602240_check_bootloader(struct i2c_client *client, | ||
425 | unsigned int state) | ||
426 | { | ||
427 | u8 val; | ||
428 | |||
429 | recheck: | ||
430 | if (i2c_master_recv(client, &val, 1) != 1) { | ||
431 | dev_err(&client->dev, "%s: i2c recv failed\n", __func__); | ||
432 | return -EIO; | ||
433 | } | ||
434 | |||
435 | switch (state) { | ||
436 | case QT602240_WAITING_BOOTLOAD_CMD: | ||
437 | case QT602240_WAITING_FRAME_DATA: | ||
438 | val &= ~QT602240_BOOT_STATUS_MASK; | ||
439 | break; | ||
440 | case QT602240_FRAME_CRC_PASS: | ||
441 | if (val == QT602240_FRAME_CRC_CHECK) | ||
442 | goto recheck; | ||
443 | break; | ||
444 | default: | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | if (val != state) { | ||
449 | dev_err(&client->dev, "Unvalid bootloader mode state\n"); | ||
450 | return -EINVAL; | ||
451 | } | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int qt602240_unlock_bootloader(struct i2c_client *client) | ||
457 | { | ||
458 | u8 buf[2]; | ||
459 | |||
460 | buf[0] = QT602240_UNLOCK_CMD_LSB; | ||
461 | buf[1] = QT602240_UNLOCK_CMD_MSB; | ||
462 | |||
463 | if (i2c_master_send(client, buf, 2) != 2) { | ||
464 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
465 | return -EIO; | ||
466 | } | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int qt602240_fw_write(struct i2c_client *client, | ||
472 | const u8 *data, unsigned int frame_size) | ||
473 | { | ||
474 | if (i2c_master_send(client, data, frame_size) != frame_size) { | ||
475 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
476 | return -EIO; | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int __qt602240_read_reg(struct i2c_client *client, | ||
483 | u16 reg, u16 len, void *val) | ||
484 | { | ||
485 | struct i2c_msg xfer[2]; | ||
486 | u8 buf[2]; | ||
487 | |||
488 | buf[0] = reg & 0xff; | ||
489 | buf[1] = (reg >> 8) & 0xff; | ||
490 | |||
491 | /* Write register */ | ||
492 | xfer[0].addr = client->addr; | ||
493 | xfer[0].flags = 0; | ||
494 | xfer[0].len = 2; | ||
495 | xfer[0].buf = buf; | ||
496 | |||
497 | /* Read data */ | ||
498 | xfer[1].addr = client->addr; | ||
499 | xfer[1].flags = I2C_M_RD; | ||
500 | xfer[1].len = len; | ||
501 | xfer[1].buf = val; | ||
502 | |||
503 | if (i2c_transfer(client->adapter, xfer, 2) != 2) { | ||
504 | dev_err(&client->dev, "%s: i2c transfer failed\n", __func__); | ||
505 | return -EIO; | ||
506 | } | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int qt602240_read_reg(struct i2c_client *client, u16 reg, u8 *val) | ||
512 | { | ||
513 | return __qt602240_read_reg(client, reg, 1, val); | ||
514 | } | ||
515 | |||
516 | static int qt602240_write_reg(struct i2c_client *client, u16 reg, u8 val) | ||
517 | { | ||
518 | u8 buf[3]; | ||
519 | |||
520 | buf[0] = reg & 0xff; | ||
521 | buf[1] = (reg >> 8) & 0xff; | ||
522 | buf[2] = val; | ||
523 | |||
524 | if (i2c_master_send(client, buf, 3) != 3) { | ||
525 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
526 | return -EIO; | ||
527 | } | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static int qt602240_read_object_table(struct i2c_client *client, | ||
533 | u16 reg, u8 *object_buf) | ||
534 | { | ||
535 | return __qt602240_read_reg(client, reg, QT602240_OBJECT_SIZE, | ||
536 | object_buf); | ||
537 | } | ||
538 | |||
539 | static struct qt602240_object * | ||
540 | qt602240_get_object(struct qt602240_data *data, u8 type) | ||
541 | { | ||
542 | struct qt602240_object *object; | ||
543 | int i; | ||
544 | |||
545 | for (i = 0; i < data->info.object_num; i++) { | ||
546 | object = data->object_table + i; | ||
547 | if (object->type == type) | ||
548 | return object; | ||
549 | } | ||
550 | |||
551 | dev_err(&data->client->dev, "Invalid object type\n"); | ||
552 | return NULL; | ||
553 | } | ||
554 | |||
555 | static int qt602240_read_message(struct qt602240_data *data, | ||
556 | struct qt602240_message *message) | ||
557 | { | ||
558 | struct qt602240_object *object; | ||
559 | u16 reg; | ||
560 | |||
561 | object = qt602240_get_object(data, QT602240_GEN_MESSAGE); | ||
562 | if (!object) | ||
563 | return -EINVAL; | ||
564 | |||
565 | reg = object->start_address; | ||
566 | return __qt602240_read_reg(data->client, reg, | ||
567 | sizeof(struct qt602240_message), message); | ||
568 | } | ||
569 | |||
570 | static int qt602240_read_object(struct qt602240_data *data, | ||
571 | u8 type, u8 offset, u8 *val) | ||
572 | { | ||
573 | struct qt602240_object *object; | ||
574 | u16 reg; | ||
575 | |||
576 | object = qt602240_get_object(data, type); | ||
577 | if (!object) | ||
578 | return -EINVAL; | ||
579 | |||
580 | reg = object->start_address; | ||
581 | return __qt602240_read_reg(data->client, reg + offset, 1, val); | ||
582 | } | ||
583 | |||
584 | static int qt602240_write_object(struct qt602240_data *data, | ||
585 | u8 type, u8 offset, u8 val) | ||
586 | { | ||
587 | struct qt602240_object *object; | ||
588 | u16 reg; | ||
589 | |||
590 | object = qt602240_get_object(data, type); | ||
591 | if (!object) | ||
592 | return -EINVAL; | ||
593 | |||
594 | reg = object->start_address; | ||
595 | return qt602240_write_reg(data->client, reg + offset, val); | ||
596 | } | ||
597 | |||
598 | static void qt602240_input_report(struct qt602240_data *data, int single_id) | ||
599 | { | ||
600 | struct qt602240_finger *finger = data->finger; | ||
601 | struct input_dev *input_dev = data->input_dev; | ||
602 | int status = finger[single_id].status; | ||
603 | int finger_num = 0; | ||
604 | int id; | ||
605 | |||
606 | for (id = 0; id < QT602240_MAX_FINGER; id++) { | ||
607 | if (!finger[id].status) | ||
608 | continue; | ||
609 | |||
610 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, | ||
611 | finger[id].status != QT602240_RELEASE ? | ||
612 | finger[id].area : 0); | ||
613 | input_report_abs(input_dev, ABS_MT_POSITION_X, | ||
614 | finger[id].x); | ||
615 | input_report_abs(input_dev, ABS_MT_POSITION_Y, | ||
616 | finger[id].y); | ||
617 | input_mt_sync(input_dev); | ||
618 | |||
619 | if (finger[id].status == QT602240_RELEASE) | ||
620 | finger[id].status = 0; | ||
621 | else | ||
622 | finger_num++; | ||
623 | } | ||
624 | |||
625 | input_report_key(input_dev, BTN_TOUCH, finger_num > 0); | ||
626 | |||
627 | if (status != QT602240_RELEASE) { | ||
628 | input_report_abs(input_dev, ABS_X, finger[single_id].x); | ||
629 | input_report_abs(input_dev, ABS_Y, finger[single_id].y); | ||
630 | } | ||
631 | |||
632 | input_sync(input_dev); | ||
633 | } | ||
634 | |||
635 | static void qt602240_input_touchevent(struct qt602240_data *data, | ||
636 | struct qt602240_message *message, int id) | ||
637 | { | ||
638 | struct qt602240_finger *finger = data->finger; | ||
639 | struct device *dev = &data->client->dev; | ||
640 | u8 status = message->message[0]; | ||
641 | int x; | ||
642 | int y; | ||
643 | int area; | ||
644 | |||
645 | /* Check the touch is present on the screen */ | ||
646 | if (!(status & QT602240_DETECT)) { | ||
647 | if (status & QT602240_RELEASE) { | ||
648 | dev_dbg(dev, "[%d] released\n", id); | ||
649 | |||
650 | finger[id].status = QT602240_RELEASE; | ||
651 | qt602240_input_report(data, id); | ||
652 | } | ||
653 | return; | ||
654 | } | ||
655 | |||
656 | /* Check only AMP detection */ | ||
657 | if (!(status & (QT602240_PRESS | QT602240_MOVE))) | ||
658 | return; | ||
659 | |||
660 | x = (message->message[1] << 2) | ((message->message[3] & ~0x3f) >> 6); | ||
661 | y = (message->message[2] << 2) | ((message->message[3] & ~0xf3) >> 2); | ||
662 | area = message->message[4]; | ||
663 | |||
664 | dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, | ||
665 | status & QT602240_MOVE ? "moved" : "pressed", | ||
666 | x, y, area); | ||
667 | |||
668 | finger[id].status = status & QT602240_MOVE ? | ||
669 | QT602240_MOVE : QT602240_PRESS; | ||
670 | finger[id].x = x; | ||
671 | finger[id].y = y; | ||
672 | finger[id].area = area; | ||
673 | |||
674 | qt602240_input_report(data, id); | ||
675 | } | ||
676 | |||
677 | static irqreturn_t qt602240_interrupt(int irq, void *dev_id) | ||
678 | { | ||
679 | struct qt602240_data *data = dev_id; | ||
680 | struct qt602240_message message; | ||
681 | struct qt602240_object *object; | ||
682 | struct device *dev = &data->client->dev; | ||
683 | int id; | ||
684 | u8 reportid; | ||
685 | u8 max_reportid; | ||
686 | u8 min_reportid; | ||
687 | |||
688 | do { | ||
689 | if (qt602240_read_message(data, &message)) { | ||
690 | dev_err(dev, "Failed to read message\n"); | ||
691 | goto end; | ||
692 | } | ||
693 | |||
694 | reportid = message.reportid; | ||
695 | |||
696 | /* whether reportid is thing of QT602240_TOUCH_MULTI */ | ||
697 | object = qt602240_get_object(data, QT602240_TOUCH_MULTI); | ||
698 | if (!object) | ||
699 | goto end; | ||
700 | |||
701 | max_reportid = object->max_reportid; | ||
702 | min_reportid = max_reportid - object->num_report_ids + 1; | ||
703 | id = reportid - min_reportid; | ||
704 | |||
705 | if (reportid >= min_reportid && reportid <= max_reportid) | ||
706 | qt602240_input_touchevent(data, &message, id); | ||
707 | else | ||
708 | qt602240_dump_message(dev, &message); | ||
709 | } while (reportid != 0xff); | ||
710 | |||
711 | end: | ||
712 | return IRQ_HANDLED; | ||
713 | } | ||
714 | |||
715 | static int qt602240_check_reg_init(struct qt602240_data *data) | ||
716 | { | ||
717 | struct qt602240_object *object; | ||
718 | struct device *dev = &data->client->dev; | ||
719 | int index = 0; | ||
720 | int i, j; | ||
721 | u8 version = data->info.version; | ||
722 | u8 *init_vals; | ||
723 | |||
724 | switch (version) { | ||
725 | case QT602240_VER_20: | ||
726 | init_vals = (u8 *)init_vals_ver_20; | ||
727 | break; | ||
728 | case QT602240_VER_21: | ||
729 | init_vals = (u8 *)init_vals_ver_21; | ||
730 | break; | ||
731 | case QT602240_VER_22: | ||
732 | init_vals = (u8 *)init_vals_ver_22; | ||
733 | break; | ||
734 | default: | ||
735 | dev_err(dev, "Firmware version %d doesn't support\n", version); | ||
736 | return -EINVAL; | ||
737 | } | ||
738 | |||
739 | for (i = 0; i < data->info.object_num; i++) { | ||
740 | object = data->object_table + i; | ||
741 | |||
742 | if (!qt602240_object_writable(object->type)) | ||
743 | continue; | ||
744 | |||
745 | for (j = 0; j < object->size + 1; j++) | ||
746 | qt602240_write_object(data, object->type, j, | ||
747 | init_vals[index + j]); | ||
748 | |||
749 | index += object->size + 1; | ||
750 | } | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static int qt602240_check_matrix_size(struct qt602240_data *data) | ||
756 | { | ||
757 | const struct qt602240_platform_data *pdata = data->pdata; | ||
758 | struct device *dev = &data->client->dev; | ||
759 | int mode = -1; | ||
760 | int error; | ||
761 | u8 val; | ||
762 | |||
763 | dev_dbg(dev, "Number of X lines: %d\n", pdata->x_line); | ||
764 | dev_dbg(dev, "Number of Y lines: %d\n", pdata->y_line); | ||
765 | |||
766 | switch (pdata->x_line) { | ||
767 | case 0 ... 15: | ||
768 | if (pdata->y_line <= 14) | ||
769 | mode = 0; | ||
770 | break; | ||
771 | case 16: | ||
772 | if (pdata->y_line <= 12) | ||
773 | mode = 1; | ||
774 | if (pdata->y_line == 13 || pdata->y_line == 14) | ||
775 | mode = 0; | ||
776 | break; | ||
777 | case 17: | ||
778 | if (pdata->y_line <= 11) | ||
779 | mode = 2; | ||
780 | if (pdata->y_line == 12 || pdata->y_line == 13) | ||
781 | mode = 1; | ||
782 | break; | ||
783 | case 18: | ||
784 | if (pdata->y_line <= 10) | ||
785 | mode = 3; | ||
786 | if (pdata->y_line == 11 || pdata->y_line == 12) | ||
787 | mode = 2; | ||
788 | break; | ||
789 | case 19: | ||
790 | if (pdata->y_line <= 9) | ||
791 | mode = 4; | ||
792 | if (pdata->y_line == 10 || pdata->y_line == 11) | ||
793 | mode = 3; | ||
794 | break; | ||
795 | case 20: | ||
796 | mode = 4; | ||
797 | } | ||
798 | |||
799 | if (mode < 0) { | ||
800 | dev_err(dev, "Invalid X/Y lines\n"); | ||
801 | return -EINVAL; | ||
802 | } | ||
803 | |||
804 | error = qt602240_read_object(data, QT602240_SPT_CTECONFIG, | ||
805 | QT602240_CTE_MODE, &val); | ||
806 | if (error) | ||
807 | return error; | ||
808 | |||
809 | if (mode == val) | ||
810 | return 0; | ||
811 | |||
812 | /* Change the CTE configuration */ | ||
813 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
814 | QT602240_CTE_CTRL, 1); | ||
815 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
816 | QT602240_CTE_MODE, mode); | ||
817 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
818 | QT602240_CTE_CTRL, 0); | ||
819 | |||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | static int qt602240_make_highchg(struct qt602240_data *data) | ||
824 | { | ||
825 | struct device *dev = &data->client->dev; | ||
826 | int count = 10; | ||
827 | int error; | ||
828 | u8 val; | ||
829 | |||
830 | /* Read dummy message to make high CHG pin */ | ||
831 | do { | ||
832 | error = qt602240_read_object(data, QT602240_GEN_MESSAGE, 0, &val); | ||
833 | if (error) | ||
834 | return error; | ||
835 | } while ((val != 0xff) && --count); | ||
836 | |||
837 | if (!count) { | ||
838 | dev_err(dev, "CHG pin isn't cleared\n"); | ||
839 | return -EBUSY; | ||
840 | } | ||
841 | |||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static void qt602240_handle_pdata(struct qt602240_data *data) | ||
846 | { | ||
847 | const struct qt602240_platform_data *pdata = data->pdata; | ||
848 | u8 voltage; | ||
849 | |||
850 | /* Set touchscreen lines */ | ||
851 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_XSIZE, | ||
852 | pdata->x_line); | ||
853 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_YSIZE, | ||
854 | pdata->y_line); | ||
855 | |||
856 | /* Set touchscreen orient */ | ||
857 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_ORIENT, | ||
858 | pdata->orient); | ||
859 | |||
860 | /* Set touchscreen burst length */ | ||
861 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
862 | QT602240_TOUCH_BLEN, pdata->blen); | ||
863 | |||
864 | /* Set touchscreen threshold */ | ||
865 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
866 | QT602240_TOUCH_TCHTHR, pdata->threshold); | ||
867 | |||
868 | /* Set touchscreen resolution */ | ||
869 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
870 | QT602240_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff); | ||
871 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
872 | QT602240_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8); | ||
873 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
874 | QT602240_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff); | ||
875 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
876 | QT602240_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8); | ||
877 | |||
878 | /* Set touchscreen voltage */ | ||
879 | if (data->info.version >= QT602240_VER_21 && pdata->voltage) { | ||
880 | if (pdata->voltage < QT602240_VOLTAGE_DEFAULT) { | ||
881 | voltage = (QT602240_VOLTAGE_DEFAULT - pdata->voltage) / | ||
882 | QT602240_VOLTAGE_STEP; | ||
883 | voltage = 0xff - voltage + 1; | ||
884 | } else | ||
885 | voltage = (pdata->voltage - QT602240_VOLTAGE_DEFAULT) / | ||
886 | QT602240_VOLTAGE_STEP; | ||
887 | |||
888 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
889 | QT602240_CTE_VOLTAGE, voltage); | ||
890 | } | ||
891 | } | ||
892 | |||
893 | static int qt602240_get_info(struct qt602240_data *data) | ||
894 | { | ||
895 | struct i2c_client *client = data->client; | ||
896 | struct qt602240_info *info = &data->info; | ||
897 | int error; | ||
898 | u8 val; | ||
899 | |||
900 | error = qt602240_read_reg(client, QT602240_FAMILY_ID, &val); | ||
901 | if (error) | ||
902 | return error; | ||
903 | info->family_id = val; | ||
904 | |||
905 | error = qt602240_read_reg(client, QT602240_VARIANT_ID, &val); | ||
906 | if (error) | ||
907 | return error; | ||
908 | info->variant_id = val; | ||
909 | |||
910 | error = qt602240_read_reg(client, QT602240_VERSION, &val); | ||
911 | if (error) | ||
912 | return error; | ||
913 | info->version = val; | ||
914 | |||
915 | error = qt602240_read_reg(client, QT602240_BUILD, &val); | ||
916 | if (error) | ||
917 | return error; | ||
918 | info->build = val; | ||
919 | |||
920 | error = qt602240_read_reg(client, QT602240_OBJECT_NUM, &val); | ||
921 | if (error) | ||
922 | return error; | ||
923 | info->object_num = val; | ||
924 | |||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static int qt602240_get_object_table(struct qt602240_data *data) | ||
929 | { | ||
930 | int error; | ||
931 | int i; | ||
932 | u16 reg; | ||
933 | u8 reportid = 0; | ||
934 | u8 buf[QT602240_OBJECT_SIZE]; | ||
935 | |||
936 | for (i = 0; i < data->info.object_num; i++) { | ||
937 | struct qt602240_object *object = data->object_table + i; | ||
938 | |||
939 | reg = QT602240_OBJECT_START + QT602240_OBJECT_SIZE * i; | ||
940 | error = qt602240_read_object_table(data->client, reg, buf); | ||
941 | if (error) | ||
942 | return error; | ||
943 | |||
944 | object->type = buf[0]; | ||
945 | object->start_address = (buf[2] << 8) | buf[1]; | ||
946 | object->size = buf[3]; | ||
947 | object->instances = buf[4]; | ||
948 | object->num_report_ids = buf[5]; | ||
949 | |||
950 | if (object->num_report_ids) { | ||
951 | reportid += object->num_report_ids * | ||
952 | (object->instances + 1); | ||
953 | object->max_reportid = reportid; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static int qt602240_initialize(struct qt602240_data *data) | ||
961 | { | ||
962 | struct i2c_client *client = data->client; | ||
963 | struct qt602240_info *info = &data->info; | ||
964 | int error; | ||
965 | u8 val; | ||
966 | |||
967 | error = qt602240_get_info(data); | ||
968 | if (error) | ||
969 | return error; | ||
970 | |||
971 | data->object_table = kcalloc(info->object_num, | ||
972 | sizeof(struct qt602240_data), | ||
973 | GFP_KERNEL); | ||
974 | if (!data->object_table) { | ||
975 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
976 | return -ENOMEM; | ||
977 | } | ||
978 | |||
979 | /* Get object table information */ | ||
980 | error = qt602240_get_object_table(data); | ||
981 | if (error) | ||
982 | return error; | ||
983 | |||
984 | /* Check register init values */ | ||
985 | error = qt602240_check_reg_init(data); | ||
986 | if (error) | ||
987 | return error; | ||
988 | |||
989 | /* Check X/Y matrix size */ | ||
990 | error = qt602240_check_matrix_size(data); | ||
991 | if (error) | ||
992 | return error; | ||
993 | |||
994 | error = qt602240_make_highchg(data); | ||
995 | if (error) | ||
996 | return error; | ||
997 | |||
998 | qt602240_handle_pdata(data); | ||
999 | |||
1000 | /* Backup to memory */ | ||
1001 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1002 | QT602240_COMMAND_BACKUPNV, | ||
1003 | QT602240_BACKUP_VALUE); | ||
1004 | msleep(QT602240_BACKUP_TIME); | ||
1005 | |||
1006 | /* Soft reset */ | ||
1007 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1008 | QT602240_COMMAND_RESET, 1); | ||
1009 | msleep(QT602240_RESET_TIME); | ||
1010 | |||
1011 | /* Update matrix size at info struct */ | ||
1012 | error = qt602240_read_reg(client, QT602240_MATRIX_X_SIZE, &val); | ||
1013 | if (error) | ||
1014 | return error; | ||
1015 | info->matrix_xsize = val; | ||
1016 | |||
1017 | error = qt602240_read_reg(client, QT602240_MATRIX_Y_SIZE, &val); | ||
1018 | if (error) | ||
1019 | return error; | ||
1020 | info->matrix_ysize = val; | ||
1021 | |||
1022 | dev_info(&client->dev, | ||
1023 | "Family ID: %d Variant ID: %d Version: %d Build: %d\n", | ||
1024 | info->family_id, info->variant_id, info->version, | ||
1025 | info->build); | ||
1026 | |||
1027 | dev_info(&client->dev, | ||
1028 | "Matrix X Size: %d Matrix Y Size: %d Object Num: %d\n", | ||
1029 | info->matrix_xsize, info->matrix_ysize, | ||
1030 | info->object_num); | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | static ssize_t qt602240_object_show(struct device *dev, | ||
1036 | struct device_attribute *attr, char *buf) | ||
1037 | { | ||
1038 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1039 | struct qt602240_object *object; | ||
1040 | int count = 0; | ||
1041 | int i, j; | ||
1042 | int error; | ||
1043 | u8 val; | ||
1044 | |||
1045 | for (i = 0; i < data->info.object_num; i++) { | ||
1046 | object = data->object_table + i; | ||
1047 | |||
1048 | count += sprintf(buf + count, | ||
1049 | "Object Table Element %d(Type %d)\n", | ||
1050 | i + 1, object->type); | ||
1051 | |||
1052 | if (!qt602240_object_readable(object->type)) { | ||
1053 | count += sprintf(buf + count, "\n"); | ||
1054 | continue; | ||
1055 | } | ||
1056 | |||
1057 | for (j = 0; j < object->size + 1; j++) { | ||
1058 | error = qt602240_read_object(data, | ||
1059 | object->type, j, &val); | ||
1060 | if (error) | ||
1061 | return error; | ||
1062 | |||
1063 | count += sprintf(buf + count, | ||
1064 | " Byte %d: 0x%x (%d)\n", j, val, val); | ||
1065 | } | ||
1066 | |||
1067 | count += sprintf(buf + count, "\n"); | ||
1068 | } | ||
1069 | |||
1070 | return count; | ||
1071 | } | ||
1072 | |||
1073 | static int qt602240_load_fw(struct device *dev, const char *fn) | ||
1074 | { | ||
1075 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1076 | struct i2c_client *client = data->client; | ||
1077 | const struct firmware *fw = NULL; | ||
1078 | unsigned int frame_size; | ||
1079 | unsigned int pos = 0; | ||
1080 | int ret; | ||
1081 | |||
1082 | ret = request_firmware(&fw, fn, dev); | ||
1083 | if (ret) { | ||
1084 | dev_err(dev, "Unable to open firmware %s\n", fn); | ||
1085 | return ret; | ||
1086 | } | ||
1087 | |||
1088 | /* Change to the bootloader mode */ | ||
1089 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1090 | QT602240_COMMAND_RESET, QT602240_BOOT_VALUE); | ||
1091 | msleep(QT602240_RESET_TIME); | ||
1092 | |||
1093 | /* Change to slave address of bootloader */ | ||
1094 | if (client->addr == QT602240_APP_LOW) | ||
1095 | client->addr = QT602240_BOOT_LOW; | ||
1096 | else | ||
1097 | client->addr = QT602240_BOOT_HIGH; | ||
1098 | |||
1099 | ret = qt602240_check_bootloader(client, QT602240_WAITING_BOOTLOAD_CMD); | ||
1100 | if (ret) | ||
1101 | goto out; | ||
1102 | |||
1103 | /* Unlock bootloader */ | ||
1104 | qt602240_unlock_bootloader(client); | ||
1105 | |||
1106 | while (pos < fw->size) { | ||
1107 | ret = qt602240_check_bootloader(client, | ||
1108 | QT602240_WAITING_FRAME_DATA); | ||
1109 | if (ret) | ||
1110 | goto out; | ||
1111 | |||
1112 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); | ||
1113 | |||
1114 | /* We should add 2 at frame size as the the firmware data is not | ||
1115 | * included the CRC bytes. | ||
1116 | */ | ||
1117 | frame_size += 2; | ||
1118 | |||
1119 | /* Write one frame to device */ | ||
1120 | qt602240_fw_write(client, fw->data + pos, frame_size); | ||
1121 | |||
1122 | ret = qt602240_check_bootloader(client, | ||
1123 | QT602240_FRAME_CRC_PASS); | ||
1124 | if (ret) | ||
1125 | goto out; | ||
1126 | |||
1127 | pos += frame_size; | ||
1128 | |||
1129 | dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); | ||
1130 | } | ||
1131 | |||
1132 | out: | ||
1133 | release_firmware(fw); | ||
1134 | |||
1135 | /* Change to slave address of application */ | ||
1136 | if (client->addr == QT602240_BOOT_LOW) | ||
1137 | client->addr = QT602240_APP_LOW; | ||
1138 | else | ||
1139 | client->addr = QT602240_APP_HIGH; | ||
1140 | |||
1141 | return ret; | ||
1142 | } | ||
1143 | |||
1144 | static ssize_t qt602240_update_fw_store(struct device *dev, | ||
1145 | struct device_attribute *attr, | ||
1146 | const char *buf, size_t count) | ||
1147 | { | ||
1148 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1149 | unsigned int version; | ||
1150 | int error; | ||
1151 | |||
1152 | if (sscanf(buf, "%u", &version) != 1) { | ||
1153 | dev_err(dev, "Invalid values\n"); | ||
1154 | return -EINVAL; | ||
1155 | } | ||
1156 | |||
1157 | if (data->info.version < QT602240_VER_21 || version < QT602240_VER_21) { | ||
1158 | dev_err(dev, "FW update supported starting with version 21\n"); | ||
1159 | return -EINVAL; | ||
1160 | } | ||
1161 | |||
1162 | disable_irq(data->irq); | ||
1163 | |||
1164 | error = qt602240_load_fw(dev, QT602240_FW_NAME); | ||
1165 | if (error) { | ||
1166 | dev_err(dev, "The firmware update failed(%d)\n", error); | ||
1167 | count = error; | ||
1168 | } else { | ||
1169 | dev_dbg(dev, "The firmware update succeeded\n"); | ||
1170 | |||
1171 | /* Wait for reset */ | ||
1172 | msleep(QT602240_FWRESET_TIME); | ||
1173 | |||
1174 | kfree(data->object_table); | ||
1175 | data->object_table = NULL; | ||
1176 | |||
1177 | qt602240_initialize(data); | ||
1178 | } | ||
1179 | |||
1180 | enable_irq(data->irq); | ||
1181 | |||
1182 | return count; | ||
1183 | } | ||
1184 | |||
1185 | static DEVICE_ATTR(object, 0444, qt602240_object_show, NULL); | ||
1186 | static DEVICE_ATTR(update_fw, 0664, NULL, qt602240_update_fw_store); | ||
1187 | |||
1188 | static struct attribute *qt602240_attrs[] = { | ||
1189 | &dev_attr_object.attr, | ||
1190 | &dev_attr_update_fw.attr, | ||
1191 | NULL | ||
1192 | }; | ||
1193 | |||
1194 | static const struct attribute_group qt602240_attr_group = { | ||
1195 | .attrs = qt602240_attrs, | ||
1196 | }; | ||
1197 | |||
1198 | static void qt602240_start(struct qt602240_data *data) | ||
1199 | { | ||
1200 | /* Touch enable */ | ||
1201 | qt602240_write_object(data, | ||
1202 | QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0x83); | ||
1203 | } | ||
1204 | |||
1205 | static void qt602240_stop(struct qt602240_data *data) | ||
1206 | { | ||
1207 | /* Touch disable */ | ||
1208 | qt602240_write_object(data, | ||
1209 | QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0); | ||
1210 | } | ||
1211 | |||
1212 | static int qt602240_input_open(struct input_dev *dev) | ||
1213 | { | ||
1214 | struct qt602240_data *data = input_get_drvdata(dev); | ||
1215 | |||
1216 | qt602240_start(data); | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1221 | static void qt602240_input_close(struct input_dev *dev) | ||
1222 | { | ||
1223 | struct qt602240_data *data = input_get_drvdata(dev); | ||
1224 | |||
1225 | qt602240_stop(data); | ||
1226 | } | ||
1227 | |||
1228 | static int __devinit qt602240_probe(struct i2c_client *client, | ||
1229 | const struct i2c_device_id *id) | ||
1230 | { | ||
1231 | struct qt602240_data *data; | ||
1232 | struct input_dev *input_dev; | ||
1233 | int error; | ||
1234 | |||
1235 | if (!client->dev.platform_data) | ||
1236 | return -EINVAL; | ||
1237 | |||
1238 | data = kzalloc(sizeof(struct qt602240_data), GFP_KERNEL); | ||
1239 | input_dev = input_allocate_device(); | ||
1240 | if (!data || !input_dev) { | ||
1241 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
1242 | error = -ENOMEM; | ||
1243 | goto err_free_mem; | ||
1244 | } | ||
1245 | |||
1246 | input_dev->name = "AT42QT602240/ATMXT224 Touchscreen"; | ||
1247 | input_dev->id.bustype = BUS_I2C; | ||
1248 | input_dev->dev.parent = &client->dev; | ||
1249 | input_dev->open = qt602240_input_open; | ||
1250 | input_dev->close = qt602240_input_close; | ||
1251 | |||
1252 | __set_bit(EV_ABS, input_dev->evbit); | ||
1253 | __set_bit(EV_KEY, input_dev->evbit); | ||
1254 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1255 | |||
1256 | /* For single touch */ | ||
1257 | input_set_abs_params(input_dev, ABS_X, | ||
1258 | 0, QT602240_MAX_XC, 0, 0); | ||
1259 | input_set_abs_params(input_dev, ABS_Y, | ||
1260 | 0, QT602240_MAX_YC, 0, 0); | ||
1261 | |||
1262 | /* For multi touch */ | ||
1263 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
1264 | 0, QT602240_MAX_AREA, 0, 0); | ||
1265 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1266 | 0, QT602240_MAX_XC, 0, 0); | ||
1267 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1268 | 0, QT602240_MAX_YC, 0, 0); | ||
1269 | |||
1270 | input_set_drvdata(input_dev, data); | ||
1271 | |||
1272 | data->client = client; | ||
1273 | data->input_dev = input_dev; | ||
1274 | data->pdata = client->dev.platform_data; | ||
1275 | data->irq = client->irq; | ||
1276 | |||
1277 | i2c_set_clientdata(client, data); | ||
1278 | |||
1279 | error = qt602240_initialize(data); | ||
1280 | if (error) | ||
1281 | goto err_free_object; | ||
1282 | |||
1283 | error = request_threaded_irq(client->irq, NULL, qt602240_interrupt, | ||
1284 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); | ||
1285 | if (error) { | ||
1286 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
1287 | goto err_free_object; | ||
1288 | } | ||
1289 | |||
1290 | error = input_register_device(input_dev); | ||
1291 | if (error) | ||
1292 | goto err_free_irq; | ||
1293 | |||
1294 | error = sysfs_create_group(&client->dev.kobj, &qt602240_attr_group); | ||
1295 | if (error) | ||
1296 | goto err_unregister_device; | ||
1297 | |||
1298 | return 0; | ||
1299 | |||
1300 | err_unregister_device: | ||
1301 | input_unregister_device(input_dev); | ||
1302 | input_dev = NULL; | ||
1303 | err_free_irq: | ||
1304 | free_irq(client->irq, data); | ||
1305 | err_free_object: | ||
1306 | kfree(data->object_table); | ||
1307 | err_free_mem: | ||
1308 | input_free_device(input_dev); | ||
1309 | kfree(data); | ||
1310 | return error; | ||
1311 | } | ||
1312 | |||
1313 | static int __devexit qt602240_remove(struct i2c_client *client) | ||
1314 | { | ||
1315 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1316 | |||
1317 | sysfs_remove_group(&client->dev.kobj, &qt602240_attr_group); | ||
1318 | free_irq(data->irq, data); | ||
1319 | input_unregister_device(data->input_dev); | ||
1320 | kfree(data->object_table); | ||
1321 | kfree(data); | ||
1322 | |||
1323 | return 0; | ||
1324 | } | ||
1325 | |||
1326 | #ifdef CONFIG_PM | ||
1327 | static int qt602240_suspend(struct i2c_client *client, pm_message_t mesg) | ||
1328 | { | ||
1329 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1330 | struct input_dev *input_dev = data->input_dev; | ||
1331 | |||
1332 | mutex_lock(&input_dev->mutex); | ||
1333 | |||
1334 | if (input_dev->users) | ||
1335 | qt602240_stop(data); | ||
1336 | |||
1337 | mutex_unlock(&input_dev->mutex); | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | static int qt602240_resume(struct i2c_client *client) | ||
1343 | { | ||
1344 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1345 | struct input_dev *input_dev = data->input_dev; | ||
1346 | |||
1347 | /* Soft reset */ | ||
1348 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1349 | QT602240_COMMAND_RESET, 1); | ||
1350 | |||
1351 | msleep(QT602240_RESET_TIME); | ||
1352 | |||
1353 | mutex_lock(&input_dev->mutex); | ||
1354 | |||
1355 | if (input_dev->users) | ||
1356 | qt602240_start(data); | ||
1357 | |||
1358 | mutex_unlock(&input_dev->mutex); | ||
1359 | |||
1360 | return 0; | ||
1361 | } | ||
1362 | #else | ||
1363 | #define qt602240_suspend NULL | ||
1364 | #define qt602240_resume NULL | ||
1365 | #endif | ||
1366 | |||
1367 | static const struct i2c_device_id qt602240_id[] = { | ||
1368 | { "qt602240_ts", 0 }, | ||
1369 | { } | ||
1370 | }; | ||
1371 | MODULE_DEVICE_TABLE(i2c, qt602240_id); | ||
1372 | |||
1373 | static struct i2c_driver qt602240_driver = { | ||
1374 | .driver = { | ||
1375 | .name = "qt602240_ts", | ||
1376 | .owner = THIS_MODULE, | ||
1377 | }, | ||
1378 | .probe = qt602240_probe, | ||
1379 | .remove = __devexit_p(qt602240_remove), | ||
1380 | .suspend = qt602240_suspend, | ||
1381 | .resume = qt602240_resume, | ||
1382 | .id_table = qt602240_id, | ||
1383 | }; | ||
1384 | |||
1385 | static int __init qt602240_init(void) | ||
1386 | { | ||
1387 | return i2c_add_driver(&qt602240_driver); | ||
1388 | } | ||
1389 | |||
1390 | static void __exit qt602240_exit(void) | ||
1391 | { | ||
1392 | i2c_del_driver(&qt602240_driver); | ||
1393 | } | ||
1394 | |||
1395 | module_init(qt602240_init); | ||
1396 | module_exit(qt602240_exit); | ||
1397 | |||
1398 | /* Module information */ | ||
1399 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
1400 | MODULE_DESCRIPTION("AT42QT602240/ATMXT224 Touchscreen driver"); | ||
1401 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 6085d12fd561..8feb7f3c8be1 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c | |||
@@ -350,7 +350,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) | |||
350 | err_tcirq: | 350 | err_tcirq: |
351 | free_irq(ts.irq_tc, ts.input); | 351 | free_irq(ts.irq_tc, ts.input); |
352 | err_inputdev: | 352 | err_inputdev: |
353 | input_unregister_device(ts.input); | 353 | input_free_device(ts.input); |
354 | err_iomap: | 354 | err_iomap: |
355 | iounmap(ts.io); | 355 | iounmap(ts.io); |
356 | err_clk: | 356 | err_clk: |
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c new file mode 100644 index 000000000000..4ab371358b33 --- /dev/null +++ b/drivers/input/touchscreen/st1232.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * ST1232 Touchscreen Controller Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Renesas Solutions Corp. | ||
5 | * Tony SIM <chinyeow.sim.xt@renesas.com> | ||
6 | * | ||
7 | * Using code from: | ||
8 | * - android.git.kernel.org: projects/kernel/common.git: synaptics_i2c_rmi.c | ||
9 | * Copyright (C) 2007 Google, Inc. | ||
10 | * | ||
11 | * This software is licensed under the terms of the GNU General Public | ||
12 | * License version 2, as published by the Free Software Foundation, and | ||
13 | * may be copied, distributed, and modified under those terms. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | #include <linux/delay.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/types.h> | ||
28 | |||
29 | #define ST1232_TS_NAME "st1232-ts" | ||
30 | |||
31 | #define MIN_X 0x00 | ||
32 | #define MIN_Y 0x00 | ||
33 | #define MAX_X 0x31f /* (800 - 1) */ | ||
34 | #define MAX_Y 0x1df /* (480 - 1) */ | ||
35 | #define MAX_AREA 0xff | ||
36 | #define MAX_FINGERS 2 | ||
37 | |||
38 | struct st1232_ts_finger { | ||
39 | u16 x; | ||
40 | u16 y; | ||
41 | u8 t; | ||
42 | bool is_valid; | ||
43 | }; | ||
44 | |||
45 | struct st1232_ts_data { | ||
46 | struct i2c_client *client; | ||
47 | struct input_dev *input_dev; | ||
48 | struct st1232_ts_finger finger[MAX_FINGERS]; | ||
49 | }; | ||
50 | |||
51 | static int st1232_ts_read_data(struct st1232_ts_data *ts) | ||
52 | { | ||
53 | struct st1232_ts_finger *finger = ts->finger; | ||
54 | struct i2c_client *client = ts->client; | ||
55 | struct i2c_msg msg[2]; | ||
56 | int error; | ||
57 | u8 start_reg; | ||
58 | u8 buf[10]; | ||
59 | |||
60 | /* read touchscreen data from ST1232 */ | ||
61 | msg[0].addr = client->addr; | ||
62 | msg[0].flags = 0; | ||
63 | msg[0].len = 1; | ||
64 | msg[0].buf = &start_reg; | ||
65 | start_reg = 0x10; | ||
66 | |||
67 | msg[1].addr = ts->client->addr; | ||
68 | msg[1].flags = I2C_M_RD; | ||
69 | msg[1].len = sizeof(buf); | ||
70 | msg[1].buf = buf; | ||
71 | |||
72 | error = i2c_transfer(client->adapter, msg, 2); | ||
73 | if (error < 0) | ||
74 | return error; | ||
75 | |||
76 | /* get "valid" bits */ | ||
77 | finger[0].is_valid = buf[2] >> 7; | ||
78 | finger[1].is_valid = buf[5] >> 7; | ||
79 | |||
80 | /* get xy coordinate */ | ||
81 | if (finger[0].is_valid) { | ||
82 | finger[0].x = ((buf[2] & 0x0070) << 4) | buf[3]; | ||
83 | finger[0].y = ((buf[2] & 0x0007) << 8) | buf[4]; | ||
84 | finger[0].t = buf[8]; | ||
85 | } | ||
86 | |||
87 | if (finger[1].is_valid) { | ||
88 | finger[1].x = ((buf[5] & 0x0070) << 4) | buf[6]; | ||
89 | finger[1].y = ((buf[5] & 0x0007) << 8) | buf[7]; | ||
90 | finger[1].t = buf[9]; | ||
91 | } | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) | ||
97 | { | ||
98 | struct st1232_ts_data *ts = dev_id; | ||
99 | struct st1232_ts_finger *finger = ts->finger; | ||
100 | struct input_dev *input_dev = ts->input_dev; | ||
101 | int count = 0; | ||
102 | int i, ret; | ||
103 | |||
104 | ret = st1232_ts_read_data(ts); | ||
105 | if (ret < 0) | ||
106 | goto end; | ||
107 | |||
108 | /* multi touch protocol */ | ||
109 | for (i = 0; i < MAX_FINGERS; i++) { | ||
110 | if (!finger[i].is_valid) | ||
111 | continue; | ||
112 | |||
113 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t); | ||
114 | input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x); | ||
115 | input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y); | ||
116 | input_mt_sync(input_dev); | ||
117 | count++; | ||
118 | } | ||
119 | |||
120 | /* SYN_MT_REPORT only if no contact */ | ||
121 | if (!count) | ||
122 | input_mt_sync(input_dev); | ||
123 | |||
124 | /* SYN_REPORT */ | ||
125 | input_sync(input_dev); | ||
126 | |||
127 | end: | ||
128 | return IRQ_HANDLED; | ||
129 | } | ||
130 | |||
131 | static int __devinit st1232_ts_probe(struct i2c_client *client, | ||
132 | const struct i2c_device_id *id) | ||
133 | { | ||
134 | struct st1232_ts_data *ts; | ||
135 | struct input_dev *input_dev; | ||
136 | int error; | ||
137 | |||
138 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
139 | dev_err(&client->dev, "need I2C_FUNC_I2C\n"); | ||
140 | return -EIO; | ||
141 | } | ||
142 | |||
143 | if (!client->irq) { | ||
144 | dev_err(&client->dev, "no IRQ?\n"); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | |||
148 | |||
149 | ts = kzalloc(sizeof(struct st1232_ts_data), GFP_KERNEL); | ||
150 | input_dev = input_allocate_device(); | ||
151 | if (!ts || !input_dev) { | ||
152 | error = -ENOMEM; | ||
153 | goto err_free_mem; | ||
154 | } | ||
155 | |||
156 | ts->client = client; | ||
157 | ts->input_dev = input_dev; | ||
158 | |||
159 | input_dev->name = "st1232-touchscreen"; | ||
160 | input_dev->id.bustype = BUS_I2C; | ||
161 | input_dev->dev.parent = &client->dev; | ||
162 | |||
163 | __set_bit(EV_SYN, input_dev->evbit); | ||
164 | __set_bit(EV_KEY, input_dev->evbit); | ||
165 | __set_bit(EV_ABS, input_dev->evbit); | ||
166 | |||
167 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0); | ||
168 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, MIN_X, MAX_X, 0, 0); | ||
169 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, MIN_Y, MAX_Y, 0, 0); | ||
170 | |||
171 | error = request_threaded_irq(client->irq, NULL, st1232_ts_irq_handler, | ||
172 | IRQF_ONESHOT, client->name, ts); | ||
173 | if (error) { | ||
174 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
175 | goto err_free_mem; | ||
176 | } | ||
177 | |||
178 | error = input_register_device(ts->input_dev); | ||
179 | if (error) { | ||
180 | dev_err(&client->dev, "Unable to register %s input device\n", | ||
181 | input_dev->name); | ||
182 | goto err_free_irq; | ||
183 | } | ||
184 | |||
185 | i2c_set_clientdata(client, ts); | ||
186 | device_init_wakeup(&client->dev, 1); | ||
187 | |||
188 | return 0; | ||
189 | |||
190 | err_free_irq: | ||
191 | free_irq(client->irq, ts); | ||
192 | err_free_mem: | ||
193 | input_free_device(input_dev); | ||
194 | kfree(ts); | ||
195 | return error; | ||
196 | } | ||
197 | |||
198 | static int __devexit st1232_ts_remove(struct i2c_client *client) | ||
199 | { | ||
200 | struct st1232_ts_data *ts = i2c_get_clientdata(client); | ||
201 | |||
202 | device_init_wakeup(&client->dev, 0); | ||
203 | free_irq(client->irq, ts); | ||
204 | input_unregister_device(ts->input_dev); | ||
205 | kfree(ts); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | #ifdef CONFIG_PM | ||
211 | static int st1232_ts_suspend(struct device *dev) | ||
212 | { | ||
213 | struct i2c_client *client = to_i2c_client(dev); | ||
214 | |||
215 | if (device_may_wakeup(&client->dev)) | ||
216 | enable_irq_wake(client->irq); | ||
217 | else | ||
218 | disable_irq(client->irq); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int st1232_ts_resume(struct device *dev) | ||
224 | { | ||
225 | struct i2c_client *client = to_i2c_client(dev); | ||
226 | |||
227 | if (device_may_wakeup(&client->dev)) | ||
228 | disable_irq_wake(client->irq); | ||
229 | else | ||
230 | enable_irq(client->irq); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static const struct dev_pm_ops st1232_ts_pm_ops = { | ||
236 | .suspend = st1232_ts_suspend, | ||
237 | .resume = st1232_ts_resume, | ||
238 | }; | ||
239 | #endif | ||
240 | |||
241 | static const struct i2c_device_id st1232_ts_id[] = { | ||
242 | { ST1232_TS_NAME, 0 }, | ||
243 | { } | ||
244 | }; | ||
245 | MODULE_DEVICE_TABLE(i2c, st1232_ts_id); | ||
246 | |||
247 | static struct i2c_driver st1232_ts_driver = { | ||
248 | .probe = st1232_ts_probe, | ||
249 | .remove = __devexit_p(st1232_ts_remove), | ||
250 | .id_table = st1232_ts_id, | ||
251 | .driver = { | ||
252 | .name = ST1232_TS_NAME, | ||
253 | .owner = THIS_MODULE, | ||
254 | #ifdef CONFIG_PM | ||
255 | .pm = &st1232_ts_pm_ops, | ||
256 | #endif | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | static int __init st1232_ts_init(void) | ||
261 | { | ||
262 | return i2c_add_driver(&st1232_ts_driver); | ||
263 | } | ||
264 | module_init(st1232_ts_init); | ||
265 | |||
266 | static void __exit st1232_ts_exit(void) | ||
267 | { | ||
268 | i2c_del_driver(&st1232_ts_driver); | ||
269 | } | ||
270 | module_exit(st1232_ts_exit); | ||
271 | |||
272 | MODULE_AUTHOR("Tony SIM <chinyeow.sim.xt@renesas.com>"); | ||
273 | MODULE_DESCRIPTION("SITRONIX ST1232 Touchscreen Controller Driver"); | ||
274 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 656148ec0027..ae88e13c99ff 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c | |||
@@ -268,7 +268,7 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) | |||
268 | struct stmpe_touch *ts; | 268 | struct stmpe_touch *ts; |
269 | struct input_dev *idev; | 269 | struct input_dev *idev; |
270 | struct stmpe_ts_platform_data *ts_pdata = NULL; | 270 | struct stmpe_ts_platform_data *ts_pdata = NULL; |
271 | int ret = 0; | 271 | int ret; |
272 | int ts_irq; | 272 | int ts_irq; |
273 | 273 | ||
274 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); | 274 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); |
@@ -276,12 +276,16 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) | |||
276 | return ts_irq; | 276 | return ts_irq; |
277 | 277 | ||
278 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | 278 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); |
279 | if (!ts) | 279 | if (!ts) { |
280 | ret = -ENOMEM; | ||
280 | goto err_out; | 281 | goto err_out; |
282 | } | ||
281 | 283 | ||
282 | idev = input_allocate_device(); | 284 | idev = input_allocate_device(); |
283 | if (!idev) | 285 | if (!idev) { |
286 | ret = -ENOMEM; | ||
284 | goto err_free_ts; | 287 | goto err_free_ts; |
288 | } | ||
285 | 289 | ||
286 | platform_set_drvdata(pdev, ts); | 290 | platform_set_drvdata(pdev, ts); |
287 | ts->stmpe = stmpe; | 291 | ts->stmpe = stmpe; |
@@ -361,7 +365,6 @@ static int __devexit stmpe_ts_remove(struct platform_device *pdev) | |||
361 | platform_set_drvdata(pdev, NULL); | 365 | platform_set_drvdata(pdev, NULL); |
362 | 366 | ||
363 | input_unregister_device(ts->idev); | 367 | input_unregister_device(ts->idev); |
364 | input_free_device(ts->idev); | ||
365 | 368 | ||
366 | kfree(ts); | 369 | kfree(ts); |
367 | 370 | ||
diff --git a/drivers/input/touchscreen/tnetv107x-ts.c b/drivers/input/touchscreen/tnetv107x-ts.c new file mode 100644 index 000000000000..22a3411e93c5 --- /dev/null +++ b/drivers/input/touchscreen/tnetv107x-ts.c | |||
@@ -0,0 +1,397 @@ | |||
1 | /* | ||
2 | * Texas Instruments TNETV107X Touchscreen Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/ctype.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/clk.h> | ||
27 | |||
28 | #include <mach/tnetv107x.h> | ||
29 | |||
30 | #define TSC_PENUP_POLL (HZ / 5) | ||
31 | #define IDLE_TIMEOUT 100 /* msec */ | ||
32 | |||
33 | /* | ||
34 | * The first and last samples of a touch interval are usually garbage and need | ||
35 | * to be filtered out with these devices. The following definitions control | ||
36 | * the number of samples skipped. | ||
37 | */ | ||
38 | #define TSC_HEAD_SKIP 1 | ||
39 | #define TSC_TAIL_SKIP 1 | ||
40 | #define TSC_SKIP (TSC_HEAD_SKIP + TSC_TAIL_SKIP + 1) | ||
41 | #define TSC_SAMPLES (TSC_SKIP + 1) | ||
42 | |||
43 | /* Register Offsets */ | ||
44 | struct tsc_regs { | ||
45 | u32 rev; | ||
46 | u32 tscm; | ||
47 | u32 bwcm; | ||
48 | u32 swc; | ||
49 | u32 adcchnl; | ||
50 | u32 adcdata; | ||
51 | u32 chval[4]; | ||
52 | }; | ||
53 | |||
54 | /* TSC Mode Configuration Register (tscm) bits */ | ||
55 | #define WMODE BIT(0) | ||
56 | #define TSKIND BIT(1) | ||
57 | #define ZMEASURE_EN BIT(2) | ||
58 | #define IDLE BIT(3) | ||
59 | #define TSC_EN BIT(4) | ||
60 | #define STOP BIT(5) | ||
61 | #define ONE_SHOT BIT(6) | ||
62 | #define SINGLE BIT(7) | ||
63 | #define AVG BIT(8) | ||
64 | #define AVGNUM(x) (((x) & 0x03) << 9) | ||
65 | #define PVSTC(x) (((x) & 0x07) << 11) | ||
66 | #define PON BIT(14) | ||
67 | #define PONBG BIT(15) | ||
68 | #define AFERST BIT(16) | ||
69 | |||
70 | /* ADC DATA Capture Register bits */ | ||
71 | #define DATA_VALID BIT(16) | ||
72 | |||
73 | /* Register Access Macros */ | ||
74 | #define tsc_read(ts, reg) __raw_readl(&(ts)->regs->reg) | ||
75 | #define tsc_write(ts, reg, val) __raw_writel(val, &(ts)->regs->reg); | ||
76 | #define tsc_set_bits(ts, reg, val) \ | ||
77 | tsc_write(ts, reg, tsc_read(ts, reg) | (val)) | ||
78 | #define tsc_clr_bits(ts, reg, val) \ | ||
79 | tsc_write(ts, reg, tsc_read(ts, reg) & ~(val)) | ||
80 | |||
81 | struct sample { | ||
82 | int x, y, p; | ||
83 | }; | ||
84 | |||
85 | struct tsc_data { | ||
86 | struct input_dev *input_dev; | ||
87 | struct resource *res; | ||
88 | struct tsc_regs __iomem *regs; | ||
89 | struct timer_list timer; | ||
90 | spinlock_t lock; | ||
91 | struct clk *clk; | ||
92 | struct device *dev; | ||
93 | int sample_count; | ||
94 | struct sample samples[TSC_SAMPLES]; | ||
95 | int tsc_irq; | ||
96 | }; | ||
97 | |||
98 | static int tsc_read_sample(struct tsc_data *ts, struct sample* sample) | ||
99 | { | ||
100 | int x, y, z1, z2, t, p = 0; | ||
101 | u32 val; | ||
102 | |||
103 | val = tsc_read(ts, chval[0]); | ||
104 | if (val & DATA_VALID) | ||
105 | x = val & 0xffff; | ||
106 | else | ||
107 | return -EINVAL; | ||
108 | |||
109 | y = tsc_read(ts, chval[1]) & 0xffff; | ||
110 | z1 = tsc_read(ts, chval[2]) & 0xffff; | ||
111 | z2 = tsc_read(ts, chval[3]) & 0xffff; | ||
112 | |||
113 | if (z1) { | ||
114 | t = ((600 * x) * (z2 - z1)); | ||
115 | p = t / (u32) (z1 << 12); | ||
116 | if (p < 0) | ||
117 | p = 0; | ||
118 | } | ||
119 | |||
120 | sample->x = x; | ||
121 | sample->y = y; | ||
122 | sample->p = p; | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static void tsc_poll(unsigned long data) | ||
128 | { | ||
129 | struct tsc_data *ts = (struct tsc_data *)data; | ||
130 | unsigned long flags; | ||
131 | int i, val, x, y, p; | ||
132 | |||
133 | spin_lock_irqsave(&ts->lock, flags); | ||
134 | |||
135 | if (ts->sample_count >= TSC_SKIP) { | ||
136 | input_report_abs(ts->input_dev, ABS_PRESSURE, 0); | ||
137 | input_report_key(ts->input_dev, BTN_TOUCH, 0); | ||
138 | input_sync(ts->input_dev); | ||
139 | } else if (ts->sample_count > 0) { | ||
140 | /* | ||
141 | * A touch event lasted less than our skip count. Salvage and | ||
142 | * report anyway. | ||
143 | */ | ||
144 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
145 | val += ts->samples[i].x; | ||
146 | x = val / ts->sample_count; | ||
147 | |||
148 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
149 | val += ts->samples[i].y; | ||
150 | y = val / ts->sample_count; | ||
151 | |||
152 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
153 | val += ts->samples[i].p; | ||
154 | p = val / ts->sample_count; | ||
155 | |||
156 | input_report_abs(ts->input_dev, ABS_X, x); | ||
157 | input_report_abs(ts->input_dev, ABS_Y, y); | ||
158 | input_report_abs(ts->input_dev, ABS_PRESSURE, p); | ||
159 | input_report_key(ts->input_dev, BTN_TOUCH, 1); | ||
160 | input_sync(ts->input_dev); | ||
161 | } | ||
162 | |||
163 | ts->sample_count = 0; | ||
164 | |||
165 | spin_unlock_irqrestore(&ts->lock, flags); | ||
166 | } | ||
167 | |||
168 | static irqreturn_t tsc_irq(int irq, void *dev_id) | ||
169 | { | ||
170 | struct tsc_data *ts = (struct tsc_data *)dev_id; | ||
171 | struct sample *sample; | ||
172 | int index; | ||
173 | |||
174 | spin_lock(&ts->lock); | ||
175 | |||
176 | index = ts->sample_count % TSC_SAMPLES; | ||
177 | sample = &ts->samples[index]; | ||
178 | if (tsc_read_sample(ts, sample) < 0) | ||
179 | goto out; | ||
180 | |||
181 | if (++ts->sample_count >= TSC_SKIP) { | ||
182 | index = (ts->sample_count - TSC_TAIL_SKIP - 1) % TSC_SAMPLES; | ||
183 | sample = &ts->samples[index]; | ||
184 | |||
185 | input_report_abs(ts->input_dev, ABS_X, sample->x); | ||
186 | input_report_abs(ts->input_dev, ABS_Y, sample->y); | ||
187 | input_report_abs(ts->input_dev, ABS_PRESSURE, sample->p); | ||
188 | if (ts->sample_count == TSC_SKIP) | ||
189 | input_report_key(ts->input_dev, BTN_TOUCH, 1); | ||
190 | input_sync(ts->input_dev); | ||
191 | } | ||
192 | mod_timer(&ts->timer, jiffies + TSC_PENUP_POLL); | ||
193 | out: | ||
194 | spin_unlock(&ts->lock); | ||
195 | return IRQ_HANDLED; | ||
196 | } | ||
197 | |||
198 | static int tsc_start(struct input_dev *dev) | ||
199 | { | ||
200 | struct tsc_data *ts = input_get_drvdata(dev); | ||
201 | unsigned long timeout = jiffies + msecs_to_jiffies(IDLE_TIMEOUT); | ||
202 | u32 val; | ||
203 | |||
204 | clk_enable(ts->clk); | ||
205 | |||
206 | /* Go to idle mode, before any initialization */ | ||
207 | while (time_after(timeout, jiffies)) { | ||
208 | if (tsc_read(ts, tscm) & IDLE) | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | if (time_before(timeout, jiffies)) { | ||
213 | dev_warn(ts->dev, "timeout waiting for idle\n"); | ||
214 | clk_disable(ts->clk); | ||
215 | return -EIO; | ||
216 | } | ||
217 | |||
218 | /* Configure TSC Control register*/ | ||
219 | val = (PONBG | PON | PVSTC(4) | ONE_SHOT | ZMEASURE_EN); | ||
220 | tsc_write(ts, tscm, val); | ||
221 | |||
222 | /* Bring TSC out of reset: Clear AFE reset bit */ | ||
223 | val &= ~(AFERST); | ||
224 | tsc_write(ts, tscm, val); | ||
225 | |||
226 | /* Configure all pins for hardware control*/ | ||
227 | tsc_write(ts, bwcm, 0); | ||
228 | |||
229 | /* Finally enable the TSC */ | ||
230 | tsc_set_bits(ts, tscm, TSC_EN); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static void tsc_stop(struct input_dev *dev) | ||
236 | { | ||
237 | struct tsc_data *ts = input_get_drvdata(dev); | ||
238 | |||
239 | tsc_clr_bits(ts, tscm, TSC_EN); | ||
240 | synchronize_irq(ts->tsc_irq); | ||
241 | del_timer_sync(&ts->timer); | ||
242 | clk_disable(ts->clk); | ||
243 | } | ||
244 | |||
245 | static int __devinit tsc_probe(struct platform_device *pdev) | ||
246 | { | ||
247 | struct device *dev = &pdev->dev; | ||
248 | struct tsc_data *ts; | ||
249 | int error = 0; | ||
250 | u32 rev = 0; | ||
251 | |||
252 | ts = kzalloc(sizeof(struct tsc_data), GFP_KERNEL); | ||
253 | if (!ts) { | ||
254 | dev_err(dev, "cannot allocate device info\n"); | ||
255 | return -ENOMEM; | ||
256 | } | ||
257 | |||
258 | ts->dev = dev; | ||
259 | spin_lock_init(&ts->lock); | ||
260 | setup_timer(&ts->timer, tsc_poll, (unsigned long)ts); | ||
261 | platform_set_drvdata(pdev, ts); | ||
262 | |||
263 | ts->tsc_irq = platform_get_irq(pdev, 0); | ||
264 | if (ts->tsc_irq < 0) { | ||
265 | dev_err(dev, "cannot determine device interrupt\n"); | ||
266 | error = -ENODEV; | ||
267 | goto error_res; | ||
268 | } | ||
269 | |||
270 | ts->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
271 | if (!ts->res) { | ||
272 | dev_err(dev, "cannot determine register area\n"); | ||
273 | error = -ENODEV; | ||
274 | goto error_res; | ||
275 | } | ||
276 | |||
277 | if (!request_mem_region(ts->res->start, resource_size(ts->res), | ||
278 | pdev->name)) { | ||
279 | dev_err(dev, "cannot claim register memory\n"); | ||
280 | ts->res = NULL; | ||
281 | error = -EINVAL; | ||
282 | goto error_res; | ||
283 | } | ||
284 | |||
285 | ts->regs = ioremap(ts->res->start, resource_size(ts->res)); | ||
286 | if (!ts->regs) { | ||
287 | dev_err(dev, "cannot map register memory\n"); | ||
288 | error = -ENOMEM; | ||
289 | goto error_map; | ||
290 | } | ||
291 | |||
292 | ts->clk = clk_get(dev, NULL); | ||
293 | if (IS_ERR(ts->clk)) { | ||
294 | dev_err(dev, "cannot claim device clock\n"); | ||
295 | error = PTR_ERR(ts->clk); | ||
296 | goto error_clk; | ||
297 | } | ||
298 | |||
299 | error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, 0, | ||
300 | dev_name(dev), ts); | ||
301 | if (error < 0) { | ||
302 | dev_err(ts->dev, "Could not allocate ts irq\n"); | ||
303 | goto error_irq; | ||
304 | } | ||
305 | |||
306 | ts->input_dev = input_allocate_device(); | ||
307 | if (!ts->input_dev) { | ||
308 | dev_err(dev, "cannot allocate input device\n"); | ||
309 | error = -ENOMEM; | ||
310 | goto error_input; | ||
311 | } | ||
312 | input_set_drvdata(ts->input_dev, ts); | ||
313 | |||
314 | ts->input_dev->name = pdev->name; | ||
315 | ts->input_dev->id.bustype = BUS_HOST; | ||
316 | ts->input_dev->dev.parent = &pdev->dev; | ||
317 | ts->input_dev->open = tsc_start; | ||
318 | ts->input_dev->close = tsc_stop; | ||
319 | |||
320 | clk_enable(ts->clk); | ||
321 | rev = tsc_read(ts, rev); | ||
322 | ts->input_dev->id.product = ((rev >> 8) & 0x07); | ||
323 | ts->input_dev->id.version = ((rev >> 16) & 0xfff); | ||
324 | clk_disable(ts->clk); | ||
325 | |||
326 | __set_bit(EV_KEY, ts->input_dev->evbit); | ||
327 | __set_bit(EV_ABS, ts->input_dev->evbit); | ||
328 | __set_bit(BTN_TOUCH, ts->input_dev->keybit); | ||
329 | |||
330 | input_set_abs_params(ts->input_dev, ABS_X, 0, 0xffff, 5, 0); | ||
331 | input_set_abs_params(ts->input_dev, ABS_Y, 0, 0xffff, 5, 0); | ||
332 | input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 4095, 128, 0); | ||
333 | |||
334 | error = input_register_device(ts->input_dev); | ||
335 | if (error < 0) { | ||
336 | dev_err(dev, "failed input device registration\n"); | ||
337 | goto error_reg; | ||
338 | } | ||
339 | |||
340 | return 0; | ||
341 | |||
342 | error_reg: | ||
343 | input_free_device(ts->input_dev); | ||
344 | error_input: | ||
345 | free_irq(ts->tsc_irq, ts); | ||
346 | error_irq: | ||
347 | clk_put(ts->clk); | ||
348 | error_clk: | ||
349 | iounmap(ts->regs); | ||
350 | error_map: | ||
351 | release_mem_region(ts->res->start, resource_size(ts->res)); | ||
352 | error_res: | ||
353 | platform_set_drvdata(pdev, NULL); | ||
354 | kfree(ts); | ||
355 | |||
356 | return error; | ||
357 | } | ||
358 | |||
359 | static int __devexit tsc_remove(struct platform_device *pdev) | ||
360 | { | ||
361 | struct tsc_data *ts = platform_get_drvdata(pdev); | ||
362 | |||
363 | input_unregister_device(ts->input_dev); | ||
364 | free_irq(ts->tsc_irq, ts); | ||
365 | clk_put(ts->clk); | ||
366 | iounmap(ts->regs); | ||
367 | release_mem_region(ts->res->start, resource_size(ts->res)); | ||
368 | platform_set_drvdata(pdev, NULL); | ||
369 | kfree(ts); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static struct platform_driver tsc_driver = { | ||
375 | .probe = tsc_probe, | ||
376 | .remove = __devexit_p(tsc_remove), | ||
377 | .driver.name = "tnetv107x-ts", | ||
378 | .driver.owner = THIS_MODULE, | ||
379 | }; | ||
380 | |||
381 | static int __init tsc_init(void) | ||
382 | { | ||
383 | return platform_driver_register(&tsc_driver); | ||
384 | } | ||
385 | |||
386 | static void __exit tsc_exit(void) | ||
387 | { | ||
388 | platform_driver_unregister(&tsc_driver); | ||
389 | } | ||
390 | |||
391 | module_init(tsc_init); | ||
392 | module_exit(tsc_exit); | ||
393 | |||
394 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
395 | MODULE_DESCRIPTION("TNETV107X Touchscreen Driver"); | ||
396 | MODULE_ALIAS("platform: tnetv107x-ts"); | ||
397 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index a644d18c04dc..43031492d733 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c | |||
@@ -43,7 +43,6 @@ struct tps6507x_ts { | |||
43 | struct input_dev *input_dev; | 43 | struct input_dev *input_dev; |
44 | struct device *dev; | 44 | struct device *dev; |
45 | char phys[32]; | 45 | char phys[32]; |
46 | struct workqueue_struct *wq; | ||
47 | struct delayed_work work; | 46 | struct delayed_work work; |
48 | unsigned polling; /* polling is active */ | 47 | unsigned polling; /* polling is active */ |
49 | struct ts_event tc; | 48 | struct ts_event tc; |
@@ -220,8 +219,8 @@ done: | |||
220 | poll = 1; | 219 | poll = 1; |
221 | 220 | ||
222 | if (poll) { | 221 | if (poll) { |
223 | schd = queue_delayed_work(tsc->wq, &tsc->work, | 222 | schd = schedule_delayed_work(&tsc->work, |
224 | msecs_to_jiffies(tsc->poll_period)); | 223 | msecs_to_jiffies(tsc->poll_period)); |
225 | if (schd) | 224 | if (schd) |
226 | tsc->polling = 1; | 225 | tsc->polling = 1; |
227 | else { | 226 | else { |
@@ -303,7 +302,6 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
303 | tsc->input_dev = input_dev; | 302 | tsc->input_dev = input_dev; |
304 | 303 | ||
305 | INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); | 304 | INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); |
306 | tsc->wq = create_workqueue("TPS6507x Touchscreen"); | ||
307 | 305 | ||
308 | if (init_data) { | 306 | if (init_data) { |
309 | tsc->poll_period = init_data->poll_period; | 307 | tsc->poll_period = init_data->poll_period; |
@@ -325,8 +323,8 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
325 | if (error) | 323 | if (error) |
326 | goto err2; | 324 | goto err2; |
327 | 325 | ||
328 | schd = queue_delayed_work(tsc->wq, &tsc->work, | 326 | schd = schedule_delayed_work(&tsc->work, |
329 | msecs_to_jiffies(tsc->poll_period)); | 327 | msecs_to_jiffies(tsc->poll_period)); |
330 | 328 | ||
331 | if (schd) | 329 | if (schd) |
332 | tsc->polling = 1; | 330 | tsc->polling = 1; |
@@ -335,12 +333,12 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
335 | dev_err(tsc->dev, "schedule failed"); | 333 | dev_err(tsc->dev, "schedule failed"); |
336 | goto err2; | 334 | goto err2; |
337 | } | 335 | } |
336 | platform_set_drvdata(pdev, tps6507x_dev); | ||
338 | 337 | ||
339 | return 0; | 338 | return 0; |
340 | 339 | ||
341 | err2: | 340 | err2: |
342 | cancel_delayed_work_sync(&tsc->work); | 341 | cancel_delayed_work_sync(&tsc->work); |
343 | destroy_workqueue(tsc->wq); | ||
344 | input_free_device(input_dev); | 342 | input_free_device(input_dev); |
345 | err1: | 343 | err1: |
346 | kfree(tsc); | 344 | kfree(tsc); |
@@ -356,9 +354,8 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev) | |||
356 | struct input_dev *input_dev = tsc->input_dev; | 354 | struct input_dev *input_dev = tsc->input_dev; |
357 | 355 | ||
358 | cancel_delayed_work_sync(&tsc->work); | 356 | cancel_delayed_work_sync(&tsc->work); |
359 | destroy_workqueue(tsc->wq); | ||
360 | 357 | ||
361 | input_free_device(input_dev); | 358 | input_unregister_device(input_dev); |
362 | 359 | ||
363 | tps6507x_dev->ts = NULL; | 360 | tps6507x_dev->ts = NULL; |
364 | kfree(tsc); | 361 | kfree(tsc); |
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c new file mode 100644 index 000000000000..cbf0ff322676 --- /dev/null +++ b/drivers/input/touchscreen/tsc2005.c | |||
@@ -0,0 +1,764 @@ | |||
1 | /* | ||
2 | * TSC2005 touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2006-2010 Nokia Corporation | ||
5 | * | ||
6 | * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com> | ||
7 | * based on TSC2301 driver by Klaus K. Pedersen <klaus.k.pedersen@nokia.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/input.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/pm.h> | ||
31 | #include <linux/spi/spi.h> | ||
32 | #include <linux/spi/tsc2005.h> | ||
33 | |||
34 | /* | ||
35 | * The touchscreen interface operates as follows: | ||
36 | * | ||
37 | * 1) Pen is pressed against the touchscreen. | ||
38 | * 2) TSC2005 performs AD conversion. | ||
39 | * 3) After the conversion is done TSC2005 drives DAV line down. | ||
40 | * 4) GPIO IRQ is received and tsc2005_irq_thread() is scheduled. | ||
41 | * 5) tsc2005_irq_thread() queues up an spi transfer to fetch the x, y, z1, z2 | ||
42 | * values. | ||
43 | * 6) tsc2005_irq_thread() reports coordinates to input layer and sets up | ||
44 | * tsc2005_penup_timer() to be called after TSC2005_PENUP_TIME_MS (40ms). | ||
45 | * 7) When the penup timer expires, there have not been touch or DAV interrupts | ||
46 | * during the last 40ms which means the pen has been lifted. | ||
47 | * | ||
48 | * ESD recovery via a hardware reset is done if the TSC2005 doesn't respond | ||
49 | * after a configurable period (in ms) of activity. If esd_timeout is 0, the | ||
50 | * watchdog is disabled. | ||
51 | */ | ||
52 | |||
53 | /* control byte 1 */ | ||
54 | #define TSC2005_CMD 0x80 | ||
55 | #define TSC2005_CMD_NORMAL 0x00 | ||
56 | #define TSC2005_CMD_STOP 0x01 | ||
57 | #define TSC2005_CMD_12BIT 0x04 | ||
58 | |||
59 | /* control byte 0 */ | ||
60 | #define TSC2005_REG_READ 0x0001 | ||
61 | #define TSC2005_REG_PND0 0x0002 | ||
62 | #define TSC2005_REG_X 0x0000 | ||
63 | #define TSC2005_REG_Y 0x0008 | ||
64 | #define TSC2005_REG_Z1 0x0010 | ||
65 | #define TSC2005_REG_Z2 0x0018 | ||
66 | #define TSC2005_REG_TEMP_HIGH 0x0050 | ||
67 | #define TSC2005_REG_CFR0 0x0060 | ||
68 | #define TSC2005_REG_CFR1 0x0068 | ||
69 | #define TSC2005_REG_CFR2 0x0070 | ||
70 | |||
71 | /* configuration register 0 */ | ||
72 | #define TSC2005_CFR0_PRECHARGE_276US 0x0040 | ||
73 | #define TSC2005_CFR0_STABTIME_1MS 0x0300 | ||
74 | #define TSC2005_CFR0_CLOCK_1MHZ 0x1000 | ||
75 | #define TSC2005_CFR0_RESOLUTION12 0x2000 | ||
76 | #define TSC2005_CFR0_PENMODE 0x8000 | ||
77 | #define TSC2005_CFR0_INITVALUE (TSC2005_CFR0_STABTIME_1MS | \ | ||
78 | TSC2005_CFR0_CLOCK_1MHZ | \ | ||
79 | TSC2005_CFR0_RESOLUTION12 | \ | ||
80 | TSC2005_CFR0_PRECHARGE_276US | \ | ||
81 | TSC2005_CFR0_PENMODE) | ||
82 | |||
83 | /* bits common to both read and write of configuration register 0 */ | ||
84 | #define TSC2005_CFR0_RW_MASK 0x3fff | ||
85 | |||
86 | /* configuration register 1 */ | ||
87 | #define TSC2005_CFR1_BATCHDELAY_4MS 0x0003 | ||
88 | #define TSC2005_CFR1_INITVALUE TSC2005_CFR1_BATCHDELAY_4MS | ||
89 | |||
90 | /* configuration register 2 */ | ||
91 | #define TSC2005_CFR2_MAVE_Z 0x0004 | ||
92 | #define TSC2005_CFR2_MAVE_Y 0x0008 | ||
93 | #define TSC2005_CFR2_MAVE_X 0x0010 | ||
94 | #define TSC2005_CFR2_AVG_7 0x0800 | ||
95 | #define TSC2005_CFR2_MEDIUM_15 0x3000 | ||
96 | #define TSC2005_CFR2_INITVALUE (TSC2005_CFR2_MAVE_X | \ | ||
97 | TSC2005_CFR2_MAVE_Y | \ | ||
98 | TSC2005_CFR2_MAVE_Z | \ | ||
99 | TSC2005_CFR2_MEDIUM_15 | \ | ||
100 | TSC2005_CFR2_AVG_7) | ||
101 | |||
102 | #define MAX_12BIT 0xfff | ||
103 | #define TSC2005_SPI_MAX_SPEED_HZ 10000000 | ||
104 | #define TSC2005_PENUP_TIME_MS 40 | ||
105 | |||
106 | struct tsc2005_spi_rd { | ||
107 | struct spi_transfer spi_xfer; | ||
108 | u32 spi_tx; | ||
109 | u32 spi_rx; | ||
110 | }; | ||
111 | |||
112 | struct tsc2005 { | ||
113 | struct spi_device *spi; | ||
114 | |||
115 | struct spi_message spi_read_msg; | ||
116 | struct tsc2005_spi_rd spi_x; | ||
117 | struct tsc2005_spi_rd spi_y; | ||
118 | struct tsc2005_spi_rd spi_z1; | ||
119 | struct tsc2005_spi_rd spi_z2; | ||
120 | |||
121 | struct input_dev *idev; | ||
122 | char phys[32]; | ||
123 | |||
124 | struct mutex mutex; | ||
125 | |||
126 | /* raw copy of previous x,y,z */ | ||
127 | int in_x; | ||
128 | int in_y; | ||
129 | int in_z1; | ||
130 | int in_z2; | ||
131 | |||
132 | spinlock_t lock; | ||
133 | struct timer_list penup_timer; | ||
134 | |||
135 | unsigned int esd_timeout; | ||
136 | struct delayed_work esd_work; | ||
137 | unsigned long last_valid_interrupt; | ||
138 | |||
139 | unsigned int x_plate_ohm; | ||
140 | |||
141 | bool opened; | ||
142 | bool suspended; | ||
143 | |||
144 | bool pen_down; | ||
145 | |||
146 | void (*set_reset)(bool enable); | ||
147 | }; | ||
148 | |||
149 | static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd) | ||
150 | { | ||
151 | u8 tx = TSC2005_CMD | TSC2005_CMD_12BIT | cmd; | ||
152 | struct spi_transfer xfer = { | ||
153 | .tx_buf = &tx, | ||
154 | .len = 1, | ||
155 | .bits_per_word = 8, | ||
156 | }; | ||
157 | struct spi_message msg; | ||
158 | int error; | ||
159 | |||
160 | spi_message_init(&msg); | ||
161 | spi_message_add_tail(&xfer, &msg); | ||
162 | |||
163 | error = spi_sync(ts->spi, &msg); | ||
164 | if (error) { | ||
165 | dev_err(&ts->spi->dev, "%s: failed, command: %x, error: %d\n", | ||
166 | __func__, cmd, error); | ||
167 | return error; | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) | ||
174 | { | ||
175 | u32 tx = ((reg | TSC2005_REG_PND0) << 16) | value; | ||
176 | struct spi_transfer xfer = { | ||
177 | .tx_buf = &tx, | ||
178 | .len = 4, | ||
179 | .bits_per_word = 24, | ||
180 | }; | ||
181 | struct spi_message msg; | ||
182 | int error; | ||
183 | |||
184 | spi_message_init(&msg); | ||
185 | spi_message_add_tail(&xfer, &msg); | ||
186 | |||
187 | error = spi_sync(ts->spi, &msg); | ||
188 | if (error) { | ||
189 | dev_err(&ts->spi->dev, | ||
190 | "%s: failed, register: %x, value: %x, error: %d\n", | ||
191 | __func__, reg, value, error); | ||
192 | return error; | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static void tsc2005_setup_read(struct tsc2005_spi_rd *rd, u8 reg, bool last) | ||
199 | { | ||
200 | memset(rd, 0, sizeof(*rd)); | ||
201 | |||
202 | rd->spi_tx = (reg | TSC2005_REG_READ) << 16; | ||
203 | rd->spi_xfer.tx_buf = &rd->spi_tx; | ||
204 | rd->spi_xfer.rx_buf = &rd->spi_rx; | ||
205 | rd->spi_xfer.len = 4; | ||
206 | rd->spi_xfer.bits_per_word = 24; | ||
207 | rd->spi_xfer.cs_change = !last; | ||
208 | } | ||
209 | |||
210 | static int tsc2005_read(struct tsc2005 *ts, u8 reg, u16 *value) | ||
211 | { | ||
212 | struct tsc2005_spi_rd spi_rd; | ||
213 | struct spi_message msg; | ||
214 | int error; | ||
215 | |||
216 | tsc2005_setup_read(&spi_rd, reg, true); | ||
217 | |||
218 | spi_message_init(&msg); | ||
219 | spi_message_add_tail(&spi_rd.spi_xfer, &msg); | ||
220 | |||
221 | error = spi_sync(ts->spi, &msg); | ||
222 | if (error) | ||
223 | return error; | ||
224 | |||
225 | *value = spi_rd.spi_rx; | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static void tsc2005_update_pen_state(struct tsc2005 *ts, | ||
230 | int x, int y, int pressure) | ||
231 | { | ||
232 | if (pressure) { | ||
233 | input_report_abs(ts->idev, ABS_X, x); | ||
234 | input_report_abs(ts->idev, ABS_Y, y); | ||
235 | input_report_abs(ts->idev, ABS_PRESSURE, pressure); | ||
236 | if (!ts->pen_down) { | ||
237 | input_report_key(ts->idev, BTN_TOUCH, !!pressure); | ||
238 | ts->pen_down = true; | ||
239 | } | ||
240 | } else { | ||
241 | input_report_abs(ts->idev, ABS_PRESSURE, 0); | ||
242 | if (ts->pen_down) { | ||
243 | input_report_key(ts->idev, BTN_TOUCH, 0); | ||
244 | ts->pen_down = false; | ||
245 | } | ||
246 | } | ||
247 | input_sync(ts->idev); | ||
248 | dev_dbg(&ts->spi->dev, "point(%4d,%4d), pressure (%4d)\n", x, y, | ||
249 | pressure); | ||
250 | } | ||
251 | |||
252 | static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) | ||
253 | { | ||
254 | struct tsc2005 *ts = _ts; | ||
255 | unsigned long flags; | ||
256 | unsigned int pressure; | ||
257 | u32 x, y; | ||
258 | u32 z1, z2; | ||
259 | int error; | ||
260 | |||
261 | /* read the coordinates */ | ||
262 | error = spi_sync(ts->spi, &ts->spi_read_msg); | ||
263 | if (unlikely(error)) | ||
264 | goto out; | ||
265 | |||
266 | x = ts->spi_x.spi_rx; | ||
267 | y = ts->spi_y.spi_rx; | ||
268 | z1 = ts->spi_z1.spi_rx; | ||
269 | z2 = ts->spi_z2.spi_rx; | ||
270 | |||
271 | /* validate position */ | ||
272 | if (unlikely(x > MAX_12BIT || y > MAX_12BIT)) | ||
273 | goto out; | ||
274 | |||
275 | /* Skip reading if the pressure components are out of range */ | ||
276 | if (unlikely(z1 == 0 || z2 > MAX_12BIT || z1 >= z2)) | ||
277 | goto out; | ||
278 | |||
279 | /* | ||
280 | * Skip point if this is a pen down with the exact same values as | ||
281 | * the value before pen-up - that implies SPI fed us stale data | ||
282 | */ | ||
283 | if (!ts->pen_down && | ||
284 | ts->in_x == x && ts->in_y == y && | ||
285 | ts->in_z1 == z1 && ts->in_z2 == z2) { | ||
286 | goto out; | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * At this point we are happy we have a valid and useful reading. | ||
291 | * Remember it for later comparisons. We may now begin downsampling. | ||
292 | */ | ||
293 | ts->in_x = x; | ||
294 | ts->in_y = y; | ||
295 | ts->in_z1 = z1; | ||
296 | ts->in_z2 = z2; | ||
297 | |||
298 | /* Compute touch pressure resistance using equation #1 */ | ||
299 | pressure = x * (z2 - z1) / z1; | ||
300 | pressure = pressure * ts->x_plate_ohm / 4096; | ||
301 | if (unlikely(pressure > MAX_12BIT)) | ||
302 | goto out; | ||
303 | |||
304 | spin_lock_irqsave(&ts->lock, flags); | ||
305 | |||
306 | tsc2005_update_pen_state(ts, x, y, pressure); | ||
307 | mod_timer(&ts->penup_timer, | ||
308 | jiffies + msecs_to_jiffies(TSC2005_PENUP_TIME_MS)); | ||
309 | |||
310 | spin_unlock_irqrestore(&ts->lock, flags); | ||
311 | |||
312 | ts->last_valid_interrupt = jiffies; | ||
313 | out: | ||
314 | return IRQ_HANDLED; | ||
315 | } | ||
316 | |||
317 | static void tsc2005_penup_timer(unsigned long data) | ||
318 | { | ||
319 | struct tsc2005 *ts = (struct tsc2005 *)data; | ||
320 | unsigned long flags; | ||
321 | |||
322 | spin_lock_irqsave(&ts->lock, flags); | ||
323 | tsc2005_update_pen_state(ts, 0, 0, 0); | ||
324 | spin_unlock_irqrestore(&ts->lock, flags); | ||
325 | } | ||
326 | |||
327 | static void tsc2005_start_scan(struct tsc2005 *ts) | ||
328 | { | ||
329 | tsc2005_write(ts, TSC2005_REG_CFR0, TSC2005_CFR0_INITVALUE); | ||
330 | tsc2005_write(ts, TSC2005_REG_CFR1, TSC2005_CFR1_INITVALUE); | ||
331 | tsc2005_write(ts, TSC2005_REG_CFR2, TSC2005_CFR2_INITVALUE); | ||
332 | tsc2005_cmd(ts, TSC2005_CMD_NORMAL); | ||
333 | } | ||
334 | |||
335 | static void tsc2005_stop_scan(struct tsc2005 *ts) | ||
336 | { | ||
337 | tsc2005_cmd(ts, TSC2005_CMD_STOP); | ||
338 | } | ||
339 | |||
340 | /* must be called with ts->mutex held */ | ||
341 | static void __tsc2005_disable(struct tsc2005 *ts) | ||
342 | { | ||
343 | tsc2005_stop_scan(ts); | ||
344 | |||
345 | disable_irq(ts->spi->irq); | ||
346 | del_timer_sync(&ts->penup_timer); | ||
347 | |||
348 | cancel_delayed_work_sync(&ts->esd_work); | ||
349 | |||
350 | enable_irq(ts->spi->irq); | ||
351 | } | ||
352 | |||
353 | /* must be called with ts->mutex held */ | ||
354 | static void __tsc2005_enable(struct tsc2005 *ts) | ||
355 | { | ||
356 | tsc2005_start_scan(ts); | ||
357 | |||
358 | if (ts->esd_timeout && ts->set_reset) { | ||
359 | ts->last_valid_interrupt = jiffies; | ||
360 | schedule_delayed_work(&ts->esd_work, | ||
361 | round_jiffies_relative( | ||
362 | msecs_to_jiffies(ts->esd_timeout))); | ||
363 | } | ||
364 | |||
365 | } | ||
366 | |||
367 | static ssize_t tsc2005_selftest_show(struct device *dev, | ||
368 | struct device_attribute *attr, | ||
369 | char *buf) | ||
370 | { | ||
371 | struct spi_device *spi = to_spi_device(dev); | ||
372 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
373 | u16 temp_high; | ||
374 | u16 temp_high_orig; | ||
375 | u16 temp_high_test; | ||
376 | bool success = true; | ||
377 | int error; | ||
378 | |||
379 | mutex_lock(&ts->mutex); | ||
380 | |||
381 | /* | ||
382 | * Test TSC2005 communications via temp high register. | ||
383 | */ | ||
384 | __tsc2005_disable(ts); | ||
385 | |||
386 | error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high_orig); | ||
387 | if (error) { | ||
388 | dev_warn(dev, "selftest failed: read error %d\n", error); | ||
389 | success = false; | ||
390 | goto out; | ||
391 | } | ||
392 | |||
393 | temp_high_test = (temp_high_orig - 1) & MAX_12BIT; | ||
394 | |||
395 | error = tsc2005_write(ts, TSC2005_REG_TEMP_HIGH, temp_high_test); | ||
396 | if (error) { | ||
397 | dev_warn(dev, "selftest failed: write error %d\n", error); | ||
398 | success = false; | ||
399 | goto out; | ||
400 | } | ||
401 | |||
402 | error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high); | ||
403 | if (error) { | ||
404 | dev_warn(dev, "selftest failed: read error %d after write\n", | ||
405 | error); | ||
406 | success = false; | ||
407 | goto out; | ||
408 | } | ||
409 | |||
410 | if (temp_high != temp_high_test) { | ||
411 | dev_warn(dev, "selftest failed: %d != %d\n", | ||
412 | temp_high, temp_high_test); | ||
413 | success = false; | ||
414 | } | ||
415 | |||
416 | /* hardware reset */ | ||
417 | ts->set_reset(false); | ||
418 | usleep_range(100, 500); /* only 10us required */ | ||
419 | ts->set_reset(true); | ||
420 | |||
421 | if (!success) | ||
422 | goto out; | ||
423 | |||
424 | /* test that the reset really happened */ | ||
425 | error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high); | ||
426 | if (error) { | ||
427 | dev_warn(dev, "selftest failed: read error %d after reset\n", | ||
428 | error); | ||
429 | success = false; | ||
430 | goto out; | ||
431 | } | ||
432 | |||
433 | if (temp_high != temp_high_orig) { | ||
434 | dev_warn(dev, "selftest failed after reset: %d != %d\n", | ||
435 | temp_high, temp_high_orig); | ||
436 | success = false; | ||
437 | } | ||
438 | |||
439 | out: | ||
440 | __tsc2005_enable(ts); | ||
441 | mutex_unlock(&ts->mutex); | ||
442 | |||
443 | return sprintf(buf, "%d\n", success); | ||
444 | } | ||
445 | |||
446 | static DEVICE_ATTR(selftest, S_IRUGO, tsc2005_selftest_show, NULL); | ||
447 | |||
448 | static struct attribute *tsc2005_attrs[] = { | ||
449 | &dev_attr_selftest.attr, | ||
450 | NULL | ||
451 | }; | ||
452 | |||
453 | static mode_t tsc2005_attr_is_visible(struct kobject *kobj, | ||
454 | struct attribute *attr, int n) | ||
455 | { | ||
456 | struct device *dev = container_of(kobj, struct device, kobj); | ||
457 | struct spi_device *spi = to_spi_device(dev); | ||
458 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
459 | mode_t mode = attr->mode; | ||
460 | |||
461 | if (attr == &dev_attr_selftest.attr) { | ||
462 | if (!ts->set_reset) | ||
463 | mode = 0; | ||
464 | } | ||
465 | |||
466 | return mode; | ||
467 | } | ||
468 | |||
469 | static const struct attribute_group tsc2005_attr_group = { | ||
470 | .is_visible = tsc2005_attr_is_visible, | ||
471 | .attrs = tsc2005_attrs, | ||
472 | }; | ||
473 | |||
474 | static void tsc2005_esd_work(struct work_struct *work) | ||
475 | { | ||
476 | struct tsc2005 *ts = container_of(work, struct tsc2005, esd_work.work); | ||
477 | int error; | ||
478 | u16 r; | ||
479 | |||
480 | if (!mutex_trylock(&ts->mutex)) { | ||
481 | /* | ||
482 | * If the mutex is taken, it means that disable or enable is in | ||
483 | * progress. In that case just reschedule the work. If the work | ||
484 | * is not needed, it will be canceled by disable. | ||
485 | */ | ||
486 | goto reschedule; | ||
487 | } | ||
488 | |||
489 | if (time_is_after_jiffies(ts->last_valid_interrupt + | ||
490 | msecs_to_jiffies(ts->esd_timeout))) | ||
491 | goto out; | ||
492 | |||
493 | /* We should be able to read register without disabling interrupts. */ | ||
494 | error = tsc2005_read(ts, TSC2005_REG_CFR0, &r); | ||
495 | if (!error && | ||
496 | !((r ^ TSC2005_CFR0_INITVALUE) & TSC2005_CFR0_RW_MASK)) { | ||
497 | goto out; | ||
498 | } | ||
499 | |||
500 | /* | ||
501 | * If we could not read our known value from configuration register 0 | ||
502 | * then we should reset the controller as if from power-up and start | ||
503 | * scanning again. | ||
504 | */ | ||
505 | dev_info(&ts->spi->dev, "TSC2005 not responding - resetting\n"); | ||
506 | |||
507 | disable_irq(ts->spi->irq); | ||
508 | del_timer_sync(&ts->penup_timer); | ||
509 | |||
510 | tsc2005_update_pen_state(ts, 0, 0, 0); | ||
511 | |||
512 | ts->set_reset(false); | ||
513 | usleep_range(100, 500); /* only 10us required */ | ||
514 | ts->set_reset(true); | ||
515 | |||
516 | enable_irq(ts->spi->irq); | ||
517 | tsc2005_start_scan(ts); | ||
518 | |||
519 | out: | ||
520 | mutex_unlock(&ts->mutex); | ||
521 | reschedule: | ||
522 | /* re-arm the watchdog */ | ||
523 | schedule_delayed_work(&ts->esd_work, | ||
524 | round_jiffies_relative( | ||
525 | msecs_to_jiffies(ts->esd_timeout))); | ||
526 | } | ||
527 | |||
528 | static int tsc2005_open(struct input_dev *input) | ||
529 | { | ||
530 | struct tsc2005 *ts = input_get_drvdata(input); | ||
531 | |||
532 | mutex_lock(&ts->mutex); | ||
533 | |||
534 | if (!ts->suspended) | ||
535 | __tsc2005_enable(ts); | ||
536 | |||
537 | ts->opened = true; | ||
538 | |||
539 | mutex_unlock(&ts->mutex); | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | static void tsc2005_close(struct input_dev *input) | ||
545 | { | ||
546 | struct tsc2005 *ts = input_get_drvdata(input); | ||
547 | |||
548 | mutex_lock(&ts->mutex); | ||
549 | |||
550 | if (!ts->suspended) | ||
551 | __tsc2005_disable(ts); | ||
552 | |||
553 | ts->opened = false; | ||
554 | |||
555 | mutex_unlock(&ts->mutex); | ||
556 | } | ||
557 | |||
558 | static void __devinit tsc2005_setup_spi_xfer(struct tsc2005 *ts) | ||
559 | { | ||
560 | tsc2005_setup_read(&ts->spi_x, TSC2005_REG_X, false); | ||
561 | tsc2005_setup_read(&ts->spi_y, TSC2005_REG_Y, false); | ||
562 | tsc2005_setup_read(&ts->spi_z1, TSC2005_REG_Z1, false); | ||
563 | tsc2005_setup_read(&ts->spi_z2, TSC2005_REG_Z2, true); | ||
564 | |||
565 | spi_message_init(&ts->spi_read_msg); | ||
566 | spi_message_add_tail(&ts->spi_x.spi_xfer, &ts->spi_read_msg); | ||
567 | spi_message_add_tail(&ts->spi_y.spi_xfer, &ts->spi_read_msg); | ||
568 | spi_message_add_tail(&ts->spi_z1.spi_xfer, &ts->spi_read_msg); | ||
569 | spi_message_add_tail(&ts->spi_z2.spi_xfer, &ts->spi_read_msg); | ||
570 | } | ||
571 | |||
572 | static int __devinit tsc2005_probe(struct spi_device *spi) | ||
573 | { | ||
574 | const struct tsc2005_platform_data *pdata = spi->dev.platform_data; | ||
575 | struct tsc2005 *ts; | ||
576 | struct input_dev *input_dev; | ||
577 | unsigned int max_x, max_y, max_p; | ||
578 | unsigned int fudge_x, fudge_y, fudge_p; | ||
579 | int error; | ||
580 | |||
581 | if (!pdata) { | ||
582 | dev_dbg(&spi->dev, "no platform data\n"); | ||
583 | return -ENODEV; | ||
584 | } | ||
585 | |||
586 | fudge_x = pdata->ts_x_fudge ? : 4; | ||
587 | fudge_y = pdata->ts_y_fudge ? : 8; | ||
588 | fudge_p = pdata->ts_pressure_fudge ? : 2; | ||
589 | max_x = pdata->ts_x_max ? : MAX_12BIT; | ||
590 | max_y = pdata->ts_y_max ? : MAX_12BIT; | ||
591 | max_p = pdata->ts_pressure_max ? : MAX_12BIT; | ||
592 | |||
593 | if (spi->irq <= 0) { | ||
594 | dev_dbg(&spi->dev, "no irq\n"); | ||
595 | return -ENODEV; | ||
596 | } | ||
597 | |||
598 | spi->mode = SPI_MODE_0; | ||
599 | spi->bits_per_word = 8; | ||
600 | if (!spi->max_speed_hz) | ||
601 | spi->max_speed_hz = TSC2005_SPI_MAX_SPEED_HZ; | ||
602 | |||
603 | error = spi_setup(spi); | ||
604 | if (error) | ||
605 | return error; | ||
606 | |||
607 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | ||
608 | input_dev = input_allocate_device(); | ||
609 | if (!ts || !input_dev) { | ||
610 | error = -ENOMEM; | ||
611 | goto err_free_mem; | ||
612 | } | ||
613 | |||
614 | ts->spi = spi; | ||
615 | ts->idev = input_dev; | ||
616 | |||
617 | ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; | ||
618 | ts->esd_timeout = pdata->esd_timeout_ms; | ||
619 | ts->set_reset = pdata->set_reset; | ||
620 | |||
621 | mutex_init(&ts->mutex); | ||
622 | |||
623 | spin_lock_init(&ts->lock); | ||
624 | setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts); | ||
625 | |||
626 | INIT_DELAYED_WORK(&ts->esd_work, tsc2005_esd_work); | ||
627 | |||
628 | tsc2005_setup_spi_xfer(ts); | ||
629 | |||
630 | snprintf(ts->phys, sizeof(ts->phys), | ||
631 | "%s/input-ts", dev_name(&spi->dev)); | ||
632 | |||
633 | input_dev->name = "TSC2005 touchscreen"; | ||
634 | input_dev->phys = ts->phys; | ||
635 | input_dev->id.bustype = BUS_SPI; | ||
636 | input_dev->dev.parent = &spi->dev; | ||
637 | input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); | ||
638 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
639 | |||
640 | input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0); | ||
641 | input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0); | ||
642 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); | ||
643 | |||
644 | input_dev->open = tsc2005_open; | ||
645 | input_dev->close = tsc2005_close; | ||
646 | |||
647 | input_set_drvdata(input_dev, ts); | ||
648 | |||
649 | /* Ensure the touchscreen is off */ | ||
650 | tsc2005_stop_scan(ts); | ||
651 | |||
652 | error = request_threaded_irq(spi->irq, NULL, tsc2005_irq_thread, | ||
653 | IRQF_TRIGGER_RISING, "tsc2005", ts); | ||
654 | if (error) { | ||
655 | dev_err(&spi->dev, "Failed to request irq, err: %d\n", error); | ||
656 | goto err_free_mem; | ||
657 | } | ||
658 | |||
659 | spi_set_drvdata(spi, ts); | ||
660 | error = sysfs_create_group(&spi->dev.kobj, &tsc2005_attr_group); | ||
661 | if (error) { | ||
662 | dev_err(&spi->dev, | ||
663 | "Failed to create sysfs attributes, err: %d\n", error); | ||
664 | goto err_clear_drvdata; | ||
665 | } | ||
666 | |||
667 | error = input_register_device(ts->idev); | ||
668 | if (error) { | ||
669 | dev_err(&spi->dev, | ||
670 | "Failed to register input device, err: %d\n", error); | ||
671 | goto err_remove_sysfs; | ||
672 | } | ||
673 | |||
674 | irq_set_irq_wake(spi->irq, 1); | ||
675 | return 0; | ||
676 | |||
677 | err_remove_sysfs: | ||
678 | sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); | ||
679 | err_clear_drvdata: | ||
680 | spi_set_drvdata(spi, NULL); | ||
681 | free_irq(spi->irq, ts); | ||
682 | err_free_mem: | ||
683 | input_free_device(input_dev); | ||
684 | kfree(ts); | ||
685 | return error; | ||
686 | } | ||
687 | |||
688 | static int __devexit tsc2005_remove(struct spi_device *spi) | ||
689 | { | ||
690 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
691 | |||
692 | sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group); | ||
693 | |||
694 | free_irq(ts->spi->irq, ts); | ||
695 | input_unregister_device(ts->idev); | ||
696 | kfree(ts); | ||
697 | |||
698 | spi_set_drvdata(spi, NULL); | ||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | #ifdef CONFIG_PM_SLEEP | ||
703 | static int tsc2005_suspend(struct device *dev) | ||
704 | { | ||
705 | struct spi_device *spi = to_spi_device(dev); | ||
706 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
707 | |||
708 | mutex_lock(&ts->mutex); | ||
709 | |||
710 | if (!ts->suspended && ts->opened) | ||
711 | __tsc2005_disable(ts); | ||
712 | |||
713 | ts->suspended = true; | ||
714 | |||
715 | mutex_unlock(&ts->mutex); | ||
716 | |||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static int tsc2005_resume(struct device *dev) | ||
721 | { | ||
722 | struct spi_device *spi = to_spi_device(dev); | ||
723 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
724 | |||
725 | mutex_lock(&ts->mutex); | ||
726 | |||
727 | if (ts->suspended && ts->opened) | ||
728 | __tsc2005_enable(ts); | ||
729 | |||
730 | ts->suspended = false; | ||
731 | |||
732 | mutex_unlock(&ts->mutex); | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | #endif | ||
737 | |||
738 | static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume); | ||
739 | |||
740 | static struct spi_driver tsc2005_driver = { | ||
741 | .driver = { | ||
742 | .name = "tsc2005", | ||
743 | .owner = THIS_MODULE, | ||
744 | .pm = &tsc2005_pm_ops, | ||
745 | }, | ||
746 | .probe = tsc2005_probe, | ||
747 | .remove = __devexit_p(tsc2005_remove), | ||
748 | }; | ||
749 | |||
750 | static int __init tsc2005_init(void) | ||
751 | { | ||
752 | return spi_register_driver(&tsc2005_driver); | ||
753 | } | ||
754 | module_init(tsc2005_init); | ||
755 | |||
756 | static void __exit tsc2005_exit(void) | ||
757 | { | ||
758 | spi_unregister_driver(&tsc2005_driver); | ||
759 | } | ||
760 | module_exit(tsc2005_exit); | ||
761 | |||
762 | MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>"); | ||
763 | MODULE_DESCRIPTION("TSC2005 Touchscreen Driver"); | ||
764 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index be23780e8a3e..fadc11545b1e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c | |||
@@ -27,9 +27,6 @@ | |||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/i2c/tsc2007.h> | 28 | #include <linux/i2c/tsc2007.h> |
29 | 29 | ||
30 | #define TS_POLL_DELAY 1 /* ms delay between samples */ | ||
31 | #define TS_POLL_PERIOD 1 /* ms delay between samples */ | ||
32 | |||
33 | #define TSC2007_MEASURE_TEMP0 (0x0 << 4) | 30 | #define TSC2007_MEASURE_TEMP0 (0x0 << 4) |
34 | #define TSC2007_MEASURE_AUX (0x2 << 4) | 31 | #define TSC2007_MEASURE_AUX (0x2 << 4) |
35 | #define TSC2007_MEASURE_TEMP1 (0x4 << 4) | 32 | #define TSC2007_MEASURE_TEMP1 (0x4 << 4) |
@@ -75,6 +72,9 @@ struct tsc2007 { | |||
75 | 72 | ||
76 | u16 model; | 73 | u16 model; |
77 | u16 x_plate_ohms; | 74 | u16 x_plate_ohms; |
75 | u16 max_rt; | ||
76 | unsigned long poll_delay; | ||
77 | unsigned long poll_period; | ||
78 | 78 | ||
79 | bool pendown; | 79 | bool pendown; |
80 | int irq; | 80 | int irq; |
@@ -156,6 +156,7 @@ static void tsc2007_work(struct work_struct *work) | |||
156 | { | 156 | { |
157 | struct tsc2007 *ts = | 157 | struct tsc2007 *ts = |
158 | container_of(to_delayed_work(work), struct tsc2007, work); | 158 | container_of(to_delayed_work(work), struct tsc2007, work); |
159 | bool debounced = false; | ||
159 | struct ts_event tc; | 160 | struct ts_event tc; |
160 | u32 rt; | 161 | u32 rt; |
161 | 162 | ||
@@ -184,13 +185,14 @@ static void tsc2007_work(struct work_struct *work) | |||
184 | tsc2007_read_values(ts, &tc); | 185 | tsc2007_read_values(ts, &tc); |
185 | 186 | ||
186 | rt = tsc2007_calculate_pressure(ts, &tc); | 187 | rt = tsc2007_calculate_pressure(ts, &tc); |
187 | if (rt > MAX_12BIT) { | 188 | if (rt > ts->max_rt) { |
188 | /* | 189 | /* |
189 | * Sample found inconsistent by debouncing or pressure is | 190 | * Sample found inconsistent by debouncing or pressure is |
190 | * beyond the maximum. Don't report it to user space, | 191 | * beyond the maximum. Don't report it to user space, |
191 | * repeat at least once more the measurement. | 192 | * repeat at least once more the measurement. |
192 | */ | 193 | */ |
193 | dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt); | 194 | dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt); |
195 | debounced = true; | ||
194 | goto out; | 196 | goto out; |
195 | 197 | ||
196 | } | 198 | } |
@@ -225,9 +227,9 @@ static void tsc2007_work(struct work_struct *work) | |||
225 | } | 227 | } |
226 | 228 | ||
227 | out: | 229 | out: |
228 | if (ts->pendown) | 230 | if (ts->pendown || debounced) |
229 | schedule_delayed_work(&ts->work, | 231 | schedule_delayed_work(&ts->work, |
230 | msecs_to_jiffies(TS_POLL_PERIOD)); | 232 | msecs_to_jiffies(ts->poll_period)); |
231 | else | 233 | else |
232 | enable_irq(ts->irq); | 234 | enable_irq(ts->irq); |
233 | } | 235 | } |
@@ -239,7 +241,7 @@ static irqreturn_t tsc2007_irq(int irq, void *handle) | |||
239 | if (!ts->get_pendown_state || likely(ts->get_pendown_state())) { | 241 | if (!ts->get_pendown_state || likely(ts->get_pendown_state())) { |
240 | disable_irq_nosync(ts->irq); | 242 | disable_irq_nosync(ts->irq); |
241 | schedule_delayed_work(&ts->work, | 243 | schedule_delayed_work(&ts->work, |
242 | msecs_to_jiffies(TS_POLL_DELAY)); | 244 | msecs_to_jiffies(ts->poll_delay)); |
243 | } | 245 | } |
244 | 246 | ||
245 | if (ts->clear_penirq) | 247 | if (ts->clear_penirq) |
@@ -265,7 +267,7 @@ static int __devinit tsc2007_probe(struct i2c_client *client, | |||
265 | const struct i2c_device_id *id) | 267 | const struct i2c_device_id *id) |
266 | { | 268 | { |
267 | struct tsc2007 *ts; | 269 | struct tsc2007 *ts; |
268 | struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data; | 270 | struct tsc2007_platform_data *pdata = client->dev.platform_data; |
269 | struct input_dev *input_dev; | 271 | struct input_dev *input_dev; |
270 | int err; | 272 | int err; |
271 | 273 | ||
@@ -292,6 +294,9 @@ static int __devinit tsc2007_probe(struct i2c_client *client, | |||
292 | 294 | ||
293 | ts->model = pdata->model; | 295 | ts->model = pdata->model; |
294 | ts->x_plate_ohms = pdata->x_plate_ohms; | 296 | ts->x_plate_ohms = pdata->x_plate_ohms; |
297 | ts->max_rt = pdata->max_rt ? : MAX_12BIT; | ||
298 | ts->poll_delay = pdata->poll_delay ? : 1; | ||
299 | ts->poll_period = pdata->poll_period ? : 1; | ||
295 | ts->get_pendown_state = pdata->get_pendown_state; | 300 | ts->get_pendown_state = pdata->get_pendown_state; |
296 | ts->clear_penirq = pdata->clear_penirq; | 301 | ts->clear_penirq = pdata->clear_penirq; |
297 | 302 | ||
@@ -305,9 +310,10 @@ static int __devinit tsc2007_probe(struct i2c_client *client, | |||
305 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 310 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
306 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 311 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
307 | 312 | ||
308 | input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); | 313 | input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0); |
309 | input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); | 314 | input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0); |
310 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); | 315 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, |
316 | pdata->fuzzz, 0); | ||
311 | 317 | ||
312 | if (pdata->init_platform_hw) | 318 | if (pdata->init_platform_hw) |
313 | pdata->init_platform_hw(); | 319 | pdata->init_platform_hw(); |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 028a5363eea1..3b5b5df04dd6 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright: MontaVista Software, Inc. | 6 | * Copyright: MontaVista Software, Inc. |
7 | * | 7 | * |
8 | * Spliting done by: Marek Vasut <marek.vasut@gmail.com> | 8 | * Spliting done by: Marek Vasut <marek.vasut@gmail.com> |
9 | * If something doesnt work and it worked before spliting, e-mail me, | 9 | * If something doesn't work and it worked before spliting, e-mail me, |
10 | * dont bother Nicolas please ;-) | 10 | * dont bother Nicolas please ;-) |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index f45f80f6d336..73fd6642b681 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = { | |||
178 | 178 | ||
179 | #ifdef CONFIG_TOUCHSCREEN_USB_ITM | 179 | #ifdef CONFIG_TOUCHSCREEN_USB_ITM |
180 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, | 180 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, |
181 | {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM}, | ||
181 | #endif | 182 | #endif |
182 | 183 | ||
183 | #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO | 184 | #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO |
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 56dc35c94bb1..c14412ef4648 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * Wacom W8001 penabled serial touchscreen driver | 2 | * Wacom W8001 penabled serial touchscreen driver |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Jaya Kumar | 4 | * Copyright (c) 2008 Jaya Kumar |
5 | * Copyright (c) 2010 Red Hat, Inc. | ||
6 | * Copyright (c) 2010 - 2011 Ping Cheng, Wacom. <pingc@wacom.com> | ||
5 | * | 7 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | 8 | * 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 | 9 | * License. See the file COPYING in the main directory of this archive for |
@@ -14,10 +16,11 @@ | |||
14 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
17 | #include <linux/input.h> | 19 | #include <linux/input/mt.h> |
18 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
19 | #include <linux/init.h> | 21 | #include <linux/init.h> |
20 | #include <linux/ctype.h> | 22 | #include <linux/ctype.h> |
23 | #include <linux/delay.h> | ||
21 | 24 | ||
22 | #define DRIVER_DESC "Wacom W8001 serial touchscreen driver" | 25 | #define DRIVER_DESC "Wacom W8001 serial touchscreen driver" |
23 | 26 | ||
@@ -30,11 +33,27 @@ MODULE_LICENSE("GPL"); | |||
30 | #define W8001_LEAD_BYTE 0x80 | 33 | #define W8001_LEAD_BYTE 0x80 |
31 | #define W8001_TAB_MASK 0x40 | 34 | #define W8001_TAB_MASK 0x40 |
32 | #define W8001_TAB_BYTE 0x40 | 35 | #define W8001_TAB_BYTE 0x40 |
36 | /* set in first byte of touch data packets */ | ||
37 | #define W8001_TOUCH_MASK (0x10 | W8001_LEAD_MASK) | ||
38 | #define W8001_TOUCH_BYTE (0x10 | W8001_LEAD_BYTE) | ||
33 | 39 | ||
34 | #define W8001_QUERY_PACKET 0x20 | 40 | #define W8001_QUERY_PACKET 0x20 |
35 | 41 | ||
42 | #define W8001_CMD_STOP '0' | ||
36 | #define W8001_CMD_START '1' | 43 | #define W8001_CMD_START '1' |
37 | #define W8001_CMD_QUERY '*' | 44 | #define W8001_CMD_QUERY '*' |
45 | #define W8001_CMD_TOUCHQUERY '%' | ||
46 | |||
47 | /* length of data packets in bytes, depends on device. */ | ||
48 | #define W8001_PKTLEN_TOUCH93 5 | ||
49 | #define W8001_PKTLEN_TOUCH9A 7 | ||
50 | #define W8001_PKTLEN_TPCPEN 9 | ||
51 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ | ||
52 | #define W8001_PKTLEN_TOUCH2FG 13 | ||
53 | |||
54 | /* resolution in points/mm */ | ||
55 | #define W8001_PEN_RESOLUTION 100 | ||
56 | #define W8001_TOUCH_RESOLUTION 10 | ||
38 | 57 | ||
39 | struct w8001_coord { | 58 | struct w8001_coord { |
40 | u8 rdy; | 59 | u8 rdy; |
@@ -48,6 +67,15 @@ struct w8001_coord { | |||
48 | u8 tilt_y; | 67 | u8 tilt_y; |
49 | }; | 68 | }; |
50 | 69 | ||
70 | /* touch query reply packet */ | ||
71 | struct w8001_touch_query { | ||
72 | u16 x; | ||
73 | u16 y; | ||
74 | u8 panel_res; | ||
75 | u8 capacity_res; | ||
76 | u8 sensor_id; | ||
77 | }; | ||
78 | |||
51 | /* | 79 | /* |
52 | * Per-touchscreen data. | 80 | * Per-touchscreen data. |
53 | */ | 81 | */ |
@@ -62,9 +90,16 @@ struct w8001 { | |||
62 | unsigned char response[W8001_MAX_LENGTH]; | 90 | unsigned char response[W8001_MAX_LENGTH]; |
63 | unsigned char data[W8001_MAX_LENGTH]; | 91 | unsigned char data[W8001_MAX_LENGTH]; |
64 | char phys[32]; | 92 | char phys[32]; |
93 | int type; | ||
94 | unsigned int pktlen; | ||
95 | u16 max_touch_x; | ||
96 | u16 max_touch_y; | ||
97 | u16 max_pen_x; | ||
98 | u16 max_pen_y; | ||
99 | char name[64]; | ||
65 | }; | 100 | }; |
66 | 101 | ||
67 | static void parse_data(u8 *data, struct w8001_coord *coord) | 102 | static void parse_pen_data(u8 *data, struct w8001_coord *coord) |
68 | { | 103 | { |
69 | memset(coord, 0, sizeof(*coord)); | 104 | memset(coord, 0, sizeof(*coord)); |
70 | 105 | ||
@@ -88,11 +123,166 @@ static void parse_data(u8 *data, struct w8001_coord *coord) | |||
88 | coord->tilt_y = data[8] & 0x7F; | 123 | coord->tilt_y = data[8] & 0x7F; |
89 | } | 124 | } |
90 | 125 | ||
126 | static void parse_single_touch(u8 *data, struct w8001_coord *coord) | ||
127 | { | ||
128 | coord->x = (data[1] << 7) | data[2]; | ||
129 | coord->y = (data[3] << 7) | data[4]; | ||
130 | coord->tsw = data[0] & 0x01; | ||
131 | } | ||
132 | |||
133 | static void scale_touch_coordinates(struct w8001 *w8001, | ||
134 | unsigned int *x, unsigned int *y) | ||
135 | { | ||
136 | if (w8001->max_pen_x && w8001->max_touch_x) | ||
137 | *x = *x * w8001->max_pen_x / w8001->max_touch_x; | ||
138 | |||
139 | if (w8001->max_pen_y && w8001->max_touch_y) | ||
140 | *y = *y * w8001->max_pen_y / w8001->max_touch_y; | ||
141 | } | ||
142 | |||
143 | static void parse_multi_touch(struct w8001 *w8001) | ||
144 | { | ||
145 | struct input_dev *dev = w8001->dev; | ||
146 | unsigned char *data = w8001->data; | ||
147 | unsigned int x, y; | ||
148 | int i; | ||
149 | int count = 0; | ||
150 | |||
151 | for (i = 0; i < 2; i++) { | ||
152 | bool touch = data[0] & (1 << i); | ||
153 | |||
154 | input_mt_slot(dev, i); | ||
155 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); | ||
156 | if (touch) { | ||
157 | x = (data[6 * i + 1] << 7) | data[6 * i + 2]; | ||
158 | y = (data[6 * i + 3] << 7) | data[6 * i + 4]; | ||
159 | /* data[5,6] and [11,12] is finger capacity */ | ||
160 | |||
161 | /* scale to pen maximum */ | ||
162 | scale_touch_coordinates(w8001, &x, &y); | ||
163 | |||
164 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
165 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | ||
166 | count++; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /* emulate single touch events when stylus is out of proximity. | ||
171 | * This is to make single touch backward support consistent | ||
172 | * across all Wacom single touch devices. | ||
173 | */ | ||
174 | if (w8001->type != BTN_TOOL_PEN && | ||
175 | w8001->type != BTN_TOOL_RUBBER) { | ||
176 | w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED; | ||
177 | input_mt_report_pointer_emulation(dev, true); | ||
178 | } | ||
179 | |||
180 | input_sync(dev); | ||
181 | } | ||
182 | |||
183 | static void parse_touchquery(u8 *data, struct w8001_touch_query *query) | ||
184 | { | ||
185 | memset(query, 0, sizeof(*query)); | ||
186 | |||
187 | query->panel_res = data[1]; | ||
188 | query->sensor_id = data[2] & 0x7; | ||
189 | query->capacity_res = data[7]; | ||
190 | |||
191 | query->x = data[3] << 9; | ||
192 | query->x |= data[4] << 2; | ||
193 | query->x |= (data[2] >> 5) & 0x3; | ||
194 | |||
195 | query->y = data[5] << 9; | ||
196 | query->y |= data[6] << 2; | ||
197 | query->y |= (data[2] >> 3) & 0x3; | ||
198 | |||
199 | /* Early days' single-finger touch models need the following defaults */ | ||
200 | if (!query->x && !query->y) { | ||
201 | query->x = 1024; | ||
202 | query->y = 1024; | ||
203 | if (query->panel_res) | ||
204 | query->x = query->y = (1 << query->panel_res); | ||
205 | query->panel_res = W8001_TOUCH_RESOLUTION; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) | ||
210 | { | ||
211 | struct input_dev *dev = w8001->dev; | ||
212 | |||
213 | /* | ||
214 | * We have 1 bit for proximity (rdy) and 3 bits for tip, side, | ||
215 | * side2/eraser. If rdy && f2 are set, this can be either pen + side2, | ||
216 | * or eraser. Assume: | ||
217 | * - if dev is already in proximity and f2 is toggled → pen + side2 | ||
218 | * - if dev comes into proximity with f2 set → eraser | ||
219 | * If f2 disappears after assuming eraser, fake proximity out for | ||
220 | * eraser and in for pen. | ||
221 | */ | ||
222 | |||
223 | switch (w8001->type) { | ||
224 | case BTN_TOOL_RUBBER: | ||
225 | if (!coord->f2) { | ||
226 | input_report_abs(dev, ABS_PRESSURE, 0); | ||
227 | input_report_key(dev, BTN_TOUCH, 0); | ||
228 | input_report_key(dev, BTN_STYLUS, 0); | ||
229 | input_report_key(dev, BTN_STYLUS2, 0); | ||
230 | input_report_key(dev, BTN_TOOL_RUBBER, 0); | ||
231 | input_sync(dev); | ||
232 | w8001->type = BTN_TOOL_PEN; | ||
233 | } | ||
234 | break; | ||
235 | |||
236 | case BTN_TOOL_FINGER: | ||
237 | input_report_key(dev, BTN_TOUCH, 0); | ||
238 | input_report_key(dev, BTN_TOOL_FINGER, 0); | ||
239 | input_sync(dev); | ||
240 | /* fall through */ | ||
241 | |||
242 | case KEY_RESERVED: | ||
243 | w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
244 | break; | ||
245 | |||
246 | default: | ||
247 | input_report_key(dev, BTN_STYLUS2, coord->f2); | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | input_report_abs(dev, ABS_X, coord->x); | ||
252 | input_report_abs(dev, ABS_Y, coord->y); | ||
253 | input_report_abs(dev, ABS_PRESSURE, coord->pen_pressure); | ||
254 | input_report_key(dev, BTN_TOUCH, coord->tsw); | ||
255 | input_report_key(dev, BTN_STYLUS, coord->f1); | ||
256 | input_report_key(dev, w8001->type, coord->rdy); | ||
257 | input_sync(dev); | ||
258 | |||
259 | if (!coord->rdy) | ||
260 | w8001->type = KEY_RESERVED; | ||
261 | } | ||
262 | |||
263 | static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord) | ||
264 | { | ||
265 | struct input_dev *dev = w8001->dev; | ||
266 | unsigned int x = coord->x; | ||
267 | unsigned int y = coord->y; | ||
268 | |||
269 | /* scale to pen maximum */ | ||
270 | scale_touch_coordinates(w8001, &x, &y); | ||
271 | |||
272 | input_report_abs(dev, ABS_X, x); | ||
273 | input_report_abs(dev, ABS_Y, y); | ||
274 | input_report_key(dev, BTN_TOUCH, coord->tsw); | ||
275 | input_report_key(dev, BTN_TOOL_FINGER, coord->tsw); | ||
276 | |||
277 | input_sync(dev); | ||
278 | |||
279 | w8001->type = coord->tsw ? BTN_TOOL_FINGER : KEY_RESERVED; | ||
280 | } | ||
281 | |||
91 | static irqreturn_t w8001_interrupt(struct serio *serio, | 282 | static irqreturn_t w8001_interrupt(struct serio *serio, |
92 | unsigned char data, unsigned int flags) | 283 | unsigned char data, unsigned int flags) |
93 | { | 284 | { |
94 | struct w8001 *w8001 = serio_get_drvdata(serio); | 285 | struct w8001 *w8001 = serio_get_drvdata(serio); |
95 | struct input_dev *dev = w8001->dev; | ||
96 | struct w8001_coord coord; | 286 | struct w8001_coord coord; |
97 | unsigned char tmp; | 287 | unsigned char tmp; |
98 | 288 | ||
@@ -105,26 +295,54 @@ static irqreturn_t w8001_interrupt(struct serio *serio, | |||
105 | } | 295 | } |
106 | break; | 296 | break; |
107 | 297 | ||
108 | case 8: | 298 | case W8001_PKTLEN_TOUCH93 - 1: |
299 | case W8001_PKTLEN_TOUCH9A - 1: | ||
300 | tmp = w8001->data[0] & W8001_TOUCH_BYTE; | ||
301 | if (tmp != W8001_TOUCH_BYTE) | ||
302 | break; | ||
303 | |||
304 | if (w8001->pktlen == w8001->idx) { | ||
305 | w8001->idx = 0; | ||
306 | if (w8001->type != BTN_TOOL_PEN && | ||
307 | w8001->type != BTN_TOOL_RUBBER) { | ||
308 | parse_single_touch(w8001->data, &coord); | ||
309 | report_single_touch(w8001, &coord); | ||
310 | } | ||
311 | } | ||
312 | break; | ||
313 | |||
314 | /* Pen coordinates packet */ | ||
315 | case W8001_PKTLEN_TPCPEN - 1: | ||
109 | tmp = w8001->data[0] & W8001_TAB_MASK; | 316 | tmp = w8001->data[0] & W8001_TAB_MASK; |
110 | if (unlikely(tmp == W8001_TAB_BYTE)) | 317 | if (unlikely(tmp == W8001_TAB_BYTE)) |
111 | break; | 318 | break; |
112 | 319 | ||
320 | tmp = w8001->data[0] & W8001_TOUCH_BYTE; | ||
321 | if (tmp == W8001_TOUCH_BYTE) | ||
322 | break; | ||
323 | |||
113 | w8001->idx = 0; | 324 | w8001->idx = 0; |
114 | parse_data(w8001->data, &coord); | 325 | parse_pen_data(w8001->data, &coord); |
115 | input_report_abs(dev, ABS_X, coord.x); | 326 | report_pen_events(w8001, &coord); |
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; | 327 | break; |
121 | 328 | ||
122 | case 10: | 329 | /* control packet */ |
330 | case W8001_PKTLEN_TPCCTL - 1: | ||
331 | tmp = w8001->data[0] & W8001_TOUCH_MASK; | ||
332 | if (tmp == W8001_TOUCH_BYTE) | ||
333 | break; | ||
334 | |||
123 | w8001->idx = 0; | 335 | w8001->idx = 0; |
124 | memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); | 336 | memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); |
125 | w8001->response_type = W8001_QUERY_PACKET; | 337 | w8001->response_type = W8001_QUERY_PACKET; |
126 | complete(&w8001->cmd_done); | 338 | complete(&w8001->cmd_done); |
127 | break; | 339 | break; |
340 | |||
341 | /* 2 finger touch packet */ | ||
342 | case W8001_PKTLEN_TOUCH2FG - 1: | ||
343 | w8001->idx = 0; | ||
344 | parse_multi_touch(w8001); | ||
345 | break; | ||
128 | } | 346 | } |
129 | 347 | ||
130 | return IRQ_HANDLED; | 348 | return IRQ_HANDLED; |
@@ -153,19 +371,108 @@ static int w8001_setup(struct w8001 *w8001) | |||
153 | { | 371 | { |
154 | struct input_dev *dev = w8001->dev; | 372 | struct input_dev *dev = w8001->dev; |
155 | struct w8001_coord coord; | 373 | struct w8001_coord coord; |
374 | struct w8001_touch_query touch; | ||
156 | int error; | 375 | int error; |
157 | 376 | ||
158 | error = w8001_command(w8001, W8001_CMD_QUERY, true); | 377 | error = w8001_command(w8001, W8001_CMD_STOP, false); |
159 | if (error) | 378 | if (error) |
160 | return error; | 379 | return error; |
161 | 380 | ||
162 | parse_data(w8001->response, &coord); | 381 | msleep(250); /* wait 250ms before querying the device */ |
382 | |||
383 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
384 | strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name)); | ||
163 | 385 | ||
164 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); | 386 | /* penabled? */ |
165 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); | 387 | error = w8001_command(w8001, W8001_CMD_QUERY, true); |
166 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); | 388 | if (!error) { |
167 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | 389 | __set_bit(BTN_TOUCH, dev->keybit); |
168 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | 390 | __set_bit(BTN_TOOL_PEN, dev->keybit); |
391 | __set_bit(BTN_TOOL_RUBBER, dev->keybit); | ||
392 | __set_bit(BTN_STYLUS, dev->keybit); | ||
393 | __set_bit(BTN_STYLUS2, dev->keybit); | ||
394 | |||
395 | parse_pen_data(w8001->response, &coord); | ||
396 | w8001->max_pen_x = coord.x; | ||
397 | w8001->max_pen_y = coord.y; | ||
398 | |||
399 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); | ||
400 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); | ||
401 | input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); | ||
402 | input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); | ||
403 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); | ||
404 | if (coord.tilt_x && coord.tilt_y) { | ||
405 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | ||
406 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | ||
407 | } | ||
408 | w8001->id = 0x90; | ||
409 | strlcat(w8001->name, " Penabled", sizeof(w8001->name)); | ||
410 | } | ||
411 | |||
412 | /* Touch enabled? */ | ||
413 | error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); | ||
414 | |||
415 | /* | ||
416 | * Some non-touch devices may reply to the touch query. But their | ||
417 | * second byte is empty, which indicates touch is not supported. | ||
418 | */ | ||
419 | if (!error && w8001->response[1]) { | ||
420 | __set_bit(BTN_TOUCH, dev->keybit); | ||
421 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
422 | |||
423 | parse_touchquery(w8001->response, &touch); | ||
424 | w8001->max_touch_x = touch.x; | ||
425 | w8001->max_touch_y = touch.y; | ||
426 | |||
427 | if (w8001->max_pen_x && w8001->max_pen_y) { | ||
428 | /* if pen is supported scale to pen maximum */ | ||
429 | touch.x = w8001->max_pen_x; | ||
430 | touch.y = w8001->max_pen_y; | ||
431 | touch.panel_res = W8001_PEN_RESOLUTION; | ||
432 | } | ||
433 | |||
434 | input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); | ||
435 | input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); | ||
436 | input_abs_set_res(dev, ABS_X, touch.panel_res); | ||
437 | input_abs_set_res(dev, ABS_Y, touch.panel_res); | ||
438 | |||
439 | switch (touch.sensor_id) { | ||
440 | case 0: | ||
441 | case 2: | ||
442 | w8001->pktlen = W8001_PKTLEN_TOUCH93; | ||
443 | w8001->id = 0x93; | ||
444 | strlcat(w8001->name, " 1FG", sizeof(w8001->name)); | ||
445 | break; | ||
446 | |||
447 | case 1: | ||
448 | case 3: | ||
449 | case 4: | ||
450 | w8001->pktlen = W8001_PKTLEN_TOUCH9A; | ||
451 | strlcat(w8001->name, " 1FG", sizeof(w8001->name)); | ||
452 | w8001->id = 0x9a; | ||
453 | break; | ||
454 | |||
455 | case 5: | ||
456 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; | ||
457 | |||
458 | input_mt_init_slots(dev, 2); | ||
459 | input_set_abs_params(dev, ABS_MT_POSITION_X, | ||
460 | 0, touch.x, 0, 0); | ||
461 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | ||
462 | 0, touch.y, 0, 0); | ||
463 | input_set_abs_params(dev, ABS_MT_TOOL_TYPE, | ||
464 | 0, MT_TOOL_MAX, 0, 0); | ||
465 | |||
466 | strlcat(w8001->name, " 2FG", sizeof(w8001->name)); | ||
467 | if (w8001->max_pen_x && w8001->max_pen_y) | ||
468 | w8001->id = 0xE3; | ||
469 | else | ||
470 | w8001->id = 0xE2; | ||
471 | break; | ||
472 | } | ||
473 | } | ||
474 | |||
475 | strlcat(w8001->name, " Touchscreen", sizeof(w8001->name)); | ||
169 | 476 | ||
170 | return w8001_command(w8001, W8001_CMD_START, false); | 477 | return w8001_command(w8001, W8001_CMD_START, false); |
171 | } | 478 | } |
@@ -206,22 +513,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
206 | } | 513 | } |
207 | 514 | ||
208 | w8001->serio = serio; | 515 | w8001->serio = serio; |
209 | w8001->id = serio->id.id; | ||
210 | w8001->dev = input_dev; | 516 | w8001->dev = input_dev; |
211 | init_completion(&w8001->cmd_done); | 517 | init_completion(&w8001->cmd_done); |
212 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); | 518 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); |
213 | 519 | ||
214 | input_dev->name = "Wacom W8001 Penabled Serial TouchScreen"; | ||
215 | input_dev->phys = w8001->phys; | ||
216 | input_dev->id.bustype = BUS_RS232; | ||
217 | input_dev->id.vendor = SERIO_W8001; | ||
218 | input_dev->id.product = w8001->id; | ||
219 | input_dev->id.version = 0x0100; | ||
220 | input_dev->dev.parent = &serio->dev; | ||
221 | |||
222 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
223 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
224 | |||
225 | serio_set_drvdata(serio, w8001); | 520 | serio_set_drvdata(serio, w8001); |
226 | err = serio_open(serio, drv); | 521 | err = serio_open(serio, drv); |
227 | if (err) | 522 | if (err) |
@@ -231,6 +526,14 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
231 | if (err) | 526 | if (err) |
232 | goto fail3; | 527 | goto fail3; |
233 | 528 | ||
529 | input_dev->name = w8001->name; | ||
530 | input_dev->phys = w8001->phys; | ||
531 | input_dev->id.product = w8001->id; | ||
532 | input_dev->id.bustype = BUS_RS232; | ||
533 | input_dev->id.vendor = 0x056a; | ||
534 | input_dev->id.version = 0x0100; | ||
535 | input_dev->dev.parent = &serio->dev; | ||
536 | |||
234 | err = input_register_device(w8001->dev); | 537 | err = input_register_device(w8001->dev); |
235 | if (err) | 538 | if (err) |
236 | goto fail3; | 539 | goto fail3; |
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c new file mode 100644 index 000000000000..9175d49d2546 --- /dev/null +++ b/drivers/input/touchscreen/wm831x-ts.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Touchscreen driver for WM831x PMICs | ||
3 | * | ||
4 | * Copyright 2011 Wolfson Microelectronics plc. | ||
5 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/moduleparam.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/pm.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/mfd/wm831x/core.h> | ||
23 | #include <linux/mfd/wm831x/irq.h> | ||
24 | #include <linux/mfd/wm831x/pdata.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/types.h> | ||
28 | |||
29 | /* | ||
30 | * R16424 (0x4028) - Touch Control 1 | ||
31 | */ | ||
32 | #define WM831X_TCH_ENA 0x8000 /* TCH_ENA */ | ||
33 | #define WM831X_TCH_CVT_ENA 0x4000 /* TCH_CVT_ENA */ | ||
34 | #define WM831X_TCH_SLPENA 0x1000 /* TCH_SLPENA */ | ||
35 | #define WM831X_TCH_Z_ENA 0x0400 /* TCH_Z_ENA */ | ||
36 | #define WM831X_TCH_Y_ENA 0x0200 /* TCH_Y_ENA */ | ||
37 | #define WM831X_TCH_X_ENA 0x0100 /* TCH_X_ENA */ | ||
38 | #define WM831X_TCH_DELAY_MASK 0x00E0 /* TCH_DELAY - [7:5] */ | ||
39 | #define WM831X_TCH_DELAY_SHIFT 5 /* TCH_DELAY - [7:5] */ | ||
40 | #define WM831X_TCH_DELAY_WIDTH 3 /* TCH_DELAY - [7:5] */ | ||
41 | #define WM831X_TCH_RATE_MASK 0x001F /* TCH_RATE - [4:0] */ | ||
42 | #define WM831X_TCH_RATE_SHIFT 0 /* TCH_RATE - [4:0] */ | ||
43 | #define WM831X_TCH_RATE_WIDTH 5 /* TCH_RATE - [4:0] */ | ||
44 | |||
45 | /* | ||
46 | * R16425 (0x4029) - Touch Control 2 | ||
47 | */ | ||
48 | #define WM831X_TCH_PD_WK 0x2000 /* TCH_PD_WK */ | ||
49 | #define WM831X_TCH_5WIRE 0x1000 /* TCH_5WIRE */ | ||
50 | #define WM831X_TCH_PDONLY 0x0800 /* TCH_PDONLY */ | ||
51 | #define WM831X_TCH_ISEL 0x0100 /* TCH_ISEL */ | ||
52 | #define WM831X_TCH_RPU_MASK 0x000F /* TCH_RPU - [3:0] */ | ||
53 | #define WM831X_TCH_RPU_SHIFT 0 /* TCH_RPU - [3:0] */ | ||
54 | #define WM831X_TCH_RPU_WIDTH 4 /* TCH_RPU - [3:0] */ | ||
55 | |||
56 | /* | ||
57 | * R16426-8 (0x402A-C) - Touch Data X/Y/X | ||
58 | */ | ||
59 | #define WM831X_TCH_PD 0x8000 /* TCH_PD1 */ | ||
60 | #define WM831X_TCH_DATA_MASK 0x0FFF /* TCH_DATA - [11:0] */ | ||
61 | #define WM831X_TCH_DATA_SHIFT 0 /* TCH_DATA - [11:0] */ | ||
62 | #define WM831X_TCH_DATA_WIDTH 12 /* TCH_DATA - [11:0] */ | ||
63 | |||
64 | struct wm831x_ts { | ||
65 | struct input_dev *input_dev; | ||
66 | struct wm831x *wm831x; | ||
67 | unsigned int data_irq; | ||
68 | unsigned int pd_irq; | ||
69 | bool pressure; | ||
70 | bool pen_down; | ||
71 | struct work_struct pd_data_work; | ||
72 | }; | ||
73 | |||
74 | static void wm831x_pd_data_work(struct work_struct *work) | ||
75 | { | ||
76 | struct wm831x_ts *wm831x_ts = | ||
77 | container_of(work, struct wm831x_ts, pd_data_work); | ||
78 | |||
79 | if (wm831x_ts->pen_down) { | ||
80 | enable_irq(wm831x_ts->data_irq); | ||
81 | dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n"); | ||
82 | } else { | ||
83 | enable_irq(wm831x_ts->pd_irq); | ||
84 | dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n"); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) | ||
89 | { | ||
90 | struct wm831x_ts *wm831x_ts = irq_data; | ||
91 | struct wm831x *wm831x = wm831x_ts->wm831x; | ||
92 | static int data_types[] = { ABS_X, ABS_Y, ABS_PRESSURE }; | ||
93 | u16 data[3]; | ||
94 | int count; | ||
95 | int i, ret; | ||
96 | |||
97 | if (wm831x_ts->pressure) | ||
98 | count = 3; | ||
99 | else | ||
100 | count = 2; | ||
101 | |||
102 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, | ||
103 | WM831X_TCHDATA_EINT, WM831X_TCHDATA_EINT); | ||
104 | |||
105 | ret = wm831x_bulk_read(wm831x, WM831X_TOUCH_DATA_X, count, | ||
106 | data); | ||
107 | if (ret != 0) { | ||
108 | dev_err(wm831x->dev, "Failed to read touch data: %d\n", | ||
109 | ret); | ||
110 | return IRQ_NONE; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * We get a pen down reading on every reading, report pen up if any | ||
115 | * individual reading does so. | ||
116 | */ | ||
117 | wm831x_ts->pen_down = true; | ||
118 | for (i = 0; i < count; i++) { | ||
119 | if (!(data[i] & WM831X_TCH_PD)) { | ||
120 | wm831x_ts->pen_down = false; | ||
121 | continue; | ||
122 | } | ||
123 | input_report_abs(wm831x_ts->input_dev, data_types[i], | ||
124 | data[i] & WM831X_TCH_DATA_MASK); | ||
125 | } | ||
126 | |||
127 | if (!wm831x_ts->pen_down) { | ||
128 | /* Switch from data to pen down */ | ||
129 | dev_dbg(wm831x->dev, "IRQ DATA->PD\n"); | ||
130 | |||
131 | disable_irq_nosync(wm831x_ts->data_irq); | ||
132 | |||
133 | /* Don't need data any more */ | ||
134 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
135 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | | ||
136 | WM831X_TCH_Z_ENA, 0); | ||
137 | |||
138 | /* Flush any final samples that arrived while reading */ | ||
139 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, | ||
140 | WM831X_TCHDATA_EINT, WM831X_TCHDATA_EINT); | ||
141 | |||
142 | wm831x_bulk_read(wm831x, WM831X_TOUCH_DATA_X, count, data); | ||
143 | |||
144 | if (wm831x_ts->pressure) | ||
145 | input_report_abs(wm831x_ts->input_dev, | ||
146 | ABS_PRESSURE, 0); | ||
147 | |||
148 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0); | ||
149 | |||
150 | schedule_work(&wm831x_ts->pd_data_work); | ||
151 | } else { | ||
152 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1); | ||
153 | } | ||
154 | |||
155 | input_sync(wm831x_ts->input_dev); | ||
156 | |||
157 | return IRQ_HANDLED; | ||
158 | } | ||
159 | |||
160 | static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data) | ||
161 | { | ||
162 | struct wm831x_ts *wm831x_ts = irq_data; | ||
163 | struct wm831x *wm831x = wm831x_ts->wm831x; | ||
164 | int ena = 0; | ||
165 | |||
166 | if (wm831x_ts->pen_down) | ||
167 | return IRQ_HANDLED; | ||
168 | |||
169 | disable_irq_nosync(wm831x_ts->pd_irq); | ||
170 | |||
171 | /* Start collecting data */ | ||
172 | if (wm831x_ts->pressure) | ||
173 | ena |= WM831X_TCH_Z_ENA; | ||
174 | |||
175 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
176 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, | ||
177 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena); | ||
178 | |||
179 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, | ||
180 | WM831X_TCHPD_EINT, WM831X_TCHPD_EINT); | ||
181 | |||
182 | wm831x_ts->pen_down = true; | ||
183 | |||
184 | /* Switch from pen down to data */ | ||
185 | dev_dbg(wm831x->dev, "IRQ PD->DATA\n"); | ||
186 | schedule_work(&wm831x_ts->pd_data_work); | ||
187 | |||
188 | return IRQ_HANDLED; | ||
189 | } | ||
190 | |||
191 | static int wm831x_ts_input_open(struct input_dev *idev) | ||
192 | { | ||
193 | struct wm831x_ts *wm831x_ts = input_get_drvdata(idev); | ||
194 | struct wm831x *wm831x = wm831x_ts->wm831x; | ||
195 | |||
196 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
197 | WM831X_TCH_ENA | WM831X_TCH_CVT_ENA | | ||
198 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | | ||
199 | WM831X_TCH_Z_ENA, WM831X_TCH_ENA); | ||
200 | |||
201 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
202 | WM831X_TCH_CVT_ENA, WM831X_TCH_CVT_ENA); | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static void wm831x_ts_input_close(struct input_dev *idev) | ||
208 | { | ||
209 | struct wm831x_ts *wm831x_ts = input_get_drvdata(idev); | ||
210 | struct wm831x *wm831x = wm831x_ts->wm831x; | ||
211 | |||
212 | /* Shut the controller down, disabling all other functionality too */ | ||
213 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
214 | WM831X_TCH_ENA | WM831X_TCH_X_ENA | | ||
215 | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0); | ||
216 | |||
217 | /* Make sure any pending IRQs are done, the above will prevent | ||
218 | * new ones firing. | ||
219 | */ | ||
220 | synchronize_irq(wm831x_ts->data_irq); | ||
221 | synchronize_irq(wm831x_ts->pd_irq); | ||
222 | |||
223 | /* Make sure the IRQ completion work is quiesced */ | ||
224 | flush_work_sync(&wm831x_ts->pd_data_work); | ||
225 | |||
226 | /* If we ended up with the pen down then make sure we revert back | ||
227 | * to pen detection state for the next time we start up. | ||
228 | */ | ||
229 | if (wm831x_ts->pen_down) { | ||
230 | disable_irq(wm831x_ts->data_irq); | ||
231 | enable_irq(wm831x_ts->pd_irq); | ||
232 | wm831x_ts->pen_down = false; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | static __devinit int wm831x_ts_probe(struct platform_device *pdev) | ||
237 | { | ||
238 | struct wm831x_ts *wm831x_ts; | ||
239 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | ||
240 | struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent); | ||
241 | struct wm831x_touch_pdata *pdata = NULL; | ||
242 | struct input_dev *input_dev; | ||
243 | int error, irqf; | ||
244 | |||
245 | if (core_pdata) | ||
246 | pdata = core_pdata->touch; | ||
247 | |||
248 | wm831x_ts = kzalloc(sizeof(struct wm831x_ts), GFP_KERNEL); | ||
249 | input_dev = input_allocate_device(); | ||
250 | if (!wm831x_ts || !input_dev) { | ||
251 | error = -ENOMEM; | ||
252 | goto err_alloc; | ||
253 | } | ||
254 | |||
255 | wm831x_ts->wm831x = wm831x; | ||
256 | wm831x_ts->input_dev = input_dev; | ||
257 | INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work); | ||
258 | |||
259 | /* | ||
260 | * If we have a direct IRQ use it, otherwise use the interrupt | ||
261 | * from the WM831x IRQ controller. | ||
262 | */ | ||
263 | if (pdata && pdata->data_irq) | ||
264 | wm831x_ts->data_irq = pdata->data_irq; | ||
265 | else | ||
266 | wm831x_ts->data_irq = platform_get_irq_byname(pdev, "TCHDATA"); | ||
267 | |||
268 | if (pdata && pdata->pd_irq) | ||
269 | wm831x_ts->pd_irq = pdata->pd_irq; | ||
270 | else | ||
271 | wm831x_ts->pd_irq = platform_get_irq_byname(pdev, "TCHPD"); | ||
272 | |||
273 | if (pdata) | ||
274 | wm831x_ts->pressure = pdata->pressure; | ||
275 | else | ||
276 | wm831x_ts->pressure = true; | ||
277 | |||
278 | /* Five wire touchscreens can't report pressure */ | ||
279 | if (pdata && pdata->fivewire) { | ||
280 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
281 | WM831X_TCH_5WIRE, WM831X_TCH_5WIRE); | ||
282 | |||
283 | /* Pressure measurements are not possible for five wire mode */ | ||
284 | WARN_ON(pdata->pressure && pdata->fivewire); | ||
285 | wm831x_ts->pressure = false; | ||
286 | } else { | ||
287 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
288 | WM831X_TCH_5WIRE, 0); | ||
289 | } | ||
290 | |||
291 | if (pdata) { | ||
292 | switch (pdata->isel) { | ||
293 | default: | ||
294 | dev_err(&pdev->dev, "Unsupported ISEL setting: %d\n", | ||
295 | pdata->isel); | ||
296 | /* Fall through */ | ||
297 | case 200: | ||
298 | case 0: | ||
299 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
300 | WM831X_TCH_ISEL, 0); | ||
301 | break; | ||
302 | case 400: | ||
303 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
304 | WM831X_TCH_ISEL, WM831X_TCH_ISEL); | ||
305 | break; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
310 | WM831X_TCH_PDONLY, 0); | ||
311 | |||
312 | /* Default to 96 samples/sec */ | ||
313 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
314 | WM831X_TCH_RATE_MASK, 6); | ||
315 | |||
316 | if (pdata && pdata->data_irqf) | ||
317 | irqf = pdata->data_irqf; | ||
318 | else | ||
319 | irqf = IRQF_TRIGGER_HIGH; | ||
320 | |||
321 | error = request_threaded_irq(wm831x_ts->data_irq, | ||
322 | NULL, wm831x_ts_data_irq, | ||
323 | irqf | IRQF_ONESHOT, | ||
324 | "Touchscreen data", wm831x_ts); | ||
325 | if (error) { | ||
326 | dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n", | ||
327 | wm831x_ts->data_irq, error); | ||
328 | goto err_alloc; | ||
329 | } | ||
330 | disable_irq(wm831x_ts->data_irq); | ||
331 | |||
332 | if (pdata && pdata->pd_irqf) | ||
333 | irqf = pdata->pd_irqf; | ||
334 | else | ||
335 | irqf = IRQF_TRIGGER_HIGH; | ||
336 | |||
337 | error = request_threaded_irq(wm831x_ts->pd_irq, | ||
338 | NULL, wm831x_ts_pen_down_irq, | ||
339 | irqf | IRQF_ONESHOT, | ||
340 | "Touchscreen pen down", wm831x_ts); | ||
341 | if (error) { | ||
342 | dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n", | ||
343 | wm831x_ts->pd_irq, error); | ||
344 | goto err_data_irq; | ||
345 | } | ||
346 | |||
347 | /* set up touch configuration */ | ||
348 | input_dev->name = "WM831x touchscreen"; | ||
349 | input_dev->phys = "wm831x"; | ||
350 | input_dev->open = wm831x_ts_input_open; | ||
351 | input_dev->close = wm831x_ts_input_close; | ||
352 | |||
353 | __set_bit(EV_ABS, input_dev->evbit); | ||
354 | __set_bit(EV_KEY, input_dev->evbit); | ||
355 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
356 | |||
357 | input_set_abs_params(input_dev, ABS_X, 0, 4095, 5, 0); | ||
358 | input_set_abs_params(input_dev, ABS_Y, 0, 4095, 5, 0); | ||
359 | if (wm831x_ts->pressure) | ||
360 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 4095, 5, 0); | ||
361 | |||
362 | input_set_drvdata(input_dev, wm831x_ts); | ||
363 | input_dev->dev.parent = &pdev->dev; | ||
364 | |||
365 | error = input_register_device(input_dev); | ||
366 | if (error) | ||
367 | goto err_pd_irq; | ||
368 | |||
369 | platform_set_drvdata(pdev, wm831x_ts); | ||
370 | return 0; | ||
371 | |||
372 | err_pd_irq: | ||
373 | free_irq(wm831x_ts->pd_irq, wm831x_ts); | ||
374 | err_data_irq: | ||
375 | free_irq(wm831x_ts->data_irq, wm831x_ts); | ||
376 | err_alloc: | ||
377 | input_free_device(input_dev); | ||
378 | kfree(wm831x_ts); | ||
379 | |||
380 | return error; | ||
381 | } | ||
382 | |||
383 | static __devexit int wm831x_ts_remove(struct platform_device *pdev) | ||
384 | { | ||
385 | struct wm831x_ts *wm831x_ts = platform_get_drvdata(pdev); | ||
386 | |||
387 | free_irq(wm831x_ts->pd_irq, wm831x_ts); | ||
388 | free_irq(wm831x_ts->data_irq, wm831x_ts); | ||
389 | input_unregister_device(wm831x_ts->input_dev); | ||
390 | kfree(wm831x_ts); | ||
391 | |||
392 | platform_set_drvdata(pdev, NULL); | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static struct platform_driver wm831x_ts_driver = { | ||
397 | .driver = { | ||
398 | .name = "wm831x-touch", | ||
399 | .owner = THIS_MODULE, | ||
400 | }, | ||
401 | .probe = wm831x_ts_probe, | ||
402 | .remove = __devexit_p(wm831x_ts_remove), | ||
403 | }; | ||
404 | |||
405 | static int __init wm831x_ts_init(void) | ||
406 | { | ||
407 | return platform_driver_register(&wm831x_ts_driver); | ||
408 | } | ||
409 | module_init(wm831x_ts_init); | ||
410 | |||
411 | static void __exit wm831x_ts_exit(void) | ||
412 | { | ||
413 | platform_driver_unregister(&wm831x_ts_driver); | ||
414 | } | ||
415 | module_exit(wm831x_ts_exit); | ||
416 | |||
417 | /* Module information */ | ||
418 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
419 | MODULE_DESCRIPTION("WM831x PMIC touchscreen driver"); | ||
420 | MODULE_LICENSE("GPL"); | ||
421 | MODULE_ALIAS("platform:wm831x-touch"); | ||
diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c index 6b5be742c27d..98e61175d3f5 100644 --- a/drivers/input/touchscreen/wm9705.c +++ b/drivers/input/touchscreen/wm9705.c | |||
@@ -306,7 +306,7 @@ static int wm9705_acc_enable(struct wm97xx *wm, int enable) | |||
306 | dig2 = wm->dig[2]; | 306 | dig2 = wm->dig[2]; |
307 | 307 | ||
308 | if (enable) { | 308 | if (enable) { |
309 | /* continous mode */ | 309 | /* continuous mode */ |
310 | if (wm->mach_ops->acc_startup && | 310 | if (wm->mach_ops->acc_startup && |
311 | (ret = wm->mach_ops->acc_startup(wm)) < 0) | 311 | (ret = wm->mach_ops->acc_startup(wm)) < 0) |
312 | return ret; | 312 | return ret; |
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 7490b05c3566..2bc2fb801009 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c | |||
@@ -419,7 +419,7 @@ static int wm9712_acc_enable(struct wm97xx *wm, int enable) | |||
419 | dig2 = wm->dig[2]; | 419 | dig2 = wm->dig[2]; |
420 | 420 | ||
421 | if (enable) { | 421 | if (enable) { |
422 | /* continous mode */ | 422 | /* continuous mode */ |
423 | if (wm->mach_ops->acc_startup) { | 423 | if (wm->mach_ops->acc_startup) { |
424 | ret = wm->mach_ops->acc_startup(wm); | 424 | ret = wm->mach_ops->acc_startup(wm); |
425 | if (ret < 0) | 425 | if (ret < 0) |
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c index 238b5132712e..73ec99568f12 100644 --- a/drivers/input/touchscreen/wm9713.c +++ b/drivers/input/touchscreen/wm9713.c | |||
@@ -431,7 +431,7 @@ static int wm9713_acc_enable(struct wm97xx *wm, int enable) | |||
431 | dig3 = wm->dig[2]; | 431 | dig3 = wm->dig[2]; |
432 | 432 | ||
433 | if (enable) { | 433 | if (enable) { |
434 | /* continous mode */ | 434 | /* continuous mode */ |
435 | if (wm->mach_ops->acc_startup && | 435 | if (wm->mach_ops->acc_startup && |
436 | (ret = wm->mach_ops->acc_startup(wm)) < 0) | 436 | (ret = wm->mach_ops->acc_startup(wm)) < 0) |
437 | return ret; | 437 | return ret; |
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index cbfef1ea7e30..5dbe73af2f8f 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -125,6 +125,8 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
125 | { | 125 | { |
126 | int power_adc = 0, auxval; | 126 | int power_adc = 0, auxval; |
127 | u16 power = 0; | 127 | u16 power = 0; |
128 | int rc = 0; | ||
129 | int timeout = 0; | ||
128 | 130 | ||
129 | /* get codec */ | 131 | /* get codec */ |
130 | mutex_lock(&wm->codec_mutex); | 132 | mutex_lock(&wm->codec_mutex); |
@@ -143,7 +145,9 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
143 | 145 | ||
144 | /* Turn polling mode on to read AUX ADC */ | 146 | /* Turn polling mode on to read AUX ADC */ |
145 | wm->pen_probably_down = 1; | 147 | wm->pen_probably_down = 1; |
146 | wm->codec->poll_sample(wm, adcsel, &auxval); | 148 | |
149 | while (rc != RC_VALID && timeout++ < 5) | ||
150 | rc = wm->codec->poll_sample(wm, adcsel, &auxval); | ||
147 | 151 | ||
148 | if (power_adc) | 152 | if (power_adc) |
149 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); | 153 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); |
@@ -152,8 +156,15 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
152 | 156 | ||
153 | wm->pen_probably_down = 0; | 157 | wm->pen_probably_down = 0; |
154 | 158 | ||
159 | if (timeout >= 5) { | ||
160 | dev_err(wm->dev, | ||
161 | "timeout reading auxadc %d, disabling digitiser\n", | ||
162 | adcsel); | ||
163 | wm->codec->dig_enable(wm, false); | ||
164 | } | ||
165 | |||
155 | mutex_unlock(&wm->codec_mutex); | 166 | mutex_unlock(&wm->codec_mutex); |
156 | return auxval & 0xfff; | 167 | return (rc == RC_VALID ? auxval & 0xfff : -EBUSY); |
157 | } | 168 | } |
158 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); | 169 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); |
159 | 170 | ||
@@ -324,7 +335,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work) | |||
324 | */ | 335 | */ |
325 | if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) { | 336 | if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) { |
326 | if (wm->pen_is_down && !pen_was_down) { | 337 | if (wm->pen_is_down && !pen_was_down) { |
327 | /* Data is not availiable immediately on pen down */ | 338 | /* Data is not available immediately on pen down */ |
328 | queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1); | 339 | queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1); |
329 | } | 340 | } |
330 | 341 | ||
@@ -343,7 +354,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work) | |||
343 | * Codec PENDOWN irq handler | 354 | * Codec PENDOWN irq handler |
344 | * | 355 | * |
345 | * We have to disable the codec interrupt in the handler because it | 356 | * We have to disable the codec interrupt in the handler because it |
346 | * can take upto 1ms to clear the interrupt source. We schedule a task | 357 | * can take up to 1ms to clear the interrupt source. We schedule a task |
347 | * in a work queue to do the actual interaction with the chip. The | 358 | * in a work queue to do the actual interaction with the chip. The |
348 | * interrupt is then enabled again in the slow handler when the source | 359 | * interrupt is then enabled again in the slow handler when the source |
349 | * has been cleared. | 360 | * has been cleared. |
@@ -684,8 +695,7 @@ static int wm97xx_probe(struct device *dev) | |||
684 | touch_reg_err: | 695 | touch_reg_err: |
685 | platform_device_put(wm->touch_dev); | 696 | platform_device_put(wm->touch_dev); |
686 | touch_err: | 697 | touch_err: |
687 | platform_device_unregister(wm->battery_dev); | 698 | platform_device_del(wm->battery_dev); |
688 | wm->battery_dev = NULL; | ||
689 | batt_reg_err: | 699 | batt_reg_err: |
690 | platform_device_put(wm->battery_dev); | 700 | platform_device_put(wm->battery_dev); |
691 | batt_err: | 701 | batt_err: |
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index 048849867643..5b0f15ec874a 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c | |||
@@ -193,7 +193,7 @@ static int zylonite_wm97xx_probe(struct platform_device *pdev) | |||
193 | gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26); | 193 | gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26); |
194 | 194 | ||
195 | wm->pen_irq = IRQ_GPIO(gpio_touch_irq); | 195 | wm->pen_irq = IRQ_GPIO(gpio_touch_irq); |
196 | set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH); | 196 | irq_set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH); |
197 | 197 | ||
198 | wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, | 198 | wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, |
199 | WM97XX_GPIO_POL_HIGH, | 199 | WM97XX_GPIO_POL_HIGH, |