diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-10-11 03:45:21 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-10-11 03:45:21 -0400 |
commit | 0cc8d6a9d23d6662da91eeb6bb8e7d1c559850f0 (patch) | |
tree | 7187a6807ff5bd6e8f8dac7c53e2de28759a8354 /drivers/input | |
parent | dde3ada3d0069855eeb353707b2b0f946191cfd6 (diff) | |
parent | 7f8d4cad1e4e11a45d02bd6e024cc2812963c38a (diff) |
Merge branch 'next' into for-linus
Prepare second set of updates for 3.7 merge window (Wacom driver update
and patches extending number of input minors).
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/evdev.c | 177 | ||||
-rw-r--r-- | drivers/input/input-mt.c | 305 | ||||
-rw-r--r-- | drivers/input/input.c | 366 | ||||
-rw-r--r-- | drivers/input/joydev.c | 88 | ||||
-rw-r--r-- | drivers/input/keyboard/samsung-keypad.c | 11 | ||||
-rw-r--r-- | drivers/input/misc/uinput.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 348 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/sentelic.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 4 | ||||
-rw-r--r-- | drivers/input/mousedev.c | 224 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 145 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 36 | ||||
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 8 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_core.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/edt-ft5x06.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/egalax_ts.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/ili210x.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/mms114.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/penmount.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/wacom_w8001.c | 2 |
22 files changed, 1045 insertions, 691 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6c58bfff01a3..6ae2ac47c9c8 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -23,11 +23,11 @@ | |||
23 | #include <linux/input/mt.h> | 23 | #include <linux/input/mt.h> |
24 | #include <linux/major.h> | 24 | #include <linux/major.h> |
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/cdev.h> | ||
26 | #include "input-compat.h" | 27 | #include "input-compat.h" |
27 | 28 | ||
28 | struct evdev { | 29 | struct evdev { |
29 | int open; | 30 | int open; |
30 | int minor; | ||
31 | struct input_handle handle; | 31 | struct input_handle handle; |
32 | wait_queue_head_t wait; | 32 | wait_queue_head_t wait; |
33 | struct evdev_client __rcu *grab; | 33 | struct evdev_client __rcu *grab; |
@@ -35,6 +35,7 @@ struct evdev { | |||
35 | spinlock_t client_lock; /* protects client_list */ | 35 | spinlock_t client_lock; /* protects client_list */ |
36 | struct mutex mutex; | 36 | struct mutex mutex; |
37 | struct device dev; | 37 | struct device dev; |
38 | struct cdev cdev; | ||
38 | bool exist; | 39 | bool exist; |
39 | }; | 40 | }; |
40 | 41 | ||
@@ -51,19 +52,9 @@ struct evdev_client { | |||
51 | struct input_event buffer[]; | 52 | struct input_event buffer[]; |
52 | }; | 53 | }; |
53 | 54 | ||
54 | static struct evdev *evdev_table[EVDEV_MINORS]; | 55 | static void __pass_event(struct evdev_client *client, |
55 | static DEFINE_MUTEX(evdev_table_mutex); | 56 | const struct input_event *event) |
56 | |||
57 | static void evdev_pass_event(struct evdev_client *client, | ||
58 | struct input_event *event, | ||
59 | ktime_t mono, ktime_t real) | ||
60 | { | 57 | { |
61 | event->time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? | ||
62 | mono : real); | ||
63 | |||
64 | /* Interrupts are disabled, just acquire the lock. */ | ||
65 | spin_lock(&client->buffer_lock); | ||
66 | |||
67 | client->buffer[client->head++] = *event; | 58 | client->buffer[client->head++] = *event; |
68 | client->head &= client->bufsize - 1; | 59 | client->head &= client->bufsize - 1; |
69 | 60 | ||
@@ -86,42 +77,74 @@ static void evdev_pass_event(struct evdev_client *client, | |||
86 | client->packet_head = client->head; | 77 | client->packet_head = client->head; |
87 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | 78 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
88 | } | 79 | } |
80 | } | ||
81 | |||
82 | static void evdev_pass_values(struct evdev_client *client, | ||
83 | const struct input_value *vals, unsigned int count, | ||
84 | ktime_t mono, ktime_t real) | ||
85 | { | ||
86 | struct evdev *evdev = client->evdev; | ||
87 | const struct input_value *v; | ||
88 | struct input_event event; | ||
89 | bool wakeup = false; | ||
90 | |||
91 | event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? | ||
92 | mono : real); | ||
93 | |||
94 | /* Interrupts are disabled, just acquire the lock. */ | ||
95 | spin_lock(&client->buffer_lock); | ||
96 | |||
97 | for (v = vals; v != vals + count; v++) { | ||
98 | event.type = v->type; | ||
99 | event.code = v->code; | ||
100 | event.value = v->value; | ||
101 | __pass_event(client, &event); | ||
102 | if (v->type == EV_SYN && v->code == SYN_REPORT) | ||
103 | wakeup = true; | ||
104 | } | ||
89 | 105 | ||
90 | spin_unlock(&client->buffer_lock); | 106 | spin_unlock(&client->buffer_lock); |
107 | |||
108 | if (wakeup) | ||
109 | wake_up_interruptible(&evdev->wait); | ||
91 | } | 110 | } |
92 | 111 | ||
93 | /* | 112 | /* |
94 | * Pass incoming event to all connected clients. | 113 | * Pass incoming events to all connected clients. |
95 | */ | 114 | */ |
96 | static void evdev_event(struct input_handle *handle, | 115 | static void evdev_events(struct input_handle *handle, |
97 | unsigned int type, unsigned int code, int value) | 116 | const struct input_value *vals, unsigned int count) |
98 | { | 117 | { |
99 | struct evdev *evdev = handle->private; | 118 | struct evdev *evdev = handle->private; |
100 | struct evdev_client *client; | 119 | struct evdev_client *client; |
101 | struct input_event event; | ||
102 | ktime_t time_mono, time_real; | 120 | ktime_t time_mono, time_real; |
103 | 121 | ||
104 | time_mono = ktime_get(); | 122 | time_mono = ktime_get(); |
105 | time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); | 123 | time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); |
106 | 124 | ||
107 | event.type = type; | ||
108 | event.code = code; | ||
109 | event.value = value; | ||
110 | |||
111 | rcu_read_lock(); | 125 | rcu_read_lock(); |
112 | 126 | ||
113 | client = rcu_dereference(evdev->grab); | 127 | client = rcu_dereference(evdev->grab); |
114 | 128 | ||
115 | if (client) | 129 | if (client) |
116 | evdev_pass_event(client, &event, time_mono, time_real); | 130 | evdev_pass_values(client, vals, count, time_mono, time_real); |
117 | else | 131 | else |
118 | list_for_each_entry_rcu(client, &evdev->client_list, node) | 132 | list_for_each_entry_rcu(client, &evdev->client_list, node) |
119 | evdev_pass_event(client, &event, time_mono, time_real); | 133 | evdev_pass_values(client, vals, count, |
134 | time_mono, time_real); | ||
120 | 135 | ||
121 | rcu_read_unlock(); | 136 | rcu_read_unlock(); |
137 | } | ||
122 | 138 | ||
123 | if (type == EV_SYN && code == SYN_REPORT) | 139 | /* |
124 | wake_up_interruptible(&evdev->wait); | 140 | * Pass incoming event to all connected clients. |
141 | */ | ||
142 | static void evdev_event(struct input_handle *handle, | ||
143 | unsigned int type, unsigned int code, int value) | ||
144 | { | ||
145 | struct input_value vals[] = { { type, code, value } }; | ||
146 | |||
147 | evdev_events(handle, vals, 1); | ||
125 | } | 148 | } |
126 | 149 | ||
127 | static int evdev_fasync(int fd, struct file *file, int on) | 150 | static int evdev_fasync(int fd, struct file *file, int on) |
@@ -285,35 +308,16 @@ static unsigned int evdev_compute_buffer_size(struct input_dev *dev) | |||
285 | 308 | ||
286 | static int evdev_open(struct inode *inode, struct file *file) | 309 | static int evdev_open(struct inode *inode, struct file *file) |
287 | { | 310 | { |
288 | struct evdev *evdev; | 311 | struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); |
312 | unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); | ||
289 | struct evdev_client *client; | 313 | struct evdev_client *client; |
290 | int i = iminor(inode) - EVDEV_MINOR_BASE; | ||
291 | unsigned int bufsize; | ||
292 | int error; | 314 | int error; |
293 | 315 | ||
294 | if (i >= EVDEV_MINORS) | ||
295 | return -ENODEV; | ||
296 | |||
297 | error = mutex_lock_interruptible(&evdev_table_mutex); | ||
298 | if (error) | ||
299 | return error; | ||
300 | evdev = evdev_table[i]; | ||
301 | if (evdev) | ||
302 | get_device(&evdev->dev); | ||
303 | mutex_unlock(&evdev_table_mutex); | ||
304 | |||
305 | if (!evdev) | ||
306 | return -ENODEV; | ||
307 | |||
308 | bufsize = evdev_compute_buffer_size(evdev->handle.dev); | ||
309 | |||
310 | client = kzalloc(sizeof(struct evdev_client) + | 316 | client = kzalloc(sizeof(struct evdev_client) + |
311 | bufsize * sizeof(struct input_event), | 317 | bufsize * sizeof(struct input_event), |
312 | GFP_KERNEL); | 318 | GFP_KERNEL); |
313 | if (!client) { | 319 | if (!client) |
314 | error = -ENOMEM; | 320 | return -ENOMEM; |
315 | goto err_put_evdev; | ||
316 | } | ||
317 | 321 | ||
318 | client->bufsize = bufsize; | 322 | client->bufsize = bufsize; |
319 | spin_lock_init(&client->buffer_lock); | 323 | spin_lock_init(&client->buffer_lock); |
@@ -327,13 +331,12 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
327 | file->private_data = client; | 331 | file->private_data = client; |
328 | nonseekable_open(inode, file); | 332 | nonseekable_open(inode, file); |
329 | 333 | ||
334 | get_device(&evdev->dev); | ||
330 | return 0; | 335 | return 0; |
331 | 336 | ||
332 | err_free_client: | 337 | err_free_client: |
333 | evdev_detach_client(evdev, client); | 338 | evdev_detach_client(evdev, client); |
334 | kfree(client); | 339 | kfree(client); |
335 | err_put_evdev: | ||
336 | put_device(&evdev->dev); | ||
337 | return error; | 340 | return error; |
338 | } | 341 | } |
339 | 342 | ||
@@ -653,20 +656,22 @@ static int evdev_handle_mt_request(struct input_dev *dev, | |||
653 | unsigned int size, | 656 | unsigned int size, |
654 | int __user *ip) | 657 | int __user *ip) |
655 | { | 658 | { |
656 | const struct input_mt_slot *mt = dev->mt; | 659 | const struct input_mt *mt = dev->mt; |
657 | unsigned int code; | 660 | unsigned int code; |
658 | int max_slots; | 661 | int max_slots; |
659 | int i; | 662 | int i; |
660 | 663 | ||
661 | if (get_user(code, &ip[0])) | 664 | if (get_user(code, &ip[0])) |
662 | return -EFAULT; | 665 | return -EFAULT; |
663 | if (!input_is_mt_value(code)) | 666 | if (!mt || !input_is_mt_value(code)) |
664 | return -EINVAL; | 667 | return -EINVAL; |
665 | 668 | ||
666 | max_slots = (size - sizeof(__u32)) / sizeof(__s32); | 669 | max_slots = (size - sizeof(__u32)) / sizeof(__s32); |
667 | for (i = 0; i < dev->mtsize && i < max_slots; i++) | 670 | for (i = 0; i < mt->num_slots && i < max_slots; i++) { |
668 | if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i])) | 671 | int value = input_mt_get_value(&mt->slots[i], code); |
672 | if (put_user(value, &ip[1 + i])) | ||
669 | return -EFAULT; | 673 | return -EFAULT; |
674 | } | ||
670 | 675 | ||
671 | return 0; | 676 | return 0; |
672 | } | 677 | } |
@@ -915,26 +920,6 @@ static const struct file_operations evdev_fops = { | |||
915 | .llseek = no_llseek, | 920 | .llseek = no_llseek, |
916 | }; | 921 | }; |
917 | 922 | ||
918 | static int evdev_install_chrdev(struct evdev *evdev) | ||
919 | { | ||
920 | /* | ||
921 | * No need to do any locking here as calls to connect and | ||
922 | * disconnect are serialized by the input core | ||
923 | */ | ||
924 | evdev_table[evdev->minor] = evdev; | ||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static void evdev_remove_chrdev(struct evdev *evdev) | ||
929 | { | ||
930 | /* | ||
931 | * Lock evdev table to prevent race with evdev_open() | ||
932 | */ | ||
933 | mutex_lock(&evdev_table_mutex); | ||
934 | evdev_table[evdev->minor] = NULL; | ||
935 | mutex_unlock(&evdev_table_mutex); | ||
936 | } | ||
937 | |||
938 | /* | 923 | /* |
939 | * Mark device non-existent. This disables writes, ioctls and | 924 | * Mark device non-existent. This disables writes, ioctls and |
940 | * prevents new users from opening the device. Already posted | 925 | * prevents new users from opening the device. Already posted |
@@ -953,7 +938,8 @@ static void evdev_cleanup(struct evdev *evdev) | |||
953 | 938 | ||
954 | evdev_mark_dead(evdev); | 939 | evdev_mark_dead(evdev); |
955 | evdev_hangup(evdev); | 940 | evdev_hangup(evdev); |
956 | evdev_remove_chrdev(evdev); | 941 | |
942 | cdev_del(&evdev->cdev); | ||
957 | 943 | ||
958 | /* evdev is marked dead so no one else accesses evdev->open */ | 944 | /* evdev is marked dead so no one else accesses evdev->open */ |
959 | if (evdev->open) { | 945 | if (evdev->open) { |
@@ -964,43 +950,47 @@ static void evdev_cleanup(struct evdev *evdev) | |||
964 | 950 | ||
965 | /* | 951 | /* |
966 | * Create new evdev device. Note that input core serializes calls | 952 | * Create new evdev device. Note that input core serializes calls |
967 | * to connect and disconnect so we don't need to lock evdev_table here. | 953 | * to connect and disconnect. |
968 | */ | 954 | */ |
969 | static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | 955 | static int evdev_connect(struct input_handler *handler, struct input_dev *dev, |
970 | const struct input_device_id *id) | 956 | const struct input_device_id *id) |
971 | { | 957 | { |
972 | struct evdev *evdev; | 958 | struct evdev *evdev; |
973 | int minor; | 959 | int minor; |
960 | int dev_no; | ||
974 | int error; | 961 | int error; |
975 | 962 | ||
976 | for (minor = 0; minor < EVDEV_MINORS; minor++) | 963 | minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true); |
977 | if (!evdev_table[minor]) | 964 | if (minor < 0) { |
978 | break; | 965 | error = minor; |
979 | 966 | pr_err("failed to reserve new minor: %d\n", error); | |
980 | if (minor == EVDEV_MINORS) { | 967 | return error; |
981 | pr_err("no more free evdev devices\n"); | ||
982 | return -ENFILE; | ||
983 | } | 968 | } |
984 | 969 | ||
985 | evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); | 970 | evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); |
986 | if (!evdev) | 971 | if (!evdev) { |
987 | return -ENOMEM; | 972 | error = -ENOMEM; |
973 | goto err_free_minor; | ||
974 | } | ||
988 | 975 | ||
989 | INIT_LIST_HEAD(&evdev->client_list); | 976 | INIT_LIST_HEAD(&evdev->client_list); |
990 | spin_lock_init(&evdev->client_lock); | 977 | spin_lock_init(&evdev->client_lock); |
991 | mutex_init(&evdev->mutex); | 978 | mutex_init(&evdev->mutex); |
992 | init_waitqueue_head(&evdev->wait); | 979 | init_waitqueue_head(&evdev->wait); |
993 | |||
994 | dev_set_name(&evdev->dev, "event%d", minor); | ||
995 | evdev->exist = true; | 980 | evdev->exist = true; |
996 | evdev->minor = minor; | 981 | |
982 | dev_no = minor; | ||
983 | /* Normalize device number if it falls into legacy range */ | ||
984 | if (dev_no < EVDEV_MINOR_BASE + EVDEV_MINORS) | ||
985 | dev_no -= EVDEV_MINOR_BASE; | ||
986 | dev_set_name(&evdev->dev, "event%d", dev_no); | ||
997 | 987 | ||
998 | evdev->handle.dev = input_get_device(dev); | 988 | evdev->handle.dev = input_get_device(dev); |
999 | evdev->handle.name = dev_name(&evdev->dev); | 989 | evdev->handle.name = dev_name(&evdev->dev); |
1000 | evdev->handle.handler = handler; | 990 | evdev->handle.handler = handler; |
1001 | evdev->handle.private = evdev; | 991 | evdev->handle.private = evdev; |
1002 | 992 | ||
1003 | evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); | 993 | evdev->dev.devt = MKDEV(INPUT_MAJOR, minor); |
1004 | evdev->dev.class = &input_class; | 994 | evdev->dev.class = &input_class; |
1005 | evdev->dev.parent = &dev->dev; | 995 | evdev->dev.parent = &dev->dev; |
1006 | evdev->dev.release = evdev_free; | 996 | evdev->dev.release = evdev_free; |
@@ -1010,7 +1000,8 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
1010 | if (error) | 1000 | if (error) |
1011 | goto err_free_evdev; | 1001 | goto err_free_evdev; |
1012 | 1002 | ||
1013 | error = evdev_install_chrdev(evdev); | 1003 | cdev_init(&evdev->cdev, &evdev_fops); |
1004 | error = cdev_add(&evdev->cdev, evdev->dev.devt, 1); | ||
1014 | if (error) | 1005 | if (error) |
1015 | goto err_unregister_handle; | 1006 | goto err_unregister_handle; |
1016 | 1007 | ||
@@ -1026,6 +1017,8 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
1026 | input_unregister_handle(&evdev->handle); | 1017 | input_unregister_handle(&evdev->handle); |
1027 | err_free_evdev: | 1018 | err_free_evdev: |
1028 | put_device(&evdev->dev); | 1019 | put_device(&evdev->dev); |
1020 | err_free_minor: | ||
1021 | input_free_minor(minor); | ||
1029 | return error; | 1022 | return error; |
1030 | } | 1023 | } |
1031 | 1024 | ||
@@ -1035,6 +1028,7 @@ static void evdev_disconnect(struct input_handle *handle) | |||
1035 | 1028 | ||
1036 | device_del(&evdev->dev); | 1029 | device_del(&evdev->dev); |
1037 | evdev_cleanup(evdev); | 1030 | evdev_cleanup(evdev); |
1031 | input_free_minor(MINOR(evdev->dev.devt)); | ||
1038 | input_unregister_handle(handle); | 1032 | input_unregister_handle(handle); |
1039 | put_device(&evdev->dev); | 1033 | put_device(&evdev->dev); |
1040 | } | 1034 | } |
@@ -1048,9 +1042,10 @@ MODULE_DEVICE_TABLE(input, evdev_ids); | |||
1048 | 1042 | ||
1049 | static struct input_handler evdev_handler = { | 1043 | static struct input_handler evdev_handler = { |
1050 | .event = evdev_event, | 1044 | .event = evdev_event, |
1045 | .events = evdev_events, | ||
1051 | .connect = evdev_connect, | 1046 | .connect = evdev_connect, |
1052 | .disconnect = evdev_disconnect, | 1047 | .disconnect = evdev_disconnect, |
1053 | .fops = &evdev_fops, | 1048 | .legacy_minors = true, |
1054 | .minor = EVDEV_MINOR_BASE, | 1049 | .minor = EVDEV_MINOR_BASE, |
1055 | .name = "evdev", | 1050 | .name = "evdev", |
1056 | .id_table = evdev_ids, | 1051 | .id_table = evdev_ids, |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 70a16c7da8cc..c0ec7d42c3be 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
@@ -14,6 +14,14 @@ | |||
14 | 14 | ||
15 | #define TRKID_SGN ((TRKID_MAX + 1) >> 1) | 15 | #define TRKID_SGN ((TRKID_MAX + 1) >> 1) |
16 | 16 | ||
17 | static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) | ||
18 | { | ||
19 | if (dev->absinfo && test_bit(src, dev->absbit)) { | ||
20 | dev->absinfo[dst] = dev->absinfo[src]; | ||
21 | dev->absbit[BIT_WORD(dst)] |= BIT_MASK(dst); | ||
22 | } | ||
23 | } | ||
24 | |||
17 | /** | 25 | /** |
18 | * input_mt_init_slots() - initialize MT input slots | 26 | * input_mt_init_slots() - initialize MT input slots |
19 | * @dev: input device supporting MT events and finger tracking | 27 | * @dev: input device supporting MT events and finger tracking |
@@ -25,29 +33,63 @@ | |||
25 | * May be called repeatedly. Returns -EINVAL if attempting to | 33 | * May be called repeatedly. Returns -EINVAL if attempting to |
26 | * reinitialize with a different number of slots. | 34 | * reinitialize with a different number of slots. |
27 | */ | 35 | */ |
28 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) | 36 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, |
37 | unsigned int flags) | ||
29 | { | 38 | { |
39 | struct input_mt *mt = dev->mt; | ||
30 | int i; | 40 | int i; |
31 | 41 | ||
32 | if (!num_slots) | 42 | if (!num_slots) |
33 | return 0; | 43 | return 0; |
34 | if (dev->mt) | 44 | if (mt) |
35 | return dev->mtsize != num_slots ? -EINVAL : 0; | 45 | return mt->num_slots != num_slots ? -EINVAL : 0; |
36 | 46 | ||
37 | dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL); | 47 | mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL); |
38 | if (!dev->mt) | 48 | if (!mt) |
39 | return -ENOMEM; | 49 | goto err_mem; |
40 | 50 | ||
41 | dev->mtsize = num_slots; | 51 | mt->num_slots = num_slots; |
52 | mt->flags = flags; | ||
42 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); | 53 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); |
43 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); | 54 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); |
44 | input_set_events_per_packet(dev, 6 * num_slots); | 55 | |
56 | if (flags & (INPUT_MT_POINTER | INPUT_MT_DIRECT)) { | ||
57 | __set_bit(EV_KEY, dev->evbit); | ||
58 | __set_bit(BTN_TOUCH, dev->keybit); | ||
59 | |||
60 | copy_abs(dev, ABS_X, ABS_MT_POSITION_X); | ||
61 | copy_abs(dev, ABS_Y, ABS_MT_POSITION_Y); | ||
62 | copy_abs(dev, ABS_PRESSURE, ABS_MT_PRESSURE); | ||
63 | } | ||
64 | if (flags & INPUT_MT_POINTER) { | ||
65 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
66 | __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); | ||
67 | if (num_slots >= 3) | ||
68 | __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); | ||
69 | if (num_slots >= 4) | ||
70 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | ||
71 | if (num_slots >= 5) | ||
72 | __set_bit(BTN_TOOL_QUINTTAP, dev->keybit); | ||
73 | __set_bit(INPUT_PROP_POINTER, dev->propbit); | ||
74 | } | ||
75 | if (flags & INPUT_MT_DIRECT) | ||
76 | __set_bit(INPUT_PROP_DIRECT, dev->propbit); | ||
77 | if (flags & INPUT_MT_TRACK) { | ||
78 | unsigned int n2 = num_slots * num_slots; | ||
79 | mt->red = kcalloc(n2, sizeof(*mt->red), GFP_KERNEL); | ||
80 | if (!mt->red) | ||
81 | goto err_mem; | ||
82 | } | ||
45 | 83 | ||
46 | /* Mark slots as 'unused' */ | 84 | /* Mark slots as 'unused' */ |
47 | for (i = 0; i < num_slots; i++) | 85 | for (i = 0; i < num_slots; i++) |
48 | input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1); | 86 | input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1); |
49 | 87 | ||
88 | dev->mt = mt; | ||
50 | return 0; | 89 | return 0; |
90 | err_mem: | ||
91 | kfree(mt); | ||
92 | return -ENOMEM; | ||
51 | } | 93 | } |
52 | EXPORT_SYMBOL(input_mt_init_slots); | 94 | EXPORT_SYMBOL(input_mt_init_slots); |
53 | 95 | ||
@@ -60,11 +102,11 @@ EXPORT_SYMBOL(input_mt_init_slots); | |||
60 | */ | 102 | */ |
61 | void input_mt_destroy_slots(struct input_dev *dev) | 103 | void input_mt_destroy_slots(struct input_dev *dev) |
62 | { | 104 | { |
63 | kfree(dev->mt); | 105 | if (dev->mt) { |
106 | kfree(dev->mt->red); | ||
107 | kfree(dev->mt); | ||
108 | } | ||
64 | dev->mt = NULL; | 109 | dev->mt = NULL; |
65 | dev->mtsize = 0; | ||
66 | dev->slot = 0; | ||
67 | dev->trkid = 0; | ||
68 | } | 110 | } |
69 | EXPORT_SYMBOL(input_mt_destroy_slots); | 111 | EXPORT_SYMBOL(input_mt_destroy_slots); |
70 | 112 | ||
@@ -83,18 +125,24 @@ EXPORT_SYMBOL(input_mt_destroy_slots); | |||
83 | void input_mt_report_slot_state(struct input_dev *dev, | 125 | void input_mt_report_slot_state(struct input_dev *dev, |
84 | unsigned int tool_type, bool active) | 126 | unsigned int tool_type, bool active) |
85 | { | 127 | { |
86 | struct input_mt_slot *mt; | 128 | struct input_mt *mt = dev->mt; |
129 | struct input_mt_slot *slot; | ||
87 | int id; | 130 | int id; |
88 | 131 | ||
89 | if (!dev->mt || !active) { | 132 | if (!mt) |
133 | return; | ||
134 | |||
135 | slot = &mt->slots[mt->slot]; | ||
136 | slot->frame = mt->frame; | ||
137 | |||
138 | if (!active) { | ||
90 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | 139 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); |
91 | return; | 140 | return; |
92 | } | 141 | } |
93 | 142 | ||
94 | mt = &dev->mt[dev->slot]; | 143 | id = input_mt_get_value(slot, ABS_MT_TRACKING_ID); |
95 | id = input_mt_get_value(mt, ABS_MT_TRACKING_ID); | 144 | if (id < 0 || input_mt_get_value(slot, ABS_MT_TOOL_TYPE) != tool_type) |
96 | if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type) | 145 | id = input_mt_new_trkid(mt); |
97 | id = input_mt_new_trkid(dev); | ||
98 | 146 | ||
99 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); | 147 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); |
100 | input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type); | 148 | input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type); |
@@ -135,13 +183,19 @@ EXPORT_SYMBOL(input_mt_report_finger_count); | |||
135 | */ | 183 | */ |
136 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) | 184 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) |
137 | { | 185 | { |
138 | struct input_mt_slot *oldest = NULL; | 186 | struct input_mt *mt = dev->mt; |
139 | int oldid = dev->trkid; | 187 | struct input_mt_slot *oldest; |
140 | int count = 0; | 188 | int oldid, count, i; |
141 | int i; | 189 | |
190 | if (!mt) | ||
191 | return; | ||
192 | |||
193 | oldest = 0; | ||
194 | oldid = mt->trkid; | ||
195 | count = 0; | ||
142 | 196 | ||
143 | for (i = 0; i < dev->mtsize; ++i) { | 197 | for (i = 0; i < mt->num_slots; ++i) { |
144 | struct input_mt_slot *ps = &dev->mt[i]; | 198 | struct input_mt_slot *ps = &mt->slots[i]; |
145 | int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); | 199 | int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); |
146 | 200 | ||
147 | if (id < 0) | 201 | if (id < 0) |
@@ -160,13 +214,208 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) | |||
160 | if (oldest) { | 214 | if (oldest) { |
161 | int x = input_mt_get_value(oldest, ABS_MT_POSITION_X); | 215 | int x = input_mt_get_value(oldest, ABS_MT_POSITION_X); |
162 | int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y); | 216 | int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y); |
163 | int p = input_mt_get_value(oldest, ABS_MT_PRESSURE); | ||
164 | 217 | ||
165 | input_event(dev, EV_ABS, ABS_X, x); | 218 | input_event(dev, EV_ABS, ABS_X, x); |
166 | input_event(dev, EV_ABS, ABS_Y, y); | 219 | input_event(dev, EV_ABS, ABS_Y, y); |
167 | input_event(dev, EV_ABS, ABS_PRESSURE, p); | 220 | |
221 | if (test_bit(ABS_MT_PRESSURE, dev->absbit)) { | ||
222 | int p = input_mt_get_value(oldest, ABS_MT_PRESSURE); | ||
223 | input_event(dev, EV_ABS, ABS_PRESSURE, p); | ||
224 | } | ||
168 | } else { | 225 | } else { |
169 | input_event(dev, EV_ABS, ABS_PRESSURE, 0); | 226 | if (test_bit(ABS_MT_PRESSURE, dev->absbit)) |
227 | input_event(dev, EV_ABS, ABS_PRESSURE, 0); | ||
170 | } | 228 | } |
171 | } | 229 | } |
172 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); | 230 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); |
231 | |||
232 | /** | ||
233 | * input_mt_sync_frame() - synchronize mt frame | ||
234 | * @dev: input device with allocated MT slots | ||
235 | * | ||
236 | * Close the frame and prepare the internal state for a new one. | ||
237 | * Depending on the flags, marks unused slots as inactive and performs | ||
238 | * pointer emulation. | ||
239 | */ | ||
240 | void input_mt_sync_frame(struct input_dev *dev) | ||
241 | { | ||
242 | struct input_mt *mt = dev->mt; | ||
243 | struct input_mt_slot *s; | ||
244 | |||
245 | if (!mt) | ||
246 | return; | ||
247 | |||
248 | if (mt->flags & INPUT_MT_DROP_UNUSED) { | ||
249 | for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { | ||
250 | if (s->frame == mt->frame) | ||
251 | continue; | ||
252 | input_mt_slot(dev, s - mt->slots); | ||
253 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | input_mt_report_pointer_emulation(dev, (mt->flags & INPUT_MT_POINTER)); | ||
258 | |||
259 | mt->frame++; | ||
260 | } | ||
261 | EXPORT_SYMBOL(input_mt_sync_frame); | ||
262 | |||
263 | static int adjust_dual(int *begin, int step, int *end, int eq) | ||
264 | { | ||
265 | int f, *p, s, c; | ||
266 | |||
267 | if (begin == end) | ||
268 | return 0; | ||
269 | |||
270 | f = *begin; | ||
271 | p = begin + step; | ||
272 | s = p == end ? f + 1 : *p; | ||
273 | |||
274 | for (; p != end; p += step) | ||
275 | if (*p < f) | ||
276 | s = f, f = *p; | ||
277 | else if (*p < s) | ||
278 | s = *p; | ||
279 | |||
280 | c = (f + s + 1) / 2; | ||
281 | if (c == 0 || (c > 0 && !eq)) | ||
282 | return 0; | ||
283 | if (s < 0) | ||
284 | c *= 2; | ||
285 | |||
286 | for (p = begin; p != end; p += step) | ||
287 | *p -= c; | ||
288 | |||
289 | return (c < s && s <= 0) || (f >= 0 && f < c); | ||
290 | } | ||
291 | |||
292 | static void find_reduced_matrix(int *w, int nr, int nc, int nrc) | ||
293 | { | ||
294 | int i, k, sum; | ||
295 | |||
296 | for (k = 0; k < nrc; k++) { | ||
297 | for (i = 0; i < nr; i++) | ||
298 | adjust_dual(w + i, nr, w + i + nrc, nr <= nc); | ||
299 | sum = 0; | ||
300 | for (i = 0; i < nrc; i += nr) | ||
301 | sum += adjust_dual(w + i, 1, w + i + nr, nc <= nr); | ||
302 | if (!sum) | ||
303 | break; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | static int input_mt_set_matrix(struct input_mt *mt, | ||
308 | const struct input_mt_pos *pos, int num_pos) | ||
309 | { | ||
310 | const struct input_mt_pos *p; | ||
311 | struct input_mt_slot *s; | ||
312 | int *w = mt->red; | ||
313 | int x, y; | ||
314 | |||
315 | for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { | ||
316 | if (!input_mt_is_active(s)) | ||
317 | continue; | ||
318 | x = input_mt_get_value(s, ABS_MT_POSITION_X); | ||
319 | y = input_mt_get_value(s, ABS_MT_POSITION_Y); | ||
320 | for (p = pos; p != pos + num_pos; p++) { | ||
321 | int dx = x - p->x, dy = y - p->y; | ||
322 | *w++ = dx * dx + dy * dy; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | return w - mt->red; | ||
327 | } | ||
328 | |||
329 | static void input_mt_set_slots(struct input_mt *mt, | ||
330 | int *slots, int num_pos) | ||
331 | { | ||
332 | struct input_mt_slot *s; | ||
333 | int *w = mt->red, *p; | ||
334 | |||
335 | for (p = slots; p != slots + num_pos; p++) | ||
336 | *p = -1; | ||
337 | |||
338 | for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { | ||
339 | if (!input_mt_is_active(s)) | ||
340 | continue; | ||
341 | for (p = slots; p != slots + num_pos; p++) | ||
342 | if (*w++ < 0) | ||
343 | *p = s - mt->slots; | ||
344 | } | ||
345 | |||
346 | for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { | ||
347 | if (input_mt_is_active(s)) | ||
348 | continue; | ||
349 | for (p = slots; p != slots + num_pos; p++) | ||
350 | if (*p < 0) { | ||
351 | *p = s - mt->slots; | ||
352 | break; | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | |||
357 | /** | ||
358 | * input_mt_assign_slots() - perform a best-match assignment | ||
359 | * @dev: input device with allocated MT slots | ||
360 | * @slots: the slot assignment to be filled | ||
361 | * @pos: the position array to match | ||
362 | * @num_pos: number of positions | ||
363 | * | ||
364 | * Performs a best match against the current contacts and returns | ||
365 | * the slot assignment list. New contacts are assigned to unused | ||
366 | * slots. | ||
367 | * | ||
368 | * Returns zero on success, or negative error in case of failure. | ||
369 | */ | ||
370 | int input_mt_assign_slots(struct input_dev *dev, int *slots, | ||
371 | const struct input_mt_pos *pos, int num_pos) | ||
372 | { | ||
373 | struct input_mt *mt = dev->mt; | ||
374 | int nrc; | ||
375 | |||
376 | if (!mt || !mt->red) | ||
377 | return -ENXIO; | ||
378 | if (num_pos > mt->num_slots) | ||
379 | return -EINVAL; | ||
380 | if (num_pos < 1) | ||
381 | return 0; | ||
382 | |||
383 | nrc = input_mt_set_matrix(mt, pos, num_pos); | ||
384 | find_reduced_matrix(mt->red, num_pos, nrc / num_pos, nrc); | ||
385 | input_mt_set_slots(mt, slots, num_pos); | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | EXPORT_SYMBOL(input_mt_assign_slots); | ||
390 | |||
391 | /** | ||
392 | * input_mt_get_slot_by_key() - return slot matching key | ||
393 | * @dev: input device with allocated MT slots | ||
394 | * @key: the key of the sought slot | ||
395 | * | ||
396 | * Returns the slot of the given key, if it exists, otherwise | ||
397 | * set the key on the first unused slot and return. | ||
398 | * | ||
399 | * If no available slot can be found, -1 is returned. | ||
400 | */ | ||
401 | int input_mt_get_slot_by_key(struct input_dev *dev, int key) | ||
402 | { | ||
403 | struct input_mt *mt = dev->mt; | ||
404 | struct input_mt_slot *s; | ||
405 | |||
406 | if (!mt) | ||
407 | return -1; | ||
408 | |||
409 | for (s = mt->slots; s != mt->slots + mt->num_slots; s++) | ||
410 | if (input_mt_is_active(s) && s->key == key) | ||
411 | return s - mt->slots; | ||
412 | |||
413 | for (s = mt->slots; s != mt->slots + mt->num_slots; s++) | ||
414 | if (!input_mt_is_active(s)) { | ||
415 | s->key = key; | ||
416 | return s - mt->slots; | ||
417 | } | ||
418 | |||
419 | return -1; | ||
420 | } | ||
421 | EXPORT_SYMBOL(input_mt_get_slot_by_key); | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index 768e46b05ef0..53a0ddee7872 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/idr.h> | ||
17 | #include <linux/input/mt.h> | 18 | #include <linux/input/mt.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
@@ -32,7 +33,9 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | |||
32 | MODULE_DESCRIPTION("Input core"); | 33 | MODULE_DESCRIPTION("Input core"); |
33 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
34 | 35 | ||
35 | #define INPUT_DEVICES 256 | 36 | #define INPUT_MAX_CHAR_DEVICES 1024 |
37 | #define INPUT_FIRST_DYNAMIC_DEV 256 | ||
38 | static DEFINE_IDA(input_ida); | ||
36 | 39 | ||
37 | static LIST_HEAD(input_dev_list); | 40 | static LIST_HEAD(input_dev_list); |
38 | static LIST_HEAD(input_handler_list); | 41 | static LIST_HEAD(input_handler_list); |
@@ -45,7 +48,7 @@ static LIST_HEAD(input_handler_list); | |||
45 | */ | 48 | */ |
46 | static DEFINE_MUTEX(input_mutex); | 49 | static DEFINE_MUTEX(input_mutex); |
47 | 50 | ||
48 | static struct input_handler *input_table[8]; | 51 | static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 }; |
49 | 52 | ||
50 | static inline int is_event_supported(unsigned int code, | 53 | static inline int is_event_supported(unsigned int code, |
51 | unsigned long *bm, unsigned int max) | 54 | unsigned long *bm, unsigned int max) |
@@ -69,42 +72,102 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) | |||
69 | return value; | 72 | return value; |
70 | } | 73 | } |
71 | 74 | ||
75 | static void input_start_autorepeat(struct input_dev *dev, int code) | ||
76 | { | ||
77 | if (test_bit(EV_REP, dev->evbit) && | ||
78 | dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] && | ||
79 | dev->timer.data) { | ||
80 | dev->repeat_key = code; | ||
81 | mod_timer(&dev->timer, | ||
82 | jiffies + msecs_to_jiffies(dev->rep[REP_DELAY])); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | static void input_stop_autorepeat(struct input_dev *dev) | ||
87 | { | ||
88 | del_timer(&dev->timer); | ||
89 | } | ||
90 | |||
72 | /* | 91 | /* |
73 | * Pass event first through all filters and then, if event has not been | 92 | * Pass event first through all filters and then, if event has not been |
74 | * filtered out, through all open handles. This function is called with | 93 | * filtered out, through all open handles. This function is called with |
75 | * dev->event_lock held and interrupts disabled. | 94 | * dev->event_lock held and interrupts disabled. |
76 | */ | 95 | */ |
77 | static void input_pass_event(struct input_dev *dev, | 96 | static unsigned int input_to_handler(struct input_handle *handle, |
78 | unsigned int type, unsigned int code, int value) | 97 | struct input_value *vals, unsigned int count) |
98 | { | ||
99 | struct input_handler *handler = handle->handler; | ||
100 | struct input_value *end = vals; | ||
101 | struct input_value *v; | ||
102 | |||
103 | for (v = vals; v != vals + count; v++) { | ||
104 | if (handler->filter && | ||
105 | handler->filter(handle, v->type, v->code, v->value)) | ||
106 | continue; | ||
107 | if (end != v) | ||
108 | *end = *v; | ||
109 | end++; | ||
110 | } | ||
111 | |||
112 | count = end - vals; | ||
113 | if (!count) | ||
114 | return 0; | ||
115 | |||
116 | if (handler->events) | ||
117 | handler->events(handle, vals, count); | ||
118 | else if (handler->event) | ||
119 | for (v = vals; v != end; v++) | ||
120 | handler->event(handle, v->type, v->code, v->value); | ||
121 | |||
122 | return count; | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Pass values first through all filters and then, if event has not been | ||
127 | * filtered out, through all open handles. This function is called with | ||
128 | * dev->event_lock held and interrupts disabled. | ||
129 | */ | ||
130 | static void input_pass_values(struct input_dev *dev, | ||
131 | struct input_value *vals, unsigned int count) | ||
79 | { | 132 | { |
80 | struct input_handler *handler; | ||
81 | struct input_handle *handle; | 133 | struct input_handle *handle; |
134 | struct input_value *v; | ||
135 | |||
136 | if (!count) | ||
137 | return; | ||
82 | 138 | ||
83 | rcu_read_lock(); | 139 | rcu_read_lock(); |
84 | 140 | ||
85 | handle = rcu_dereference(dev->grab); | 141 | handle = rcu_dereference(dev->grab); |
86 | if (handle) | 142 | if (handle) { |
87 | handle->handler->event(handle, type, code, value); | 143 | count = input_to_handler(handle, vals, count); |
88 | else { | 144 | } else { |
89 | bool filtered = false; | 145 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) |
90 | 146 | if (handle->open) | |
91 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) { | 147 | count = input_to_handler(handle, vals, count); |
92 | if (!handle->open) | 148 | } |
93 | continue; | ||
94 | 149 | ||
95 | handler = handle->handler; | 150 | rcu_read_unlock(); |
96 | if (!handler->filter) { | ||
97 | if (filtered) | ||
98 | break; | ||
99 | 151 | ||
100 | handler->event(handle, type, code, value); | 152 | add_input_randomness(vals->type, vals->code, vals->value); |
101 | 153 | ||
102 | } else if (handler->filter(handle, type, code, value)) | 154 | /* trigger auto repeat for key events */ |
103 | filtered = true; | 155 | for (v = vals; v != vals + count; v++) { |
156 | if (v->type == EV_KEY && v->value != 2) { | ||
157 | if (v->value) | ||
158 | input_start_autorepeat(dev, v->code); | ||
159 | else | ||
160 | input_stop_autorepeat(dev); | ||
104 | } | 161 | } |
105 | } | 162 | } |
163 | } | ||
106 | 164 | ||
107 | rcu_read_unlock(); | 165 | static void input_pass_event(struct input_dev *dev, |
166 | unsigned int type, unsigned int code, int value) | ||
167 | { | ||
168 | struct input_value vals[] = { { type, code, value } }; | ||
169 | |||
170 | input_pass_values(dev, vals, ARRAY_SIZE(vals)); | ||
108 | } | 171 | } |
109 | 172 | ||
110 | /* | 173 | /* |
@@ -121,18 +184,12 @@ static void input_repeat_key(unsigned long data) | |||
121 | 184 | ||
122 | if (test_bit(dev->repeat_key, dev->key) && | 185 | if (test_bit(dev->repeat_key, dev->key) && |
123 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { | 186 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { |
187 | struct input_value vals[] = { | ||
188 | { EV_KEY, dev->repeat_key, 2 }, | ||
189 | input_value_sync | ||
190 | }; | ||
124 | 191 | ||
125 | input_pass_event(dev, EV_KEY, dev->repeat_key, 2); | 192 | input_pass_values(dev, vals, ARRAY_SIZE(vals)); |
126 | |||
127 | if (dev->sync) { | ||
128 | /* | ||
129 | * Only send SYN_REPORT if we are not in a middle | ||
130 | * of driver parsing a new hardware packet. | ||
131 | * Otherwise assume that the driver will send | ||
132 | * SYN_REPORT once it's done. | ||
133 | */ | ||
134 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | ||
135 | } | ||
136 | 193 | ||
137 | if (dev->rep[REP_PERIOD]) | 194 | if (dev->rep[REP_PERIOD]) |
138 | mod_timer(&dev->timer, jiffies + | 195 | mod_timer(&dev->timer, jiffies + |
@@ -142,30 +199,17 @@ static void input_repeat_key(unsigned long data) | |||
142 | spin_unlock_irqrestore(&dev->event_lock, flags); | 199 | spin_unlock_irqrestore(&dev->event_lock, flags); |
143 | } | 200 | } |
144 | 201 | ||
145 | static void input_start_autorepeat(struct input_dev *dev, int code) | ||
146 | { | ||
147 | if (test_bit(EV_REP, dev->evbit) && | ||
148 | dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] && | ||
149 | dev->timer.data) { | ||
150 | dev->repeat_key = code; | ||
151 | mod_timer(&dev->timer, | ||
152 | jiffies + msecs_to_jiffies(dev->rep[REP_DELAY])); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | static void input_stop_autorepeat(struct input_dev *dev) | ||
157 | { | ||
158 | del_timer(&dev->timer); | ||
159 | } | ||
160 | |||
161 | #define INPUT_IGNORE_EVENT 0 | 202 | #define INPUT_IGNORE_EVENT 0 |
162 | #define INPUT_PASS_TO_HANDLERS 1 | 203 | #define INPUT_PASS_TO_HANDLERS 1 |
163 | #define INPUT_PASS_TO_DEVICE 2 | 204 | #define INPUT_PASS_TO_DEVICE 2 |
205 | #define INPUT_SLOT 4 | ||
206 | #define INPUT_FLUSH 8 | ||
164 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) | 207 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) |
165 | 208 | ||
166 | static int input_handle_abs_event(struct input_dev *dev, | 209 | static int input_handle_abs_event(struct input_dev *dev, |
167 | unsigned int code, int *pval) | 210 | unsigned int code, int *pval) |
168 | { | 211 | { |
212 | struct input_mt *mt = dev->mt; | ||
169 | bool is_mt_event; | 213 | bool is_mt_event; |
170 | int *pold; | 214 | int *pold; |
171 | 215 | ||
@@ -174,8 +218,8 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
174 | * "Stage" the event; we'll flush it later, when we | 218 | * "Stage" the event; we'll flush it later, when we |
175 | * get actual touch data. | 219 | * get actual touch data. |
176 | */ | 220 | */ |
177 | if (*pval >= 0 && *pval < dev->mtsize) | 221 | if (mt && *pval >= 0 && *pval < mt->num_slots) |
178 | dev->slot = *pval; | 222 | mt->slot = *pval; |
179 | 223 | ||
180 | return INPUT_IGNORE_EVENT; | 224 | return INPUT_IGNORE_EVENT; |
181 | } | 225 | } |
@@ -184,9 +228,8 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
184 | 228 | ||
185 | if (!is_mt_event) { | 229 | if (!is_mt_event) { |
186 | pold = &dev->absinfo[code].value; | 230 | pold = &dev->absinfo[code].value; |
187 | } else if (dev->mt) { | 231 | } else if (mt) { |
188 | struct input_mt_slot *mtslot = &dev->mt[dev->slot]; | 232 | pold = &mt->slots[mt->slot].abs[code - ABS_MT_FIRST]; |
189 | pold = &mtslot->abs[code - ABS_MT_FIRST]; | ||
190 | } else { | 233 | } else { |
191 | /* | 234 | /* |
192 | * Bypass filtering for multi-touch events when | 235 | * Bypass filtering for multi-touch events when |
@@ -205,16 +248,16 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
205 | } | 248 | } |
206 | 249 | ||
207 | /* Flush pending "slot" event */ | 250 | /* Flush pending "slot" event */ |
208 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { | 251 | if (is_mt_event && mt && mt->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { |
209 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); | 252 | input_abs_set_val(dev, ABS_MT_SLOT, mt->slot); |
210 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); | 253 | return INPUT_PASS_TO_HANDLERS | INPUT_SLOT; |
211 | } | 254 | } |
212 | 255 | ||
213 | return INPUT_PASS_TO_HANDLERS; | 256 | return INPUT_PASS_TO_HANDLERS; |
214 | } | 257 | } |
215 | 258 | ||
216 | static void input_handle_event(struct input_dev *dev, | 259 | static int input_get_disposition(struct input_dev *dev, |
217 | unsigned int type, unsigned int code, int value) | 260 | unsigned int type, unsigned int code, int value) |
218 | { | 261 | { |
219 | int disposition = INPUT_IGNORE_EVENT; | 262 | int disposition = INPUT_IGNORE_EVENT; |
220 | 263 | ||
@@ -227,37 +270,34 @@ static void input_handle_event(struct input_dev *dev, | |||
227 | break; | 270 | break; |
228 | 271 | ||
229 | case SYN_REPORT: | 272 | case SYN_REPORT: |
230 | if (!dev->sync) { | 273 | disposition = INPUT_PASS_TO_HANDLERS | INPUT_FLUSH; |
231 | dev->sync = true; | ||
232 | disposition = INPUT_PASS_TO_HANDLERS; | ||
233 | } | ||
234 | break; | 274 | break; |
235 | case SYN_MT_REPORT: | 275 | case SYN_MT_REPORT: |
236 | dev->sync = false; | ||
237 | disposition = INPUT_PASS_TO_HANDLERS; | 276 | disposition = INPUT_PASS_TO_HANDLERS; |
238 | break; | 277 | break; |
239 | } | 278 | } |
240 | break; | 279 | break; |
241 | 280 | ||
242 | case EV_KEY: | 281 | case EV_KEY: |
243 | if (is_event_supported(code, dev->keybit, KEY_MAX) && | 282 | if (is_event_supported(code, dev->keybit, KEY_MAX)) { |
244 | !!test_bit(code, dev->key) != value) { | ||
245 | 283 | ||
246 | if (value != 2) { | 284 | /* auto-repeat bypasses state updates */ |
247 | __change_bit(code, dev->key); | 285 | if (value == 2) { |
248 | if (value) | 286 | disposition = INPUT_PASS_TO_HANDLERS; |
249 | input_start_autorepeat(dev, code); | 287 | break; |
250 | else | ||
251 | input_stop_autorepeat(dev); | ||
252 | } | 288 | } |
253 | 289 | ||
254 | disposition = INPUT_PASS_TO_HANDLERS; | 290 | if (!!test_bit(code, dev->key) != !!value) { |
291 | |||
292 | __change_bit(code, dev->key); | ||
293 | disposition = INPUT_PASS_TO_HANDLERS; | ||
294 | } | ||
255 | } | 295 | } |
256 | break; | 296 | break; |
257 | 297 | ||
258 | case EV_SW: | 298 | case EV_SW: |
259 | if (is_event_supported(code, dev->swbit, SW_MAX) && | 299 | if (is_event_supported(code, dev->swbit, SW_MAX) && |
260 | !!test_bit(code, dev->sw) != value) { | 300 | !!test_bit(code, dev->sw) != !!value) { |
261 | 301 | ||
262 | __change_bit(code, dev->sw); | 302 | __change_bit(code, dev->sw); |
263 | disposition = INPUT_PASS_TO_HANDLERS; | 303 | disposition = INPUT_PASS_TO_HANDLERS; |
@@ -284,7 +324,7 @@ static void input_handle_event(struct input_dev *dev, | |||
284 | 324 | ||
285 | case EV_LED: | 325 | case EV_LED: |
286 | if (is_event_supported(code, dev->ledbit, LED_MAX) && | 326 | if (is_event_supported(code, dev->ledbit, LED_MAX) && |
287 | !!test_bit(code, dev->led) != value) { | 327 | !!test_bit(code, dev->led) != !!value) { |
288 | 328 | ||
289 | __change_bit(code, dev->led); | 329 | __change_bit(code, dev->led); |
290 | disposition = INPUT_PASS_TO_ALL; | 330 | disposition = INPUT_PASS_TO_ALL; |
@@ -317,14 +357,48 @@ static void input_handle_event(struct input_dev *dev, | |||
317 | break; | 357 | break; |
318 | } | 358 | } |
319 | 359 | ||
320 | if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) | 360 | return disposition; |
321 | dev->sync = false; | 361 | } |
362 | |||
363 | static void input_handle_event(struct input_dev *dev, | ||
364 | unsigned int type, unsigned int code, int value) | ||
365 | { | ||
366 | int disposition; | ||
367 | |||
368 | disposition = input_get_disposition(dev, type, code, value); | ||
322 | 369 | ||
323 | if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) | 370 | if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) |
324 | dev->event(dev, type, code, value); | 371 | dev->event(dev, type, code, value); |
325 | 372 | ||
326 | if (disposition & INPUT_PASS_TO_HANDLERS) | 373 | if (!dev->vals) |
327 | input_pass_event(dev, type, code, value); | 374 | return; |
375 | |||
376 | if (disposition & INPUT_PASS_TO_HANDLERS) { | ||
377 | struct input_value *v; | ||
378 | |||
379 | if (disposition & INPUT_SLOT) { | ||
380 | v = &dev->vals[dev->num_vals++]; | ||
381 | v->type = EV_ABS; | ||
382 | v->code = ABS_MT_SLOT; | ||
383 | v->value = dev->mt->slot; | ||
384 | } | ||
385 | |||
386 | v = &dev->vals[dev->num_vals++]; | ||
387 | v->type = type; | ||
388 | v->code = code; | ||
389 | v->value = value; | ||
390 | } | ||
391 | |||
392 | if (disposition & INPUT_FLUSH) { | ||
393 | if (dev->num_vals >= 2) | ||
394 | input_pass_values(dev, dev->vals, dev->num_vals); | ||
395 | dev->num_vals = 0; | ||
396 | } else if (dev->num_vals >= dev->max_vals - 2) { | ||
397 | dev->vals[dev->num_vals++] = input_value_sync; | ||
398 | input_pass_values(dev, dev->vals, dev->num_vals); | ||
399 | dev->num_vals = 0; | ||
400 | } | ||
401 | |||
328 | } | 402 | } |
329 | 403 | ||
330 | /** | 404 | /** |
@@ -352,7 +426,6 @@ void input_event(struct input_dev *dev, | |||
352 | if (is_event_supported(type, dev->evbit, EV_MAX)) { | 426 | if (is_event_supported(type, dev->evbit, EV_MAX)) { |
353 | 427 | ||
354 | spin_lock_irqsave(&dev->event_lock, flags); | 428 | spin_lock_irqsave(&dev->event_lock, flags); |
355 | add_input_randomness(type, code, value); | ||
356 | input_handle_event(dev, type, code, value); | 429 | input_handle_event(dev, type, code, value); |
357 | spin_unlock_irqrestore(&dev->event_lock, flags); | 430 | spin_unlock_irqrestore(&dev->event_lock, flags); |
358 | } | 431 | } |
@@ -831,10 +904,12 @@ int input_set_keycode(struct input_dev *dev, | |||
831 | if (test_bit(EV_KEY, dev->evbit) && | 904 | if (test_bit(EV_KEY, dev->evbit) && |
832 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && | 905 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && |
833 | __test_and_clear_bit(old_keycode, dev->key)) { | 906 | __test_and_clear_bit(old_keycode, dev->key)) { |
907 | struct input_value vals[] = { | ||
908 | { EV_KEY, old_keycode, 0 }, | ||
909 | input_value_sync | ||
910 | }; | ||
834 | 911 | ||
835 | input_pass_event(dev, EV_KEY, old_keycode, 0); | 912 | input_pass_values(dev, vals, ARRAY_SIZE(vals)); |
836 | if (dev->sync) | ||
837 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | ||
838 | } | 913 | } |
839 | 914 | ||
840 | out: | 915 | out: |
@@ -1144,7 +1219,7 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v) | |||
1144 | seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); | 1219 | seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); |
1145 | if (handler->filter) | 1220 | if (handler->filter) |
1146 | seq_puts(seq, " (filter)"); | 1221 | seq_puts(seq, " (filter)"); |
1147 | if (handler->fops) | 1222 | if (handler->legacy_minors) |
1148 | seq_printf(seq, " Minor=%d", handler->minor); | 1223 | seq_printf(seq, " Minor=%d", handler->minor); |
1149 | seq_putc(seq, '\n'); | 1224 | seq_putc(seq, '\n'); |
1150 | 1225 | ||
@@ -1425,6 +1500,7 @@ static void input_dev_release(struct device *device) | |||
1425 | input_ff_destroy(dev); | 1500 | input_ff_destroy(dev); |
1426 | input_mt_destroy_slots(dev); | 1501 | input_mt_destroy_slots(dev); |
1427 | kfree(dev->absinfo); | 1502 | kfree(dev->absinfo); |
1503 | kfree(dev->vals); | ||
1428 | kfree(dev); | 1504 | kfree(dev); |
1429 | 1505 | ||
1430 | module_put(THIS_MODULE); | 1506 | module_put(THIS_MODULE); |
@@ -1760,8 +1836,8 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | |||
1760 | int i; | 1836 | int i; |
1761 | unsigned int events; | 1837 | unsigned int events; |
1762 | 1838 | ||
1763 | if (dev->mtsize) { | 1839 | if (dev->mt) { |
1764 | mt_slots = dev->mtsize; | 1840 | mt_slots = dev->mt->num_slots; |
1765 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { | 1841 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { |
1766 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - | 1842 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - |
1767 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, | 1843 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, |
@@ -1787,6 +1863,9 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | |||
1787 | if (test_bit(i, dev->relbit)) | 1863 | if (test_bit(i, dev->relbit)) |
1788 | events++; | 1864 | events++; |
1789 | 1865 | ||
1866 | /* Make room for KEY and MSC events */ | ||
1867 | events += 7; | ||
1868 | |||
1790 | return events; | 1869 | return events; |
1791 | } | 1870 | } |
1792 | 1871 | ||
@@ -1825,6 +1904,7 @@ int input_register_device(struct input_dev *dev) | |||
1825 | { | 1904 | { |
1826 | static atomic_t input_no = ATOMIC_INIT(0); | 1905 | static atomic_t input_no = ATOMIC_INIT(0); |
1827 | struct input_handler *handler; | 1906 | struct input_handler *handler; |
1907 | unsigned int packet_size; | ||
1828 | const char *path; | 1908 | const char *path; |
1829 | int error; | 1909 | int error; |
1830 | 1910 | ||
@@ -1837,9 +1917,14 @@ int input_register_device(struct input_dev *dev) | |||
1837 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ | 1917 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ |
1838 | input_cleanse_bitmasks(dev); | 1918 | input_cleanse_bitmasks(dev); |
1839 | 1919 | ||
1840 | if (!dev->hint_events_per_packet) | 1920 | packet_size = input_estimate_events_per_packet(dev); |
1841 | dev->hint_events_per_packet = | 1921 | if (dev->hint_events_per_packet < packet_size) |
1842 | input_estimate_events_per_packet(dev); | 1922 | dev->hint_events_per_packet = packet_size; |
1923 | |||
1924 | dev->max_vals = max(dev->hint_events_per_packet, packet_size) + 2; | ||
1925 | dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); | ||
1926 | if (!dev->vals) | ||
1927 | return -ENOMEM; | ||
1843 | 1928 | ||
1844 | /* | 1929 | /* |
1845 | * If delay and period are pre-set by the driver, then autorepeating | 1930 | * If delay and period are pre-set by the driver, then autorepeating |
@@ -1932,22 +2017,14 @@ EXPORT_SYMBOL(input_unregister_device); | |||
1932 | int input_register_handler(struct input_handler *handler) | 2017 | int input_register_handler(struct input_handler *handler) |
1933 | { | 2018 | { |
1934 | struct input_dev *dev; | 2019 | struct input_dev *dev; |
1935 | int retval; | 2020 | int error; |
1936 | 2021 | ||
1937 | retval = mutex_lock_interruptible(&input_mutex); | 2022 | error = mutex_lock_interruptible(&input_mutex); |
1938 | if (retval) | 2023 | if (error) |
1939 | return retval; | 2024 | return error; |
1940 | 2025 | ||
1941 | INIT_LIST_HEAD(&handler->h_list); | 2026 | INIT_LIST_HEAD(&handler->h_list); |
1942 | 2027 | ||
1943 | if (handler->fops != NULL) { | ||
1944 | if (input_table[handler->minor >> 5]) { | ||
1945 | retval = -EBUSY; | ||
1946 | goto out; | ||
1947 | } | ||
1948 | input_table[handler->minor >> 5] = handler; | ||
1949 | } | ||
1950 | |||
1951 | list_add_tail(&handler->node, &input_handler_list); | 2028 | list_add_tail(&handler->node, &input_handler_list); |
1952 | 2029 | ||
1953 | list_for_each_entry(dev, &input_dev_list, node) | 2030 | list_for_each_entry(dev, &input_dev_list, node) |
@@ -1955,9 +2032,8 @@ int input_register_handler(struct input_handler *handler) | |||
1955 | 2032 | ||
1956 | input_wakeup_procfs_readers(); | 2033 | input_wakeup_procfs_readers(); |
1957 | 2034 | ||
1958 | out: | ||
1959 | mutex_unlock(&input_mutex); | 2035 | mutex_unlock(&input_mutex); |
1960 | return retval; | 2036 | return 0; |
1961 | } | 2037 | } |
1962 | EXPORT_SYMBOL(input_register_handler); | 2038 | EXPORT_SYMBOL(input_register_handler); |
1963 | 2039 | ||
@@ -1980,9 +2056,6 @@ void input_unregister_handler(struct input_handler *handler) | |||
1980 | 2056 | ||
1981 | list_del_init(&handler->node); | 2057 | list_del_init(&handler->node); |
1982 | 2058 | ||
1983 | if (handler->fops != NULL) | ||
1984 | input_table[handler->minor >> 5] = NULL; | ||
1985 | |||
1986 | input_wakeup_procfs_readers(); | 2059 | input_wakeup_procfs_readers(); |
1987 | 2060 | ||
1988 | mutex_unlock(&input_mutex); | 2061 | mutex_unlock(&input_mutex); |
@@ -2099,51 +2172,52 @@ void input_unregister_handle(struct input_handle *handle) | |||
2099 | } | 2172 | } |
2100 | EXPORT_SYMBOL(input_unregister_handle); | 2173 | EXPORT_SYMBOL(input_unregister_handle); |
2101 | 2174 | ||
2102 | static int input_open_file(struct inode *inode, struct file *file) | 2175 | /** |
2176 | * input_get_new_minor - allocates a new input minor number | ||
2177 | * @legacy_base: beginning or the legacy range to be searched | ||
2178 | * @legacy_num: size of legacy range | ||
2179 | * @allow_dynamic: whether we can also take ID from the dynamic range | ||
2180 | * | ||
2181 | * This function allocates a new device minor for from input major namespace. | ||
2182 | * Caller can request legacy minor by specifying @legacy_base and @legacy_num | ||
2183 | * parameters and whether ID can be allocated from dynamic range if there are | ||
2184 | * no free IDs in legacy range. | ||
2185 | */ | ||
2186 | int input_get_new_minor(int legacy_base, unsigned int legacy_num, | ||
2187 | bool allow_dynamic) | ||
2103 | { | 2188 | { |
2104 | struct input_handler *handler; | ||
2105 | const struct file_operations *old_fops, *new_fops = NULL; | ||
2106 | int err; | ||
2107 | |||
2108 | err = mutex_lock_interruptible(&input_mutex); | ||
2109 | if (err) | ||
2110 | return err; | ||
2111 | |||
2112 | /* No load-on-demand here? */ | ||
2113 | handler = input_table[iminor(inode) >> 5]; | ||
2114 | if (handler) | ||
2115 | new_fops = fops_get(handler->fops); | ||
2116 | |||
2117 | mutex_unlock(&input_mutex); | ||
2118 | |||
2119 | /* | 2189 | /* |
2120 | * That's _really_ odd. Usually NULL ->open means "nothing special", | 2190 | * This function should be called from input handler's ->connect() |
2121 | * not "no device". Oh, well... | 2191 | * methods, which are serialized with input_mutex, so no additional |
2192 | * locking is needed here. | ||
2122 | */ | 2193 | */ |
2123 | if (!new_fops || !new_fops->open) { | 2194 | if (legacy_base >= 0) { |
2124 | fops_put(new_fops); | 2195 | int minor = ida_simple_get(&input_ida, |
2125 | err = -ENODEV; | 2196 | legacy_base, |
2126 | goto out; | 2197 | legacy_base + legacy_num, |
2198 | GFP_KERNEL); | ||
2199 | if (minor >= 0 || !allow_dynamic) | ||
2200 | return minor; | ||
2127 | } | 2201 | } |
2128 | 2202 | ||
2129 | old_fops = file->f_op; | 2203 | return ida_simple_get(&input_ida, |
2130 | file->f_op = new_fops; | 2204 | INPUT_FIRST_DYNAMIC_DEV, INPUT_MAX_CHAR_DEVICES, |
2131 | 2205 | GFP_KERNEL); | |
2132 | err = new_fops->open(inode, file); | ||
2133 | if (err) { | ||
2134 | fops_put(file->f_op); | ||
2135 | file->f_op = fops_get(old_fops); | ||
2136 | } | ||
2137 | fops_put(old_fops); | ||
2138 | out: | ||
2139 | return err; | ||
2140 | } | 2206 | } |
2207 | EXPORT_SYMBOL(input_get_new_minor); | ||
2141 | 2208 | ||
2142 | static const struct file_operations input_fops = { | 2209 | /** |
2143 | .owner = THIS_MODULE, | 2210 | * input_free_minor - release previously allocated minor |
2144 | .open = input_open_file, | 2211 | * @minor: minor to be released |
2145 | .llseek = noop_llseek, | 2212 | * |
2146 | }; | 2213 | * This function releases previously allocated input minor so that it can be |
2214 | * reused later. | ||
2215 | */ | ||
2216 | void input_free_minor(unsigned int minor) | ||
2217 | { | ||
2218 | ida_simple_remove(&input_ida, minor); | ||
2219 | } | ||
2220 | EXPORT_SYMBOL(input_free_minor); | ||
2147 | 2221 | ||
2148 | static int __init input_init(void) | 2222 | static int __init input_init(void) |
2149 | { | 2223 | { |
@@ -2159,7 +2233,8 @@ static int __init input_init(void) | |||
2159 | if (err) | 2233 | if (err) |
2160 | goto fail1; | 2234 | goto fail1; |
2161 | 2235 | ||
2162 | err = register_chrdev(INPUT_MAJOR, "input", &input_fops); | 2236 | err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0), |
2237 | INPUT_MAX_CHAR_DEVICES, "input"); | ||
2163 | if (err) { | 2238 | if (err) { |
2164 | pr_err("unable to register char major %d", INPUT_MAJOR); | 2239 | pr_err("unable to register char major %d", INPUT_MAJOR); |
2165 | goto fail2; | 2240 | goto fail2; |
@@ -2175,7 +2250,8 @@ static int __init input_init(void) | |||
2175 | static void __exit input_exit(void) | 2250 | static void __exit input_exit(void) |
2176 | { | 2251 | { |
2177 | input_proc_exit(); | 2252 | input_proc_exit(); |
2178 | unregister_chrdev(INPUT_MAJOR, "input"); | 2253 | unregister_chrdev_region(MKDEV(INPUT_MAJOR, 0), |
2254 | INPUT_MAX_CHAR_DEVICES); | ||
2179 | class_unregister(&input_class); | 2255 | class_unregister(&input_class); |
2180 | } | 2256 | } |
2181 | 2257 | ||
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 78f323ea1e4b..b62b5891f399 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/poll.h> | 27 | #include <linux/poll.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/cdev.h> | ||
30 | 31 | ||
31 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 32 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
32 | MODULE_DESCRIPTION("Joystick device interfaces"); | 33 | MODULE_DESCRIPTION("Joystick device interfaces"); |
@@ -39,13 +40,13 @@ MODULE_LICENSE("GPL"); | |||
39 | 40 | ||
40 | struct joydev { | 41 | struct joydev { |
41 | int open; | 42 | int open; |
42 | int minor; | ||
43 | struct input_handle handle; | 43 | struct input_handle handle; |
44 | wait_queue_head_t wait; | 44 | wait_queue_head_t wait; |
45 | struct list_head client_list; | 45 | struct list_head client_list; |
46 | spinlock_t client_lock; /* protects client_list */ | 46 | spinlock_t client_lock; /* protects client_list */ |
47 | struct mutex mutex; | 47 | struct mutex mutex; |
48 | struct device dev; | 48 | struct device dev; |
49 | struct cdev cdev; | ||
49 | bool exist; | 50 | bool exist; |
50 | 51 | ||
51 | struct js_corr corr[ABS_CNT]; | 52 | struct js_corr corr[ABS_CNT]; |
@@ -70,9 +71,6 @@ struct joydev_client { | |||
70 | struct list_head node; | 71 | struct list_head node; |
71 | }; | 72 | }; |
72 | 73 | ||
73 | static struct joydev *joydev_table[JOYDEV_MINORS]; | ||
74 | static DEFINE_MUTEX(joydev_table_mutex); | ||
75 | |||
76 | static int joydev_correct(int value, struct js_corr *corr) | 74 | static int joydev_correct(int value, struct js_corr *corr) |
77 | { | 75 | { |
78 | switch (corr->type) { | 76 | switch (corr->type) { |
@@ -252,30 +250,14 @@ static int joydev_release(struct inode *inode, struct file *file) | |||
252 | 250 | ||
253 | static int joydev_open(struct inode *inode, struct file *file) | 251 | static int joydev_open(struct inode *inode, struct file *file) |
254 | { | 252 | { |
253 | struct joydev *joydev = | ||
254 | container_of(inode->i_cdev, struct joydev, cdev); | ||
255 | struct joydev_client *client; | 255 | struct joydev_client *client; |
256 | struct joydev *joydev; | ||
257 | int i = iminor(inode) - JOYDEV_MINOR_BASE; | ||
258 | int error; | 256 | int error; |
259 | 257 | ||
260 | if (i >= JOYDEV_MINORS) | ||
261 | return -ENODEV; | ||
262 | |||
263 | error = mutex_lock_interruptible(&joydev_table_mutex); | ||
264 | if (error) | ||
265 | return error; | ||
266 | joydev = joydev_table[i]; | ||
267 | if (joydev) | ||
268 | get_device(&joydev->dev); | ||
269 | mutex_unlock(&joydev_table_mutex); | ||
270 | |||
271 | if (!joydev) | ||
272 | return -ENODEV; | ||
273 | |||
274 | client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); | 258 | client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); |
275 | if (!client) { | 259 | if (!client) |
276 | error = -ENOMEM; | 260 | return -ENOMEM; |
277 | goto err_put_joydev; | ||
278 | } | ||
279 | 261 | ||
280 | spin_lock_init(&client->buffer_lock); | 262 | spin_lock_init(&client->buffer_lock); |
281 | client->joydev = joydev; | 263 | client->joydev = joydev; |
@@ -288,13 +270,12 @@ static int joydev_open(struct inode *inode, struct file *file) | |||
288 | file->private_data = client; | 270 | file->private_data = client; |
289 | nonseekable_open(inode, file); | 271 | nonseekable_open(inode, file); |
290 | 272 | ||
273 | get_device(&joydev->dev); | ||
291 | return 0; | 274 | return 0; |
292 | 275 | ||
293 | err_free_client: | 276 | err_free_client: |
294 | joydev_detach_client(joydev, client); | 277 | joydev_detach_client(joydev, client); |
295 | kfree(client); | 278 | kfree(client); |
296 | err_put_joydev: | ||
297 | put_device(&joydev->dev); | ||
298 | return error; | 279 | return error; |
299 | } | 280 | } |
300 | 281 | ||
@@ -742,19 +723,6 @@ static const struct file_operations joydev_fops = { | |||
742 | .llseek = no_llseek, | 723 | .llseek = no_llseek, |
743 | }; | 724 | }; |
744 | 725 | ||
745 | static int joydev_install_chrdev(struct joydev *joydev) | ||
746 | { | ||
747 | joydev_table[joydev->minor] = joydev; | ||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static void joydev_remove_chrdev(struct joydev *joydev) | ||
752 | { | ||
753 | mutex_lock(&joydev_table_mutex); | ||
754 | joydev_table[joydev->minor] = NULL; | ||
755 | mutex_unlock(&joydev_table_mutex); | ||
756 | } | ||
757 | |||
758 | /* | 726 | /* |
759 | * Mark device non-existent. This disables writes, ioctls and | 727 | * Mark device non-existent. This disables writes, ioctls and |
760 | * prevents new users from opening the device. Already posted | 728 | * prevents new users from opening the device. Already posted |
@@ -773,7 +741,8 @@ static void joydev_cleanup(struct joydev *joydev) | |||
773 | 741 | ||
774 | joydev_mark_dead(joydev); | 742 | joydev_mark_dead(joydev); |
775 | joydev_hangup(joydev); | 743 | joydev_hangup(joydev); |
776 | joydev_remove_chrdev(joydev); | 744 | |
745 | cdev_del(&joydev->cdev); | ||
777 | 746 | ||
778 | /* joydev is marked dead so no one else accesses joydev->open */ | 747 | /* joydev is marked dead so no one else accesses joydev->open */ |
779 | if (joydev->open) | 748 | if (joydev->open) |
@@ -798,30 +767,33 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
798 | const struct input_device_id *id) | 767 | const struct input_device_id *id) |
799 | { | 768 | { |
800 | struct joydev *joydev; | 769 | struct joydev *joydev; |
801 | int i, j, t, minor; | 770 | int i, j, t, minor, dev_no; |
802 | int error; | 771 | int error; |
803 | 772 | ||
804 | for (minor = 0; minor < JOYDEV_MINORS; minor++) | 773 | minor = input_get_new_minor(JOYDEV_MINOR_BASE, JOYDEV_MINORS, true); |
805 | if (!joydev_table[minor]) | 774 | if (minor < 0) { |
806 | break; | 775 | error = minor; |
807 | 776 | pr_err("failed to reserve new minor: %d\n", error); | |
808 | if (minor == JOYDEV_MINORS) { | 777 | return error; |
809 | pr_err("no more free joydev devices\n"); | ||
810 | return -ENFILE; | ||
811 | } | 778 | } |
812 | 779 | ||
813 | joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL); | 780 | joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL); |
814 | if (!joydev) | 781 | if (!joydev) { |
815 | return -ENOMEM; | 782 | error = -ENOMEM; |
783 | goto err_free_minor; | ||
784 | } | ||
816 | 785 | ||
817 | INIT_LIST_HEAD(&joydev->client_list); | 786 | INIT_LIST_HEAD(&joydev->client_list); |
818 | spin_lock_init(&joydev->client_lock); | 787 | spin_lock_init(&joydev->client_lock); |
819 | mutex_init(&joydev->mutex); | 788 | mutex_init(&joydev->mutex); |
820 | init_waitqueue_head(&joydev->wait); | 789 | init_waitqueue_head(&joydev->wait); |
821 | |||
822 | dev_set_name(&joydev->dev, "js%d", minor); | ||
823 | joydev->exist = true; | 790 | joydev->exist = true; |
824 | joydev->minor = minor; | 791 | |
792 | dev_no = minor; | ||
793 | /* Normalize device number if it falls into legacy range */ | ||
794 | if (dev_no < JOYDEV_MINOR_BASE + JOYDEV_MINORS) | ||
795 | dev_no -= JOYDEV_MINOR_BASE; | ||
796 | dev_set_name(&joydev->dev, "js%d", dev_no); | ||
825 | 797 | ||
826 | joydev->handle.dev = input_get_device(dev); | 798 | joydev->handle.dev = input_get_device(dev); |
827 | joydev->handle.name = dev_name(&joydev->dev); | 799 | joydev->handle.name = dev_name(&joydev->dev); |
@@ -875,7 +847,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
875 | } | 847 | } |
876 | } | 848 | } |
877 | 849 | ||
878 | joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor); | 850 | joydev->dev.devt = MKDEV(INPUT_MAJOR, minor); |
879 | joydev->dev.class = &input_class; | 851 | joydev->dev.class = &input_class; |
880 | joydev->dev.parent = &dev->dev; | 852 | joydev->dev.parent = &dev->dev; |
881 | joydev->dev.release = joydev_free; | 853 | joydev->dev.release = joydev_free; |
@@ -885,7 +857,8 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
885 | if (error) | 857 | if (error) |
886 | goto err_free_joydev; | 858 | goto err_free_joydev; |
887 | 859 | ||
888 | error = joydev_install_chrdev(joydev); | 860 | cdev_init(&joydev->cdev, &joydev_fops); |
861 | error = cdev_add(&joydev->cdev, joydev->dev.devt, 1); | ||
889 | if (error) | 862 | if (error) |
890 | goto err_unregister_handle; | 863 | goto err_unregister_handle; |
891 | 864 | ||
@@ -901,6 +874,8 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
901 | input_unregister_handle(&joydev->handle); | 874 | input_unregister_handle(&joydev->handle); |
902 | err_free_joydev: | 875 | err_free_joydev: |
903 | put_device(&joydev->dev); | 876 | put_device(&joydev->dev); |
877 | err_free_minor: | ||
878 | input_free_minor(minor); | ||
904 | return error; | 879 | return error; |
905 | } | 880 | } |
906 | 881 | ||
@@ -910,6 +885,7 @@ static void joydev_disconnect(struct input_handle *handle) | |||
910 | 885 | ||
911 | device_del(&joydev->dev); | 886 | device_del(&joydev->dev); |
912 | joydev_cleanup(joydev); | 887 | joydev_cleanup(joydev); |
888 | input_free_minor(MINOR(joydev->dev.devt)); | ||
913 | input_unregister_handle(handle); | 889 | input_unregister_handle(handle); |
914 | put_device(&joydev->dev); | 890 | put_device(&joydev->dev); |
915 | } | 891 | } |
@@ -961,7 +937,7 @@ static struct input_handler joydev_handler = { | |||
961 | .match = joydev_match, | 937 | .match = joydev_match, |
962 | .connect = joydev_connect, | 938 | .connect = joydev_connect, |
963 | .disconnect = joydev_disconnect, | 939 | .disconnect = joydev_disconnect, |
964 | .fops = &joydev_fops, | 940 | .legacy_minors = true, |
965 | .minor = JOYDEV_MINOR_BASE, | 941 | .minor = JOYDEV_MINOR_BASE, |
966 | .name = "joydev", | 942 | .name = "joydev", |
967 | .id_table = joydev_ids, | 943 | .id_table = joydev_ids, |
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 277e26dc910e..9d7a111486f7 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c | |||
@@ -431,6 +431,12 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) | |||
431 | goto err_unmap_base; | 431 | goto err_unmap_base; |
432 | } | 432 | } |
433 | 433 | ||
434 | error = clk_prepare(keypad->clk); | ||
435 | if (error) { | ||
436 | dev_err(&pdev->dev, "keypad clock prepare failed\n"); | ||
437 | goto err_put_clk; | ||
438 | } | ||
439 | |||
434 | keypad->input_dev = input_dev; | 440 | keypad->input_dev = input_dev; |
435 | keypad->pdev = pdev; | 441 | keypad->pdev = pdev; |
436 | keypad->row_shift = row_shift; | 442 | keypad->row_shift = row_shift; |
@@ -461,7 +467,7 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) | |||
461 | keypad->keycodes, input_dev); | 467 | keypad->keycodes, input_dev); |
462 | if (error) { | 468 | if (error) { |
463 | dev_err(&pdev->dev, "failed to build keymap\n"); | 469 | dev_err(&pdev->dev, "failed to build keymap\n"); |
464 | goto err_put_clk; | 470 | goto err_unprepare_clk; |
465 | } | 471 | } |
466 | 472 | ||
467 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 473 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
@@ -503,6 +509,8 @@ err_free_irq: | |||
503 | pm_runtime_disable(&pdev->dev); | 509 | pm_runtime_disable(&pdev->dev); |
504 | device_init_wakeup(&pdev->dev, 0); | 510 | device_init_wakeup(&pdev->dev, 0); |
505 | platform_set_drvdata(pdev, NULL); | 511 | platform_set_drvdata(pdev, NULL); |
512 | err_unprepare_clk: | ||
513 | clk_unprepare(keypad->clk); | ||
506 | err_put_clk: | 514 | err_put_clk: |
507 | clk_put(keypad->clk); | 515 | clk_put(keypad->clk); |
508 | samsung_keypad_dt_gpio_free(keypad); | 516 | samsung_keypad_dt_gpio_free(keypad); |
@@ -531,6 +539,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev) | |||
531 | */ | 539 | */ |
532 | free_irq(keypad->irq, keypad); | 540 | free_irq(keypad->irq, keypad); |
533 | 541 | ||
542 | clk_unprepare(keypad->clk); | ||
534 | clk_put(keypad->clk); | 543 | clk_put(keypad->clk); |
535 | samsung_keypad_dt_gpio_free(keypad); | 544 | samsung_keypad_dt_gpio_free(keypad); |
536 | 545 | ||
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 86328e9c9848..a0a4bbaef02c 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -416,7 +416,7 @@ static int uinput_setup_device(struct uinput_device *udev, | |||
416 | goto exit; | 416 | goto exit; |
417 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { | 417 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { |
418 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; | 418 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; |
419 | input_mt_init_slots(dev, nslot); | 419 | input_mt_init_slots(dev, nslot, 0); |
420 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | 420 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { |
421 | input_set_events_per_packet(dev, 60); | 421 | input_set_events_per_packet(dev, 60); |
422 | } | 422 | } |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4a1347e91bdc..cf5af1f495ec 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -1620,7 +1620,7 @@ int alps_init(struct psmouse *psmouse) | |||
1620 | case ALPS_PROTO_V3: | 1620 | case ALPS_PROTO_V3: |
1621 | case ALPS_PROTO_V4: | 1621 | case ALPS_PROTO_V4: |
1622 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); | 1622 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); |
1623 | input_mt_init_slots(dev1, 2); | 1623 | input_mt_init_slots(dev1, 2, 0); |
1624 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); | 1624 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); |
1625 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0); | 1625 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0); |
1626 | 1626 | ||
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index d528c23e194f..3a78f235fa3e 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/usb/input.h> | 40 | #include <linux/usb/input.h> |
41 | #include <linux/hid.h> | 41 | #include <linux/hid.h> |
42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
43 | #include <linux/input/mt.h> | ||
43 | 44 | ||
44 | #define USB_VENDOR_ID_APPLE 0x05ac | 45 | #define USB_VENDOR_ID_APPLE 0x05ac |
45 | 46 | ||
@@ -183,26 +184,26 @@ struct tp_finger { | |||
183 | __le16 abs_y; /* absolute y coodinate */ | 184 | __le16 abs_y; /* absolute y coodinate */ |
184 | __le16 rel_x; /* relative x coodinate */ | 185 | __le16 rel_x; /* relative x coodinate */ |
185 | __le16 rel_y; /* relative y coodinate */ | 186 | __le16 rel_y; /* relative y coodinate */ |
186 | __le16 size_major; /* finger size, major axis? */ | 187 | __le16 tool_major; /* tool area, major axis */ |
187 | __le16 size_minor; /* finger size, minor axis? */ | 188 | __le16 tool_minor; /* tool area, minor axis */ |
188 | __le16 orientation; /* 16384 when point, else 15 bit angle */ | 189 | __le16 orientation; /* 16384 when point, else 15 bit angle */ |
189 | __le16 force_major; /* trackpad force, major axis? */ | 190 | __le16 touch_major; /* touch area, major axis */ |
190 | __le16 force_minor; /* trackpad force, minor axis? */ | 191 | __le16 touch_minor; /* touch area, minor axis */ |
191 | __le16 unused[3]; /* zeros */ | 192 | __le16 unused[3]; /* zeros */ |
192 | __le16 multi; /* one finger: varies, more fingers: constant */ | 193 | __le16 multi; /* one finger: varies, more fingers: constant */ |
193 | } __attribute__((packed,aligned(2))); | 194 | } __attribute__((packed,aligned(2))); |
194 | 195 | ||
195 | /* trackpad finger data size, empirically at least ten fingers */ | 196 | /* trackpad finger data size, empirically at least ten fingers */ |
197 | #define MAX_FINGERS 16 | ||
196 | #define SIZEOF_FINGER sizeof(struct tp_finger) | 198 | #define SIZEOF_FINGER sizeof(struct tp_finger) |
197 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) | 199 | #define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) |
198 | #define MAX_FINGER_ORIENTATION 16384 | 200 | #define MAX_FINGER_ORIENTATION 16384 |
199 | 201 | ||
200 | /* device-specific parameters */ | 202 | /* device-specific parameters */ |
201 | struct bcm5974_param { | 203 | struct bcm5974_param { |
202 | int dim; /* logical dimension */ | 204 | int snratio; /* signal-to-noise ratio */ |
203 | int fuzz; /* logical noise value */ | 205 | int min; /* device minimum reading */ |
204 | int devmin; /* device minimum reading */ | 206 | int max; /* device maximum reading */ |
205 | int devmax; /* device maximum reading */ | ||
206 | }; | 207 | }; |
207 | 208 | ||
208 | /* device-specific configuration */ | 209 | /* device-specific configuration */ |
@@ -219,6 +220,7 @@ struct bcm5974_config { | |||
219 | struct bcm5974_param w; /* finger width limits */ | 220 | struct bcm5974_param w; /* finger width limits */ |
220 | struct bcm5974_param x; /* horizontal limits */ | 221 | struct bcm5974_param x; /* horizontal limits */ |
221 | struct bcm5974_param y; /* vertical limits */ | 222 | struct bcm5974_param y; /* vertical limits */ |
223 | struct bcm5974_param o; /* orientation limits */ | ||
222 | }; | 224 | }; |
223 | 225 | ||
224 | /* logical device structure */ | 226 | /* logical device structure */ |
@@ -234,23 +236,16 @@ struct bcm5974 { | |||
234 | struct bt_data *bt_data; /* button transferred data */ | 236 | struct bt_data *bt_data; /* button transferred data */ |
235 | struct urb *tp_urb; /* trackpad usb request block */ | 237 | struct urb *tp_urb; /* trackpad usb request block */ |
236 | u8 *tp_data; /* trackpad transferred data */ | 238 | u8 *tp_data; /* trackpad transferred data */ |
237 | int fingers; /* number of fingers on trackpad */ | 239 | const struct tp_finger *index[MAX_FINGERS]; /* finger index data */ |
240 | struct input_mt_pos pos[MAX_FINGERS]; /* position array */ | ||
241 | int slots[MAX_FINGERS]; /* slot assignments */ | ||
238 | }; | 242 | }; |
239 | 243 | ||
240 | /* logical dimensions */ | ||
241 | #define DIM_PRESSURE 256 /* maximum finger pressure */ | ||
242 | #define DIM_WIDTH 16 /* maximum finger width */ | ||
243 | #define DIM_X 1280 /* maximum trackpad x value */ | ||
244 | #define DIM_Y 800 /* maximum trackpad y value */ | ||
245 | |||
246 | /* logical signal quality */ | 244 | /* logical signal quality */ |
247 | #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ | 245 | #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ |
248 | #define SN_WIDTH 100 /* width signal-to-noise ratio */ | 246 | #define SN_WIDTH 25 /* width signal-to-noise ratio */ |
249 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ | 247 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ |
250 | 248 | #define SN_ORIENT 10 /* orientation signal-to-noise ratio */ | |
251 | /* pressure thresholds */ | ||
252 | #define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE) | ||
253 | #define PRESSURE_HIGH (3 * PRESSURE_LOW) | ||
254 | 249 | ||
255 | /* device constants */ | 250 | /* device constants */ |
256 | static const struct bcm5974_config bcm5974_config_table[] = { | 251 | static const struct bcm5974_config bcm5974_config_table[] = { |
@@ -261,10 +256,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
261 | 0, | 256 | 0, |
262 | 0x84, sizeof(struct bt_data), | 257 | 0x84, sizeof(struct bt_data), |
263 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, | 258 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
264 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 259 | { SN_PRESSURE, 0, 256 }, |
265 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 260 | { SN_WIDTH, 0, 2048 }, |
266 | { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, | 261 | { SN_COORD, -4824, 5342 }, |
267 | { DIM_Y, DIM_Y / SN_COORD, -172, 5820 } | 262 | { SN_COORD, -172, 5820 }, |
263 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
268 | }, | 264 | }, |
269 | { | 265 | { |
270 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, | 266 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, |
@@ -273,10 +269,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
273 | 0, | 269 | 0, |
274 | 0x84, sizeof(struct bt_data), | 270 | 0x84, sizeof(struct bt_data), |
275 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, | 271 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
276 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 272 | { SN_PRESSURE, 0, 256 }, |
277 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 273 | { SN_WIDTH, 0, 2048 }, |
278 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, | 274 | { SN_COORD, -4824, 4824 }, |
279 | { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } | 275 | { SN_COORD, -172, 4290 }, |
276 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
280 | }, | 277 | }, |
281 | { | 278 | { |
282 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, | 279 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, |
@@ -285,10 +282,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
285 | HAS_INTEGRATED_BUTTON, | 282 | HAS_INTEGRATED_BUTTON, |
286 | 0x84, sizeof(struct bt_data), | 283 | 0x84, sizeof(struct bt_data), |
287 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 284 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
288 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 285 | { SN_PRESSURE, 0, 300 }, |
289 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 286 | { SN_WIDTH, 0, 2048 }, |
290 | { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, | 287 | { SN_COORD, -4460, 5166 }, |
291 | { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } | 288 | { SN_COORD, -75, 6700 }, |
289 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
292 | }, | 290 | }, |
293 | { | 291 | { |
294 | USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, | 292 | USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, |
@@ -297,10 +295,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
297 | HAS_INTEGRATED_BUTTON, | 295 | HAS_INTEGRATED_BUTTON, |
298 | 0x84, sizeof(struct bt_data), | 296 | 0x84, sizeof(struct bt_data), |
299 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 297 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
300 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 298 | { SN_PRESSURE, 0, 300 }, |
301 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 299 | { SN_WIDTH, 0, 2048 }, |
302 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, | 300 | { SN_COORD, -4620, 5140 }, |
303 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } | 301 | { SN_COORD, -150, 6600 }, |
302 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
304 | }, | 303 | }, |
305 | { | 304 | { |
306 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, | 305 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, |
@@ -309,10 +308,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
309 | HAS_INTEGRATED_BUTTON, | 308 | HAS_INTEGRATED_BUTTON, |
310 | 0x84, sizeof(struct bt_data), | 309 | 0x84, sizeof(struct bt_data), |
311 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 310 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
312 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 311 | { SN_PRESSURE, 0, 300 }, |
313 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 312 | { SN_WIDTH, 0, 2048 }, |
314 | { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, | 313 | { SN_COORD, -4616, 5112 }, |
315 | { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } | 314 | { SN_COORD, -142, 5234 }, |
315 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
316 | }, | 316 | }, |
317 | { | 317 | { |
318 | USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, | 318 | USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, |
@@ -321,10 +321,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
321 | HAS_INTEGRATED_BUTTON, | 321 | HAS_INTEGRATED_BUTTON, |
322 | 0x84, sizeof(struct bt_data), | 322 | 0x84, sizeof(struct bt_data), |
323 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 323 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
324 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 324 | { SN_PRESSURE, 0, 300 }, |
325 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 325 | { SN_WIDTH, 0, 2048 }, |
326 | { DIM_X, DIM_X / SN_COORD, -4415, 5050 }, | 326 | { SN_COORD, -4415, 5050 }, |
327 | { DIM_Y, DIM_Y / SN_COORD, -55, 6680 } | 327 | { SN_COORD, -55, 6680 }, |
328 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
328 | }, | 329 | }, |
329 | { | 330 | { |
330 | USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, | 331 | USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, |
@@ -333,10 +334,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
333 | HAS_INTEGRATED_BUTTON, | 334 | HAS_INTEGRATED_BUTTON, |
334 | 0x84, sizeof(struct bt_data), | 335 | 0x84, sizeof(struct bt_data), |
335 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 336 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
336 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 337 | { SN_PRESSURE, 0, 300 }, |
337 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 338 | { SN_WIDTH, 0, 2048 }, |
338 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, | 339 | { SN_COORD, -4620, 5140 }, |
339 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } | 340 | { SN_COORD, -150, 6600 }, |
341 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
340 | }, | 342 | }, |
341 | { | 343 | { |
342 | USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, | 344 | USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, |
@@ -345,10 +347,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
345 | HAS_INTEGRATED_BUTTON, | 347 | HAS_INTEGRATED_BUTTON, |
346 | 0x84, sizeof(struct bt_data), | 348 | 0x84, sizeof(struct bt_data), |
347 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 349 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
348 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 350 | { SN_PRESSURE, 0, 300 }, |
349 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 351 | { SN_WIDTH, 0, 2048 }, |
350 | { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, | 352 | { SN_COORD, -4750, 5280 }, |
351 | { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } | 353 | { SN_COORD, -150, 6730 }, |
354 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
352 | }, | 355 | }, |
353 | { | 356 | { |
354 | USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, | 357 | USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, |
@@ -357,10 +360,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
357 | HAS_INTEGRATED_BUTTON, | 360 | HAS_INTEGRATED_BUTTON, |
358 | 0x84, sizeof(struct bt_data), | 361 | 0x84, sizeof(struct bt_data), |
359 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 362 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
360 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 363 | { SN_PRESSURE, 0, 300 }, |
361 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 364 | { SN_WIDTH, 0, 2048 }, |
362 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, | 365 | { SN_COORD, -4620, 5140 }, |
363 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } | 366 | { SN_COORD, -150, 6600 }, |
367 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
364 | }, | 368 | }, |
365 | { | 369 | { |
366 | USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, | 370 | USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, |
@@ -369,10 +373,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
369 | HAS_INTEGRATED_BUTTON, | 373 | HAS_INTEGRATED_BUTTON, |
370 | 0x84, sizeof(struct bt_data), | 374 | 0x84, sizeof(struct bt_data), |
371 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 375 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
372 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 376 | { SN_PRESSURE, 0, 300 }, |
373 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 377 | { SN_WIDTH, 0, 2048 }, |
374 | { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, | 378 | { SN_COORD, -4750, 5280 }, |
375 | { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } | 379 | { SN_COORD, -150, 6730 }, |
380 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
376 | }, | 381 | }, |
377 | {} | 382 | {} |
378 | }; | 383 | }; |
@@ -396,18 +401,11 @@ static inline int raw2int(__le16 x) | |||
396 | return (signed short)le16_to_cpu(x); | 401 | return (signed short)le16_to_cpu(x); |
397 | } | 402 | } |
398 | 403 | ||
399 | /* scale device data to logical dimensions (asserts devmin < devmax) */ | 404 | static void set_abs(struct input_dev *input, unsigned int code, |
400 | static inline int int2scale(const struct bcm5974_param *p, int x) | 405 | const struct bcm5974_param *p) |
401 | { | ||
402 | return x * p->dim / (p->devmax - p->devmin); | ||
403 | } | ||
404 | |||
405 | /* all logical value ranges are [0,dim). */ | ||
406 | static inline int int2bound(const struct bcm5974_param *p, int x) | ||
407 | { | 406 | { |
408 | int s = int2scale(p, x); | 407 | int fuzz = p->snratio ? (p->max - p->min) / p->snratio : 0; |
409 | 408 | input_set_abs_params(input, code, p->min, p->max, fuzz, 0); | |
410 | return clamp_val(s, 0, p->dim - 1); | ||
411 | } | 409 | } |
412 | 410 | ||
413 | /* setup which logical events to report */ | 411 | /* setup which logical events to report */ |
@@ -416,48 +414,30 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
416 | { | 414 | { |
417 | __set_bit(EV_ABS, input_dev->evbit); | 415 | __set_bit(EV_ABS, input_dev->evbit); |
418 | 416 | ||
419 | input_set_abs_params(input_dev, ABS_PRESSURE, | 417 | /* for synaptics only */ |
420 | 0, cfg->p.dim, cfg->p.fuzz, 0); | 418 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 5, 0); |
421 | input_set_abs_params(input_dev, ABS_TOOL_WIDTH, | 419 | input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 16, 0, 0); |
422 | 0, cfg->w.dim, cfg->w.fuzz, 0); | ||
423 | input_set_abs_params(input_dev, ABS_X, | ||
424 | 0, cfg->x.dim, cfg->x.fuzz, 0); | ||
425 | input_set_abs_params(input_dev, ABS_Y, | ||
426 | 0, cfg->y.dim, cfg->y.fuzz, 0); | ||
427 | 420 | ||
428 | /* finger touch area */ | 421 | /* finger touch area */ |
429 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 422 | set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w); |
430 | cfg->w.devmin, cfg->w.devmax, 0, 0); | 423 | set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w); |
431 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, | ||
432 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
433 | /* finger approach area */ | 424 | /* finger approach area */ |
434 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, | 425 | set_abs(input_dev, ABS_MT_WIDTH_MAJOR, &cfg->w); |
435 | cfg->w.devmin, cfg->w.devmax, 0, 0); | 426 | set_abs(input_dev, ABS_MT_WIDTH_MINOR, &cfg->w); |
436 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, | ||
437 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
438 | /* finger orientation */ | 427 | /* finger orientation */ |
439 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, | 428 | set_abs(input_dev, ABS_MT_ORIENTATION, &cfg->o); |
440 | -MAX_FINGER_ORIENTATION, | ||
441 | MAX_FINGER_ORIENTATION, 0, 0); | ||
442 | /* finger position */ | 429 | /* finger position */ |
443 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 430 | set_abs(input_dev, ABS_MT_POSITION_X, &cfg->x); |
444 | cfg->x.devmin, cfg->x.devmax, 0, 0); | 431 | set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y); |
445 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
446 | cfg->y.devmin, cfg->y.devmax, 0, 0); | ||
447 | 432 | ||
448 | __set_bit(EV_KEY, input_dev->evbit); | 433 | __set_bit(EV_KEY, input_dev->evbit); |
449 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
450 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
451 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
452 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
453 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | ||
454 | __set_bit(BTN_LEFT, input_dev->keybit); | 434 | __set_bit(BTN_LEFT, input_dev->keybit); |
455 | 435 | ||
456 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
457 | if (cfg->caps & HAS_INTEGRATED_BUTTON) | 436 | if (cfg->caps & HAS_INTEGRATED_BUTTON) |
458 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); | 437 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); |
459 | 438 | ||
460 | input_set_events_per_packet(input_dev, 60); | 439 | input_mt_init_slots(input_dev, MAX_FINGERS, |
440 | INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); | ||
461 | } | 441 | } |
462 | 442 | ||
463 | /* report button data as logical button state */ | 443 | /* report button data as logical button state */ |
@@ -477,24 +457,44 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
477 | return 0; | 457 | return 0; |
478 | } | 458 | } |
479 | 459 | ||
480 | static void report_finger_data(struct input_dev *input, | 460 | static void report_finger_data(struct input_dev *input, int slot, |
481 | const struct bcm5974_config *cfg, | 461 | const struct input_mt_pos *pos, |
482 | const struct tp_finger *f) | 462 | const struct tp_finger *f) |
483 | { | 463 | { |
464 | input_mt_slot(input, slot); | ||
465 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
466 | |||
484 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, | 467 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, |
485 | raw2int(f->force_major) << 1); | 468 | raw2int(f->touch_major) << 1); |
486 | input_report_abs(input, ABS_MT_TOUCH_MINOR, | 469 | input_report_abs(input, ABS_MT_TOUCH_MINOR, |
487 | raw2int(f->force_minor) << 1); | 470 | raw2int(f->touch_minor) << 1); |
488 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, | 471 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, |
489 | raw2int(f->size_major) << 1); | 472 | raw2int(f->tool_major) << 1); |
490 | input_report_abs(input, ABS_MT_WIDTH_MINOR, | 473 | input_report_abs(input, ABS_MT_WIDTH_MINOR, |
491 | raw2int(f->size_minor) << 1); | 474 | raw2int(f->tool_minor) << 1); |
492 | input_report_abs(input, ABS_MT_ORIENTATION, | 475 | input_report_abs(input, ABS_MT_ORIENTATION, |
493 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); | 476 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); |
494 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); | 477 | input_report_abs(input, ABS_MT_POSITION_X, pos->x); |
495 | input_report_abs(input, ABS_MT_POSITION_Y, | 478 | input_report_abs(input, ABS_MT_POSITION_Y, pos->y); |
496 | cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y)); | 479 | } |
497 | input_mt_sync(input); | 480 | |
481 | static void report_synaptics_data(struct input_dev *input, | ||
482 | const struct bcm5974_config *cfg, | ||
483 | const struct tp_finger *f, int raw_n) | ||
484 | { | ||
485 | int abs_p = 0, abs_w = 0; | ||
486 | |||
487 | if (raw_n) { | ||
488 | int p = raw2int(f->touch_major); | ||
489 | int w = raw2int(f->tool_major); | ||
490 | if (p > 0 && raw2int(f->origin)) { | ||
491 | abs_p = clamp_val(256 * p / cfg->p.max, 0, 255); | ||
492 | abs_w = clamp_val(16 * w / cfg->w.max, 0, 15); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | input_report_abs(input, ABS_PRESSURE, abs_p); | ||
497 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); | ||
498 | } | 498 | } |
499 | 499 | ||
500 | /* report trackpad data as logical trackpad state */ | 500 | /* report trackpad data as logical trackpad state */ |
@@ -503,9 +503,7 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
503 | const struct bcm5974_config *c = &dev->cfg; | 503 | const struct bcm5974_config *c = &dev->cfg; |
504 | const struct tp_finger *f; | 504 | const struct tp_finger *f; |
505 | struct input_dev *input = dev->input; | 505 | struct input_dev *input = dev->input; |
506 | int raw_p, raw_w, raw_x, raw_y, raw_n, i; | 506 | int raw_n, i, n = 0; |
507 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; | ||
508 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | ||
509 | 507 | ||
510 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) | 508 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) |
511 | return -EIO; | 509 | return -EIO; |
@@ -514,76 +512,29 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
514 | f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); | 512 | f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); |
515 | raw_n = (size - c->tp_offset) / SIZEOF_FINGER; | 513 | raw_n = (size - c->tp_offset) / SIZEOF_FINGER; |
516 | 514 | ||
517 | /* always track the first finger; when detached, start over */ | 515 | for (i = 0; i < raw_n; i++) { |
518 | if (raw_n) { | 516 | if (raw2int(f[i].touch_major) == 0) |
519 | 517 | continue; | |
520 | /* report raw trackpad data */ | 518 | dev->pos[n].x = raw2int(f[i].abs_x); |
521 | for (i = 0; i < raw_n; i++) | 519 | dev->pos[n].y = c->y.min + c->y.max - raw2int(f[i].abs_y); |
522 | report_finger_data(input, c, &f[i]); | 520 | dev->index[n++] = &f[i]; |
523 | |||
524 | raw_p = raw2int(f->force_major); | ||
525 | raw_w = raw2int(f->size_major); | ||
526 | raw_x = raw2int(f->abs_x); | ||
527 | raw_y = raw2int(f->abs_y); | ||
528 | |||
529 | dprintk(9, | ||
530 | "bcm5974: " | ||
531 | "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", | ||
532 | raw_p, raw_w, raw_x, raw_y, raw_n); | ||
533 | |||
534 | ptest = int2bound(&c->p, raw_p); | ||
535 | origin = raw2int(f->origin); | ||
536 | |||
537 | /* while tracking finger still valid, count all fingers */ | ||
538 | if (ptest > PRESSURE_LOW && origin) { | ||
539 | abs_p = ptest; | ||
540 | abs_w = int2bound(&c->w, raw_w); | ||
541 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); | ||
542 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); | ||
543 | while (raw_n--) { | ||
544 | ptest = int2bound(&c->p, | ||
545 | raw2int(f->force_major)); | ||
546 | if (ptest > PRESSURE_LOW) | ||
547 | nmax++; | ||
548 | if (ptest > PRESSURE_HIGH) | ||
549 | nmin++; | ||
550 | f++; | ||
551 | } | ||
552 | } | ||
553 | } | 521 | } |
554 | 522 | ||
555 | /* set the integrated button if applicable */ | 523 | input_mt_assign_slots(input, dev->slots, dev->pos, n); |
556 | if (c->tp_type == TYPE2) | ||
557 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
558 | |||
559 | if (dev->fingers < nmin) | ||
560 | dev->fingers = nmin; | ||
561 | if (dev->fingers > nmax) | ||
562 | dev->fingers = nmax; | ||
563 | |||
564 | input_report_key(input, BTN_TOUCH, dev->fingers > 0); | ||
565 | input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); | ||
566 | input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); | ||
567 | input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3); | ||
568 | input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3); | ||
569 | |||
570 | input_report_abs(input, ABS_PRESSURE, abs_p); | ||
571 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); | ||
572 | 524 | ||
573 | if (abs_p) { | 525 | for (i = 0; i < n; i++) |
574 | input_report_abs(input, ABS_X, abs_x); | 526 | report_finger_data(input, dev->slots[i], |
575 | input_report_abs(input, ABS_Y, abs_y); | 527 | &dev->pos[i], dev->index[i]); |
576 | 528 | ||
577 | dprintk(8, | 529 | input_mt_sync_frame(input); |
578 | "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " | ||
579 | "nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w, | ||
580 | abs_x, abs_y, nmin, nmax, dev->fingers, ibt); | ||
581 | 530 | ||
582 | } | 531 | report_synaptics_data(input, c, f, raw_n); |
583 | 532 | ||
584 | /* type 2 reports button events via ibt only */ | 533 | /* type 2 reports button events via ibt only */ |
585 | if (c->tp_type == TYPE2) | 534 | if (c->tp_type == TYPE2) { |
535 | int ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
586 | input_report_key(input, BTN_LEFT, ibt); | 536 | input_report_key(input, BTN_LEFT, ibt); |
537 | } | ||
587 | 538 | ||
588 | input_sync(input); | 539 | input_sync(input); |
589 | 540 | ||
@@ -742,9 +693,11 @@ static int bcm5974_start_traffic(struct bcm5974 *dev) | |||
742 | goto err_out; | 693 | goto err_out; |
743 | } | 694 | } |
744 | 695 | ||
745 | error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); | 696 | if (dev->bt_urb) { |
746 | if (error) | 697 | error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); |
747 | goto err_reset_mode; | 698 | if (error) |
699 | goto err_reset_mode; | ||
700 | } | ||
748 | 701 | ||
749 | error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); | 702 | error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); |
750 | if (error) | 703 | if (error) |
@@ -868,19 +821,23 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
868 | mutex_init(&dev->pm_mutex); | 821 | mutex_init(&dev->pm_mutex); |
869 | 822 | ||
870 | /* setup urbs */ | 823 | /* setup urbs */ |
871 | dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); | 824 | if (cfg->tp_type == TYPE1) { |
872 | if (!dev->bt_urb) | 825 | dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); |
873 | goto err_free_devs; | 826 | if (!dev->bt_urb) |
827 | goto err_free_devs; | ||
828 | } | ||
874 | 829 | ||
875 | dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); | 830 | dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); |
876 | if (!dev->tp_urb) | 831 | if (!dev->tp_urb) |
877 | goto err_free_bt_urb; | 832 | goto err_free_bt_urb; |
878 | 833 | ||
879 | dev->bt_data = usb_alloc_coherent(dev->udev, | 834 | if (dev->bt_urb) { |
835 | dev->bt_data = usb_alloc_coherent(dev->udev, | ||
880 | dev->cfg.bt_datalen, GFP_KERNEL, | 836 | dev->cfg.bt_datalen, GFP_KERNEL, |
881 | &dev->bt_urb->transfer_dma); | 837 | &dev->bt_urb->transfer_dma); |
882 | if (!dev->bt_data) | 838 | if (!dev->bt_data) |
883 | goto err_free_urb; | 839 | goto err_free_urb; |
840 | } | ||
884 | 841 | ||
885 | dev->tp_data = usb_alloc_coherent(dev->udev, | 842 | dev->tp_data = usb_alloc_coherent(dev->udev, |
886 | dev->cfg.tp_datalen, GFP_KERNEL, | 843 | dev->cfg.tp_datalen, GFP_KERNEL, |
@@ -888,10 +845,11 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
888 | if (!dev->tp_data) | 845 | if (!dev->tp_data) |
889 | goto err_free_bt_buffer; | 846 | goto err_free_bt_buffer; |
890 | 847 | ||
891 | usb_fill_int_urb(dev->bt_urb, udev, | 848 | if (dev->bt_urb) |
892 | usb_rcvintpipe(udev, cfg->bt_ep), | 849 | usb_fill_int_urb(dev->bt_urb, udev, |
893 | dev->bt_data, dev->cfg.bt_datalen, | 850 | usb_rcvintpipe(udev, cfg->bt_ep), |
894 | bcm5974_irq_button, dev, 1); | 851 | dev->bt_data, dev->cfg.bt_datalen, |
852 | bcm5974_irq_button, dev, 1); | ||
895 | 853 | ||
896 | usb_fill_int_urb(dev->tp_urb, udev, | 854 | usb_fill_int_urb(dev->tp_urb, udev, |
897 | usb_rcvintpipe(udev, cfg->tp_ep), | 855 | usb_rcvintpipe(udev, cfg->tp_ep), |
@@ -929,8 +887,9 @@ err_free_buffer: | |||
929 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, | 887 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
930 | dev->tp_data, dev->tp_urb->transfer_dma); | 888 | dev->tp_data, dev->tp_urb->transfer_dma); |
931 | err_free_bt_buffer: | 889 | err_free_bt_buffer: |
932 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, | 890 | if (dev->bt_urb) |
933 | dev->bt_data, dev->bt_urb->transfer_dma); | 891 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
892 | dev->bt_data, dev->bt_urb->transfer_dma); | ||
934 | err_free_urb: | 893 | err_free_urb: |
935 | usb_free_urb(dev->tp_urb); | 894 | usb_free_urb(dev->tp_urb); |
936 | err_free_bt_urb: | 895 | err_free_bt_urb: |
@@ -951,8 +910,9 @@ static void bcm5974_disconnect(struct usb_interface *iface) | |||
951 | input_unregister_device(dev->input); | 910 | input_unregister_device(dev->input); |
952 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, | 911 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
953 | dev->tp_data, dev->tp_urb->transfer_dma); | 912 | dev->tp_data, dev->tp_urb->transfer_dma); |
954 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, | 913 | if (dev->bt_urb) |
955 | dev->bt_data, dev->bt_urb->transfer_dma); | 914 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
915 | dev->bt_data, dev->bt_urb->transfer_dma); | ||
956 | usb_free_urb(dev->tp_urb); | 916 | usb_free_urb(dev->tp_urb); |
957 | usb_free_urb(dev->bt_urb); | 917 | usb_free_urb(dev->bt_urb); |
958 | kfree(dev); | 918 | kfree(dev); |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 479011004a11..1e8e42fb03a4 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -1004,7 +1004,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
1004 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | 1004 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, |
1005 | ETP_WMAX_V2, 0, 0); | 1005 | ETP_WMAX_V2, 0, 0); |
1006 | } | 1006 | } |
1007 | input_mt_init_slots(dev, 2); | 1007 | input_mt_init_slots(dev, 2, 0); |
1008 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); | 1008 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); |
1009 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); | 1009 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); |
1010 | break; | 1010 | break; |
@@ -1035,7 +1035,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
1035 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | 1035 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, |
1036 | ETP_WMAX_V2, 0, 0); | 1036 | ETP_WMAX_V2, 0, 0); |
1037 | /* Multitouch capable pad, up to 5 fingers. */ | 1037 | /* Multitouch capable pad, up to 5 fingers. */ |
1038 | input_mt_init_slots(dev, ETP_MAX_FINGERS); | 1038 | input_mt_init_slots(dev, ETP_MAX_FINGERS, 0); |
1039 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); | 1039 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); |
1040 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); | 1040 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); |
1041 | input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); | 1041 | input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index a261d8576919..e582922bacf7 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -971,7 +971,7 @@ static int fsp_set_input_params(struct psmouse *psmouse) | |||
971 | 971 | ||
972 | input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0); | 972 | input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0); |
973 | input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0); | 973 | input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0); |
974 | input_mt_init_slots(dev, 2); | 974 | input_mt_init_slots(dev, 2, 0); |
975 | input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0); | 975 | input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0); |
976 | input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0); | 976 | input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0); |
977 | } | 977 | } |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 0786919c15cd..12d12ca3fee0 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -1247,7 +1247,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
1247 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 1247 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
1248 | 1248 | ||
1249 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | 1249 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { |
1250 | input_mt_init_slots(dev, 2); | 1250 | input_mt_init_slots(dev, 2, 0); |
1251 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1251 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1252 | ABS_MT_POSITION_Y); | 1252 | ABS_MT_POSITION_Y); |
1253 | /* Image sensors can report per-contact pressure */ | 1253 | /* Image sensors can report per-contact pressure */ |
@@ -1259,7 +1259,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
1259 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | 1259 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
1260 | /* Non-image sensors with AGM use semi-mt */ | 1260 | /* Non-image sensors with AGM use semi-mt */ |
1261 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 1261 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
1262 | input_mt_init_slots(dev, 2); | 1262 | input_mt_init_slots(dev, 2, 0); |
1263 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1263 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1264 | ABS_MT_POSITION_Y); | 1264 | ABS_MT_POSITION_Y); |
1265 | } | 1265 | } |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 964e43d81e29..a1b4c37956b2 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -24,10 +24,8 @@ | |||
24 | #include <linux/random.h> | 24 | #include <linux/random.h> |
25 | #include <linux/major.h> | 25 | #include <linux/major.h> |
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/cdev.h> | ||
27 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
28 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | ||
29 | #include <linux/miscdevice.h> | ||
30 | #endif | ||
31 | 29 | ||
32 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 30 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
33 | MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces"); | 31 | MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces"); |
@@ -61,17 +59,18 @@ struct mousedev_hw_data { | |||
61 | 59 | ||
62 | struct mousedev { | 60 | struct mousedev { |
63 | int open; | 61 | int open; |
64 | int minor; | ||
65 | struct input_handle handle; | 62 | struct input_handle handle; |
66 | wait_queue_head_t wait; | 63 | wait_queue_head_t wait; |
67 | struct list_head client_list; | 64 | struct list_head client_list; |
68 | spinlock_t client_lock; /* protects client_list */ | 65 | spinlock_t client_lock; /* protects client_list */ |
69 | struct mutex mutex; | 66 | struct mutex mutex; |
70 | struct device dev; | 67 | struct device dev; |
68 | struct cdev cdev; | ||
71 | bool exist; | 69 | bool exist; |
70 | bool is_mixdev; | ||
72 | 71 | ||
73 | struct list_head mixdev_node; | 72 | struct list_head mixdev_node; |
74 | int mixdev_open; | 73 | bool opened_by_mixdev; |
75 | 74 | ||
76 | struct mousedev_hw_data packet; | 75 | struct mousedev_hw_data packet; |
77 | unsigned int pkt_count; | 76 | unsigned int pkt_count; |
@@ -114,10 +113,6 @@ struct mousedev_client { | |||
114 | static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 }; | 113 | static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 }; |
115 | static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; | 114 | static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; |
116 | 115 | ||
117 | static struct input_handler mousedev_handler; | ||
118 | |||
119 | static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; | ||
120 | static DEFINE_MUTEX(mousedev_table_mutex); | ||
121 | static struct mousedev *mousedev_mix; | 116 | static struct mousedev *mousedev_mix; |
122 | static LIST_HEAD(mousedev_mix_list); | 117 | static LIST_HEAD(mousedev_mix_list); |
123 | 118 | ||
@@ -433,7 +428,7 @@ static int mousedev_open_device(struct mousedev *mousedev) | |||
433 | if (retval) | 428 | if (retval) |
434 | return retval; | 429 | return retval; |
435 | 430 | ||
436 | if (mousedev->minor == MOUSEDEV_MIX) | 431 | if (mousedev->is_mixdev) |
437 | mixdev_open_devices(); | 432 | mixdev_open_devices(); |
438 | else if (!mousedev->exist) | 433 | else if (!mousedev->exist) |
439 | retval = -ENODEV; | 434 | retval = -ENODEV; |
@@ -451,7 +446,7 @@ static void mousedev_close_device(struct mousedev *mousedev) | |||
451 | { | 446 | { |
452 | mutex_lock(&mousedev->mutex); | 447 | mutex_lock(&mousedev->mutex); |
453 | 448 | ||
454 | if (mousedev->minor == MOUSEDEV_MIX) | 449 | if (mousedev->is_mixdev) |
455 | mixdev_close_devices(); | 450 | mixdev_close_devices(); |
456 | else if (mousedev->exist && !--mousedev->open) | 451 | else if (mousedev->exist && !--mousedev->open) |
457 | input_close_device(&mousedev->handle); | 452 | input_close_device(&mousedev->handle); |
@@ -472,11 +467,11 @@ static void mixdev_open_devices(void) | |||
472 | return; | 467 | return; |
473 | 468 | ||
474 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { | 469 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { |
475 | if (!mousedev->mixdev_open) { | 470 | if (!mousedev->opened_by_mixdev) { |
476 | if (mousedev_open_device(mousedev)) | 471 | if (mousedev_open_device(mousedev)) |
477 | continue; | 472 | continue; |
478 | 473 | ||
479 | mousedev->mixdev_open = 1; | 474 | mousedev->opened_by_mixdev = true; |
480 | } | 475 | } |
481 | } | 476 | } |
482 | } | 477 | } |
@@ -494,8 +489,8 @@ static void mixdev_close_devices(void) | |||
494 | return; | 489 | return; |
495 | 490 | ||
496 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { | 491 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { |
497 | if (mousedev->mixdev_open) { | 492 | if (mousedev->opened_by_mixdev) { |
498 | mousedev->mixdev_open = 0; | 493 | mousedev->opened_by_mixdev = false; |
499 | mousedev_close_device(mousedev); | 494 | mousedev_close_device(mousedev); |
500 | } | 495 | } |
501 | } | 496 | } |
@@ -538,35 +533,17 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
538 | struct mousedev_client *client; | 533 | struct mousedev_client *client; |
539 | struct mousedev *mousedev; | 534 | struct mousedev *mousedev; |
540 | int error; | 535 | int error; |
541 | int i; | ||
542 | 536 | ||
543 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 537 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
544 | if (imajor(inode) == MISC_MAJOR) | 538 | if (imajor(inode) == MISC_MAJOR) |
545 | i = MOUSEDEV_MIX; | 539 | mousedev = mousedev_mix; |
546 | else | 540 | else |
547 | #endif | 541 | #endif |
548 | i = iminor(inode) - MOUSEDEV_MINOR_BASE; | 542 | mousedev = container_of(inode->i_cdev, struct mousedev, cdev); |
549 | |||
550 | if (i >= MOUSEDEV_MINORS) | ||
551 | return -ENODEV; | ||
552 | |||
553 | error = mutex_lock_interruptible(&mousedev_table_mutex); | ||
554 | if (error) | ||
555 | return error; | ||
556 | |||
557 | mousedev = mousedev_table[i]; | ||
558 | if (mousedev) | ||
559 | get_device(&mousedev->dev); | ||
560 | mutex_unlock(&mousedev_table_mutex); | ||
561 | |||
562 | if (!mousedev) | ||
563 | return -ENODEV; | ||
564 | 543 | ||
565 | client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); | 544 | client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); |
566 | if (!client) { | 545 | if (!client) |
567 | error = -ENOMEM; | 546 | return -ENOMEM; |
568 | goto err_put_mousedev; | ||
569 | } | ||
570 | 547 | ||
571 | spin_lock_init(&client->packet_lock); | 548 | spin_lock_init(&client->packet_lock); |
572 | client->pos_x = xres / 2; | 549 | client->pos_x = xres / 2; |
@@ -579,13 +556,14 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
579 | goto err_free_client; | 556 | goto err_free_client; |
580 | 557 | ||
581 | file->private_data = client; | 558 | file->private_data = client; |
559 | nonseekable_open(inode, file); | ||
560 | |||
561 | get_device(&mousedev->dev); | ||
582 | return 0; | 562 | return 0; |
583 | 563 | ||
584 | err_free_client: | 564 | err_free_client: |
585 | mousedev_detach_client(mousedev, client); | 565 | mousedev_detach_client(mousedev, client); |
586 | kfree(client); | 566 | kfree(client); |
587 | err_put_mousedev: | ||
588 | put_device(&mousedev->dev); | ||
589 | return error; | 567 | return error; |
590 | } | 568 | } |
591 | 569 | ||
@@ -785,29 +763,16 @@ static unsigned int mousedev_poll(struct file *file, poll_table *wait) | |||
785 | } | 763 | } |
786 | 764 | ||
787 | static const struct file_operations mousedev_fops = { | 765 | static const struct file_operations mousedev_fops = { |
788 | .owner = THIS_MODULE, | 766 | .owner = THIS_MODULE, |
789 | .read = mousedev_read, | 767 | .read = mousedev_read, |
790 | .write = mousedev_write, | 768 | .write = mousedev_write, |
791 | .poll = mousedev_poll, | 769 | .poll = mousedev_poll, |
792 | .open = mousedev_open, | 770 | .open = mousedev_open, |
793 | .release = mousedev_release, | 771 | .release = mousedev_release, |
794 | .fasync = mousedev_fasync, | 772 | .fasync = mousedev_fasync, |
795 | .llseek = noop_llseek, | 773 | .llseek = noop_llseek, |
796 | }; | 774 | }; |
797 | 775 | ||
798 | static int mousedev_install_chrdev(struct mousedev *mousedev) | ||
799 | { | ||
800 | mousedev_table[mousedev->minor] = mousedev; | ||
801 | return 0; | ||
802 | } | ||
803 | |||
804 | static void mousedev_remove_chrdev(struct mousedev *mousedev) | ||
805 | { | ||
806 | mutex_lock(&mousedev_table_mutex); | ||
807 | mousedev_table[mousedev->minor] = NULL; | ||
808 | mutex_unlock(&mousedev_table_mutex); | ||
809 | } | ||
810 | |||
811 | /* | 776 | /* |
812 | * Mark device non-existent. This disables writes, ioctls and | 777 | * Mark device non-existent. This disables writes, ioctls and |
813 | * prevents new users from opening the device. Already posted | 778 | * prevents new users from opening the device. Already posted |
@@ -842,24 +807,50 @@ static void mousedev_cleanup(struct mousedev *mousedev) | |||
842 | 807 | ||
843 | mousedev_mark_dead(mousedev); | 808 | mousedev_mark_dead(mousedev); |
844 | mousedev_hangup(mousedev); | 809 | mousedev_hangup(mousedev); |
845 | mousedev_remove_chrdev(mousedev); | 810 | |
811 | cdev_del(&mousedev->cdev); | ||
846 | 812 | ||
847 | /* mousedev is marked dead so no one else accesses mousedev->open */ | 813 | /* mousedev is marked dead so no one else accesses mousedev->open */ |
848 | if (mousedev->open) | 814 | if (mousedev->open) |
849 | input_close_device(handle); | 815 | input_close_device(handle); |
850 | } | 816 | } |
851 | 817 | ||
818 | static int mousedev_reserve_minor(bool mixdev) | ||
819 | { | ||
820 | int minor; | ||
821 | |||
822 | if (mixdev) { | ||
823 | minor = input_get_new_minor(MOUSEDEV_MIX, 1, false); | ||
824 | if (minor < 0) | ||
825 | pr_err("failed to reserve mixdev minor: %d\n", minor); | ||
826 | } else { | ||
827 | minor = input_get_new_minor(MOUSEDEV_MINOR_BASE, | ||
828 | MOUSEDEV_MINORS, true); | ||
829 | if (minor < 0) | ||
830 | pr_err("failed to reserve new minor: %d\n", minor); | ||
831 | } | ||
832 | |||
833 | return minor; | ||
834 | } | ||
835 | |||
852 | static struct mousedev *mousedev_create(struct input_dev *dev, | 836 | static struct mousedev *mousedev_create(struct input_dev *dev, |
853 | struct input_handler *handler, | 837 | struct input_handler *handler, |
854 | int minor) | 838 | bool mixdev) |
855 | { | 839 | { |
856 | struct mousedev *mousedev; | 840 | struct mousedev *mousedev; |
841 | int minor; | ||
857 | int error; | 842 | int error; |
858 | 843 | ||
844 | minor = mousedev_reserve_minor(mixdev); | ||
845 | if (minor < 0) { | ||
846 | error = minor; | ||
847 | goto err_out; | ||
848 | } | ||
849 | |||
859 | mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); | 850 | mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); |
860 | if (!mousedev) { | 851 | if (!mousedev) { |
861 | error = -ENOMEM; | 852 | error = -ENOMEM; |
862 | goto err_out; | 853 | goto err_free_minor; |
863 | } | 854 | } |
864 | 855 | ||
865 | INIT_LIST_HEAD(&mousedev->client_list); | 856 | INIT_LIST_HEAD(&mousedev->client_list); |
@@ -867,16 +858,21 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
867 | spin_lock_init(&mousedev->client_lock); | 858 | spin_lock_init(&mousedev->client_lock); |
868 | mutex_init(&mousedev->mutex); | 859 | mutex_init(&mousedev->mutex); |
869 | lockdep_set_subclass(&mousedev->mutex, | 860 | lockdep_set_subclass(&mousedev->mutex, |
870 | minor == MOUSEDEV_MIX ? SINGLE_DEPTH_NESTING : 0); | 861 | mixdev ? SINGLE_DEPTH_NESTING : 0); |
871 | init_waitqueue_head(&mousedev->wait); | 862 | init_waitqueue_head(&mousedev->wait); |
872 | 863 | ||
873 | if (minor == MOUSEDEV_MIX) | 864 | if (mixdev) { |
874 | dev_set_name(&mousedev->dev, "mice"); | 865 | dev_set_name(&mousedev->dev, "mice"); |
875 | else | 866 | } else { |
876 | dev_set_name(&mousedev->dev, "mouse%d", minor); | 867 | int dev_no = minor; |
868 | /* Normalize device number if it falls into legacy range */ | ||
869 | if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS) | ||
870 | dev_no -= MOUSEDEV_MINOR_BASE; | ||
871 | dev_set_name(&mousedev->dev, "mouse%d", dev_no); | ||
872 | } | ||
877 | 873 | ||
878 | mousedev->minor = minor; | ||
879 | mousedev->exist = true; | 874 | mousedev->exist = true; |
875 | mousedev->is_mixdev = mixdev; | ||
880 | mousedev->handle.dev = input_get_device(dev); | 876 | mousedev->handle.dev = input_get_device(dev); |
881 | mousedev->handle.name = dev_name(&mousedev->dev); | 877 | mousedev->handle.name = dev_name(&mousedev->dev); |
882 | mousedev->handle.handler = handler; | 878 | mousedev->handle.handler = handler; |
@@ -885,17 +881,18 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
885 | mousedev->dev.class = &input_class; | 881 | mousedev->dev.class = &input_class; |
886 | if (dev) | 882 | if (dev) |
887 | mousedev->dev.parent = &dev->dev; | 883 | mousedev->dev.parent = &dev->dev; |
888 | mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor); | 884 | mousedev->dev.devt = MKDEV(INPUT_MAJOR, minor); |
889 | mousedev->dev.release = mousedev_free; | 885 | mousedev->dev.release = mousedev_free; |
890 | device_initialize(&mousedev->dev); | 886 | device_initialize(&mousedev->dev); |
891 | 887 | ||
892 | if (minor != MOUSEDEV_MIX) { | 888 | if (!mixdev) { |
893 | error = input_register_handle(&mousedev->handle); | 889 | error = input_register_handle(&mousedev->handle); |
894 | if (error) | 890 | if (error) |
895 | goto err_free_mousedev; | 891 | goto err_free_mousedev; |
896 | } | 892 | } |
897 | 893 | ||
898 | error = mousedev_install_chrdev(mousedev); | 894 | cdev_init(&mousedev->cdev, &mousedev_fops); |
895 | error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1); | ||
899 | if (error) | 896 | if (error) |
900 | goto err_unregister_handle; | 897 | goto err_unregister_handle; |
901 | 898 | ||
@@ -908,10 +905,12 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
908 | err_cleanup_mousedev: | 905 | err_cleanup_mousedev: |
909 | mousedev_cleanup(mousedev); | 906 | mousedev_cleanup(mousedev); |
910 | err_unregister_handle: | 907 | err_unregister_handle: |
911 | if (minor != MOUSEDEV_MIX) | 908 | if (!mixdev) |
912 | input_unregister_handle(&mousedev->handle); | 909 | input_unregister_handle(&mousedev->handle); |
913 | err_free_mousedev: | 910 | err_free_mousedev: |
914 | put_device(&mousedev->dev); | 911 | put_device(&mousedev->dev); |
912 | err_free_minor: | ||
913 | input_free_minor(minor); | ||
915 | err_out: | 914 | err_out: |
916 | return ERR_PTR(error); | 915 | return ERR_PTR(error); |
917 | } | 916 | } |
@@ -920,7 +919,8 @@ static void mousedev_destroy(struct mousedev *mousedev) | |||
920 | { | 919 | { |
921 | device_del(&mousedev->dev); | 920 | device_del(&mousedev->dev); |
922 | mousedev_cleanup(mousedev); | 921 | mousedev_cleanup(mousedev); |
923 | if (mousedev->minor != MOUSEDEV_MIX) | 922 | input_free_minor(MINOR(mousedev->dev.devt)); |
923 | if (!mousedev->is_mixdev) | ||
924 | input_unregister_handle(&mousedev->handle); | 924 | input_unregister_handle(&mousedev->handle); |
925 | put_device(&mousedev->dev); | 925 | put_device(&mousedev->dev); |
926 | } | 926 | } |
@@ -938,7 +938,7 @@ static int mixdev_add_device(struct mousedev *mousedev) | |||
938 | if (retval) | 938 | if (retval) |
939 | goto out; | 939 | goto out; |
940 | 940 | ||
941 | mousedev->mixdev_open = 1; | 941 | mousedev->opened_by_mixdev = true; |
942 | } | 942 | } |
943 | 943 | ||
944 | get_device(&mousedev->dev); | 944 | get_device(&mousedev->dev); |
@@ -953,8 +953,8 @@ static void mixdev_remove_device(struct mousedev *mousedev) | |||
953 | { | 953 | { |
954 | mutex_lock(&mousedev_mix->mutex); | 954 | mutex_lock(&mousedev_mix->mutex); |
955 | 955 | ||
956 | if (mousedev->mixdev_open) { | 956 | if (mousedev->opened_by_mixdev) { |
957 | mousedev->mixdev_open = 0; | 957 | mousedev->opened_by_mixdev = false; |
958 | mousedev_close_device(mousedev); | 958 | mousedev_close_device(mousedev); |
959 | } | 959 | } |
960 | 960 | ||
@@ -969,19 +969,9 @@ static int mousedev_connect(struct input_handler *handler, | |||
969 | const struct input_device_id *id) | 969 | const struct input_device_id *id) |
970 | { | 970 | { |
971 | struct mousedev *mousedev; | 971 | struct mousedev *mousedev; |
972 | int minor; | ||
973 | int error; | 972 | int error; |
974 | 973 | ||
975 | for (minor = 0; minor < MOUSEDEV_MINORS; minor++) | 974 | mousedev = mousedev_create(dev, handler, false); |
976 | if (!mousedev_table[minor]) | ||
977 | break; | ||
978 | |||
979 | if (minor == MOUSEDEV_MINORS) { | ||
980 | pr_err("no more free mousedev devices\n"); | ||
981 | return -ENFILE; | ||
982 | } | ||
983 | |||
984 | mousedev = mousedev_create(dev, handler, minor); | ||
985 | if (IS_ERR(mousedev)) | 975 | if (IS_ERR(mousedev)) |
986 | return PTR_ERR(mousedev); | 976 | return PTR_ERR(mousedev); |
987 | 977 | ||
@@ -1054,27 +1044,53 @@ static const struct input_device_id mousedev_ids[] = { | |||
1054 | MODULE_DEVICE_TABLE(input, mousedev_ids); | 1044 | MODULE_DEVICE_TABLE(input, mousedev_ids); |
1055 | 1045 | ||
1056 | static struct input_handler mousedev_handler = { | 1046 | static struct input_handler mousedev_handler = { |
1057 | .event = mousedev_event, | 1047 | .event = mousedev_event, |
1058 | .connect = mousedev_connect, | 1048 | .connect = mousedev_connect, |
1059 | .disconnect = mousedev_disconnect, | 1049 | .disconnect = mousedev_disconnect, |
1060 | .fops = &mousedev_fops, | 1050 | .legacy_minors = true, |
1061 | .minor = MOUSEDEV_MINOR_BASE, | 1051 | .minor = MOUSEDEV_MINOR_BASE, |
1062 | .name = "mousedev", | 1052 | .name = "mousedev", |
1063 | .id_table = mousedev_ids, | 1053 | .id_table = mousedev_ids, |
1064 | }; | 1054 | }; |
1065 | 1055 | ||
1066 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 1056 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
1057 | #include <linux/miscdevice.h> | ||
1058 | |||
1067 | static struct miscdevice psaux_mouse = { | 1059 | static struct miscdevice psaux_mouse = { |
1068 | PSMOUSE_MINOR, "psaux", &mousedev_fops | 1060 | .minor = PSMOUSE_MINOR, |
1061 | .name = "psaux", | ||
1062 | .fops = &mousedev_fops, | ||
1069 | }; | 1063 | }; |
1070 | static int psaux_registered; | 1064 | |
1065 | static bool psaux_registered; | ||
1066 | |||
1067 | static void __init mousedev_psaux_register(void) | ||
1068 | { | ||
1069 | int error; | ||
1070 | |||
1071 | error = misc_register(&psaux_mouse); | ||
1072 | if (error) | ||
1073 | pr_warn("could not register psaux device, error: %d\n", | ||
1074 | error); | ||
1075 | else | ||
1076 | psaux_registered = true; | ||
1077 | } | ||
1078 | |||
1079 | static void __exit mousedev_psaux_unregister(void) | ||
1080 | { | ||
1081 | if (psaux_registered) | ||
1082 | misc_deregister(&psaux_mouse); | ||
1083 | } | ||
1084 | #else | ||
1085 | static inline void mousedev_psaux_register(void) { } | ||
1086 | static inline void mousedev_psaux_unregister(void) { } | ||
1071 | #endif | 1087 | #endif |
1072 | 1088 | ||
1073 | static int __init mousedev_init(void) | 1089 | static int __init mousedev_init(void) |
1074 | { | 1090 | { |
1075 | int error; | 1091 | int error; |
1076 | 1092 | ||
1077 | mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX); | 1093 | mousedev_mix = mousedev_create(NULL, &mousedev_handler, true); |
1078 | if (IS_ERR(mousedev_mix)) | 1094 | if (IS_ERR(mousedev_mix)) |
1079 | return PTR_ERR(mousedev_mix); | 1095 | return PTR_ERR(mousedev_mix); |
1080 | 1096 | ||
@@ -1084,14 +1100,7 @@ static int __init mousedev_init(void) | |||
1084 | return error; | 1100 | return error; |
1085 | } | 1101 | } |
1086 | 1102 | ||
1087 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 1103 | mousedev_psaux_register(); |
1088 | error = misc_register(&psaux_mouse); | ||
1089 | if (error) | ||
1090 | pr_warn("could not register psaux device, error: %d\n", | ||
1091 | error); | ||
1092 | else | ||
1093 | psaux_registered = 1; | ||
1094 | #endif | ||
1095 | 1104 | ||
1096 | pr_info("PS/2 mouse device common for all mice\n"); | 1105 | pr_info("PS/2 mouse device common for all mice\n"); |
1097 | 1106 | ||
@@ -1100,10 +1109,7 @@ static int __init mousedev_init(void) | |||
1100 | 1109 | ||
1101 | static void __exit mousedev_exit(void) | 1110 | static void __exit mousedev_exit(void) |
1102 | { | 1111 | { |
1103 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 1112 | mousedev_psaux_unregister(); |
1104 | if (psaux_registered) | ||
1105 | misc_deregister(&psaux_mouse); | ||
1106 | #endif | ||
1107 | input_unregister_handler(&mousedev_handler); | 1113 | input_unregister_handler(&mousedev_handler); |
1108 | mousedev_destroy(mousedev_mix); | 1114 | mousedev_destroy(mousedev_mix); |
1109 | } | 1115 | } |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 0d3219f29744..9edf9806cff9 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -172,6 +172,76 @@ static void wacom_close(struct input_dev *dev) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | /* | 174 | /* |
175 | * Calculate the resolution of the X or Y axis, given appropriate HID data. | ||
176 | * This function is little more than hidinput_calc_abs_res stripped down. | ||
177 | */ | ||
178 | static int wacom_calc_hid_res(int logical_extents, int physical_extents, | ||
179 | unsigned char unit, unsigned char exponent) | ||
180 | { | ||
181 | int prev, unit_exponent; | ||
182 | |||
183 | /* Check if the extents are sane */ | ||
184 | if (logical_extents <= 0 || physical_extents <= 0) | ||
185 | return 0; | ||
186 | |||
187 | /* Get signed value of nybble-sized twos-compliment exponent */ | ||
188 | unit_exponent = exponent; | ||
189 | if (unit_exponent > 7) | ||
190 | unit_exponent -= 16; | ||
191 | |||
192 | /* Convert physical_extents to millimeters */ | ||
193 | if (unit == 0x11) { /* If centimeters */ | ||
194 | unit_exponent += 1; | ||
195 | } else if (unit == 0x13) { /* If inches */ | ||
196 | prev = physical_extents; | ||
197 | physical_extents *= 254; | ||
198 | if (physical_extents < prev) | ||
199 | return 0; | ||
200 | unit_exponent -= 1; | ||
201 | } else { | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | /* Apply negative unit exponent */ | ||
206 | for (; unit_exponent < 0; unit_exponent++) { | ||
207 | prev = logical_extents; | ||
208 | logical_extents *= 10; | ||
209 | if (logical_extents < prev) | ||
210 | return 0; | ||
211 | } | ||
212 | /* Apply positive unit exponent */ | ||
213 | for (; unit_exponent > 0; unit_exponent--) { | ||
214 | prev = physical_extents; | ||
215 | physical_extents *= 10; | ||
216 | if (physical_extents < prev) | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | /* Calculate resolution */ | ||
221 | return logical_extents / physical_extents; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * The physical dimension specified by the HID descriptor is likely not in | ||
226 | * the "100th of a mm" units expected by wacom_calculate_touch_res. This | ||
227 | * function adjusts the value of [xy]_phy based on the unit and exponent | ||
228 | * provided by the HID descriptor. If an error occurs durring conversion | ||
229 | * (e.g. from the unit being left unspecified) [xy]_phy is not modified. | ||
230 | */ | ||
231 | static void wacom_fix_phy_from_hid(struct wacom_features *features) | ||
232 | { | ||
233 | int xres = wacom_calc_hid_res(features->x_max, features->x_phy, | ||
234 | features->unit, features->unitExpo); | ||
235 | int yres = wacom_calc_hid_res(features->y_max, features->y_phy, | ||
236 | features->unit, features->unitExpo); | ||
237 | |||
238 | if (xres > 0 && yres > 0) { | ||
239 | features->x_phy = (100 * features->x_max) / xres; | ||
240 | features->y_phy = (100 * features->y_max) / yres; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | /* | ||
175 | * Static values for max X/Y and resolution of Pen interface is stored in | 245 | * Static values for max X/Y and resolution of Pen interface is stored in |
176 | * features. This mean physical size of active area can be computed. | 246 | * features. This mean physical size of active area can be computed. |
177 | * This is useful to do when Pen and Touch have same active area of tablet. | 247 | * This is useful to do when Pen and Touch have same active area of tablet. |
@@ -432,56 +502,52 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
432 | return result; | 502 | return result; |
433 | } | 503 | } |
434 | 504 | ||
435 | static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features) | 505 | static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int length, int mode) |
436 | { | 506 | { |
437 | unsigned char *rep_data; | 507 | unsigned char *rep_data; |
438 | int limit = 0, report_id = 2; | 508 | int error = -ENOMEM, limit = 0; |
439 | int error = -ENOMEM; | ||
440 | 509 | ||
441 | rep_data = kmalloc(4, GFP_KERNEL); | 510 | rep_data = kzalloc(length, GFP_KERNEL); |
442 | if (!rep_data) | 511 | if (!rep_data) |
443 | return error; | 512 | return error; |
444 | 513 | ||
445 | /* ask to report Wacom data */ | 514 | rep_data[0] = report_id; |
515 | rep_data[1] = mode; | ||
516 | |||
517 | do { | ||
518 | error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, | ||
519 | report_id, rep_data, length, 1); | ||
520 | if (error >= 0) | ||
521 | error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, | ||
522 | report_id, rep_data, length, 1); | ||
523 | } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); | ||
524 | |||
525 | kfree(rep_data); | ||
526 | |||
527 | return error < 0 ? error : 0; | ||
528 | } | ||
529 | |||
530 | /* | ||
531 | * Switch the tablet into its most-capable mode. Wacom tablets are | ||
532 | * typically configured to power-up in a mode which sends mouse-like | ||
533 | * reports to the OS. To get absolute position, pressure data, etc. | ||
534 | * from the tablet, it is necessary to switch the tablet out of this | ||
535 | * mode and into one which sends the full range of tablet data. | ||
536 | */ | ||
537 | static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features) | ||
538 | { | ||
446 | if (features->device_type == BTN_TOOL_FINGER) { | 539 | if (features->device_type == BTN_TOOL_FINGER) { |
447 | /* if it is an MT Tablet PC touch */ | ||
448 | if (features->type > TABLETPC) { | 540 | if (features->type > TABLETPC) { |
449 | do { | 541 | /* MT Tablet PC touch */ |
450 | rep_data[0] = 3; | 542 | return wacom_set_device_mode(intf, 3, 4, 4); |
451 | rep_data[1] = 4; | 543 | } |
452 | rep_data[2] = 0; | 544 | } else if (features->device_type == BTN_TOOL_PEN) { |
453 | rep_data[3] = 0; | 545 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { |
454 | report_id = 3; | 546 | return wacom_set_device_mode(intf, 2, 2, 2); |
455 | error = wacom_set_report(intf, | ||
456 | WAC_HID_FEATURE_REPORT, | ||
457 | report_id, | ||
458 | rep_data, 4, 1); | ||
459 | if (error >= 0) | ||
460 | error = wacom_get_report(intf, | ||
461 | WAC_HID_FEATURE_REPORT, | ||
462 | report_id, | ||
463 | rep_data, 4, 1); | ||
464 | } while ((error < 0 || rep_data[1] != 4) && | ||
465 | limit++ < WAC_MSG_RETRIES); | ||
466 | } | 547 | } |
467 | } else if (features->type <= BAMBOO_PT && | ||
468 | features->type != WIRELESS && | ||
469 | features->device_type == BTN_TOOL_PEN) { | ||
470 | do { | ||
471 | rep_data[0] = 2; | ||
472 | rep_data[1] = 2; | ||
473 | error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, | ||
474 | report_id, rep_data, 2, 1); | ||
475 | if (error >= 0) | ||
476 | error = wacom_get_report(intf, | ||
477 | WAC_HID_FEATURE_REPORT, | ||
478 | report_id, rep_data, 2, 1); | ||
479 | } while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES); | ||
480 | } | 548 | } |
481 | 549 | ||
482 | kfree(rep_data); | 550 | return 0; |
483 | |||
484 | return error < 0 ? error : 0; | ||
485 | } | 551 | } |
486 | 552 | ||
487 | static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | 553 | static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, |
@@ -531,6 +597,7 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
531 | error = wacom_parse_hid(intf, hid_desc, features); | 597 | error = wacom_parse_hid(intf, hid_desc, features); |
532 | if (error) | 598 | if (error) |
533 | goto out; | 599 | goto out; |
600 | wacom_fix_phy_from_hid(features); | ||
534 | 601 | ||
535 | out: | 602 | out: |
536 | return error; | 603 | return error; |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 93171098abbd..c3468c8dbd89 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -25,6 +25,11 @@ | |||
25 | #define WACOM_INTUOS_RES 100 | 25 | #define WACOM_INTUOS_RES 100 |
26 | #define WACOM_INTUOS3_RES 200 | 26 | #define WACOM_INTUOS3_RES 200 |
27 | 27 | ||
28 | /* Scale factor relating reported contact size to logical contact area. | ||
29 | * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo | ||
30 | */ | ||
31 | #define WACOM_CONTACT_AREA_SCALE 2607 | ||
32 | |||
28 | static int wacom_penpartner_irq(struct wacom_wac *wacom) | 33 | static int wacom_penpartner_irq(struct wacom_wac *wacom) |
29 | { | 34 | { |
30 | unsigned char *data = wacom->data; | 35 | unsigned char *data = wacom->data; |
@@ -326,7 +331,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
326 | 331 | ||
327 | /* Enter report */ | 332 | /* Enter report */ |
328 | if ((data[1] & 0xfc) == 0xc0) { | 333 | if ((data[1] & 0xfc) == 0xc0) { |
329 | if (features->type >= INTUOS5S && features->type <= INTUOS5L) | 334 | if (features->quirks == WACOM_QUIRK_MULTI_INPUT) |
330 | wacom->shared->stylus_in_proximity = true; | 335 | wacom->shared->stylus_in_proximity = true; |
331 | 336 | ||
332 | /* serial number of the tool */ | 337 | /* serial number of the tool */ |
@@ -414,7 +419,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
414 | 419 | ||
415 | /* Exit report */ | 420 | /* Exit report */ |
416 | if ((data[1] & 0xfe) == 0x80) { | 421 | if ((data[1] & 0xfe) == 0x80) { |
417 | if (features->type >= INTUOS5S && features->type <= INTUOS5L) | 422 | if (features->quirks == WACOM_QUIRK_MULTI_INPUT) |
418 | wacom->shared->stylus_in_proximity = false; | 423 | wacom->shared->stylus_in_proximity = false; |
419 | 424 | ||
420 | /* | 425 | /* |
@@ -1043,11 +1048,19 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) | |||
1043 | if (touch) { | 1048 | if (touch) { |
1044 | int x = (data[2] << 4) | (data[4] >> 4); | 1049 | int x = (data[2] << 4) | (data[4] >> 4); |
1045 | int y = (data[3] << 4) | (data[4] & 0x0f); | 1050 | int y = (data[3] << 4) | (data[4] & 0x0f); |
1046 | int w = data[6]; | 1051 | int a = data[5]; |
1052 | |||
1053 | // "a" is a scaled-down area which we assume is roughly | ||
1054 | // circular and which can be described as: a=(pi*r^2)/C. | ||
1055 | int x_res = input_abs_get_res(input, ABS_X); | ||
1056 | int y_res = input_abs_get_res(input, ABS_Y); | ||
1057 | int width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE); | ||
1058 | int height = width * y_res / x_res; | ||
1047 | 1059 | ||
1048 | input_report_abs(input, ABS_MT_POSITION_X, x); | 1060 | input_report_abs(input, ABS_MT_POSITION_X, x); |
1049 | input_report_abs(input, ABS_MT_POSITION_Y, y); | 1061 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
1050 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, w); | 1062 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, width); |
1063 | input_report_abs(input, ABS_MT_TOUCH_MINOR, height); | ||
1051 | } | 1064 | } |
1052 | } | 1065 | } |
1053 | 1066 | ||
@@ -1530,10 +1543,12 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1530 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 1543 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); |
1531 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | 1544 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); |
1532 | 1545 | ||
1533 | input_mt_init_slots(input_dev, features->touch_max); | 1546 | input_mt_init_slots(input_dev, features->touch_max, 0); |
1534 | 1547 | ||
1535 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 1548 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
1536 | 0, 255, 0, 0); | 1549 | 0, features->x_max, 0, 0); |
1550 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, | ||
1551 | 0, features->y_max, 0, 0); | ||
1537 | 1552 | ||
1538 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1553 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
1539 | 0, features->x_max, | 1554 | 0, features->x_max, |
@@ -1575,7 +1590,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1575 | 1590 | ||
1576 | case TABLETPC2FG: | 1591 | case TABLETPC2FG: |
1577 | if (features->device_type == BTN_TOOL_FINGER) { | 1592 | if (features->device_type == BTN_TOOL_FINGER) { |
1578 | input_mt_init_slots(input_dev, features->touch_max); | 1593 | input_mt_init_slots(input_dev, features->touch_max, 0); |
1579 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, | 1594 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, |
1580 | 0, MT_TOOL_MAX, 0, 0); | 1595 | 0, MT_TOOL_MAX, 0, 0); |
1581 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1596 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
@@ -1631,7 +1646,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1631 | 1646 | ||
1632 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 1647 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
1633 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | 1648 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); |
1634 | input_mt_init_slots(input_dev, features->touch_max); | 1649 | input_mt_init_slots(input_dev, features->touch_max, 0); |
1635 | 1650 | ||
1636 | if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { | 1651 | if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { |
1637 | __set_bit(BTN_TOOL_TRIPLETAP, | 1652 | __set_bit(BTN_TOOL_TRIPLETAP, |
@@ -1641,7 +1656,10 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1641 | 1656 | ||
1642 | input_set_abs_params(input_dev, | 1657 | input_set_abs_params(input_dev, |
1643 | ABS_MT_TOUCH_MAJOR, | 1658 | ABS_MT_TOUCH_MAJOR, |
1644 | 0, 255, 0, 0); | 1659 | 0, features->x_max, 0, 0); |
1660 | input_set_abs_params(input_dev, | ||
1661 | ABS_MT_TOUCH_MINOR, | ||
1662 | 0, features->y_max, 0, 0); | ||
1645 | } | 1663 | } |
1646 | 1664 | ||
1647 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1665 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 4623cc69fc60..1df2396af008 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -320,10 +320,8 @@ static bool mxt_object_writable(unsigned int type) | |||
320 | static void mxt_dump_message(struct device *dev, | 320 | static void mxt_dump_message(struct device *dev, |
321 | struct mxt_message *message) | 321 | struct mxt_message *message) |
322 | { | 322 | { |
323 | dev_dbg(dev, "reportid: %u\tmessage: %02x %02x %02x %02x %02x %02x %02x\n", | 323 | dev_dbg(dev, "reportid: %u\tmessage: %*ph\n", |
324 | message->reportid, message->message[0], message->message[1], | 324 | message->reportid, 7, message->message); |
325 | message->message[2], message->message[3], message->message[4], | ||
326 | message->message[5], message->message[6]); | ||
327 | } | 325 | } |
328 | 326 | ||
329 | static int mxt_check_bootloader(struct i2c_client *client, | 327 | static int mxt_check_bootloader(struct i2c_client *client, |
@@ -1152,7 +1150,7 @@ static int __devinit mxt_probe(struct i2c_client *client, | |||
1152 | 1150 | ||
1153 | /* For multi touch */ | 1151 | /* For multi touch */ |
1154 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; | 1152 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; |
1155 | error = input_mt_init_slots(input_dev, num_mt_slots); | 1153 | error = input_mt_init_slots(input_dev, num_mt_slots, 0); |
1156 | if (error) | 1154 | if (error) |
1157 | goto err_free_object; | 1155 | goto err_free_object; |
1158 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 1156 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c index f030d9ec795d..8e60437ac85b 100644 --- a/drivers/input/touchscreen/cyttsp_core.c +++ b/drivers/input/touchscreen/cyttsp_core.c | |||
@@ -571,7 +571,7 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, | |||
571 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 571 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
572 | 0, CY_MAXZ, 0, 0); | 572 | 0, CY_MAXZ, 0, 0); |
573 | 573 | ||
574 | input_mt_init_slots(input_dev, CY_MAX_ID); | 574 | input_mt_init_slots(input_dev, CY_MAX_ID, 0); |
575 | 575 | ||
576 | error = request_threaded_irq(ts->irq, NULL, cyttsp_irq, | 576 | error = request_threaded_irq(ts->irq, NULL, cyttsp_irq, |
577 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 577 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 64957770b522..099d144ab7c9 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -782,7 +782,7 @@ static int __devinit edt_ft5x06_ts_probe(struct i2c_client *client, | |||
782 | 0, tsdata->num_x * 64 - 1, 0, 0); | 782 | 0, tsdata->num_x * 64 - 1, 0, 0); |
783 | input_set_abs_params(input, ABS_MT_POSITION_Y, | 783 | input_set_abs_params(input, ABS_MT_POSITION_Y, |
784 | 0, tsdata->num_y * 64 - 1, 0, 0); | 784 | 0, tsdata->num_y * 64 - 1, 0, 0); |
785 | error = input_mt_init_slots(input, MAX_SUPPORT_POINTS); | 785 | error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0); |
786 | if (error) { | 786 | if (error) { |
787 | dev_err(&client->dev, "Unable to init MT slots.\n"); | 787 | dev_err(&client->dev, "Unable to init MT slots.\n"); |
788 | goto err_free_mem; | 788 | goto err_free_mem; |
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index 70524dd34f42..c1e3460f1195 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c | |||
@@ -204,7 +204,7 @@ static int __devinit egalax_ts_probe(struct i2c_client *client, | |||
204 | ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0); | 204 | ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0); |
205 | input_set_abs_params(input_dev, | 205 | input_set_abs_params(input_dev, |
206 | ABS_MT_POSITION_X, 0, EGALAX_MAX_Y, 0, 0); | 206 | ABS_MT_POSITION_X, 0, EGALAX_MAX_Y, 0, 0); |
207 | input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS); | 207 | input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0); |
208 | 208 | ||
209 | input_set_drvdata(input_dev, ts); | 209 | input_set_drvdata(input_dev, ts); |
210 | 210 | ||
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index c0044175a921..4ac69760ec08 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c | |||
@@ -252,7 +252,7 @@ static int __devinit ili210x_i2c_probe(struct i2c_client *client, | |||
252 | input_set_abs_params(input, ABS_Y, 0, ymax, 0, 0); | 252 | input_set_abs_params(input, ABS_Y, 0, ymax, 0, 0); |
253 | 253 | ||
254 | /* Multi touch */ | 254 | /* Multi touch */ |
255 | input_mt_init_slots(input, MAX_TOUCHES); | 255 | input_mt_init_slots(input, MAX_TOUCHES, 0); |
256 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0); | 256 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0); |
257 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0); | 257 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0); |
258 | 258 | ||
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 49c44bbf548d..560cf09d1c5a 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c | |||
@@ -404,7 +404,7 @@ static int __devinit mms114_probe(struct i2c_client *client, | |||
404 | input_set_abs_params(input_dev, ABS_Y, 0, data->pdata->y_size, 0, 0); | 404 | input_set_abs_params(input_dev, ABS_Y, 0, data->pdata->y_size, 0, 0); |
405 | 405 | ||
406 | /* For multi touch */ | 406 | /* For multi touch */ |
407 | input_mt_init_slots(input_dev, MMS114_MAX_TOUCH); | 407 | input_mt_init_slots(input_dev, MMS114_MAX_TOUCH, 0); |
408 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 408 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
409 | 0, MMS114_MAX_AREA, 0, 0); | 409 | 0, MMS114_MAX_AREA, 0, 0); |
410 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 410 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index 4ccde45b9da2..b49f0b836925 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c | |||
@@ -264,7 +264,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) | |||
264 | input_set_abs_params(pm->dev, ABS_Y, 0, max_y, 0, 0); | 264 | input_set_abs_params(pm->dev, ABS_Y, 0, max_y, 0, 0); |
265 | 265 | ||
266 | if (pm->maxcontacts > 1) { | 266 | if (pm->maxcontacts > 1) { |
267 | input_mt_init_slots(pm->dev, pm->maxcontacts); | 267 | input_mt_init_slots(pm->dev, pm->maxcontacts, 0); |
268 | input_set_abs_params(pm->dev, | 268 | input_set_abs_params(pm->dev, |
269 | ABS_MT_POSITION_X, 0, max_x, 0, 0); | 269 | ABS_MT_POSITION_X, 0, max_x, 0, 0); |
270 | input_set_abs_params(pm->dev, | 270 | input_set_abs_params(pm->dev, |
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 8f9ad2f893b8..9a83be6b6584 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
@@ -471,7 +471,7 @@ static int w8001_setup(struct w8001 *w8001) | |||
471 | case 5: | 471 | case 5: |
472 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; | 472 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; |
473 | 473 | ||
474 | input_mt_init_slots(dev, 2); | 474 | input_mt_init_slots(dev, 2, 0); |
475 | input_set_abs_params(dev, ABS_MT_POSITION_X, | 475 | input_set_abs_params(dev, ABS_MT_POSITION_X, |
476 | 0, touch.x, 0, 0); | 476 | 0, touch.x, 0, 0); |
477 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | 477 | input_set_abs_params(dev, ABS_MT_POSITION_Y, |