diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-10-01 17:40:51 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-10-01 17:40:51 -0400 |
| commit | 7774036808011ceecc88cef01dfafcce39ed9fc5 (patch) | |
| tree | e88670cf3fba9d885b3d71c00fb9a7809ed3f9e2 /drivers/input | |
| parent | fb4f552e895cec29934d94a99cbd1f1f00448a88 (diff) | |
| parent | 51c80b74002f86477d691ed7c8ac479dcfa6271c (diff) | |
Merge branch 'for-next' of git://github.com/rydberg/linux into next
Merge Henrik's updates to multitouch code. Even though Jiri already
pulled them in I need to do it too since my changes to evdev using
dynamic major would clash with them.
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/evdev.c | 78 | ||||
| -rw-r--r-- | drivers/input/input-mt.c | 305 | ||||
| -rw-r--r-- | drivers/input/input.c | 254 | ||||
| -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/tablet/wacom_wac.c | 6 | ||||
| -rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 2 | ||||
| -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 |
18 files changed, 671 insertions, 350 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6c58bfff01a3..118d0300f1fb 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -54,16 +54,9 @@ struct evdev_client { | |||
| 54 | static struct evdev *evdev_table[EVDEV_MINORS]; | 54 | static struct evdev *evdev_table[EVDEV_MINORS]; |
| 55 | static DEFINE_MUTEX(evdev_table_mutex); | 55 | static DEFINE_MUTEX(evdev_table_mutex); |
| 56 | 56 | ||
| 57 | static void evdev_pass_event(struct evdev_client *client, | 57 | static void __pass_event(struct evdev_client *client, |
| 58 | struct input_event *event, | 58 | const struct input_event *event) |
| 59 | ktime_t mono, ktime_t real) | ||
| 60 | { | 59 | { |
| 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; | 60 | client->buffer[client->head++] = *event; |
| 68 | client->head &= client->bufsize - 1; | 61 | client->head &= client->bufsize - 1; |
| 69 | 62 | ||
| @@ -86,42 +79,74 @@ static void evdev_pass_event(struct evdev_client *client, | |||
| 86 | client->packet_head = client->head; | 79 | client->packet_head = client->head; |
| 87 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | 80 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
| 88 | } | 81 | } |
| 82 | } | ||
| 83 | |||
| 84 | static void evdev_pass_values(struct evdev_client *client, | ||
| 85 | const struct input_value *vals, unsigned int count, | ||
| 86 | ktime_t mono, ktime_t real) | ||
| 87 | { | ||
| 88 | struct evdev *evdev = client->evdev; | ||
| 89 | const struct input_value *v; | ||
| 90 | struct input_event event; | ||
| 91 | bool wakeup = false; | ||
| 92 | |||
| 93 | event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? | ||
| 94 | mono : real); | ||
| 95 | |||
| 96 | /* Interrupts are disabled, just acquire the lock. */ | ||
| 97 | spin_lock(&client->buffer_lock); | ||
| 98 | |||
| 99 | for (v = vals; v != vals + count; v++) { | ||
| 100 | event.type = v->type; | ||
| 101 | event.code = v->code; | ||
| 102 | event.value = v->value; | ||
| 103 | __pass_event(client, &event); | ||
| 104 | if (v->type == EV_SYN && v->code == SYN_REPORT) | ||
| 105 | wakeup = true; | ||
| 106 | } | ||
| 89 | 107 | ||
| 90 | spin_unlock(&client->buffer_lock); | 108 | spin_unlock(&client->buffer_lock); |
| 109 | |||
| 110 | if (wakeup) | ||
| 111 | wake_up_interruptible(&evdev->wait); | ||
| 91 | } | 112 | } |
| 92 | 113 | ||
| 93 | /* | 114 | /* |
| 94 | * Pass incoming event to all connected clients. | 115 | * Pass incoming events to all connected clients. |
| 95 | */ | 116 | */ |
| 96 | static void evdev_event(struct input_handle *handle, | 117 | static void evdev_events(struct input_handle *handle, |
| 97 | unsigned int type, unsigned int code, int value) | 118 | const struct input_value *vals, unsigned int count) |
| 98 | { | 119 | { |
| 99 | struct evdev *evdev = handle->private; | 120 | struct evdev *evdev = handle->private; |
| 100 | struct evdev_client *client; | 121 | struct evdev_client *client; |
| 101 | struct input_event event; | ||
| 102 | ktime_t time_mono, time_real; | 122 | ktime_t time_mono, time_real; |
| 103 | 123 | ||
| 104 | time_mono = ktime_get(); | 124 | time_mono = ktime_get(); |
| 105 | time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); | 125 | time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); |
| 106 | 126 | ||
| 107 | event.type = type; | ||
| 108 | event.code = code; | ||
| 109 | event.value = value; | ||
| 110 | |||
| 111 | rcu_read_lock(); | 127 | rcu_read_lock(); |
| 112 | 128 | ||
| 113 | client = rcu_dereference(evdev->grab); | 129 | client = rcu_dereference(evdev->grab); |
| 114 | 130 | ||
| 115 | if (client) | 131 | if (client) |
| 116 | evdev_pass_event(client, &event, time_mono, time_real); | 132 | evdev_pass_values(client, vals, count, time_mono, time_real); |
| 117 | else | 133 | else |
| 118 | list_for_each_entry_rcu(client, &evdev->client_list, node) | 134 | list_for_each_entry_rcu(client, &evdev->client_list, node) |
| 119 | evdev_pass_event(client, &event, time_mono, time_real); | 135 | evdev_pass_values(client, vals, count, |
| 136 | time_mono, time_real); | ||
| 120 | 137 | ||
| 121 | rcu_read_unlock(); | 138 | rcu_read_unlock(); |
| 139 | } | ||
| 122 | 140 | ||
| 123 | if (type == EV_SYN && code == SYN_REPORT) | 141 | /* |
| 124 | wake_up_interruptible(&evdev->wait); | 142 | * Pass incoming event to all connected clients. |
| 143 | */ | ||
| 144 | static void evdev_event(struct input_handle *handle, | ||
| 145 | unsigned int type, unsigned int code, int value) | ||
| 146 | { | ||
| 147 | struct input_value vals[] = { { type, code, value } }; | ||
| 148 | |||
| 149 | evdev_events(handle, vals, 1); | ||
| 125 | } | 150 | } |
| 126 | 151 | ||
| 127 | static int evdev_fasync(int fd, struct file *file, int on) | 152 | static int evdev_fasync(int fd, struct file *file, int on) |
| @@ -653,20 +678,22 @@ static int evdev_handle_mt_request(struct input_dev *dev, | |||
| 653 | unsigned int size, | 678 | unsigned int size, |
| 654 | int __user *ip) | 679 | int __user *ip) |
| 655 | { | 680 | { |
| 656 | const struct input_mt_slot *mt = dev->mt; | 681 | const struct input_mt *mt = dev->mt; |
| 657 | unsigned int code; | 682 | unsigned int code; |
| 658 | int max_slots; | 683 | int max_slots; |
| 659 | int i; | 684 | int i; |
| 660 | 685 | ||
| 661 | if (get_user(code, &ip[0])) | 686 | if (get_user(code, &ip[0])) |
| 662 | return -EFAULT; | 687 | return -EFAULT; |
| 663 | if (!input_is_mt_value(code)) | 688 | if (!mt || !input_is_mt_value(code)) |
| 664 | return -EINVAL; | 689 | return -EINVAL; |
| 665 | 690 | ||
| 666 | max_slots = (size - sizeof(__u32)) / sizeof(__s32); | 691 | max_slots = (size - sizeof(__u32)) / sizeof(__s32); |
| 667 | for (i = 0; i < dev->mtsize && i < max_slots; i++) | 692 | 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])) | 693 | int value = input_mt_get_value(&mt->slots[i], code); |
| 694 | if (put_user(value, &ip[1 + i])) | ||
| 669 | return -EFAULT; | 695 | return -EFAULT; |
| 696 | } | ||
| 670 | 697 | ||
| 671 | return 0; | 698 | return 0; |
| 672 | } | 699 | } |
| @@ -1048,6 +1075,7 @@ MODULE_DEVICE_TABLE(input, evdev_ids); | |||
| 1048 | 1075 | ||
| 1049 | static struct input_handler evdev_handler = { | 1076 | static struct input_handler evdev_handler = { |
| 1050 | .event = evdev_event, | 1077 | .event = evdev_event, |
| 1078 | .events = evdev_events, | ||
| 1051 | .connect = evdev_connect, | 1079 | .connect = evdev_connect, |
| 1052 | .disconnect = evdev_disconnect, | 1080 | .disconnect = evdev_disconnect, |
| 1053 | .fops = &evdev_fops, | 1081 | .fops = &evdev_fops, |
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..ace3f7c4226d 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -47,6 +47,8 @@ static DEFINE_MUTEX(input_mutex); | |||
| 47 | 47 | ||
| 48 | static struct input_handler *input_table[8]; | 48 | static struct input_handler *input_table[8]; |
| 49 | 49 | ||
| 50 | static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 }; | ||
| 51 | |||
| 50 | static inline int is_event_supported(unsigned int code, | 52 | static inline int is_event_supported(unsigned int code, |
| 51 | unsigned long *bm, unsigned int max) | 53 | unsigned long *bm, unsigned int max) |
| 52 | { | 54 | { |
| @@ -69,42 +71,102 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) | |||
| 69 | return value; | 71 | return value; |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 74 | static void input_start_autorepeat(struct input_dev *dev, int code) | ||
| 75 | { | ||
| 76 | if (test_bit(EV_REP, dev->evbit) && | ||
| 77 | dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] && | ||
| 78 | dev->timer.data) { | ||
| 79 | dev->repeat_key = code; | ||
| 80 | mod_timer(&dev->timer, | ||
| 81 | jiffies + msecs_to_jiffies(dev->rep[REP_DELAY])); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | static void input_stop_autorepeat(struct input_dev *dev) | ||
| 86 | { | ||
| 87 | del_timer(&dev->timer); | ||
| 88 | } | ||
| 89 | |||
| 72 | /* | 90 | /* |
| 73 | * Pass event first through all filters and then, if event has not been | 91 | * 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 | 92 | * filtered out, through all open handles. This function is called with |
| 75 | * dev->event_lock held and interrupts disabled. | 93 | * dev->event_lock held and interrupts disabled. |
| 76 | */ | 94 | */ |
| 77 | static void input_pass_event(struct input_dev *dev, | 95 | static unsigned int input_to_handler(struct input_handle *handle, |
| 78 | unsigned int type, unsigned int code, int value) | 96 | struct input_value *vals, unsigned int count) |
| 97 | { | ||
| 98 | struct input_handler *handler = handle->handler; | ||
| 99 | struct input_value *end = vals; | ||
| 100 | struct input_value *v; | ||
| 101 | |||
| 102 | for (v = vals; v != vals + count; v++) { | ||
| 103 | if (handler->filter && | ||
| 104 | handler->filter(handle, v->type, v->code, v->value)) | ||
| 105 | continue; | ||
| 106 | if (end != v) | ||
| 107 | *end = *v; | ||
| 108 | end++; | ||
| 109 | } | ||
| 110 | |||
| 111 | count = end - vals; | ||
| 112 | if (!count) | ||
| 113 | return 0; | ||
| 114 | |||
| 115 | if (handler->events) | ||
| 116 | handler->events(handle, vals, count); | ||
| 117 | else if (handler->event) | ||
| 118 | for (v = vals; v != end; v++) | ||
| 119 | handler->event(handle, v->type, v->code, v->value); | ||
| 120 | |||
| 121 | return count; | ||
| 122 | } | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Pass values first through all filters and then, if event has not been | ||
| 126 | * filtered out, through all open handles. This function is called with | ||
| 127 | * dev->event_lock held and interrupts disabled. | ||
| 128 | */ | ||
| 129 | static void input_pass_values(struct input_dev *dev, | ||
| 130 | struct input_value *vals, unsigned int count) | ||
| 79 | { | 131 | { |
| 80 | struct input_handler *handler; | ||
| 81 | struct input_handle *handle; | 132 | struct input_handle *handle; |
| 133 | struct input_value *v; | ||
| 134 | |||
| 135 | if (!count) | ||
| 136 | return; | ||
| 82 | 137 | ||
| 83 | rcu_read_lock(); | 138 | rcu_read_lock(); |
| 84 | 139 | ||
| 85 | handle = rcu_dereference(dev->grab); | 140 | handle = rcu_dereference(dev->grab); |
| 86 | if (handle) | 141 | if (handle) { |
| 87 | handle->handler->event(handle, type, code, value); | 142 | count = input_to_handler(handle, vals, count); |
| 88 | else { | 143 | } else { |
| 89 | bool filtered = false; | 144 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) |
| 90 | 145 | if (handle->open) | |
| 91 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) { | 146 | count = input_to_handler(handle, vals, count); |
| 92 | if (!handle->open) | 147 | } |
| 93 | continue; | ||
| 94 | 148 | ||
| 95 | handler = handle->handler; | 149 | rcu_read_unlock(); |
| 96 | if (!handler->filter) { | ||
| 97 | if (filtered) | ||
| 98 | break; | ||
| 99 | 150 | ||
| 100 | handler->event(handle, type, code, value); | 151 | add_input_randomness(vals->type, vals->code, vals->value); |
| 101 | 152 | ||
| 102 | } else if (handler->filter(handle, type, code, value)) | 153 | /* trigger auto repeat for key events */ |
| 103 | filtered = true; | 154 | for (v = vals; v != vals + count; v++) { |
| 155 | if (v->type == EV_KEY && v->value != 2) { | ||
| 156 | if (v->value) | ||
| 157 | input_start_autorepeat(dev, v->code); | ||
| 158 | else | ||
| 159 | input_stop_autorepeat(dev); | ||
| 104 | } | 160 | } |
| 105 | } | 161 | } |
| 162 | } | ||
| 106 | 163 | ||
| 107 | rcu_read_unlock(); | 164 | static void input_pass_event(struct input_dev *dev, |
| 165 | unsigned int type, unsigned int code, int value) | ||
| 166 | { | ||
| 167 | struct input_value vals[] = { { type, code, value } }; | ||
| 168 | |||
| 169 | input_pass_values(dev, vals, ARRAY_SIZE(vals)); | ||
| 108 | } | 170 | } |
| 109 | 171 | ||
| 110 | /* | 172 | /* |
| @@ -121,18 +183,12 @@ static void input_repeat_key(unsigned long data) | |||
| 121 | 183 | ||
| 122 | if (test_bit(dev->repeat_key, dev->key) && | 184 | if (test_bit(dev->repeat_key, dev->key) && |
| 123 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { | 185 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { |
| 186 | struct input_value vals[] = { | ||
| 187 | { EV_KEY, dev->repeat_key, 2 }, | ||
| 188 | input_value_sync | ||
| 189 | }; | ||
| 124 | 190 | ||
| 125 | input_pass_event(dev, EV_KEY, dev->repeat_key, 2); | 191 | 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 | 192 | ||
| 137 | if (dev->rep[REP_PERIOD]) | 193 | if (dev->rep[REP_PERIOD]) |
| 138 | mod_timer(&dev->timer, jiffies + | 194 | mod_timer(&dev->timer, jiffies + |
| @@ -142,30 +198,17 @@ static void input_repeat_key(unsigned long data) | |||
| 142 | spin_unlock_irqrestore(&dev->event_lock, flags); | 198 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 143 | } | 199 | } |
| 144 | 200 | ||
| 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 | 201 | #define INPUT_IGNORE_EVENT 0 |
| 162 | #define INPUT_PASS_TO_HANDLERS 1 | 202 | #define INPUT_PASS_TO_HANDLERS 1 |
| 163 | #define INPUT_PASS_TO_DEVICE 2 | 203 | #define INPUT_PASS_TO_DEVICE 2 |
| 204 | #define INPUT_SLOT 4 | ||
| 205 | #define INPUT_FLUSH 8 | ||
| 164 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) | 206 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) |
| 165 | 207 | ||
| 166 | static int input_handle_abs_event(struct input_dev *dev, | 208 | static int input_handle_abs_event(struct input_dev *dev, |
| 167 | unsigned int code, int *pval) | 209 | unsigned int code, int *pval) |
| 168 | { | 210 | { |
| 211 | struct input_mt *mt = dev->mt; | ||
| 169 | bool is_mt_event; | 212 | bool is_mt_event; |
| 170 | int *pold; | 213 | int *pold; |
| 171 | 214 | ||
| @@ -174,8 +217,8 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
| 174 | * "Stage" the event; we'll flush it later, when we | 217 | * "Stage" the event; we'll flush it later, when we |
| 175 | * get actual touch data. | 218 | * get actual touch data. |
| 176 | */ | 219 | */ |
| 177 | if (*pval >= 0 && *pval < dev->mtsize) | 220 | if (mt && *pval >= 0 && *pval < mt->num_slots) |
| 178 | dev->slot = *pval; | 221 | mt->slot = *pval; |
| 179 | 222 | ||
| 180 | return INPUT_IGNORE_EVENT; | 223 | return INPUT_IGNORE_EVENT; |
| 181 | } | 224 | } |
| @@ -184,9 +227,8 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
| 184 | 227 | ||
| 185 | if (!is_mt_event) { | 228 | if (!is_mt_event) { |
| 186 | pold = &dev->absinfo[code].value; | 229 | pold = &dev->absinfo[code].value; |
| 187 | } else if (dev->mt) { | 230 | } else if (mt) { |
| 188 | struct input_mt_slot *mtslot = &dev->mt[dev->slot]; | 231 | pold = &mt->slots[mt->slot].abs[code - ABS_MT_FIRST]; |
| 189 | pold = &mtslot->abs[code - ABS_MT_FIRST]; | ||
| 190 | } else { | 232 | } else { |
| 191 | /* | 233 | /* |
| 192 | * Bypass filtering for multi-touch events when | 234 | * Bypass filtering for multi-touch events when |
| @@ -205,16 +247,16 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
| 205 | } | 247 | } |
| 206 | 248 | ||
| 207 | /* Flush pending "slot" event */ | 249 | /* Flush pending "slot" event */ |
| 208 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { | 250 | 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); | 251 | input_abs_set_val(dev, ABS_MT_SLOT, mt->slot); |
| 210 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); | 252 | return INPUT_PASS_TO_HANDLERS | INPUT_SLOT; |
| 211 | } | 253 | } |
| 212 | 254 | ||
| 213 | return INPUT_PASS_TO_HANDLERS; | 255 | return INPUT_PASS_TO_HANDLERS; |
| 214 | } | 256 | } |
| 215 | 257 | ||
| 216 | static void input_handle_event(struct input_dev *dev, | 258 | static int input_get_disposition(struct input_dev *dev, |
| 217 | unsigned int type, unsigned int code, int value) | 259 | unsigned int type, unsigned int code, int value) |
| 218 | { | 260 | { |
| 219 | int disposition = INPUT_IGNORE_EVENT; | 261 | int disposition = INPUT_IGNORE_EVENT; |
| 220 | 262 | ||
| @@ -227,37 +269,34 @@ static void input_handle_event(struct input_dev *dev, | |||
| 227 | break; | 269 | break; |
| 228 | 270 | ||
| 229 | case SYN_REPORT: | 271 | case SYN_REPORT: |
| 230 | if (!dev->sync) { | 272 | disposition = INPUT_PASS_TO_HANDLERS | INPUT_FLUSH; |
| 231 | dev->sync = true; | ||
| 232 | disposition = INPUT_PASS_TO_HANDLERS; | ||
| 233 | } | ||
| 234 | break; | 273 | break; |
| 235 | case SYN_MT_REPORT: | 274 | case SYN_MT_REPORT: |
| 236 | dev->sync = false; | ||
| 237 | disposition = INPUT_PASS_TO_HANDLERS; | 275 | disposition = INPUT_PASS_TO_HANDLERS; |
| 238 | break; | 276 | break; |
| 239 | } | 277 | } |
| 240 | break; | 278 | break; |
| 241 | 279 | ||
| 242 | case EV_KEY: | 280 | case EV_KEY: |
| 243 | if (is_event_supported(code, dev->keybit, KEY_MAX) && | 281 | if (is_event_supported(code, dev->keybit, KEY_MAX)) { |
| 244 | !!test_bit(code, dev->key) != value) { | ||
| 245 | 282 | ||
| 246 | if (value != 2) { | 283 | /* auto-repeat bypasses state updates */ |
| 247 | __change_bit(code, dev->key); | 284 | if (value == 2) { |
| 248 | if (value) | 285 | disposition = INPUT_PASS_TO_HANDLERS; |
| 249 | input_start_autorepeat(dev, code); | 286 | break; |
| 250 | else | ||
| 251 | input_stop_autorepeat(dev); | ||
| 252 | } | 287 | } |
| 253 | 288 | ||
| 254 | disposition = INPUT_PASS_TO_HANDLERS; | 289 | if (!!test_bit(code, dev->key) != !!value) { |
| 290 | |||
| 291 | __change_bit(code, dev->key); | ||
| 292 | disposition = INPUT_PASS_TO_HANDLERS; | ||
| 293 | } | ||
| 255 | } | 294 | } |
| 256 | break; | 295 | break; |
| 257 | 296 | ||
| 258 | case EV_SW: | 297 | case EV_SW: |
| 259 | if (is_event_supported(code, dev->swbit, SW_MAX) && | 298 | if (is_event_supported(code, dev->swbit, SW_MAX) && |
| 260 | !!test_bit(code, dev->sw) != value) { | 299 | !!test_bit(code, dev->sw) != !!value) { |
| 261 | 300 | ||
| 262 | __change_bit(code, dev->sw); | 301 | __change_bit(code, dev->sw); |
| 263 | disposition = INPUT_PASS_TO_HANDLERS; | 302 | disposition = INPUT_PASS_TO_HANDLERS; |
| @@ -284,7 +323,7 @@ static void input_handle_event(struct input_dev *dev, | |||
| 284 | 323 | ||
| 285 | case EV_LED: | 324 | case EV_LED: |
| 286 | if (is_event_supported(code, dev->ledbit, LED_MAX) && | 325 | if (is_event_supported(code, dev->ledbit, LED_MAX) && |
| 287 | !!test_bit(code, dev->led) != value) { | 326 | !!test_bit(code, dev->led) != !!value) { |
| 288 | 327 | ||
| 289 | __change_bit(code, dev->led); | 328 | __change_bit(code, dev->led); |
| 290 | disposition = INPUT_PASS_TO_ALL; | 329 | disposition = INPUT_PASS_TO_ALL; |
| @@ -317,14 +356,48 @@ static void input_handle_event(struct input_dev *dev, | |||
| 317 | break; | 356 | break; |
| 318 | } | 357 | } |
| 319 | 358 | ||
| 320 | if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) | 359 | return disposition; |
| 321 | dev->sync = false; | 360 | } |
| 361 | |||
| 362 | static void input_handle_event(struct input_dev *dev, | ||
| 363 | unsigned int type, unsigned int code, int value) | ||
| 364 | { | ||
| 365 | int disposition; | ||
| 366 | |||
| 367 | disposition = input_get_disposition(dev, type, code, value); | ||
| 322 | 368 | ||
| 323 | if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) | 369 | if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) |
| 324 | dev->event(dev, type, code, value); | 370 | dev->event(dev, type, code, value); |
| 325 | 371 | ||
| 326 | if (disposition & INPUT_PASS_TO_HANDLERS) | 372 | if (!dev->vals) |
| 327 | input_pass_event(dev, type, code, value); | 373 | return; |
| 374 | |||
| 375 | if (disposition & INPUT_PASS_TO_HANDLERS) { | ||
| 376 | struct input_value *v; | ||
| 377 | |||
| 378 | if (disposition & INPUT_SLOT) { | ||
| 379 | v = &dev->vals[dev->num_vals++]; | ||
| 380 | v->type = EV_ABS; | ||
| 381 | v->code = ABS_MT_SLOT; | ||
| 382 | v->value = dev->mt->slot; | ||
| 383 | } | ||
| 384 | |||
| 385 | v = &dev->vals[dev->num_vals++]; | ||
| 386 | v->type = type; | ||
| 387 | v->code = code; | ||
| 388 | v->value = value; | ||
| 389 | } | ||
| 390 | |||
| 391 | if (disposition & INPUT_FLUSH) { | ||
| 392 | if (dev->num_vals >= 2) | ||
| 393 | input_pass_values(dev, dev->vals, dev->num_vals); | ||
| 394 | dev->num_vals = 0; | ||
| 395 | } else if (dev->num_vals >= dev->max_vals - 2) { | ||
| 396 | dev->vals[dev->num_vals++] = input_value_sync; | ||
| 397 | input_pass_values(dev, dev->vals, dev->num_vals); | ||
| 398 | dev->num_vals = 0; | ||
| 399 | } | ||
| 400 | |||
| 328 | } | 401 | } |
| 329 | 402 | ||
| 330 | /** | 403 | /** |
| @@ -352,7 +425,6 @@ void input_event(struct input_dev *dev, | |||
| 352 | if (is_event_supported(type, dev->evbit, EV_MAX)) { | 425 | if (is_event_supported(type, dev->evbit, EV_MAX)) { |
| 353 | 426 | ||
| 354 | spin_lock_irqsave(&dev->event_lock, flags); | 427 | spin_lock_irqsave(&dev->event_lock, flags); |
| 355 | add_input_randomness(type, code, value); | ||
| 356 | input_handle_event(dev, type, code, value); | 428 | input_handle_event(dev, type, code, value); |
| 357 | spin_unlock_irqrestore(&dev->event_lock, flags); | 429 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 358 | } | 430 | } |
| @@ -831,10 +903,12 @@ int input_set_keycode(struct input_dev *dev, | |||
| 831 | if (test_bit(EV_KEY, dev->evbit) && | 903 | if (test_bit(EV_KEY, dev->evbit) && |
| 832 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && | 904 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && |
| 833 | __test_and_clear_bit(old_keycode, dev->key)) { | 905 | __test_and_clear_bit(old_keycode, dev->key)) { |
| 906 | struct input_value vals[] = { | ||
| 907 | { EV_KEY, old_keycode, 0 }, | ||
| 908 | input_value_sync | ||
| 909 | }; | ||
| 834 | 910 | ||
| 835 | input_pass_event(dev, EV_KEY, old_keycode, 0); | 911 | input_pass_values(dev, vals, ARRAY_SIZE(vals)); |
| 836 | if (dev->sync) | ||
| 837 | input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | ||
| 838 | } | 912 | } |
| 839 | 913 | ||
| 840 | out: | 914 | out: |
| @@ -1425,6 +1499,7 @@ static void input_dev_release(struct device *device) | |||
| 1425 | input_ff_destroy(dev); | 1499 | input_ff_destroy(dev); |
| 1426 | input_mt_destroy_slots(dev); | 1500 | input_mt_destroy_slots(dev); |
| 1427 | kfree(dev->absinfo); | 1501 | kfree(dev->absinfo); |
| 1502 | kfree(dev->vals); | ||
| 1428 | kfree(dev); | 1503 | kfree(dev); |
| 1429 | 1504 | ||
| 1430 | module_put(THIS_MODULE); | 1505 | module_put(THIS_MODULE); |
| @@ -1760,8 +1835,8 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | |||
| 1760 | int i; | 1835 | int i; |
| 1761 | unsigned int events; | 1836 | unsigned int events; |
| 1762 | 1837 | ||
| 1763 | if (dev->mtsize) { | 1838 | if (dev->mt) { |
| 1764 | mt_slots = dev->mtsize; | 1839 | mt_slots = dev->mt->num_slots; |
| 1765 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { | 1840 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { |
| 1766 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - | 1841 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - |
| 1767 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, | 1842 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, |
| @@ -1787,6 +1862,9 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | |||
| 1787 | if (test_bit(i, dev->relbit)) | 1862 | if (test_bit(i, dev->relbit)) |
| 1788 | events++; | 1863 | events++; |
| 1789 | 1864 | ||
| 1865 | /* Make room for KEY and MSC events */ | ||
| 1866 | events += 7; | ||
| 1867 | |||
| 1790 | return events; | 1868 | return events; |
| 1791 | } | 1869 | } |
| 1792 | 1870 | ||
| @@ -1825,6 +1903,7 @@ int input_register_device(struct input_dev *dev) | |||
| 1825 | { | 1903 | { |
| 1826 | static atomic_t input_no = ATOMIC_INIT(0); | 1904 | static atomic_t input_no = ATOMIC_INIT(0); |
| 1827 | struct input_handler *handler; | 1905 | struct input_handler *handler; |
| 1906 | unsigned int packet_size; | ||
| 1828 | const char *path; | 1907 | const char *path; |
| 1829 | int error; | 1908 | int error; |
| 1830 | 1909 | ||
| @@ -1837,9 +1916,14 @@ int input_register_device(struct input_dev *dev) | |||
| 1837 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ | 1916 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ |
| 1838 | input_cleanse_bitmasks(dev); | 1917 | input_cleanse_bitmasks(dev); |
| 1839 | 1918 | ||
| 1840 | if (!dev->hint_events_per_packet) | 1919 | packet_size = input_estimate_events_per_packet(dev); |
| 1841 | dev->hint_events_per_packet = | 1920 | if (dev->hint_events_per_packet < packet_size) |
| 1842 | input_estimate_events_per_packet(dev); | 1921 | dev->hint_events_per_packet = packet_size; |
| 1922 | |||
| 1923 | dev->max_vals = max(dev->hint_events_per_packet, packet_size) + 2; | ||
| 1924 | dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); | ||
| 1925 | if (!dev->vals) | ||
| 1926 | return -ENOMEM; | ||
| 1843 | 1927 | ||
| 1844 | /* | 1928 | /* |
| 1845 | * If delay and period are pre-set by the driver, then autorepeating | 1929 | * If delay and period are pre-set by the driver, then autorepeating |
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 3f5649f19082..b47155d8bc8c 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
| @@ -960,7 +960,7 @@ static int fsp_set_input_params(struct psmouse *psmouse) | |||
| 960 | 960 | ||
| 961 | input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0); | 961 | input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0); |
| 962 | input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0); | 962 | input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0); |
| 963 | input_mt_init_slots(dev, 2); | 963 | input_mt_init_slots(dev, 2, 0); |
| 964 | input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0); | 964 | input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0); |
| 965 | input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0); | 965 | input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0); |
| 966 | } | 966 | } |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 14eaecea2b70..37033ade79d3 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -1232,7 +1232,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
| 1232 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 1232 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
| 1233 | 1233 | ||
| 1234 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | 1234 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { |
| 1235 | input_mt_init_slots(dev, 2); | 1235 | input_mt_init_slots(dev, 2, 0); |
| 1236 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1236 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
| 1237 | ABS_MT_POSITION_Y); | 1237 | ABS_MT_POSITION_Y); |
| 1238 | /* Image sensors can report per-contact pressure */ | 1238 | /* Image sensors can report per-contact pressure */ |
| @@ -1244,7 +1244,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
| 1244 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | 1244 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
| 1245 | /* Non-image sensors with AGM use semi-mt */ | 1245 | /* Non-image sensors with AGM use semi-mt */ |
| 1246 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 1246 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
| 1247 | input_mt_init_slots(dev, 2); | 1247 | input_mt_init_slots(dev, 2, 0); |
| 1248 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1248 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
| 1249 | ABS_MT_POSITION_Y); | 1249 | ABS_MT_POSITION_Y); |
| 1250 | } | 1250 | } |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 532d067a9e07..2a81ce375f75 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -1530,7 +1530,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1530 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 1530 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); |
| 1531 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | 1531 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); |
| 1532 | 1532 | ||
| 1533 | input_mt_init_slots(input_dev, features->touch_max); | 1533 | input_mt_init_slots(input_dev, features->touch_max, 0); |
| 1534 | 1534 | ||
| 1535 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 1535 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
| 1536 | 0, 255, 0, 0); | 1536 | 0, 255, 0, 0); |
| @@ -1575,7 +1575,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1575 | 1575 | ||
| 1576 | case TABLETPC2FG: | 1576 | case TABLETPC2FG: |
| 1577 | if (features->device_type == BTN_TOOL_FINGER) { | 1577 | if (features->device_type == BTN_TOOL_FINGER) { |
| 1578 | input_mt_init_slots(input_dev, features->touch_max); | 1578 | input_mt_init_slots(input_dev, features->touch_max, 0); |
| 1579 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, | 1579 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, |
| 1580 | 0, MT_TOOL_MAX, 0, 0); | 1580 | 0, MT_TOOL_MAX, 0, 0); |
| 1581 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1581 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
| @@ -1631,7 +1631,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1631 | 1631 | ||
| 1632 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 1632 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
| 1633 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | 1633 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); |
| 1634 | input_mt_init_slots(input_dev, features->touch_max); | 1634 | input_mt_init_slots(input_dev, features->touch_max, 0); |
| 1635 | 1635 | ||
| 1636 | if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { | 1636 | if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { |
| 1637 | __set_bit(BTN_TOOL_TRIPLETAP, | 1637 | __set_bit(BTN_TOOL_TRIPLETAP, |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 4623cc69fc60..e92615d0b1b0 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
| @@ -1152,7 +1152,7 @@ static int __devinit mxt_probe(struct i2c_client *client, | |||
| 1152 | 1152 | ||
| 1153 | /* For multi touch */ | 1153 | /* For multi touch */ |
| 1154 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; | 1154 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; |
| 1155 | error = input_mt_init_slots(input_dev, num_mt_slots); | 1155 | error = input_mt_init_slots(input_dev, num_mt_slots, 0); |
| 1156 | if (error) | 1156 | if (error) |
| 1157 | goto err_free_object; | 1157 | goto err_free_object; |
| 1158 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 1158 | 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 9afc777a40a7..7b786e757ba2 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
| @@ -778,7 +778,7 @@ static int __devinit edt_ft5x06_ts_probe(struct i2c_client *client, | |||
| 778 | 0, tsdata->num_x * 64 - 1, 0, 0); | 778 | 0, tsdata->num_x * 64 - 1, 0, 0); |
| 779 | input_set_abs_params(input, ABS_MT_POSITION_Y, | 779 | input_set_abs_params(input, ABS_MT_POSITION_Y, |
| 780 | 0, tsdata->num_y * 64 - 1, 0, 0); | 780 | 0, tsdata->num_y * 64 - 1, 0, 0); |
| 781 | error = input_mt_init_slots(input, MAX_SUPPORT_POINTS); | 781 | error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0); |
| 782 | if (error) { | 782 | if (error) { |
| 783 | dev_err(&client->dev, "Unable to init MT slots.\n"); | 783 | dev_err(&client->dev, "Unable to init MT slots.\n"); |
| 784 | goto err_free_mem; | 784 | 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, |
