diff options
| author | J. Bruce Fields <bfields@redhat.com> | 2012-10-09 18:35:22 -0400 |
|---|---|---|
| committer | J. Bruce Fields <bfields@redhat.com> | 2012-10-09 18:35:22 -0400 |
| commit | f474af7051212b4efc8267583fad9c4ebf33ccff (patch) | |
| tree | 1aa46ebc8065a341f247c2a2d9af2f624ad1d4f8 /drivers/input | |
| parent | 0d22f68f02c10d5d10ec5712917e5828b001a822 (diff) | |
| parent | e3dd9a52cb5552c46c2a4ca7ccdfb4dab5c72457 (diff) | |
nfs: disintegrate UAPI for nfs
This is to complete part of the Userspace API (UAPI) disintegration for which
the preparatory patches were pulled recently. After these patches, userspace
headers will be segregated into:
include/uapi/linux/.../foo.h
for the userspace interface stuff, and:
include/linux/.../foo.h
for the strictly kernel internal stuff.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'drivers/input')
55 files changed, 1460 insertions, 810 deletions
diff --git a/drivers/input/apm-power.c b/drivers/input/apm-power.c index e90ee3d30613..650177a3c858 100644 --- a/drivers/input/apm-power.c +++ b/drivers/input/apm-power.c | |||
| @@ -33,7 +33,7 @@ static void system_power_event(unsigned int keycode) | |||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | static void apmpower_event(struct input_handle *handle, unsigned int type, | 35 | static void apmpower_event(struct input_handle *handle, unsigned int type, |
| 36 | unsigned int code, int value) | 36 | unsigned int code, int value) |
| 37 | { | 37 | { |
| 38 | /* only react on key down events */ | 38 | /* only react on key down events */ |
| 39 | if (value != 1) | 39 | if (value != 1) |
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/ff-core.c b/drivers/input/ff-core.c index 480eb9d9876a..f50f6dd92274 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c | |||
| @@ -138,8 +138,8 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, | |||
| 138 | 138 | ||
| 139 | if (effect->id == -1) { | 139 | if (effect->id == -1) { |
| 140 | for (id = 0; id < ff->max_effects; id++) | 140 | for (id = 0; id < ff->max_effects; id++) |
| 141 | if (!ff->effect_owners[id]) | 141 | if (!ff->effect_owners[id]) |
| 142 | break; | 142 | break; |
| 143 | 143 | ||
| 144 | if (id >= ff->max_effects) { | 144 | if (id >= ff->max_effects) { |
| 145 | ret = -ENOSPC; | 145 | ret = -ENOSPC; |
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index b107922514fb..74c0d8c6002a 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c | |||
| @@ -72,12 +72,14 @@ static const struct ff_envelope *get_envelope(const struct ff_effect *effect) | |||
| 72 | static const struct ff_envelope empty_envelope; | 72 | static const struct ff_envelope empty_envelope; |
| 73 | 73 | ||
| 74 | switch (effect->type) { | 74 | switch (effect->type) { |
| 75 | case FF_PERIODIC: | 75 | case FF_PERIODIC: |
| 76 | return &effect->u.periodic.envelope; | 76 | return &effect->u.periodic.envelope; |
| 77 | case FF_CONSTANT: | 77 | |
| 78 | return &effect->u.constant.envelope; | 78 | case FF_CONSTANT: |
| 79 | default: | 79 | return &effect->u.constant.envelope; |
| 80 | return &empty_envelope; | 80 | |
| 81 | default: | ||
| 82 | return &empty_envelope; | ||
| 81 | } | 83 | } |
| 82 | } | 84 | } |
| 83 | 85 | ||
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 8921c6180c51..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: |
| @@ -844,18 +918,10 @@ int input_set_keycode(struct input_dev *dev, | |||
| 844 | } | 918 | } |
| 845 | EXPORT_SYMBOL(input_set_keycode); | 919 | EXPORT_SYMBOL(input_set_keycode); |
| 846 | 920 | ||
| 847 | #define MATCH_BIT(bit, max) \ | ||
| 848 | for (i = 0; i < BITS_TO_LONGS(max); i++) \ | ||
| 849 | if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ | ||
| 850 | break; \ | ||
| 851 | if (i != BITS_TO_LONGS(max)) \ | ||
| 852 | continue; | ||
| 853 | |||
| 854 | static const struct input_device_id *input_match_device(struct input_handler *handler, | 921 | static const struct input_device_id *input_match_device(struct input_handler *handler, |
| 855 | struct input_dev *dev) | 922 | struct input_dev *dev) |
| 856 | { | 923 | { |
| 857 | const struct input_device_id *id; | 924 | const struct input_device_id *id; |
| 858 | int i; | ||
| 859 | 925 | ||
| 860 | for (id = handler->id_table; id->flags || id->driver_info; id++) { | 926 | for (id = handler->id_table; id->flags || id->driver_info; id++) { |
| 861 | 927 | ||
| @@ -875,15 +941,32 @@ static const struct input_device_id *input_match_device(struct input_handler *ha | |||
| 875 | if (id->version != dev->id.version) | 941 | if (id->version != dev->id.version) |
| 876 | continue; | 942 | continue; |
| 877 | 943 | ||
| 878 | MATCH_BIT(evbit, EV_MAX); | 944 | if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX)) |
| 879 | MATCH_BIT(keybit, KEY_MAX); | 945 | continue; |
| 880 | MATCH_BIT(relbit, REL_MAX); | 946 | |
| 881 | MATCH_BIT(absbit, ABS_MAX); | 947 | if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX)) |
| 882 | MATCH_BIT(mscbit, MSC_MAX); | 948 | continue; |
| 883 | MATCH_BIT(ledbit, LED_MAX); | 949 | |
| 884 | MATCH_BIT(sndbit, SND_MAX); | 950 | if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX)) |
| 885 | MATCH_BIT(ffbit, FF_MAX); | 951 | continue; |
| 886 | MATCH_BIT(swbit, SW_MAX); | 952 | |
| 953 | if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX)) | ||
| 954 | continue; | ||
| 955 | |||
| 956 | if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX)) | ||
| 957 | continue; | ||
| 958 | |||
| 959 | if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX)) | ||
| 960 | continue; | ||
| 961 | |||
| 962 | if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX)) | ||
| 963 | continue; | ||
| 964 | |||
| 965 | if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX)) | ||
| 966 | continue; | ||
| 967 | |||
| 968 | if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX)) | ||
| 969 | continue; | ||
| 887 | 970 | ||
| 888 | if (!handler->match || handler->match(handler, dev)) | 971 | if (!handler->match || handler->match(handler, dev)) |
| 889 | return id; | 972 | return id; |
| @@ -1416,6 +1499,7 @@ static void input_dev_release(struct device *device) | |||
| 1416 | input_ff_destroy(dev); | 1499 | input_ff_destroy(dev); |
| 1417 | input_mt_destroy_slots(dev); | 1500 | input_mt_destroy_slots(dev); |
| 1418 | kfree(dev->absinfo); | 1501 | kfree(dev->absinfo); |
| 1502 | kfree(dev->vals); | ||
| 1419 | kfree(dev); | 1503 | kfree(dev); |
| 1420 | 1504 | ||
| 1421 | module_put(THIS_MODULE); | 1505 | module_put(THIS_MODULE); |
| @@ -1751,8 +1835,8 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | |||
| 1751 | int i; | 1835 | int i; |
| 1752 | unsigned int events; | 1836 | unsigned int events; |
| 1753 | 1837 | ||
| 1754 | if (dev->mtsize) { | 1838 | if (dev->mt) { |
| 1755 | mt_slots = dev->mtsize; | 1839 | mt_slots = dev->mt->num_slots; |
| 1756 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { | 1840 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { |
| 1757 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - | 1841 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - |
| 1758 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, | 1842 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, |
| @@ -1778,6 +1862,9 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | |||
| 1778 | if (test_bit(i, dev->relbit)) | 1862 | if (test_bit(i, dev->relbit)) |
| 1779 | events++; | 1863 | events++; |
| 1780 | 1864 | ||
| 1865 | /* Make room for KEY and MSC events */ | ||
| 1866 | events += 7; | ||
| 1867 | |||
| 1781 | return events; | 1868 | return events; |
| 1782 | } | 1869 | } |
| 1783 | 1870 | ||
| @@ -1816,6 +1903,7 @@ int input_register_device(struct input_dev *dev) | |||
| 1816 | { | 1903 | { |
| 1817 | static atomic_t input_no = ATOMIC_INIT(0); | 1904 | static atomic_t input_no = ATOMIC_INIT(0); |
| 1818 | struct input_handler *handler; | 1905 | struct input_handler *handler; |
| 1906 | unsigned int packet_size; | ||
| 1819 | const char *path; | 1907 | const char *path; |
| 1820 | int error; | 1908 | int error; |
| 1821 | 1909 | ||
| @@ -1828,9 +1916,14 @@ int input_register_device(struct input_dev *dev) | |||
| 1828 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ | 1916 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ |
| 1829 | input_cleanse_bitmasks(dev); | 1917 | input_cleanse_bitmasks(dev); |
| 1830 | 1918 | ||
| 1831 | if (!dev->hint_events_per_packet) | 1919 | packet_size = input_estimate_events_per_packet(dev); |
| 1832 | dev->hint_events_per_packet = | 1920 | if (dev->hint_events_per_packet < packet_size) |
| 1833 | 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; | ||
| 1834 | 1927 | ||
| 1835 | /* | 1928 | /* |
| 1836 | * 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/joydev.c b/drivers/input/joydev.c index 26043cc6a016..78f323ea1e4b 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -711,7 +711,7 @@ static long joydev_ioctl(struct file *file, | |||
| 711 | 711 | ||
| 712 | case JS_SET_ALL: | 712 | case JS_SET_ALL: |
| 713 | retval = copy_from_user(&joydev->glue, argp, | 713 | retval = copy_from_user(&joydev->glue, argp, |
| 714 | sizeof(joydev->glue)) ? -EFAULT: 0; | 714 | sizeof(joydev->glue)) ? -EFAULT : 0; |
| 715 | break; | 715 | break; |
| 716 | 716 | ||
| 717 | case JS_GET_ALL: | 717 | case JS_GET_ALL: |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index c50fa75416f8..b4b65af8612a 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -533,7 +533,7 @@ config KEYBOARD_DAVINCI | |||
| 533 | 533 | ||
| 534 | config KEYBOARD_OMAP | 534 | config KEYBOARD_OMAP |
| 535 | tristate "TI OMAP keypad support" | 535 | tristate "TI OMAP keypad support" |
| 536 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 536 | depends on ARCH_OMAP1 |
| 537 | select INPUT_MATRIXKMAP | 537 | select INPUT_MATRIXKMAP |
| 538 | help | 538 | help |
| 539 | Say Y here if you want to use the OMAP keypad. | 539 | Say Y here if you want to use the OMAP keypad. |
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 9d82b3aeff5e..d5bacbb479b0 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
| 38 | #include <mach/irqs.h> | 38 | #include <mach/irqs.h> |
| 39 | #include <mach/keyscan.h> | 39 | #include <linux/platform_data/keyscan-davinci.h> |
| 40 | 40 | ||
| 41 | /* Key scan registers */ | 41 | /* Key scan registers */ |
| 42 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 | 42 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 |
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index c46fc8185469..7363402de8d4 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 30 | 30 | ||
| 31 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
| 32 | #include <mach/ep93xx_keypad.h> | 32 | #include <linux/platform_data/keypad-ep93xx.h> |
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| 35 | * Keypad Interface Register offsets | 35 | * Keypad Interface Register offsets |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index cbb1add43d5e..6a68041c261d 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
| @@ -43,11 +43,9 @@ struct gpio_button_data { | |||
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | struct gpio_keys_drvdata { | 45 | struct gpio_keys_drvdata { |
| 46 | const struct gpio_keys_platform_data *pdata; | ||
| 46 | struct input_dev *input; | 47 | struct input_dev *input; |
| 47 | struct mutex disable_lock; | 48 | struct mutex disable_lock; |
| 48 | unsigned int n_buttons; | ||
| 49 | int (*enable)(struct device *dev); | ||
| 50 | void (*disable)(struct device *dev); | ||
| 51 | struct gpio_button_data data[0]; | 49 | struct gpio_button_data data[0]; |
| 52 | }; | 50 | }; |
| 53 | 51 | ||
| @@ -171,7 +169,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, | |||
| 171 | if (!bits) | 169 | if (!bits) |
| 172 | return -ENOMEM; | 170 | return -ENOMEM; |
| 173 | 171 | ||
| 174 | for (i = 0; i < ddata->n_buttons; i++) { | 172 | for (i = 0; i < ddata->pdata->nbuttons; i++) { |
| 175 | struct gpio_button_data *bdata = &ddata->data[i]; | 173 | struct gpio_button_data *bdata = &ddata->data[i]; |
| 176 | 174 | ||
| 177 | if (bdata->button->type != type) | 175 | if (bdata->button->type != type) |
| @@ -219,7 +217,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, | |||
| 219 | goto out; | 217 | goto out; |
| 220 | 218 | ||
| 221 | /* First validate */ | 219 | /* First validate */ |
| 222 | for (i = 0; i < ddata->n_buttons; i++) { | 220 | for (i = 0; i < ddata->pdata->nbuttons; i++) { |
| 223 | struct gpio_button_data *bdata = &ddata->data[i]; | 221 | struct gpio_button_data *bdata = &ddata->data[i]; |
| 224 | 222 | ||
| 225 | if (bdata->button->type != type) | 223 | if (bdata->button->type != type) |
| @@ -234,7 +232,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, | |||
| 234 | 232 | ||
| 235 | mutex_lock(&ddata->disable_lock); | 233 | mutex_lock(&ddata->disable_lock); |
| 236 | 234 | ||
| 237 | for (i = 0; i < ddata->n_buttons; i++) { | 235 | for (i = 0; i < ddata->pdata->nbuttons; i++) { |
| 238 | struct gpio_button_data *bdata = &ddata->data[i]; | 236 | struct gpio_button_data *bdata = &ddata->data[i]; |
| 239 | 237 | ||
| 240 | if (bdata->button->type != type) | 238 | if (bdata->button->type != type) |
| @@ -346,6 +344,9 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) | |||
| 346 | container_of(work, struct gpio_button_data, work); | 344 | container_of(work, struct gpio_button_data, work); |
| 347 | 345 | ||
| 348 | gpio_keys_gpio_report_event(bdata); | 346 | gpio_keys_gpio_report_event(bdata); |
| 347 | |||
| 348 | if (bdata->button->wakeup) | ||
| 349 | pm_relax(bdata->input->dev.parent); | ||
| 349 | } | 350 | } |
| 350 | 351 | ||
| 351 | static void gpio_keys_gpio_timer(unsigned long _data) | 352 | static void gpio_keys_gpio_timer(unsigned long _data) |
| @@ -361,6 +362,8 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) | |||
| 361 | 362 | ||
| 362 | BUG_ON(irq != bdata->irq); | 363 | BUG_ON(irq != bdata->irq); |
| 363 | 364 | ||
| 365 | if (bdata->button->wakeup) | ||
| 366 | pm_stay_awake(bdata->input->dev.parent); | ||
| 364 | if (bdata->timer_debounce) | 367 | if (bdata->timer_debounce) |
| 365 | mod_timer(&bdata->timer, | 368 | mod_timer(&bdata->timer, |
| 366 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); | 369 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); |
| @@ -397,6 +400,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) | |||
| 397 | spin_lock_irqsave(&bdata->lock, flags); | 400 | spin_lock_irqsave(&bdata->lock, flags); |
| 398 | 401 | ||
| 399 | if (!bdata->key_pressed) { | 402 | if (!bdata->key_pressed) { |
| 403 | if (bdata->button->wakeup) | ||
| 404 | pm_wakeup_event(bdata->input->dev.parent, 0); | ||
| 405 | |||
| 400 | input_event(input, EV_KEY, button->code, 1); | 406 | input_event(input, EV_KEY, button->code, 1); |
| 401 | input_sync(input); | 407 | input_sync(input); |
| 402 | 408 | ||
| @@ -523,56 +529,64 @@ fail: | |||
| 523 | static int gpio_keys_open(struct input_dev *input) | 529 | static int gpio_keys_open(struct input_dev *input) |
| 524 | { | 530 | { |
| 525 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); | 531 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); |
| 532 | const struct gpio_keys_platform_data *pdata = ddata->pdata; | ||
| 526 | 533 | ||
| 527 | return ddata->enable ? ddata->enable(input->dev.parent) : 0; | 534 | return pdata->enable ? pdata->enable(input->dev.parent) : 0; |
| 528 | } | 535 | } |
| 529 | 536 | ||
| 530 | static void gpio_keys_close(struct input_dev *input) | 537 | static void gpio_keys_close(struct input_dev *input) |
| 531 | { | 538 | { |
| 532 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); | 539 | struct gpio_keys_drvdata *ddata = input_get_drvdata(input); |
| 540 | const struct gpio_keys_platform_data *pdata = ddata->pdata; | ||
| 533 | 541 | ||
| 534 | if (ddata->disable) | 542 | if (pdata->disable) |
| 535 | ddata->disable(input->dev.parent); | 543 | pdata->disable(input->dev.parent); |
| 536 | } | 544 | } |
| 537 | 545 | ||
| 538 | /* | 546 | /* |
| 539 | * Handlers for alternative sources of platform_data | 547 | * Handlers for alternative sources of platform_data |
| 540 | */ | 548 | */ |
| 549 | |||
| 541 | #ifdef CONFIG_OF | 550 | #ifdef CONFIG_OF |
| 542 | /* | 551 | /* |
| 543 | * Translate OpenFirmware node properties into platform_data | 552 | * Translate OpenFirmware node properties into platform_data |
| 544 | */ | 553 | */ |
| 545 | static int gpio_keys_get_devtree_pdata(struct device *dev, | 554 | static struct gpio_keys_platform_data * __devinit |
| 546 | struct gpio_keys_platform_data *pdata) | 555 | gpio_keys_get_devtree_pdata(struct device *dev) |
| 547 | { | 556 | { |
| 548 | struct device_node *node, *pp; | 557 | struct device_node *node, *pp; |
| 558 | struct gpio_keys_platform_data *pdata; | ||
| 559 | struct gpio_keys_button *button; | ||
| 560 | int error; | ||
| 561 | int nbuttons; | ||
| 549 | int i; | 562 | int i; |
| 550 | struct gpio_keys_button *buttons; | ||
| 551 | u32 reg; | ||
| 552 | 563 | ||
| 553 | node = dev->of_node; | 564 | node = dev->of_node; |
| 554 | if (node == NULL) | 565 | if (!node) { |
| 555 | return -ENODEV; | 566 | error = -ENODEV; |
| 556 | 567 | goto err_out; | |
| 557 | memset(pdata, 0, sizeof *pdata); | 568 | } |
| 558 | 569 | ||
| 559 | pdata->rep = !!of_get_property(node, "autorepeat", NULL); | 570 | nbuttons = of_get_child_count(node); |
| 571 | if (nbuttons == 0) { | ||
| 572 | error = -ENODEV; | ||
| 573 | goto err_out; | ||
| 574 | } | ||
| 560 | 575 | ||
| 561 | /* First count the subnodes */ | 576 | pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), |
| 562 | pp = NULL; | 577 | GFP_KERNEL); |
| 563 | while ((pp = of_get_next_child(node, pp))) | 578 | if (!pdata) { |
| 564 | pdata->nbuttons++; | 579 | error = -ENOMEM; |
| 580 | goto err_out; | ||
| 581 | } | ||
| 565 | 582 | ||
| 566 | if (pdata->nbuttons == 0) | 583 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); |
| 567 | return -ENODEV; | 584 | pdata->nbuttons = nbuttons; |
| 568 | 585 | ||
| 569 | buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); | 586 | pdata->rep = !!of_get_property(node, "autorepeat", NULL); |
| 570 | if (!buttons) | ||
| 571 | return -ENOMEM; | ||
| 572 | 587 | ||
| 573 | pp = NULL; | ||
| 574 | i = 0; | 588 | i = 0; |
| 575 | while ((pp = of_get_next_child(node, pp))) { | 589 | for_each_child_of_node(node, pp) { |
| 576 | enum of_gpio_flags flags; | 590 | enum of_gpio_flags flags; |
| 577 | 591 | ||
| 578 | if (!of_find_property(pp, "gpios", NULL)) { | 592 | if (!of_find_property(pp, "gpios", NULL)) { |
| @@ -580,39 +594,42 @@ static int gpio_keys_get_devtree_pdata(struct device *dev, | |||
| 580 | dev_warn(dev, "Found button without gpios\n"); | 594 | dev_warn(dev, "Found button without gpios\n"); |
| 581 | continue; | 595 | continue; |
| 582 | } | 596 | } |
| 583 | buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); | ||
| 584 | buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
| 585 | 597 | ||
| 586 | if (of_property_read_u32(pp, "linux,code", ®)) { | 598 | button = &pdata->buttons[i++]; |
| 587 | dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); | ||
| 588 | goto out_fail; | ||
| 589 | } | ||
| 590 | buttons[i].code = reg; | ||
| 591 | 599 | ||
| 592 | buttons[i].desc = of_get_property(pp, "label", NULL); | 600 | button->gpio = of_get_gpio_flags(pp, 0, &flags); |
| 601 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
| 593 | 602 | ||
| 594 | if (of_property_read_u32(pp, "linux,input-type", ®) == 0) | 603 | if (of_property_read_u32(pp, "linux,code", &button->code)) { |
| 595 | buttons[i].type = reg; | 604 | dev_err(dev, "Button without keycode: 0x%x\n", |
| 596 | else | 605 | button->gpio); |
| 597 | buttons[i].type = EV_KEY; | 606 | error = -EINVAL; |
| 607 | goto err_free_pdata; | ||
| 608 | } | ||
| 598 | 609 | ||
| 599 | buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | 610 | button->desc = of_get_property(pp, "label", NULL); |
| 600 | 611 | ||
| 601 | if (of_property_read_u32(pp, "debounce-interval", ®) == 0) | 612 | if (of_property_read_u32(pp, "linux,input-type", &button->type)) |
| 602 | buttons[i].debounce_interval = reg; | 613 | button->type = EV_KEY; |
| 603 | else | ||
| 604 | buttons[i].debounce_interval = 5; | ||
| 605 | 614 | ||
| 606 | i++; | 615 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); |
| 616 | |||
| 617 | if (of_property_read_u32(pp, "debounce-interval", | ||
| 618 | &button->debounce_interval)) | ||
| 619 | button->debounce_interval = 5; | ||
| 607 | } | 620 | } |
| 608 | 621 | ||
| 609 | pdata->buttons = buttons; | 622 | if (pdata->nbuttons == 0) { |
| 623 | error = -EINVAL; | ||
| 624 | goto err_free_pdata; | ||
| 625 | } | ||
| 610 | 626 | ||
| 611 | return 0; | 627 | return pdata; |
| 612 | 628 | ||
| 613 | out_fail: | 629 | err_free_pdata: |
| 614 | kfree(buttons); | 630 | kfree(pdata); |
| 615 | return -ENODEV; | 631 | err_out: |
| 632 | return ERR_PTR(error); | ||
| 616 | } | 633 | } |
| 617 | 634 | ||
| 618 | static struct of_device_id gpio_keys_of_match[] = { | 635 | static struct of_device_id gpio_keys_of_match[] = { |
| @@ -623,14 +640,12 @@ MODULE_DEVICE_TABLE(of, gpio_keys_of_match); | |||
| 623 | 640 | ||
| 624 | #else | 641 | #else |
| 625 | 642 | ||
| 626 | static int gpio_keys_get_devtree_pdata(struct device *dev, | 643 | static inline struct gpio_keys_platform_data * |
| 627 | struct gpio_keys_platform_data *altp) | 644 | gpio_keys_get_devtree_pdata(struct device *dev) |
| 628 | { | 645 | { |
| 629 | return -ENODEV; | 646 | return ERR_PTR(-ENODEV); |
| 630 | } | 647 | } |
| 631 | 648 | ||
| 632 | #define gpio_keys_of_match NULL | ||
| 633 | |||
| 634 | #endif | 649 | #endif |
| 635 | 650 | ||
| 636 | static void gpio_remove_key(struct gpio_button_data *bdata) | 651 | static void gpio_remove_key(struct gpio_button_data *bdata) |
| @@ -645,19 +660,17 @@ static void gpio_remove_key(struct gpio_button_data *bdata) | |||
| 645 | 660 | ||
| 646 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 661 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
| 647 | { | 662 | { |
| 648 | const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
| 649 | struct gpio_keys_drvdata *ddata; | ||
| 650 | struct device *dev = &pdev->dev; | 663 | struct device *dev = &pdev->dev; |
| 651 | struct gpio_keys_platform_data alt_pdata; | 664 | const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); |
| 665 | struct gpio_keys_drvdata *ddata; | ||
| 652 | struct input_dev *input; | 666 | struct input_dev *input; |
| 653 | int i, error; | 667 | int i, error; |
| 654 | int wakeup = 0; | 668 | int wakeup = 0; |
| 655 | 669 | ||
| 656 | if (!pdata) { | 670 | if (!pdata) { |
| 657 | error = gpio_keys_get_devtree_pdata(dev, &alt_pdata); | 671 | pdata = gpio_keys_get_devtree_pdata(dev); |
| 658 | if (error) | 672 | if (IS_ERR(pdata)) |
| 659 | return error; | 673 | return PTR_ERR(pdata); |
| 660 | pdata = &alt_pdata; | ||
| 661 | } | 674 | } |
| 662 | 675 | ||
| 663 | ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + | 676 | ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + |
| @@ -670,10 +683,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
| 670 | goto fail1; | 683 | goto fail1; |
| 671 | } | 684 | } |
| 672 | 685 | ||
| 686 | ddata->pdata = pdata; | ||
| 673 | ddata->input = input; | 687 | ddata->input = input; |
| 674 | ddata->n_buttons = pdata->nbuttons; | ||
| 675 | ddata->enable = pdata->enable; | ||
| 676 | ddata->disable = pdata->disable; | ||
| 677 | mutex_init(&ddata->disable_lock); | 688 | mutex_init(&ddata->disable_lock); |
| 678 | 689 | ||
| 679 | platform_set_drvdata(pdev, ddata); | 690 | platform_set_drvdata(pdev, ddata); |
| @@ -742,9 +753,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
| 742 | fail1: | 753 | fail1: |
| 743 | input_free_device(input); | 754 | input_free_device(input); |
| 744 | kfree(ddata); | 755 | kfree(ddata); |
| 745 | /* If we have no platform_data, we allocated buttons dynamically. */ | 756 | /* If we have no platform data, we allocated pdata dynamically. */ |
| 746 | if (!pdev->dev.platform_data) | 757 | if (!dev_get_platdata(&pdev->dev)) |
| 747 | kfree(pdata->buttons); | 758 | kfree(pdata); |
| 748 | 759 | ||
| 749 | return error; | 760 | return error; |
| 750 | } | 761 | } |
| @@ -759,18 +770,14 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
| 759 | 770 | ||
| 760 | device_init_wakeup(&pdev->dev, 0); | 771 | device_init_wakeup(&pdev->dev, 0); |
| 761 | 772 | ||
| 762 | for (i = 0; i < ddata->n_buttons; i++) | 773 | for (i = 0; i < ddata->pdata->nbuttons; i++) |
| 763 | gpio_remove_key(&ddata->data[i]); | 774 | gpio_remove_key(&ddata->data[i]); |
| 764 | 775 | ||
| 765 | input_unregister_device(input); | 776 | input_unregister_device(input); |
| 766 | 777 | ||
| 767 | /* | 778 | /* If we have no platform data, we allocated pdata dynamically. */ |
| 768 | * If we had no platform_data, we allocated buttons dynamically, and | 779 | if (!dev_get_platdata(&pdev->dev)) |
| 769 | * must free them here. ddata->data[0].button is the pointer to the | 780 | kfree(ddata->pdata); |
| 770 | * beginning of the allocated array. | ||
| 771 | */ | ||
| 772 | if (!pdev->dev.platform_data) | ||
| 773 | kfree(ddata->data[0].button); | ||
| 774 | 781 | ||
| 775 | kfree(ddata); | 782 | kfree(ddata); |
| 776 | 783 | ||
| @@ -784,7 +791,7 @@ static int gpio_keys_suspend(struct device *dev) | |||
| 784 | int i; | 791 | int i; |
| 785 | 792 | ||
| 786 | if (device_may_wakeup(dev)) { | 793 | if (device_may_wakeup(dev)) { |
| 787 | for (i = 0; i < ddata->n_buttons; i++) { | 794 | for (i = 0; i < ddata->pdata->nbuttons; i++) { |
| 788 | struct gpio_button_data *bdata = &ddata->data[i]; | 795 | struct gpio_button_data *bdata = &ddata->data[i]; |
| 789 | if (bdata->button->wakeup) | 796 | if (bdata->button->wakeup) |
| 790 | enable_irq_wake(bdata->irq); | 797 | enable_irq_wake(bdata->irq); |
| @@ -799,7 +806,7 @@ static int gpio_keys_resume(struct device *dev) | |||
| 799 | struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); | 806 | struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); |
| 800 | int i; | 807 | int i; |
| 801 | 808 | ||
| 802 | for (i = 0; i < ddata->n_buttons; i++) { | 809 | for (i = 0; i < ddata->pdata->nbuttons; i++) { |
| 803 | struct gpio_button_data *bdata = &ddata->data[i]; | 810 | struct gpio_button_data *bdata = &ddata->data[i]; |
| 804 | if (bdata->button->wakeup && device_may_wakeup(dev)) | 811 | if (bdata->button->wakeup && device_may_wakeup(dev)) |
| 805 | disable_irq_wake(bdata->irq); | 812 | disable_irq_wake(bdata->irq); |
| @@ -822,7 +829,7 @@ static struct platform_driver gpio_keys_device_driver = { | |||
| 822 | .name = "gpio-keys", | 829 | .name = "gpio-keys", |
| 823 | .owner = THIS_MODULE, | 830 | .owner = THIS_MODULE, |
| 824 | .pm = &gpio_keys_pm_ops, | 831 | .pm = &gpio_keys_pm_ops, |
| 825 | .of_match_table = gpio_keys_of_match, | 832 | .of_match_table = of_match_ptr(gpio_keys_of_match), |
| 826 | } | 833 | } |
| 827 | }; | 834 | }; |
| 828 | 835 | ||
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 20c8ab172214..f2142de789e7 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
| 27 | #include <linux/gpio_keys.h> | 27 | #include <linux/gpio_keys.h> |
| 28 | #include <linux/of_platform.h> | ||
| 29 | #include <linux/of_gpio.h> | ||
| 28 | 30 | ||
| 29 | #define DRV_NAME "gpio-keys-polled" | 31 | #define DRV_NAME "gpio-keys-polled" |
| 30 | 32 | ||
| @@ -38,7 +40,7 @@ struct gpio_keys_button_data { | |||
| 38 | struct gpio_keys_polled_dev { | 40 | struct gpio_keys_polled_dev { |
| 39 | struct input_polled_dev *poll_dev; | 41 | struct input_polled_dev *poll_dev; |
| 40 | struct device *dev; | 42 | struct device *dev; |
| 41 | struct gpio_keys_platform_data *pdata; | 43 | const struct gpio_keys_platform_data *pdata; |
| 42 | struct gpio_keys_button_data data[0]; | 44 | struct gpio_keys_button_data data[0]; |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| @@ -67,11 +69,11 @@ static void gpio_keys_polled_check_state(struct input_dev *input, | |||
| 67 | static void gpio_keys_polled_poll(struct input_polled_dev *dev) | 69 | static void gpio_keys_polled_poll(struct input_polled_dev *dev) |
| 68 | { | 70 | { |
| 69 | struct gpio_keys_polled_dev *bdev = dev->private; | 71 | struct gpio_keys_polled_dev *bdev = dev->private; |
| 70 | struct gpio_keys_platform_data *pdata = bdev->pdata; | 72 | const struct gpio_keys_platform_data *pdata = bdev->pdata; |
| 71 | struct input_dev *input = dev->input; | 73 | struct input_dev *input = dev->input; |
| 72 | int i; | 74 | int i; |
| 73 | 75 | ||
| 74 | for (i = 0; i < bdev->pdata->nbuttons; i++) { | 76 | for (i = 0; i < pdata->nbuttons; i++) { |
| 75 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | 77 | struct gpio_keys_button_data *bdata = &bdev->data[i]; |
| 76 | 78 | ||
| 77 | if (bdata->count < bdata->threshold) | 79 | if (bdata->count < bdata->threshold) |
| @@ -85,7 +87,7 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev) | |||
| 85 | static void gpio_keys_polled_open(struct input_polled_dev *dev) | 87 | static void gpio_keys_polled_open(struct input_polled_dev *dev) |
| 86 | { | 88 | { |
| 87 | struct gpio_keys_polled_dev *bdev = dev->private; | 89 | struct gpio_keys_polled_dev *bdev = dev->private; |
| 88 | struct gpio_keys_platform_data *pdata = bdev->pdata; | 90 | const struct gpio_keys_platform_data *pdata = bdev->pdata; |
| 89 | 91 | ||
| 90 | if (pdata->enable) | 92 | if (pdata->enable) |
| 91 | pdata->enable(bdev->dev); | 93 | pdata->enable(bdev->dev); |
| @@ -94,31 +96,139 @@ static void gpio_keys_polled_open(struct input_polled_dev *dev) | |||
| 94 | static void gpio_keys_polled_close(struct input_polled_dev *dev) | 96 | static void gpio_keys_polled_close(struct input_polled_dev *dev) |
| 95 | { | 97 | { |
| 96 | struct gpio_keys_polled_dev *bdev = dev->private; | 98 | struct gpio_keys_polled_dev *bdev = dev->private; |
| 97 | struct gpio_keys_platform_data *pdata = bdev->pdata; | 99 | const struct gpio_keys_platform_data *pdata = bdev->pdata; |
| 98 | 100 | ||
| 99 | if (pdata->disable) | 101 | if (pdata->disable) |
| 100 | pdata->disable(bdev->dev); | 102 | pdata->disable(bdev->dev); |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 105 | #ifdef CONFIG_OF | ||
| 106 | static struct gpio_keys_platform_data * __devinit | ||
| 107 | gpio_keys_polled_get_devtree_pdata(struct device *dev) | ||
| 108 | { | ||
| 109 | struct device_node *node, *pp; | ||
| 110 | struct gpio_keys_platform_data *pdata; | ||
| 111 | struct gpio_keys_button *button; | ||
| 112 | int error; | ||
| 113 | int nbuttons; | ||
| 114 | int i; | ||
| 115 | |||
| 116 | node = dev->of_node; | ||
| 117 | if (!node) | ||
| 118 | return NULL; | ||
| 119 | |||
| 120 | nbuttons = of_get_child_count(node); | ||
| 121 | if (nbuttons == 0) | ||
| 122 | return NULL; | ||
| 123 | |||
| 124 | pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), | ||
| 125 | GFP_KERNEL); | ||
| 126 | if (!pdata) { | ||
| 127 | error = -ENOMEM; | ||
| 128 | goto err_out; | ||
| 129 | } | ||
| 130 | |||
| 131 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); | ||
| 132 | pdata->nbuttons = nbuttons; | ||
| 133 | |||
| 134 | pdata->rep = !!of_get_property(node, "autorepeat", NULL); | ||
| 135 | of_property_read_u32(node, "poll-interval", &pdata->poll_interval); | ||
| 136 | |||
| 137 | i = 0; | ||
| 138 | for_each_child_of_node(node, pp) { | ||
| 139 | enum of_gpio_flags flags; | ||
| 140 | |||
| 141 | if (!of_find_property(pp, "gpios", NULL)) { | ||
| 142 | pdata->nbuttons--; | ||
| 143 | dev_warn(dev, "Found button without gpios\n"); | ||
| 144 | continue; | ||
| 145 | } | ||
| 146 | |||
| 147 | button = &pdata->buttons[i++]; | ||
| 148 | |||
| 149 | button->gpio = of_get_gpio_flags(pp, 0, &flags); | ||
| 150 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
| 151 | |||
| 152 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | ||
| 153 | dev_err(dev, "Button without keycode: 0x%x\n", | ||
| 154 | button->gpio); | ||
| 155 | error = -EINVAL; | ||
| 156 | goto err_free_pdata; | ||
| 157 | } | ||
| 158 | |||
| 159 | button->desc = of_get_property(pp, "label", NULL); | ||
| 160 | |||
| 161 | if (of_property_read_u32(pp, "linux,input-type", &button->type)) | ||
| 162 | button->type = EV_KEY; | ||
| 163 | |||
| 164 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | ||
| 165 | |||
| 166 | if (of_property_read_u32(pp, "debounce-interval", | ||
| 167 | &button->debounce_interval)) | ||
| 168 | button->debounce_interval = 5; | ||
| 169 | } | ||
| 170 | |||
| 171 | if (pdata->nbuttons == 0) { | ||
| 172 | error = -EINVAL; | ||
| 173 | goto err_free_pdata; | ||
| 174 | } | ||
| 175 | |||
| 176 | return pdata; | ||
| 177 | |||
| 178 | err_free_pdata: | ||
| 179 | kfree(pdata); | ||
| 180 | err_out: | ||
| 181 | return ERR_PTR(error); | ||
| 182 | } | ||
| 183 | |||
| 184 | static struct of_device_id gpio_keys_polled_of_match[] = { | ||
| 185 | { .compatible = "gpio-keys-polled", }, | ||
| 186 | { }, | ||
| 187 | }; | ||
| 188 | MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); | ||
| 189 | |||
| 190 | #else | ||
| 191 | |||
| 192 | static inline struct gpio_keys_platform_data * | ||
| 193 | gpio_keys_polled_get_devtree_pdata(struct device *dev) | ||
| 194 | { | ||
| 195 | return NULL; | ||
| 196 | } | ||
| 197 | #endif | ||
| 198 | |||
| 103 | static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) | 199 | static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) |
| 104 | { | 200 | { |
| 105 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
| 106 | struct device *dev = &pdev->dev; | 201 | struct device *dev = &pdev->dev; |
| 202 | const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); | ||
| 107 | struct gpio_keys_polled_dev *bdev; | 203 | struct gpio_keys_polled_dev *bdev; |
| 108 | struct input_polled_dev *poll_dev; | 204 | struct input_polled_dev *poll_dev; |
| 109 | struct input_dev *input; | 205 | struct input_dev *input; |
| 110 | int error; | 206 | int error; |
| 111 | int i; | 207 | int i; |
| 112 | 208 | ||
| 113 | if (!pdata || !pdata->poll_interval) | 209 | if (!pdata) { |
| 114 | return -EINVAL; | 210 | pdata = gpio_keys_polled_get_devtree_pdata(dev); |
| 211 | if (IS_ERR(pdata)) | ||
| 212 | return PTR_ERR(pdata); | ||
| 213 | if (!pdata) { | ||
| 214 | dev_err(dev, "missing platform data\n"); | ||
| 215 | return -EINVAL; | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | if (!pdata->poll_interval) { | ||
| 220 | dev_err(dev, "missing poll_interval value\n"); | ||
| 221 | error = -EINVAL; | ||
| 222 | goto err_free_pdata; | ||
| 223 | } | ||
| 115 | 224 | ||
| 116 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + | 225 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + |
| 117 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), | 226 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), |
| 118 | GFP_KERNEL); | 227 | GFP_KERNEL); |
| 119 | if (!bdev) { | 228 | if (!bdev) { |
| 120 | dev_err(dev, "no memory for private data\n"); | 229 | dev_err(dev, "no memory for private data\n"); |
| 121 | return -ENOMEM; | 230 | error = -ENOMEM; |
| 231 | goto err_free_pdata; | ||
| 122 | } | 232 | } |
| 123 | 233 | ||
| 124 | poll_dev = input_allocate_polled_device(); | 234 | poll_dev = input_allocate_polled_device(); |
| @@ -197,7 +307,7 @@ static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) | |||
| 197 | /* report initial state of the buttons */ | 307 | /* report initial state of the buttons */ |
| 198 | for (i = 0; i < pdata->nbuttons; i++) | 308 | for (i = 0; i < pdata->nbuttons; i++) |
| 199 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | 309 | gpio_keys_polled_check_state(input, &pdata->buttons[i], |
| 200 | &bdev->data[i]); | 310 | &bdev->data[i]); |
| 201 | 311 | ||
| 202 | return 0; | 312 | return 0; |
| 203 | 313 | ||
| @@ -209,15 +319,20 @@ err_free_gpio: | |||
| 209 | 319 | ||
| 210 | err_free_bdev: | 320 | err_free_bdev: |
| 211 | kfree(bdev); | 321 | kfree(bdev); |
| 212 | |||
| 213 | platform_set_drvdata(pdev, NULL); | 322 | platform_set_drvdata(pdev, NULL); |
| 323 | |||
| 324 | err_free_pdata: | ||
| 325 | /* If we have no platform_data, we allocated pdata dynamically. */ | ||
| 326 | if (!dev_get_platdata(&pdev->dev)) | ||
| 327 | kfree(pdata); | ||
| 328 | |||
| 214 | return error; | 329 | return error; |
| 215 | } | 330 | } |
| 216 | 331 | ||
| 217 | static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) | 332 | static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) |
| 218 | { | 333 | { |
| 219 | struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); | 334 | struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); |
| 220 | struct gpio_keys_platform_data *pdata = bdev->pdata; | 335 | const struct gpio_keys_platform_data *pdata = bdev->pdata; |
| 221 | int i; | 336 | int i; |
| 222 | 337 | ||
| 223 | input_unregister_polled_device(bdev->poll_dev); | 338 | input_unregister_polled_device(bdev->poll_dev); |
| @@ -227,6 +342,13 @@ static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) | |||
| 227 | 342 | ||
| 228 | input_free_polled_device(bdev->poll_dev); | 343 | input_free_polled_device(bdev->poll_dev); |
| 229 | 344 | ||
| 345 | /* | ||
| 346 | * If we had no platform_data, we allocated pdata dynamically and | ||
| 347 | * must free it here. | ||
| 348 | */ | ||
| 349 | if (!dev_get_platdata(&pdev->dev)) | ||
| 350 | kfree(pdata); | ||
| 351 | |||
| 230 | kfree(bdev); | 352 | kfree(bdev); |
| 231 | platform_set_drvdata(pdev, NULL); | 353 | platform_set_drvdata(pdev, NULL); |
| 232 | 354 | ||
| @@ -239,6 +361,7 @@ static struct platform_driver gpio_keys_polled_driver = { | |||
| 239 | .driver = { | 361 | .driver = { |
| 240 | .name = DRV_NAME, | 362 | .name = DRV_NAME, |
| 241 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
| 364 | .of_match_table = of_match_ptr(gpio_keys_polled_of_match), | ||
| 242 | }, | 365 | }, |
| 243 | }; | 366 | }; |
| 244 | module_platform_driver(gpio_keys_polled_driver); | 367 | module_platform_driver(gpio_keys_polled_driver); |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index ff4c0a87a25f..cdc252612c0b 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
| @@ -358,6 +358,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad) | |||
| 358 | /* Inhibit KDI and KRI interrupts. */ | 358 | /* Inhibit KDI and KRI interrupts. */ |
| 359 | reg_val = readw(keypad->mmio_base + KPSR); | 359 | reg_val = readw(keypad->mmio_base + KPSR); |
| 360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | 360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); |
| 361 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
| 361 | writew(reg_val, keypad->mmio_base + KPSR); | 362 | writew(reg_val, keypad->mmio_base + KPSR); |
| 362 | 363 | ||
| 363 | /* Colums as open drain and disable all rows */ | 364 | /* Colums as open drain and disable all rows */ |
| @@ -515,7 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev) | |||
| 515 | input_set_drvdata(input_dev, keypad); | 516 | input_set_drvdata(input_dev, keypad); |
| 516 | 517 | ||
| 517 | /* Ensure that the keypad will stay dormant until opened */ | 518 | /* Ensure that the keypad will stay dormant until opened */ |
| 519 | clk_prepare_enable(keypad->clk); | ||
| 518 | imx_keypad_inhibit(keypad); | 520 | imx_keypad_inhibit(keypad); |
| 521 | clk_disable_unprepare(keypad->clk); | ||
| 519 | 522 | ||
| 520 | error = request_irq(irq, imx_keypad_irq_handler, 0, | 523 | error = request_irq(irq, imx_keypad_irq_handler, 0, |
| 521 | pdev->name, keypad); | 524 | pdev->name, keypad); |
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index a880e7414202..49f5fa64e0b1 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | 22 | ||
| 23 | #include <plat/ske.h> | 23 | #include <linux/platform_data/keypad-nomadik-ske.h> |
| 24 | 24 | ||
| 25 | /* SKE_CR bits */ | 25 | /* SKE_CR bits */ |
| 26 | #define SKE_KPMLT (0x1 << 6) | 26 | #define SKE_KPMLT (0x1 << 6) |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index a0222db4dc86..4a5fcc8026f5 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
| @@ -35,13 +35,9 @@ | |||
| 35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
| 36 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
| 37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
| 38 | #include <asm/gpio.h> | 38 | #include <linux/gpio.h> |
| 39 | #include <plat/keypad.h> | 39 | #include <linux/platform_data/gpio-omap.h> |
| 40 | #include <plat/menelaus.h> | 40 | #include <linux/platform_data/keypad-omap.h> |
| 41 | #include <asm/irq.h> | ||
| 42 | #include <mach/hardware.h> | ||
| 43 | #include <asm/io.h> | ||
| 44 | #include <plat/mux.h> | ||
| 45 | 41 | ||
| 46 | #undef NEW_BOARD_LEARNING_MODE | 42 | #undef NEW_BOARD_LEARNING_MODE |
| 47 | 43 | ||
| @@ -96,28 +92,8 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp) | |||
| 96 | 92 | ||
| 97 | static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) | 93 | static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) |
| 98 | { | 94 | { |
| 99 | struct omap_kp *omap_kp = dev_id; | ||
| 100 | |||
| 101 | /* disable keyboard interrupt and schedule for handling */ | 95 | /* disable keyboard interrupt and schedule for handling */ |
| 102 | if (cpu_is_omap24xx()) { | 96 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
| 103 | int i; | ||
| 104 | |||
| 105 | for (i = 0; i < omap_kp->rows; i++) { | ||
| 106 | int gpio_irq = gpio_to_irq(row_gpios[i]); | ||
| 107 | /* | ||
| 108 | * The interrupt which we're currently handling should | ||
| 109 | * be disabled _nosync() to avoid deadlocks waiting | ||
| 110 | * for this handler to complete. All others should | ||
| 111 | * be disabled the regular way for SMP safety. | ||
| 112 | */ | ||
| 113 | if (gpio_irq == irq) | ||
| 114 | disable_irq_nosync(gpio_irq); | ||
| 115 | else | ||
| 116 | disable_irq(gpio_irq); | ||
| 117 | } | ||
| 118 | } else | ||
| 119 | /* disable keyboard interrupt and schedule for handling */ | ||
| 120 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
| 121 | 97 | ||
| 122 | tasklet_schedule(&kp_tasklet); | 98 | tasklet_schedule(&kp_tasklet); |
| 123 | 99 | ||
| @@ -133,33 +109,22 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state) | |||
| 133 | { | 109 | { |
| 134 | int col = 0; | 110 | int col = 0; |
| 135 | 111 | ||
| 136 | /* read the keypad status */ | 112 | /* disable keyboard interrupt and schedule for handling */ |
| 137 | if (cpu_is_omap24xx()) { | 113 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
| 138 | /* read the keypad status */ | ||
| 139 | for (col = 0; col < omap_kp->cols; col++) { | ||
| 140 | set_col_gpio_val(omap_kp, ~(1 << col)); | ||
| 141 | state[col] = ~(get_row_gpio_val(omap_kp)) & 0xff; | ||
| 142 | } | ||
| 143 | set_col_gpio_val(omap_kp, 0); | ||
| 144 | |||
| 145 | } else { | ||
| 146 | /* disable keyboard interrupt and schedule for handling */ | ||
| 147 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
| 148 | 114 | ||
| 149 | /* read the keypad status */ | 115 | /* read the keypad status */ |
| 150 | omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | 116 | omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); |
| 151 | for (col = 0; col < omap_kp->cols; col++) { | 117 | for (col = 0; col < omap_kp->cols; col++) { |
| 152 | omap_writew(~(1 << col) & 0xff, | 118 | omap_writew(~(1 << col) & 0xff, |
| 153 | OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | 119 | OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); |
| 154 | 120 | ||
| 155 | udelay(omap_kp->delay); | 121 | udelay(omap_kp->delay); |
| 156 | 122 | ||
| 157 | state[col] = ~omap_readw(OMAP1_MPUIO_BASE + | 123 | state[col] = ~omap_readw(OMAP1_MPUIO_BASE + |
| 158 | OMAP_MPUIO_KBR_LATCH) & 0xff; | 124 | OMAP_MPUIO_KBR_LATCH) & 0xff; |
| 159 | } | ||
| 160 | omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
| 161 | udelay(2); | ||
| 162 | } | 125 | } |
| 126 | omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
| 127 | udelay(2); | ||
| 163 | } | 128 | } |
| 164 | 129 | ||
| 165 | static void omap_kp_tasklet(unsigned long data) | 130 | static void omap_kp_tasklet(unsigned long data) |
| @@ -214,7 +179,7 @@ static void omap_kp_tasklet(unsigned long data) | |||
| 214 | memcpy(keypad_state, new_state, sizeof(keypad_state)); | 179 | memcpy(keypad_state, new_state, sizeof(keypad_state)); |
| 215 | 180 | ||
| 216 | if (key_down) { | 181 | if (key_down) { |
| 217 | int delay = HZ / 20; | 182 | int delay = HZ / 20; |
| 218 | /* some key is pressed - keep irq disabled and use timer | 183 | /* some key is pressed - keep irq disabled and use timer |
| 219 | * to poll the keypad */ | 184 | * to poll the keypad */ |
| 220 | if (spurious) | 185 | if (spurious) |
| @@ -222,14 +187,8 @@ static void omap_kp_tasklet(unsigned long data) | |||
| 222 | mod_timer(&omap_kp_data->timer, jiffies + delay); | 187 | mod_timer(&omap_kp_data->timer, jiffies + delay); |
| 223 | } else { | 188 | } else { |
| 224 | /* enable interrupts */ | 189 | /* enable interrupts */ |
| 225 | if (cpu_is_omap24xx()) { | 190 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
| 226 | int i; | 191 | kp_cur_group = -1; |
| 227 | for (i = 0; i < omap_kp_data->rows; i++) | ||
| 228 | enable_irq(gpio_to_irq(row_gpios[i])); | ||
| 229 | } else { | ||
| 230 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
| 231 | kp_cur_group = -1; | ||
| 232 | } | ||
| 233 | } | 192 | } |
| 234 | } | 193 | } |
| 235 | 194 | ||
| @@ -242,6 +201,7 @@ static ssize_t omap_kp_enable_show(struct device *dev, | |||
| 242 | static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr, | 201 | static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr, |
| 243 | const char *buf, size_t count) | 202 | const char *buf, size_t count) |
| 244 | { | 203 | { |
| 204 | struct omap_kp *omap_kp = dev_get_drvdata(dev); | ||
| 245 | int state; | 205 | int state; |
| 246 | 206 | ||
| 247 | if (sscanf(buf, "%u", &state) != 1) | 207 | if (sscanf(buf, "%u", &state) != 1) |
| @@ -253,9 +213,9 @@ static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute | |||
| 253 | mutex_lock(&kp_enable_mutex); | 213 | mutex_lock(&kp_enable_mutex); |
| 254 | if (state != kp_enable) { | 214 | if (state != kp_enable) { |
| 255 | if (state) | 215 | if (state) |
| 256 | enable_irq(INT_KEYBOARD); | 216 | enable_irq(omap_kp->irq); |
| 257 | else | 217 | else |
| 258 | disable_irq(INT_KEYBOARD); | 218 | disable_irq(omap_kp->irq); |
| 259 | kp_enable = state; | 219 | kp_enable = state; |
| 260 | } | 220 | } |
| 261 | mutex_unlock(&kp_enable_mutex); | 221 | mutex_unlock(&kp_enable_mutex); |
| @@ -289,7 +249,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
| 289 | struct omap_kp *omap_kp; | 249 | struct omap_kp *omap_kp; |
| 290 | struct input_dev *input_dev; | 250 | struct input_dev *input_dev; |
| 291 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; | 251 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; |
| 292 | int i, col_idx, row_idx, irq_idx, ret; | 252 | int i, col_idx, row_idx, ret; |
| 293 | unsigned int row_shift, keycodemax; | 253 | unsigned int row_shift, keycodemax; |
| 294 | 254 | ||
| 295 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { | 255 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { |
| @@ -314,8 +274,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
| 314 | omap_kp->input = input_dev; | 274 | omap_kp->input = input_dev; |
| 315 | 275 | ||
| 316 | /* Disable the interrupt for the MPUIO keyboard */ | 276 | /* Disable the interrupt for the MPUIO keyboard */ |
| 317 | if (!cpu_is_omap24xx()) | 277 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
| 318 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
| 319 | 278 | ||
| 320 | if (pdata->delay) | 279 | if (pdata->delay) |
| 321 | omap_kp->delay = pdata->delay; | 280 | omap_kp->delay = pdata->delay; |
| @@ -328,31 +287,8 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
| 328 | omap_kp->rows = pdata->rows; | 287 | omap_kp->rows = pdata->rows; |
| 329 | omap_kp->cols = pdata->cols; | 288 | omap_kp->cols = pdata->cols; |
| 330 | 289 | ||
| 331 | if (cpu_is_omap24xx()) { | 290 | col_idx = 0; |
| 332 | /* Cols: outputs */ | 291 | row_idx = 0; |
| 333 | for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) { | ||
| 334 | if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) { | ||
| 335 | printk(KERN_ERR "Failed to request" | ||
| 336 | "GPIO%d for keypad\n", | ||
| 337 | col_gpios[col_idx]); | ||
| 338 | goto err1; | ||
| 339 | } | ||
| 340 | gpio_direction_output(col_gpios[col_idx], 0); | ||
| 341 | } | ||
| 342 | /* Rows: inputs */ | ||
| 343 | for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) { | ||
| 344 | if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) { | ||
| 345 | printk(KERN_ERR "Failed to request" | ||
| 346 | "GPIO%d for keypad\n", | ||
| 347 | row_gpios[row_idx]); | ||
| 348 | goto err2; | ||
| 349 | } | ||
| 350 | gpio_direction_input(row_gpios[row_idx]); | ||
| 351 | } | ||
| 352 | } else { | ||
| 353 | col_idx = 0; | ||
| 354 | row_idx = 0; | ||
| 355 | } | ||
| 356 | 292 | ||
| 357 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); | 293 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); |
| 358 | 294 | ||
| @@ -394,37 +330,25 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
| 394 | 330 | ||
| 395 | /* scan current status and enable interrupt */ | 331 | /* scan current status and enable interrupt */ |
| 396 | omap_kp_scan_keypad(omap_kp, keypad_state); | 332 | omap_kp_scan_keypad(omap_kp, keypad_state); |
| 397 | if (!cpu_is_omap24xx()) { | 333 | omap_kp->irq = platform_get_irq(pdev, 0); |
| 398 | omap_kp->irq = platform_get_irq(pdev, 0); | 334 | if (omap_kp->irq >= 0) { |
| 399 | if (omap_kp->irq >= 0) { | 335 | if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, |
| 400 | if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, | 336 | "omap-keypad", omap_kp) < 0) |
| 401 | "omap-keypad", omap_kp) < 0) | 337 | goto err4; |
| 402 | goto err4; | ||
| 403 | } | ||
| 404 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
| 405 | } else { | ||
| 406 | for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) { | ||
| 407 | if (request_irq(gpio_to_irq(row_gpios[irq_idx]), | ||
| 408 | omap_kp_interrupt, | ||
| 409 | IRQF_TRIGGER_FALLING, | ||
| 410 | "omap-keypad", omap_kp) < 0) | ||
| 411 | goto err5; | ||
| 412 | } | ||
| 413 | } | 338 | } |
| 339 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
| 340 | |||
| 414 | return 0; | 341 | return 0; |
| 415 | err5: | 342 | |
| 416 | for (i = irq_idx - 1; i >=0; i--) | ||
| 417 | free_irq(row_gpios[i], omap_kp); | ||
| 418 | err4: | 343 | err4: |
| 419 | input_unregister_device(omap_kp->input); | 344 | input_unregister_device(omap_kp->input); |
| 420 | input_dev = NULL; | 345 | input_dev = NULL; |
| 421 | err3: | 346 | err3: |
| 422 | device_remove_file(&pdev->dev, &dev_attr_enable); | 347 | device_remove_file(&pdev->dev, &dev_attr_enable); |
| 423 | err2: | 348 | err2: |
| 424 | for (i = row_idx - 1; i >=0; i--) | 349 | for (i = row_idx - 1; i >= 0; i--) |
| 425 | gpio_free(row_gpios[i]); | 350 | gpio_free(row_gpios[i]); |
| 426 | err1: | 351 | for (i = col_idx - 1; i >= 0; i--) |
| 427 | for (i = col_idx - 1; i >=0; i--) | ||
| 428 | gpio_free(col_gpios[i]); | 352 | gpio_free(col_gpios[i]); |
| 429 | 353 | ||
| 430 | kfree(omap_kp); | 354 | kfree(omap_kp); |
| @@ -439,18 +363,8 @@ static int __devexit omap_kp_remove(struct platform_device *pdev) | |||
| 439 | 363 | ||
| 440 | /* disable keypad interrupt handling */ | 364 | /* disable keypad interrupt handling */ |
| 441 | tasklet_disable(&kp_tasklet); | 365 | tasklet_disable(&kp_tasklet); |
| 442 | if (cpu_is_omap24xx()) { | 366 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
| 443 | int i; | 367 | free_irq(omap_kp->irq, omap_kp); |
| 444 | for (i = 0; i < omap_kp->cols; i++) | ||
| 445 | gpio_free(col_gpios[i]); | ||
| 446 | for (i = 0; i < omap_kp->rows; i++) { | ||
| 447 | gpio_free(row_gpios[i]); | ||
| 448 | free_irq(gpio_to_irq(row_gpios[i]), omap_kp); | ||
| 449 | } | ||
| 450 | } else { | ||
| 451 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
| 452 | free_irq(omap_kp->irq, omap_kp); | ||
| 453 | } | ||
| 454 | 368 | ||
| 455 | del_timer_sync(&omap_kp->timer); | 369 | del_timer_sync(&omap_kp->timer); |
| 456 | tasklet_kill(&kp_tasklet); | 370 | tasklet_kill(&kp_tasklet); |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 7f7b72464a37..803ff6fe021e 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
| 33 | 33 | ||
| 34 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
| 35 | #include <plat/pxa27x_keypad.h> | 35 | #include <linux/platform_data/keypad-pxa27x.h> |
| 36 | /* | 36 | /* |
| 37 | * Keypad Controller registers | 37 | * Keypad Controller registers |
| 38 | */ | 38 | */ |
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index d7f1134b789e..41488f9add20 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | 17 | ||
| 18 | #include <mach/pxa930_rotary.h> | 18 | #include <linux/platform_data/keyboard-pxa930_rotary.h> |
| 19 | 19 | ||
| 20 | #define SBCR (0x04) | 20 | #define SBCR (0x04) |
| 21 | #define ERCR (0x0c) | 21 | #define ERCR (0x0c) |
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index e7a5e36e1203..76b7d430d03a 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c | |||
| @@ -156,8 +156,7 @@ static irqreturn_t qt2160_irq(int irq, void *_qt2160) | |||
| 156 | 156 | ||
| 157 | spin_lock_irqsave(&qt2160->lock, flags); | 157 | spin_lock_irqsave(&qt2160->lock, flags); |
| 158 | 158 | ||
| 159 | __cancel_delayed_work(&qt2160->dwork); | 159 | mod_delayed_work(system_wq, &qt2160->dwork, 0); |
| 160 | schedule_delayed_work(&qt2160->dwork, 0); | ||
| 161 | 160 | ||
| 162 | spin_unlock_irqrestore(&qt2160->lock, flags); | 161 | spin_unlock_irqrestore(&qt2160->lock, flags); |
| 163 | 162 | ||
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index a061ba603a29..277e26dc910e 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c | |||
| @@ -256,7 +256,7 @@ static struct samsung_keypad_platdata *samsung_keypad_parse_dt( | |||
| 256 | struct matrix_keymap_data *keymap_data; | 256 | struct matrix_keymap_data *keymap_data; |
| 257 | uint32_t *keymap, num_rows = 0, num_cols = 0; | 257 | uint32_t *keymap, num_rows = 0, num_cols = 0; |
| 258 | struct device_node *np = dev->of_node, *key_np; | 258 | struct device_node *np = dev->of_node, *key_np; |
| 259 | unsigned int key_count = 0; | 259 | unsigned int key_count; |
| 260 | 260 | ||
| 261 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 261 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| 262 | if (!pdata) { | 262 | if (!pdata) { |
| @@ -280,9 +280,7 @@ static struct samsung_keypad_platdata *samsung_keypad_parse_dt( | |||
| 280 | } | 280 | } |
| 281 | pdata->keymap_data = keymap_data; | 281 | pdata->keymap_data = keymap_data; |
| 282 | 282 | ||
| 283 | for_each_child_of_node(np, key_np) | 283 | key_count = of_get_child_count(np); |
| 284 | key_count++; | ||
| 285 | |||
| 286 | keymap_data->keymap_size = key_count; | 284 | keymap_data->keymap_size = key_count; |
| 287 | keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); | 285 | keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); |
| 288 | if (!keymap) { | 286 | if (!keymap) { |
| @@ -662,8 +660,6 @@ static const struct of_device_id samsung_keypad_dt_match[] = { | |||
| 662 | {}, | 660 | {}, |
| 663 | }; | 661 | }; |
| 664 | MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match); | 662 | MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match); |
| 665 | #else | ||
| 666 | #define samsung_keypad_dt_match NULL | ||
| 667 | #endif | 663 | #endif |
| 668 | 664 | ||
| 669 | static struct platform_device_id samsung_keypad_driver_ids[] = { | 665 | static struct platform_device_id samsung_keypad_driver_ids[] = { |
| @@ -684,7 +680,7 @@ static struct platform_driver samsung_keypad_driver = { | |||
| 684 | .driver = { | 680 | .driver = { |
| 685 | .name = "samsung-keypad", | 681 | .name = "samsung-keypad", |
| 686 | .owner = THIS_MODULE, | 682 | .owner = THIS_MODULE, |
| 687 | .of_match_table = samsung_keypad_dt_match, | 683 | .of_match_table = of_match_ptr(samsung_keypad_dt_match), |
| 688 | .pm = &samsung_keypad_pm_ops, | 684 | .pm = &samsung_keypad_pm_ops, |
| 689 | }, | 685 | }, |
| 690 | .id_table = samsung_keypad_driver_ids, | 686 | .id_table = samsung_keypad_driver_ids, |
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 72ef01be3360..c7ca97f44bfb 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #include <linux/pm_wakeup.h> | 24 | #include <linux/pm_wakeup.h> |
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 27 | #include <plat/keyboard.h> | 27 | #include <linux/platform_data/keyboard-spear.h> |
| 28 | 28 | ||
| 29 | /* Keyboard Registers */ | 29 | /* Keyboard Registers */ |
| 30 | #define MODE_CTL_REG 0x00 | 30 | #define MODE_CTL_REG 0x00 |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 2c1c9ed1bd9f..5faaf2553e33 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
| @@ -29,8 +29,8 @@ | |||
| 29 | #include <linux/of.h> | 29 | #include <linux/of.h> |
| 30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/input/tegra_kbc.h> | ||
| 32 | #include <mach/clk.h> | 33 | #include <mach/clk.h> |
| 33 | #include <mach/kbc.h> | ||
| 34 | 34 | ||
| 35 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu | 35 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu |
| 36 | 36 | ||
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 085ede4d972d..e0f6cd1ad0fd 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | 23 | ||
| 24 | #include <mach/w90p910_keypad.h> | 24 | #include <linux/platform_data/keypad-w90p910.h> |
| 25 | 25 | ||
| 26 | /* Keypad Interface Control Registers */ | 26 | /* Keypad Interface Control Registers */ |
| 27 | #define KPI_CONF 0x00 | 27 | #define KPI_CONF 0x00 |
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index f06231b7cab1..84ec691c05aa 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c | |||
| @@ -74,8 +74,8 @@ static int __devinit ab8500_ponkey_probe(struct platform_device *pdev) | |||
| 74 | 74 | ||
| 75 | ponkey->idev = input; | 75 | ponkey->idev = input; |
| 76 | ponkey->ab8500 = ab8500; | 76 | ponkey->ab8500 = ab8500; |
| 77 | ponkey->irq_dbf = ab8500_irq_get_virq(ab8500, irq_dbf); | 77 | ponkey->irq_dbf = irq_dbf; |
| 78 | ponkey->irq_dbr = ab8500_irq_get_virq(ab8500, irq_dbr); | 78 | ponkey->irq_dbr = irq_dbr; |
| 79 | 79 | ||
| 80 | input->name = "AB8500 POn(PowerOn) Key"; | 80 | input->name = "AB8500 POn(PowerOn) Key"; |
| 81 | input->dev.parent = &pdev->dev; | 81 | input->dev.parent = &pdev->dev; |
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 601f7372f9c4..26f13131639a 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c | |||
| @@ -151,22 +151,7 @@ static struct acpi_driver atlas_acpi_driver = { | |||
| 151 | .remove = atlas_acpi_button_remove, | 151 | .remove = atlas_acpi_button_remove, |
| 152 | }, | 152 | }, |
| 153 | }; | 153 | }; |
| 154 | 154 | module_acpi_driver(atlas_acpi_driver); | |
| 155 | static int __init atlas_acpi_init(void) | ||
| 156 | { | ||
| 157 | if (acpi_disabled) | ||
| 158 | return -ENODEV; | ||
| 159 | |||
| 160 | return acpi_bus_register_driver(&atlas_acpi_driver); | ||
| 161 | } | ||
| 162 | |||
| 163 | static void __exit atlas_acpi_exit(void) | ||
| 164 | { | ||
| 165 | acpi_bus_unregister_driver(&atlas_acpi_driver); | ||
| 166 | } | ||
| 167 | |||
| 168 | module_init(atlas_acpi_init); | ||
| 169 | module_exit(atlas_acpi_exit); | ||
| 170 | 155 | ||
| 171 | MODULE_AUTHOR("Jaya Kumar"); | 156 | MODULE_AUTHOR("Jaya Kumar"); |
| 172 | MODULE_LICENSE("GPL"); | 157 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index f07f784198b9..99a49e4968d2 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
| @@ -24,12 +24,14 @@ | |||
| 24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
| 25 | #include <linux/rotary_encoder.h> | 25 | #include <linux/rotary_encoder.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/of_platform.h> | ||
| 28 | #include <linux/of_gpio.h> | ||
| 27 | 29 | ||
| 28 | #define DRV_NAME "rotary-encoder" | 30 | #define DRV_NAME "rotary-encoder" |
| 29 | 31 | ||
| 30 | struct rotary_encoder { | 32 | struct rotary_encoder { |
| 31 | struct input_dev *input; | 33 | struct input_dev *input; |
| 32 | struct rotary_encoder_platform_data *pdata; | 34 | const struct rotary_encoder_platform_data *pdata; |
| 33 | 35 | ||
| 34 | unsigned int axis; | 36 | unsigned int axis; |
| 35 | unsigned int pos; | 37 | unsigned int pos; |
| @@ -43,7 +45,7 @@ struct rotary_encoder { | |||
| 43 | char last_stable; | 45 | char last_stable; |
| 44 | }; | 46 | }; |
| 45 | 47 | ||
| 46 | static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata) | 48 | static int rotary_encoder_get_state(const struct rotary_encoder_platform_data *pdata) |
| 47 | { | 49 | { |
| 48 | int a = !!gpio_get_value(pdata->gpio_a); | 50 | int a = !!gpio_get_value(pdata->gpio_a); |
| 49 | int b = !!gpio_get_value(pdata->gpio_b); | 51 | int b = !!gpio_get_value(pdata->gpio_b); |
| @@ -56,7 +58,7 @@ static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata) | |||
| 56 | 58 | ||
| 57 | static void rotary_encoder_report_event(struct rotary_encoder *encoder) | 59 | static void rotary_encoder_report_event(struct rotary_encoder *encoder) |
| 58 | { | 60 | { |
| 59 | struct rotary_encoder_platform_data *pdata = encoder->pdata; | 61 | const struct rotary_encoder_platform_data *pdata = encoder->pdata; |
| 60 | 62 | ||
| 61 | if (pdata->relative_axis) { | 63 | if (pdata->relative_axis) { |
| 62 | input_report_rel(encoder->input, | 64 | input_report_rel(encoder->input, |
| @@ -140,36 +142,89 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) | |||
| 140 | return IRQ_HANDLED; | 142 | return IRQ_HANDLED; |
| 141 | } | 143 | } |
| 142 | 144 | ||
| 145 | #ifdef CONFIG_OF | ||
| 146 | static struct of_device_id rotary_encoder_of_match[] = { | ||
| 147 | { .compatible = "rotary-encoder", }, | ||
| 148 | { }, | ||
| 149 | }; | ||
| 150 | MODULE_DEVICE_TABLE(of, rotary_encoder_of_match); | ||
| 151 | |||
| 152 | static struct rotary_encoder_platform_data * __devinit | ||
| 153 | rotary_encoder_parse_dt(struct device *dev) | ||
| 154 | { | ||
| 155 | const struct of_device_id *of_id = | ||
| 156 | of_match_device(rotary_encoder_of_match, dev); | ||
| 157 | struct device_node *np = dev->of_node; | ||
| 158 | struct rotary_encoder_platform_data *pdata; | ||
| 159 | enum of_gpio_flags flags; | ||
| 160 | |||
| 161 | if (!of_id || !np) | ||
| 162 | return NULL; | ||
| 163 | |||
| 164 | pdata = kzalloc(sizeof(struct rotary_encoder_platform_data), | ||
| 165 | GFP_KERNEL); | ||
| 166 | if (!pdata) | ||
| 167 | return ERR_PTR(-ENOMEM); | ||
| 168 | |||
| 169 | of_property_read_u32(np, "rotary-encoder,steps", &pdata->steps); | ||
| 170 | of_property_read_u32(np, "linux,axis", &pdata->axis); | ||
| 171 | |||
| 172 | pdata->gpio_a = of_get_gpio_flags(np, 0, &flags); | ||
| 173 | pdata->inverted_a = flags & OF_GPIO_ACTIVE_LOW; | ||
| 174 | |||
| 175 | pdata->gpio_b = of_get_gpio_flags(np, 1, &flags); | ||
| 176 | pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW; | ||
| 177 | |||
| 178 | pdata->relative_axis = !!of_get_property(np, | ||
| 179 | "rotary-encoder,relative-axis", NULL); | ||
| 180 | pdata->rollover = !!of_get_property(np, | ||
| 181 | "rotary-encoder,rollover", NULL); | ||
| 182 | pdata->half_period = !!of_get_property(np, | ||
| 183 | "rotary-encoder,half-period", NULL); | ||
| 184 | |||
| 185 | return pdata; | ||
| 186 | } | ||
| 187 | #else | ||
| 188 | static inline struct rotary_encoder_platform_data * | ||
| 189 | rotary_encoder_parse_dt(struct device *dev) | ||
| 190 | { | ||
| 191 | return NULL; | ||
| 192 | } | ||
| 193 | #endif | ||
| 194 | |||
| 143 | static int __devinit rotary_encoder_probe(struct platform_device *pdev) | 195 | static int __devinit rotary_encoder_probe(struct platform_device *pdev) |
| 144 | { | 196 | { |
| 145 | struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; | 197 | struct device *dev = &pdev->dev; |
| 198 | const struct rotary_encoder_platform_data *pdata = dev_get_platdata(dev); | ||
| 146 | struct rotary_encoder *encoder; | 199 | struct rotary_encoder *encoder; |
| 147 | struct input_dev *input; | 200 | struct input_dev *input; |
| 148 | irq_handler_t handler; | 201 | irq_handler_t handler; |
| 149 | int err; | 202 | int err; |
| 150 | 203 | ||
| 151 | if (!pdata) { | 204 | if (!pdata) { |
| 152 | dev_err(&pdev->dev, "missing platform data\n"); | 205 | pdata = rotary_encoder_parse_dt(dev); |
| 153 | return -ENOENT; | 206 | if (IS_ERR(pdata)) |
| 207 | return PTR_ERR(pdata); | ||
| 208 | |||
| 209 | if (!pdata) { | ||
| 210 | dev_err(dev, "missing platform data\n"); | ||
| 211 | return -EINVAL; | ||
| 212 | } | ||
| 154 | } | 213 | } |
| 155 | 214 | ||
| 156 | encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL); | 215 | encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL); |
| 157 | input = input_allocate_device(); | 216 | input = input_allocate_device(); |
| 158 | if (!encoder || !input) { | 217 | if (!encoder || !input) { |
| 159 | dev_err(&pdev->dev, "failed to allocate memory for device\n"); | ||
| 160 | err = -ENOMEM; | 218 | err = -ENOMEM; |
| 161 | goto exit_free_mem; | 219 | goto exit_free_mem; |
| 162 | } | 220 | } |
| 163 | 221 | ||
| 164 | encoder->input = input; | 222 | encoder->input = input; |
| 165 | encoder->pdata = pdata; | 223 | encoder->pdata = pdata; |
| 166 | encoder->irq_a = gpio_to_irq(pdata->gpio_a); | ||
| 167 | encoder->irq_b = gpio_to_irq(pdata->gpio_b); | ||
| 168 | 224 | ||
| 169 | /* create and register the input driver */ | ||
| 170 | input->name = pdev->name; | 225 | input->name = pdev->name; |
| 171 | input->id.bustype = BUS_HOST; | 226 | input->id.bustype = BUS_HOST; |
| 172 | input->dev.parent = &pdev->dev; | 227 | input->dev.parent = dev; |
| 173 | 228 | ||
| 174 | if (pdata->relative_axis) { | 229 | if (pdata->relative_axis) { |
| 175 | input->evbit[0] = BIT_MASK(EV_REL); | 230 | input->evbit[0] = BIT_MASK(EV_REL); |
| @@ -180,40 +235,21 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
| 180 | pdata->axis, 0, pdata->steps, 0, 1); | 235 | pdata->axis, 0, pdata->steps, 0, 1); |
| 181 | } | 236 | } |
| 182 | 237 | ||
| 183 | err = input_register_device(input); | ||
| 184 | if (err) { | ||
| 185 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
| 186 | goto exit_free_mem; | ||
| 187 | } | ||
| 188 | |||
| 189 | /* request the GPIOs */ | 238 | /* request the GPIOs */ |
| 190 | err = gpio_request(pdata->gpio_a, DRV_NAME); | 239 | err = gpio_request_one(pdata->gpio_a, GPIOF_IN, dev_name(dev)); |
| 191 | if (err) { | ||
| 192 | dev_err(&pdev->dev, "unable to request GPIO %d\n", | ||
| 193 | pdata->gpio_a); | ||
| 194 | goto exit_unregister_input; | ||
| 195 | } | ||
| 196 | |||
| 197 | err = gpio_direction_input(pdata->gpio_a); | ||
| 198 | if (err) { | 240 | if (err) { |
| 199 | dev_err(&pdev->dev, "unable to set GPIO %d for input\n", | 241 | dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_a); |
| 200 | pdata->gpio_a); | 242 | goto exit_free_mem; |
| 201 | goto exit_unregister_input; | ||
| 202 | } | 243 | } |
| 203 | 244 | ||
| 204 | err = gpio_request(pdata->gpio_b, DRV_NAME); | 245 | err = gpio_request_one(pdata->gpio_b, GPIOF_IN, dev_name(dev)); |
| 205 | if (err) { | 246 | if (err) { |
| 206 | dev_err(&pdev->dev, "unable to request GPIO %d\n", | 247 | dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_b); |
| 207 | pdata->gpio_b); | ||
| 208 | goto exit_free_gpio_a; | 248 | goto exit_free_gpio_a; |
| 209 | } | 249 | } |
| 210 | 250 | ||
| 211 | err = gpio_direction_input(pdata->gpio_b); | 251 | encoder->irq_a = gpio_to_irq(pdata->gpio_a); |
| 212 | if (err) { | 252 | encoder->irq_b = gpio_to_irq(pdata->gpio_b); |
| 213 | dev_err(&pdev->dev, "unable to set GPIO %d for input\n", | ||
| 214 | pdata->gpio_b); | ||
| 215 | goto exit_free_gpio_a; | ||
| 216 | } | ||
| 217 | 253 | ||
| 218 | /* request the IRQs */ | 254 | /* request the IRQs */ |
| 219 | if (pdata->half_period) { | 255 | if (pdata->half_period) { |
| @@ -227,8 +263,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
| 227 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 263 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| 228 | DRV_NAME, encoder); | 264 | DRV_NAME, encoder); |
| 229 | if (err) { | 265 | if (err) { |
| 230 | dev_err(&pdev->dev, "unable to request IRQ %d\n", | 266 | dev_err(dev, "unable to request IRQ %d\n", encoder->irq_a); |
| 231 | encoder->irq_a); | ||
| 232 | goto exit_free_gpio_b; | 267 | goto exit_free_gpio_b; |
| 233 | } | 268 | } |
| 234 | 269 | ||
| @@ -236,43 +271,55 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
| 236 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 271 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| 237 | DRV_NAME, encoder); | 272 | DRV_NAME, encoder); |
| 238 | if (err) { | 273 | if (err) { |
| 239 | dev_err(&pdev->dev, "unable to request IRQ %d\n", | 274 | dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b); |
| 240 | encoder->irq_b); | ||
| 241 | goto exit_free_irq_a; | 275 | goto exit_free_irq_a; |
| 242 | } | 276 | } |
| 243 | 277 | ||
| 278 | err = input_register_device(input); | ||
| 279 | if (err) { | ||
| 280 | dev_err(dev, "failed to register input device\n"); | ||
| 281 | goto exit_free_irq_b; | ||
| 282 | } | ||
| 283 | |||
| 244 | platform_set_drvdata(pdev, encoder); | 284 | platform_set_drvdata(pdev, encoder); |
| 245 | 285 | ||
| 246 | return 0; | 286 | return 0; |
| 247 | 287 | ||
| 288 | exit_free_irq_b: | ||
| 289 | free_irq(encoder->irq_b, encoder); | ||
| 248 | exit_free_irq_a: | 290 | exit_free_irq_a: |
| 249 | free_irq(encoder->irq_a, encoder); | 291 | free_irq(encoder->irq_a, encoder); |
| 250 | exit_free_gpio_b: | 292 | exit_free_gpio_b: |
| 251 | gpio_free(pdata->gpio_b); | 293 | gpio_free(pdata->gpio_b); |
| 252 | exit_free_gpio_a: | 294 | exit_free_gpio_a: |
| 253 | gpio_free(pdata->gpio_a); | 295 | gpio_free(pdata->gpio_a); |
| 254 | exit_unregister_input: | ||
| 255 | input_unregister_device(input); | ||
| 256 | input = NULL; /* so we don't try to free it */ | ||
| 257 | exit_free_mem: | 296 | exit_free_mem: |
| 258 | input_free_device(input); | 297 | input_free_device(input); |
| 259 | kfree(encoder); | 298 | kfree(encoder); |
| 299 | if (!dev_get_platdata(&pdev->dev)) | ||
| 300 | kfree(pdata); | ||
| 301 | |||
| 260 | return err; | 302 | return err; |
| 261 | } | 303 | } |
| 262 | 304 | ||
| 263 | static int __devexit rotary_encoder_remove(struct platform_device *pdev) | 305 | static int __devexit rotary_encoder_remove(struct platform_device *pdev) |
| 264 | { | 306 | { |
| 265 | struct rotary_encoder *encoder = platform_get_drvdata(pdev); | 307 | struct rotary_encoder *encoder = platform_get_drvdata(pdev); |
| 266 | struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; | 308 | const struct rotary_encoder_platform_data *pdata = encoder->pdata; |
| 267 | 309 | ||
| 268 | free_irq(encoder->irq_a, encoder); | 310 | free_irq(encoder->irq_a, encoder); |
| 269 | free_irq(encoder->irq_b, encoder); | 311 | free_irq(encoder->irq_b, encoder); |
| 270 | gpio_free(pdata->gpio_a); | 312 | gpio_free(pdata->gpio_a); |
| 271 | gpio_free(pdata->gpio_b); | 313 | gpio_free(pdata->gpio_b); |
| 314 | |||
| 272 | input_unregister_device(encoder->input); | 315 | input_unregister_device(encoder->input); |
| 273 | platform_set_drvdata(pdev, NULL); | ||
| 274 | kfree(encoder); | 316 | kfree(encoder); |
| 275 | 317 | ||
| 318 | if (!dev_get_platdata(&pdev->dev)) | ||
| 319 | kfree(pdata); | ||
| 320 | |||
| 321 | platform_set_drvdata(pdev, NULL); | ||
| 322 | |||
| 276 | return 0; | 323 | return 0; |
| 277 | } | 324 | } |
| 278 | 325 | ||
| @@ -282,6 +329,7 @@ static struct platform_driver rotary_encoder_driver = { | |||
| 282 | .driver = { | 329 | .driver = { |
| 283 | .name = DRV_NAME, | 330 | .name = DRV_NAME, |
| 284 | .owner = THIS_MODULE, | 331 | .owner = THIS_MODULE, |
| 332 | .of_match_table = of_match_ptr(rotary_encoder_of_match), | ||
| 285 | } | 333 | } |
| 286 | }; | 334 | }; |
| 287 | module_platform_driver(rotary_encoder_driver); | 335 | module_platform_driver(rotary_encoder_driver); |
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index 38e4b507b94c..b3dd96d6448b 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c | |||
| @@ -42,6 +42,7 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr) | |||
| 42 | err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value, | 42 | err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value, |
| 43 | STS_HW_CONDITIONS); | 43 | STS_HW_CONDITIONS); |
| 44 | if (!err) { | 44 | if (!err) { |
| 45 | pm_wakeup_event(pwr->dev.parent, 0); | ||
| 45 | input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); | 46 | input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); |
| 46 | input_sync(pwr); | 47 | input_sync(pwr); |
| 47 | } else { | 48 | } else { |
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index fc0ed9b43424..2194a3c7236a 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 27 | #include <linux/jiffies.h> | 27 | #include <linux/jiffies.h> |
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 29 | #include <linux/of.h> | ||
| 29 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
| 30 | #include <linux/i2c/twl.h> | 31 | #include <linux/i2c/twl.h> |
| 31 | #include <linux/mfd/twl4030-audio.h> | 32 | #include <linux/mfd/twl4030-audio.h> |
| @@ -194,13 +195,26 @@ static int twl4030_vibra_resume(struct device *dev) | |||
| 194 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, | 195 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, |
| 195 | twl4030_vibra_suspend, twl4030_vibra_resume); | 196 | twl4030_vibra_suspend, twl4030_vibra_resume); |
| 196 | 197 | ||
| 198 | static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata, | ||
| 199 | struct device_node *node) | ||
| 200 | { | ||
| 201 | if (pdata && pdata->coexist) | ||
| 202 | return true; | ||
| 203 | |||
| 204 | if (of_find_node_by_name(node, "codec")) | ||
| 205 | return true; | ||
| 206 | |||
| 207 | return false; | ||
| 208 | } | ||
| 209 | |||
| 197 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) | 210 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) |
| 198 | { | 211 | { |
| 199 | struct twl4030_vibra_data *pdata = pdev->dev.platform_data; | 212 | struct twl4030_vibra_data *pdata = pdev->dev.platform_data; |
| 213 | struct device_node *twl4030_core_node = pdev->dev.parent->of_node; | ||
| 200 | struct vibra_info *info; | 214 | struct vibra_info *info; |
| 201 | int ret; | 215 | int ret; |
| 202 | 216 | ||
| 203 | if (!pdata) { | 217 | if (!pdata && !twl4030_core_node) { |
| 204 | dev_dbg(&pdev->dev, "platform_data not available\n"); | 218 | dev_dbg(&pdev->dev, "platform_data not available\n"); |
| 205 | return -EINVAL; | 219 | return -EINVAL; |
| 206 | } | 220 | } |
| @@ -210,7 +224,7 @@ static int __devinit twl4030_vibra_probe(struct platform_device *pdev) | |||
| 210 | return -ENOMEM; | 224 | return -ENOMEM; |
| 211 | 225 | ||
| 212 | info->dev = &pdev->dev; | 226 | info->dev = &pdev->dev; |
| 213 | info->coexist = pdata->coexist; | 227 | info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node); |
| 214 | INIT_WORK(&info->play_work, vibra_play_work); | 228 | INIT_WORK(&info->play_work, vibra_play_work); |
| 215 | 229 | ||
| 216 | info->input_dev = input_allocate_device(); | 230 | info->input_dev = input_allocate_device(); |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 736056897e50..a0a4bbaef02c 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
| @@ -40,7 +40,8 @@ | |||
| 40 | #include <linux/input/mt.h> | 40 | #include <linux/input/mt.h> |
| 41 | #include "../input-compat.h" | 41 | #include "../input-compat.h" |
| 42 | 42 | ||
| 43 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 43 | static int uinput_dev_event(struct input_dev *dev, |
| 44 | unsigned int type, unsigned int code, int value) | ||
| 44 | { | 45 | { |
| 45 | struct uinput_device *udev = input_get_drvdata(dev); | 46 | struct uinput_device *udev = input_get_drvdata(dev); |
| 46 | 47 | ||
| @@ -56,10 +57,11 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned i | |||
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | /* Atomically allocate an ID for the given request. Returns 0 on success. */ | 59 | /* Atomically allocate an ID for the given request. Returns 0 on success. */ |
| 59 | static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request) | 60 | static bool uinput_request_alloc_id(struct uinput_device *udev, |
| 61 | struct uinput_request *request) | ||
| 60 | { | 62 | { |
| 61 | int id; | 63 | unsigned int id; |
| 62 | int err = -1; | 64 | bool reserved = false; |
| 63 | 65 | ||
| 64 | spin_lock(&udev->requests_lock); | 66 | spin_lock(&udev->requests_lock); |
| 65 | 67 | ||
| @@ -67,32 +69,35 @@ static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_req | |||
| 67 | if (!udev->requests[id]) { | 69 | if (!udev->requests[id]) { |
| 68 | request->id = id; | 70 | request->id = id; |
| 69 | udev->requests[id] = request; | 71 | udev->requests[id] = request; |
| 70 | err = 0; | 72 | reserved = true; |
| 71 | break; | 73 | break; |
| 72 | } | 74 | } |
| 73 | } | 75 | } |
| 74 | 76 | ||
| 75 | spin_unlock(&udev->requests_lock); | 77 | spin_unlock(&udev->requests_lock); |
| 76 | return err; | 78 | return reserved; |
| 77 | } | 79 | } |
| 78 | 80 | ||
| 79 | static struct uinput_request *uinput_request_find(struct uinput_device *udev, int id) | 81 | static struct uinput_request *uinput_request_find(struct uinput_device *udev, |
| 82 | unsigned int id) | ||
| 80 | { | 83 | { |
| 81 | /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ | 84 | /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ |
| 82 | if (id >= UINPUT_NUM_REQUESTS || id < 0) | 85 | if (id >= UINPUT_NUM_REQUESTS) |
| 83 | return NULL; | 86 | return NULL; |
| 84 | 87 | ||
| 85 | return udev->requests[id]; | 88 | return udev->requests[id]; |
| 86 | } | 89 | } |
| 87 | 90 | ||
| 88 | static inline int uinput_request_reserve_slot(struct uinput_device *udev, struct uinput_request *request) | 91 | static int uinput_request_reserve_slot(struct uinput_device *udev, |
| 92 | struct uinput_request *request) | ||
| 89 | { | 93 | { |
| 90 | /* Allocate slot. If none are available right away, wait. */ | 94 | /* Allocate slot. If none are available right away, wait. */ |
| 91 | return wait_event_interruptible(udev->requests_waitq, | 95 | return wait_event_interruptible(udev->requests_waitq, |
| 92 | !uinput_request_alloc_id(udev, request)); | 96 | uinput_request_alloc_id(udev, request)); |
| 93 | } | 97 | } |
| 94 | 98 | ||
| 95 | static void uinput_request_done(struct uinput_device *udev, struct uinput_request *request) | 99 | static void uinput_request_done(struct uinput_device *udev, |
| 100 | struct uinput_request *request) | ||
| 96 | { | 101 | { |
| 97 | /* Mark slot as available */ | 102 | /* Mark slot as available */ |
| 98 | udev->requests[request->id] = NULL; | 103 | udev->requests[request->id] = NULL; |
| @@ -101,14 +106,11 @@ static void uinput_request_done(struct uinput_device *udev, struct uinput_reques | |||
| 101 | complete(&request->done); | 106 | complete(&request->done); |
| 102 | } | 107 | } |
| 103 | 108 | ||
| 104 | static int uinput_request_submit(struct uinput_device *udev, struct uinput_request *request) | 109 | static int uinput_request_send(struct uinput_device *udev, |
| 110 | struct uinput_request *request) | ||
| 105 | { | 111 | { |
| 106 | int retval; | 112 | int retval; |
| 107 | 113 | ||
| 108 | retval = uinput_request_reserve_slot(udev, request); | ||
| 109 | if (retval) | ||
| 110 | return retval; | ||
| 111 | |||
| 112 | retval = mutex_lock_interruptible(&udev->mutex); | 114 | retval = mutex_lock_interruptible(&udev->mutex); |
| 113 | if (retval) | 115 | if (retval) |
| 114 | return retval; | 116 | return retval; |
| @@ -118,7 +120,12 @@ static int uinput_request_submit(struct uinput_device *udev, struct uinput_reque | |||
| 118 | goto out; | 120 | goto out; |
| 119 | } | 121 | } |
| 120 | 122 | ||
| 121 | /* Tell our userspace app about this new request by queueing an input event */ | 123 | init_completion(&request->done); |
| 124 | |||
| 125 | /* | ||
| 126 | * Tell our userspace application about this new request | ||
| 127 | * by queueing an input event. | ||
| 128 | */ | ||
| 122 | uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); | 129 | uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); |
| 123 | 130 | ||
| 124 | out: | 131 | out: |
| @@ -126,8 +133,27 @@ static int uinput_request_submit(struct uinput_device *udev, struct uinput_reque | |||
| 126 | return retval; | 133 | return retval; |
| 127 | } | 134 | } |
| 128 | 135 | ||
| 136 | static int uinput_request_submit(struct uinput_device *udev, | ||
| 137 | struct uinput_request *request) | ||
| 138 | { | ||
| 139 | int error; | ||
| 140 | |||
| 141 | error = uinput_request_reserve_slot(udev, request); | ||
| 142 | if (error) | ||
| 143 | return error; | ||
| 144 | |||
| 145 | error = uinput_request_send(udev, request); | ||
| 146 | if (error) { | ||
| 147 | uinput_request_done(udev, request); | ||
| 148 | return error; | ||
| 149 | } | ||
| 150 | |||
| 151 | wait_for_completion(&request->done); | ||
| 152 | return request->retval; | ||
| 153 | } | ||
| 154 | |||
| 129 | /* | 155 | /* |
| 130 | * Fail all ouitstanding requests so handlers don't wait for the userspace | 156 | * Fail all outstanding requests so handlers don't wait for the userspace |
| 131 | * to finish processing them. | 157 | * to finish processing them. |
| 132 | */ | 158 | */ |
| 133 | static void uinput_flush_requests(struct uinput_device *udev) | 159 | static void uinput_flush_requests(struct uinput_device *udev) |
| @@ -163,11 +189,12 @@ static int uinput_dev_playback(struct input_dev *dev, int effect_id, int value) | |||
| 163 | return uinput_dev_event(dev, EV_FF, effect_id, value); | 189 | return uinput_dev_event(dev, EV_FF, effect_id, value); |
| 164 | } | 190 | } |
| 165 | 191 | ||
| 166 | static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old) | 192 | static int uinput_dev_upload_effect(struct input_dev *dev, |
| 193 | struct ff_effect *effect, | ||
| 194 | struct ff_effect *old) | ||
| 167 | { | 195 | { |
| 168 | struct uinput_device *udev = input_get_drvdata(dev); | 196 | struct uinput_device *udev = input_get_drvdata(dev); |
| 169 | struct uinput_request request; | 197 | struct uinput_request request; |
| 170 | int retval; | ||
| 171 | 198 | ||
| 172 | /* | 199 | /* |
| 173 | * uinput driver does not currently support periodic effects with | 200 | * uinput driver does not currently support periodic effects with |
| @@ -180,42 +207,25 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff | |||
| 180 | effect->u.periodic.waveform == FF_CUSTOM) | 207 | effect->u.periodic.waveform == FF_CUSTOM) |
| 181 | return -EINVAL; | 208 | return -EINVAL; |
| 182 | 209 | ||
| 183 | request.id = -1; | ||
| 184 | init_completion(&request.done); | ||
| 185 | request.code = UI_FF_UPLOAD; | 210 | request.code = UI_FF_UPLOAD; |
| 186 | request.u.upload.effect = effect; | 211 | request.u.upload.effect = effect; |
| 187 | request.u.upload.old = old; | 212 | request.u.upload.old = old; |
| 188 | 213 | ||
| 189 | retval = uinput_request_submit(udev, &request); | 214 | return uinput_request_submit(udev, &request); |
| 190 | if (!retval) { | ||
| 191 | wait_for_completion(&request.done); | ||
| 192 | retval = request.retval; | ||
| 193 | } | ||
| 194 | |||
| 195 | return retval; | ||
| 196 | } | 215 | } |
| 197 | 216 | ||
| 198 | static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) | 217 | static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) |
| 199 | { | 218 | { |
| 200 | struct uinput_device *udev = input_get_drvdata(dev); | 219 | struct uinput_device *udev = input_get_drvdata(dev); |
| 201 | struct uinput_request request; | 220 | struct uinput_request request; |
| 202 | int retval; | ||
| 203 | 221 | ||
| 204 | if (!test_bit(EV_FF, dev->evbit)) | 222 | if (!test_bit(EV_FF, dev->evbit)) |
| 205 | return -ENOSYS; | 223 | return -ENOSYS; |
| 206 | 224 | ||
| 207 | request.id = -1; | ||
| 208 | init_completion(&request.done); | ||
| 209 | request.code = UI_FF_ERASE; | 225 | request.code = UI_FF_ERASE; |
| 210 | request.u.effect_id = effect_id; | 226 | request.u.effect_id = effect_id; |
| 211 | 227 | ||
| 212 | retval = uinput_request_submit(udev, &request); | 228 | return uinput_request_submit(udev, &request); |
| 213 | if (!retval) { | ||
| 214 | wait_for_completion(&request.done); | ||
| 215 | retval = request.retval; | ||
| 216 | } | ||
| 217 | |||
| 218 | return retval; | ||
| 219 | } | 229 | } |
| 220 | 230 | ||
| 221 | static void uinput_destroy_device(struct uinput_device *udev) | 231 | static void uinput_destroy_device(struct uinput_device *udev) |
| @@ -347,7 +357,8 @@ static int uinput_allocate_device(struct uinput_device *udev) | |||
| 347 | return 0; | 357 | return 0; |
| 348 | } | 358 | } |
| 349 | 359 | ||
| 350 | static int uinput_setup_device(struct uinput_device *udev, const char __user *buffer, size_t count) | 360 | static int uinput_setup_device(struct uinput_device *udev, |
| 361 | const char __user *buffer, size_t count) | ||
| 351 | { | 362 | { |
| 352 | struct uinput_user_dev *user_dev; | 363 | struct uinput_user_dev *user_dev; |
| 353 | struct input_dev *dev; | 364 | struct input_dev *dev; |
| @@ -405,7 +416,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
| 405 | goto exit; | 416 | goto exit; |
| 406 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { | 417 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { |
| 407 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; | 418 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; |
| 408 | input_mt_init_slots(dev, nslot); | 419 | input_mt_init_slots(dev, nslot, 0); |
| 409 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | 420 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { |
| 410 | input_set_events_per_packet(dev, 60); | 421 | input_set_events_per_packet(dev, 60); |
| 411 | } | 422 | } |
| @@ -419,7 +430,8 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
| 419 | return retval; | 430 | return retval; |
| 420 | } | 431 | } |
| 421 | 432 | ||
| 422 | static inline ssize_t uinput_inject_event(struct uinput_device *udev, const char __user *buffer, size_t count) | 433 | static ssize_t uinput_inject_event(struct uinput_device *udev, |
| 434 | const char __user *buffer, size_t count) | ||
| 423 | { | 435 | { |
| 424 | struct input_event ev; | 436 | struct input_event ev; |
| 425 | 437 | ||
| @@ -434,11 +446,15 @@ static inline ssize_t uinput_inject_event(struct uinput_device *udev, const char | |||
| 434 | return input_event_size(); | 446 | return input_event_size(); |
| 435 | } | 447 | } |
| 436 | 448 | ||
| 437 | static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 449 | static ssize_t uinput_write(struct file *file, const char __user *buffer, |
| 450 | size_t count, loff_t *ppos) | ||
| 438 | { | 451 | { |
| 439 | struct uinput_device *udev = file->private_data; | 452 | struct uinput_device *udev = file->private_data; |
| 440 | int retval; | 453 | int retval; |
| 441 | 454 | ||
| 455 | if (count == 0) | ||
| 456 | return 0; | ||
| 457 | |||
| 442 | retval = mutex_lock_interruptible(&udev->mutex); | 458 | retval = mutex_lock_interruptible(&udev->mutex); |
| 443 | if (retval) | 459 | if (retval) |
| 444 | return retval; | 460 | return retval; |
| @@ -452,42 +468,74 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t | |||
| 452 | return retval; | 468 | return retval; |
| 453 | } | 469 | } |
| 454 | 470 | ||
| 455 | static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 471 | static bool uinput_fetch_next_event(struct uinput_device *udev, |
| 472 | struct input_event *event) | ||
| 456 | { | 473 | { |
| 457 | struct uinput_device *udev = file->private_data; | 474 | bool have_event; |
| 458 | int retval = 0; | ||
| 459 | 475 | ||
| 460 | if (udev->state != UIST_CREATED) | 476 | spin_lock_irq(&udev->dev->event_lock); |
| 461 | return -ENODEV; | ||
| 462 | 477 | ||
| 463 | if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK)) | 478 | have_event = udev->head != udev->tail; |
| 464 | return -EAGAIN; | 479 | if (have_event) { |
| 480 | *event = udev->buff[udev->tail]; | ||
| 481 | udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; | ||
| 482 | } | ||
| 465 | 483 | ||
| 466 | retval = wait_event_interruptible(udev->waitq, | 484 | spin_unlock_irq(&udev->dev->event_lock); |
| 467 | udev->head != udev->tail || udev->state != UIST_CREATED); | ||
| 468 | if (retval) | ||
| 469 | return retval; | ||
| 470 | 485 | ||
| 471 | retval = mutex_lock_interruptible(&udev->mutex); | 486 | return have_event; |
| 472 | if (retval) | 487 | } |
| 473 | return retval; | ||
| 474 | 488 | ||
| 475 | if (udev->state != UIST_CREATED) { | 489 | static ssize_t uinput_events_to_user(struct uinput_device *udev, |
| 476 | retval = -ENODEV; | 490 | char __user *buffer, size_t count) |
| 477 | goto out; | 491 | { |
| 478 | } | 492 | struct input_event event; |
| 493 | size_t read = 0; | ||
| 479 | 494 | ||
| 480 | while (udev->head != udev->tail && retval + input_event_size() <= count) { | 495 | while (read + input_event_size() <= count && |
| 481 | if (input_event_to_user(buffer + retval, &udev->buff[udev->tail])) { | 496 | uinput_fetch_next_event(udev, &event)) { |
| 482 | retval = -EFAULT; | 497 | |
| 483 | goto out; | 498 | if (input_event_to_user(buffer + read, &event)) |
| 484 | } | 499 | return -EFAULT; |
| 485 | udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; | 500 | |
| 486 | retval += input_event_size(); | 501 | read += input_event_size(); |
| 487 | } | 502 | } |
| 488 | 503 | ||
| 489 | out: | 504 | return read; |
| 490 | mutex_unlock(&udev->mutex); | 505 | } |
| 506 | |||
| 507 | static ssize_t uinput_read(struct file *file, char __user *buffer, | ||
| 508 | size_t count, loff_t *ppos) | ||
| 509 | { | ||
| 510 | struct uinput_device *udev = file->private_data; | ||
| 511 | ssize_t retval; | ||
| 512 | |||
| 513 | if (count != 0 && count < input_event_size()) | ||
| 514 | return -EINVAL; | ||
| 515 | |||
| 516 | do { | ||
| 517 | retval = mutex_lock_interruptible(&udev->mutex); | ||
| 518 | if (retval) | ||
| 519 | return retval; | ||
| 520 | |||
| 521 | if (udev->state != UIST_CREATED) | ||
| 522 | retval = -ENODEV; | ||
| 523 | else if (udev->head == udev->tail && | ||
| 524 | (file->f_flags & O_NONBLOCK)) | ||
| 525 | retval = -EAGAIN; | ||
| 526 | else | ||
| 527 | retval = uinput_events_to_user(udev, buffer, count); | ||
| 528 | |||
| 529 | mutex_unlock(&udev->mutex); | ||
| 530 | |||
| 531 | if (retval || count == 0) | ||
| 532 | break; | ||
| 533 | |||
| 534 | if (!(file->f_flags & O_NONBLOCK)) | ||
| 535 | retval = wait_event_interruptible(udev->waitq, | ||
| 536 | udev->head != udev->tail || | ||
| 537 | udev->state != UIST_CREATED); | ||
| 538 | } while (retval == 0); | ||
| 491 | 539 | ||
| 492 | return retval; | 540 | return retval; |
| 493 | } | 541 | } |
| @@ -516,8 +564,8 @@ static int uinput_release(struct inode *inode, struct file *file) | |||
| 516 | 564 | ||
| 517 | #ifdef CONFIG_COMPAT | 565 | #ifdef CONFIG_COMPAT |
| 518 | struct uinput_ff_upload_compat { | 566 | struct uinput_ff_upload_compat { |
| 519 | int request_id; | 567 | __u32 request_id; |
| 520 | int retval; | 568 | __s32 retval; |
| 521 | struct ff_effect_compat effect; | 569 | struct ff_effect_compat effect; |
| 522 | struct ff_effect_compat old; | 570 | struct ff_effect_compat old; |
| 523 | }; | 571 | }; |
| @@ -703,7 +751,8 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, | |||
| 703 | break; | 751 | break; |
| 704 | 752 | ||
| 705 | req = uinput_request_find(udev, ff_up.request_id); | 753 | req = uinput_request_find(udev, ff_up.request_id); |
| 706 | if (!req || req->code != UI_FF_UPLOAD || !req->u.upload.effect) { | 754 | if (!req || req->code != UI_FF_UPLOAD || |
| 755 | !req->u.upload.effect) { | ||
| 707 | retval = -EINVAL; | 756 | retval = -EINVAL; |
| 708 | break; | 757 | break; |
| 709 | } | 758 | } |
| @@ -786,7 +835,8 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 786 | } | 835 | } |
| 787 | 836 | ||
| 788 | #ifdef CONFIG_COMPAT | 837 | #ifdef CONFIG_COMPAT |
| 789 | static long uinput_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 838 | static long uinput_compat_ioctl(struct file *file, |
| 839 | unsigned int cmd, unsigned long arg) | ||
| 790 | { | 840 | { |
| 791 | return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg)); | 841 | return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg)); |
| 792 | } | 842 | } |
| @@ -831,4 +881,3 @@ MODULE_VERSION("0.3"); | |||
| 831 | 881 | ||
| 832 | module_init(uinput_init); | 882 | module_init(uinput_init); |
| 833 | module_exit(uinput_exit); | 883 | module_exit(uinput_exit); |
| 834 | |||
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/hgpk.c b/drivers/input/mouse/hgpk.c index 575f880727fe..62be888e83d0 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
| @@ -334,11 +334,8 @@ static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet) | |||
| 334 | 334 | ||
| 335 | if (!valid) | 335 | if (!valid) |
| 336 | psmouse_dbg(psmouse, | 336 | psmouse_dbg(psmouse, |
| 337 | "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n", | 337 | "bad data, mode %d (%d) %*ph\n", |
| 338 | priv->mode, pktcnt, | 338 | priv->mode, pktcnt, 6, psmouse->packet); |
| 339 | psmouse->packet[0], psmouse->packet[1], | ||
| 340 | psmouse->packet[2], psmouse->packet[3], | ||
| 341 | psmouse->packet[4], psmouse->packet[5]); | ||
| 342 | 339 | ||
| 343 | return valid; | 340 | return valid; |
| 344 | } | 341 | } |
| @@ -1030,7 +1027,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse) | |||
| 1030 | return -EIO; | 1027 | return -EIO; |
| 1031 | } | 1028 | } |
| 1032 | 1029 | ||
| 1033 | psmouse_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]); | 1030 | psmouse_dbg(psmouse, "ID: %*ph\n", 3, param); |
| 1034 | 1031 | ||
| 1035 | /* HGPK signature: 0x67, 0x00, 0x<model> */ | 1032 | /* HGPK signature: 0x67, 0x00, 0x<model> */ |
| 1036 | if (param[0] != 0x67 || param[1] != 0x00) | 1033 | if (param[0] != 0x67 || param[1] != 0x00) |
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index a9e4bfdf31f4..4fe055f2c536 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | 21 | ||
| 22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
| 23 | #include <mach/pxa930_trkball.h> | 23 | #include <linux/platform_data/mouse-pxa930_trkball.h> |
| 24 | 24 | ||
| 25 | /* Trackball Controller Register Definitions */ | 25 | /* Trackball Controller Register Definitions */ |
| 26 | #define TBCR (0x000C) | 26 | #define TBCR (0x000C) |
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 272deddc8db6..21c60fea5d31 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c | |||
| @@ -42,7 +42,7 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id) | |||
| 42 | 42 | ||
| 43 | x = (short) iomd_readl(IOMD_MOUSEX); | 43 | x = (short) iomd_readl(IOMD_MOUSEX); |
| 44 | y = (short) iomd_readl(IOMD_MOUSEY); | 44 | y = (short) iomd_readl(IOMD_MOUSEY); |
| 45 | b = (short) (__raw_readl(0xe0310000) ^ 0x70); | 45 | b = (short) (__raw_readl(IOMEM(0xe0310000)) ^ 0x70); |
| 46 | 46 | ||
| 47 | dx = x - rpcmouse_lastx; | 47 | dx = x - rpcmouse_lastx; |
| 48 | dy = y - rpcmouse_lasty; | 48 | dy = y - rpcmouse_lasty; |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 3f5649f19082..e582922bacf7 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
| @@ -721,6 +721,17 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
| 721 | 721 | ||
| 722 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { | 722 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { |
| 723 | case FSP_PKT_TYPE_ABS: | 723 | case FSP_PKT_TYPE_ABS: |
| 724 | |||
| 725 | if ((packet[0] == 0x48 || packet[0] == 0x49) && | ||
| 726 | packet[1] == 0 && packet[2] == 0) { | ||
| 727 | /* | ||
| 728 | * Ignore coordinate noise when finger leaving the | ||
| 729 | * surface, otherwise cursor may jump to upper-left | ||
| 730 | * corner. | ||
| 731 | */ | ||
| 732 | packet[3] &= 0xf0; | ||
| 733 | } | ||
| 734 | |||
| 724 | abs_x = GET_ABS_X(packet); | 735 | abs_x = GET_ABS_X(packet); |
| 725 | abs_y = GET_ABS_Y(packet); | 736 | abs_y = GET_ABS_Y(packet); |
| 726 | 737 | ||
| @@ -960,7 +971,7 @@ static int fsp_set_input_params(struct psmouse *psmouse) | |||
| 960 | 971 | ||
| 961 | 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); |
| 962 | 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); |
| 963 | input_mt_init_slots(dev, 2); | 974 | input_mt_init_slots(dev, 2, 0); |
| 964 | 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); |
| 965 | 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); |
| 966 | } | 977 | } |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 14eaecea2b70..12d12ca3fee0 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -53,14 +53,19 @@ | |||
| 53 | #define ABS_POS_BITS 13 | 53 | #define ABS_POS_BITS 13 |
| 54 | 54 | ||
| 55 | /* | 55 | /* |
| 56 | * Any position values from the hardware above the following limits are | 56 | * These values should represent the absolute maximum value that will |
| 57 | * treated as "wrapped around negative" values that have been truncated to | 57 | * be reported for a positive position value. Some Synaptics firmware |
| 58 | * the 13-bit reporting range of the hardware. These are just reasonable | 58 | * uses this value to indicate a finger near the edge of the touchpad |
| 59 | * guesses and can be adjusted if hardware is found that operates outside | 59 | * whose precise position cannot be determined. |
| 60 | * of these parameters. | 60 | * |
| 61 | * At least one touchpad is known to report positions in excess of this | ||
| 62 | * value which are actually negative values truncated to the 13-bit | ||
| 63 | * reporting range. These values have never been observed to be lower | ||
| 64 | * than 8184 (i.e. -8), so we treat all values greater than 8176 as | ||
| 65 | * negative and any other value as positive. | ||
| 61 | */ | 66 | */ |
| 62 | #define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2) | 67 | #define X_MAX_POSITIVE 8176 |
| 63 | #define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2) | 68 | #define Y_MAX_POSITIVE 8176 |
| 64 | 69 | ||
| 65 | /***************************************************************************** | 70 | /***************************************************************************** |
| 66 | * Stuff we need even when we do not want native Synaptics support | 71 | * Stuff we need even when we do not want native Synaptics support |
| @@ -604,11 +609,21 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
| 604 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 609 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
| 605 | } | 610 | } |
| 606 | 611 | ||
| 607 | /* Convert wrap-around values to negative */ | 612 | /* |
| 613 | * Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE | ||
| 614 | * is used by some firmware to indicate a finger at the edge of | ||
| 615 | * the touchpad whose precise position cannot be determined, so | ||
| 616 | * convert these values to the maximum axis value. | ||
| 617 | */ | ||
| 608 | if (hw->x > X_MAX_POSITIVE) | 618 | if (hw->x > X_MAX_POSITIVE) |
| 609 | hw->x -= 1 << ABS_POS_BITS; | 619 | hw->x -= 1 << ABS_POS_BITS; |
| 620 | else if (hw->x == X_MAX_POSITIVE) | ||
| 621 | hw->x = XMAX; | ||
| 622 | |||
| 610 | if (hw->y > Y_MAX_POSITIVE) | 623 | if (hw->y > Y_MAX_POSITIVE) |
| 611 | hw->y -= 1 << ABS_POS_BITS; | 624 | hw->y -= 1 << ABS_POS_BITS; |
| 625 | else if (hw->y == Y_MAX_POSITIVE) | ||
| 626 | hw->y = YMAX; | ||
| 612 | 627 | ||
| 613 | return 0; | 628 | return 0; |
| 614 | } | 629 | } |
| @@ -1232,7 +1247,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); | 1247 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
| 1233 | 1248 | ||
| 1234 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | 1249 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { |
| 1235 | input_mt_init_slots(dev, 2); | 1250 | input_mt_init_slots(dev, 2, 0); |
| 1236 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1251 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
| 1237 | ABS_MT_POSITION_Y); | 1252 | ABS_MT_POSITION_Y); |
| 1238 | /* Image sensors can report per-contact pressure */ | 1253 | /* Image sensors can report per-contact pressure */ |
| @@ -1244,7 +1259,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)) { | 1259 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
| 1245 | /* Non-image sensors with AGM use semi-mt */ | 1260 | /* Non-image sensors with AGM use semi-mt */ |
| 1246 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 1261 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
| 1247 | input_mt_init_slots(dev, 2); | 1262 | input_mt_init_slots(dev, 2, 0); |
| 1248 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1263 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
| 1249 | ABS_MT_POSITION_Y); | 1264 | ABS_MT_POSITION_Y); |
| 1250 | } | 1265 | } |
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index f14675702c0f..063a174d3a88 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
| @@ -376,12 +376,7 @@ static void synaptics_i2c_reschedule_work(struct synaptics_i2c *touch, | |||
| 376 | 376 | ||
| 377 | spin_lock_irqsave(&touch->lock, flags); | 377 | spin_lock_irqsave(&touch->lock, flags); |
| 378 | 378 | ||
| 379 | /* | 379 | mod_delayed_work(system_wq, &touch->dwork, delay); |
| 380 | * If work is already scheduled then subsequent schedules will not | ||
| 381 | * change the scheduled time that's why we have to cancel it first. | ||
| 382 | */ | ||
| 383 | __cancel_delayed_work(&touch->dwork); | ||
| 384 | schedule_delayed_work(&touch->dwork, delay); | ||
| 385 | 380 | ||
| 386 | spin_unlock_irqrestore(&touch->lock, flags); | 381 | spin_unlock_irqrestore(&touch->lock, flags); |
| 387 | } | 382 | } |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 0110b5a3a167..964e43d81e29 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
| @@ -551,17 +551,16 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
| 551 | return -ENODEV; | 551 | return -ENODEV; |
| 552 | 552 | ||
| 553 | error = mutex_lock_interruptible(&mousedev_table_mutex); | 553 | error = mutex_lock_interruptible(&mousedev_table_mutex); |
| 554 | if (error) { | 554 | if (error) |
| 555 | return error; | 555 | return error; |
| 556 | } | 556 | |
| 557 | mousedev = mousedev_table[i]; | 557 | mousedev = mousedev_table[i]; |
| 558 | if (mousedev) | 558 | if (mousedev) |
| 559 | get_device(&mousedev->dev); | 559 | get_device(&mousedev->dev); |
| 560 | mutex_unlock(&mousedev_table_mutex); | 560 | mutex_unlock(&mousedev_table_mutex); |
| 561 | 561 | ||
| 562 | if (!mousedev) { | 562 | if (!mousedev) |
| 563 | return -ENODEV; | 563 | return -ENODEV; |
| 564 | } | ||
| 565 | 564 | ||
| 566 | client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); | 565 | client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); |
| 567 | if (!client) { | 566 | if (!client) { |
| @@ -1088,7 +1087,7 @@ static int __init mousedev_init(void) | |||
| 1088 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 1087 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
| 1089 | error = misc_register(&psaux_mouse); | 1088 | error = misc_register(&psaux_mouse); |
| 1090 | if (error) | 1089 | if (error) |
| 1091 | pr_warning("could not register psaux device, error: %d\n", | 1090 | pr_warn("could not register psaux device, error: %d\n", |
| 1092 | error); | 1091 | error); |
| 1093 | else | 1092 | else |
| 1094 | psaux_registered = 1; | 1093 | psaux_registered = 1; |
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 2ffd110bd5bc..2e77246c2e5a 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c | |||
| @@ -72,7 +72,7 @@ static int amba_kmi_open(struct serio *io) | |||
| 72 | unsigned int divisor; | 72 | unsigned int divisor; |
| 73 | int ret; | 73 | int ret; |
| 74 | 74 | ||
| 75 | ret = clk_enable(kmi->clk); | 75 | ret = clk_prepare_enable(kmi->clk); |
| 76 | if (ret) | 76 | if (ret) |
| 77 | goto out; | 77 | goto out; |
| 78 | 78 | ||
| @@ -92,7 +92,7 @@ static int amba_kmi_open(struct serio *io) | |||
| 92 | return 0; | 92 | return 0; |
| 93 | 93 | ||
| 94 | clk_disable: | 94 | clk_disable: |
| 95 | clk_disable(kmi->clk); | 95 | clk_disable_unprepare(kmi->clk); |
| 96 | out: | 96 | out: |
| 97 | return ret; | 97 | return ret; |
| 98 | } | 98 | } |
| @@ -104,7 +104,7 @@ static void amba_kmi_close(struct serio *io) | |||
| 104 | writeb(0, KMICR); | 104 | writeb(0, KMICR); |
| 105 | 105 | ||
| 106 | free_irq(kmi->irq, kmi); | 106 | free_irq(kmi->irq, kmi); |
| 107 | clk_disable(kmi->clk); | 107 | clk_disable_unprepare(kmi->clk); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static int __devinit amba_kmi_probe(struct amba_device *dev, | 110 | static int __devinit amba_kmi_probe(struct amba_device *dev, |
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index f5fbdf94de3b..45887e31242a 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | 28 | ||
| 29 | #include <asm/mach-types.h> | 29 | #include <asm/mach-types.h> |
| 30 | #include <plat/board-ams-delta.h> | 30 | #include <mach/board-ams-delta.h> |
| 31 | 31 | ||
| 32 | #include <mach/ams-delta-fiq.h> | 32 | #include <mach/ams-delta-fiq.h> |
| 33 | 33 | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5ec774d6c82b..d6cc77a53c7e 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
| @@ -177,6 +177,20 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { | |||
| 177 | }, | 177 | }, |
| 178 | }, | 178 | }, |
| 179 | { | 179 | { |
| 180 | /* Gigabyte T1005 - defines wrong chassis type ("Other") */ | ||
| 181 | .matches = { | ||
| 182 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
| 183 | DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), | ||
| 184 | }, | ||
| 185 | }, | ||
| 186 | { | ||
| 187 | /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ | ||
| 188 | .matches = { | ||
| 189 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
| 190 | DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), | ||
| 191 | }, | ||
| 192 | }, | ||
| 193 | { | ||
| 180 | .matches = { | 194 | .matches = { |
| 181 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 195 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
| 182 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), | 196 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), |
| @@ -321,6 +335,12 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | |||
| 321 | }, | 335 | }, |
| 322 | { | 336 | { |
| 323 | .matches = { | 337 | .matches = { |
| 338 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 339 | DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), | ||
| 340 | }, | ||
| 341 | }, | ||
| 342 | { | ||
| 343 | .matches = { | ||
| 324 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), | 344 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), |
| 325 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), | 345 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), |
| 326 | }, | 346 | }, |
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index 75fb040a3435..a70aa555bbff 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c | |||
| @@ -180,11 +180,11 @@ int sparse_keymap_setup(struct input_dev *dev, | |||
| 180 | for (e = keymap; e->type != KE_END; e++) | 180 | for (e = keymap; e->type != KE_END; e++) |
| 181 | map_size++; | 181 | map_size++; |
| 182 | 182 | ||
| 183 | map = kcalloc(map_size, sizeof (struct key_entry), GFP_KERNEL); | 183 | map = kcalloc(map_size, sizeof(struct key_entry), GFP_KERNEL); |
| 184 | if (!map) | 184 | if (!map) |
| 185 | return -ENOMEM; | 185 | return -ENOMEM; |
| 186 | 186 | ||
| 187 | memcpy(map, keymap, map_size * sizeof (struct key_entry)); | 187 | memcpy(map, keymap, map_size * sizeof(struct key_entry)); |
| 188 | 188 | ||
| 189 | for (i = 0; i < map_size; i++) { | 189 | for (i = 0; i < map_size; i++) { |
| 190 | entry = &map[i]; | 190 | entry = &map[i]; |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 002041975de9..08b462b6c0d8 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -606,7 +606,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 606 | input_report_abs(input, ABS_WHEEL, 0); | 606 | input_report_abs(input, ABS_WHEEL, 0); |
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | if (data[2] | (data[3] & 0x01) | data[4]) { | 609 | if (data[2] | (data[3] & 0x01) | data[4] | data[5]) { |
| 610 | input_report_key(input, wacom->tool[1], 1); | 610 | input_report_key(input, wacom->tool[1], 1); |
| 611 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | 611 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); |
| 612 | } else { | 612 | } else { |
| @@ -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, |
| @@ -1848,7 +1848,10 @@ static const struct wacom_features wacom_features_0x2A = | |||
| 1848 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, | 1848 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, |
| 1849 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1849 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
| 1850 | static const struct wacom_features wacom_features_0xF4 = | 1850 | static const struct wacom_features wacom_features_0xF4 = |
| 1851 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | 1851 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, |
| 1852 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
| 1853 | static const struct wacom_features wacom_features_0xF8 = | ||
| 1854 | { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | ||
| 1852 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1855 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
| 1853 | static const struct wacom_features wacom_features_0x3F = | 1856 | static const struct wacom_features wacom_features_0x3F = |
| 1854 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, | 1857 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, |
| @@ -2091,6 +2094,7 @@ const struct usb_device_id wacom_ids[] = { | |||
| 2091 | { USB_DEVICE_WACOM(0xEF) }, | 2094 | { USB_DEVICE_WACOM(0xEF) }, |
| 2092 | { USB_DEVICE_WACOM(0x47) }, | 2095 | { USB_DEVICE_WACOM(0x47) }, |
| 2093 | { USB_DEVICE_WACOM(0xF4) }, | 2096 | { USB_DEVICE_WACOM(0xF4) }, |
| 2097 | { USB_DEVICE_WACOM(0xF8) }, | ||
| 2094 | { USB_DEVICE_WACOM(0xFA) }, | 2098 | { USB_DEVICE_WACOM(0xFA) }, |
| 2095 | { USB_DEVICE_LENOVO(0x6004) }, | 2099 | { USB_DEVICE_LENOVO(0x6004) }, |
| 2096 | { } | 2100 | { } |
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c index 05f30b73c3c3..326218dbd6e6 100644 --- a/drivers/input/touchscreen/88pm860x-ts.c +++ b/drivers/input/touchscreen/88pm860x-ts.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | */ | 10 | */ |
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/of.h> | ||
| 13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 14 | #include <linux/i2c.h> | 15 | #include <linux/i2c.h> |
| 15 | #include <linux/input.h> | 16 | #include <linux/input.h> |
| @@ -113,14 +114,69 @@ static void pm860x_touch_close(struct input_dev *dev) | |||
| 113 | pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); | 114 | pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 117 | #ifdef CONFIG_OF | ||
| 118 | static int __devinit pm860x_touch_dt_init(struct platform_device *pdev, | ||
| 119 | struct pm860x_chip *chip, | ||
| 120 | int *res_x) | ||
| 121 | { | ||
| 122 | struct device_node *np = pdev->dev.parent->of_node; | ||
| 123 | struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ | ||
| 124 | : chip->companion; | ||
| 125 | int data, n, ret; | ||
| 126 | if (!np) | ||
| 127 | return -ENODEV; | ||
| 128 | np = of_find_node_by_name(np, "touch"); | ||
| 129 | if (!np) { | ||
| 130 | dev_err(&pdev->dev, "Can't find touch node\n"); | ||
| 131 | return -EINVAL; | ||
| 132 | } | ||
| 133 | /* set GPADC MISC1 register */ | ||
| 134 | data = 0; | ||
| 135 | if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-prebias", &n)) | ||
| 136 | data |= (n << 1) & PM8607_GPADC_PREBIAS_MASK; | ||
| 137 | if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-slot-cycle", &n)) | ||
| 138 | data |= (n << 3) & PM8607_GPADC_SLOT_CYCLE_MASK; | ||
| 139 | if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-off-scale", &n)) | ||
| 140 | data |= (n << 5) & PM8607_GPADC_OFF_SCALE_MASK; | ||
| 141 | if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-sw-cal", &n)) | ||
| 142 | data |= (n << 7) & PM8607_GPADC_SW_CAL_MASK; | ||
| 143 | if (data) { | ||
| 144 | ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data); | ||
| 145 | if (ret < 0) | ||
| 146 | return -EINVAL; | ||
| 147 | } | ||
| 148 | /* set tsi prebias time */ | ||
| 149 | if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) { | ||
| 150 | ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data); | ||
| 151 | if (ret < 0) | ||
| 152 | return -EINVAL; | ||
| 153 | } | ||
| 154 | /* set prebias & prechg time of pen detect */ | ||
| 155 | data = 0; | ||
| 156 | if (!of_property_read_u32(np, "marvell,88pm860x-pen-prebias", &n)) | ||
| 157 | data |= n & PM8607_PD_PREBIAS_MASK; | ||
| 158 | if (!of_property_read_u32(np, "marvell,88pm860x-pen-prechg", &n)) | ||
| 159 | data |= n & PM8607_PD_PRECHG_MASK; | ||
| 160 | if (data) { | ||
| 161 | ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data); | ||
| 162 | if (ret < 0) | ||
| 163 | return -EINVAL; | ||
| 164 | } | ||
| 165 | of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x); | ||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | #else | ||
| 169 | #define pm860x_touch_dt_init(x, y, z) (-1) | ||
| 170 | #endif | ||
| 171 | |||
| 116 | static int __devinit pm860x_touch_probe(struct platform_device *pdev) | 172 | static int __devinit pm860x_touch_probe(struct platform_device *pdev) |
| 117 | { | 173 | { |
| 118 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | 174 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
| 119 | struct pm860x_platform_data *pm860x_pdata = \ | 175 | struct pm860x_touch_pdata *pdata = pdev->dev.platform_data; |
| 120 | pdev->dev.parent->platform_data; | ||
| 121 | struct pm860x_touch_pdata *pdata = NULL; | ||
| 122 | struct pm860x_touch *touch; | 176 | struct pm860x_touch *touch; |
| 123 | int irq, ret; | 177 | struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ |
| 178 | : chip->companion; | ||
| 179 | int irq, ret, res_x = 0, data = 0; | ||
| 124 | 180 | ||
| 125 | irq = platform_get_irq(pdev, 0); | 181 | irq = platform_get_irq(pdev, 0); |
| 126 | if (irq < 0) { | 182 | if (irq < 0) { |
| @@ -128,16 +184,55 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) | |||
| 128 | return -EINVAL; | 184 | return -EINVAL; |
| 129 | } | 185 | } |
| 130 | 186 | ||
| 131 | if (!pm860x_pdata) { | 187 | if (pm860x_touch_dt_init(pdev, chip, &res_x)) { |
| 132 | dev_err(&pdev->dev, "platform data is missing\n"); | 188 | if (pdata) { |
| 133 | return -EINVAL; | 189 | /* set GPADC MISC1 register */ |
| 134 | } | 190 | data = 0; |
| 135 | 191 | data |= (pdata->gpadc_prebias << 1) | |
| 136 | pdata = pm860x_pdata->touch; | 192 | & PM8607_GPADC_PREBIAS_MASK; |
| 137 | if (!pdata) { | 193 | data |= (pdata->slot_cycle << 3) |
| 138 | dev_err(&pdev->dev, "touchscreen data is missing\n"); | 194 | & PM8607_GPADC_SLOT_CYCLE_MASK; |
| 139 | return -EINVAL; | 195 | data |= (pdata->off_scale << 5) |
| 196 | & PM8607_GPADC_OFF_SCALE_MASK; | ||
| 197 | data |= (pdata->sw_cal << 7) | ||
| 198 | & PM8607_GPADC_SW_CAL_MASK; | ||
| 199 | if (data) { | ||
| 200 | ret = pm860x_reg_write(i2c, | ||
| 201 | PM8607_GPADC_MISC1, data); | ||
| 202 | if (ret < 0) | ||
| 203 | return -EINVAL; | ||
| 204 | } | ||
| 205 | /* set tsi prebias time */ | ||
| 206 | if (pdata->tsi_prebias) { | ||
| 207 | data = pdata->tsi_prebias; | ||
| 208 | ret = pm860x_reg_write(i2c, | ||
| 209 | PM8607_TSI_PREBIAS, data); | ||
| 210 | if (ret < 0) | ||
| 211 | return -EINVAL; | ||
| 212 | } | ||
| 213 | /* set prebias & prechg time of pen detect */ | ||
| 214 | data = 0; | ||
| 215 | data |= pdata->pen_prebias | ||
| 216 | & PM8607_PD_PREBIAS_MASK; | ||
| 217 | data |= (pdata->pen_prechg << 5) | ||
| 218 | & PM8607_PD_PRECHG_MASK; | ||
| 219 | if (data) { | ||
| 220 | ret = pm860x_reg_write(i2c, | ||
| 221 | PM8607_PD_PREBIAS, data); | ||
| 222 | if (ret < 0) | ||
| 223 | return -EINVAL; | ||
| 224 | } | ||
| 225 | res_x = pdata->res_x; | ||
| 226 | } else { | ||
| 227 | dev_err(&pdev->dev, "failed to get platform data\n"); | ||
| 228 | return -EINVAL; | ||
| 229 | } | ||
| 140 | } | 230 | } |
| 231 | /* enable GPADC */ | ||
| 232 | ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, PM8607_GPADC_EN, | ||
| 233 | PM8607_GPADC_EN); | ||
| 234 | if (ret) | ||
| 235 | return ret; | ||
| 141 | 236 | ||
| 142 | touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); | 237 | touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); |
| 143 | if (touch == NULL) | 238 | if (touch == NULL) |
| @@ -158,9 +253,9 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) | |||
| 158 | touch->idev->open = pm860x_touch_open; | 253 | touch->idev->open = pm860x_touch_open; |
| 159 | touch->idev->close = pm860x_touch_close; | 254 | touch->idev->close = pm860x_touch_close; |
| 160 | touch->chip = chip; | 255 | touch->chip = chip; |
| 161 | touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | 256 | touch->i2c = i2c; |
| 162 | touch->irq = irq + chip->irq_base; | 257 | touch->irq = irq; |
| 163 | touch->res_x = pdata->res_x; | 258 | touch->res_x = res_x; |
| 164 | input_set_drvdata(touch->idev, touch); | 259 | input_set_drvdata(touch->idev, touch); |
| 165 | 260 | ||
| 166 | ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, | 261 | ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, |
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..099d144ab7c9 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
| @@ -566,9 +566,12 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file, | |||
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | read = min_t(size_t, count, tsdata->raw_bufsize - *off); | 568 | read = min_t(size_t, count, tsdata->raw_bufsize - *off); |
| 569 | error = copy_to_user(buf, tsdata->raw_buffer + *off, read); | 569 | if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) { |
| 570 | if (!error) | 570 | error = -EFAULT; |
| 571 | *off += read; | 571 | goto out; |
| 572 | } | ||
| 573 | |||
| 574 | *off += read; | ||
| 572 | out: | 575 | out: |
| 573 | mutex_unlock(&tsdata->mutex); | 576 | mutex_unlock(&tsdata->mutex); |
| 574 | return error ?: read; | 577 | return error ?: read; |
| @@ -602,6 +605,7 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata) | |||
| 602 | { | 605 | { |
| 603 | if (tsdata->debug_dir) | 606 | if (tsdata->debug_dir) |
| 604 | debugfs_remove_recursive(tsdata->debug_dir); | 607 | debugfs_remove_recursive(tsdata->debug_dir); |
| 608 | kfree(tsdata->raw_buffer); | ||
| 605 | } | 609 | } |
| 606 | 610 | ||
| 607 | #else | 611 | #else |
| @@ -778,7 +782,7 @@ static int __devinit edt_ft5x06_ts_probe(struct i2c_client *client, | |||
| 778 | 0, tsdata->num_x * 64 - 1, 0, 0); | 782 | 0, tsdata->num_x * 64 - 1, 0, 0); |
| 779 | input_set_abs_params(input, ABS_MT_POSITION_Y, | 783 | input_set_abs_params(input, ABS_MT_POSITION_Y, |
| 780 | 0, tsdata->num_y * 64 - 1, 0, 0); | 784 | 0, tsdata->num_y * 64 - 1, 0, 0); |
| 781 | error = input_mt_init_slots(input, MAX_SUPPORT_POINTS); | 785 | error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0); |
| 782 | if (error) { | 786 | if (error) { |
| 783 | dev_err(&client->dev, "Unable to init MT slots.\n"); | 787 | dev_err(&client->dev, "Unable to init MT slots.\n"); |
| 784 | goto err_free_mem; | 788 | goto err_free_mem; |
| @@ -843,7 +847,6 @@ static int __devexit edt_ft5x06_ts_remove(struct i2c_client *client) | |||
| 843 | if (gpio_is_valid(pdata->reset_pin)) | 847 | if (gpio_is_valid(pdata->reset_pin)) |
| 844 | gpio_free(pdata->reset_pin); | 848 | gpio_free(pdata->reset_pin); |
| 845 | 849 | ||
| 846 | kfree(tsdata->raw_buffer); | ||
| 847 | kfree(tsdata); | 850 | kfree(tsdata); |
| 848 | 851 | ||
| 849 | return 0; | 852 | return 0; |
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/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index bf1a06400067..549fa29548f8 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | #include <plat/adc.h> | 38 | #include <plat/adc.h> |
| 39 | #include <plat/regs-adc.h> | 39 | #include <plat/regs-adc.h> |
| 40 | #include <plat/ts.h> | 40 | #include <linux/platform_data/touchscreen-s3c2410.h> |
| 41 | 41 | ||
| 42 | #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) | 42 | #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) |
| 43 | 43 | ||
| @@ -406,7 +406,7 @@ static int s3c2410ts_resume(struct device *dev) | |||
| 406 | return 0; | 406 | return 0; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | static struct dev_pm_ops s3c_ts_pmops = { | 409 | static const struct dev_pm_ops s3c_ts_pmops = { |
| 410 | .suspend = s3c2410ts_suspend, | 410 | .suspend = s3c2410ts_suspend, |
| 411 | .resume = s3c2410ts_resume, | 411 | .resume = s3c2410ts_resume, |
| 412 | }; | 412 | }; |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index e32709e0dd65..721fdb3597ca 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
| @@ -304,6 +304,45 @@ static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
| 304 | #define EGALAX_PKT_TYPE_REPT 0x80 | 304 | #define EGALAX_PKT_TYPE_REPT 0x80 |
| 305 | #define EGALAX_PKT_TYPE_DIAG 0x0A | 305 | #define EGALAX_PKT_TYPE_DIAG 0x0A |
| 306 | 306 | ||
| 307 | static int egalax_init(struct usbtouch_usb *usbtouch) | ||
| 308 | { | ||
| 309 | int ret, i; | ||
| 310 | unsigned char *buf; | ||
| 311 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
| 312 | |||
| 313 | /* | ||
| 314 | * An eGalax diagnostic packet kicks the device into using the right | ||
| 315 | * protocol. We send a "check active" packet. The response will be | ||
| 316 | * read later and ignored. | ||
| 317 | */ | ||
| 318 | |||
| 319 | buf = kmalloc(3, GFP_KERNEL); | ||
| 320 | if (!buf) | ||
| 321 | return -ENOMEM; | ||
| 322 | |||
| 323 | buf[0] = EGALAX_PKT_TYPE_DIAG; | ||
| 324 | buf[1] = 1; /* length */ | ||
| 325 | buf[2] = 'A'; /* command - check active */ | ||
| 326 | |||
| 327 | for (i = 0; i < 3; i++) { | ||
| 328 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
| 329 | 0, | ||
| 330 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 331 | 0, 0, buf, 3, | ||
| 332 | USB_CTRL_SET_TIMEOUT); | ||
| 333 | if (ret >= 0) { | ||
| 334 | ret = 0; | ||
| 335 | break; | ||
| 336 | } | ||
| 337 | if (ret != -EPIPE) | ||
| 338 | break; | ||
| 339 | } | ||
| 340 | |||
| 341 | kfree(buf); | ||
| 342 | |||
| 343 | return ret; | ||
| 344 | } | ||
| 345 | |||
| 307 | static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 346 | static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
| 308 | { | 347 | { |
| 309 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) | 348 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) |
| @@ -1056,6 +1095,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
| 1056 | .process_pkt = usbtouch_process_multi, | 1095 | .process_pkt = usbtouch_process_multi, |
| 1057 | .get_pkt_len = egalax_get_pkt_len, | 1096 | .get_pkt_len = egalax_get_pkt_len, |
| 1058 | .read_data = egalax_read_data, | 1097 | .read_data = egalax_read_data, |
| 1098 | .init = egalax_init, | ||
| 1059 | }, | 1099 | }, |
| 1060 | #endif | 1100 | #endif |
| 1061 | 1101 | ||
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, |
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c index e83410721e38..52abb98a8ae5 100644 --- a/drivers/input/touchscreen/wm831x-ts.c +++ b/drivers/input/touchscreen/wm831x-ts.c | |||
| @@ -221,7 +221,7 @@ static void wm831x_ts_input_close(struct input_dev *idev) | |||
| 221 | synchronize_irq(wm831x_ts->pd_irq); | 221 | synchronize_irq(wm831x_ts->pd_irq); |
| 222 | 222 | ||
| 223 | /* Make sure the IRQ completion work is quiesced */ | 223 | /* Make sure the IRQ completion work is quiesced */ |
| 224 | flush_work_sync(&wm831x_ts->pd_data_work); | 224 | flush_work(&wm831x_ts->pd_data_work); |
| 225 | 225 | ||
| 226 | /* If we ended up with the pen down then make sure we revert back | 226 | /* If we ended up with the pen down then make sure we revert back |
| 227 | * to pen detection state for the next time we start up. | 227 | * to pen detection state for the next time we start up. |
