diff options
Diffstat (limited to 'drivers/input')
150 files changed, 8487 insertions, 2952 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index cd50c00ab20f..07c2cd43109c 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig | |||
@@ -8,7 +8,7 @@ menu "Input device support" | |||
8 | config INPUT | 8 | config INPUT |
9 | tristate "Generic input layer (needed for keyboard, mouse, ...)" if EMBEDDED | 9 | tristate "Generic input layer (needed for keyboard, mouse, ...)" if EMBEDDED |
10 | default y | 10 | default y |
11 | ---help--- | 11 | help |
12 | Say Y here if you have any input device (mouse, keyboard, tablet, | 12 | Say Y here if you have any input device (mouse, keyboard, tablet, |
13 | joystick, steering wheel ...) connected to your system and want | 13 | joystick, steering wheel ...) connected to your system and want |
14 | it to be available to applications. This includes standard PS/2 | 14 | it to be available to applications. This includes standard PS/2 |
@@ -27,8 +27,7 @@ if INPUT | |||
27 | 27 | ||
28 | config INPUT_FF_MEMLESS | 28 | config INPUT_FF_MEMLESS |
29 | tristate "Support for memoryless force-feedback devices" | 29 | tristate "Support for memoryless force-feedback devices" |
30 | default n | 30 | help |
31 | ---help--- | ||
32 | Say Y here if you have memoryless force-feedback input device | 31 | Say Y here if you have memoryless force-feedback input device |
33 | such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual | 32 | such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual |
34 | Power 2, or similar. You will also need to enable hardware-specific | 33 | Power 2, or similar. You will also need to enable hardware-specific |
@@ -52,12 +51,25 @@ config INPUT_POLLDEV | |||
52 | To compile this driver as a module, choose M here: the | 51 | To compile this driver as a module, choose M here: the |
53 | module will be called input-polldev. | 52 | module will be called input-polldev. |
54 | 53 | ||
54 | config INPUT_SPARSEKMAP | ||
55 | tristate "Sparse keymap support library" | ||
56 | help | ||
57 | Say Y here if you are using a driver for an input | ||
58 | device that uses sparse keymap. This option is only | ||
59 | useful for out-of-tree drivers since in-tree drivers | ||
60 | select it automatically. | ||
61 | |||
62 | If unsure, say N. | ||
63 | |||
64 | To compile this driver as a module, choose M here: the | ||
65 | module will be called sparse-keymap. | ||
66 | |||
55 | comment "Userland interfaces" | 67 | comment "Userland interfaces" |
56 | 68 | ||
57 | config INPUT_MOUSEDEV | 69 | config INPUT_MOUSEDEV |
58 | tristate "Mouse interface" if EMBEDDED | 70 | tristate "Mouse interface" if EMBEDDED |
59 | default y | 71 | default y |
60 | ---help--- | 72 | help |
61 | Say Y here if you want your mouse to be accessible as char devices | 73 | Say Y here if you want your mouse to be accessible as char devices |
62 | 13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an | 74 | 13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an |
63 | emulated IntelliMouse Explorer PS/2 mouse. That way, all user space | 75 | emulated IntelliMouse Explorer PS/2 mouse. That way, all user space |
@@ -73,7 +85,7 @@ config INPUT_MOUSEDEV_PSAUX | |||
73 | bool "Provide legacy /dev/psaux device" | 85 | bool "Provide legacy /dev/psaux device" |
74 | default y | 86 | default y |
75 | depends on INPUT_MOUSEDEV | 87 | depends on INPUT_MOUSEDEV |
76 | ---help--- | 88 | help |
77 | Say Y here if you want your mouse also be accessible as char device | 89 | Say Y here if you want your mouse also be accessible as char device |
78 | 10:1 - /dev/psaux. The data available through /dev/psaux is exactly | 90 | 10:1 - /dev/psaux. The data available through /dev/psaux is exactly |
79 | the same as the data from /dev/input/mice. | 91 | the same as the data from /dev/input/mice. |
@@ -103,7 +115,7 @@ config INPUT_MOUSEDEV_SCREEN_Y | |||
103 | 115 | ||
104 | config INPUT_JOYDEV | 116 | config INPUT_JOYDEV |
105 | tristate "Joystick interface" | 117 | tristate "Joystick interface" |
106 | ---help--- | 118 | help |
107 | Say Y here if you want your joystick or gamepad to be | 119 | Say Y here if you want your joystick or gamepad to be |
108 | accessible as char device 13:0+ - /dev/input/jsX device. | 120 | accessible as char device 13:0+ - /dev/input/jsX device. |
109 | 121 | ||
@@ -125,7 +137,7 @@ config INPUT_EVDEV | |||
125 | 137 | ||
126 | config INPUT_EVBUG | 138 | config INPUT_EVBUG |
127 | tristate "Event debugging" | 139 | tristate "Event debugging" |
128 | ---help--- | 140 | help |
129 | Say Y here if you have a problem with the input subsystem and | 141 | Say Y here if you have a problem with the input subsystem and |
130 | want all events (keypresses, mouse movements), to be output to | 142 | want all events (keypresses, mouse movements), to be output to |
131 | the system log. While this is useful for debugging, it's also | 143 | the system log. While this is useful for debugging, it's also |
@@ -140,7 +152,7 @@ config INPUT_EVBUG | |||
140 | config INPUT_APMPOWER | 152 | config INPUT_APMPOWER |
141 | tristate "Input Power Event -> APM Bridge" if EMBEDDED | 153 | tristate "Input Power Event -> APM Bridge" if EMBEDDED |
142 | depends on INPUT && APM_EMULATION | 154 | depends on INPUT && APM_EMULATION |
143 | ---help--- | 155 | help |
144 | Say Y here if you want suspend key events to trigger a user | 156 | Say Y here if you want suspend key events to trigger a user |
145 | requested suspend through APM. This is useful on embedded | 157 | requested suspend through APM. This is useful on embedded |
146 | systems where such behaviour is desired without userspace | 158 | systems where such behaviour is desired without userspace |
@@ -153,6 +165,7 @@ config XEN_KBDDEV_FRONTEND | |||
153 | tristate "Xen virtual keyboard and mouse support" | 165 | tristate "Xen virtual keyboard and mouse support" |
154 | depends on XEN_FBDEV_FRONTEND | 166 | depends on XEN_FBDEV_FRONTEND |
155 | default y | 167 | default y |
168 | select XEN_XENBUS_FRONTEND | ||
156 | help | 169 | help |
157 | This driver implements the front-end of the Xen virtual | 170 | This driver implements the front-end of the Xen virtual |
158 | keyboard and mouse device driver. It communicates with a back-end | 171 | keyboard and mouse device driver. It communicates with a back-end |
diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 4c9c745a7020..7ad212d31f99 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile | |||
@@ -9,6 +9,7 @@ input-core-objs := input.o input-compat.o ff-core.o | |||
9 | 9 | ||
10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o | 10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o |
11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o | 11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o |
12 | obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o | ||
12 | 13 | ||
13 | obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o | 14 | obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o |
14 | obj-$(CONFIG_INPUT_JOYDEV) += joydev.o | 15 | obj-$(CONFIG_INPUT_JOYDEV) += joydev.o |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index dee6706038aa..2ee6c7a68bdc 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -59,7 +59,8 @@ static void evdev_pass_event(struct evdev_client *client, | |||
59 | client->head &= EVDEV_BUFFER_SIZE - 1; | 59 | client->head &= EVDEV_BUFFER_SIZE - 1; |
60 | spin_unlock(&client->buffer_lock); | 60 | spin_unlock(&client->buffer_lock); |
61 | 61 | ||
62 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | 62 | if (event->type == EV_SYN) |
63 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | ||
63 | } | 64 | } |
64 | 65 | ||
65 | /* | 66 | /* |
@@ -277,6 +278,8 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
277 | goto err_free_client; | 278 | goto err_free_client; |
278 | 279 | ||
279 | file->private_data = client; | 280 | file->private_data = client; |
281 | nonseekable_open(inode, file); | ||
282 | |||
280 | return 0; | 283 | return 0; |
281 | 284 | ||
282 | err_free_client: | 285 | err_free_client: |
@@ -512,7 +515,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
512 | struct input_absinfo abs; | 515 | struct input_absinfo abs; |
513 | struct ff_effect effect; | 516 | struct ff_effect effect; |
514 | int __user *ip = (int __user *)p; | 517 | int __user *ip = (int __user *)p; |
515 | int i, t, u, v; | 518 | unsigned int i, t, u, v; |
516 | int error; | 519 | int error; |
517 | 520 | ||
518 | switch (cmd) { | 521 | switch (cmd) { |
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 38df81fcdc3a..03078c08309a 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
32 | #include <linux/slab.h> | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * Check that the effect_id is a valid effect and whether the user | 35 | * Check that the effect_id is a valid effect and whether the user |
@@ -353,7 +354,7 @@ int input_ff_create(struct input_dev *dev, int max_effects) | |||
353 | EXPORT_SYMBOL_GPL(input_ff_create); | 354 | EXPORT_SYMBOL_GPL(input_ff_create); |
354 | 355 | ||
355 | /** | 356 | /** |
356 | * input_ff_free() - frees force feedback portion of input device | 357 | * input_ff_destroy() - frees force feedback portion of input device |
357 | * @dev: input device supporting force feedback | 358 | * @dev: input device supporting force feedback |
358 | * | 359 | * |
359 | * This function is only needed in error path as input core will | 360 | * This function is only needed in error path as input core will |
@@ -369,6 +370,7 @@ void input_ff_destroy(struct input_dev *dev) | |||
369 | if (ff->destroy) | 370 | if (ff->destroy) |
370 | ff->destroy(ff); | 371 | ff->destroy(ff); |
371 | kfree(ff->private); | 372 | kfree(ff->private); |
373 | kfree(ff->effects); | ||
372 | kfree(ff); | 374 | kfree(ff); |
373 | dev->ff = NULL; | 375 | dev->ff = NULL; |
374 | } | 376 | } |
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index b483b2995fa9..1d881c96ba8f 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg) | 26 | #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg) |
27 | 27 | ||
28 | #include <linux/slab.h> | ||
28 | #include <linux/input.h> | 29 | #include <linux/input.h> |
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
@@ -221,11 +222,27 @@ static int get_compatible_type(struct ff_device *ff, int effect_type) | |||
221 | } | 222 | } |
222 | 223 | ||
223 | /* | 224 | /* |
225 | * Only left/right direction should be used (under/over 0x8000) for | ||
226 | * forward/reverse motor direction (to keep calculation fast & simple). | ||
227 | */ | ||
228 | static u16 ml_calculate_direction(u16 direction, u16 force, | ||
229 | u16 new_direction, u16 new_force) | ||
230 | { | ||
231 | if (!force) | ||
232 | return new_direction; | ||
233 | if (!new_force) | ||
234 | return direction; | ||
235 | return (((u32)(direction >> 1) * force + | ||
236 | (new_direction >> 1) * new_force) / | ||
237 | (force + new_force)) << 1; | ||
238 | } | ||
239 | |||
240 | /* | ||
224 | * Combine two effects and apply gain. | 241 | * Combine two effects and apply gain. |
225 | */ | 242 | */ |
226 | static void ml_combine_effects(struct ff_effect *effect, | 243 | static void ml_combine_effects(struct ff_effect *effect, |
227 | struct ml_effect_state *state, | 244 | struct ml_effect_state *state, |
228 | unsigned int gain) | 245 | int gain) |
229 | { | 246 | { |
230 | struct ff_effect *new = state->effect; | 247 | struct ff_effect *new = state->effect; |
231 | unsigned int strong, weak, i; | 248 | unsigned int strong, weak, i; |
@@ -252,8 +269,21 @@ static void ml_combine_effects(struct ff_effect *effect, | |||
252 | break; | 269 | break; |
253 | 270 | ||
254 | case FF_RUMBLE: | 271 | case FF_RUMBLE: |
255 | strong = new->u.rumble.strong_magnitude * gain / 0xffff; | 272 | strong = (u32)new->u.rumble.strong_magnitude * gain / 0xffff; |
256 | weak = new->u.rumble.weak_magnitude * gain / 0xffff; | 273 | weak = (u32)new->u.rumble.weak_magnitude * gain / 0xffff; |
274 | |||
275 | if (effect->u.rumble.strong_magnitude + strong) | ||
276 | effect->direction = ml_calculate_direction( | ||
277 | effect->direction, | ||
278 | effect->u.rumble.strong_magnitude, | ||
279 | new->direction, strong); | ||
280 | else if (effect->u.rumble.weak_magnitude + weak) | ||
281 | effect->direction = ml_calculate_direction( | ||
282 | effect->direction, | ||
283 | effect->u.rumble.weak_magnitude, | ||
284 | new->direction, weak); | ||
285 | else | ||
286 | effect->direction = 0; | ||
257 | effect->u.rumble.strong_magnitude = | 287 | effect->u.rumble.strong_magnitude = |
258 | min(strong + effect->u.rumble.strong_magnitude, | 288 | min(strong + effect->u.rumble.strong_magnitude, |
259 | 0xffffU); | 289 | 0xffffU); |
@@ -268,6 +298,13 @@ static void ml_combine_effects(struct ff_effect *effect, | |||
268 | /* here we also scale it 0x7fff => 0xffff */ | 298 | /* here we also scale it 0x7fff => 0xffff */ |
269 | i = i * gain / 0x7fff; | 299 | i = i * gain / 0x7fff; |
270 | 300 | ||
301 | if (effect->u.rumble.strong_magnitude + i) | ||
302 | effect->direction = ml_calculate_direction( | ||
303 | effect->direction, | ||
304 | effect->u.rumble.strong_magnitude, | ||
305 | new->direction, i); | ||
306 | else | ||
307 | effect->direction = 0; | ||
271 | effect->u.rumble.strong_magnitude = | 308 | effect->u.rumble.strong_magnitude = |
272 | min(i + effect->u.rumble.strong_magnitude, 0xffffU); | 309 | min(i + effect->u.rumble.strong_magnitude, 0xffffU); |
273 | effect->u.rumble.weak_magnitude = | 310 | effect->u.rumble.weak_magnitude = |
@@ -411,8 +448,6 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) | |||
411 | msecs_to_jiffies(state->effect->replay.length); | 448 | msecs_to_jiffies(state->effect->replay.length); |
412 | state->adj_at = state->play_at; | 449 | state->adj_at = state->play_at; |
413 | 450 | ||
414 | ml_schedule_timer(ml); | ||
415 | |||
416 | } else { | 451 | } else { |
417 | debug("initiated stop"); | 452 | debug("initiated stop"); |
418 | 453 | ||
@@ -420,10 +455,10 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) | |||
420 | __set_bit(FF_EFFECT_ABORTING, &state->flags); | 455 | __set_bit(FF_EFFECT_ABORTING, &state->flags); |
421 | else | 456 | else |
422 | __clear_bit(FF_EFFECT_STARTED, &state->flags); | 457 | __clear_bit(FF_EFFECT_STARTED, &state->flags); |
423 | |||
424 | ml_play_effects(ml); | ||
425 | } | 458 | } |
426 | 459 | ||
460 | ml_play_effects(ml); | ||
461 | |||
427 | return 0; | 462 | return 0; |
428 | } | 463 | } |
429 | 464 | ||
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index b04930f7ea7d..7392992da424 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c | |||
@@ -46,7 +46,7 @@ struct emu { | |||
46 | int size; | 46 | int size; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static struct pci_device_id emu_tbl[] = { | 49 | static const struct pci_device_id emu_tbl[] = { |
50 | 50 | ||
51 | { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */ | 51 | { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */ |
52 | { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */ | 52 | { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */ |
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 8a1810f88b9e..14d3f3e208a2 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
@@ -140,7 +140,7 @@ static void __devexit fm801_gp_remove(struct pci_dev *pci) | |||
140 | } | 140 | } |
141 | } | 141 | } |
142 | 142 | ||
143 | static struct pci_device_id fm801_gp_id_table[] = { | 143 | static const struct pci_device_id fm801_gp_id_table[] = { |
144 | { PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 144 | { PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
145 | { 0 } | 145 | { 0 } |
146 | }; | 146 | }; |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index ac11be08585e..7e18bcf05a66 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * the Free Software Foundation. | 11 | * the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/stddef.h> | 16 | #include <linux/stddef.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
@@ -190,9 +192,8 @@ static int gameport_bind_driver(struct gameport *gameport, struct gameport_drive | |||
190 | 192 | ||
191 | error = device_bind_driver(&gameport->dev); | 193 | error = device_bind_driver(&gameport->dev); |
192 | if (error) { | 194 | if (error) { |
193 | printk(KERN_WARNING | 195 | dev_warn(&gameport->dev, |
194 | "gameport: device_bind_driver() failed " | 196 | "device_bind_driver() failed for %s (%s) and %s, error: %d\n", |
195 | "for %s (%s) and %s, error: %d\n", | ||
196 | gameport->phys, gameport->name, | 197 | gameport->phys, gameport->name, |
197 | drv->description, error); | 198 | drv->description, error); |
198 | drv->disconnect(gameport); | 199 | drv->disconnect(gameport); |
@@ -209,9 +210,9 @@ static void gameport_find_driver(struct gameport *gameport) | |||
209 | 210 | ||
210 | error = device_attach(&gameport->dev); | 211 | error = device_attach(&gameport->dev); |
211 | if (error < 0) | 212 | if (error < 0) |
212 | printk(KERN_WARNING | 213 | dev_warn(&gameport->dev, |
213 | "gameport: device_attach() failed for %s (%s), error: %d\n", | 214 | "device_attach() failed for %s (%s), error: %d\n", |
214 | gameport->phys, gameport->name, error); | 215 | gameport->phys, gameport->name, error); |
215 | } | 216 | } |
216 | 217 | ||
217 | 218 | ||
@@ -262,17 +263,14 @@ static int gameport_queue_event(void *object, struct module *owner, | |||
262 | 263 | ||
263 | event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); | 264 | event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); |
264 | if (!event) { | 265 | if (!event) { |
265 | printk(KERN_ERR | 266 | pr_err("Not enough memory to queue event %d\n", event_type); |
266 | "gameport: Not enough memory to queue event %d\n", | ||
267 | event_type); | ||
268 | retval = -ENOMEM; | 267 | retval = -ENOMEM; |
269 | goto out; | 268 | goto out; |
270 | } | 269 | } |
271 | 270 | ||
272 | if (!try_module_get(owner)) { | 271 | if (!try_module_get(owner)) { |
273 | printk(KERN_WARNING | 272 | pr_warning("Can't get module reference, dropping event %d\n", |
274 | "gameport: Can't get module reference, dropping event %d\n", | 273 | event_type); |
275 | event_type); | ||
276 | kfree(event); | 274 | kfree(event); |
277 | retval = -EINVAL; | 275 | retval = -EINVAL; |
278 | goto out; | 276 | goto out; |
@@ -298,14 +296,12 @@ static void gameport_free_event(struct gameport_event *event) | |||
298 | 296 | ||
299 | static void gameport_remove_duplicate_events(struct gameport_event *event) | 297 | static void gameport_remove_duplicate_events(struct gameport_event *event) |
300 | { | 298 | { |
301 | struct list_head *node, *next; | 299 | struct gameport_event *e, *next; |
302 | struct gameport_event *e; | ||
303 | unsigned long flags; | 300 | unsigned long flags; |
304 | 301 | ||
305 | spin_lock_irqsave(&gameport_event_lock, flags); | 302 | spin_lock_irqsave(&gameport_event_lock, flags); |
306 | 303 | ||
307 | list_for_each_safe(node, next, &gameport_event_list) { | 304 | list_for_each_entry_safe(e, next, &gameport_event_list, node) { |
308 | e = list_entry(node, struct gameport_event, node); | ||
309 | if (event->object == e->object) { | 305 | if (event->object == e->object) { |
310 | /* | 306 | /* |
311 | * If this event is of different type we should not | 307 | * If this event is of different type we should not |
@@ -315,7 +311,7 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) | |||
315 | if (event->type != e->type) | 311 | if (event->type != e->type) |
316 | break; | 312 | break; |
317 | 313 | ||
318 | list_del_init(node); | 314 | list_del_init(&e->node); |
319 | gameport_free_event(e); | 315 | gameport_free_event(e); |
320 | } | 316 | } |
321 | } | 317 | } |
@@ -325,23 +321,18 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) | |||
325 | 321 | ||
326 | static struct gameport_event *gameport_get_event(void) | 322 | static struct gameport_event *gameport_get_event(void) |
327 | { | 323 | { |
328 | struct gameport_event *event; | 324 | struct gameport_event *event = NULL; |
329 | struct list_head *node; | ||
330 | unsigned long flags; | 325 | unsigned long flags; |
331 | 326 | ||
332 | spin_lock_irqsave(&gameport_event_lock, flags); | 327 | spin_lock_irqsave(&gameport_event_lock, flags); |
333 | 328 | ||
334 | if (list_empty(&gameport_event_list)) { | 329 | if (!list_empty(&gameport_event_list)) { |
335 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 330 | event = list_first_entry(&gameport_event_list, |
336 | return NULL; | 331 | struct gameport_event, node); |
332 | list_del_init(&event->node); | ||
337 | } | 333 | } |
338 | 334 | ||
339 | node = gameport_event_list.next; | ||
340 | event = list_entry(node, struct gameport_event, node); | ||
341 | list_del_init(node); | ||
342 | |||
343 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 335 | spin_unlock_irqrestore(&gameport_event_lock, flags); |
344 | |||
345 | return event; | 336 | return event; |
346 | } | 337 | } |
347 | 338 | ||
@@ -360,16 +351,14 @@ static void gameport_handle_event(void) | |||
360 | if ((event = gameport_get_event())) { | 351 | if ((event = gameport_get_event())) { |
361 | 352 | ||
362 | switch (event->type) { | 353 | switch (event->type) { |
363 | case GAMEPORT_REGISTER_PORT: | ||
364 | gameport_add_port(event->object); | ||
365 | break; | ||
366 | 354 | ||
367 | case GAMEPORT_ATTACH_DRIVER: | 355 | case GAMEPORT_REGISTER_PORT: |
368 | gameport_attach_driver(event->object); | 356 | gameport_add_port(event->object); |
369 | break; | 357 | break; |
370 | 358 | ||
371 | default: | 359 | case GAMEPORT_ATTACH_DRIVER: |
372 | break; | 360 | gameport_attach_driver(event->object); |
361 | break; | ||
373 | } | 362 | } |
374 | 363 | ||
375 | gameport_remove_duplicate_events(event); | 364 | gameport_remove_duplicate_events(event); |
@@ -385,16 +374,14 @@ static void gameport_handle_event(void) | |||
385 | */ | 374 | */ |
386 | static void gameport_remove_pending_events(void *object) | 375 | static void gameport_remove_pending_events(void *object) |
387 | { | 376 | { |
388 | struct list_head *node, *next; | 377 | struct gameport_event *event, *next; |
389 | struct gameport_event *event; | ||
390 | unsigned long flags; | 378 | unsigned long flags; |
391 | 379 | ||
392 | spin_lock_irqsave(&gameport_event_lock, flags); | 380 | spin_lock_irqsave(&gameport_event_lock, flags); |
393 | 381 | ||
394 | list_for_each_safe(node, next, &gameport_event_list) { | 382 | list_for_each_entry_safe(event, next, &gameport_event_list, node) { |
395 | event = list_entry(node, struct gameport_event, node); | ||
396 | if (event->object == object) { | 383 | if (event->object == object) { |
397 | list_del_init(node); | 384 | list_del_init(&event->node); |
398 | gameport_free_event(event); | 385 | gameport_free_event(event); |
399 | } | 386 | } |
400 | } | 387 | } |
@@ -441,7 +428,6 @@ static int gameport_thread(void *nothing) | |||
441 | kthread_should_stop() || !list_empty(&gameport_event_list)); | 428 | kthread_should_stop() || !list_empty(&gameport_event_list)); |
442 | } while (!kthread_should_stop()); | 429 | } while (!kthread_should_stop()); |
443 | 430 | ||
444 | printk(KERN_DEBUG "gameport: kgameportd exiting\n"); | ||
445 | return 0; | 431 | return 0; |
446 | } | 432 | } |
447 | 433 | ||
@@ -453,6 +439,7 @@ static int gameport_thread(void *nothing) | |||
453 | static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf) | 439 | static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf) |
454 | { | 440 | { |
455 | struct gameport *gameport = to_gameport_port(dev); | 441 | struct gameport *gameport = to_gameport_port(dev); |
442 | |||
456 | return sprintf(buf, "%s\n", gameport->name); | 443 | return sprintf(buf, "%s\n", gameport->name); |
457 | } | 444 | } |
458 | 445 | ||
@@ -521,7 +508,8 @@ static void gameport_init_port(struct gameport *gameport) | |||
521 | 508 | ||
522 | mutex_init(&gameport->drv_mutex); | 509 | mutex_init(&gameport->drv_mutex); |
523 | device_initialize(&gameport->dev); | 510 | device_initialize(&gameport->dev); |
524 | dev_set_name(&gameport->dev, "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1); | 511 | dev_set_name(&gameport->dev, "gameport%lu", |
512 | (unsigned long)atomic_inc_return(&gameport_no) - 1); | ||
525 | gameport->dev.bus = &gameport_bus; | 513 | gameport->dev.bus = &gameport_bus; |
526 | gameport->dev.release = gameport_release_port; | 514 | gameport->dev.release = gameport_release_port; |
527 | if (gameport->parent) | 515 | if (gameport->parent) |
@@ -550,19 +538,17 @@ static void gameport_add_port(struct gameport *gameport) | |||
550 | list_add_tail(&gameport->node, &gameport_list); | 538 | list_add_tail(&gameport->node, &gameport_list); |
551 | 539 | ||
552 | if (gameport->io) | 540 | if (gameport->io) |
553 | printk(KERN_INFO "gameport: %s is %s, io %#x, speed %dkHz\n", | 541 | dev_info(&gameport->dev, "%s is %s, io %#x, speed %dkHz\n", |
554 | gameport->name, gameport->phys, gameport->io, gameport->speed); | 542 | gameport->name, gameport->phys, gameport->io, gameport->speed); |
555 | else | 543 | else |
556 | printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", | 544 | dev_info(&gameport->dev, "%s is %s, speed %dkHz\n", |
557 | gameport->name, gameport->phys, gameport->speed); | 545 | gameport->name, gameport->phys, gameport->speed); |
558 | 546 | ||
559 | error = device_add(&gameport->dev); | 547 | error = device_add(&gameport->dev); |
560 | if (error) | 548 | if (error) |
561 | printk(KERN_ERR | 549 | dev_err(&gameport->dev, |
562 | "gameport: device_add() failed for %s (%s), error: %d\n", | 550 | "device_add() failed for %s (%s), error: %d\n", |
563 | gameport->phys, gameport->name, error); | 551 | gameport->phys, gameport->name, error); |
564 | else | ||
565 | gameport->registered = 1; | ||
566 | } | 552 | } |
567 | 553 | ||
568 | /* | 554 | /* |
@@ -584,10 +570,8 @@ static void gameport_destroy_port(struct gameport *gameport) | |||
584 | gameport->parent = NULL; | 570 | gameport->parent = NULL; |
585 | } | 571 | } |
586 | 572 | ||
587 | if (gameport->registered) { | 573 | if (device_is_registered(&gameport->dev)) |
588 | device_del(&gameport->dev); | 574 | device_del(&gameport->dev); |
589 | gameport->registered = 0; | ||
590 | } | ||
591 | 575 | ||
592 | list_del_init(&gameport->node); | 576 | list_del_init(&gameport->node); |
593 | 577 | ||
@@ -705,8 +689,7 @@ static void gameport_attach_driver(struct gameport_driver *drv) | |||
705 | 689 | ||
706 | error = driver_attach(&drv->driver); | 690 | error = driver_attach(&drv->driver); |
707 | if (error) | 691 | if (error) |
708 | printk(KERN_ERR | 692 | pr_err("driver_attach() failed for %s, error: %d\n", |
709 | "gameport: driver_attach() failed for %s, error: %d\n", | ||
710 | drv->driver.name, error); | 693 | drv->driver.name, error); |
711 | } | 694 | } |
712 | 695 | ||
@@ -727,8 +710,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner | |||
727 | 710 | ||
728 | error = driver_register(&drv->driver); | 711 | error = driver_register(&drv->driver); |
729 | if (error) { | 712 | if (error) { |
730 | printk(KERN_ERR | 713 | pr_err("driver_register() failed for %s, error: %d\n", |
731 | "gameport: driver_register() failed for %s, error: %d\n", | ||
732 | drv->driver.name, error); | 714 | drv->driver.name, error); |
733 | return error; | 715 | return error; |
734 | } | 716 | } |
@@ -828,7 +810,7 @@ static int __init gameport_init(void) | |||
828 | 810 | ||
829 | error = bus_register(&gameport_bus); | 811 | error = bus_register(&gameport_bus); |
830 | if (error) { | 812 | if (error) { |
831 | printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); | 813 | pr_err("failed to register gameport bus, error: %d\n", error); |
832 | return error; | 814 | return error; |
833 | } | 815 | } |
834 | 816 | ||
@@ -836,7 +818,7 @@ static int __init gameport_init(void) | |||
836 | if (IS_ERR(gameport_task)) { | 818 | if (IS_ERR(gameport_task)) { |
837 | bus_unregister(&gameport_bus); | 819 | bus_unregister(&gameport_bus); |
838 | error = PTR_ERR(gameport_task); | 820 | error = PTR_ERR(gameport_task); |
839 | printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error); | 821 | pr_err("Failed to start kgameportd, error: %d\n", error); |
840 | return error; | 822 | return error; |
841 | } | 823 | } |
842 | 824 | ||
diff --git a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c index 06ad36ed3483..85d6ee09f11f 100644 --- a/drivers/input/gameport/lightning.c +++ b/drivers/input/gameport/lightning.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/gameport.h> | 36 | #include <linux/gameport.h> |
37 | #include <linux/slab.h> | ||
38 | 37 | ||
39 | #define L4_PORT 0x201 | 38 | #define L4_PORT 0x201 |
40 | #define L4_SELECT_ANALOG 0xa4 | 39 | #define L4_SELECT_ANALOG 0xa4 |
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c index db556b71ddda..7c217848613e 100644 --- a/drivers/input/gameport/ns558.c +++ b/drivers/input/gameport/ns558.c | |||
@@ -166,7 +166,7 @@ static int ns558_isa_probe(int io) | |||
166 | 166 | ||
167 | #ifdef CONFIG_PNP | 167 | #ifdef CONFIG_PNP |
168 | 168 | ||
169 | static struct pnp_device_id pnp_devids[] = { | 169 | static const struct pnp_device_id pnp_devids[] = { |
170 | { .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */ | 170 | { .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */ |
171 | { .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */ | 171 | { .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */ |
172 | { .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */ | 172 | { .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */ |
diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h index 47cd9eaee66a..4d8ea32e8a00 100644 --- a/drivers/input/input-compat.h +++ b/drivers/input/input-compat.h | |||
@@ -21,8 +21,6 @@ | |||
21 | you why the ifdefs are needed? Think about it again. -AK */ | 21 | you why the ifdefs are needed? Think about it again. -AK */ |
22 | #ifdef CONFIG_X86_64 | 22 | #ifdef CONFIG_X86_64 |
23 | # define INPUT_COMPAT_TEST is_compat_task() | 23 | # define INPUT_COMPAT_TEST is_compat_task() |
24 | #elif defined(CONFIG_IA64) | ||
25 | # define INPUT_COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current)) | ||
26 | #elif defined(CONFIG_S390) | 24 | #elif defined(CONFIG_S390) |
27 | # define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT) | 25 | # define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT) |
28 | #elif defined(CONFIG_MIPS) | 26 | #elif defined(CONFIG_MIPS) |
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 0d3ce7a50fb1..10c9b0a845f0 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/jiffies.h> | 11 | #include <linux/jiffies.h> |
12 | #include <linux/slab.h> | ||
12 | #include <linux/mutex.h> | 13 | #include <linux/mutex.h> |
13 | #include <linux/input-polldev.h> | 14 | #include <linux/input-polldev.h> |
14 | 15 | ||
@@ -56,14 +57,10 @@ static void input_polldev_stop_workqueue(void) | |||
56 | mutex_unlock(&polldev_mutex); | 57 | mutex_unlock(&polldev_mutex); |
57 | } | 58 | } |
58 | 59 | ||
59 | static void input_polled_device_work(struct work_struct *work) | 60 | static void input_polldev_queue_work(struct input_polled_dev *dev) |
60 | { | 61 | { |
61 | struct input_polled_dev *dev = | ||
62 | container_of(work, struct input_polled_dev, work.work); | ||
63 | unsigned long delay; | 62 | unsigned long delay; |
64 | 63 | ||
65 | dev->poll(dev); | ||
66 | |||
67 | delay = msecs_to_jiffies(dev->poll_interval); | 64 | delay = msecs_to_jiffies(dev->poll_interval); |
68 | if (delay >= HZ) | 65 | if (delay >= HZ) |
69 | delay = round_jiffies_relative(delay); | 66 | delay = round_jiffies_relative(delay); |
@@ -71,6 +68,15 @@ static void input_polled_device_work(struct work_struct *work) | |||
71 | queue_delayed_work(polldev_wq, &dev->work, delay); | 68 | queue_delayed_work(polldev_wq, &dev->work, delay); |
72 | } | 69 | } |
73 | 70 | ||
71 | static void input_polled_device_work(struct work_struct *work) | ||
72 | { | ||
73 | struct input_polled_dev *dev = | ||
74 | container_of(work, struct input_polled_dev, work.work); | ||
75 | |||
76 | dev->poll(dev); | ||
77 | input_polldev_queue_work(dev); | ||
78 | } | ||
79 | |||
74 | static int input_open_polled_device(struct input_dev *input) | 80 | static int input_open_polled_device(struct input_dev *input) |
75 | { | 81 | { |
76 | struct input_polled_dev *dev = input_get_drvdata(input); | 82 | struct input_polled_dev *dev = input_get_drvdata(input); |
@@ -80,11 +86,12 @@ static int input_open_polled_device(struct input_dev *input) | |||
80 | if (error) | 86 | if (error) |
81 | return error; | 87 | return error; |
82 | 88 | ||
83 | if (dev->flush) | 89 | if (dev->open) |
84 | dev->flush(dev); | 90 | dev->open(dev); |
85 | 91 | ||
86 | queue_delayed_work(polldev_wq, &dev->work, | 92 | /* Only start polling if polling is enabled */ |
87 | msecs_to_jiffies(dev->poll_interval)); | 93 | if (dev->poll_interval > 0) |
94 | queue_delayed_work(polldev_wq, &dev->work, 0); | ||
88 | 95 | ||
89 | return 0; | 96 | return 0; |
90 | } | 97 | } |
@@ -94,9 +101,95 @@ static void input_close_polled_device(struct input_dev *input) | |||
94 | struct input_polled_dev *dev = input_get_drvdata(input); | 101 | struct input_polled_dev *dev = input_get_drvdata(input); |
95 | 102 | ||
96 | cancel_delayed_work_sync(&dev->work); | 103 | cancel_delayed_work_sync(&dev->work); |
104 | /* | ||
105 | * Clean up work struct to remove references to the workqueue. | ||
106 | * It may be destroyed by the next call. This causes problems | ||
107 | * at next device open-close in case of poll_interval == 0. | ||
108 | */ | ||
109 | INIT_DELAYED_WORK(&dev->work, dev->work.work.func); | ||
97 | input_polldev_stop_workqueue(); | 110 | input_polldev_stop_workqueue(); |
111 | |||
112 | if (dev->close) | ||
113 | dev->close(dev); | ||
98 | } | 114 | } |
99 | 115 | ||
116 | /* SYSFS interface */ | ||
117 | |||
118 | static ssize_t input_polldev_get_poll(struct device *dev, | ||
119 | struct device_attribute *attr, char *buf) | ||
120 | { | ||
121 | struct input_polled_dev *polldev = dev_get_drvdata(dev); | ||
122 | |||
123 | return sprintf(buf, "%d\n", polldev->poll_interval); | ||
124 | } | ||
125 | |||
126 | static ssize_t input_polldev_set_poll(struct device *dev, | ||
127 | struct device_attribute *attr, const char *buf, | ||
128 | size_t count) | ||
129 | { | ||
130 | struct input_polled_dev *polldev = dev_get_drvdata(dev); | ||
131 | struct input_dev *input = polldev->input; | ||
132 | unsigned long interval; | ||
133 | |||
134 | if (strict_strtoul(buf, 0, &interval)) | ||
135 | return -EINVAL; | ||
136 | |||
137 | if (interval < polldev->poll_interval_min) | ||
138 | return -EINVAL; | ||
139 | |||
140 | if (interval > polldev->poll_interval_max) | ||
141 | return -EINVAL; | ||
142 | |||
143 | mutex_lock(&input->mutex); | ||
144 | |||
145 | polldev->poll_interval = interval; | ||
146 | |||
147 | if (input->users) { | ||
148 | cancel_delayed_work_sync(&polldev->work); | ||
149 | if (polldev->poll_interval > 0) | ||
150 | input_polldev_queue_work(polldev); | ||
151 | } | ||
152 | |||
153 | mutex_unlock(&input->mutex); | ||
154 | |||
155 | return count; | ||
156 | } | ||
157 | |||
158 | static DEVICE_ATTR(poll, S_IRUGO | S_IWUSR, input_polldev_get_poll, | ||
159 | input_polldev_set_poll); | ||
160 | |||
161 | |||
162 | static ssize_t input_polldev_get_max(struct device *dev, | ||
163 | struct device_attribute *attr, char *buf) | ||
164 | { | ||
165 | struct input_polled_dev *polldev = dev_get_drvdata(dev); | ||
166 | |||
167 | return sprintf(buf, "%d\n", polldev->poll_interval_max); | ||
168 | } | ||
169 | |||
170 | static DEVICE_ATTR(max, S_IRUGO, input_polldev_get_max, NULL); | ||
171 | |||
172 | static ssize_t input_polldev_get_min(struct device *dev, | ||
173 | struct device_attribute *attr, char *buf) | ||
174 | { | ||
175 | struct input_polled_dev *polldev = dev_get_drvdata(dev); | ||
176 | |||
177 | return sprintf(buf, "%d\n", polldev->poll_interval_min); | ||
178 | } | ||
179 | |||
180 | static DEVICE_ATTR(min, S_IRUGO, input_polldev_get_min, NULL); | ||
181 | |||
182 | static struct attribute *sysfs_attrs[] = { | ||
183 | &dev_attr_poll.attr, | ||
184 | &dev_attr_max.attr, | ||
185 | &dev_attr_min.attr, | ||
186 | NULL | ||
187 | }; | ||
188 | |||
189 | static struct attribute_group input_polldev_attribute_group = { | ||
190 | .attrs = sysfs_attrs | ||
191 | }; | ||
192 | |||
100 | /** | 193 | /** |
101 | * input_allocate_polled_device - allocated memory polled device | 194 | * input_allocate_polled_device - allocated memory polled device |
102 | * | 195 | * |
@@ -126,7 +219,7 @@ EXPORT_SYMBOL(input_allocate_polled_device); | |||
126 | * @dev: device to free | 219 | * @dev: device to free |
127 | * | 220 | * |
128 | * The function frees memory allocated for polling device and drops | 221 | * The function frees memory allocated for polling device and drops |
129 | * reference to the associated input device (if present). | 222 | * reference to the associated input device. |
130 | */ | 223 | */ |
131 | void input_free_polled_device(struct input_polled_dev *dev) | 224 | void input_free_polled_device(struct input_polled_dev *dev) |
132 | { | 225 | { |
@@ -150,15 +243,38 @@ EXPORT_SYMBOL(input_free_polled_device); | |||
150 | int input_register_polled_device(struct input_polled_dev *dev) | 243 | int input_register_polled_device(struct input_polled_dev *dev) |
151 | { | 244 | { |
152 | struct input_dev *input = dev->input; | 245 | struct input_dev *input = dev->input; |
246 | int error; | ||
153 | 247 | ||
154 | input_set_drvdata(input, dev); | 248 | input_set_drvdata(input, dev); |
155 | INIT_DELAYED_WORK(&dev->work, input_polled_device_work); | 249 | INIT_DELAYED_WORK(&dev->work, input_polled_device_work); |
156 | if (!dev->poll_interval) | 250 | if (!dev->poll_interval) |
157 | dev->poll_interval = 500; | 251 | dev->poll_interval = 500; |
252 | if (!dev->poll_interval_max) | ||
253 | dev->poll_interval_max = dev->poll_interval; | ||
158 | input->open = input_open_polled_device; | 254 | input->open = input_open_polled_device; |
159 | input->close = input_close_polled_device; | 255 | input->close = input_close_polled_device; |
160 | 256 | ||
161 | return input_register_device(input); | 257 | error = input_register_device(input); |
258 | if (error) | ||
259 | return error; | ||
260 | |||
261 | error = sysfs_create_group(&input->dev.kobj, | ||
262 | &input_polldev_attribute_group); | ||
263 | if (error) { | ||
264 | input_unregister_device(input); | ||
265 | return error; | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * Take extra reference to the underlying input device so | ||
270 | * that it survives call to input_unregister_polled_device() | ||
271 | * and is deleted only after input_free_polled_device() | ||
272 | * has been invoked. This is needed to ease task of freeing | ||
273 | * sparse keymaps. | ||
274 | */ | ||
275 | input_get_device(input); | ||
276 | |||
277 | return 0; | ||
162 | } | 278 | } |
163 | EXPORT_SYMBOL(input_register_polled_device); | 279 | EXPORT_SYMBOL(input_register_polled_device); |
164 | 280 | ||
@@ -169,13 +285,13 @@ EXPORT_SYMBOL(input_register_polled_device); | |||
169 | * The function unregisters previously registered polled input | 285 | * The function unregisters previously registered polled input |
170 | * device from input layer. Polling is stopped and device is | 286 | * device from input layer. Polling is stopped and device is |
171 | * ready to be freed with call to input_free_polled_device(). | 287 | * ready to be freed with call to input_free_polled_device(). |
172 | * Callers should not attempt to access dev->input pointer | ||
173 | * after calling this function. | ||
174 | */ | 288 | */ |
175 | void input_unregister_polled_device(struct input_polled_dev *dev) | 289 | void input_unregister_polled_device(struct input_polled_dev *dev) |
176 | { | 290 | { |
291 | sysfs_remove_group(&dev->input->dev.kobj, | ||
292 | &input_polldev_attribute_group); | ||
293 | |||
177 | input_unregister_device(dev->input); | 294 | input_unregister_device(dev->input); |
178 | dev->input = NULL; | ||
179 | } | 295 | } |
180 | EXPORT_SYMBOL(input_unregister_polled_device); | 296 | EXPORT_SYMBOL(input_unregister_polled_device); |
181 | 297 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index 2266ecbfbc01..9c79bd56b51a 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/input.h> | 15 | #include <linux/input.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/random.h> | 18 | #include <linux/random.h> |
18 | #include <linux/major.h> | 19 | #include <linux/major.h> |
19 | #include <linux/proc_fs.h> | 20 | #include <linux/proc_fs.h> |
@@ -24,6 +25,7 @@ | |||
24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
25 | #include <linux/rcupdate.h> | 26 | #include <linux/rcupdate.h> |
26 | #include <linux/smp_lock.h> | 27 | #include <linux/smp_lock.h> |
28 | #include "input-compat.h" | ||
27 | 29 | ||
28 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | 30 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); |
29 | MODULE_DESCRIPTION("Input core"); | 31 | MODULE_DESCRIPTION("Input core"); |
@@ -45,6 +47,7 @@ static unsigned int input_abs_bypass_init_data[] __initdata = { | |||
45 | ABS_MT_TOOL_TYPE, | 47 | ABS_MT_TOOL_TYPE, |
46 | ABS_MT_BLOB_ID, | 48 | ABS_MT_BLOB_ID, |
47 | ABS_MT_TRACKING_ID, | 49 | ABS_MT_TRACKING_ID, |
50 | ABS_MT_PRESSURE, | ||
48 | 0 | 51 | 0 |
49 | }; | 52 | }; |
50 | static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)]; | 53 | static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)]; |
@@ -85,12 +88,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) | |||
85 | } | 88 | } |
86 | 89 | ||
87 | /* | 90 | /* |
88 | * Pass event through all open handles. This function is called with | 91 | * Pass event first through all filters and then, if event has not been |
92 | * filtered out, through all open handles. This function is called with | ||
89 | * dev->event_lock held and interrupts disabled. | 93 | * dev->event_lock held and interrupts disabled. |
90 | */ | 94 | */ |
91 | static void input_pass_event(struct input_dev *dev, | 95 | static void input_pass_event(struct input_dev *dev, |
92 | unsigned int type, unsigned int code, int value) | 96 | unsigned int type, unsigned int code, int value) |
93 | { | 97 | { |
98 | struct input_handler *handler; | ||
94 | struct input_handle *handle; | 99 | struct input_handle *handle; |
95 | 100 | ||
96 | rcu_read_lock(); | 101 | rcu_read_lock(); |
@@ -98,11 +103,25 @@ static void input_pass_event(struct input_dev *dev, | |||
98 | handle = rcu_dereference(dev->grab); | 103 | handle = rcu_dereference(dev->grab); |
99 | if (handle) | 104 | if (handle) |
100 | handle->handler->event(handle, type, code, value); | 105 | handle->handler->event(handle, type, code, value); |
101 | else | 106 | else { |
102 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) | 107 | bool filtered = false; |
103 | if (handle->open) | 108 | |
104 | handle->handler->event(handle, | 109 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) { |
105 | type, code, value); | 110 | if (!handle->open) |
111 | continue; | ||
112 | |||
113 | handler = handle->handler; | ||
114 | if (!handler->filter) { | ||
115 | if (filtered) | ||
116 | break; | ||
117 | |||
118 | handler->event(handle, type, code, value); | ||
119 | |||
120 | } else if (handler->filter(handle, type, code, value)) | ||
121 | filtered = true; | ||
122 | } | ||
123 | } | ||
124 | |||
106 | rcu_read_unlock(); | 125 | rcu_read_unlock(); |
107 | } | 126 | } |
108 | 127 | ||
@@ -296,9 +315,15 @@ static void input_handle_event(struct input_dev *dev, | |||
296 | * @value: value of the event | 315 | * @value: value of the event |
297 | * | 316 | * |
298 | * This function should be used by drivers implementing various input | 317 | * This function should be used by drivers implementing various input |
299 | * devices. See also input_inject_event(). | 318 | * devices to report input events. See also input_inject_event(). |
319 | * | ||
320 | * NOTE: input_event() may be safely used right after input device was | ||
321 | * allocated with input_allocate_device(), even before it is registered | ||
322 | * with input_register_device(), but the event will not reach any of the | ||
323 | * input handlers. Such early invocation of input_event() may be used | ||
324 | * to 'seed' initial state of a switch or initial position of absolute | ||
325 | * axis, etc. | ||
300 | */ | 326 | */ |
301 | |||
302 | void input_event(struct input_dev *dev, | 327 | void input_event(struct input_dev *dev, |
303 | unsigned int type, unsigned int code, int value) | 328 | unsigned int type, unsigned int code, int value) |
304 | { | 329 | { |
@@ -558,7 +583,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode) | |||
558 | } | 583 | } |
559 | 584 | ||
560 | static int input_default_getkeycode(struct input_dev *dev, | 585 | static int input_default_getkeycode(struct input_dev *dev, |
561 | int scancode, int *keycode) | 586 | unsigned int scancode, |
587 | unsigned int *keycode) | ||
562 | { | 588 | { |
563 | if (!dev->keycodesize) | 589 | if (!dev->keycodesize) |
564 | return -EINVAL; | 590 | return -EINVAL; |
@@ -572,7 +598,8 @@ static int input_default_getkeycode(struct input_dev *dev, | |||
572 | } | 598 | } |
573 | 599 | ||
574 | static int input_default_setkeycode(struct input_dev *dev, | 600 | static int input_default_setkeycode(struct input_dev *dev, |
575 | int scancode, int keycode) | 601 | unsigned int scancode, |
602 | unsigned int keycode) | ||
576 | { | 603 | { |
577 | int old_keycode; | 604 | int old_keycode; |
578 | int i; | 605 | int i; |
@@ -607,12 +634,12 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
607 | } | 634 | } |
608 | } | 635 | } |
609 | 636 | ||
610 | clear_bit(old_keycode, dev->keybit); | 637 | __clear_bit(old_keycode, dev->keybit); |
611 | set_bit(keycode, dev->keybit); | 638 | __set_bit(keycode, dev->keybit); |
612 | 639 | ||
613 | for (i = 0; i < dev->keycodemax; i++) { | 640 | for (i = 0; i < dev->keycodemax; i++) { |
614 | if (input_fetch_keycode(dev, i) == old_keycode) { | 641 | if (input_fetch_keycode(dev, i) == old_keycode) { |
615 | set_bit(old_keycode, dev->keybit); | 642 | __set_bit(old_keycode, dev->keybit); |
616 | break; /* Setting the bit twice is useless, so break */ | 643 | break; /* Setting the bit twice is useless, so break */ |
617 | } | 644 | } |
618 | } | 645 | } |
@@ -630,12 +657,17 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
630 | * This function should be called by anyone interested in retrieving current | 657 | * This function should be called by anyone interested in retrieving current |
631 | * keymap. Presently keyboard and evdev handlers use it. | 658 | * keymap. Presently keyboard and evdev handlers use it. |
632 | */ | 659 | */ |
633 | int input_get_keycode(struct input_dev *dev, int scancode, int *keycode) | 660 | int input_get_keycode(struct input_dev *dev, |
661 | unsigned int scancode, unsigned int *keycode) | ||
634 | { | 662 | { |
635 | if (scancode < 0) | 663 | unsigned long flags; |
636 | return -EINVAL; | 664 | int retval; |
665 | |||
666 | spin_lock_irqsave(&dev->event_lock, flags); | ||
667 | retval = dev->getkeycode(dev, scancode, keycode); | ||
668 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
637 | 669 | ||
638 | return dev->getkeycode(dev, scancode, keycode); | 670 | return retval; |
639 | } | 671 | } |
640 | EXPORT_SYMBOL(input_get_keycode); | 672 | EXPORT_SYMBOL(input_get_keycode); |
641 | 673 | ||
@@ -648,16 +680,14 @@ EXPORT_SYMBOL(input_get_keycode); | |||
648 | * This function should be called by anyone needing to update current | 680 | * This function should be called by anyone needing to update current |
649 | * keymap. Presently keyboard and evdev handlers use it. | 681 | * keymap. Presently keyboard and evdev handlers use it. |
650 | */ | 682 | */ |
651 | int input_set_keycode(struct input_dev *dev, int scancode, int keycode) | 683 | int input_set_keycode(struct input_dev *dev, |
684 | unsigned int scancode, unsigned int keycode) | ||
652 | { | 685 | { |
653 | unsigned long flags; | 686 | unsigned long flags; |
654 | int old_keycode; | 687 | int old_keycode; |
655 | int retval; | 688 | int retval; |
656 | 689 | ||
657 | if (scancode < 0) | 690 | if (keycode > KEY_MAX) |
658 | return -EINVAL; | ||
659 | |||
660 | if (keycode < 0 || keycode > KEY_MAX) | ||
661 | return -EINVAL; | 691 | return -EINVAL; |
662 | 692 | ||
663 | spin_lock_irqsave(&dev->event_lock, flags); | 693 | spin_lock_irqsave(&dev->event_lock, flags); |
@@ -670,6 +700,9 @@ int input_set_keycode(struct input_dev *dev, int scancode, int keycode) | |||
670 | if (retval) | 700 | if (retval) |
671 | goto out; | 701 | goto out; |
672 | 702 | ||
703 | /* Make sure KEY_RESERVED did not get enabled. */ | ||
704 | __clear_bit(KEY_RESERVED, dev->keybit); | ||
705 | |||
673 | /* | 706 | /* |
674 | * Simulate keyup event if keycode is not present | 707 | * Simulate keyup event if keycode is not present |
675 | * in the keymap anymore | 708 | * in the keymap anymore |
@@ -697,12 +730,13 @@ EXPORT_SYMBOL(input_set_keycode); | |||
697 | if (i != BITS_TO_LONGS(max)) \ | 730 | if (i != BITS_TO_LONGS(max)) \ |
698 | continue; | 731 | continue; |
699 | 732 | ||
700 | static const struct input_device_id *input_match_device(const struct input_device_id *id, | 733 | static const struct input_device_id *input_match_device(struct input_handler *handler, |
701 | struct input_dev *dev) | 734 | struct input_dev *dev) |
702 | { | 735 | { |
736 | const struct input_device_id *id; | ||
703 | int i; | 737 | int i; |
704 | 738 | ||
705 | for (; id->flags || id->driver_info; id++) { | 739 | for (id = handler->id_table; id->flags || id->driver_info; id++) { |
706 | 740 | ||
707 | if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) | 741 | if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) |
708 | if (id->bustype != dev->id.bustype) | 742 | if (id->bustype != dev->id.bustype) |
@@ -730,7 +764,8 @@ static const struct input_device_id *input_match_device(const struct input_devic | |||
730 | MATCH_BIT(ffbit, FF_MAX); | 764 | MATCH_BIT(ffbit, FF_MAX); |
731 | MATCH_BIT(swbit, SW_MAX); | 765 | MATCH_BIT(swbit, SW_MAX); |
732 | 766 | ||
733 | return id; | 767 | if (!handler->match || handler->match(handler, dev)) |
768 | return id; | ||
734 | } | 769 | } |
735 | 770 | ||
736 | return NULL; | 771 | return NULL; |
@@ -741,10 +776,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
741 | const struct input_device_id *id; | 776 | const struct input_device_id *id; |
742 | int error; | 777 | int error; |
743 | 778 | ||
744 | if (handler->blacklist && input_match_device(handler->blacklist, dev)) | 779 | id = input_match_device(handler, dev); |
745 | return -ENODEV; | ||
746 | |||
747 | id = input_match_device(handler->id_table, dev); | ||
748 | if (!id) | 780 | if (!id) |
749 | return -ENODEV; | 781 | return -ENODEV; |
750 | 782 | ||
@@ -758,6 +790,40 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
758 | return error; | 790 | return error; |
759 | } | 791 | } |
760 | 792 | ||
793 | #ifdef CONFIG_COMPAT | ||
794 | |||
795 | static int input_bits_to_string(char *buf, int buf_size, | ||
796 | unsigned long bits, bool skip_empty) | ||
797 | { | ||
798 | int len = 0; | ||
799 | |||
800 | if (INPUT_COMPAT_TEST) { | ||
801 | u32 dword = bits >> 32; | ||
802 | if (dword || !skip_empty) | ||
803 | len += snprintf(buf, buf_size, "%x ", dword); | ||
804 | |||
805 | dword = bits & 0xffffffffUL; | ||
806 | if (dword || !skip_empty || len) | ||
807 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
808 | "%x", dword); | ||
809 | } else { | ||
810 | if (bits || !skip_empty) | ||
811 | len += snprintf(buf, buf_size, "%lx", bits); | ||
812 | } | ||
813 | |||
814 | return len; | ||
815 | } | ||
816 | |||
817 | #else /* !CONFIG_COMPAT */ | ||
818 | |||
819 | static int input_bits_to_string(char *buf, int buf_size, | ||
820 | unsigned long bits, bool skip_empty) | ||
821 | { | ||
822 | return bits || !skip_empty ? | ||
823 | snprintf(buf, buf_size, "%lx", bits) : 0; | ||
824 | } | ||
825 | |||
826 | #endif | ||
761 | 827 | ||
762 | #ifdef CONFIG_PROC_FS | 828 | #ifdef CONFIG_PROC_FS |
763 | 829 | ||
@@ -826,14 +892,25 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, | |||
826 | unsigned long *bitmap, int max) | 892 | unsigned long *bitmap, int max) |
827 | { | 893 | { |
828 | int i; | 894 | int i; |
829 | 895 | bool skip_empty = true; | |
830 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 896 | char buf[18]; |
831 | if (bitmap[i]) | ||
832 | break; | ||
833 | 897 | ||
834 | seq_printf(seq, "B: %s=", name); | 898 | seq_printf(seq, "B: %s=", name); |
835 | for (; i >= 0; i--) | 899 | |
836 | seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : ""); | 900 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { |
901 | if (input_bits_to_string(buf, sizeof(buf), | ||
902 | bitmap[i], skip_empty)) { | ||
903 | skip_empty = false; | ||
904 | seq_printf(seq, "%s%s", buf, i > 0 ? " " : ""); | ||
905 | } | ||
906 | } | ||
907 | |||
908 | /* | ||
909 | * If no output was produced print a single 0. | ||
910 | */ | ||
911 | if (skip_empty) | ||
912 | seq_puts(seq, "0"); | ||
913 | |||
837 | seq_putc(seq, '\n'); | 914 | seq_putc(seq, '\n'); |
838 | } | 915 | } |
839 | 916 | ||
@@ -935,6 +1012,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v) | |||
935 | union input_seq_state *state = (union input_seq_state *)&seq->private; | 1012 | union input_seq_state *state = (union input_seq_state *)&seq->private; |
936 | 1013 | ||
937 | seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); | 1014 | seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); |
1015 | if (handler->filter) | ||
1016 | seq_puts(seq, " (filter)"); | ||
938 | if (handler->fops) | 1017 | if (handler->fops) |
939 | seq_printf(seq, " Minor=%d", handler->minor); | 1018 | seq_printf(seq, " Minor=%d", handler->minor); |
940 | seq_putc(seq, '\n'); | 1019 | seq_putc(seq, '\n'); |
@@ -1122,14 +1201,23 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, | |||
1122 | { | 1201 | { |
1123 | int i; | 1202 | int i; |
1124 | int len = 0; | 1203 | int len = 0; |
1204 | bool skip_empty = true; | ||
1205 | |||
1206 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { | ||
1207 | len += input_bits_to_string(buf + len, max(buf_size - len, 0), | ||
1208 | bitmap[i], skip_empty); | ||
1209 | if (len) { | ||
1210 | skip_empty = false; | ||
1211 | if (i > 0) | ||
1212 | len += snprintf(buf + len, max(buf_size - len, 0), " "); | ||
1213 | } | ||
1214 | } | ||
1125 | 1215 | ||
1126 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 1216 | /* |
1127 | if (bitmap[i]) | 1217 | * If no output was produced print a single 0. |
1128 | break; | 1218 | */ |
1129 | 1219 | if (len == 0) | |
1130 | for (; i >= 0; i--) | 1220 | len = snprintf(buf, buf_size, "%d", 0); |
1131 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
1132 | "%lx%s", bitmap[i], i > 0 ? " " : ""); | ||
1133 | 1221 | ||
1134 | if (add_cr) | 1222 | if (add_cr) |
1135 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); | 1223 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); |
@@ -1144,7 +1232,8 @@ static ssize_t input_dev_show_cap_##bm(struct device *dev, \ | |||
1144 | { \ | 1232 | { \ |
1145 | struct input_dev *input_dev = to_input_dev(dev); \ | 1233 | struct input_dev *input_dev = to_input_dev(dev); \ |
1146 | int len = input_print_bitmap(buf, PAGE_SIZE, \ | 1234 | int len = input_print_bitmap(buf, PAGE_SIZE, \ |
1147 | input_dev->bm##bit, ev##_MAX, 1); \ | 1235 | input_dev->bm##bit, ev##_MAX, \ |
1236 | true); \ | ||
1148 | return min_t(int, len, PAGE_SIZE); \ | 1237 | return min_t(int, len, PAGE_SIZE); \ |
1149 | } \ | 1238 | } \ |
1150 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) | 1239 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) |
@@ -1208,7 +1297,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, | |||
1208 | 1297 | ||
1209 | len = input_print_bitmap(&env->buf[env->buflen - 1], | 1298 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
1210 | sizeof(env->buf) - env->buflen, | 1299 | sizeof(env->buf) - env->buflen, |
1211 | bitmap, max, 0); | 1300 | bitmap, max, false); |
1212 | if (len >= (sizeof(env->buf) - env->buflen)) | 1301 | if (len >= (sizeof(env->buf) - env->buflen)) |
1213 | return -ENOMEM; | 1302 | return -ENOMEM; |
1214 | 1303 | ||
@@ -1488,6 +1577,25 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int | |||
1488 | } | 1577 | } |
1489 | EXPORT_SYMBOL(input_set_capability); | 1578 | EXPORT_SYMBOL(input_set_capability); |
1490 | 1579 | ||
1580 | #define INPUT_CLEANSE_BITMASK(dev, type, bits) \ | ||
1581 | do { \ | ||
1582 | if (!test_bit(EV_##type, dev->evbit)) \ | ||
1583 | memset(dev->bits##bit, 0, \ | ||
1584 | sizeof(dev->bits##bit)); \ | ||
1585 | } while (0) | ||
1586 | |||
1587 | static void input_cleanse_bitmasks(struct input_dev *dev) | ||
1588 | { | ||
1589 | INPUT_CLEANSE_BITMASK(dev, KEY, key); | ||
1590 | INPUT_CLEANSE_BITMASK(dev, REL, rel); | ||
1591 | INPUT_CLEANSE_BITMASK(dev, ABS, abs); | ||
1592 | INPUT_CLEANSE_BITMASK(dev, MSC, msc); | ||
1593 | INPUT_CLEANSE_BITMASK(dev, LED, led); | ||
1594 | INPUT_CLEANSE_BITMASK(dev, SND, snd); | ||
1595 | INPUT_CLEANSE_BITMASK(dev, FF, ff); | ||
1596 | INPUT_CLEANSE_BITMASK(dev, SW, sw); | ||
1597 | } | ||
1598 | |||
1491 | /** | 1599 | /** |
1492 | * input_register_device - register device with input core | 1600 | * input_register_device - register device with input core |
1493 | * @dev: device to be registered | 1601 | * @dev: device to be registered |
@@ -1507,13 +1615,19 @@ int input_register_device(struct input_dev *dev) | |||
1507 | const char *path; | 1615 | const char *path; |
1508 | int error; | 1616 | int error; |
1509 | 1617 | ||
1618 | /* Every input device generates EV_SYN/SYN_REPORT events. */ | ||
1510 | __set_bit(EV_SYN, dev->evbit); | 1619 | __set_bit(EV_SYN, dev->evbit); |
1511 | 1620 | ||
1621 | /* KEY_RESERVED is not supposed to be transmitted to userspace. */ | ||
1622 | __clear_bit(KEY_RESERVED, dev->keybit); | ||
1623 | |||
1624 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ | ||
1625 | input_cleanse_bitmasks(dev); | ||
1626 | |||
1512 | /* | 1627 | /* |
1513 | * If delay and period are pre-set by the driver, then autorepeating | 1628 | * If delay and period are pre-set by the driver, then autorepeating |
1514 | * is handled by the driver itself and we don't do it in input.c. | 1629 | * is handled by the driver itself and we don't do it in input.c. |
1515 | */ | 1630 | */ |
1516 | |||
1517 | init_timer(&dev->timer); | 1631 | init_timer(&dev->timer); |
1518 | if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { | 1632 | if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { |
1519 | dev->timer.data = (long) dev; | 1633 | dev->timer.data = (long) dev; |
@@ -1658,6 +1772,38 @@ void input_unregister_handler(struct input_handler *handler) | |||
1658 | EXPORT_SYMBOL(input_unregister_handler); | 1772 | EXPORT_SYMBOL(input_unregister_handler); |
1659 | 1773 | ||
1660 | /** | 1774 | /** |
1775 | * input_handler_for_each_handle - handle iterator | ||
1776 | * @handler: input handler to iterate | ||
1777 | * @data: data for the callback | ||
1778 | * @fn: function to be called for each handle | ||
1779 | * | ||
1780 | * Iterate over @bus's list of devices, and call @fn for each, passing | ||
1781 | * it @data and stop when @fn returns a non-zero value. The function is | ||
1782 | * using RCU to traverse the list and therefore may be usind in atonic | ||
1783 | * contexts. The @fn callback is invoked from RCU critical section and | ||
1784 | * thus must not sleep. | ||
1785 | */ | ||
1786 | int input_handler_for_each_handle(struct input_handler *handler, void *data, | ||
1787 | int (*fn)(struct input_handle *, void *)) | ||
1788 | { | ||
1789 | struct input_handle *handle; | ||
1790 | int retval = 0; | ||
1791 | |||
1792 | rcu_read_lock(); | ||
1793 | |||
1794 | list_for_each_entry_rcu(handle, &handler->h_list, h_node) { | ||
1795 | retval = fn(handle, data); | ||
1796 | if (retval) | ||
1797 | break; | ||
1798 | } | ||
1799 | |||
1800 | rcu_read_unlock(); | ||
1801 | |||
1802 | return retval; | ||
1803 | } | ||
1804 | EXPORT_SYMBOL(input_handler_for_each_handle); | ||
1805 | |||
1806 | /** | ||
1661 | * input_register_handle - register a new input handle | 1807 | * input_register_handle - register a new input handle |
1662 | * @handle: handle to register | 1808 | * @handle: handle to register |
1663 | * | 1809 | * |
@@ -1681,7 +1827,16 @@ int input_register_handle(struct input_handle *handle) | |||
1681 | error = mutex_lock_interruptible(&dev->mutex); | 1827 | error = mutex_lock_interruptible(&dev->mutex); |
1682 | if (error) | 1828 | if (error) |
1683 | return error; | 1829 | return error; |
1684 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | 1830 | |
1831 | /* | ||
1832 | * Filters go to the head of the list, normal handlers | ||
1833 | * to the tail. | ||
1834 | */ | ||
1835 | if (handler->filter) | ||
1836 | list_add_rcu(&handle->d_node, &dev->h_list); | ||
1837 | else | ||
1838 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | ||
1839 | |||
1685 | mutex_unlock(&dev->mutex); | 1840 | mutex_unlock(&dev->mutex); |
1686 | 1841 | ||
1687 | /* | 1842 | /* |
@@ -1690,7 +1845,7 @@ int input_register_handle(struct input_handle *handle) | |||
1690 | * we can't be racing with input_unregister_handle() | 1845 | * we can't be racing with input_unregister_handle() |
1691 | * and so separate lock is not needed here. | 1846 | * and so separate lock is not needed here. |
1692 | */ | 1847 | */ |
1693 | list_add_tail(&handle->h_node, &handler->h_list); | 1848 | list_add_tail_rcu(&handle->h_node, &handler->h_list); |
1694 | 1849 | ||
1695 | if (handler->start) | 1850 | if (handler->start) |
1696 | handler->start(handle); | 1851 | handler->start(handle); |
@@ -1713,7 +1868,7 @@ void input_unregister_handle(struct input_handle *handle) | |||
1713 | { | 1868 | { |
1714 | struct input_dev *dev = handle->dev; | 1869 | struct input_dev *dev = handle->dev; |
1715 | 1870 | ||
1716 | list_del_init(&handle->h_node); | 1871 | list_del_rcu(&handle->h_node); |
1717 | 1872 | ||
1718 | /* | 1873 | /* |
1719 | * Take dev->mutex to prevent race with input_release_device(). | 1874 | * Take dev->mutex to prevent race with input_release_device(). |
@@ -1721,6 +1876,7 @@ void input_unregister_handle(struct input_handle *handle) | |||
1721 | mutex_lock(&dev->mutex); | 1876 | mutex_lock(&dev->mutex); |
1722 | list_del_rcu(&handle->d_node); | 1877 | list_del_rcu(&handle->d_node); |
1723 | mutex_unlock(&dev->mutex); | 1878 | mutex_unlock(&dev->mutex); |
1879 | |||
1724 | synchronize_rcu(); | 1880 | synchronize_rcu(); |
1725 | } | 1881 | } |
1726 | EXPORT_SYMBOL(input_unregister_handle); | 1882 | EXPORT_SYMBOL(input_unregister_handle); |
@@ -1731,35 +1887,37 @@ static int input_open_file(struct inode *inode, struct file *file) | |||
1731 | const struct file_operations *old_fops, *new_fops = NULL; | 1887 | const struct file_operations *old_fops, *new_fops = NULL; |
1732 | int err; | 1888 | int err; |
1733 | 1889 | ||
1734 | lock_kernel(); | 1890 | err = mutex_lock_interruptible(&input_mutex); |
1891 | if (err) | ||
1892 | return err; | ||
1893 | |||
1735 | /* No load-on-demand here? */ | 1894 | /* No load-on-demand here? */ |
1736 | handler = input_table[iminor(inode) >> 5]; | 1895 | handler = input_table[iminor(inode) >> 5]; |
1737 | if (!handler || !(new_fops = fops_get(handler->fops))) { | 1896 | if (handler) |
1738 | err = -ENODEV; | 1897 | new_fops = fops_get(handler->fops); |
1739 | goto out; | 1898 | |
1740 | } | 1899 | mutex_unlock(&input_mutex); |
1741 | 1900 | ||
1742 | /* | 1901 | /* |
1743 | * That's _really_ odd. Usually NULL ->open means "nothing special", | 1902 | * That's _really_ odd. Usually NULL ->open means "nothing special", |
1744 | * not "no device". Oh, well... | 1903 | * not "no device". Oh, well... |
1745 | */ | 1904 | */ |
1746 | if (!new_fops->open) { | 1905 | if (!new_fops || !new_fops->open) { |
1747 | fops_put(new_fops); | 1906 | fops_put(new_fops); |
1748 | err = -ENODEV; | 1907 | err = -ENODEV; |
1749 | goto out; | 1908 | goto out; |
1750 | } | 1909 | } |
1910 | |||
1751 | old_fops = file->f_op; | 1911 | old_fops = file->f_op; |
1752 | file->f_op = new_fops; | 1912 | file->f_op = new_fops; |
1753 | 1913 | ||
1754 | err = new_fops->open(inode, file); | 1914 | err = new_fops->open(inode, file); |
1755 | |||
1756 | if (err) { | 1915 | if (err) { |
1757 | fops_put(file->f_op); | 1916 | fops_put(file->f_op); |
1758 | file->f_op = fops_get(old_fops); | 1917 | file->f_op = fops_get(old_fops); |
1759 | } | 1918 | } |
1760 | fops_put(old_fops); | 1919 | fops_put(old_fops); |
1761 | out: | 1920 | out: |
1762 | unlock_kernel(); | ||
1763 | return err; | 1921 | return err; |
1764 | } | 1922 | } |
1765 | 1923 | ||
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b1bd6dd32286..423e0e6031ab 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -286,6 +286,8 @@ static int joydev_open(struct inode *inode, struct file *file) | |||
286 | goto err_free_client; | 286 | goto err_free_client; |
287 | 287 | ||
288 | file->private_data = client; | 288 | file->private_data = client; |
289 | nonseekable_open(inode, file); | ||
290 | |||
289 | return 0; | 291 | return 0; |
290 | 292 | ||
291 | err_free_client: | 293 | err_free_client: |
@@ -775,6 +777,20 @@ static void joydev_cleanup(struct joydev *joydev) | |||
775 | input_close_device(handle); | 777 | input_close_device(handle); |
776 | } | 778 | } |
777 | 779 | ||
780 | |||
781 | static bool joydev_match(struct input_handler *handler, struct input_dev *dev) | ||
782 | { | ||
783 | /* Avoid touchpads and touchscreens */ | ||
784 | if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit)) | ||
785 | return false; | ||
786 | |||
787 | /* Avoid tablets, digitisers and similar devices */ | ||
788 | if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit)) | ||
789 | return false; | ||
790 | |||
791 | return true; | ||
792 | } | ||
793 | |||
778 | static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | 794 | static int joydev_connect(struct input_handler *handler, struct input_dev *dev, |
779 | const struct input_device_id *id) | 795 | const struct input_device_id *id) |
780 | { | 796 | { |
@@ -894,22 +910,6 @@ static void joydev_disconnect(struct input_handle *handle) | |||
894 | put_device(&joydev->dev); | 910 | put_device(&joydev->dev); |
895 | } | 911 | } |
896 | 912 | ||
897 | static const struct input_device_id joydev_blacklist[] = { | ||
898 | { | ||
899 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
900 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
901 | .evbit = { BIT_MASK(EV_KEY) }, | ||
902 | .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, | ||
903 | }, /* Avoid itouchpads and touchscreens */ | ||
904 | { | ||
905 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
906 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
907 | .evbit = { BIT_MASK(EV_KEY) }, | ||
908 | .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) }, | ||
909 | }, /* Avoid tablets, digitisers and similar devices */ | ||
910 | { } /* Terminating entry */ | ||
911 | }; | ||
912 | |||
913 | static const struct input_device_id joydev_ids[] = { | 913 | static const struct input_device_id joydev_ids[] = { |
914 | { | 914 | { |
915 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | 915 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | |
@@ -929,6 +929,24 @@ static const struct input_device_id joydev_ids[] = { | |||
929 | .evbit = { BIT_MASK(EV_ABS) }, | 929 | .evbit = { BIT_MASK(EV_ABS) }, |
930 | .absbit = { BIT_MASK(ABS_THROTTLE) }, | 930 | .absbit = { BIT_MASK(ABS_THROTTLE) }, |
931 | }, | 931 | }, |
932 | { | ||
933 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
934 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
935 | .evbit = { BIT_MASK(EV_KEY) }, | ||
936 | .keybit = {[BIT_WORD(BTN_JOYSTICK)] = BIT_MASK(BTN_JOYSTICK) }, | ||
937 | }, | ||
938 | { | ||
939 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
940 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
941 | .evbit = { BIT_MASK(EV_KEY) }, | ||
942 | .keybit = { [BIT_WORD(BTN_GAMEPAD)] = BIT_MASK(BTN_GAMEPAD) }, | ||
943 | }, | ||
944 | { | ||
945 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
946 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
947 | .evbit = { BIT_MASK(EV_KEY) }, | ||
948 | .keybit = { [BIT_WORD(BTN_TRIGGER_HAPPY)] = BIT_MASK(BTN_TRIGGER_HAPPY) }, | ||
949 | }, | ||
932 | { } /* Terminating entry */ | 950 | { } /* Terminating entry */ |
933 | }; | 951 | }; |
934 | 952 | ||
@@ -936,13 +954,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids); | |||
936 | 954 | ||
937 | static struct input_handler joydev_handler = { | 955 | static struct input_handler joydev_handler = { |
938 | .event = joydev_event, | 956 | .event = joydev_event, |
957 | .match = joydev_match, | ||
939 | .connect = joydev_connect, | 958 | .connect = joydev_connect, |
940 | .disconnect = joydev_disconnect, | 959 | .disconnect = joydev_disconnect, |
941 | .fops = &joydev_fops, | 960 | .fops = &joydev_fops, |
942 | .minor = JOYDEV_MINOR_BASE, | 961 | .minor = JOYDEV_MINOR_BASE, |
943 | .name = "joydev", | 962 | .name = "joydev", |
944 | .id_table = joydev_ids, | 963 | .id_table = joydev_ids, |
945 | .blacklist = joydev_blacklist, | ||
946 | }; | 964 | }; |
947 | 965 | ||
948 | static int __init joydev_init(void) | 966 | static int __init joydev_init(void) |
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index b11419590cfe..5b596165b571 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig | |||
@@ -221,6 +221,7 @@ config JOYSTICK_DB9 | |||
221 | config JOYSTICK_GAMECON | 221 | config JOYSTICK_GAMECON |
222 | tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads" | 222 | tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads" |
223 | depends on PARPORT | 223 | depends on PARPORT |
224 | select INPUT_FF_MEMLESS | ||
224 | ---help--- | 225 | ---help--- |
225 | Say Y here if you have a Nintendo Entertainment System gamepad, | 226 | Say Y here if you have a Nintendo Entertainment System gamepad, |
226 | Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad, | 227 | Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad, |
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 523959484753..8e7de5c7754f 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/parport.h> | 36 | #include <linux/parport.h> |
37 | #include <linux/input.h> | 37 | #include <linux/input.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/slab.h> | ||
39 | 40 | ||
40 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 41 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
41 | MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver"); | 42 | MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver"); |
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 07a32aff5a31..fbd62abb66f9 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c | |||
@@ -30,6 +30,8 @@ | |||
30 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 30 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
34 | |||
33 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
34 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
35 | #include <linux/module.h> | 37 | #include <linux/module.h> |
@@ -37,6 +39,7 @@ | |||
37 | #include <linux/parport.h> | 39 | #include <linux/parport.h> |
38 | #include <linux/input.h> | 40 | #include <linux/input.h> |
39 | #include <linux/mutex.h> | 41 | #include <linux/mutex.h> |
42 | #include <linux/slab.h> | ||
40 | 43 | ||
41 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 44 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
42 | MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); | 45 | MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); |
@@ -61,48 +64,73 @@ MODULE_PARM_DESC(map3, "Describes third set of devices"); | |||
61 | 64 | ||
62 | /* see also gs_psx_delay parameter in PSX support section */ | 65 | /* see also gs_psx_delay parameter in PSX support section */ |
63 | 66 | ||
64 | #define GC_SNES 1 | 67 | enum gc_type { |
65 | #define GC_NES 2 | 68 | GC_NONE = 0, |
66 | #define GC_NES4 3 | 69 | GC_SNES, |
67 | #define GC_MULTI 4 | 70 | GC_NES, |
68 | #define GC_MULTI2 5 | 71 | GC_NES4, |
69 | #define GC_N64 6 | 72 | GC_MULTI, |
70 | #define GC_PSX 7 | 73 | GC_MULTI2, |
71 | #define GC_DDR 8 | 74 | GC_N64, |
72 | #define GC_SNESMOUSE 9 | 75 | GC_PSX, |
73 | 76 | GC_DDR, | |
74 | #define GC_MAX 9 | 77 | GC_SNESMOUSE, |
78 | GC_MAX | ||
79 | }; | ||
75 | 80 | ||
76 | #define GC_REFRESH_TIME HZ/100 | 81 | #define GC_REFRESH_TIME HZ/100 |
77 | 82 | ||
83 | struct gc_pad { | ||
84 | struct input_dev *dev; | ||
85 | enum gc_type type; | ||
86 | char phys[32]; | ||
87 | }; | ||
88 | |||
78 | struct gc { | 89 | struct gc { |
79 | struct pardevice *pd; | 90 | struct pardevice *pd; |
91 | struct gc_pad pads[GC_MAX_DEVICES]; | ||
80 | struct input_dev *dev[GC_MAX_DEVICES]; | 92 | struct input_dev *dev[GC_MAX_DEVICES]; |
81 | struct timer_list timer; | 93 | struct timer_list timer; |
82 | unsigned char pads[GC_MAX + 1]; | 94 | int pad_count[GC_MAX]; |
83 | int used; | 95 | int used; |
84 | struct mutex mutex; | 96 | struct mutex mutex; |
85 | char phys[GC_MAX_DEVICES][32]; | 97 | }; |
98 | |||
99 | struct gc_subdev { | ||
100 | unsigned int idx; | ||
86 | }; | 101 | }; |
87 | 102 | ||
88 | static struct gc *gc_base[3]; | 103 | static struct gc *gc_base[3]; |
89 | 104 | ||
90 | static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; | 105 | static const int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; |
106 | |||
107 | static const char *gc_names[] = { | ||
108 | NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", | ||
109 | "Multisystem 2-button joystick", "N64 controller", "PSX controller", | ||
110 | "PSX DDR controller", "SNES mouse" | ||
111 | }; | ||
91 | 112 | ||
92 | static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", | ||
93 | "Multisystem 2-button joystick", "N64 controller", "PSX controller", | ||
94 | "PSX DDR controller", "SNES mouse" }; | ||
95 | /* | 113 | /* |
96 | * N64 support. | 114 | * N64 support. |
97 | */ | 115 | */ |
98 | 116 | ||
99 | static unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; | 117 | static const unsigned char gc_n64_bytes[] = { 0, 1, 13, 15, 14, 12, 10, 11, 2, 3 }; |
100 | static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START }; | 118 | static const short gc_n64_btn[] = { |
119 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, | ||
120 | BTN_TL, BTN_TR, BTN_TRIGGER, BTN_START | ||
121 | }; | ||
101 | 122 | ||
102 | #define GC_N64_LENGTH 32 /* N64 bit length, not including stop bit */ | 123 | #define GC_N64_LENGTH 32 /* N64 bit length, not including stop bit */ |
103 | #define GC_N64_REQUEST_LENGTH 37 /* transmit request sequence is 9 bits long */ | 124 | #define GC_N64_STOP_LENGTH 5 /* Length of encoded stop bit */ |
125 | #define GC_N64_CMD_00 0x11111111UL | ||
126 | #define GC_N64_CMD_01 0xd1111111UL | ||
127 | #define GC_N64_CMD_03 0xdd111111UL | ||
128 | #define GC_N64_CMD_1b 0xdd1dd111UL | ||
129 | #define GC_N64_CMD_c0 0x111111ddUL | ||
130 | #define GC_N64_CMD_80 0x1111111dUL | ||
131 | #define GC_N64_STOP_BIT 0x1d /* Encoded stop bit */ | ||
132 | #define GC_N64_REQUEST_DATA GC_N64_CMD_01 /* the request data command */ | ||
104 | #define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */ | 133 | #define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */ |
105 | #define GC_N64_REQUEST 0x1dd1111111ULL /* the request data command (encoded for 000000011) */ | ||
106 | #define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */ | 134 | #define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */ |
107 | /* GC_N64_DWS > 24 is known to fail */ | 135 | /* GC_N64_DWS > 24 is known to fail */ |
108 | #define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */ | 136 | #define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */ |
@@ -114,8 +142,40 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, | |||
114 | #define GC_N64_CLOCK 0x02 /* clock bits for read */ | 142 | #define GC_N64_CLOCK 0x02 /* clock bits for read */ |
115 | 143 | ||
116 | /* | 144 | /* |
145 | * Used for rumble code. | ||
146 | */ | ||
147 | |||
148 | /* Send encoded command */ | ||
149 | static void gc_n64_send_command(struct gc *gc, unsigned long cmd, | ||
150 | unsigned char target) | ||
151 | { | ||
152 | struct parport *port = gc->pd->port; | ||
153 | int i; | ||
154 | |||
155 | for (i = 0; i < GC_N64_LENGTH; i++) { | ||
156 | unsigned char data = (cmd >> i) & 1 ? target : 0; | ||
157 | parport_write_data(port, GC_N64_POWER_W | data); | ||
158 | udelay(GC_N64_DWS); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | /* Send stop bit */ | ||
163 | static void gc_n64_send_stop_bit(struct gc *gc, unsigned char target) | ||
164 | { | ||
165 | struct parport *port = gc->pd->port; | ||
166 | int i; | ||
167 | |||
168 | for (i = 0; i < GC_N64_STOP_LENGTH; i++) { | ||
169 | unsigned char data = (GC_N64_STOP_BIT >> i) & 1 ? target : 0; | ||
170 | parport_write_data(port, GC_N64_POWER_W | data); | ||
171 | udelay(GC_N64_DWS); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | /* | ||
117 | * gc_n64_read_packet() reads an N64 packet. | 176 | * gc_n64_read_packet() reads an N64 packet. |
118 | * Each pad uses one bit per byte. So all pads connected to this port are read in parallel. | 177 | * Each pad uses one bit per byte. So all pads connected to this port |
178 | * are read in parallel. | ||
119 | */ | 179 | */ |
120 | 180 | ||
121 | static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | 181 | static void gc_n64_read_packet(struct gc *gc, unsigned char *data) |
@@ -128,14 +188,13 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
128 | */ | 188 | */ |
129 | 189 | ||
130 | local_irq_save(flags); | 190 | local_irq_save(flags); |
131 | for (i = 0; i < GC_N64_REQUEST_LENGTH; i++) { | 191 | gc_n64_send_command(gc, GC_N64_REQUEST_DATA, GC_N64_OUT); |
132 | parport_write_data(gc->pd->port, GC_N64_POWER_W | ((GC_N64_REQUEST >> i) & 1 ? GC_N64_OUT : 0)); | 192 | gc_n64_send_stop_bit(gc, GC_N64_OUT); |
133 | udelay(GC_N64_DWS); | ||
134 | } | ||
135 | local_irq_restore(flags); | 193 | local_irq_restore(flags); |
136 | 194 | ||
137 | /* | 195 | /* |
138 | * Wait for the pad response to be loaded into the 33-bit register of the adapter | 196 | * Wait for the pad response to be loaded into the 33-bit register |
197 | * of the adapter. | ||
139 | */ | 198 | */ |
140 | 199 | ||
141 | udelay(GC_N64_DELAY); | 200 | udelay(GC_N64_DELAY); |
@@ -146,13 +205,15 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
146 | 205 | ||
147 | for (i = 0; i < GC_N64_LENGTH; i++) { | 206 | for (i = 0; i < GC_N64_LENGTH; i++) { |
148 | parport_write_data(gc->pd->port, GC_N64_POWER_R); | 207 | parport_write_data(gc->pd->port, GC_N64_POWER_R); |
208 | udelay(2); | ||
149 | data[i] = parport_read_status(gc->pd->port); | 209 | data[i] = parport_read_status(gc->pd->port); |
150 | parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK); | 210 | parport_write_data(gc->pd->port, GC_N64_POWER_R | GC_N64_CLOCK); |
151 | } | 211 | } |
152 | 212 | ||
153 | /* | 213 | /* |
154 | * We must wait 200 ms here for the controller to reinitialize before the next read request. | 214 | * We must wait 200 ms here for the controller to reinitialize before |
155 | * No worries as long as gc_read is polled less frequently than this. | 215 | * the next read request. No worries as long as gc_read is polled less |
216 | * frequently than this. | ||
156 | */ | 217 | */ |
157 | 218 | ||
158 | } | 219 | } |
@@ -160,45 +221,112 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
160 | static void gc_n64_process_packet(struct gc *gc) | 221 | static void gc_n64_process_packet(struct gc *gc) |
161 | { | 222 | { |
162 | unsigned char data[GC_N64_LENGTH]; | 223 | unsigned char data[GC_N64_LENGTH]; |
163 | signed char axes[2]; | ||
164 | struct input_dev *dev; | 224 | struct input_dev *dev; |
165 | int i, j, s; | 225 | int i, j, s; |
226 | signed char x, y; | ||
166 | 227 | ||
167 | gc_n64_read_packet(gc, data); | 228 | gc_n64_read_packet(gc, data); |
168 | 229 | ||
169 | for (i = 0; i < GC_MAX_DEVICES; i++) { | 230 | for (i = 0; i < GC_MAX_DEVICES; i++) { |
170 | 231 | ||
171 | dev = gc->dev[i]; | 232 | if (gc->pads[i].type != GC_N64) |
172 | if (!dev) | ||
173 | continue; | 233 | continue; |
174 | 234 | ||
235 | dev = gc->pads[i].dev; | ||
175 | s = gc_status_bit[i]; | 236 | s = gc_status_bit[i]; |
176 | 237 | ||
177 | if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { | 238 | if (s & ~(data[8] | data[9])) { |
178 | 239 | ||
179 | axes[0] = axes[1] = 0; | 240 | x = y = 0; |
180 | 241 | ||
181 | for (j = 0; j < 8; j++) { | 242 | for (j = 0; j < 8; j++) { |
182 | if (data[23 - j] & s) | 243 | if (data[23 - j] & s) |
183 | axes[0] |= 1 << j; | 244 | x |= 1 << j; |
184 | if (data[31 - j] & s) | 245 | if (data[31 - j] & s) |
185 | axes[1] |= 1 << j; | 246 | y |= 1 << j; |
186 | } | 247 | } |
187 | 248 | ||
188 | input_report_abs(dev, ABS_X, axes[0]); | 249 | input_report_abs(dev, ABS_X, x); |
189 | input_report_abs(dev, ABS_Y, -axes[1]); | 250 | input_report_abs(dev, ABS_Y, -y); |
190 | 251 | ||
191 | input_report_abs(dev, ABS_HAT0X, !(s & data[6]) - !(s & data[7])); | 252 | input_report_abs(dev, ABS_HAT0X, |
192 | input_report_abs(dev, ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); | 253 | !(s & data[6]) - !(s & data[7])); |
254 | input_report_abs(dev, ABS_HAT0Y, | ||
255 | !(s & data[4]) - !(s & data[5])); | ||
193 | 256 | ||
194 | for (j = 0; j < 10; j++) | 257 | for (j = 0; j < 10; j++) |
195 | input_report_key(dev, gc_n64_btn[j], s & data[gc_n64_bytes[j]]); | 258 | input_report_key(dev, gc_n64_btn[j], |
259 | s & data[gc_n64_bytes[j]]); | ||
196 | 260 | ||
197 | input_sync(dev); | 261 | input_sync(dev); |
198 | } | 262 | } |
199 | } | 263 | } |
200 | } | 264 | } |
201 | 265 | ||
266 | static int gc_n64_play_effect(struct input_dev *dev, void *data, | ||
267 | struct ff_effect *effect) | ||
268 | { | ||
269 | int i; | ||
270 | unsigned long flags; | ||
271 | struct gc *gc = input_get_drvdata(dev); | ||
272 | struct gc_subdev *sdev = data; | ||
273 | unsigned char target = 1 << sdev->idx; /* select desired pin */ | ||
274 | |||
275 | if (effect->type == FF_RUMBLE) { | ||
276 | struct ff_rumble_effect *rumble = &effect->u.rumble; | ||
277 | unsigned int cmd = | ||
278 | rumble->strong_magnitude || rumble->weak_magnitude ? | ||
279 | GC_N64_CMD_01 : GC_N64_CMD_00; | ||
280 | |||
281 | local_irq_save(flags); | ||
282 | |||
283 | /* Init Rumble - 0x03, 0x80, 0x01, (34)0x80 */ | ||
284 | gc_n64_send_command(gc, GC_N64_CMD_03, target); | ||
285 | gc_n64_send_command(gc, GC_N64_CMD_80, target); | ||
286 | gc_n64_send_command(gc, GC_N64_CMD_01, target); | ||
287 | for (i = 0; i < 32; i++) | ||
288 | gc_n64_send_command(gc, GC_N64_CMD_80, target); | ||
289 | gc_n64_send_stop_bit(gc, target); | ||
290 | |||
291 | udelay(GC_N64_DELAY); | ||
292 | |||
293 | /* Now start or stop it - 0x03, 0xc0, 0zx1b, (32)0x01/0x00 */ | ||
294 | gc_n64_send_command(gc, GC_N64_CMD_03, target); | ||
295 | gc_n64_send_command(gc, GC_N64_CMD_c0, target); | ||
296 | gc_n64_send_command(gc, GC_N64_CMD_1b, target); | ||
297 | for (i = 0; i < 32; i++) | ||
298 | gc_n64_send_command(gc, cmd, target); | ||
299 | gc_n64_send_stop_bit(gc, target); | ||
300 | |||
301 | local_irq_restore(flags); | ||
302 | |||
303 | } | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static int __init gc_n64_init_ff(struct input_dev *dev, int i) | ||
309 | { | ||
310 | struct gc_subdev *sdev; | ||
311 | int err; | ||
312 | |||
313 | sdev = kmalloc(sizeof(*sdev), GFP_KERNEL); | ||
314 | if (!sdev) | ||
315 | return -ENOMEM; | ||
316 | |||
317 | sdev->idx = i; | ||
318 | |||
319 | input_set_capability(dev, EV_FF, FF_RUMBLE); | ||
320 | |||
321 | err = input_ff_create_memless(dev, sdev, gc_n64_play_effect); | ||
322 | if (err) { | ||
323 | kfree(sdev); | ||
324 | return err; | ||
325 | } | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
202 | /* | 330 | /* |
203 | * NES/SNES support. | 331 | * NES/SNES support. |
204 | */ | 332 | */ |
@@ -214,9 +342,11 @@ static void gc_n64_process_packet(struct gc *gc) | |||
214 | #define GC_NES_CLOCK 0x01 | 342 | #define GC_NES_CLOCK 0x01 |
215 | #define GC_NES_LATCH 0x02 | 343 | #define GC_NES_LATCH 0x02 |
216 | 344 | ||
217 | static unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 }; | 345 | static const unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 }; |
218 | static unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 }; | 346 | static const unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 }; |
219 | static short gc_snes_btn[] = { BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR }; | 347 | static const short gc_snes_btn[] = { |
348 | BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR | ||
349 | }; | ||
220 | 350 | ||
221 | /* | 351 | /* |
222 | * gc_nes_read_packet() reads a NES/SNES packet. | 352 | * gc_nes_read_packet() reads a NES/SNES packet. |
@@ -244,40 +374,51 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data) | |||
244 | static void gc_nes_process_packet(struct gc *gc) | 374 | static void gc_nes_process_packet(struct gc *gc) |
245 | { | 375 | { |
246 | unsigned char data[GC_SNESMOUSE_LENGTH]; | 376 | unsigned char data[GC_SNESMOUSE_LENGTH]; |
377 | struct gc_pad *pad; | ||
247 | struct input_dev *dev; | 378 | struct input_dev *dev; |
248 | int i, j, s, len; | 379 | int i, j, s, len; |
249 | char x_rel, y_rel; | 380 | char x_rel, y_rel; |
250 | 381 | ||
251 | len = gc->pads[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH : | 382 | len = gc->pad_count[GC_SNESMOUSE] ? GC_SNESMOUSE_LENGTH : |
252 | (gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH); | 383 | (gc->pad_count[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH); |
253 | 384 | ||
254 | gc_nes_read_packet(gc, len, data); | 385 | gc_nes_read_packet(gc, len, data); |
255 | 386 | ||
256 | for (i = 0; i < GC_MAX_DEVICES; i++) { | 387 | for (i = 0; i < GC_MAX_DEVICES; i++) { |
257 | 388 | ||
389 | pad = &gc->pads[i]; | ||
258 | dev = gc->dev[i]; | 390 | dev = gc->dev[i]; |
259 | if (!dev) | ||
260 | continue; | ||
261 | |||
262 | s = gc_status_bit[i]; | 391 | s = gc_status_bit[i]; |
263 | 392 | ||
264 | if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { | 393 | switch (pad->type) { |
394 | |||
395 | case GC_NES: | ||
396 | |||
265 | input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); | 397 | input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); |
266 | input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); | 398 | input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); |
267 | } | ||
268 | 399 | ||
269 | if (s & gc->pads[GC_NES]) | ||
270 | for (j = 0; j < 4; j++) | 400 | for (j = 0; j < 4; j++) |
271 | input_report_key(dev, gc_snes_btn[j], s & data[gc_nes_bytes[j]]); | 401 | input_report_key(dev, gc_snes_btn[j], |
402 | s & data[gc_nes_bytes[j]]); | ||
403 | input_sync(dev); | ||
404 | break; | ||
405 | |||
406 | case GC_SNES: | ||
407 | |||
408 | input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); | ||
409 | input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); | ||
272 | 410 | ||
273 | if (s & gc->pads[GC_SNES]) | ||
274 | for (j = 0; j < 8; j++) | 411 | for (j = 0; j < 8; j++) |
275 | input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); | 412 | input_report_key(dev, gc_snes_btn[j], |
413 | s & data[gc_snes_bytes[j]]); | ||
414 | input_sync(dev); | ||
415 | break; | ||
276 | 416 | ||
277 | if (s & gc->pads[GC_SNESMOUSE]) { | 417 | case GC_SNESMOUSE: |
278 | /* | 418 | /* |
279 | * The 4 unused bits from SNES controllers appear to be ID bits | 419 | * The 4 unused bits from SNES controllers appear |
280 | * so use them to make sure iwe are dealing with a mouse. | 420 | * to be ID bits so use them to make sure we are |
421 | * dealing with a mouse. | ||
281 | * gamepad is connected. This is important since | 422 | * gamepad is connected. This is important since |
282 | * my SNES gamepad sends 1's for bits 16-31, which | 423 | * my SNES gamepad sends 1's for bits 16-31, which |
283 | * cause the mouse pointer to quickly move to the | 424 | * cause the mouse pointer to quickly move to the |
@@ -310,9 +451,14 @@ static void gc_nes_process_packet(struct gc *gc) | |||
310 | y_rel = -y_rel; | 451 | y_rel = -y_rel; |
311 | input_report_rel(dev, REL_Y, y_rel); | 452 | input_report_rel(dev, REL_Y, y_rel); |
312 | } | 453 | } |
454 | |||
455 | input_sync(dev); | ||
313 | } | 456 | } |
457 | break; | ||
458 | |||
459 | default: | ||
460 | break; | ||
314 | } | 461 | } |
315 | input_sync(dev); | ||
316 | } | 462 | } |
317 | } | 463 | } |
318 | 464 | ||
@@ -340,29 +486,35 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data) | |||
340 | static void gc_multi_process_packet(struct gc *gc) | 486 | static void gc_multi_process_packet(struct gc *gc) |
341 | { | 487 | { |
342 | unsigned char data[GC_MULTI2_LENGTH]; | 488 | unsigned char data[GC_MULTI2_LENGTH]; |
489 | int data_len = gc->pad_count[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH; | ||
490 | struct gc_pad *pad; | ||
343 | struct input_dev *dev; | 491 | struct input_dev *dev; |
344 | int i, s; | 492 | int i, s; |
345 | 493 | ||
346 | gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data); | 494 | gc_multi_read_packet(gc, data_len, data); |
347 | 495 | ||
348 | for (i = 0; i < GC_MAX_DEVICES; i++) { | 496 | for (i = 0; i < GC_MAX_DEVICES; i++) { |
349 | 497 | pad = &gc->pads[i]; | |
350 | dev = gc->dev[i]; | 498 | dev = pad->dev; |
351 | if (!dev) | ||
352 | continue; | ||
353 | |||
354 | s = gc_status_bit[i]; | 499 | s = gc_status_bit[i]; |
355 | 500 | ||
356 | if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { | 501 | switch (pad->type) { |
357 | input_report_abs(dev, ABS_X, !(s & data[2]) - !(s & data[3])); | 502 | case GC_MULTI2: |
358 | input_report_abs(dev, ABS_Y, !(s & data[0]) - !(s & data[1])); | ||
359 | input_report_key(dev, BTN_TRIGGER, s & data[4]); | ||
360 | } | ||
361 | |||
362 | if (s & gc->pads[GC_MULTI2]) | ||
363 | input_report_key(dev, BTN_THUMB, s & data[5]); | 503 | input_report_key(dev, BTN_THUMB, s & data[5]); |
504 | /* fall through */ | ||
364 | 505 | ||
365 | input_sync(dev); | 506 | case GC_MULTI: |
507 | input_report_abs(dev, ABS_X, | ||
508 | !(s & data[2]) - !(s & data[3])); | ||
509 | input_report_abs(dev, ABS_Y, | ||
510 | !(s & data[0]) - !(s & data[1])); | ||
511 | input_report_key(dev, BTN_TRIGGER, s & data[4]); | ||
512 | input_sync(dev); | ||
513 | break; | ||
514 | |||
515 | default: | ||
516 | break; | ||
517 | } | ||
366 | } | 518 | } |
367 | } | 519 | } |
368 | 520 | ||
@@ -398,30 +550,41 @@ static int gc_psx_delay = GC_PSX_DELAY; | |||
398 | module_param_named(psx_delay, gc_psx_delay, uint, 0); | 550 | module_param_named(psx_delay, gc_psx_delay, uint, 0); |
399 | MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)"); | 551 | MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)"); |
400 | 552 | ||
401 | static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y }; | 553 | static const short gc_psx_abs[] = { |
402 | static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, | 554 | ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y |
403 | BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR }; | 555 | }; |
404 | static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; | 556 | static const short gc_psx_btn[] = { |
557 | BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y, | ||
558 | BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR | ||
559 | }; | ||
560 | static const short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; | ||
405 | 561 | ||
406 | /* | 562 | /* |
407 | * gc_psx_command() writes 8bit command and reads 8bit data from | 563 | * gc_psx_command() writes 8bit command and reads 8bit data from |
408 | * the psx pad. | 564 | * the psx pad. |
409 | */ | 565 | */ |
410 | 566 | ||
411 | static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVICES]) | 567 | static void gc_psx_command(struct gc *gc, int b, unsigned char *data) |
412 | { | 568 | { |
569 | struct parport *port = gc->pd->port; | ||
413 | int i, j, cmd, read; | 570 | int i, j, cmd, read; |
414 | 571 | ||
415 | for (i = 0; i < GC_MAX_DEVICES; i++) | 572 | memset(data, 0, GC_MAX_DEVICES); |
416 | data[i] = 0; | ||
417 | 573 | ||
418 | for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) { | 574 | for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) { |
419 | cmd = (b & 1) ? GC_PSX_COMMAND : 0; | 575 | cmd = (b & 1) ? GC_PSX_COMMAND : 0; |
420 | parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); | 576 | parport_write_data(port, cmd | GC_PSX_POWER); |
421 | udelay(gc_psx_delay); | 577 | udelay(gc_psx_delay); |
422 | read = parport_read_status(gc->pd->port) ^ 0x80; | 578 | |
423 | for (j = 0; j < GC_MAX_DEVICES; j++) | 579 | read = parport_read_status(port) ^ 0x80; |
424 | data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0; | 580 | |
581 | for (j = 0; j < GC_MAX_DEVICES; j++) { | ||
582 | struct gc_pad *pad = &gc->pads[i]; | ||
583 | |||
584 | if (pad->type == GC_PSX || pad->type == GC_DDR) | ||
585 | data[j] |= (read & gc_status_bit[j]) ? (1 << i) : 0; | ||
586 | } | ||
587 | |||
425 | parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); | 588 | parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); |
426 | udelay(gc_psx_delay); | 589 | udelay(gc_psx_delay); |
427 | } | 590 | } |
@@ -432,31 +595,40 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVIC | |||
432 | * device identifier code. | 595 | * device identifier code. |
433 | */ | 596 | */ |
434 | 597 | ||
435 | static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES], | 598 | static void gc_psx_read_packet(struct gc *gc, |
599 | unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES], | ||
436 | unsigned char id[GC_MAX_DEVICES]) | 600 | unsigned char id[GC_MAX_DEVICES]) |
437 | { | 601 | { |
438 | int i, j, max_len = 0; | 602 | int i, j, max_len = 0; |
439 | unsigned long flags; | 603 | unsigned long flags; |
440 | unsigned char data2[GC_MAX_DEVICES]; | 604 | unsigned char data2[GC_MAX_DEVICES]; |
441 | 605 | ||
442 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ | 606 | /* Select pad */ |
607 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); | ||
443 | udelay(gc_psx_delay); | 608 | udelay(gc_psx_delay); |
444 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); /* Deselect, begin command */ | 609 | /* Deselect, begin command */ |
610 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER); | ||
445 | udelay(gc_psx_delay); | 611 | udelay(gc_psx_delay); |
446 | 612 | ||
447 | local_irq_save(flags); | 613 | local_irq_save(flags); |
448 | 614 | ||
449 | gc_psx_command(gc, 0x01, data2); /* Access pad */ | 615 | gc_psx_command(gc, 0x01, data2); /* Access pad */ |
450 | gc_psx_command(gc, 0x42, id); /* Get device ids */ | 616 | gc_psx_command(gc, 0x42, id); /* Get device ids */ |
451 | gc_psx_command(gc, 0, data2); /* Dump status */ | 617 | gc_psx_command(gc, 0, data2); /* Dump status */ |
618 | |||
619 | /* Find the longest pad */ | ||
620 | for (i = 0; i < GC_MAX_DEVICES; i++) { | ||
621 | struct gc_pad *pad = &gc->pads[i]; | ||
452 | 622 | ||
453 | for (i =0; i < GC_MAX_DEVICES; i++) /* Find the longest pad */ | 623 | if ((pad->type == GC_PSX || pad->type == GC_DDR) && |
454 | if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) | 624 | GC_PSX_LEN(id[i]) > max_len && |
455 | && (GC_PSX_LEN(id[i]) > max_len) | 625 | GC_PSX_LEN(id[i]) <= GC_PSX_BYTES) { |
456 | && (GC_PSX_LEN(id[i]) <= GC_PSX_BYTES)) | ||
457 | max_len = GC_PSX_LEN(id[i]); | 626 | max_len = GC_PSX_LEN(id[i]); |
627 | } | ||
628 | } | ||
458 | 629 | ||
459 | for (i = 0; i < max_len; i++) { /* Read in all the data */ | 630 | /* Read in all the data */ |
631 | for (i = 0; i < max_len; i++) { | ||
460 | gc_psx_command(gc, 0, data2); | 632 | gc_psx_command(gc, 0, data2); |
461 | for (j = 0; j < GC_MAX_DEVICES; j++) | 633 | for (j = 0; j < GC_MAX_DEVICES; j++) |
462 | data[j][i] = data2[j]; | 634 | data[j][i] = data2[j]; |
@@ -466,86 +638,104 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES] | |||
466 | 638 | ||
467 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); | 639 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); |
468 | 640 | ||
469 | for(i = 0; i < GC_MAX_DEVICES; i++) /* Set id's to the real value */ | 641 | /* Set id's to the real value */ |
642 | for (i = 0; i < GC_MAX_DEVICES; i++) | ||
470 | id[i] = GC_PSX_ID(id[i]); | 643 | id[i] = GC_PSX_ID(id[i]); |
471 | } | 644 | } |
472 | 645 | ||
473 | static void gc_psx_process_packet(struct gc *gc) | 646 | static void gc_psx_report_one(struct gc_pad *pad, unsigned char psx_type, |
647 | unsigned char *data) | ||
474 | { | 648 | { |
475 | unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; | 649 | struct input_dev *dev = pad->dev; |
476 | unsigned char id[GC_MAX_DEVICES]; | 650 | int i; |
477 | struct input_dev *dev; | ||
478 | int i, j; | ||
479 | 651 | ||
480 | gc_psx_read_packet(gc, data, id); | 652 | switch (psx_type) { |
481 | 653 | ||
482 | for (i = 0; i < GC_MAX_DEVICES; i++) { | 654 | case GC_PSX_RUMBLE: |
483 | 655 | ||
484 | dev = gc->dev[i]; | 656 | input_report_key(dev, BTN_THUMBL, ~data[0] & 0x04); |
485 | if (!dev) | 657 | input_report_key(dev, BTN_THUMBR, ~data[0] & 0x02); |
486 | continue; | ||
487 | 658 | ||
488 | switch (id[i]) { | 659 | case GC_PSX_NEGCON: |
660 | case GC_PSX_ANALOG: | ||
489 | 661 | ||
490 | case GC_PSX_RUMBLE: | 662 | if (pad->type == GC_DDR) { |
663 | for (i = 0; i < 4; i++) | ||
664 | input_report_key(dev, gc_psx_ddr_btn[i], | ||
665 | ~data[0] & (0x10 << i)); | ||
666 | } else { | ||
667 | for (i = 0; i < 4; i++) | ||
668 | input_report_abs(dev, gc_psx_abs[i + 2], | ||
669 | data[i + 2]); | ||
491 | 670 | ||
492 | input_report_key(dev, BTN_THUMBL, ~data[i][0] & 0x04); | 671 | input_report_abs(dev, ABS_X, |
493 | input_report_key(dev, BTN_THUMBR, ~data[i][0] & 0x02); | 672 | !!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127); |
673 | input_report_abs(dev, ABS_Y, | ||
674 | !!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127); | ||
675 | } | ||
494 | 676 | ||
495 | case GC_PSX_NEGCON: | 677 | for (i = 0; i < 8; i++) |
496 | case GC_PSX_ANALOG: | 678 | input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i)); |
497 | 679 | ||
498 | if (gc->pads[GC_DDR] & gc_status_bit[i]) { | 680 | input_report_key(dev, BTN_START, ~data[0] & 0x08); |
499 | for(j = 0; j < 4; j++) | 681 | input_report_key(dev, BTN_SELECT, ~data[0] & 0x01); |
500 | input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); | ||
501 | } else { | ||
502 | for (j = 0; j < 4; j++) | ||
503 | input_report_abs(dev, gc_psx_abs[j + 2], data[i][j + 2]); | ||
504 | 682 | ||
505 | input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); | 683 | input_sync(dev); |
506 | input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); | ||
507 | } | ||
508 | 684 | ||
509 | for (j = 0; j < 8; j++) | 685 | break; |
510 | input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); | ||
511 | 686 | ||
512 | input_report_key(dev, BTN_START, ~data[i][0] & 0x08); | 687 | case GC_PSX_NORMAL: |
513 | input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); | ||
514 | 688 | ||
515 | input_sync(dev); | 689 | if (pad->type == GC_DDR) { |
690 | for (i = 0; i < 4; i++) | ||
691 | input_report_key(dev, gc_psx_ddr_btn[i], | ||
692 | ~data[0] & (0x10 << i)); | ||
693 | } else { | ||
694 | input_report_abs(dev, ABS_X, | ||
695 | !!(data[0] & 0x80) * 128 + !(data[0] & 0x20) * 127); | ||
696 | input_report_abs(dev, ABS_Y, | ||
697 | !!(data[0] & 0x10) * 128 + !(data[0] & 0x40) * 127); | ||
516 | 698 | ||
517 | break; | 699 | /* |
518 | 700 | * For some reason if the extra axes are left unset | |
519 | case GC_PSX_NORMAL: | 701 | * they drift. |
520 | if (gc->pads[GC_DDR] & gc_status_bit[i]) { | 702 | * for (i = 0; i < 4; i++) |
521 | for(j = 0; j < 4; j++) | 703 | input_report_abs(dev, gc_psx_abs[i + 2], 128); |
522 | input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); | 704 | * This needs to be debugged properly, |
523 | } else { | 705 | * maybe fuzz processing needs to be done |
524 | input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); | 706 | * in input_sync() |
525 | input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); | 707 | * --vojtech |
526 | 708 | */ | |
527 | /* for some reason if the extra axes are left unset they drift */ | 709 | } |
528 | /* for (j = 0; j < 4; j++) | ||
529 | input_report_abs(dev, gc_psx_abs[j + 2], 128); | ||
530 | * This needs to be debugged properly, | ||
531 | * maybe fuzz processing needs to be done in input_sync() | ||
532 | * --vojtech | ||
533 | */ | ||
534 | } | ||
535 | 710 | ||
536 | for (j = 0; j < 8; j++) | 711 | for (i = 0; i < 8; i++) |
537 | input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); | 712 | input_report_key(dev, gc_psx_btn[i], ~data[1] & (1 << i)); |
538 | 713 | ||
539 | input_report_key(dev, BTN_START, ~data[i][0] & 0x08); | 714 | input_report_key(dev, BTN_START, ~data[0] & 0x08); |
540 | input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); | 715 | input_report_key(dev, BTN_SELECT, ~data[0] & 0x01); |
541 | 716 | ||
542 | input_sync(dev); | 717 | input_sync(dev); |
543 | 718 | ||
544 | break; | 719 | break; |
545 | 720 | ||
546 | case 0: /* not a pad, ignore */ | 721 | default: /* not a pad, ignore */ |
547 | break; | 722 | break; |
548 | } | 723 | } |
724 | } | ||
725 | |||
726 | static void gc_psx_process_packet(struct gc *gc) | ||
727 | { | ||
728 | unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; | ||
729 | unsigned char id[GC_MAX_DEVICES]; | ||
730 | struct gc_pad *pad; | ||
731 | int i; | ||
732 | |||
733 | gc_psx_read_packet(gc, data, id); | ||
734 | |||
735 | for (i = 0; i < GC_MAX_DEVICES; i++) { | ||
736 | pad = &gc->pads[i]; | ||
737 | if (pad->type == GC_PSX || pad->type == GC_DDR) | ||
738 | gc_psx_report_one(pad, id[i], data[i]); | ||
549 | } | 739 | } |
550 | } | 740 | } |
551 | 741 | ||
@@ -561,28 +751,31 @@ static void gc_timer(unsigned long private) | |||
561 | * N64 pads - must be read first, any read confuses them for 200 us | 751 | * N64 pads - must be read first, any read confuses them for 200 us |
562 | */ | 752 | */ |
563 | 753 | ||
564 | if (gc->pads[GC_N64]) | 754 | if (gc->pad_count[GC_N64]) |
565 | gc_n64_process_packet(gc); | 755 | gc_n64_process_packet(gc); |
566 | 756 | ||
567 | /* | 757 | /* |
568 | * NES and SNES pads or mouse | 758 | * NES and SNES pads or mouse |
569 | */ | 759 | */ |
570 | 760 | ||
571 | if (gc->pads[GC_NES] || gc->pads[GC_SNES] || gc->pads[GC_SNESMOUSE]) | 761 | if (gc->pad_count[GC_NES] || |
762 | gc->pad_count[GC_SNES] || | ||
763 | gc->pad_count[GC_SNESMOUSE]) { | ||
572 | gc_nes_process_packet(gc); | 764 | gc_nes_process_packet(gc); |
765 | } | ||
573 | 766 | ||
574 | /* | 767 | /* |
575 | * Multi and Multi2 joysticks | 768 | * Multi and Multi2 joysticks |
576 | */ | 769 | */ |
577 | 770 | ||
578 | if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) | 771 | if (gc->pad_count[GC_MULTI] || gc->pad_count[GC_MULTI2]) |
579 | gc_multi_process_packet(gc); | 772 | gc_multi_process_packet(gc); |
580 | 773 | ||
581 | /* | 774 | /* |
582 | * PSX controllers | 775 | * PSX controllers |
583 | */ | 776 | */ |
584 | 777 | ||
585 | if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) | 778 | if (gc->pad_count[GC_PSX] || gc->pad_count[GC_DDR]) |
586 | gc_psx_process_packet(gc); | 779 | gc_psx_process_packet(gc); |
587 | 780 | ||
588 | mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); | 781 | mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); |
@@ -622,25 +815,29 @@ static void gc_close(struct input_dev *dev) | |||
622 | 815 | ||
623 | static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) | 816 | static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) |
624 | { | 817 | { |
818 | struct gc_pad *pad = &gc->pads[idx]; | ||
625 | struct input_dev *input_dev; | 819 | struct input_dev *input_dev; |
626 | int i; | 820 | int i; |
821 | int err; | ||
627 | 822 | ||
628 | if (!pad_type) | 823 | if (pad_type < 1 || pad_type >= GC_MAX) { |
629 | return 0; | 824 | pr_err("Pad type %d unknown\n", pad_type); |
630 | |||
631 | if (pad_type < 1 || pad_type > GC_MAX) { | ||
632 | printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type); | ||
633 | return -EINVAL; | 825 | return -EINVAL; |
634 | } | 826 | } |
635 | 827 | ||
636 | gc->dev[idx] = input_dev = input_allocate_device(); | 828 | pad->dev = input_dev = input_allocate_device(); |
637 | if (!input_dev) { | 829 | if (!input_dev) { |
638 | printk(KERN_ERR "gamecon.c: Not enough memory for input device\n"); | 830 | pr_err("Not enough memory for input device\n"); |
639 | return -ENOMEM; | 831 | return -ENOMEM; |
640 | } | 832 | } |
641 | 833 | ||
834 | pad->type = pad_type; | ||
835 | |||
836 | snprintf(pad->phys, sizeof(pad->phys), | ||
837 | "%s/input%d", gc->pd->port->name, idx); | ||
838 | |||
642 | input_dev->name = gc_names[pad_type]; | 839 | input_dev->name = gc_names[pad_type]; |
643 | input_dev->phys = gc->phys[idx]; | 840 | input_dev->phys = pad->phys; |
644 | input_dev->id.bustype = BUS_PARPORT; | 841 | input_dev->id.bustype = BUS_PARPORT; |
645 | input_dev->id.vendor = 0x0001; | 842 | input_dev->id.vendor = 0x0001; |
646 | input_dev->id.product = pad_type; | 843 | input_dev->id.product = pad_type; |
@@ -659,61 +856,76 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
659 | } else | 856 | } else |
660 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 857 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
661 | 858 | ||
662 | gc->pads[0] |= gc_status_bit[idx]; | 859 | gc->pad_count[pad_type]++; |
663 | gc->pads[pad_type] |= gc_status_bit[idx]; | ||
664 | 860 | ||
665 | switch (pad_type) { | 861 | switch (pad_type) { |
666 | 862 | ||
667 | case GC_N64: | 863 | case GC_N64: |
668 | for (i = 0; i < 10; i++) | 864 | for (i = 0; i < 10; i++) |
669 | set_bit(gc_n64_btn[i], input_dev->keybit); | 865 | __set_bit(gc_n64_btn[i], input_dev->keybit); |
670 | |||
671 | for (i = 0; i < 2; i++) { | ||
672 | input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); | ||
673 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); | ||
674 | } | ||
675 | |||
676 | break; | ||
677 | |||
678 | case GC_SNESMOUSE: | ||
679 | set_bit(BTN_LEFT, input_dev->keybit); | ||
680 | set_bit(BTN_RIGHT, input_dev->keybit); | ||
681 | set_bit(REL_X, input_dev->relbit); | ||
682 | set_bit(REL_Y, input_dev->relbit); | ||
683 | break; | ||
684 | |||
685 | case GC_SNES: | ||
686 | for (i = 4; i < 8; i++) | ||
687 | set_bit(gc_snes_btn[i], input_dev->keybit); | ||
688 | case GC_NES: | ||
689 | for (i = 0; i < 4; i++) | ||
690 | set_bit(gc_snes_btn[i], input_dev->keybit); | ||
691 | break; | ||
692 | |||
693 | case GC_MULTI2: | ||
694 | set_bit(BTN_THUMB, input_dev->keybit); | ||
695 | case GC_MULTI: | ||
696 | set_bit(BTN_TRIGGER, input_dev->keybit); | ||
697 | break; | ||
698 | |||
699 | case GC_PSX: | ||
700 | for (i = 0; i < 6; i++) | ||
701 | input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2); | ||
702 | for (i = 0; i < 12; i++) | ||
703 | set_bit(gc_psx_btn[i], input_dev->keybit); | ||
704 | 866 | ||
705 | break; | 867 | for (i = 0; i < 2; i++) { |
868 | input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); | ||
869 | input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0); | ||
870 | } | ||
706 | 871 | ||
707 | case GC_DDR: | 872 | err = gc_n64_init_ff(input_dev, idx); |
708 | for (i = 0; i < 4; i++) | 873 | if (err) { |
709 | set_bit(gc_psx_ddr_btn[i], input_dev->keybit); | 874 | pr_warning("Failed to initiate rumble for N64 device %d\n", idx); |
710 | for (i = 0; i < 12; i++) | 875 | goto err_free_dev; |
711 | set_bit(gc_psx_btn[i], input_dev->keybit); | 876 | } |
712 | 877 | ||
713 | break; | 878 | break; |
879 | |||
880 | case GC_SNESMOUSE: | ||
881 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
882 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
883 | __set_bit(REL_X, input_dev->relbit); | ||
884 | __set_bit(REL_Y, input_dev->relbit); | ||
885 | break; | ||
886 | |||
887 | case GC_SNES: | ||
888 | for (i = 4; i < 8; i++) | ||
889 | __set_bit(gc_snes_btn[i], input_dev->keybit); | ||
890 | case GC_NES: | ||
891 | for (i = 0; i < 4; i++) | ||
892 | __set_bit(gc_snes_btn[i], input_dev->keybit); | ||
893 | break; | ||
894 | |||
895 | case GC_MULTI2: | ||
896 | __set_bit(BTN_THUMB, input_dev->keybit); | ||
897 | case GC_MULTI: | ||
898 | __set_bit(BTN_TRIGGER, input_dev->keybit); | ||
899 | break; | ||
900 | |||
901 | case GC_PSX: | ||
902 | for (i = 0; i < 6; i++) | ||
903 | input_set_abs_params(input_dev, | ||
904 | gc_psx_abs[i], 4, 252, 0, 2); | ||
905 | for (i = 0; i < 12; i++) | ||
906 | __set_bit(gc_psx_btn[i], input_dev->keybit); | ||
907 | |||
908 | break; | ||
909 | |||
910 | case GC_DDR: | ||
911 | for (i = 0; i < 4; i++) | ||
912 | __set_bit(gc_psx_ddr_btn[i], input_dev->keybit); | ||
913 | for (i = 0; i < 12; i++) | ||
914 | __set_bit(gc_psx_btn[i], input_dev->keybit); | ||
915 | |||
916 | break; | ||
714 | } | 917 | } |
715 | 918 | ||
919 | err = input_register_device(pad->dev); | ||
920 | if (err) | ||
921 | goto err_free_dev; | ||
922 | |||
716 | return 0; | 923 | return 0; |
924 | |||
925 | err_free_dev: | ||
926 | input_free_device(pad->dev); | ||
927 | pad->dev = NULL; | ||
928 | return err; | ||
717 | } | 929 | } |
718 | 930 | ||
719 | static struct gc __init *gc_probe(int parport, int *pads, int n_pads) | 931 | static struct gc __init *gc_probe(int parport, int *pads, int n_pads) |
@@ -722,52 +934,47 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) | |||
722 | struct parport *pp; | 934 | struct parport *pp; |
723 | struct pardevice *pd; | 935 | struct pardevice *pd; |
724 | int i; | 936 | int i; |
937 | int count = 0; | ||
725 | int err; | 938 | int err; |
726 | 939 | ||
727 | pp = parport_find_number(parport); | 940 | pp = parport_find_number(parport); |
728 | if (!pp) { | 941 | if (!pp) { |
729 | printk(KERN_ERR "gamecon.c: no such parport\n"); | 942 | pr_err("no such parport %d\n", parport); |
730 | err = -EINVAL; | 943 | err = -EINVAL; |
731 | goto err_out; | 944 | goto err_out; |
732 | } | 945 | } |
733 | 946 | ||
734 | pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); | 947 | pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); |
735 | if (!pd) { | 948 | if (!pd) { |
736 | printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n"); | 949 | pr_err("parport busy already - lp.o loaded?\n"); |
737 | err = -EBUSY; | 950 | err = -EBUSY; |
738 | goto err_put_pp; | 951 | goto err_put_pp; |
739 | } | 952 | } |
740 | 953 | ||
741 | gc = kzalloc(sizeof(struct gc), GFP_KERNEL); | 954 | gc = kzalloc(sizeof(struct gc), GFP_KERNEL); |
742 | if (!gc) { | 955 | if (!gc) { |
743 | printk(KERN_ERR "gamecon.c: Not enough memory\n"); | 956 | pr_err("Not enough memory\n"); |
744 | err = -ENOMEM; | 957 | err = -ENOMEM; |
745 | goto err_unreg_pardev; | 958 | goto err_unreg_pardev; |
746 | } | 959 | } |
747 | 960 | ||
748 | mutex_init(&gc->mutex); | 961 | mutex_init(&gc->mutex); |
749 | gc->pd = pd; | 962 | gc->pd = pd; |
750 | init_timer(&gc->timer); | 963 | setup_timer(&gc->timer, gc_timer, (long) gc); |
751 | gc->timer.data = (long) gc; | ||
752 | gc->timer.function = gc_timer; | ||
753 | 964 | ||
754 | for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) { | 965 | for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) { |
755 | if (!pads[i]) | 966 | if (!pads[i]) |
756 | continue; | 967 | continue; |
757 | 968 | ||
758 | snprintf(gc->phys[i], sizeof(gc->phys[i]), | ||
759 | "%s/input%d", gc->pd->port->name, i); | ||
760 | err = gc_setup_pad(gc, i, pads[i]); | 969 | err = gc_setup_pad(gc, i, pads[i]); |
761 | if (err) | 970 | if (err) |
762 | goto err_unreg_devs; | 971 | goto err_unreg_devs; |
763 | 972 | ||
764 | err = input_register_device(gc->dev[i]); | 973 | count++; |
765 | if (err) | ||
766 | goto err_free_dev; | ||
767 | } | 974 | } |
768 | 975 | ||
769 | if (!gc->pads[0]) { | 976 | if (count == 0) { |
770 | printk(KERN_ERR "gamecon.c: No valid devices specified\n"); | 977 | pr_err("No valid devices specified\n"); |
771 | err = -EINVAL; | 978 | err = -EINVAL; |
772 | goto err_free_gc; | 979 | goto err_free_gc; |
773 | } | 980 | } |
@@ -775,12 +982,10 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) | |||
775 | parport_put_port(pp); | 982 | parport_put_port(pp); |
776 | return gc; | 983 | return gc; |
777 | 984 | ||
778 | err_free_dev: | ||
779 | input_free_device(gc->dev[i]); | ||
780 | err_unreg_devs: | 985 | err_unreg_devs: |
781 | while (--i >= 0) | 986 | while (--i >= 0) |
782 | if (gc->dev[i]) | 987 | if (gc->pads[i].dev) |
783 | input_unregister_device(gc->dev[i]); | 988 | input_unregister_device(gc->pads[i].dev); |
784 | err_free_gc: | 989 | err_free_gc: |
785 | kfree(gc); | 990 | kfree(gc); |
786 | err_unreg_pardev: | 991 | err_unreg_pardev: |
@@ -796,8 +1001,8 @@ static void gc_remove(struct gc *gc) | |||
796 | int i; | 1001 | int i; |
797 | 1002 | ||
798 | for (i = 0; i < GC_MAX_DEVICES; i++) | 1003 | for (i = 0; i < GC_MAX_DEVICES; i++) |
799 | if (gc->dev[i]) | 1004 | if (gc->pads[i].dev) |
800 | input_unregister_device(gc->dev[i]); | 1005 | input_unregister_device(gc->pads[i].dev); |
801 | parport_unregister_device(gc->pd); | 1006 | parport_unregister_device(gc->pd); |
802 | kfree(gc); | 1007 | kfree(gc); |
803 | } | 1008 | } |
@@ -813,7 +1018,7 @@ static int __init gc_init(void) | |||
813 | continue; | 1018 | continue; |
814 | 1019 | ||
815 | if (gc_cfg[i].nargs < 2) { | 1020 | if (gc_cfg[i].nargs < 2) { |
816 | printk(KERN_ERR "gamecon.c: at least one device must be specified\n"); | 1021 | pr_err("at least one device must be specified\n"); |
817 | err = -EINVAL; | 1022 | err = -EINVAL; |
818 | break; | 1023 | break; |
819 | } | 1024 | } |
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 67c207f5b1a1..45ac70eae0aa 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c | |||
@@ -277,7 +277,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
277 | } | 277 | } |
278 | 278 | ||
279 | #ifdef RESET_WORKS | 279 | #ifdef RESET_WORKS |
280 | if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) || | 280 | if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) && |
281 | (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) { | 281 | (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) { |
282 | err = -ENODEV; | 282 | err = -ENODEV; |
283 | goto fail2; | 283 | goto fail2; |
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index f6c688cae334..405febd94f24 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
@@ -54,6 +54,9 @@ static signed short btn_avb_wheel[] = | |||
54 | static signed short abs_joystick[] = | 54 | static signed short abs_joystick[] = |
55 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; | 55 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; |
56 | 56 | ||
57 | static signed short abs_joystick_rudder[] = | ||
58 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 }; | ||
59 | |||
57 | static signed short abs_avb_pegasus[] = | 60 | static signed short abs_avb_pegasus[] = |
58 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, | 61 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, |
59 | ABS_HAT1X, ABS_HAT1Y, -1 }; | 62 | ABS_HAT1X, ABS_HAT1Y, -1 }; |
@@ -76,8 +79,9 @@ static struct iforce_device iforce_device[] = { | |||
76 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? | 79 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? |
77 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, | 80 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, |
78 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? | 81 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? |
82 | { 0x06f8, 0x0001, "Guillemot Jet Leader Force Feedback", btn_joystick, abs_joystick_rudder, ff_iforce }, | ||
79 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? | 83 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? |
80 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? | 84 | { 0x06f8, 0xa302, "Guillemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? |
81 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, | 85 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, |
82 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } | 86 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } |
83 | }; | 87 | }; |
@@ -210,7 +214,7 @@ static int iforce_open(struct input_dev *dev) | |||
210 | return 0; | 214 | return 0; |
211 | } | 215 | } |
212 | 216 | ||
213 | static void iforce_release(struct input_dev *dev) | 217 | static void iforce_close(struct input_dev *dev) |
214 | { | 218 | { |
215 | struct iforce *iforce = input_get_drvdata(dev); | 219 | struct iforce *iforce = input_get_drvdata(dev); |
216 | int i; | 220 | int i; |
@@ -228,30 +232,17 @@ static void iforce_release(struct input_dev *dev) | |||
228 | 232 | ||
229 | /* Disable force feedback playback */ | 233 | /* Disable force feedback playback */ |
230 | iforce_send_packet(iforce, FF_CMD_ENABLE, "\001"); | 234 | iforce_send_packet(iforce, FF_CMD_ENABLE, "\001"); |
235 | /* Wait for the command to complete */ | ||
236 | wait_event_interruptible(iforce->wait, | ||
237 | !test_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)); | ||
231 | } | 238 | } |
232 | 239 | ||
233 | switch (iforce->bus) { | 240 | switch (iforce->bus) { |
234 | #ifdef CONFIG_JOYSTICK_IFORCE_USB | 241 | #ifdef CONFIG_JOYSTICK_IFORCE_USB |
235 | case IFORCE_USB: | ||
236 | usb_kill_urb(iforce->irq); | ||
237 | |||
238 | /* The device was unplugged before the file | ||
239 | * was released */ | ||
240 | if (iforce->usbdev == NULL) { | ||
241 | iforce_delete_device(iforce); | ||
242 | kfree(iforce); | ||
243 | } | ||
244 | break; | ||
245 | #endif | ||
246 | } | ||
247 | } | ||
248 | |||
249 | void iforce_delete_device(struct iforce *iforce) | ||
250 | { | ||
251 | switch (iforce->bus) { | ||
252 | #ifdef CONFIG_JOYSTICK_IFORCE_USB | ||
253 | case IFORCE_USB: | 242 | case IFORCE_USB: |
254 | iforce_usb_delete(iforce); | 243 | usb_kill_urb(iforce->irq); |
244 | usb_kill_urb(iforce->out); | ||
245 | usb_kill_urb(iforce->ctrl); | ||
255 | break; | 246 | break; |
256 | #endif | 247 | #endif |
257 | #ifdef CONFIG_JOYSTICK_IFORCE_232 | 248 | #ifdef CONFIG_JOYSTICK_IFORCE_232 |
@@ -303,7 +294,7 @@ int iforce_init_device(struct iforce *iforce) | |||
303 | 294 | ||
304 | input_dev->name = "Unknown I-Force device"; | 295 | input_dev->name = "Unknown I-Force device"; |
305 | input_dev->open = iforce_open; | 296 | input_dev->open = iforce_open; |
306 | input_dev->close = iforce_release; | 297 | input_dev->close = iforce_close; |
307 | 298 | ||
308 | /* | 299 | /* |
309 | * On-device memory allocation. | 300 | * On-device memory allocation. |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 9f289d8f52c6..6c96631ae5d9 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
@@ -109,6 +109,7 @@ static void iforce_usb_out(struct urb *urb) | |||
109 | struct iforce *iforce = urb->context; | 109 | struct iforce *iforce = urb->context; |
110 | 110 | ||
111 | if (urb->status) { | 111 | if (urb->status) { |
112 | clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); | ||
112 | dbg("urb->status %d, exiting", urb->status); | 113 | dbg("urb->status %d, exiting", urb->status); |
113 | return; | 114 | return; |
114 | } | 115 | } |
@@ -186,33 +187,19 @@ fail: | |||
186 | return err; | 187 | return err; |
187 | } | 188 | } |
188 | 189 | ||
189 | /* Called by iforce_delete() */ | ||
190 | void iforce_usb_delete(struct iforce* iforce) | ||
191 | { | ||
192 | usb_kill_urb(iforce->irq); | ||
193 | usb_kill_urb(iforce->out); | ||
194 | usb_kill_urb(iforce->ctrl); | ||
195 | |||
196 | usb_free_urb(iforce->irq); | ||
197 | usb_free_urb(iforce->out); | ||
198 | usb_free_urb(iforce->ctrl); | ||
199 | } | ||
200 | |||
201 | static void iforce_usb_disconnect(struct usb_interface *intf) | 190 | static void iforce_usb_disconnect(struct usb_interface *intf) |
202 | { | 191 | { |
203 | struct iforce *iforce = usb_get_intfdata(intf); | 192 | struct iforce *iforce = usb_get_intfdata(intf); |
204 | int open = 0; /* FIXME! iforce->dev.handle->open; */ | ||
205 | 193 | ||
206 | usb_set_intfdata(intf, NULL); | 194 | usb_set_intfdata(intf, NULL); |
207 | if (iforce) { | ||
208 | iforce->usbdev = NULL; | ||
209 | input_unregister_device(iforce->dev); | ||
210 | 195 | ||
211 | if (!open) { | 196 | input_unregister_device(iforce->dev); |
212 | iforce_delete_device(iforce); | 197 | |
213 | kfree(iforce); | 198 | usb_free_urb(iforce->irq); |
214 | } | 199 | usb_free_urb(iforce->out); |
215 | } | 200 | usb_free_urb(iforce->ctrl); |
201 | |||
202 | kfree(iforce); | ||
216 | } | 203 | } |
217 | 204 | ||
218 | static struct usb_device_id iforce_usb_ids [] = { | 205 | static struct usb_device_id iforce_usb_ids [] = { |
@@ -225,6 +212,7 @@ static struct usb_device_id iforce_usb_ids [] = { | |||
225 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ | 212 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ |
226 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ | 213 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ |
227 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ | 214 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ |
215 | { USB_DEVICE(0x06f8, 0x0003) }, /* Guillemot Jet Leader Force Feedback */ | ||
228 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ | 216 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ |
229 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ | 217 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ |
230 | { } /* Terminating entry */ | 218 | { } /* Terminating entry */ |
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index f2d91f4028ca..9f494b75848a 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h | |||
@@ -150,11 +150,9 @@ void iforce_serial_xmit(struct iforce *iforce); | |||
150 | 150 | ||
151 | /* iforce-usb.c */ | 151 | /* iforce-usb.c */ |
152 | void iforce_usb_xmit(struct iforce *iforce); | 152 | void iforce_usb_xmit(struct iforce *iforce); |
153 | void iforce_usb_delete(struct iforce *iforce); | ||
154 | 153 | ||
155 | /* iforce-main.c */ | 154 | /* iforce-main.c */ |
156 | int iforce_init_device(struct iforce *iforce); | 155 | int iforce_init_device(struct iforce *iforce); |
157 | void iforce_delete_device(struct iforce *iforce); | ||
158 | 156 | ||
159 | /* iforce-packets.c */ | 157 | /* iforce-packets.c */ |
160 | int iforce_control_playback(struct iforce*, u16 id, unsigned int); | 158 | int iforce_control_playback(struct iforce*, u16 id, unsigned int); |
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index b6f859869540..d53b9e900234 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
38 | #include <linux/slab.h> | ||
38 | 39 | ||
39 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 40 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
40 | MODULE_DESCRIPTION("TurboGraFX parallel port interface driver"); | 41 | MODULE_DESCRIPTION("TurboGraFX parallel port interface driver"); |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 79e3edcced1a..9b3353b404da 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -86,9 +86,8 @@ | |||
86 | 86 | ||
87 | /* xbox d-pads should map to buttons, as is required for DDR pads | 87 | /* xbox d-pads should map to buttons, as is required for DDR pads |
88 | but we map them to axes when possible to simplify things */ | 88 | but we map them to axes when possible to simplify things */ |
89 | #define MAP_DPAD_TO_BUTTONS 0 | 89 | #define MAP_DPAD_TO_BUTTONS (1 << 0) |
90 | #define MAP_DPAD_TO_AXES 1 | 90 | #define MAP_TRIGGERS_TO_BUTTONS (1 << 1) |
91 | #define MAP_DPAD_UNKNOWN 2 | ||
92 | 91 | ||
93 | #define XTYPE_XBOX 0 | 92 | #define XTYPE_XBOX 0 |
94 | #define XTYPE_XBOX360 1 | 93 | #define XTYPE_XBOX360 1 |
@@ -99,55 +98,61 @@ static int dpad_to_buttons; | |||
99 | module_param(dpad_to_buttons, bool, S_IRUGO); | 98 | module_param(dpad_to_buttons, bool, S_IRUGO); |
100 | MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); | 99 | MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); |
101 | 100 | ||
101 | static int triggers_to_buttons; | ||
102 | module_param(triggers_to_buttons, bool, S_IRUGO); | ||
103 | MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads"); | ||
104 | |||
102 | static const struct xpad_device { | 105 | static const struct xpad_device { |
103 | u16 idVendor; | 106 | u16 idVendor; |
104 | u16 idProduct; | 107 | u16 idProduct; |
105 | char *name; | 108 | char *name; |
106 | u8 dpad_mapping; | 109 | u8 mapping; |
107 | u8 xtype; | 110 | u8 xtype; |
108 | } xpad_device[] = { | 111 | } xpad_device[] = { |
109 | { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 112 | { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX }, |
110 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 113 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, |
111 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 114 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX }, |
112 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 115 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, |
113 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, | 116 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, |
114 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 117 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
115 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 118 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, |
116 | { 0x046d, 0xc242, "Logitech Chillstream Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 119 | { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, |
117 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 120 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, |
118 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 121 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, |
119 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 122 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, |
120 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 123 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX }, |
121 | { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 124 | { 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX }, |
122 | { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 125 | { 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX }, |
123 | { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 126 | { 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX }, |
124 | { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 127 | { 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX }, |
125 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 128 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
126 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 129 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, |
127 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 130 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
131 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, | ||
128 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 132 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
129 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 133 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
130 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 134 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, |
131 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 135 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
132 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 136 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, |
133 | { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 137 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, |
134 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 138 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, |
135 | { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 139 | { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, |
136 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 140 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX }, |
137 | { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 141 | { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX }, |
138 | { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 142 | { 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
139 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 143 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX }, |
140 | { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 144 | { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, |
141 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 145 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, |
142 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 146 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX }, |
143 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 147 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
144 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 148 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 }, |
145 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 149 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
146 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 150 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, |
147 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 151 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, |
148 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | 152 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, |
149 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 153 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
150 | { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } | 154 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, |
155 | { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } | ||
151 | }; | 156 | }; |
152 | 157 | ||
153 | /* buttons shared with xbox and xbox360 */ | 158 | /* buttons shared with xbox and xbox360 */ |
@@ -163,13 +168,20 @@ static const signed short xpad_btn[] = { | |||
163 | -1 /* terminating entry */ | 168 | -1 /* terminating entry */ |
164 | }; | 169 | }; |
165 | 170 | ||
166 | /* only used if MAP_DPAD_TO_BUTTONS */ | 171 | /* used when dpad is mapped to nuttons */ |
167 | static const signed short xpad_btn_pad[] = { | 172 | static const signed short xpad_btn_pad[] = { |
168 | BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ | 173 | BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ |
169 | BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ | 174 | BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ |
170 | -1 /* terminating entry */ | 175 | -1 /* terminating entry */ |
171 | }; | 176 | }; |
172 | 177 | ||
178 | /* used when triggers are mapped to buttons */ | ||
179 | static const signed short xpad_btn_triggers[] = { | ||
180 | BTN_TL2, BTN_TR2, /* triggers left/right */ | ||
181 | -1 | ||
182 | }; | ||
183 | |||
184 | |||
173 | static const signed short xpad360_btn[] = { /* buttons for x360 controller */ | 185 | static const signed short xpad360_btn[] = { /* buttons for x360 controller */ |
174 | BTN_TL, BTN_TR, /* Button LB/RB */ | 186 | BTN_TL, BTN_TR, /* Button LB/RB */ |
175 | BTN_MODE, /* The big X button */ | 187 | BTN_MODE, /* The big X button */ |
@@ -179,16 +191,21 @@ static const signed short xpad360_btn[] = { /* buttons for x360 controller */ | |||
179 | static const signed short xpad_abs[] = { | 191 | static const signed short xpad_abs[] = { |
180 | ABS_X, ABS_Y, /* left stick */ | 192 | ABS_X, ABS_Y, /* left stick */ |
181 | ABS_RX, ABS_RY, /* right stick */ | 193 | ABS_RX, ABS_RY, /* right stick */ |
182 | ABS_Z, ABS_RZ, /* triggers left/right */ | ||
183 | -1 /* terminating entry */ | 194 | -1 /* terminating entry */ |
184 | }; | 195 | }; |
185 | 196 | ||
186 | /* only used if MAP_DPAD_TO_AXES */ | 197 | /* used when dpad is mapped to axes */ |
187 | static const signed short xpad_abs_pad[] = { | 198 | static const signed short xpad_abs_pad[] = { |
188 | ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ | 199 | ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ |
189 | -1 /* terminating entry */ | 200 | -1 /* terminating entry */ |
190 | }; | 201 | }; |
191 | 202 | ||
203 | /* used when triggers are mapped to axes */ | ||
204 | static const signed short xpad_abs_triggers[] = { | ||
205 | ABS_Z, ABS_RZ, /* triggers left/right */ | ||
206 | -1 | ||
207 | }; | ||
208 | |||
192 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only | 209 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only |
193 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we | 210 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we |
194 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, | 211 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, |
@@ -212,6 +229,7 @@ static struct usb_device_id xpad_table [] = { | |||
212 | XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ | 229 | XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ |
213 | XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ | 230 | XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ |
214 | XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */ | 231 | XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */ |
232 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ | ||
215 | { } | 233 | { } |
216 | }; | 234 | }; |
217 | 235 | ||
@@ -243,7 +261,7 @@ struct usb_xpad { | |||
243 | 261 | ||
244 | char phys[64]; /* physical device path */ | 262 | char phys[64]; /* physical device path */ |
245 | 263 | ||
246 | int dpad_mapping; /* map d-pad to buttons or to axes */ | 264 | int mapping; /* map d-pad to buttons or to axes */ |
247 | int xtype; /* type of xbox device */ | 265 | int xtype; /* type of xbox device */ |
248 | }; | 266 | }; |
249 | 267 | ||
@@ -274,20 +292,25 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d | |||
274 | ~(__s16) le16_to_cpup((__le16 *)(data + 18))); | 292 | ~(__s16) le16_to_cpup((__le16 *)(data + 18))); |
275 | 293 | ||
276 | /* triggers left/right */ | 294 | /* triggers left/right */ |
277 | input_report_abs(dev, ABS_Z, data[10]); | 295 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
278 | input_report_abs(dev, ABS_RZ, data[11]); | 296 | input_report_key(dev, BTN_TL2, data[10]); |
297 | input_report_key(dev, BTN_TR2, data[11]); | ||
298 | } else { | ||
299 | input_report_abs(dev, ABS_Z, data[10]); | ||
300 | input_report_abs(dev, ABS_RZ, data[11]); | ||
301 | } | ||
279 | 302 | ||
280 | /* digital pad */ | 303 | /* digital pad */ |
281 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { | 304 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { |
282 | input_report_abs(dev, ABS_HAT0X, | ||
283 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | ||
284 | input_report_abs(dev, ABS_HAT0Y, | ||
285 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
286 | } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { | ||
287 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); | 305 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); |
288 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); | 306 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); |
289 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ | 307 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ |
290 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ | 308 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ |
309 | } else { | ||
310 | input_report_abs(dev, ABS_HAT0X, | ||
311 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | ||
312 | input_report_abs(dev, ABS_HAT0Y, | ||
313 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
291 | } | 314 | } |
292 | 315 | ||
293 | /* start/back buttons and stick press left/right */ | 316 | /* start/back buttons and stick press left/right */ |
@@ -325,17 +348,17 @@ static void xpad360_process_packet(struct usb_xpad *xpad, | |||
325 | struct input_dev *dev = xpad->dev; | 348 | struct input_dev *dev = xpad->dev; |
326 | 349 | ||
327 | /* digital pad */ | 350 | /* digital pad */ |
328 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { | 351 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { |
329 | input_report_abs(dev, ABS_HAT0X, | ||
330 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | ||
331 | input_report_abs(dev, ABS_HAT0Y, | ||
332 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
333 | } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) { | ||
334 | /* dpad as buttons (right, left, down, up) */ | 352 | /* dpad as buttons (right, left, down, up) */ |
335 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); | 353 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); |
336 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); | 354 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); |
337 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ | 355 | input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ |
338 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ | 356 | input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ |
357 | } else { | ||
358 | input_report_abs(dev, ABS_HAT0X, | ||
359 | !!(data[2] & 0x08) - !!(data[2] & 0x04)); | ||
360 | input_report_abs(dev, ABS_HAT0Y, | ||
361 | !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
339 | } | 362 | } |
340 | 363 | ||
341 | /* start/back buttons */ | 364 | /* start/back buttons */ |
@@ -368,8 +391,13 @@ static void xpad360_process_packet(struct usb_xpad *xpad, | |||
368 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); | 391 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); |
369 | 392 | ||
370 | /* triggers left/right */ | 393 | /* triggers left/right */ |
371 | input_report_abs(dev, ABS_Z, data[4]); | 394 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
372 | input_report_abs(dev, ABS_RZ, data[5]); | 395 | input_report_key(dev, BTN_TL2, data[4]); |
396 | input_report_key(dev, BTN_TR2, data[5]); | ||
397 | } else { | ||
398 | input_report_abs(dev, ABS_Z, data[4]); | ||
399 | input_report_abs(dev, ABS_RZ, data[5]); | ||
400 | } | ||
373 | 401 | ||
374 | input_sync(dev); | 402 | input_sync(dev); |
375 | } | 403 | } |
@@ -443,7 +471,7 @@ static void xpad_irq_in(struct urb *urb) | |||
443 | } | 471 | } |
444 | 472 | ||
445 | exit: | 473 | exit: |
446 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 474 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
447 | if (retval) | 475 | if (retval) |
448 | err ("%s - usb_submit_urb failed with result %d", | 476 | err ("%s - usb_submit_urb failed with result %d", |
449 | __func__, retval); | 477 | __func__, retval); |
@@ -502,7 +530,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
502 | struct usb_endpoint_descriptor *ep_irq_out; | 530 | struct usb_endpoint_descriptor *ep_irq_out; |
503 | int error = -ENOMEM; | 531 | int error = -ENOMEM; |
504 | 532 | ||
505 | if (xpad->xtype != XTYPE_XBOX360) | 533 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
506 | return 0; | 534 | return 0; |
507 | 535 | ||
508 | xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, | 536 | xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, |
@@ -532,13 +560,13 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
532 | 560 | ||
533 | static void xpad_stop_output(struct usb_xpad *xpad) | 561 | static void xpad_stop_output(struct usb_xpad *xpad) |
534 | { | 562 | { |
535 | if (xpad->xtype == XTYPE_XBOX360) | 563 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) |
536 | usb_kill_urb(xpad->irq_out); | 564 | usb_kill_urb(xpad->irq_out); |
537 | } | 565 | } |
538 | 566 | ||
539 | static void xpad_deinit_output(struct usb_xpad *xpad) | 567 | static void xpad_deinit_output(struct usb_xpad *xpad) |
540 | { | 568 | { |
541 | if (xpad->xtype == XTYPE_XBOX360) { | 569 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) { |
542 | usb_free_urb(xpad->irq_out); | 570 | usb_free_urb(xpad->irq_out); |
543 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, | 571 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, |
544 | xpad->odata, xpad->odata_dma); | 572 | xpad->odata, xpad->odata_dma); |
@@ -551,24 +579,45 @@ static void xpad_stop_output(struct usb_xpad *xpad) {} | |||
551 | #endif | 579 | #endif |
552 | 580 | ||
553 | #ifdef CONFIG_JOYSTICK_XPAD_FF | 581 | #ifdef CONFIG_JOYSTICK_XPAD_FF |
554 | static int xpad_play_effect(struct input_dev *dev, void *data, | 582 | static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) |
555 | struct ff_effect *effect) | ||
556 | { | 583 | { |
557 | struct usb_xpad *xpad = input_get_drvdata(dev); | 584 | struct usb_xpad *xpad = input_get_drvdata(dev); |
558 | 585 | ||
559 | if (effect->type == FF_RUMBLE) { | 586 | if (effect->type == FF_RUMBLE) { |
560 | __u16 strong = effect->u.rumble.strong_magnitude; | 587 | __u16 strong = effect->u.rumble.strong_magnitude; |
561 | __u16 weak = effect->u.rumble.weak_magnitude; | 588 | __u16 weak = effect->u.rumble.weak_magnitude; |
562 | xpad->odata[0] = 0x00; | 589 | |
563 | xpad->odata[1] = 0x08; | 590 | switch (xpad->xtype) { |
564 | xpad->odata[2] = 0x00; | 591 | |
565 | xpad->odata[3] = strong / 256; | 592 | case XTYPE_XBOX: |
566 | xpad->odata[4] = weak / 256; | 593 | xpad->odata[0] = 0x00; |
567 | xpad->odata[5] = 0x00; | 594 | xpad->odata[1] = 0x06; |
568 | xpad->odata[6] = 0x00; | 595 | xpad->odata[2] = 0x00; |
569 | xpad->odata[7] = 0x00; | 596 | xpad->odata[3] = strong / 256; /* left actuator */ |
570 | xpad->irq_out->transfer_buffer_length = 8; | 597 | xpad->odata[4] = 0x00; |
571 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); | 598 | xpad->odata[5] = weak / 256; /* right actuator */ |
599 | xpad->irq_out->transfer_buffer_length = 6; | ||
600 | |||
601 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | ||
602 | |||
603 | case XTYPE_XBOX360: | ||
604 | xpad->odata[0] = 0x00; | ||
605 | xpad->odata[1] = 0x08; | ||
606 | xpad->odata[2] = 0x00; | ||
607 | xpad->odata[3] = strong / 256; /* left actuator? */ | ||
608 | xpad->odata[4] = weak / 256; /* right actuator? */ | ||
609 | xpad->odata[5] = 0x00; | ||
610 | xpad->odata[6] = 0x00; | ||
611 | xpad->odata[7] = 0x00; | ||
612 | xpad->irq_out->transfer_buffer_length = 8; | ||
613 | |||
614 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | ||
615 | |||
616 | default: | ||
617 | dbg("%s - rumble command sent to unsupported xpad type: %d", | ||
618 | __func__, xpad->xtype); | ||
619 | return -1; | ||
620 | } | ||
572 | } | 621 | } |
573 | 622 | ||
574 | return 0; | 623 | return 0; |
@@ -576,7 +625,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, | |||
576 | 625 | ||
577 | static int xpad_init_ff(struct usb_xpad *xpad) | 626 | static int xpad_init_ff(struct usb_xpad *xpad) |
578 | { | 627 | { |
579 | if (xpad->xtype != XTYPE_XBOX360) | 628 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
580 | return 0; | 629 | return 0; |
581 | 630 | ||
582 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | 631 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); |
@@ -709,11 +758,11 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | |||
709 | input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); | 758 | input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); |
710 | break; | 759 | break; |
711 | case ABS_Z: | 760 | case ABS_Z: |
712 | case ABS_RZ: /* the triggers */ | 761 | case ABS_RZ: /* the triggers (if mapped to axes) */ |
713 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); | 762 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); |
714 | break; | 763 | break; |
715 | case ABS_HAT0X: | 764 | case ABS_HAT0X: |
716 | case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */ | 765 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ |
717 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); | 766 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); |
718 | break; | 767 | break; |
719 | } | 768 | } |
@@ -749,10 +798,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
749 | goto fail2; | 798 | goto fail2; |
750 | 799 | ||
751 | xpad->udev = udev; | 800 | xpad->udev = udev; |
752 | xpad->dpad_mapping = xpad_device[i].dpad_mapping; | 801 | xpad->mapping = xpad_device[i].mapping; |
753 | xpad->xtype = xpad_device[i].xtype; | 802 | xpad->xtype = xpad_device[i].xtype; |
754 | if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) | 803 | |
755 | xpad->dpad_mapping = !dpad_to_buttons; | ||
756 | if (xpad->xtype == XTYPE_UNKNOWN) { | 804 | if (xpad->xtype == XTYPE_UNKNOWN) { |
757 | if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { | 805 | if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { |
758 | if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) | 806 | if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) |
@@ -761,7 +809,13 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
761 | xpad->xtype = XTYPE_XBOX360; | 809 | xpad->xtype = XTYPE_XBOX360; |
762 | } else | 810 | } else |
763 | xpad->xtype = XTYPE_XBOX; | 811 | xpad->xtype = XTYPE_XBOX; |
812 | |||
813 | if (dpad_to_buttons) | ||
814 | xpad->mapping |= MAP_DPAD_TO_BUTTONS; | ||
815 | if (triggers_to_buttons) | ||
816 | xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; | ||
764 | } | 817 | } |
818 | |||
765 | xpad->dev = input_dev; | 819 | xpad->dev = input_dev; |
766 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); | 820 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); |
767 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); | 821 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); |
@@ -778,25 +832,37 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
778 | 832 | ||
779 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 833 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
780 | 834 | ||
781 | /* set up buttons */ | 835 | /* set up standard buttons and axes */ |
782 | for (i = 0; xpad_common_btn[i] >= 0; i++) | 836 | for (i = 0; xpad_common_btn[i] >= 0; i++) |
783 | set_bit(xpad_common_btn[i], input_dev->keybit); | 837 | __set_bit(xpad_common_btn[i], input_dev->keybit); |
784 | if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W)) | ||
785 | for (i = 0; xpad360_btn[i] >= 0; i++) | ||
786 | set_bit(xpad360_btn[i], input_dev->keybit); | ||
787 | else | ||
788 | for (i = 0; xpad_btn[i] >= 0; i++) | ||
789 | set_bit(xpad_btn[i], input_dev->keybit); | ||
790 | if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) | ||
791 | for (i = 0; xpad_btn_pad[i] >= 0; i++) | ||
792 | set_bit(xpad_btn_pad[i], input_dev->keybit); | ||
793 | 838 | ||
794 | /* set up axes */ | ||
795 | for (i = 0; xpad_abs[i] >= 0; i++) | 839 | for (i = 0; xpad_abs[i] >= 0; i++) |
796 | xpad_set_up_abs(input_dev, xpad_abs[i]); | 840 | xpad_set_up_abs(input_dev, xpad_abs[i]); |
797 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) | 841 | |
842 | /* Now set up model-specific ones */ | ||
843 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { | ||
844 | for (i = 0; xpad360_btn[i] >= 0; i++) | ||
845 | __set_bit(xpad360_btn[i], input_dev->keybit); | ||
846 | } else { | ||
847 | for (i = 0; xpad_btn[i] >= 0; i++) | ||
848 | __set_bit(xpad_btn[i], input_dev->keybit); | ||
849 | } | ||
850 | |||
851 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { | ||
852 | for (i = 0; xpad_btn_pad[i] >= 0; i++) | ||
853 | __set_bit(xpad_btn_pad[i], input_dev->keybit); | ||
854 | } else { | ||
798 | for (i = 0; xpad_abs_pad[i] >= 0; i++) | 855 | for (i = 0; xpad_abs_pad[i] >= 0; i++) |
799 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); | 856 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); |
857 | } | ||
858 | |||
859 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { | ||
860 | for (i = 0; xpad_btn_triggers[i] >= 0; i++) | ||
861 | __set_bit(xpad_btn_triggers[i], input_dev->keybit); | ||
862 | } else { | ||
863 | for (i = 0; xpad_abs_triggers[i] >= 0; i++) | ||
864 | xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); | ||
865 | } | ||
800 | 866 | ||
801 | error = xpad_init_output(intf, xpad); | 867 | error = xpad_init_output(intf, xpad); |
802 | if (error) | 868 | if (error) |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index ee98b1bc5d89..64c102355f53 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -24,11 +24,21 @@ config KEYBOARD_AAED2000 | |||
24 | To compile this driver as a module, choose M here: the | 24 | To compile this driver as a module, choose M here: the |
25 | module will be called aaed2000_kbd. | 25 | module will be called aaed2000_kbd. |
26 | 26 | ||
27 | config KEYBOARD_ADP5520 | ||
28 | tristate "Keypad Support for ADP5520 PMIC" | ||
29 | depends on PMIC_ADP5520 | ||
30 | help | ||
31 | This option enables support for the keypad scan matrix | ||
32 | on Analog Devices ADP5520 PMICs. | ||
33 | |||
34 | To compile this driver as a module, choose M here: the module will | ||
35 | be called adp5520-keys. | ||
36 | |||
27 | config KEYBOARD_ADP5588 | 37 | config KEYBOARD_ADP5588 |
28 | tristate "ADP5588 I2C QWERTY Keypad and IO Expander" | 38 | tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander" |
29 | depends on I2C | 39 | depends on I2C |
30 | help | 40 | help |
31 | Say Y here if you want to use a ADP5588 attached to your | 41 | Say Y here if you want to use a ADP5588/87 attached to your |
32 | system I2C bus. | 42 | system I2C bus. |
33 | 43 | ||
34 | To compile this driver as a module, choose M here: the | 44 | To compile this driver as a module, choose M here: the |
@@ -134,13 +144,15 @@ config KEYBOARD_BFIN | |||
134 | module will be called bf54x-keys. | 144 | module will be called bf54x-keys. |
135 | 145 | ||
136 | config KEYBOARD_CORGI | 146 | config KEYBOARD_CORGI |
137 | tristate "Corgi keyboard" | 147 | tristate "Corgi keyboard (deprecated)" |
138 | depends on PXA_SHARPSL | 148 | depends on PXA_SHARPSL |
139 | default y | ||
140 | help | 149 | help |
141 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx | 150 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx |
142 | series of PDAs. | 151 | series of PDAs. |
143 | 152 | ||
153 | This driver is now deprecated, use generic GPIO based matrix | ||
154 | keyboard driver instead. | ||
155 | |||
144 | To compile this driver as a module, choose M here: the | 156 | To compile this driver as a module, choose M here: the |
145 | module will be called corgikbd. | 157 | module will be called corgikbd. |
146 | 158 | ||
@@ -282,6 +294,15 @@ config KEYBOARD_MAX7359 | |||
282 | To compile this driver as a module, choose M here: the | 294 | To compile this driver as a module, choose M here: the |
283 | module will be called max7359_keypad. | 295 | module will be called max7359_keypad. |
284 | 296 | ||
297 | config KEYBOARD_IMX | ||
298 | tristate "IMX keypad support" | ||
299 | depends on ARCH_MXC | ||
300 | help | ||
301 | Enable support for IMX keypad port. | ||
302 | |||
303 | To compile this driver as a module, choose M here: the | ||
304 | module will be called imx_keypad. | ||
305 | |||
285 | config KEYBOARD_NEWTON | 306 | config KEYBOARD_NEWTON |
286 | tristate "Newton keyboard" | 307 | tristate "Newton keyboard" |
287 | select SERIO | 308 | select SERIO |
@@ -319,13 +340,15 @@ config KEYBOARD_PXA930_ROTARY | |||
319 | module will be called pxa930_rotary. | 340 | module will be called pxa930_rotary. |
320 | 341 | ||
321 | config KEYBOARD_SPITZ | 342 | config KEYBOARD_SPITZ |
322 | tristate "Spitz keyboard" | 343 | tristate "Spitz keyboard (deprecated)" |
323 | depends on PXA_SHARPSL | 344 | depends on PXA_SHARPSL |
324 | default y | ||
325 | help | 345 | help |
326 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, | 346 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, |
327 | SL-C3000 and Sl-C3100 series of PDAs. | 347 | SL-C3000 and Sl-C3100 series of PDAs. |
328 | 348 | ||
349 | This driver is now deprecated, use generic GPIO based matrix | ||
350 | keyboard driver instead. | ||
351 | |||
329 | To compile this driver as a module, choose M here: the | 352 | To compile this driver as a module, choose M here: the |
330 | module will be called spitzkbd. | 353 | module will be called spitzkbd. |
331 | 354 | ||
@@ -353,7 +376,7 @@ config KEYBOARD_SUNKBD | |||
353 | 376 | ||
354 | config KEYBOARD_SH_KEYSC | 377 | config KEYBOARD_SH_KEYSC |
355 | tristate "SuperH KEYSC keypad support" | 378 | tristate "SuperH KEYSC keypad support" |
356 | depends on SUPERH | 379 | depends on SUPERH || ARCH_SHMOBILE |
357 | help | 380 | help |
358 | Say Y here if you want to use a keypad attached to the KEYSC block | 381 | Say Y here if you want to use a keypad attached to the KEYSC block |
359 | on SuperH processors such as sh7722 and sh7343. | 382 | on SuperH processors such as sh7722 and sh7343. |
@@ -361,6 +384,16 @@ config KEYBOARD_SH_KEYSC | |||
361 | To compile this driver as a module, choose M here: the | 384 | To compile this driver as a module, choose M here: the |
362 | module will be called sh_keysc. | 385 | module will be called sh_keysc. |
363 | 386 | ||
387 | config KEYBOARD_DAVINCI | ||
388 | tristate "TI DaVinci Key Scan" | ||
389 | depends on ARCH_DAVINCI_DM365 | ||
390 | help | ||
391 | Say Y to enable keypad module support for the TI DaVinci | ||
392 | platforms (DM365). | ||
393 | |||
394 | To compile this driver as a module, choose M here: the | ||
395 | module will be called davinci_keyscan. | ||
396 | |||
364 | config KEYBOARD_OMAP | 397 | config KEYBOARD_OMAP |
365 | tristate "TI OMAP keypad support" | 398 | tristate "TI OMAP keypad support" |
366 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 399 | depends on (ARCH_OMAP1 || ARCH_OMAP2) |
@@ -382,12 +415,14 @@ config KEYBOARD_TWL4030 | |||
382 | module will be called twl4030_keypad. | 415 | module will be called twl4030_keypad. |
383 | 416 | ||
384 | config KEYBOARD_TOSA | 417 | config KEYBOARD_TOSA |
385 | tristate "Tosa keyboard" | 418 | tristate "Tosa keyboard (deprecated)" |
386 | depends on MACH_TOSA | 419 | depends on MACH_TOSA |
387 | default y | ||
388 | help | 420 | help |
389 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) | 421 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) |
390 | 422 | ||
423 | This driver is now deprecated, use generic GPIO based matrix | ||
424 | keyboard driver instead. | ||
425 | |||
391 | To compile this driver as a module, choose M here: the | 426 | To compile this driver as a module, choose M here: the |
392 | module will be called tosakbd. | 427 | module will be called tosakbd. |
393 | 428 | ||
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index babad5e58b77..706c6b5ed5f4 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -5,16 +5,19 @@ | |||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | 7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o |
8 | obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o | ||
8 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o | 9 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o |
9 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | 10 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o |
10 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o |
11 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
12 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
13 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o | 14 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o |
15 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | ||
14 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 16 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
15 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 17 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
16 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
17 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
20 | obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o | ||
18 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | 21 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o |
19 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | 22 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o |
20 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | 23 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o |
diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c new file mode 100644 index 000000000000..3db8006dac3a --- /dev/null +++ b/drivers/input/keyboard/adp5520-keys.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * Keypad driver for Analog Devices ADP5520 MFD PMICs | ||
3 | * | ||
4 | * Copyright 2009 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <linux/mfd/adp5520.h> | ||
15 | #include <linux/slab.h> | ||
16 | |||
17 | struct adp5520_keys { | ||
18 | struct input_dev *input; | ||
19 | struct notifier_block notifier; | ||
20 | struct device *master; | ||
21 | unsigned short keycode[ADP5520_KEYMAPSIZE]; | ||
22 | }; | ||
23 | |||
24 | static void adp5520_keys_report_event(struct adp5520_keys *dev, | ||
25 | unsigned short keymask, int value) | ||
26 | { | ||
27 | int i; | ||
28 | |||
29 | for (i = 0; i < ADP5520_MAXKEYS; i++) | ||
30 | if (keymask & (1 << i)) | ||
31 | input_report_key(dev->input, dev->keycode[i], value); | ||
32 | |||
33 | input_sync(dev->input); | ||
34 | } | ||
35 | |||
36 | static int adp5520_keys_notifier(struct notifier_block *nb, | ||
37 | unsigned long event, void *data) | ||
38 | { | ||
39 | struct adp5520_keys *dev; | ||
40 | uint8_t reg_val_lo, reg_val_hi; | ||
41 | unsigned short keymask; | ||
42 | |||
43 | dev = container_of(nb, struct adp5520_keys, notifier); | ||
44 | |||
45 | if (event & ADP5520_KP_INT) { | ||
46 | adp5520_read(dev->master, ADP5520_KP_INT_STAT_1, ®_val_lo); | ||
47 | adp5520_read(dev->master, ADP5520_KP_INT_STAT_2, ®_val_hi); | ||
48 | |||
49 | keymask = (reg_val_hi << 8) | reg_val_lo; | ||
50 | /* Read twice to clear */ | ||
51 | adp5520_read(dev->master, ADP5520_KP_INT_STAT_1, ®_val_lo); | ||
52 | adp5520_read(dev->master, ADP5520_KP_INT_STAT_2, ®_val_hi); | ||
53 | keymask |= (reg_val_hi << 8) | reg_val_lo; | ||
54 | adp5520_keys_report_event(dev, keymask, 1); | ||
55 | } | ||
56 | |||
57 | if (event & ADP5520_KR_INT) { | ||
58 | adp5520_read(dev->master, ADP5520_KR_INT_STAT_1, ®_val_lo); | ||
59 | adp5520_read(dev->master, ADP5520_KR_INT_STAT_2, ®_val_hi); | ||
60 | |||
61 | keymask = (reg_val_hi << 8) | reg_val_lo; | ||
62 | /* Read twice to clear */ | ||
63 | adp5520_read(dev->master, ADP5520_KR_INT_STAT_1, ®_val_lo); | ||
64 | adp5520_read(dev->master, ADP5520_KR_INT_STAT_2, ®_val_hi); | ||
65 | keymask |= (reg_val_hi << 8) | reg_val_lo; | ||
66 | adp5520_keys_report_event(dev, keymask, 0); | ||
67 | } | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int __devinit adp5520_keys_probe(struct platform_device *pdev) | ||
73 | { | ||
74 | struct adp5520_keys_platform_data *pdata = pdev->dev.platform_data; | ||
75 | struct input_dev *input; | ||
76 | struct adp5520_keys *dev; | ||
77 | int ret, i; | ||
78 | unsigned char en_mask, ctl_mask = 0; | ||
79 | |||
80 | if (pdev->id != ID_ADP5520) { | ||
81 | dev_err(&pdev->dev, "only ADP5520 supports Keypad\n"); | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | |||
85 | if (pdata == NULL) { | ||
86 | dev_err(&pdev->dev, "missing platform data\n"); | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | |||
90 | if (!(pdata->rows_en_mask && pdata->cols_en_mask)) | ||
91 | return -EINVAL; | ||
92 | |||
93 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
94 | if (dev == NULL) { | ||
95 | dev_err(&pdev->dev, "failed to alloc memory\n"); | ||
96 | return -ENOMEM; | ||
97 | } | ||
98 | |||
99 | input = input_allocate_device(); | ||
100 | if (!input) { | ||
101 | ret = -ENOMEM; | ||
102 | goto err; | ||
103 | } | ||
104 | |||
105 | dev->master = pdev->dev.parent; | ||
106 | dev->input = input; | ||
107 | |||
108 | input->name = pdev->name; | ||
109 | input->phys = "adp5520-keys/input0"; | ||
110 | input->dev.parent = &pdev->dev; | ||
111 | |||
112 | input_set_drvdata(input, dev); | ||
113 | |||
114 | input->id.bustype = BUS_I2C; | ||
115 | input->id.vendor = 0x0001; | ||
116 | input->id.product = 0x5520; | ||
117 | input->id.version = 0x0001; | ||
118 | |||
119 | input->keycodesize = sizeof(dev->keycode[0]); | ||
120 | input->keycodemax = pdata->keymapsize; | ||
121 | input->keycode = dev->keycode; | ||
122 | |||
123 | memcpy(dev->keycode, pdata->keymap, | ||
124 | pdata->keymapsize * input->keycodesize); | ||
125 | |||
126 | /* setup input device */ | ||
127 | __set_bit(EV_KEY, input->evbit); | ||
128 | |||
129 | if (pdata->repeat) | ||
130 | __set_bit(EV_REP, input->evbit); | ||
131 | |||
132 | for (i = 0; i < input->keycodemax; i++) | ||
133 | __set_bit(dev->keycode[i], input->keybit); | ||
134 | __clear_bit(KEY_RESERVED, input->keybit); | ||
135 | |||
136 | ret = input_register_device(input); | ||
137 | if (ret) { | ||
138 | dev_err(&pdev->dev, "unable to register input device\n"); | ||
139 | goto err; | ||
140 | } | ||
141 | |||
142 | en_mask = pdata->rows_en_mask | pdata->cols_en_mask; | ||
143 | |||
144 | ret = adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_1, en_mask); | ||
145 | |||
146 | if (en_mask & ADP5520_COL_C3) | ||
147 | ctl_mask |= ADP5520_C3_MODE; | ||
148 | |||
149 | if (en_mask & ADP5520_ROW_R3) | ||
150 | ctl_mask |= ADP5520_R3_MODE; | ||
151 | |||
152 | if (ctl_mask) | ||
153 | ret |= adp5520_set_bits(dev->master, ADP5520_LED_CONTROL, | ||
154 | ctl_mask); | ||
155 | |||
156 | ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP, | ||
157 | pdata->rows_en_mask); | ||
158 | |||
159 | if (ret) { | ||
160 | dev_err(&pdev->dev, "failed to write\n"); | ||
161 | ret = -EIO; | ||
162 | goto err1; | ||
163 | } | ||
164 | |||
165 | dev->notifier.notifier_call = adp5520_keys_notifier; | ||
166 | ret = adp5520_register_notifier(dev->master, &dev->notifier, | ||
167 | ADP5520_KP_IEN | ADP5520_KR_IEN); | ||
168 | if (ret) { | ||
169 | dev_err(&pdev->dev, "failed to register notifier\n"); | ||
170 | goto err1; | ||
171 | } | ||
172 | |||
173 | platform_set_drvdata(pdev, dev); | ||
174 | return 0; | ||
175 | |||
176 | err1: | ||
177 | input_unregister_device(input); | ||
178 | input = NULL; | ||
179 | err: | ||
180 | input_free_device(input); | ||
181 | kfree(dev); | ||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | static int __devexit adp5520_keys_remove(struct platform_device *pdev) | ||
186 | { | ||
187 | struct adp5520_keys *dev = platform_get_drvdata(pdev); | ||
188 | |||
189 | adp5520_unregister_notifier(dev->master, &dev->notifier, | ||
190 | ADP5520_KP_IEN | ADP5520_KR_IEN); | ||
191 | |||
192 | input_unregister_device(dev->input); | ||
193 | kfree(dev); | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static struct platform_driver adp5520_keys_driver = { | ||
198 | .driver = { | ||
199 | .name = "adp5520-keys", | ||
200 | .owner = THIS_MODULE, | ||
201 | }, | ||
202 | .probe = adp5520_keys_probe, | ||
203 | .remove = __devexit_p(adp5520_keys_remove), | ||
204 | }; | ||
205 | |||
206 | static int __init adp5520_keys_init(void) | ||
207 | { | ||
208 | return platform_driver_register(&adp5520_keys_driver); | ||
209 | } | ||
210 | module_init(adp5520_keys_init); | ||
211 | |||
212 | static void __exit adp5520_keys_exit(void) | ||
213 | { | ||
214 | platform_driver_unregister(&adp5520_keys_driver); | ||
215 | } | ||
216 | module_exit(adp5520_keys_exit); | ||
217 | |||
218 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
219 | MODULE_DESCRIPTION("Keys ADP5520 Driver"); | ||
220 | MODULE_LICENSE("GPL"); | ||
221 | MODULE_ALIAS("platform:adp5520-keys"); | ||
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index d48c808d5928..4771ab172b59 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/input/keyboard/adp5588_keys.c | 2 | * File: drivers/input/keyboard/adp5588_keys.c |
3 | * Description: keypad driver for ADP5588 I2C QWERTY Keypad and IO Expander | 3 | * Description: keypad driver for ADP5588 and ADP5587 |
4 | * I2C QWERTY Keypad and IO Expander | ||
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 5 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
5 | * | 6 | * |
6 | * Copyright (C) 2008-2009 Analog Devices Inc. | 7 | * Copyright (C) 2008-2009 Analog Devices Inc. |
@@ -18,6 +19,7 @@ | |||
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/input.h> | 20 | #include <linux/input.h> |
20 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/slab.h> | ||
21 | 23 | ||
22 | #include <linux/i2c/adp5588.h> | 24 | #include <linux/i2c/adp5588.h> |
23 | 25 | ||
@@ -319,7 +321,7 @@ static int adp5588_resume(struct device *dev) | |||
319 | return 0; | 321 | return 0; |
320 | } | 322 | } |
321 | 323 | ||
322 | static struct dev_pm_ops adp5588_dev_pm_ops = { | 324 | static const struct dev_pm_ops adp5588_dev_pm_ops = { |
323 | .suspend = adp5588_suspend, | 325 | .suspend = adp5588_suspend, |
324 | .resume = adp5588_resume, | 326 | .resume = adp5588_resume, |
325 | }; | 327 | }; |
@@ -327,6 +329,7 @@ static struct dev_pm_ops adp5588_dev_pm_ops = { | |||
327 | 329 | ||
328 | static const struct i2c_device_id adp5588_id[] = { | 330 | static const struct i2c_device_id adp5588_id[] = { |
329 | { KBUILD_MODNAME, 0 }, | 331 | { KBUILD_MODNAME, 0 }, |
332 | { "adp5587-keys", 0 }, | ||
330 | { } | 333 | { } |
331 | }; | 334 | }; |
332 | MODULE_DEVICE_TABLE(i2c, adp5588_id); | 335 | MODULE_DEVICE_TABLE(i2c, adp5588_id); |
@@ -357,5 +360,5 @@ module_exit(adp5588_exit); | |||
357 | 360 | ||
358 | MODULE_LICENSE("GPL"); | 361 | MODULE_LICENSE("GPL"); |
359 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 362 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
360 | MODULE_DESCRIPTION("ADP5588 Keypad driver"); | 363 | MODULE_DESCRIPTION("ADP5588/87 Keypad driver"); |
361 | MODULE_ALIAS("platform:adp5588-keys"); | 364 | MODULE_ALIAS("platform:adp5588-keys"); |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 28e6110d1ff8..d358ef8623f4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -40,26 +40,26 @@ module_param_named(set, atkbd_set, int, 0); | |||
40 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); | 40 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); |
41 | 41 | ||
42 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) | 42 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) |
43 | static int atkbd_reset; | 43 | static bool atkbd_reset; |
44 | #else | 44 | #else |
45 | static int atkbd_reset = 1; | 45 | static bool atkbd_reset = true; |
46 | #endif | 46 | #endif |
47 | module_param_named(reset, atkbd_reset, bool, 0); | 47 | module_param_named(reset, atkbd_reset, bool, 0); |
48 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); | 48 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); |
49 | 49 | ||
50 | static int atkbd_softrepeat; | 50 | static bool atkbd_softrepeat; |
51 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); | 51 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); |
52 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); | 52 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); |
53 | 53 | ||
54 | static int atkbd_softraw = 1; | 54 | static bool atkbd_softraw = true; |
55 | module_param_named(softraw, atkbd_softraw, bool, 0); | 55 | module_param_named(softraw, atkbd_softraw, bool, 0); |
56 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); | 56 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); |
57 | 57 | ||
58 | static int atkbd_scroll; | 58 | static bool atkbd_scroll; |
59 | module_param_named(scroll, atkbd_scroll, bool, 0); | 59 | module_param_named(scroll, atkbd_scroll, bool, 0); |
60 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); | 60 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); |
61 | 61 | ||
62 | static int atkbd_extra; | 62 | static bool atkbd_extra; |
63 | module_param_named(extra, atkbd_extra, bool, 0); | 63 | module_param_named(extra, atkbd_extra, bool, 0); |
64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); | 64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); |
65 | 65 | ||
@@ -134,7 +134,8 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
134 | #define ATKBD_CMD_GETID 0x02f2 | 134 | #define ATKBD_CMD_GETID 0x02f2 |
135 | #define ATKBD_CMD_SETREP 0x10f3 | 135 | #define ATKBD_CMD_SETREP 0x10f3 |
136 | #define ATKBD_CMD_ENABLE 0x00f4 | 136 | #define ATKBD_CMD_ENABLE 0x00f4 |
137 | #define ATKBD_CMD_RESET_DIS 0x00f5 | 137 | #define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ |
138 | #define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ | ||
138 | #define ATKBD_CMD_SETALL_MBR 0x00fa | 139 | #define ATKBD_CMD_SETALL_MBR 0x00fa |
139 | #define ATKBD_CMD_RESET_BAT 0x02ff | 140 | #define ATKBD_CMD_RESET_BAT 0x02ff |
140 | #define ATKBD_CMD_RESEND 0x00fe | 141 | #define ATKBD_CMD_RESEND 0x00fe |
@@ -152,16 +153,16 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
152 | #define ATKBD_RET_HANGEUL 0xf2 | 153 | #define ATKBD_RET_HANGEUL 0xf2 |
153 | #define ATKBD_RET_ERR 0xff | 154 | #define ATKBD_RET_ERR 0xff |
154 | 155 | ||
155 | #define ATKBD_KEY_UNKNOWN 0 | 156 | #define ATKBD_KEY_UNKNOWN 0 |
156 | #define ATKBD_KEY_NULL 255 | 157 | #define ATKBD_KEY_NULL 255 |
157 | 158 | ||
158 | #define ATKBD_SCR_1 254 | 159 | #define ATKBD_SCR_1 0xfffe |
159 | #define ATKBD_SCR_2 253 | 160 | #define ATKBD_SCR_2 0xfffd |
160 | #define ATKBD_SCR_4 252 | 161 | #define ATKBD_SCR_4 0xfffc |
161 | #define ATKBD_SCR_8 251 | 162 | #define ATKBD_SCR_8 0xfffb |
162 | #define ATKBD_SCR_CLICK 250 | 163 | #define ATKBD_SCR_CLICK 0xfffa |
163 | #define ATKBD_SCR_LEFT 249 | 164 | #define ATKBD_SCR_LEFT 0xfff9 |
164 | #define ATKBD_SCR_RIGHT 248 | 165 | #define ATKBD_SCR_RIGHT 0xfff8 |
165 | 166 | ||
166 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT | 167 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT |
167 | 168 | ||
@@ -176,7 +177,7 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
176 | #define ATKBD_XL_HANJA 0x20 | 177 | #define ATKBD_XL_HANJA 0x20 |
177 | 178 | ||
178 | static const struct { | 179 | static const struct { |
179 | unsigned char keycode; | 180 | unsigned short keycode; |
180 | unsigned char set2; | 181 | unsigned char set2; |
181 | } atkbd_scroll_keys[] = { | 182 | } atkbd_scroll_keys[] = { |
182 | { ATKBD_SCR_1, 0xc5 }, | 183 | { ATKBD_SCR_1, 0xc5 }, |
@@ -205,18 +206,18 @@ struct atkbd { | |||
205 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; | 206 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; |
206 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); | 207 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); |
207 | unsigned char set; | 208 | unsigned char set; |
208 | unsigned char translated; | 209 | bool translated; |
209 | unsigned char extra; | 210 | bool extra; |
210 | unsigned char write; | 211 | bool write; |
211 | unsigned char softrepeat; | 212 | bool softrepeat; |
212 | unsigned char softraw; | 213 | bool softraw; |
213 | unsigned char scroll; | 214 | bool scroll; |
214 | unsigned char enabled; | 215 | bool enabled; |
215 | 216 | ||
216 | /* Accessed only from interrupt */ | 217 | /* Accessed only from interrupt */ |
217 | unsigned char emul; | 218 | unsigned char emul; |
218 | unsigned char resend; | 219 | bool resend; |
219 | unsigned char release; | 220 | bool release; |
220 | unsigned long xl_bit; | 221 | unsigned long xl_bit; |
221 | unsigned int last; | 222 | unsigned int last; |
222 | unsigned long time; | 223 | unsigned long time; |
@@ -224,8 +225,10 @@ struct atkbd { | |||
224 | 225 | ||
225 | struct delayed_work event_work; | 226 | struct delayed_work event_work; |
226 | unsigned long event_jiffies; | 227 | unsigned long event_jiffies; |
227 | struct mutex event_mutex; | ||
228 | unsigned long event_mask; | 228 | unsigned long event_mask; |
229 | |||
230 | /* Serializes reconnect(), attr->set() and event work */ | ||
231 | struct mutex mutex; | ||
229 | }; | 232 | }; |
230 | 233 | ||
231 | /* | 234 | /* |
@@ -298,18 +301,18 @@ static const unsigned int xl_table[] = { | |||
298 | * Checks if we should mangle the scancode to extract 'release' bit | 301 | * Checks if we should mangle the scancode to extract 'release' bit |
299 | * in translated mode. | 302 | * in translated mode. |
300 | */ | 303 | */ |
301 | static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code) | 304 | static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code) |
302 | { | 305 | { |
303 | int i; | 306 | int i; |
304 | 307 | ||
305 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) | 308 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) |
306 | return 0; | 309 | return false; |
307 | 310 | ||
308 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) | 311 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) |
309 | if (code == xl_table[i]) | 312 | if (code == xl_table[i]) |
310 | return test_bit(i, &xl_bit); | 313 | return test_bit(i, &xl_bit); |
311 | 314 | ||
312 | return 1; | 315 | return true; |
313 | } | 316 | } |
314 | 317 | ||
315 | /* | 318 | /* |
@@ -356,7 +359,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code | |||
356 | */ | 359 | */ |
357 | 360 | ||
358 | static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | 361 | static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, |
359 | unsigned int flags) | 362 | unsigned int flags) |
360 | { | 363 | { |
361 | struct atkbd *atkbd = serio_get_drvdata(serio); | 364 | struct atkbd *atkbd = serio_get_drvdata(serio); |
362 | struct input_dev *dev = atkbd->dev; | 365 | struct input_dev *dev = atkbd->dev; |
@@ -365,20 +368,18 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
365 | int value; | 368 | int value; |
366 | unsigned short keycode; | 369 | unsigned short keycode; |
367 | 370 | ||
368 | #ifdef ATKBD_DEBUG | 371 | dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); |
369 | printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); | ||
370 | #endif | ||
371 | 372 | ||
372 | #if !defined(__i386__) && !defined (__x86_64__) | 373 | #if !defined(__i386__) && !defined (__x86_64__) |
373 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { | 374 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { |
374 | printk(KERN_WARNING "atkbd.c: frame/parity error: %02x\n", flags); | 375 | dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); |
375 | serio_write(serio, ATKBD_CMD_RESEND); | 376 | serio_write(serio, ATKBD_CMD_RESEND); |
376 | atkbd->resend = 1; | 377 | atkbd->resend = true; |
377 | goto out; | 378 | goto out; |
378 | } | 379 | } |
379 | 380 | ||
380 | if (!flags && data == ATKBD_RET_ACK) | 381 | if (!flags && data == ATKBD_RET_ACK) |
381 | atkbd->resend = 0; | 382 | atkbd->resend = false; |
382 | #endif | 383 | #endif |
383 | 384 | ||
384 | if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) | 385 | if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) |
@@ -409,32 +410,32 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
409 | } | 410 | } |
410 | 411 | ||
411 | switch (code) { | 412 | switch (code) { |
412 | case ATKBD_RET_BAT: | 413 | case ATKBD_RET_BAT: |
413 | atkbd->enabled = 0; | 414 | atkbd->enabled = false; |
414 | serio_reconnect(atkbd->ps2dev.serio); | 415 | serio_reconnect(atkbd->ps2dev.serio); |
415 | goto out; | 416 | goto out; |
416 | case ATKBD_RET_EMUL0: | 417 | case ATKBD_RET_EMUL0: |
417 | atkbd->emul = 1; | 418 | atkbd->emul = 1; |
418 | goto out; | 419 | goto out; |
419 | case ATKBD_RET_EMUL1: | 420 | case ATKBD_RET_EMUL1: |
420 | atkbd->emul = 2; | 421 | atkbd->emul = 2; |
421 | goto out; | 422 | goto out; |
422 | case ATKBD_RET_RELEASE: | 423 | case ATKBD_RET_RELEASE: |
423 | atkbd->release = 1; | 424 | atkbd->release = true; |
424 | goto out; | 425 | goto out; |
425 | case ATKBD_RET_ACK: | 426 | case ATKBD_RET_ACK: |
426 | case ATKBD_RET_NAK: | 427 | case ATKBD_RET_NAK: |
427 | if (printk_ratelimit()) | 428 | if (printk_ratelimit()) |
428 | printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " | 429 | dev_warn(&serio->dev, |
429 | "Some program might be trying access hardware directly.\n", | 430 | "Spurious %s on %s. " |
430 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); | 431 | "Some program might be trying access hardware directly.\n", |
431 | goto out; | 432 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); |
432 | case ATKBD_RET_ERR: | 433 | goto out; |
433 | atkbd->err_count++; | 434 | case ATKBD_RET_ERR: |
434 | #ifdef ATKBD_DEBUG | 435 | atkbd->err_count++; |
435 | printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); | 436 | dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n", |
436 | #endif | 437 | serio->phys); |
437 | goto out; | 438 | goto out; |
438 | } | 439 | } |
439 | 440 | ||
440 | code = atkbd_compat_scancode(atkbd, code); | 441 | code = atkbd_compat_scancode(atkbd, code); |
@@ -448,71 +449,72 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
448 | input_event(dev, EV_MSC, MSC_SCAN, code); | 449 | input_event(dev, EV_MSC, MSC_SCAN, code); |
449 | 450 | ||
450 | switch (keycode) { | 451 | switch (keycode) { |
451 | case ATKBD_KEY_NULL: | 452 | case ATKBD_KEY_NULL: |
452 | break; | 453 | break; |
453 | case ATKBD_KEY_UNKNOWN: | 454 | case ATKBD_KEY_UNKNOWN: |
454 | printk(KERN_WARNING | 455 | dev_warn(&serio->dev, |
455 | "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", | 456 | "Unknown key %s (%s set %d, code %#x on %s).\n", |
456 | atkbd->release ? "released" : "pressed", | 457 | atkbd->release ? "released" : "pressed", |
457 | atkbd->translated ? "translated" : "raw", | 458 | atkbd->translated ? "translated" : "raw", |
458 | atkbd->set, code, serio->phys); | 459 | atkbd->set, code, serio->phys); |
459 | printk(KERN_WARNING | 460 | dev_warn(&serio->dev, |
460 | "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n", | 461 | "Use 'setkeycodes %s%02x <keycode>' to make it known.\n", |
461 | code & 0x80 ? "e0" : "", code & 0x7f); | 462 | code & 0x80 ? "e0" : "", code & 0x7f); |
462 | input_sync(dev); | 463 | input_sync(dev); |
463 | break; | 464 | break; |
464 | case ATKBD_SCR_1: | 465 | case ATKBD_SCR_1: |
465 | scroll = 1 - atkbd->release * 2; | 466 | scroll = 1; |
466 | break; | 467 | break; |
467 | case ATKBD_SCR_2: | 468 | case ATKBD_SCR_2: |
468 | scroll = 2 - atkbd->release * 4; | 469 | scroll = 2; |
469 | break; | 470 | break; |
470 | case ATKBD_SCR_4: | 471 | case ATKBD_SCR_4: |
471 | scroll = 4 - atkbd->release * 8; | 472 | scroll = 4; |
472 | break; | 473 | break; |
473 | case ATKBD_SCR_8: | 474 | case ATKBD_SCR_8: |
474 | scroll = 8 - atkbd->release * 16; | 475 | scroll = 8; |
475 | break; | 476 | break; |
476 | case ATKBD_SCR_CLICK: | 477 | case ATKBD_SCR_CLICK: |
477 | click = !atkbd->release; | 478 | click = !atkbd->release; |
478 | break; | 479 | break; |
479 | case ATKBD_SCR_LEFT: | 480 | case ATKBD_SCR_LEFT: |
480 | hscroll = -1; | 481 | hscroll = -1; |
481 | break; | 482 | break; |
482 | case ATKBD_SCR_RIGHT: | 483 | case ATKBD_SCR_RIGHT: |
483 | hscroll = 1; | 484 | hscroll = 1; |
484 | break; | 485 | break; |
485 | default: | 486 | default: |
486 | if (atkbd->release) { | 487 | if (atkbd->release) { |
487 | value = 0; | 488 | value = 0; |
488 | atkbd->last = 0; | 489 | atkbd->last = 0; |
489 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { | 490 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { |
490 | /* Workaround Toshiba laptop multiple keypress */ | 491 | /* Workaround Toshiba laptop multiple keypress */ |
491 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; | 492 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; |
492 | } else { | 493 | } else { |
493 | value = 1; | 494 | value = 1; |
494 | atkbd->last = code; | 495 | atkbd->last = code; |
495 | atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; | 496 | atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; |
496 | } | 497 | } |
497 | 498 | ||
498 | input_event(dev, EV_KEY, keycode, value); | 499 | input_event(dev, EV_KEY, keycode, value); |
499 | input_sync(dev); | 500 | input_sync(dev); |
500 | 501 | ||
501 | if (value && test_bit(code, atkbd->force_release_mask)) { | 502 | if (value && test_bit(code, atkbd->force_release_mask)) { |
502 | input_report_key(dev, keycode, 0); | 503 | input_report_key(dev, keycode, 0); |
503 | input_sync(dev); | 504 | input_sync(dev); |
504 | } | 505 | } |
505 | } | 506 | } |
506 | 507 | ||
507 | if (atkbd->scroll) { | 508 | if (atkbd->scroll) { |
508 | if (click != -1) | 509 | if (click != -1) |
509 | input_report_key(dev, BTN_MIDDLE, click); | 510 | input_report_key(dev, BTN_MIDDLE, click); |
510 | input_report_rel(dev, REL_WHEEL, scroll); | 511 | input_report_rel(dev, REL_WHEEL, |
512 | atkbd->release ? -scroll : scroll); | ||
511 | input_report_rel(dev, REL_HWHEEL, hscroll); | 513 | input_report_rel(dev, REL_HWHEEL, hscroll); |
512 | input_sync(dev); | 514 | input_sync(dev); |
513 | } | 515 | } |
514 | 516 | ||
515 | atkbd->release = 0; | 517 | atkbd->release = false; |
516 | out: | 518 | out: |
517 | return IRQ_HANDLED; | 519 | return IRQ_HANDLED; |
518 | } | 520 | } |
@@ -576,7 +578,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
576 | { | 578 | { |
577 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); | 579 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); |
578 | 580 | ||
579 | mutex_lock(&atkbd->event_mutex); | 581 | mutex_lock(&atkbd->mutex); |
580 | 582 | ||
581 | if (!atkbd->enabled) { | 583 | if (!atkbd->enabled) { |
582 | /* | 584 | /* |
@@ -595,7 +597,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
595 | atkbd_set_repeat_rate(atkbd); | 597 | atkbd_set_repeat_rate(atkbd); |
596 | } | 598 | } |
597 | 599 | ||
598 | mutex_unlock(&atkbd->event_mutex); | 600 | mutex_unlock(&atkbd->mutex); |
599 | } | 601 | } |
600 | 602 | ||
601 | /* | 603 | /* |
@@ -611,7 +613,7 @@ static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit) | |||
611 | 613 | ||
612 | atkbd->event_jiffies = jiffies; | 614 | atkbd->event_jiffies = jiffies; |
613 | set_bit(event_bit, &atkbd->event_mask); | 615 | set_bit(event_bit, &atkbd->event_mask); |
614 | wmb(); | 616 | mb(); |
615 | schedule_delayed_work(&atkbd->event_work, delay); | 617 | schedule_delayed_work(&atkbd->event_work, delay); |
616 | } | 618 | } |
617 | 619 | ||
@@ -631,17 +633,18 @@ static int atkbd_event(struct input_dev *dev, | |||
631 | 633 | ||
632 | switch (type) { | 634 | switch (type) { |
633 | 635 | ||
634 | case EV_LED: | 636 | case EV_LED: |
635 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); | 637 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); |
636 | return 0; | 638 | return 0; |
637 | 639 | ||
638 | case EV_REP: | 640 | case EV_REP: |
639 | if (!atkbd->softrepeat) | 641 | if (!atkbd->softrepeat) |
640 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); | 642 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); |
641 | return 0; | 643 | return 0; |
642 | } | ||
643 | 644 | ||
644 | return -1; | 645 | default: |
646 | return -1; | ||
647 | } | ||
645 | } | 648 | } |
646 | 649 | ||
647 | /* | 650 | /* |
@@ -652,7 +655,7 @@ static int atkbd_event(struct input_dev *dev, | |||
652 | static inline void atkbd_enable(struct atkbd *atkbd) | 655 | static inline void atkbd_enable(struct atkbd *atkbd) |
653 | { | 656 | { |
654 | serio_pause_rx(atkbd->ps2dev.serio); | 657 | serio_pause_rx(atkbd->ps2dev.serio); |
655 | atkbd->enabled = 1; | 658 | atkbd->enabled = true; |
656 | serio_continue_rx(atkbd->ps2dev.serio); | 659 | serio_continue_rx(atkbd->ps2dev.serio); |
657 | } | 660 | } |
658 | 661 | ||
@@ -664,7 +667,7 @@ static inline void atkbd_enable(struct atkbd *atkbd) | |||
664 | static inline void atkbd_disable(struct atkbd *atkbd) | 667 | static inline void atkbd_disable(struct atkbd *atkbd) |
665 | { | 668 | { |
666 | serio_pause_rx(atkbd->ps2dev.serio); | 669 | serio_pause_rx(atkbd->ps2dev.serio); |
667 | atkbd->enabled = 0; | 670 | atkbd->enabled = false; |
668 | serio_continue_rx(atkbd->ps2dev.serio); | 671 | serio_continue_rx(atkbd->ps2dev.serio); |
669 | } | 672 | } |
670 | 673 | ||
@@ -685,7 +688,9 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
685 | 688 | ||
686 | if (atkbd_reset) | 689 | if (atkbd_reset) |
687 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) | 690 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) |
688 | printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys); | 691 | dev_warn(&ps2dev->serio->dev, |
692 | "keyboard reset failed on %s\n", | ||
693 | ps2dev->serio->phys); | ||
689 | 694 | ||
690 | /* | 695 | /* |
691 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. | 696 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. |
@@ -715,8 +720,9 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
715 | atkbd->id = (param[0] << 8) | param[1]; | 720 | atkbd->id = (param[0] << 8) | param[1]; |
716 | 721 | ||
717 | if (atkbd->id == 0xaca1 && atkbd->translated) { | 722 | if (atkbd->id == 0xaca1 && atkbd->translated) { |
718 | printk(KERN_ERR "atkbd.c: NCD terminal keyboards are only supported on non-translating\n"); | 723 | dev_err(&ps2dev->serio->dev, |
719 | printk(KERN_ERR "atkbd.c: controllers. Use i8042.direct=1 to disable translation.\n"); | 724 | "NCD terminal keyboards are only supported on non-translating controlelrs. " |
725 | "Use i8042.direct=1 to disable translation.\n"); | ||
720 | return -1; | 726 | return -1; |
721 | } | 727 | } |
722 | 728 | ||
@@ -734,7 +740,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
734 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 740 | struct ps2dev *ps2dev = &atkbd->ps2dev; |
735 | unsigned char param[2]; | 741 | unsigned char param[2]; |
736 | 742 | ||
737 | atkbd->extra = 0; | 743 | atkbd->extra = false; |
738 | /* | 744 | /* |
739 | * For known special keyboards we can go ahead and set the correct set. | 745 | * For known special keyboards we can go ahead and set the correct set. |
740 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and | 746 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and |
@@ -753,7 +759,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
753 | if (allow_extra) { | 759 | if (allow_extra) { |
754 | param[0] = 0x71; | 760 | param[0] = 0x71; |
755 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { | 761 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { |
756 | atkbd->extra = 1; | 762 | atkbd->extra = true; |
757 | return 2; | 763 | return 2; |
758 | } | 764 | } |
759 | } | 765 | } |
@@ -818,7 +824,8 @@ static int atkbd_activate(struct atkbd *atkbd) | |||
818 | */ | 824 | */ |
819 | 825 | ||
820 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { | 826 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { |
821 | printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n", | 827 | dev_err(&ps2dev->serio->dev, |
828 | "Failed to enable keyboard on %s\n", | ||
822 | ps2dev->serio->phys); | 829 | ps2dev->serio->phys); |
823 | return -1; | 830 | return -1; |
824 | } | 831 | } |
@@ -836,7 +843,7 @@ static void atkbd_cleanup(struct serio *serio) | |||
836 | struct atkbd *atkbd = serio_get_drvdata(serio); | 843 | struct atkbd *atkbd = serio_get_drvdata(serio); |
837 | 844 | ||
838 | atkbd_disable(atkbd); | 845 | atkbd_disable(atkbd); |
839 | ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT); | 846 | ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF); |
840 | } | 847 | } |
841 | 848 | ||
842 | 849 | ||
@@ -848,13 +855,20 @@ static void atkbd_disconnect(struct serio *serio) | |||
848 | { | 855 | { |
849 | struct atkbd *atkbd = serio_get_drvdata(serio); | 856 | struct atkbd *atkbd = serio_get_drvdata(serio); |
850 | 857 | ||
858 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | ||
859 | |||
851 | atkbd_disable(atkbd); | 860 | atkbd_disable(atkbd); |
852 | 861 | ||
853 | /* make sure we don't have a command in flight */ | 862 | input_unregister_device(atkbd->dev); |
863 | |||
864 | /* | ||
865 | * Make sure we don't have a command in flight. | ||
866 | * Note that since atkbd->enabled is false event work will keep | ||
867 | * rescheduling itself until it gets canceled and will not try | ||
868 | * accessing freed input device or serio port. | ||
869 | */ | ||
854 | cancel_delayed_work_sync(&atkbd->event_work); | 870 | cancel_delayed_work_sync(&atkbd->event_work); |
855 | 871 | ||
856 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | ||
857 | input_unregister_device(atkbd->dev); | ||
858 | serio_close(serio); | 872 | serio_close(serio); |
859 | serio_set_drvdata(serio, NULL); | 873 | serio_set_drvdata(serio, NULL); |
860 | kfree(atkbd); | 874 | kfree(atkbd); |
@@ -1060,9 +1074,13 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) | |||
1060 | input_dev->keycodesize = sizeof(unsigned short); | 1074 | input_dev->keycodesize = sizeof(unsigned short); |
1061 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); | 1075 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); |
1062 | 1076 | ||
1063 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) | 1077 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) { |
1064 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) | 1078 | if (atkbd->keycode[i] != KEY_RESERVED && |
1079 | atkbd->keycode[i] != ATKBD_KEY_NULL && | ||
1080 | atkbd->keycode[i] < ATKBD_SPECIAL) { | ||
1065 | __set_bit(atkbd->keycode[i], input_dev->keybit); | 1081 | __set_bit(atkbd->keycode[i], input_dev->keybit); |
1082 | } | ||
1083 | } | ||
1066 | } | 1084 | } |
1067 | 1085 | ||
1068 | /* | 1086 | /* |
@@ -1086,16 +1104,18 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1086 | atkbd->dev = dev; | 1104 | atkbd->dev = dev; |
1087 | ps2_init(&atkbd->ps2dev, serio); | 1105 | ps2_init(&atkbd->ps2dev, serio); |
1088 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); | 1106 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); |
1089 | mutex_init(&atkbd->event_mutex); | 1107 | mutex_init(&atkbd->mutex); |
1090 | 1108 | ||
1091 | switch (serio->id.type) { | 1109 | switch (serio->id.type) { |
1092 | 1110 | ||
1093 | case SERIO_8042_XL: | 1111 | case SERIO_8042_XL: |
1094 | atkbd->translated = 1; | 1112 | atkbd->translated = true; |
1095 | case SERIO_8042: | 1113 | /* Fall through */ |
1096 | if (serio->write) | 1114 | |
1097 | atkbd->write = 1; | 1115 | case SERIO_8042: |
1098 | break; | 1116 | if (serio->write) |
1117 | atkbd->write = true; | ||
1118 | break; | ||
1099 | } | 1119 | } |
1100 | 1120 | ||
1101 | atkbd->softraw = atkbd_softraw; | 1121 | atkbd->softraw = atkbd_softraw; |
@@ -1103,7 +1123,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1103 | atkbd->scroll = atkbd_scroll; | 1123 | atkbd->scroll = atkbd_scroll; |
1104 | 1124 | ||
1105 | if (atkbd->softrepeat) | 1125 | if (atkbd->softrepeat) |
1106 | atkbd->softraw = 1; | 1126 | atkbd->softraw = true; |
1107 | 1127 | ||
1108 | serio_set_drvdata(serio, atkbd); | 1128 | serio_set_drvdata(serio, atkbd); |
1109 | 1129 | ||
@@ -1159,19 +1179,24 @@ static int atkbd_reconnect(struct serio *serio) | |||
1159 | { | 1179 | { |
1160 | struct atkbd *atkbd = serio_get_drvdata(serio); | 1180 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1161 | struct serio_driver *drv = serio->drv; | 1181 | struct serio_driver *drv = serio->drv; |
1182 | int retval = -1; | ||
1162 | 1183 | ||
1163 | if (!atkbd || !drv) { | 1184 | if (!atkbd || !drv) { |
1164 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 1185 | dev_dbg(&serio->dev, |
1186 | "reconnect request, but serio is disconnected, ignoring...\n"); | ||
1165 | return -1; | 1187 | return -1; |
1166 | } | 1188 | } |
1167 | 1189 | ||
1190 | mutex_lock(&atkbd->mutex); | ||
1191 | |||
1168 | atkbd_disable(atkbd); | 1192 | atkbd_disable(atkbd); |
1169 | 1193 | ||
1170 | if (atkbd->write) { | 1194 | if (atkbd->write) { |
1171 | if (atkbd_probe(atkbd)) | 1195 | if (atkbd_probe(atkbd)) |
1172 | return -1; | 1196 | goto out; |
1197 | |||
1173 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) | 1198 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) |
1174 | return -1; | 1199 | goto out; |
1175 | 1200 | ||
1176 | atkbd_activate(atkbd); | 1201 | atkbd_activate(atkbd); |
1177 | 1202 | ||
@@ -1189,8 +1214,11 @@ static int atkbd_reconnect(struct serio *serio) | |||
1189 | } | 1214 | } |
1190 | 1215 | ||
1191 | atkbd_enable(atkbd); | 1216 | atkbd_enable(atkbd); |
1217 | retval = 0; | ||
1192 | 1218 | ||
1193 | return 0; | 1219 | out: |
1220 | mutex_unlock(&atkbd->mutex); | ||
1221 | return retval; | ||
1194 | } | 1222 | } |
1195 | 1223 | ||
1196 | static struct serio_device_id atkbd_serio_ids[] = { | 1224 | static struct serio_device_id atkbd_serio_ids[] = { |
@@ -1234,47 +1262,28 @@ static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | |||
1234 | ssize_t (*handler)(struct atkbd *, char *)) | 1262 | ssize_t (*handler)(struct atkbd *, char *)) |
1235 | { | 1263 | { |
1236 | struct serio *serio = to_serio_port(dev); | 1264 | struct serio *serio = to_serio_port(dev); |
1237 | int retval; | 1265 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1238 | |||
1239 | retval = serio_pin_driver(serio); | ||
1240 | if (retval) | ||
1241 | return retval; | ||
1242 | |||
1243 | if (serio->drv != &atkbd_drv) { | ||
1244 | retval = -ENODEV; | ||
1245 | goto out; | ||
1246 | } | ||
1247 | |||
1248 | retval = handler((struct atkbd *)serio_get_drvdata(serio), buf); | ||
1249 | 1266 | ||
1250 | out: | 1267 | return handler(atkbd, buf); |
1251 | serio_unpin_driver(serio); | ||
1252 | return retval; | ||
1253 | } | 1268 | } |
1254 | 1269 | ||
1255 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, | 1270 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, |
1256 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) | 1271 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) |
1257 | { | 1272 | { |
1258 | struct serio *serio = to_serio_port(dev); | 1273 | struct serio *serio = to_serio_port(dev); |
1259 | struct atkbd *atkbd; | 1274 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1260 | int retval; | 1275 | int retval; |
1261 | 1276 | ||
1262 | retval = serio_pin_driver(serio); | 1277 | retval = mutex_lock_interruptible(&atkbd->mutex); |
1263 | if (retval) | 1278 | if (retval) |
1264 | return retval; | 1279 | return retval; |
1265 | 1280 | ||
1266 | if (serio->drv != &atkbd_drv) { | ||
1267 | retval = -ENODEV; | ||
1268 | goto out; | ||
1269 | } | ||
1270 | |||
1271 | atkbd = serio_get_drvdata(serio); | ||
1272 | atkbd_disable(atkbd); | 1281 | atkbd_disable(atkbd); |
1273 | retval = handler(atkbd, buf, count); | 1282 | retval = handler(atkbd, buf, count); |
1274 | atkbd_enable(atkbd); | 1283 | atkbd_enable(atkbd); |
1275 | 1284 | ||
1276 | out: | 1285 | mutex_unlock(&atkbd->mutex); |
1277 | serio_unpin_driver(serio); | 1286 | |
1278 | return retval; | 1287 | return retval; |
1279 | } | 1288 | } |
1280 | 1289 | ||
@@ -1288,7 +1297,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
1288 | struct input_dev *old_dev, *new_dev; | 1297 | struct input_dev *old_dev, *new_dev; |
1289 | unsigned long value; | 1298 | unsigned long value; |
1290 | int err; | 1299 | int err; |
1291 | unsigned char old_extra, old_set; | 1300 | bool old_extra; |
1301 | unsigned char old_set; | ||
1292 | 1302 | ||
1293 | if (!atkbd->write) | 1303 | if (!atkbd->write) |
1294 | return -EIO; | 1304 | return -EIO; |
@@ -1371,7 +1381,7 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou | |||
1371 | struct input_dev *old_dev, *new_dev; | 1381 | struct input_dev *old_dev, *new_dev; |
1372 | unsigned long value; | 1382 | unsigned long value; |
1373 | int err; | 1383 | int err; |
1374 | unsigned char old_scroll; | 1384 | bool old_scroll; |
1375 | 1385 | ||
1376 | if (strict_strtoul(buf, 10, &value) || value > 1) | 1386 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1377 | return -EINVAL; | 1387 | return -EINVAL; |
@@ -1415,7 +1425,8 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | |||
1415 | struct input_dev *old_dev, *new_dev; | 1425 | struct input_dev *old_dev, *new_dev; |
1416 | unsigned long value; | 1426 | unsigned long value; |
1417 | int err; | 1427 | int err; |
1418 | unsigned char old_set, old_extra; | 1428 | unsigned char old_set; |
1429 | bool old_extra; | ||
1419 | 1430 | ||
1420 | if (!atkbd->write) | 1431 | if (!atkbd->write) |
1421 | return -EIO; | 1432 | return -EIO; |
@@ -1465,7 +1476,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1465 | struct input_dev *old_dev, *new_dev; | 1476 | struct input_dev *old_dev, *new_dev; |
1466 | unsigned long value; | 1477 | unsigned long value; |
1467 | int err; | 1478 | int err; |
1468 | unsigned char old_softrepeat, old_softraw; | 1479 | bool old_softrepeat, old_softraw; |
1469 | 1480 | ||
1470 | if (!atkbd->write) | 1481 | if (!atkbd->write) |
1471 | return -EIO; | 1482 | return -EIO; |
@@ -1485,7 +1496,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1485 | atkbd->dev = new_dev; | 1496 | atkbd->dev = new_dev; |
1486 | atkbd->softrepeat = value; | 1497 | atkbd->softrepeat = value; |
1487 | if (atkbd->softrepeat) | 1498 | if (atkbd->softrepeat) |
1488 | atkbd->softraw = 1; | 1499 | atkbd->softraw = true; |
1489 | atkbd_set_device_attrs(atkbd); | 1500 | atkbd_set_device_attrs(atkbd); |
1490 | 1501 | ||
1491 | err = input_register_device(atkbd->dev); | 1502 | err = input_register_device(atkbd->dev); |
@@ -1515,7 +1526,7 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co | |||
1515 | struct input_dev *old_dev, *new_dev; | 1526 | struct input_dev *old_dev, *new_dev; |
1516 | unsigned long value; | 1527 | unsigned long value; |
1517 | int err; | 1528 | int err; |
1518 | unsigned char old_softraw; | 1529 | bool old_softraw; |
1519 | 1530 | ||
1520 | if (strict_strtoul(buf, 10, &value) || value > 1) | 1531 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1521 | return -EINVAL; | 1532 | return -EINVAL; |
@@ -1567,9 +1578,8 @@ static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) | |||
1567 | return 0; | 1578 | return 0; |
1568 | } | 1579 | } |
1569 | 1580 | ||
1570 | static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | 1581 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { |
1571 | { | 1582 | { |
1572 | .ident = "Dell Laptop", | ||
1573 | .matches = { | 1583 | .matches = { |
1574 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 1584 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
1575 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1585 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
@@ -1578,7 +1588,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1578 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 1588 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1579 | }, | 1589 | }, |
1580 | { | 1590 | { |
1581 | .ident = "Dell Laptop", | ||
1582 | .matches = { | 1591 | .matches = { |
1583 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | 1592 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
1584 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1593 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
@@ -1587,7 +1596,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1587 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 1596 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1588 | }, | 1597 | }, |
1589 | { | 1598 | { |
1590 | .ident = "HP 2133", | ||
1591 | .matches = { | 1599 | .matches = { |
1592 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1600 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1593 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), | 1601 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), |
@@ -1596,7 +1604,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1596 | .driver_data = atkbd_hp_forced_release_keys, | 1604 | .driver_data = atkbd_hp_forced_release_keys, |
1597 | }, | 1605 | }, |
1598 | { | 1606 | { |
1599 | .ident = "HP Pavilion ZV6100", | ||
1600 | .matches = { | 1607 | .matches = { |
1601 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1608 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1602 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), | 1609 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), |
@@ -1605,7 +1612,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1605 | .driver_data = atkbd_volume_forced_release_keys, | 1612 | .driver_data = atkbd_volume_forced_release_keys, |
1606 | }, | 1613 | }, |
1607 | { | 1614 | { |
1608 | .ident = "HP Presario R4000", | ||
1609 | .matches = { | 1615 | .matches = { |
1610 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1616 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1611 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), | 1617 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), |
@@ -1614,7 +1620,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1614 | .driver_data = atkbd_volume_forced_release_keys, | 1620 | .driver_data = atkbd_volume_forced_release_keys, |
1615 | }, | 1621 | }, |
1616 | { | 1622 | { |
1617 | .ident = "HP Presario R4100", | ||
1618 | .matches = { | 1623 | .matches = { |
1619 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1624 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1620 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), | 1625 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), |
@@ -1623,7 +1628,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1623 | .driver_data = atkbd_volume_forced_release_keys, | 1628 | .driver_data = atkbd_volume_forced_release_keys, |
1624 | }, | 1629 | }, |
1625 | { | 1630 | { |
1626 | .ident = "HP Presario R4200", | ||
1627 | .matches = { | 1631 | .matches = { |
1628 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1632 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1629 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), | 1633 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), |
@@ -1632,7 +1636,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1632 | .driver_data = atkbd_volume_forced_release_keys, | 1636 | .driver_data = atkbd_volume_forced_release_keys, |
1633 | }, | 1637 | }, |
1634 | { | 1638 | { |
1635 | .ident = "Inventec Symphony", | 1639 | /* Inventec Symphony */ |
1636 | .matches = { | 1640 | .matches = { |
1637 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | 1641 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), |
1638 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), | 1642 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), |
@@ -1641,7 +1645,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1641 | .driver_data = atkbd_volume_forced_release_keys, | 1645 | .driver_data = atkbd_volume_forced_release_keys, |
1642 | }, | 1646 | }, |
1643 | { | 1647 | { |
1644 | .ident = "Samsung NC10", | 1648 | /* Samsung NC10 */ |
1645 | .matches = { | 1649 | .matches = { |
1646 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1650 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1647 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), | 1651 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), |
@@ -1650,7 +1654,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1650 | .driver_data = atkbd_samsung_forced_release_keys, | 1654 | .driver_data = atkbd_samsung_forced_release_keys, |
1651 | }, | 1655 | }, |
1652 | { | 1656 | { |
1653 | .ident = "Samsung NC20", | 1657 | /* Samsung NC20 */ |
1654 | .matches = { | 1658 | .matches = { |
1655 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1659 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1656 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), | 1660 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), |
@@ -1659,7 +1663,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1659 | .driver_data = atkbd_samsung_forced_release_keys, | 1663 | .driver_data = atkbd_samsung_forced_release_keys, |
1660 | }, | 1664 | }, |
1661 | { | 1665 | { |
1662 | .ident = "Samsung SQ45S70S", | 1666 | /* Samsung SQ45S70S */ |
1663 | .matches = { | 1667 | .matches = { |
1664 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1668 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1665 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), | 1669 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), |
@@ -1668,7 +1672,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1668 | .driver_data = atkbd_samsung_forced_release_keys, | 1672 | .driver_data = atkbd_samsung_forced_release_keys, |
1669 | }, | 1673 | }, |
1670 | { | 1674 | { |
1671 | .ident = "Fujitsu Amilo PA 1510", | 1675 | /* Fujitsu Amilo PA 1510 */ |
1672 | .matches = { | 1676 | .matches = { |
1673 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1677 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1674 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), | 1678 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), |
@@ -1677,7 +1681,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1677 | .driver_data = atkbd_volume_forced_release_keys, | 1681 | .driver_data = atkbd_volume_forced_release_keys, |
1678 | }, | 1682 | }, |
1679 | { | 1683 | { |
1680 | .ident = "Fujitsu Amilo Pi 3525", | 1684 | /* Fujitsu Amilo Pi 3525 */ |
1681 | .matches = { | 1685 | .matches = { |
1682 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1686 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1683 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), | 1687 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), |
@@ -1686,7 +1690,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1686 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, | 1690 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, |
1687 | }, | 1691 | }, |
1688 | { | 1692 | { |
1689 | .ident = "Fujitsu Amilo Xi 3650", | 1693 | /* Fujitsu Amilo Xi 3650 */ |
1690 | .matches = { | 1694 | .matches = { |
1691 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1695 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1692 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), | 1696 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), |
@@ -1695,7 +1699,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1695 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, | 1699 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, |
1696 | }, | 1700 | }, |
1697 | { | 1701 | { |
1698 | .ident = "Soltech Corporation TA12", | ||
1699 | .matches = { | 1702 | .matches = { |
1700 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), | 1703 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), |
1701 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), | 1704 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), |
@@ -1704,7 +1707,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1704 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | 1707 | .driver_data = atkdb_soltech_ta12_forced_release_keys, |
1705 | }, | 1708 | }, |
1706 | { | 1709 | { |
1707 | .ident = "OQO Model 01+", | 1710 | /* OQO Model 01+ */ |
1708 | .matches = { | 1711 | .matches = { |
1709 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), | 1712 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), |
1710 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), | 1713 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index fe376a27fe57..7d989603f875 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/fs.h> | 34 | #include <linux/fs.h> |
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
37 | #include <linux/slab.h> | ||
37 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
38 | #include <linux/pm.h> | 39 | #include <linux/pm.h> |
39 | #include <linux/sysctl.h> | 40 | #include <linux/sysctl.h> |
@@ -162,7 +163,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) | |||
162 | input_sync(input); | 163 | input_sync(input); |
163 | 164 | ||
164 | if (bfin_kpad_get_keypressed(bf54x_kpad)) { | 165 | if (bfin_kpad_get_keypressed(bf54x_kpad)) { |
165 | disable_irq(bf54x_kpad->irq); | 166 | disable_irq_nosync(bf54x_kpad->irq); |
166 | bf54x_kpad->lastkey = key; | 167 | bf54x_kpad->lastkey = key; |
167 | mod_timer(&bf54x_kpad->timer, | 168 | mod_timer(&bf54x_kpad->timer, |
168 | jiffies + bf54x_kpad->keyup_test_jiffies); | 169 | jiffies + bf54x_kpad->keyup_test_jiffies); |
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c new file mode 100644 index 000000000000..a91ee941b5c1 --- /dev/null +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* | ||
2 | * DaVinci Key Scan Driver for TI platforms | ||
3 | * | ||
4 | * Copyright (C) 2009 Texas Instruments, Inc | ||
5 | * | ||
6 | * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> | ||
7 | * | ||
8 | * Intial Code: Sandeep Paulraj <s-paulraj@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/input.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | #include <asm/irq.h> | ||
36 | |||
37 | #include <mach/hardware.h> | ||
38 | #include <mach/irqs.h> | ||
39 | #include <mach/keyscan.h> | ||
40 | |||
41 | /* Key scan registers */ | ||
42 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 | ||
43 | #define DAVINCI_KEYSCAN_INTENA 0x0004 | ||
44 | #define DAVINCI_KEYSCAN_INTFLAG 0x0008 | ||
45 | #define DAVINCI_KEYSCAN_INTCLR 0x000c | ||
46 | #define DAVINCI_KEYSCAN_STRBWIDTH 0x0010 | ||
47 | #define DAVINCI_KEYSCAN_INTERVAL 0x0014 | ||
48 | #define DAVINCI_KEYSCAN_CONTTIME 0x0018 | ||
49 | #define DAVINCI_KEYSCAN_CURRENTST 0x001c | ||
50 | #define DAVINCI_KEYSCAN_PREVSTATE 0x0020 | ||
51 | #define DAVINCI_KEYSCAN_EMUCTRL 0x0024 | ||
52 | #define DAVINCI_KEYSCAN_IODFTCTRL 0x002c | ||
53 | |||
54 | /* Key Control Register (KEYCTRL) */ | ||
55 | #define DAVINCI_KEYSCAN_KEYEN 0x00000001 | ||
56 | #define DAVINCI_KEYSCAN_PREVMODE 0x00000002 | ||
57 | #define DAVINCI_KEYSCAN_CHATOFF 0x00000004 | ||
58 | #define DAVINCI_KEYSCAN_AUTODET 0x00000008 | ||
59 | #define DAVINCI_KEYSCAN_SCANMODE 0x00000010 | ||
60 | #define DAVINCI_KEYSCAN_OUTTYPE 0x00000020 | ||
61 | |||
62 | /* Masks for the interrupts */ | ||
63 | #define DAVINCI_KEYSCAN_INT_CONT 0x00000008 | ||
64 | #define DAVINCI_KEYSCAN_INT_OFF 0x00000004 | ||
65 | #define DAVINCI_KEYSCAN_INT_ON 0x00000002 | ||
66 | #define DAVINCI_KEYSCAN_INT_CHANGE 0x00000001 | ||
67 | #define DAVINCI_KEYSCAN_INT_ALL 0x0000000f | ||
68 | |||
69 | struct davinci_ks { | ||
70 | struct input_dev *input; | ||
71 | struct davinci_ks_platform_data *pdata; | ||
72 | int irq; | ||
73 | void __iomem *base; | ||
74 | resource_size_t pbase; | ||
75 | size_t base_size; | ||
76 | unsigned short keymap[]; | ||
77 | }; | ||
78 | |||
79 | /* Initializing the kp Module */ | ||
80 | static int __init davinci_ks_initialize(struct davinci_ks *davinci_ks) | ||
81 | { | ||
82 | struct device *dev = &davinci_ks->input->dev; | ||
83 | struct davinci_ks_platform_data *pdata = davinci_ks->pdata; | ||
84 | u32 matrix_ctrl; | ||
85 | |||
86 | /* Enable all interrupts */ | ||
87 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
88 | davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
89 | |||
90 | /* Clear interrupts if any */ | ||
91 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
92 | davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); | ||
93 | |||
94 | /* Setup the scan period = strobe + interval */ | ||
95 | __raw_writel(pdata->strobe, | ||
96 | davinci_ks->base + DAVINCI_KEYSCAN_STRBWIDTH); | ||
97 | __raw_writel(pdata->interval, | ||
98 | davinci_ks->base + DAVINCI_KEYSCAN_INTERVAL); | ||
99 | __raw_writel(0x01, | ||
100 | davinci_ks->base + DAVINCI_KEYSCAN_CONTTIME); | ||
101 | |||
102 | /* Define matrix type */ | ||
103 | switch (pdata->matrix_type) { | ||
104 | case DAVINCI_KEYSCAN_MATRIX_4X4: | ||
105 | matrix_ctrl = 0; | ||
106 | break; | ||
107 | case DAVINCI_KEYSCAN_MATRIX_5X3: | ||
108 | matrix_ctrl = (1 << 6); | ||
109 | break; | ||
110 | default: | ||
111 | dev_err(dev->parent, "wrong matrix type\n"); | ||
112 | return -EINVAL; | ||
113 | } | ||
114 | |||
115 | /* Enable key scan module and set matrix type */ | ||
116 | __raw_writel(DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN | | ||
117 | matrix_ctrl, davinci_ks->base + DAVINCI_KEYSCAN_KEYCTRL); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id) | ||
123 | { | ||
124 | struct davinci_ks *davinci_ks = dev_id; | ||
125 | struct device *dev = &davinci_ks->input->dev; | ||
126 | unsigned short *keymap = davinci_ks->keymap; | ||
127 | int keymapsize = davinci_ks->pdata->keymapsize; | ||
128 | u32 prev_status, new_status, changed; | ||
129 | bool release; | ||
130 | int keycode = KEY_UNKNOWN; | ||
131 | int i; | ||
132 | |||
133 | /* Disable interrupt */ | ||
134 | __raw_writel(0x0, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
135 | |||
136 | /* Reading previous and new status of the key scan */ | ||
137 | prev_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_PREVSTATE); | ||
138 | new_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_CURRENTST); | ||
139 | |||
140 | changed = prev_status ^ new_status; | ||
141 | |||
142 | if (changed) { | ||
143 | /* | ||
144 | * It goes through all bits in 'changed' to ensure | ||
145 | * that no key changes are being missed | ||
146 | */ | ||
147 | for (i = 0 ; i < keymapsize; i++) { | ||
148 | if ((changed>>i) & 0x1) { | ||
149 | keycode = keymap[i]; | ||
150 | release = (new_status >> i) & 0x1; | ||
151 | dev_dbg(dev->parent, "key %d %s\n", keycode, | ||
152 | release ? "released" : "pressed"); | ||
153 | input_report_key(davinci_ks->input, keycode, | ||
154 | !release); | ||
155 | input_sync(davinci_ks->input); | ||
156 | } | ||
157 | } | ||
158 | /* Clearing interrupt */ | ||
159 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
160 | davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); | ||
161 | } | ||
162 | |||
163 | /* Enable interrupts */ | ||
164 | __raw_writel(0x1, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
165 | |||
166 | return IRQ_HANDLED; | ||
167 | } | ||
168 | |||
169 | static int __init davinci_ks_probe(struct platform_device *pdev) | ||
170 | { | ||
171 | struct davinci_ks *davinci_ks; | ||
172 | struct input_dev *key_dev; | ||
173 | struct resource *res, *mem; | ||
174 | struct device *dev = &pdev->dev; | ||
175 | struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; | ||
176 | int error, i; | ||
177 | |||
178 | if (pdata->device_enable) { | ||
179 | error = pdata->device_enable(dev); | ||
180 | if (error < 0) { | ||
181 | dev_dbg(dev, "device enable function failed\n"); | ||
182 | return error; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | if (!pdata->keymap) { | ||
187 | dev_dbg(dev, "no keymap from pdata\n"); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | davinci_ks = kzalloc(sizeof(struct davinci_ks) + | ||
192 | sizeof(unsigned short) * pdata->keymapsize, GFP_KERNEL); | ||
193 | if (!davinci_ks) { | ||
194 | dev_dbg(dev, "could not allocate memory for private data\n"); | ||
195 | return -ENOMEM; | ||
196 | } | ||
197 | |||
198 | memcpy(davinci_ks->keymap, pdata->keymap, | ||
199 | sizeof(unsigned short) * pdata->keymapsize); | ||
200 | |||
201 | key_dev = input_allocate_device(); | ||
202 | if (!key_dev) { | ||
203 | dev_dbg(dev, "could not allocate input device\n"); | ||
204 | error = -ENOMEM; | ||
205 | goto fail1; | ||
206 | } | ||
207 | |||
208 | davinci_ks->input = key_dev; | ||
209 | |||
210 | davinci_ks->irq = platform_get_irq(pdev, 0); | ||
211 | if (davinci_ks->irq < 0) { | ||
212 | dev_err(dev, "no key scan irq\n"); | ||
213 | error = davinci_ks->irq; | ||
214 | goto fail2; | ||
215 | } | ||
216 | |||
217 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
218 | if (!res) { | ||
219 | dev_err(dev, "no mem resource\n"); | ||
220 | error = -EINVAL; | ||
221 | goto fail2; | ||
222 | } | ||
223 | |||
224 | davinci_ks->pbase = res->start; | ||
225 | davinci_ks->base_size = resource_size(res); | ||
226 | |||
227 | mem = request_mem_region(davinci_ks->pbase, davinci_ks->base_size, | ||
228 | pdev->name); | ||
229 | if (!mem) { | ||
230 | dev_err(dev, "key scan registers at %08x are not free\n", | ||
231 | davinci_ks->pbase); | ||
232 | error = -EBUSY; | ||
233 | goto fail2; | ||
234 | } | ||
235 | |||
236 | davinci_ks->base = ioremap(davinci_ks->pbase, davinci_ks->base_size); | ||
237 | if (!davinci_ks->base) { | ||
238 | dev_err(dev, "can't ioremap MEM resource.\n"); | ||
239 | error = -ENOMEM; | ||
240 | goto fail3; | ||
241 | } | ||
242 | |||
243 | /* Enable auto repeat feature of Linux input subsystem */ | ||
244 | if (pdata->rep) | ||
245 | __set_bit(EV_REP, key_dev->evbit); | ||
246 | |||
247 | /* Setup input device */ | ||
248 | __set_bit(EV_KEY, key_dev->evbit); | ||
249 | |||
250 | /* Setup the platform data */ | ||
251 | davinci_ks->pdata = pdata; | ||
252 | |||
253 | for (i = 0; i < davinci_ks->pdata->keymapsize; i++) | ||
254 | __set_bit(davinci_ks->pdata->keymap[i], key_dev->keybit); | ||
255 | |||
256 | key_dev->name = "davinci_keyscan"; | ||
257 | key_dev->phys = "davinci_keyscan/input0"; | ||
258 | key_dev->dev.parent = &pdev->dev; | ||
259 | key_dev->id.bustype = BUS_HOST; | ||
260 | key_dev->id.vendor = 0x0001; | ||
261 | key_dev->id.product = 0x0001; | ||
262 | key_dev->id.version = 0x0001; | ||
263 | key_dev->keycode = davinci_ks->keymap; | ||
264 | key_dev->keycodesize = sizeof(davinci_ks->keymap[0]); | ||
265 | key_dev->keycodemax = davinci_ks->pdata->keymapsize; | ||
266 | |||
267 | error = input_register_device(davinci_ks->input); | ||
268 | if (error < 0) { | ||
269 | dev_err(dev, "unable to register davinci key scan device\n"); | ||
270 | goto fail4; | ||
271 | } | ||
272 | |||
273 | error = request_irq(davinci_ks->irq, davinci_ks_interrupt, | ||
274 | IRQF_DISABLED, pdev->name, davinci_ks); | ||
275 | if (error < 0) { | ||
276 | dev_err(dev, "unable to register davinci key scan interrupt\n"); | ||
277 | goto fail5; | ||
278 | } | ||
279 | |||
280 | error = davinci_ks_initialize(davinci_ks); | ||
281 | if (error < 0) { | ||
282 | dev_err(dev, "unable to initialize davinci key scan device\n"); | ||
283 | goto fail6; | ||
284 | } | ||
285 | |||
286 | platform_set_drvdata(pdev, davinci_ks); | ||
287 | return 0; | ||
288 | |||
289 | fail6: | ||
290 | free_irq(davinci_ks->irq, davinci_ks); | ||
291 | fail5: | ||
292 | input_unregister_device(davinci_ks->input); | ||
293 | key_dev = NULL; | ||
294 | fail4: | ||
295 | iounmap(davinci_ks->base); | ||
296 | fail3: | ||
297 | release_mem_region(davinci_ks->pbase, davinci_ks->base_size); | ||
298 | fail2: | ||
299 | input_free_device(key_dev); | ||
300 | fail1: | ||
301 | kfree(davinci_ks); | ||
302 | |||
303 | return error; | ||
304 | } | ||
305 | |||
306 | static int __devexit davinci_ks_remove(struct platform_device *pdev) | ||
307 | { | ||
308 | struct davinci_ks *davinci_ks = platform_get_drvdata(pdev); | ||
309 | |||
310 | free_irq(davinci_ks->irq, davinci_ks); | ||
311 | |||
312 | input_unregister_device(davinci_ks->input); | ||
313 | |||
314 | iounmap(davinci_ks->base); | ||
315 | release_mem_region(davinci_ks->pbase, davinci_ks->base_size); | ||
316 | |||
317 | platform_set_drvdata(pdev, NULL); | ||
318 | |||
319 | kfree(davinci_ks); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static struct platform_driver davinci_ks_driver = { | ||
325 | .driver = { | ||
326 | .name = "davinci_keyscan", | ||
327 | .owner = THIS_MODULE, | ||
328 | }, | ||
329 | .remove = __devexit_p(davinci_ks_remove), | ||
330 | }; | ||
331 | |||
332 | static int __init davinci_ks_init(void) | ||
333 | { | ||
334 | return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe); | ||
335 | } | ||
336 | module_init(davinci_ks_init); | ||
337 | |||
338 | static void __exit davinci_ks_exit(void) | ||
339 | { | ||
340 | platform_driver_unregister(&davinci_ks_driver); | ||
341 | } | ||
342 | module_exit(davinci_ks_exit); | ||
343 | |||
344 | MODULE_AUTHOR("Miguel Aguilar"); | ||
345 | MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver"); | ||
346 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index 181d30e3018e..c8242dd190d0 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
@@ -22,11 +22,12 @@ | |||
22 | 22 | ||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/input.h> | ||
26 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/io.h> | ||
27 | #include <linux/input/matrix_keypad.h> | ||
28 | #include <linux/slab.h> | ||
27 | 29 | ||
28 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
29 | #include <mach/gpio.h> | ||
30 | #include <mach/ep93xx_keypad.h> | 31 | #include <mach/ep93xx_keypad.h> |
31 | 32 | ||
32 | /* | 33 | /* |
@@ -60,56 +61,39 @@ | |||
60 | #define KEY_REG_KEY1_MASK (0x0000003f) | 61 | #define KEY_REG_KEY1_MASK (0x0000003f) |
61 | #define KEY_REG_KEY1_SHIFT (0) | 62 | #define KEY_REG_KEY1_SHIFT (0) |
62 | 63 | ||
63 | #define keypad_readl(off) __raw_readl(keypad->mmio_base + (off)) | 64 | #define EP93XX_MATRIX_SIZE (EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS) |
64 | #define keypad_writel(v, off) __raw_writel((v), keypad->mmio_base + (off)) | ||
65 | |||
66 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) | ||
67 | 65 | ||
68 | struct ep93xx_keypad { | 66 | struct ep93xx_keypad { |
69 | struct ep93xx_keypad_platform_data *pdata; | 67 | struct ep93xx_keypad_platform_data *pdata; |
70 | |||
71 | struct clk *clk; | ||
72 | struct input_dev *input_dev; | 68 | struct input_dev *input_dev; |
69 | struct clk *clk; | ||
70 | |||
73 | void __iomem *mmio_base; | 71 | void __iomem *mmio_base; |
74 | 72 | ||
75 | int irq; | 73 | unsigned short keycodes[EP93XX_MATRIX_SIZE]; |
76 | int enabled; | ||
77 | 74 | ||
78 | int key1; | 75 | int key1; |
79 | int key2; | 76 | int key2; |
80 | 77 | ||
81 | unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; | 78 | int irq; |
82 | }; | ||
83 | |||
84 | static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad) | ||
85 | { | ||
86 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; | ||
87 | struct input_dev *input_dev = keypad->input_dev; | ||
88 | int i; | ||
89 | |||
90 | for (i = 0; i < pdata->matrix_key_map_size; i++) { | ||
91 | unsigned int key = pdata->matrix_key_map[i]; | ||
92 | int row = (key >> 28) & 0xf; | ||
93 | int col = (key >> 24) & 0xf; | ||
94 | int code = key & 0xffffff; | ||
95 | 79 | ||
96 | keypad->matrix_keycodes[(row << 3) + col] = code; | 80 | bool enabled; |
97 | __set_bit(code, input_dev->keybit); | 81 | }; |
98 | } | ||
99 | } | ||
100 | 82 | ||
101 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) | 83 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) |
102 | { | 84 | { |
103 | struct ep93xx_keypad *keypad = dev_id; | 85 | struct ep93xx_keypad *keypad = dev_id; |
104 | struct input_dev *input_dev = keypad->input_dev; | 86 | struct input_dev *input_dev = keypad->input_dev; |
105 | unsigned int status = keypad_readl(KEY_REG); | 87 | unsigned int status; |
106 | int keycode, key1, key2; | 88 | int keycode, key1, key2; |
107 | 89 | ||
90 | status = __raw_readl(keypad->mmio_base + KEY_REG); | ||
91 | |||
108 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; | 92 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; |
109 | key1 = keypad->matrix_keycodes[keycode]; | 93 | key1 = keypad->keycodes[keycode]; |
110 | 94 | ||
111 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; | 95 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; |
112 | key2 = keypad->matrix_keycodes[keycode]; | 96 | key2 = keypad->keycodes[keycode]; |
113 | 97 | ||
114 | if (status & KEY_REG_2KEYS) { | 98 | if (status & KEY_REG_2KEYS) { |
115 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) | 99 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) |
@@ -152,7 +136,10 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad) | |||
152 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; | 136 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; |
153 | unsigned int val = 0; | 137 | unsigned int val = 0; |
154 | 138 | ||
155 | clk_set_rate(keypad->clk, pdata->flags & EP93XX_KEYPAD_KDIV); | 139 | if (pdata->flags & EP93XX_KEYPAD_KDIV) |
140 | clk_set_rate(keypad->clk, EP93XX_KEYTCHCLK_DIV4); | ||
141 | else | ||
142 | clk_set_rate(keypad->clk, EP93XX_KEYTCHCLK_DIV16); | ||
156 | 143 | ||
157 | if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY) | 144 | if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY) |
158 | val |= KEY_INIT_DIS3KY; | 145 | val |= KEY_INIT_DIS3KY; |
@@ -167,7 +154,7 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad) | |||
167 | 154 | ||
168 | val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK); | 155 | val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK); |
169 | 156 | ||
170 | keypad_writel(val, KEY_INIT); | 157 | __raw_writel(val, keypad->mmio_base + KEY_INIT); |
171 | } | 158 | } |
172 | 159 | ||
173 | static int ep93xx_keypad_open(struct input_dev *pdev) | 160 | static int ep93xx_keypad_open(struct input_dev *pdev) |
@@ -177,7 +164,7 @@ static int ep93xx_keypad_open(struct input_dev *pdev) | |||
177 | if (!keypad->enabled) { | 164 | if (!keypad->enabled) { |
178 | ep93xx_keypad_config(keypad); | 165 | ep93xx_keypad_config(keypad); |
179 | clk_enable(keypad->clk); | 166 | clk_enable(keypad->clk); |
180 | keypad->enabled = 1; | 167 | keypad->enabled = true; |
181 | } | 168 | } |
182 | 169 | ||
183 | return 0; | 170 | return 0; |
@@ -189,7 +176,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev) | |||
189 | 176 | ||
190 | if (keypad->enabled) { | 177 | if (keypad->enabled) { |
191 | clk_disable(keypad->clk); | 178 | clk_disable(keypad->clk); |
192 | keypad->enabled = 0; | 179 | keypad->enabled = false; |
193 | } | 180 | } |
194 | } | 181 | } |
195 | 182 | ||
@@ -211,7 +198,7 @@ static int ep93xx_keypad_suspend(struct platform_device *pdev, | |||
211 | 198 | ||
212 | if (keypad->enabled) { | 199 | if (keypad->enabled) { |
213 | clk_disable(keypad->clk); | 200 | clk_disable(keypad->clk); |
214 | keypad->enabled = 0; | 201 | keypad->enabled = false; |
215 | } | 202 | } |
216 | 203 | ||
217 | mutex_unlock(&input_dev->mutex); | 204 | mutex_unlock(&input_dev->mutex); |
@@ -236,7 +223,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) | |||
236 | if (!keypad->enabled) { | 223 | if (!keypad->enabled) { |
237 | ep93xx_keypad_config(keypad); | 224 | ep93xx_keypad_config(keypad); |
238 | clk_enable(keypad->clk); | 225 | clk_enable(keypad->clk); |
239 | keypad->enabled = 1; | 226 | keypad->enabled = true; |
240 | } | 227 | } |
241 | } | 228 | } |
242 | 229 | ||
@@ -252,88 +239,63 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) | |||
252 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | 239 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) |
253 | { | 240 | { |
254 | struct ep93xx_keypad *keypad; | 241 | struct ep93xx_keypad *keypad; |
255 | struct ep93xx_keypad_platform_data *pdata = pdev->dev.platform_data; | 242 | const struct matrix_keymap_data *keymap_data; |
256 | struct input_dev *input_dev; | 243 | struct input_dev *input_dev; |
257 | struct resource *res; | 244 | struct resource *res; |
258 | int irq, err, i, gpio; | 245 | int err; |
259 | |||
260 | if (!pdata || | ||
261 | !pdata->matrix_key_rows || | ||
262 | pdata->matrix_key_rows > MAX_MATRIX_KEY_ROWS || | ||
263 | !pdata->matrix_key_cols || | ||
264 | pdata->matrix_key_cols > MAX_MATRIX_KEY_COLS) { | ||
265 | dev_err(&pdev->dev, "invalid or missing platform data\n"); | ||
266 | return -EINVAL; | ||
267 | } | ||
268 | 246 | ||
269 | keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL); | 247 | keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL); |
270 | if (!keypad) { | 248 | if (!keypad) |
271 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
272 | return -ENOMEM; | 249 | return -ENOMEM; |
250 | |||
251 | keypad->pdata = pdev->dev.platform_data; | ||
252 | if (!keypad->pdata) { | ||
253 | err = -EINVAL; | ||
254 | goto failed_free; | ||
273 | } | 255 | } |
274 | 256 | ||
275 | keypad->pdata = pdata; | 257 | keymap_data = keypad->pdata->keymap_data; |
258 | if (!keymap_data) { | ||
259 | err = -EINVAL; | ||
260 | goto failed_free; | ||
261 | } | ||
276 | 262 | ||
277 | irq = platform_get_irq(pdev, 0); | 263 | keypad->irq = platform_get_irq(pdev, 0); |
278 | if (irq < 0) { | 264 | if (!keypad->irq) { |
279 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | ||
280 | err = -ENXIO; | 265 | err = -ENXIO; |
281 | goto failed_free; | 266 | goto failed_free; |
282 | } | 267 | } |
283 | 268 | ||
284 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 269 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
285 | if (!res) { | 270 | if (!res) { |
286 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
287 | err = -ENXIO; | 271 | err = -ENXIO; |
288 | goto failed_free; | 272 | goto failed_free; |
289 | } | 273 | } |
290 | 274 | ||
291 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 275 | res = request_mem_region(res->start, resource_size(res), pdev->name); |
292 | if (!res) { | 276 | if (!res) { |
293 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
294 | err = -EBUSY; | 277 | err = -EBUSY; |
295 | goto failed_free; | 278 | goto failed_free; |
296 | } | 279 | } |
297 | 280 | ||
298 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | 281 | keypad->mmio_base = ioremap(res->start, resource_size(res)); |
299 | if (keypad->mmio_base == NULL) { | 282 | if (keypad->mmio_base == NULL) { |
300 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
301 | err = -ENXIO; | 283 | err = -ENXIO; |
302 | goto failed_free_mem; | 284 | goto failed_free_mem; |
303 | } | 285 | } |
304 | 286 | ||
305 | /* Request the needed GPIO's */ | 287 | err = ep93xx_keypad_acquire_gpio(pdev); |
306 | gpio = EP93XX_GPIO_LINE_ROW0; | 288 | if (err) |
307 | for (i = 0; i < keypad->pdata->matrix_key_rows; i++, gpio++) { | 289 | goto failed_free_io; |
308 | err = gpio_request(gpio, pdev->name); | ||
309 | if (err) { | ||
310 | dev_err(&pdev->dev, "failed to request gpio-%d\n", | ||
311 | gpio); | ||
312 | goto failed_free_rows; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | gpio = EP93XX_GPIO_LINE_COL0; | ||
317 | for (i = 0; i < keypad->pdata->matrix_key_cols; i++, gpio++) { | ||
318 | err = gpio_request(gpio, pdev->name); | ||
319 | if (err) { | ||
320 | dev_err(&pdev->dev, "failed to request gpio-%d\n", | ||
321 | gpio); | ||
322 | goto failed_free_cols; | ||
323 | } | ||
324 | } | ||
325 | 290 | ||
326 | keypad->clk = clk_get(&pdev->dev, "key_clk"); | 291 | keypad->clk = clk_get(&pdev->dev, NULL); |
327 | if (IS_ERR(keypad->clk)) { | 292 | if (IS_ERR(keypad->clk)) { |
328 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | ||
329 | err = PTR_ERR(keypad->clk); | 293 | err = PTR_ERR(keypad->clk); |
330 | goto failed_free_io; | 294 | goto failed_free_gpio; |
331 | } | 295 | } |
332 | 296 | ||
333 | /* Create and register the input driver */ | ||
334 | input_dev = input_allocate_device(); | 297 | input_dev = input_allocate_device(); |
335 | if (!input_dev) { | 298 | if (!input_dev) { |
336 | dev_err(&pdev->dev, "failed to allocate input device\n"); | ||
337 | err = -ENOMEM; | 299 | err = -ENOMEM; |
338 | goto failed_put_clk; | 300 | goto failed_put_clk; |
339 | } | 301 | } |
@@ -345,9 +307,9 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
345 | input_dev->open = ep93xx_keypad_open; | 307 | input_dev->open = ep93xx_keypad_open; |
346 | input_dev->close = ep93xx_keypad_close; | 308 | input_dev->close = ep93xx_keypad_close; |
347 | input_dev->dev.parent = &pdev->dev; | 309 | input_dev->dev.parent = &pdev->dev; |
348 | input_dev->keycode = keypad->matrix_keycodes; | 310 | input_dev->keycode = keypad->keycodes; |
349 | input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]); | 311 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); |
350 | input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes); | 312 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); |
351 | 313 | ||
352 | input_set_drvdata(input_dev, keypad); | 314 | input_set_drvdata(input_dev, keypad); |
353 | 315 | ||
@@ -355,47 +317,33 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
355 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) | 317 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) |
356 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | 318 | input_dev->evbit[0] |= BIT_MASK(EV_REP); |
357 | 319 | ||
358 | ep93xx_keypad_build_keycode(keypad); | 320 | matrix_keypad_build_keymap(keymap_data, 3, |
321 | input_dev->keycode, input_dev->keybit); | ||
359 | platform_set_drvdata(pdev, keypad); | 322 | platform_set_drvdata(pdev, keypad); |
360 | 323 | ||
361 | err = request_irq(irq, ep93xx_keypad_irq_handler, IRQF_DISABLED, | 324 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, |
362 | pdev->name, keypad); | 325 | IRQF_DISABLED, pdev->name, keypad); |
363 | if (err) { | 326 | if (err) |
364 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
365 | goto failed_free_dev; | 327 | goto failed_free_dev; |
366 | } | ||
367 | 328 | ||
368 | keypad->irq = irq; | ||
369 | |||
370 | /* Register the input device */ | ||
371 | err = input_register_device(input_dev); | 329 | err = input_register_device(input_dev); |
372 | if (err) { | 330 | if (err) |
373 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
374 | goto failed_free_irq; | 331 | goto failed_free_irq; |
375 | } | ||
376 | 332 | ||
377 | device_init_wakeup(&pdev->dev, 1); | 333 | device_init_wakeup(&pdev->dev, 1); |
378 | 334 | ||
379 | return 0; | 335 | return 0; |
380 | 336 | ||
381 | failed_free_irq: | 337 | failed_free_irq: |
382 | free_irq(irq, pdev); | 338 | free_irq(keypad->irq, pdev); |
383 | platform_set_drvdata(pdev, NULL); | 339 | platform_set_drvdata(pdev, NULL); |
384 | failed_free_dev: | 340 | failed_free_dev: |
385 | input_free_device(input_dev); | 341 | input_free_device(input_dev); |
386 | failed_put_clk: | 342 | failed_put_clk: |
387 | clk_put(keypad->clk); | 343 | clk_put(keypad->clk); |
344 | failed_free_gpio: | ||
345 | ep93xx_keypad_release_gpio(pdev); | ||
388 | failed_free_io: | 346 | failed_free_io: |
389 | i = keypad->pdata->matrix_key_cols - 1; | ||
390 | gpio = EP93XX_GPIO_LINE_COL0 + i; | ||
391 | failed_free_cols: | ||
392 | for ( ; i >= 0; i--, gpio--) | ||
393 | gpio_free(gpio); | ||
394 | i = keypad->pdata->matrix_key_rows - 1; | ||
395 | gpio = EP93XX_GPIO_LINE_ROW0 + i; | ||
396 | failed_free_rows: | ||
397 | for ( ; i >= 0; i--, gpio--) | ||
398 | gpio_free(gpio); | ||
399 | iounmap(keypad->mmio_base); | 347 | iounmap(keypad->mmio_base); |
400 | failed_free_mem: | 348 | failed_free_mem: |
401 | release_mem_region(res->start, resource_size(res)); | 349 | release_mem_region(res->start, resource_size(res)); |
@@ -408,7 +356,6 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev) | |||
408 | { | 356 | { |
409 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | 357 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); |
410 | struct resource *res; | 358 | struct resource *res; |
411 | int i, gpio; | ||
412 | 359 | ||
413 | free_irq(keypad->irq, pdev); | 360 | free_irq(keypad->irq, pdev); |
414 | 361 | ||
@@ -420,15 +367,7 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev) | |||
420 | 367 | ||
421 | input_unregister_device(keypad->input_dev); | 368 | input_unregister_device(keypad->input_dev); |
422 | 369 | ||
423 | i = keypad->pdata->matrix_key_cols - 1; | 370 | ep93xx_keypad_release_gpio(pdev); |
424 | gpio = EP93XX_GPIO_LINE_COL0 + i; | ||
425 | for ( ; i >= 0; i--, gpio--) | ||
426 | gpio_free(gpio); | ||
427 | |||
428 | i = keypad->pdata->matrix_key_rows - 1; | ||
429 | gpio = EP93XX_GPIO_LINE_ROW0 + i; | ||
430 | for ( ; i >= 0; i--, gpio--) | ||
431 | gpio_free(gpio); | ||
432 | 371 | ||
433 | iounmap(keypad->mmio_base); | 372 | iounmap(keypad->mmio_base); |
434 | 373 | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 77d130914259..b8213fd13c3f 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/slab.h> | ||
19 | #include <linux/sysctl.h> | 20 | #include <linux/sysctl.h> |
20 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
21 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
@@ -23,25 +24,298 @@ | |||
23 | #include <linux/input.h> | 24 | #include <linux/input.h> |
24 | #include <linux/gpio_keys.h> | 25 | #include <linux/gpio_keys.h> |
25 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
26 | 27 | #include <linux/gpio.h> | |
27 | #include <asm/gpio.h> | ||
28 | 28 | ||
29 | struct gpio_button_data { | 29 | struct gpio_button_data { |
30 | struct gpio_keys_button *button; | 30 | struct gpio_keys_button *button; |
31 | struct input_dev *input; | 31 | struct input_dev *input; |
32 | struct timer_list timer; | 32 | struct timer_list timer; |
33 | struct work_struct work; | 33 | struct work_struct work; |
34 | bool disabled; | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | struct gpio_keys_drvdata { | 37 | struct gpio_keys_drvdata { |
37 | struct input_dev *input; | 38 | struct input_dev *input; |
39 | struct mutex disable_lock; | ||
40 | unsigned int n_buttons; | ||
38 | struct gpio_button_data data[0]; | 41 | struct gpio_button_data data[0]; |
39 | }; | 42 | }; |
40 | 43 | ||
41 | static void gpio_keys_report_event(struct work_struct *work) | 44 | /* |
45 | * SYSFS interface for enabling/disabling keys and switches: | ||
46 | * | ||
47 | * There are 4 attributes under /sys/devices/platform/gpio-keys/ | ||
48 | * keys [ro] - bitmap of keys (EV_KEY) which can be | ||
49 | * disabled | ||
50 | * switches [ro] - bitmap of switches (EV_SW) which can be | ||
51 | * disabled | ||
52 | * disabled_keys [rw] - bitmap of keys currently disabled | ||
53 | * disabled_switches [rw] - bitmap of switches currently disabled | ||
54 | * | ||
55 | * Userland can change these values and hence disable event generation | ||
56 | * for each key (or switch). Disabling a key means its interrupt line | ||
57 | * is disabled. | ||
58 | * | ||
59 | * For example, if we have following switches set up as gpio-keys: | ||
60 | * SW_DOCK = 5 | ||
61 | * SW_CAMERA_LENS_COVER = 9 | ||
62 | * SW_KEYPAD_SLIDE = 10 | ||
63 | * SW_FRONT_PROXIMITY = 11 | ||
64 | * This is read from switches: | ||
65 | * 11-9,5 | ||
66 | * Next we want to disable proximity (11) and dock (5), we write: | ||
67 | * 11,5 | ||
68 | * to file disabled_switches. Now proximity and dock IRQs are disabled. | ||
69 | * This can be verified by reading the file disabled_switches: | ||
70 | * 11,5 | ||
71 | * If we now want to enable proximity (11) switch we write: | ||
72 | * 5 | ||
73 | * to disabled_switches. | ||
74 | * | ||
75 | * We can disable only those keys which don't allow sharing the irq. | ||
76 | */ | ||
77 | |||
78 | /** | ||
79 | * get_n_events_by_type() - returns maximum number of events per @type | ||
80 | * @type: type of button (%EV_KEY, %EV_SW) | ||
81 | * | ||
82 | * Return value of this function can be used to allocate bitmap | ||
83 | * large enough to hold all bits for given type. | ||
84 | */ | ||
85 | static inline int get_n_events_by_type(int type) | ||
86 | { | ||
87 | BUG_ON(type != EV_SW && type != EV_KEY); | ||
88 | |||
89 | return (type == EV_KEY) ? KEY_CNT : SW_CNT; | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * gpio_keys_disable_button() - disables given GPIO button | ||
94 | * @bdata: button data for button to be disabled | ||
95 | * | ||
96 | * Disables button pointed by @bdata. This is done by masking | ||
97 | * IRQ line. After this function is called, button won't generate | ||
98 | * input events anymore. Note that one can only disable buttons | ||
99 | * that don't share IRQs. | ||
100 | * | ||
101 | * Make sure that @bdata->disable_lock is locked when entering | ||
102 | * this function to avoid races when concurrent threads are | ||
103 | * disabling buttons at the same time. | ||
104 | */ | ||
105 | static void gpio_keys_disable_button(struct gpio_button_data *bdata) | ||
106 | { | ||
107 | if (!bdata->disabled) { | ||
108 | /* | ||
109 | * Disable IRQ and possible debouncing timer. | ||
110 | */ | ||
111 | disable_irq(gpio_to_irq(bdata->button->gpio)); | ||
112 | if (bdata->button->debounce_interval) | ||
113 | del_timer_sync(&bdata->timer); | ||
114 | |||
115 | bdata->disabled = true; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * gpio_keys_enable_button() - enables given GPIO button | ||
121 | * @bdata: button data for button to be disabled | ||
122 | * | ||
123 | * Enables given button pointed by @bdata. | ||
124 | * | ||
125 | * Make sure that @bdata->disable_lock is locked when entering | ||
126 | * this function to avoid races with concurrent threads trying | ||
127 | * to enable the same button at the same time. | ||
128 | */ | ||
129 | static void gpio_keys_enable_button(struct gpio_button_data *bdata) | ||
130 | { | ||
131 | if (bdata->disabled) { | ||
132 | enable_irq(gpio_to_irq(bdata->button->gpio)); | ||
133 | bdata->disabled = false; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons | ||
139 | * @ddata: pointer to drvdata | ||
140 | * @buf: buffer where stringified bitmap is written | ||
141 | * @type: button type (%EV_KEY, %EV_SW) | ||
142 | * @only_disabled: does caller want only those buttons that are | ||
143 | * currently disabled or all buttons that can be | ||
144 | * disabled | ||
145 | * | ||
146 | * This function writes buttons that can be disabled to @buf. If | ||
147 | * @only_disabled is true, then @buf contains only those buttons | ||
148 | * that are currently disabled. Returns 0 on success or negative | ||
149 | * errno on failure. | ||
150 | */ | ||
151 | static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, | ||
152 | char *buf, unsigned int type, | ||
153 | bool only_disabled) | ||
154 | { | ||
155 | int n_events = get_n_events_by_type(type); | ||
156 | unsigned long *bits; | ||
157 | ssize_t ret; | ||
158 | int i; | ||
159 | |||
160 | bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); | ||
161 | if (!bits) | ||
162 | return -ENOMEM; | ||
163 | |||
164 | for (i = 0; i < ddata->n_buttons; i++) { | ||
165 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
166 | |||
167 | if (bdata->button->type != type) | ||
168 | continue; | ||
169 | |||
170 | if (only_disabled && !bdata->disabled) | ||
171 | continue; | ||
172 | |||
173 | __set_bit(bdata->button->code, bits); | ||
174 | } | ||
175 | |||
176 | ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); | ||
177 | buf[ret++] = '\n'; | ||
178 | buf[ret] = '\0'; | ||
179 | |||
180 | kfree(bits); | ||
181 | |||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap | ||
187 | * @ddata: pointer to drvdata | ||
188 | * @buf: buffer from userspace that contains stringified bitmap | ||
189 | * @type: button type (%EV_KEY, %EV_SW) | ||
190 | * | ||
191 | * This function parses stringified bitmap from @buf and disables/enables | ||
192 | * GPIO buttons accordinly. Returns 0 on success and negative error | ||
193 | * on failure. | ||
194 | */ | ||
195 | static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, | ||
196 | const char *buf, unsigned int type) | ||
197 | { | ||
198 | int n_events = get_n_events_by_type(type); | ||
199 | unsigned long *bits; | ||
200 | ssize_t error; | ||
201 | int i; | ||
202 | |||
203 | bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); | ||
204 | if (!bits) | ||
205 | return -ENOMEM; | ||
206 | |||
207 | error = bitmap_parselist(buf, bits, n_events); | ||
208 | if (error) | ||
209 | goto out; | ||
210 | |||
211 | /* First validate */ | ||
212 | for (i = 0; i < ddata->n_buttons; i++) { | ||
213 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
214 | |||
215 | if (bdata->button->type != type) | ||
216 | continue; | ||
217 | |||
218 | if (test_bit(bdata->button->code, bits) && | ||
219 | !bdata->button->can_disable) { | ||
220 | error = -EINVAL; | ||
221 | goto out; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | mutex_lock(&ddata->disable_lock); | ||
226 | |||
227 | for (i = 0; i < ddata->n_buttons; i++) { | ||
228 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
229 | |||
230 | if (bdata->button->type != type) | ||
231 | continue; | ||
232 | |||
233 | if (test_bit(bdata->button->code, bits)) | ||
234 | gpio_keys_disable_button(bdata); | ||
235 | else | ||
236 | gpio_keys_enable_button(bdata); | ||
237 | } | ||
238 | |||
239 | mutex_unlock(&ddata->disable_lock); | ||
240 | |||
241 | out: | ||
242 | kfree(bits); | ||
243 | return error; | ||
244 | } | ||
245 | |||
246 | #define ATTR_SHOW_FN(name, type, only_disabled) \ | ||
247 | static ssize_t gpio_keys_show_##name(struct device *dev, \ | ||
248 | struct device_attribute *attr, \ | ||
249 | char *buf) \ | ||
250 | { \ | ||
251 | struct platform_device *pdev = to_platform_device(dev); \ | ||
252 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ | ||
253 | \ | ||
254 | return gpio_keys_attr_show_helper(ddata, buf, \ | ||
255 | type, only_disabled); \ | ||
256 | } | ||
257 | |||
258 | ATTR_SHOW_FN(keys, EV_KEY, false); | ||
259 | ATTR_SHOW_FN(switches, EV_SW, false); | ||
260 | ATTR_SHOW_FN(disabled_keys, EV_KEY, true); | ||
261 | ATTR_SHOW_FN(disabled_switches, EV_SW, true); | ||
262 | |||
263 | /* | ||
264 | * ATTRIBUTES: | ||
265 | * | ||
266 | * /sys/devices/platform/gpio-keys/keys [ro] | ||
267 | * /sys/devices/platform/gpio-keys/switches [ro] | ||
268 | */ | ||
269 | static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL); | ||
270 | static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL); | ||
271 | |||
272 | #define ATTR_STORE_FN(name, type) \ | ||
273 | static ssize_t gpio_keys_store_##name(struct device *dev, \ | ||
274 | struct device_attribute *attr, \ | ||
275 | const char *buf, \ | ||
276 | size_t count) \ | ||
277 | { \ | ||
278 | struct platform_device *pdev = to_platform_device(dev); \ | ||
279 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ | ||
280 | ssize_t error; \ | ||
281 | \ | ||
282 | error = gpio_keys_attr_store_helper(ddata, buf, type); \ | ||
283 | if (error) \ | ||
284 | return error; \ | ||
285 | \ | ||
286 | return count; \ | ||
287 | } | ||
288 | |||
289 | ATTR_STORE_FN(disabled_keys, EV_KEY); | ||
290 | ATTR_STORE_FN(disabled_switches, EV_SW); | ||
291 | |||
292 | /* | ||
293 | * ATTRIBUTES: | ||
294 | * | ||
295 | * /sys/devices/platform/gpio-keys/disabled_keys [rw] | ||
296 | * /sys/devices/platform/gpio-keys/disables_switches [rw] | ||
297 | */ | ||
298 | static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO, | ||
299 | gpio_keys_show_disabled_keys, | ||
300 | gpio_keys_store_disabled_keys); | ||
301 | static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO, | ||
302 | gpio_keys_show_disabled_switches, | ||
303 | gpio_keys_store_disabled_switches); | ||
304 | |||
305 | static struct attribute *gpio_keys_attrs[] = { | ||
306 | &dev_attr_keys.attr, | ||
307 | &dev_attr_switches.attr, | ||
308 | &dev_attr_disabled_keys.attr, | ||
309 | &dev_attr_disabled_switches.attr, | ||
310 | NULL, | ||
311 | }; | ||
312 | |||
313 | static struct attribute_group gpio_keys_attr_group = { | ||
314 | .attrs = gpio_keys_attrs, | ||
315 | }; | ||
316 | |||
317 | static void gpio_keys_report_event(struct gpio_button_data *bdata) | ||
42 | { | 318 | { |
43 | struct gpio_button_data *bdata = | ||
44 | container_of(work, struct gpio_button_data, work); | ||
45 | struct gpio_keys_button *button = bdata->button; | 319 | struct gpio_keys_button *button = bdata->button; |
46 | struct input_dev *input = bdata->input; | 320 | struct input_dev *input = bdata->input; |
47 | unsigned int type = button->type ?: EV_KEY; | 321 | unsigned int type = button->type ?: EV_KEY; |
@@ -51,6 +325,14 @@ static void gpio_keys_report_event(struct work_struct *work) | |||
51 | input_sync(input); | 325 | input_sync(input); |
52 | } | 326 | } |
53 | 327 | ||
328 | static void gpio_keys_work_func(struct work_struct *work) | ||
329 | { | ||
330 | struct gpio_button_data *bdata = | ||
331 | container_of(work, struct gpio_button_data, work); | ||
332 | |||
333 | gpio_keys_report_event(bdata); | ||
334 | } | ||
335 | |||
54 | static void gpio_keys_timer(unsigned long _data) | 336 | static void gpio_keys_timer(unsigned long _data) |
55 | { | 337 | { |
56 | struct gpio_button_data *data = (struct gpio_button_data *)_data; | 338 | struct gpio_button_data *data = (struct gpio_button_data *)_data; |
@@ -74,10 +356,69 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
74 | return IRQ_HANDLED; | 356 | return IRQ_HANDLED; |
75 | } | 357 | } |
76 | 358 | ||
359 | static int __devinit gpio_keys_setup_key(struct platform_device *pdev, | ||
360 | struct gpio_button_data *bdata, | ||
361 | struct gpio_keys_button *button) | ||
362 | { | ||
363 | char *desc = button->desc ? button->desc : "gpio_keys"; | ||
364 | struct device *dev = &pdev->dev; | ||
365 | unsigned long irqflags; | ||
366 | int irq, error; | ||
367 | |||
368 | setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); | ||
369 | INIT_WORK(&bdata->work, gpio_keys_work_func); | ||
370 | |||
371 | error = gpio_request(button->gpio, desc); | ||
372 | if (error < 0) { | ||
373 | dev_err(dev, "failed to request GPIO %d, error %d\n", | ||
374 | button->gpio, error); | ||
375 | goto fail2; | ||
376 | } | ||
377 | |||
378 | error = gpio_direction_input(button->gpio); | ||
379 | if (error < 0) { | ||
380 | dev_err(dev, "failed to configure" | ||
381 | " direction for GPIO %d, error %d\n", | ||
382 | button->gpio, error); | ||
383 | goto fail3; | ||
384 | } | ||
385 | |||
386 | irq = gpio_to_irq(button->gpio); | ||
387 | if (irq < 0) { | ||
388 | error = irq; | ||
389 | dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", | ||
390 | button->gpio, error); | ||
391 | goto fail3; | ||
392 | } | ||
393 | |||
394 | irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; | ||
395 | /* | ||
396 | * If platform has specified that the button can be disabled, | ||
397 | * we don't want it to share the interrupt line. | ||
398 | */ | ||
399 | if (!button->can_disable) | ||
400 | irqflags |= IRQF_SHARED; | ||
401 | |||
402 | error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); | ||
403 | if (error) { | ||
404 | dev_err(dev, "Unable to claim irq %d; error %d\n", | ||
405 | irq, error); | ||
406 | goto fail3; | ||
407 | } | ||
408 | |||
409 | return 0; | ||
410 | |||
411 | fail3: | ||
412 | gpio_free(button->gpio); | ||
413 | fail2: | ||
414 | return error; | ||
415 | } | ||
416 | |||
77 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 417 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
78 | { | 418 | { |
79 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 419 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
80 | struct gpio_keys_drvdata *ddata; | 420 | struct gpio_keys_drvdata *ddata; |
421 | struct device *dev = &pdev->dev; | ||
81 | struct input_dev *input; | 422 | struct input_dev *input; |
82 | int i, error; | 423 | int i, error; |
83 | int wakeup = 0; | 424 | int wakeup = 0; |
@@ -87,10 +428,15 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
87 | GFP_KERNEL); | 428 | GFP_KERNEL); |
88 | input = input_allocate_device(); | 429 | input = input_allocate_device(); |
89 | if (!ddata || !input) { | 430 | if (!ddata || !input) { |
431 | dev_err(dev, "failed to allocate state\n"); | ||
90 | error = -ENOMEM; | 432 | error = -ENOMEM; |
91 | goto fail1; | 433 | goto fail1; |
92 | } | 434 | } |
93 | 435 | ||
436 | ddata->input = input; | ||
437 | ddata->n_buttons = pdata->nbuttons; | ||
438 | mutex_init(&ddata->disable_lock); | ||
439 | |||
94 | platform_set_drvdata(pdev, ddata); | 440 | platform_set_drvdata(pdev, ddata); |
95 | 441 | ||
96 | input->name = pdev->name; | 442 | input->name = pdev->name; |
@@ -106,57 +452,17 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
106 | if (pdata->rep) | 452 | if (pdata->rep) |
107 | __set_bit(EV_REP, input->evbit); | 453 | __set_bit(EV_REP, input->evbit); |
108 | 454 | ||
109 | ddata->input = input; | ||
110 | |||
111 | for (i = 0; i < pdata->nbuttons; i++) { | 455 | for (i = 0; i < pdata->nbuttons; i++) { |
112 | struct gpio_keys_button *button = &pdata->buttons[i]; | 456 | struct gpio_keys_button *button = &pdata->buttons[i]; |
113 | struct gpio_button_data *bdata = &ddata->data[i]; | 457 | struct gpio_button_data *bdata = &ddata->data[i]; |
114 | int irq; | ||
115 | unsigned int type = button->type ?: EV_KEY; | 458 | unsigned int type = button->type ?: EV_KEY; |
116 | 459 | ||
117 | bdata->input = input; | 460 | bdata->input = input; |
118 | bdata->button = button; | 461 | bdata->button = button; |
119 | setup_timer(&bdata->timer, | ||
120 | gpio_keys_timer, (unsigned long)bdata); | ||
121 | INIT_WORK(&bdata->work, gpio_keys_report_event); | ||
122 | |||
123 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); | ||
124 | if (error < 0) { | ||
125 | pr_err("gpio-keys: failed to request GPIO %d," | ||
126 | " error %d\n", button->gpio, error); | ||
127 | goto fail2; | ||
128 | } | ||
129 | 462 | ||
130 | error = gpio_direction_input(button->gpio); | 463 | error = gpio_keys_setup_key(pdev, bdata, button); |
131 | if (error < 0) { | 464 | if (error) |
132 | pr_err("gpio-keys: failed to configure input" | ||
133 | " direction for GPIO %d, error %d\n", | ||
134 | button->gpio, error); | ||
135 | gpio_free(button->gpio); | ||
136 | goto fail2; | 465 | goto fail2; |
137 | } | ||
138 | |||
139 | irq = gpio_to_irq(button->gpio); | ||
140 | if (irq < 0) { | ||
141 | error = irq; | ||
142 | pr_err("gpio-keys: Unable to get irq number" | ||
143 | " for GPIO %d, error %d\n", | ||
144 | button->gpio, error); | ||
145 | gpio_free(button->gpio); | ||
146 | goto fail2; | ||
147 | } | ||
148 | |||
149 | error = request_irq(irq, gpio_keys_isr, | ||
150 | IRQF_SHARED | | ||
151 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
152 | button->desc ? button->desc : "gpio_keys", | ||
153 | bdata); | ||
154 | if (error) { | ||
155 | pr_err("gpio-keys: Unable to claim irq %d; error %d\n", | ||
156 | irq, error); | ||
157 | gpio_free(button->gpio); | ||
158 | goto fail2; | ||
159 | } | ||
160 | 466 | ||
161 | if (button->wakeup) | 467 | if (button->wakeup) |
162 | wakeup = 1; | 468 | wakeup = 1; |
@@ -164,17 +470,31 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
164 | input_set_capability(input, type, button->code); | 470 | input_set_capability(input, type, button->code); |
165 | } | 471 | } |
166 | 472 | ||
167 | error = input_register_device(input); | 473 | error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); |
168 | if (error) { | 474 | if (error) { |
169 | pr_err("gpio-keys: Unable to register input device, " | 475 | dev_err(dev, "Unable to export keys/switches, error: %d\n", |
170 | "error: %d\n", error); | 476 | error); |
171 | goto fail2; | 477 | goto fail2; |
172 | } | 478 | } |
173 | 479 | ||
480 | error = input_register_device(input); | ||
481 | if (error) { | ||
482 | dev_err(dev, "Unable to register input device, error: %d\n", | ||
483 | error); | ||
484 | goto fail3; | ||
485 | } | ||
486 | |||
487 | /* get current state of buttons */ | ||
488 | for (i = 0; i < pdata->nbuttons; i++) | ||
489 | gpio_keys_report_event(&ddata->data[i]); | ||
490 | input_sync(input); | ||
491 | |||
174 | device_init_wakeup(&pdev->dev, wakeup); | 492 | device_init_wakeup(&pdev->dev, wakeup); |
175 | 493 | ||
176 | return 0; | 494 | return 0; |
177 | 495 | ||
496 | fail3: | ||
497 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | ||
178 | fail2: | 498 | fail2: |
179 | while (--i >= 0) { | 499 | while (--i >= 0) { |
180 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | 500 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); |
@@ -199,6 +519,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
199 | struct input_dev *input = ddata->input; | 519 | struct input_dev *input = ddata->input; |
200 | int i; | 520 | int i; |
201 | 521 | ||
522 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | ||
523 | |||
202 | device_init_wakeup(&pdev->dev, 0); | 524 | device_init_wakeup(&pdev->dev, 0); |
203 | 525 | ||
204 | for (i = 0; i < pdata->nbuttons; i++) { | 526 | for (i = 0; i < pdata->nbuttons; i++) { |
@@ -239,18 +561,21 @@ static int gpio_keys_suspend(struct device *dev) | |||
239 | static int gpio_keys_resume(struct device *dev) | 561 | static int gpio_keys_resume(struct device *dev) |
240 | { | 562 | { |
241 | struct platform_device *pdev = to_platform_device(dev); | 563 | struct platform_device *pdev = to_platform_device(dev); |
564 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); | ||
242 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 565 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
243 | int i; | 566 | int i; |
244 | 567 | ||
245 | if (device_may_wakeup(&pdev->dev)) { | 568 | for (i = 0; i < pdata->nbuttons; i++) { |
246 | for (i = 0; i < pdata->nbuttons; i++) { | 569 | |
247 | struct gpio_keys_button *button = &pdata->buttons[i]; | 570 | struct gpio_keys_button *button = &pdata->buttons[i]; |
248 | if (button->wakeup) { | 571 | if (button->wakeup && device_may_wakeup(&pdev->dev)) { |
249 | int irq = gpio_to_irq(button->gpio); | 572 | int irq = gpio_to_irq(button->gpio); |
250 | disable_irq_wake(irq); | 573 | disable_irq_wake(irq); |
251 | } | ||
252 | } | 574 | } |
575 | |||
576 | gpio_keys_report_event(&ddata->data[i]); | ||
253 | } | 577 | } |
578 | input_sync(ddata->input); | ||
254 | 579 | ||
255 | return 0; | 580 | return 0; |
256 | } | 581 | } |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c new file mode 100644 index 000000000000..d92c15c39e68 --- /dev/null +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -0,0 +1,595 @@ | |||
1 | /* | ||
2 | * Driver for the IMX keypad port. | ||
3 | * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * <<Power management needs to be implemented>>. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input/matrix_keypad.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/jiffies.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/timer.h> | ||
26 | |||
27 | /* | ||
28 | * Keypad Controller registers (halfword) | ||
29 | */ | ||
30 | #define KPCR 0x00 /* Keypad Control Register */ | ||
31 | |||
32 | #define KPSR 0x02 /* Keypad Status Register */ | ||
33 | #define KBD_STAT_KPKD (0x1 << 0) /* Key Press Interrupt Status bit (w1c) */ | ||
34 | #define KBD_STAT_KPKR (0x1 << 1) /* Key Release Interrupt Status bit (w1c) */ | ||
35 | #define KBD_STAT_KDSC (0x1 << 2) /* Key Depress Synch Chain Status bit (w1c)*/ | ||
36 | #define KBD_STAT_KRSS (0x1 << 3) /* Key Release Synch Status bit (w1c)*/ | ||
37 | #define KBD_STAT_KDIE (0x1 << 8) /* Key Depress Interrupt Enable Status bit */ | ||
38 | #define KBD_STAT_KRIE (0x1 << 9) /* Key Release Interrupt Enable */ | ||
39 | #define KBD_STAT_KPPEN (0x1 << 10) /* Keypad Clock Enable */ | ||
40 | |||
41 | #define KDDR 0x04 /* Keypad Data Direction Register */ | ||
42 | #define KPDR 0x06 /* Keypad Data Register */ | ||
43 | |||
44 | #define MAX_MATRIX_KEY_ROWS 8 | ||
45 | #define MAX_MATRIX_KEY_COLS 8 | ||
46 | #define MATRIX_ROW_SHIFT 3 | ||
47 | |||
48 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) | ||
49 | |||
50 | struct imx_keypad { | ||
51 | |||
52 | struct clk *clk; | ||
53 | struct input_dev *input_dev; | ||
54 | void __iomem *mmio_base; | ||
55 | |||
56 | int irq; | ||
57 | struct timer_list check_matrix_timer; | ||
58 | |||
59 | /* | ||
60 | * The matrix is stable only if no changes are detected after | ||
61 | * IMX_KEYPAD_SCANS_FOR_STABILITY scans | ||
62 | */ | ||
63 | #define IMX_KEYPAD_SCANS_FOR_STABILITY 3 | ||
64 | int stable_count; | ||
65 | |||
66 | bool enabled; | ||
67 | |||
68 | /* Masks for enabled rows/cols */ | ||
69 | unsigned short rows_en_mask; | ||
70 | unsigned short cols_en_mask; | ||
71 | |||
72 | unsigned short keycodes[MAX_MATRIX_KEY_NUM]; | ||
73 | |||
74 | /* | ||
75 | * Matrix states: | ||
76 | * -stable: achieved after a complete debounce process. | ||
77 | * -unstable: used in the debouncing process. | ||
78 | */ | ||
79 | unsigned short matrix_stable_state[MAX_MATRIX_KEY_COLS]; | ||
80 | unsigned short matrix_unstable_state[MAX_MATRIX_KEY_COLS]; | ||
81 | }; | ||
82 | |||
83 | /* Scan the matrix and return the new state in *matrix_volatile_state. */ | ||
84 | static void imx_keypad_scan_matrix(struct imx_keypad *keypad, | ||
85 | unsigned short *matrix_volatile_state) | ||
86 | { | ||
87 | int col; | ||
88 | unsigned short reg_val; | ||
89 | |||
90 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
91 | if ((keypad->cols_en_mask & (1 << col)) == 0) | ||
92 | continue; | ||
93 | /* | ||
94 | * Discharge keypad capacitance: | ||
95 | * 2. write 1s on column data. | ||
96 | * 3. configure columns as totem-pole to discharge capacitance. | ||
97 | * 4. configure columns as open-drain. | ||
98 | */ | ||
99 | reg_val = readw(keypad->mmio_base + KPDR); | ||
100 | reg_val |= 0xff00; | ||
101 | writew(reg_val, keypad->mmio_base + KPDR); | ||
102 | |||
103 | reg_val = readw(keypad->mmio_base + KPCR); | ||
104 | reg_val &= ~((keypad->cols_en_mask & 0xff) << 8); | ||
105 | writew(reg_val, keypad->mmio_base + KPCR); | ||
106 | |||
107 | udelay(2); | ||
108 | |||
109 | reg_val = readw(keypad->mmio_base + KPCR); | ||
110 | reg_val |= (keypad->cols_en_mask & 0xff) << 8; | ||
111 | writew(reg_val, keypad->mmio_base + KPCR); | ||
112 | |||
113 | /* | ||
114 | * 5. Write a single column to 0, others to 1. | ||
115 | * 6. Sample row inputs and save data. | ||
116 | * 7. Repeat steps 2 - 6 for remaining columns. | ||
117 | */ | ||
118 | reg_val = readw(keypad->mmio_base + KPDR); | ||
119 | reg_val &= ~(1 << (8 + col)); | ||
120 | writew(reg_val, keypad->mmio_base + KPDR); | ||
121 | |||
122 | /* | ||
123 | * Delay added to avoid propagating the 0 from column to row | ||
124 | * when scanning. | ||
125 | */ | ||
126 | udelay(5); | ||
127 | |||
128 | /* | ||
129 | * 1s in matrix_volatile_state[col] means key pressures | ||
130 | * throw data from non enabled rows. | ||
131 | */ | ||
132 | reg_val = readw(keypad->mmio_base + KPDR); | ||
133 | matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Return in standby mode: | ||
138 | * 9. write 0s to columns | ||
139 | */ | ||
140 | reg_val = readw(keypad->mmio_base + KPDR); | ||
141 | reg_val &= 0x00ff; | ||
142 | writew(reg_val, keypad->mmio_base + KPDR); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Compare the new matrix state (volatile) with the stable one stored in | ||
147 | * keypad->matrix_stable_state and fire events if changes are detected. | ||
148 | */ | ||
149 | static void imx_keypad_fire_events(struct imx_keypad *keypad, | ||
150 | unsigned short *matrix_volatile_state) | ||
151 | { | ||
152 | struct input_dev *input_dev = keypad->input_dev; | ||
153 | int row, col; | ||
154 | |||
155 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
156 | unsigned short bits_changed; | ||
157 | int code; | ||
158 | |||
159 | if ((keypad->cols_en_mask & (1 << col)) == 0) | ||
160 | continue; /* Column is not enabled */ | ||
161 | |||
162 | bits_changed = keypad->matrix_stable_state[col] ^ | ||
163 | matrix_volatile_state[col]; | ||
164 | |||
165 | if (bits_changed == 0) | ||
166 | continue; /* Column does not contain changes */ | ||
167 | |||
168 | for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) { | ||
169 | if ((keypad->rows_en_mask & (1 << row)) == 0) | ||
170 | continue; /* Row is not enabled */ | ||
171 | if ((bits_changed & (1 << row)) == 0) | ||
172 | continue; /* Row does not contain changes */ | ||
173 | |||
174 | code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); | ||
175 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
176 | input_report_key(input_dev, keypad->keycodes[code], | ||
177 | matrix_volatile_state[col] & (1 << row)); | ||
178 | dev_dbg(&input_dev->dev, "Event code: %d, val: %d", | ||
179 | keypad->keycodes[code], | ||
180 | matrix_volatile_state[col] & (1 << row)); | ||
181 | } | ||
182 | } | ||
183 | input_sync(input_dev); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * imx_keypad_check_for_events is the timer handler. | ||
188 | */ | ||
189 | static void imx_keypad_check_for_events(unsigned long data) | ||
190 | { | ||
191 | struct imx_keypad *keypad = (struct imx_keypad *) data; | ||
192 | unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS]; | ||
193 | unsigned short reg_val; | ||
194 | bool state_changed, is_zero_matrix; | ||
195 | int i; | ||
196 | |||
197 | memset(matrix_volatile_state, 0, sizeof(matrix_volatile_state)); | ||
198 | |||
199 | imx_keypad_scan_matrix(keypad, matrix_volatile_state); | ||
200 | |||
201 | state_changed = false; | ||
202 | for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { | ||
203 | if ((keypad->cols_en_mask & (1 << i)) == 0) | ||
204 | continue; | ||
205 | |||
206 | if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) { | ||
207 | state_changed = true; | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * If the matrix state is changed from the previous scan | ||
214 | * (Re)Begin the debouncing process, saving the new state in | ||
215 | * keypad->matrix_unstable_state. | ||
216 | * else | ||
217 | * Increase the count of number of scans with a stable state. | ||
218 | */ | ||
219 | if (state_changed) { | ||
220 | memcpy(keypad->matrix_unstable_state, matrix_volatile_state, | ||
221 | sizeof(matrix_volatile_state)); | ||
222 | keypad->stable_count = 0; | ||
223 | } else | ||
224 | keypad->stable_count++; | ||
225 | |||
226 | /* | ||
227 | * If the matrix is not as stable as we want reschedule scan | ||
228 | * in the near future. | ||
229 | */ | ||
230 | if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) { | ||
231 | mod_timer(&keypad->check_matrix_timer, | ||
232 | jiffies + msecs_to_jiffies(10)); | ||
233 | return; | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | * If the matrix state is stable, fire the events and save the new | ||
238 | * stable state. Note, if the matrix is kept stable for longer | ||
239 | * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all | ||
240 | * events have already been generated. | ||
241 | */ | ||
242 | if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) { | ||
243 | imx_keypad_fire_events(keypad, matrix_volatile_state); | ||
244 | |||
245 | memcpy(keypad->matrix_stable_state, matrix_volatile_state, | ||
246 | sizeof(matrix_volatile_state)); | ||
247 | } | ||
248 | |||
249 | is_zero_matrix = true; | ||
250 | for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { | ||
251 | if (matrix_volatile_state[i] != 0) { | ||
252 | is_zero_matrix = false; | ||
253 | break; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | if (is_zero_matrix) { | ||
259 | /* | ||
260 | * All keys have been released. Enable only the KDI | ||
261 | * interrupt for future key presses (clear the KDI | ||
262 | * status bit and its sync chain before that). | ||
263 | */ | ||
264 | reg_val = readw(keypad->mmio_base + KPSR); | ||
265 | reg_val |= KBD_STAT_KPKD | KBD_STAT_KDSC; | ||
266 | writew(reg_val, keypad->mmio_base + KPSR); | ||
267 | |||
268 | reg_val = readw(keypad->mmio_base + KPSR); | ||
269 | reg_val |= KBD_STAT_KDIE; | ||
270 | reg_val &= ~KBD_STAT_KRIE; | ||
271 | writew(reg_val, keypad->mmio_base + KPSR); | ||
272 | } else { | ||
273 | /* | ||
274 | * Some keys are still pressed. Schedule a rescan in | ||
275 | * attempt to detect multiple key presses and enable | ||
276 | * the KRI interrupt to react quickly to key release | ||
277 | * event. | ||
278 | */ | ||
279 | mod_timer(&keypad->check_matrix_timer, | ||
280 | jiffies + msecs_to_jiffies(60)); | ||
281 | |||
282 | reg_val = readw(keypad->mmio_base + KPSR); | ||
283 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS; | ||
284 | writew(reg_val, keypad->mmio_base + KPSR); | ||
285 | |||
286 | reg_val = readw(keypad->mmio_base + KPSR); | ||
287 | reg_val |= KBD_STAT_KRIE; | ||
288 | reg_val &= ~KBD_STAT_KDIE; | ||
289 | writew(reg_val, keypad->mmio_base + KPSR); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id) | ||
294 | { | ||
295 | struct imx_keypad *keypad = dev_id; | ||
296 | unsigned short reg_val; | ||
297 | |||
298 | reg_val = readw(keypad->mmio_base + KPSR); | ||
299 | |||
300 | /* Disable both interrupt types */ | ||
301 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | ||
302 | /* Clear interrupts status bits */ | ||
303 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
304 | writew(reg_val, keypad->mmio_base + KPSR); | ||
305 | |||
306 | if (keypad->enabled) { | ||
307 | /* The matrix is supposed to be changed */ | ||
308 | keypad->stable_count = 0; | ||
309 | |||
310 | /* Schedule the scanning procedure near in the future */ | ||
311 | mod_timer(&keypad->check_matrix_timer, | ||
312 | jiffies + msecs_to_jiffies(2)); | ||
313 | } | ||
314 | |||
315 | return IRQ_HANDLED; | ||
316 | } | ||
317 | |||
318 | static void imx_keypad_config(struct imx_keypad *keypad) | ||
319 | { | ||
320 | unsigned short reg_val; | ||
321 | |||
322 | /* | ||
323 | * Include enabled rows in interrupt generation (KPCR[7:0]) | ||
324 | * Configure keypad columns as open-drain (KPCR[15:8]) | ||
325 | */ | ||
326 | reg_val = readw(keypad->mmio_base + KPCR); | ||
327 | reg_val |= keypad->rows_en_mask & 0xff; /* rows */ | ||
328 | reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */ | ||
329 | writew(reg_val, keypad->mmio_base + KPCR); | ||
330 | |||
331 | /* Write 0's to KPDR[15:8] (Colums) */ | ||
332 | reg_val = readw(keypad->mmio_base + KPDR); | ||
333 | reg_val &= 0x00ff; | ||
334 | writew(reg_val, keypad->mmio_base + KPDR); | ||
335 | |||
336 | /* Configure columns as output, rows as input (KDDR[15:0]) */ | ||
337 | writew(0xff00, keypad->mmio_base + KDDR); | ||
338 | |||
339 | /* | ||
340 | * Clear Key Depress and Key Release status bit. | ||
341 | * Clear both synchronizer chain. | ||
342 | */ | ||
343 | reg_val = readw(keypad->mmio_base + KPSR); | ||
344 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD | | ||
345 | KBD_STAT_KDSC | KBD_STAT_KRSS; | ||
346 | writew(reg_val, keypad->mmio_base + KPSR); | ||
347 | |||
348 | /* Enable KDI and disable KRI (avoid false release events). */ | ||
349 | reg_val |= KBD_STAT_KDIE; | ||
350 | reg_val &= ~KBD_STAT_KRIE; | ||
351 | writew(reg_val, keypad->mmio_base + KPSR); | ||
352 | } | ||
353 | |||
354 | static void imx_keypad_inhibit(struct imx_keypad *keypad) | ||
355 | { | ||
356 | unsigned short reg_val; | ||
357 | |||
358 | /* Inhibit KDI and KRI interrupts. */ | ||
359 | reg_val = readw(keypad->mmio_base + KPSR); | ||
360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | ||
361 | writew(reg_val, keypad->mmio_base + KPSR); | ||
362 | |||
363 | /* Colums as open drain and disable all rows */ | ||
364 | writew(0xff00, keypad->mmio_base + KPCR); | ||
365 | } | ||
366 | |||
367 | static void imx_keypad_close(struct input_dev *dev) | ||
368 | { | ||
369 | struct imx_keypad *keypad = input_get_drvdata(dev); | ||
370 | |||
371 | dev_dbg(&dev->dev, ">%s\n", __func__); | ||
372 | |||
373 | /* Mark keypad as being inactive */ | ||
374 | keypad->enabled = false; | ||
375 | synchronize_irq(keypad->irq); | ||
376 | del_timer_sync(&keypad->check_matrix_timer); | ||
377 | |||
378 | imx_keypad_inhibit(keypad); | ||
379 | |||
380 | /* Disable clock unit */ | ||
381 | clk_disable(keypad->clk); | ||
382 | } | ||
383 | |||
384 | static int imx_keypad_open(struct input_dev *dev) | ||
385 | { | ||
386 | struct imx_keypad *keypad = input_get_drvdata(dev); | ||
387 | |||
388 | dev_dbg(&dev->dev, ">%s\n", __func__); | ||
389 | |||
390 | /* We became active from now */ | ||
391 | keypad->enabled = true; | ||
392 | |||
393 | /* Enable the kpp clock */ | ||
394 | clk_enable(keypad->clk); | ||
395 | imx_keypad_config(keypad); | ||
396 | |||
397 | /* Sanity control, not all the rows must be actived now. */ | ||
398 | if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) { | ||
399 | dev_err(&dev->dev, | ||
400 | "too many keys pressed, control pins initialisation\n"); | ||
401 | goto open_err; | ||
402 | } | ||
403 | |||
404 | return 0; | ||
405 | |||
406 | open_err: | ||
407 | imx_keypad_close(dev); | ||
408 | return -EIO; | ||
409 | } | ||
410 | |||
411 | static int __devinit imx_keypad_probe(struct platform_device *pdev) | ||
412 | { | ||
413 | const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; | ||
414 | struct imx_keypad *keypad; | ||
415 | struct input_dev *input_dev; | ||
416 | struct resource *res; | ||
417 | int irq, error, i; | ||
418 | |||
419 | if (keymap_data == NULL) { | ||
420 | dev_err(&pdev->dev, "no keymap defined\n"); | ||
421 | return -EINVAL; | ||
422 | } | ||
423 | |||
424 | irq = platform_get_irq(pdev, 0); | ||
425 | if (irq < 0) { | ||
426 | dev_err(&pdev->dev, "no irq defined in platform data\n"); | ||
427 | return -EINVAL; | ||
428 | } | ||
429 | |||
430 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
431 | if (res == NULL) { | ||
432 | dev_err(&pdev->dev, "no I/O memory defined in platform data\n"); | ||
433 | return -EINVAL; | ||
434 | } | ||
435 | |||
436 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
437 | if (res == NULL) { | ||
438 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
439 | return -EBUSY; | ||
440 | } | ||
441 | |||
442 | input_dev = input_allocate_device(); | ||
443 | if (!input_dev) { | ||
444 | dev_err(&pdev->dev, "failed to allocate the input device\n"); | ||
445 | error = -ENOMEM; | ||
446 | goto failed_rel_mem; | ||
447 | } | ||
448 | |||
449 | keypad = kzalloc(sizeof(struct imx_keypad), GFP_KERNEL); | ||
450 | if (!keypad) { | ||
451 | dev_err(&pdev->dev, "not enough memory for driver data\n"); | ||
452 | error = -ENOMEM; | ||
453 | goto failed_free_input; | ||
454 | } | ||
455 | |||
456 | keypad->input_dev = input_dev; | ||
457 | keypad->irq = irq; | ||
458 | keypad->stable_count = 0; | ||
459 | |||
460 | setup_timer(&keypad->check_matrix_timer, | ||
461 | imx_keypad_check_for_events, (unsigned long) keypad); | ||
462 | |||
463 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | ||
464 | if (keypad->mmio_base == NULL) { | ||
465 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
466 | error = -ENOMEM; | ||
467 | goto failed_free_priv; | ||
468 | } | ||
469 | |||
470 | keypad->clk = clk_get(&pdev->dev, "kpp"); | ||
471 | if (IS_ERR(keypad->clk)) { | ||
472 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | ||
473 | error = PTR_ERR(keypad->clk); | ||
474 | goto failed_unmap; | ||
475 | } | ||
476 | |||
477 | /* Search for rows and cols enabled */ | ||
478 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
479 | keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]); | ||
480 | keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]); | ||
481 | } | ||
482 | |||
483 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || | ||
484 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { | ||
485 | dev_err(&pdev->dev, | ||
486 | "invalid key data (too many rows or colums)\n"); | ||
487 | error = -EINVAL; | ||
488 | goto failed_clock_put; | ||
489 | } | ||
490 | dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); | ||
491 | dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); | ||
492 | |||
493 | /* Init the Input device */ | ||
494 | input_dev->name = pdev->name; | ||
495 | input_dev->id.bustype = BUS_HOST; | ||
496 | input_dev->dev.parent = &pdev->dev; | ||
497 | input_dev->open = imx_keypad_open; | ||
498 | input_dev->close = imx_keypad_close; | ||
499 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
500 | input_dev->keycode = keypad->keycodes; | ||
501 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
502 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
503 | |||
504 | matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, | ||
505 | keypad->keycodes, input_dev->keybit); | ||
506 | |||
507 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
508 | input_set_drvdata(input_dev, keypad); | ||
509 | |||
510 | /* Ensure that the keypad will stay dormant until opened */ | ||
511 | imx_keypad_inhibit(keypad); | ||
512 | |||
513 | error = request_irq(irq, imx_keypad_irq_handler, IRQF_DISABLED, | ||
514 | pdev->name, keypad); | ||
515 | if (error) { | ||
516 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
517 | goto failed_clock_put; | ||
518 | } | ||
519 | |||
520 | /* Register the input device */ | ||
521 | error = input_register_device(input_dev); | ||
522 | if (error) { | ||
523 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
524 | goto failed_free_irq; | ||
525 | } | ||
526 | |||
527 | platform_set_drvdata(pdev, keypad); | ||
528 | device_init_wakeup(&pdev->dev, 1); | ||
529 | |||
530 | return 0; | ||
531 | |||
532 | failed_free_irq: | ||
533 | free_irq(irq, pdev); | ||
534 | failed_clock_put: | ||
535 | clk_put(keypad->clk); | ||
536 | failed_unmap: | ||
537 | iounmap(keypad->mmio_base); | ||
538 | failed_free_priv: | ||
539 | kfree(keypad); | ||
540 | failed_free_input: | ||
541 | input_free_device(input_dev); | ||
542 | failed_rel_mem: | ||
543 | release_mem_region(res->start, resource_size(res)); | ||
544 | return error; | ||
545 | } | ||
546 | |||
547 | static int __devexit imx_keypad_remove(struct platform_device *pdev) | ||
548 | { | ||
549 | struct imx_keypad *keypad = platform_get_drvdata(pdev); | ||
550 | struct resource *res; | ||
551 | |||
552 | dev_dbg(&pdev->dev, ">%s\n", __func__); | ||
553 | |||
554 | platform_set_drvdata(pdev, NULL); | ||
555 | |||
556 | input_unregister_device(keypad->input_dev); | ||
557 | |||
558 | free_irq(keypad->irq, keypad); | ||
559 | clk_put(keypad->clk); | ||
560 | |||
561 | iounmap(keypad->mmio_base); | ||
562 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
563 | release_mem_region(res->start, resource_size(res)); | ||
564 | |||
565 | kfree(keypad); | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | static struct platform_driver imx_keypad_driver = { | ||
571 | .driver = { | ||
572 | .name = "imx-keypad", | ||
573 | .owner = THIS_MODULE, | ||
574 | }, | ||
575 | .probe = imx_keypad_probe, | ||
576 | .remove = __devexit_p(imx_keypad_remove), | ||
577 | }; | ||
578 | |||
579 | static int __init imx_keypad_init(void) | ||
580 | { | ||
581 | return platform_driver_register(&imx_keypad_driver); | ||
582 | } | ||
583 | |||
584 | static void __exit imx_keypad_exit(void) | ||
585 | { | ||
586 | platform_driver_unregister(&imx_keypad_driver); | ||
587 | } | ||
588 | |||
589 | module_init(imx_keypad_init); | ||
590 | module_exit(imx_keypad_exit); | ||
591 | |||
592 | MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); | ||
593 | MODULE_DESCRIPTION("IMX Keypad Port Driver"); | ||
594 | MODULE_LICENSE("GPL v2"); | ||
595 | MODULE_ALIAS("platform:imx-keypad"); | ||
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 781fc6102860..5fc976dbce0b 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | ||
27 | 28 | ||
28 | #include <asm/delay.h> | 29 | #include <asm/delay.h> |
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index 4e016d823069..2cd3e1d56ea4 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/slab.h> | ||
26 | 27 | ||
27 | #include <mach/jornada720.h> | 28 | #include <mach/jornada720.h> |
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index f9847e0fb553..fa9bb6d235e2 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -72,9 +72,9 @@ | |||
72 | 72 | ||
73 | #define DRIVER_DESC "LK keyboard driver" | 73 | #define DRIVER_DESC "LK keyboard driver" |
74 | 74 | ||
75 | MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); | 75 | MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); |
76 | MODULE_DESCRIPTION (DRIVER_DESC); | 76 | MODULE_DESCRIPTION(DRIVER_DESC); |
77 | MODULE_LICENSE ("GPL"); | 77 | MODULE_LICENSE("GPL"); |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * Known parameters: | 80 | * Known parameters: |
@@ -85,27 +85,27 @@ MODULE_LICENSE ("GPL"); | |||
85 | * Please notice that there's not yet an API to set these at runtime. | 85 | * Please notice that there's not yet an API to set these at runtime. |
86 | */ | 86 | */ |
87 | static int bell_volume = 100; /* % */ | 87 | static int bell_volume = 100; /* % */ |
88 | module_param (bell_volume, int, 0); | 88 | module_param(bell_volume, int, 0); |
89 | MODULE_PARM_DESC (bell_volume, "Bell volume (in %). default is 100%"); | 89 | MODULE_PARM_DESC(bell_volume, "Bell volume (in %). default is 100%"); |
90 | 90 | ||
91 | static int keyclick_volume = 100; /* % */ | 91 | static int keyclick_volume = 100; /* % */ |
92 | module_param (keyclick_volume, int, 0); | 92 | module_param(keyclick_volume, int, 0); |
93 | MODULE_PARM_DESC (keyclick_volume, "Keyclick volume (in %), default is 100%"); | 93 | MODULE_PARM_DESC(keyclick_volume, "Keyclick volume (in %), default is 100%"); |
94 | 94 | ||
95 | static int ctrlclick_volume = 100; /* % */ | 95 | static int ctrlclick_volume = 100; /* % */ |
96 | module_param (ctrlclick_volume, int, 0); | 96 | module_param(ctrlclick_volume, int, 0); |
97 | MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%"); | 97 | MODULE_PARM_DESC(ctrlclick_volume, "Ctrlclick volume (in %), default is 100%"); |
98 | 98 | ||
99 | static int lk201_compose_is_alt; | 99 | static int lk201_compose_is_alt; |
100 | module_param (lk201_compose_is_alt, int, 0); | 100 | module_param(lk201_compose_is_alt, int, 0); |
101 | MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | 101 | MODULE_PARM_DESC(lk201_compose_is_alt, |
102 | "will act as an Alt key"); | 102 | "If set non-zero, LK201' Compose key will act as an Alt key"); |
103 | 103 | ||
104 | 104 | ||
105 | 105 | ||
106 | #undef LKKBD_DEBUG | 106 | #undef LKKBD_DEBUG |
107 | #ifdef LKKBD_DEBUG | 107 | #ifdef LKKBD_DEBUG |
108 | #define DBG(x...) printk (x) | 108 | #define DBG(x...) printk(x) |
109 | #else | 109 | #else |
110 | #define DBG(x...) do {} while (0) | 110 | #define DBG(x...) do {} while (0) |
111 | #endif | 111 | #endif |
@@ -122,7 +122,7 @@ MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | |||
122 | #define LK_MODE_DOWN 0x80 | 122 | #define LK_MODE_DOWN 0x80 |
123 | #define LK_MODE_AUTODOWN 0x82 | 123 | #define LK_MODE_AUTODOWN 0x82 |
124 | #define LK_MODE_UPDOWN 0x86 | 124 | #define LK_MODE_UPDOWN 0x86 |
125 | #define LK_CMD_SET_MODE(mode,div) ((mode) | ((div) << 3)) | 125 | #define LK_CMD_SET_MODE(mode, div) ((mode) | ((div) << 3)) |
126 | 126 | ||
127 | /* Misc commands */ | 127 | /* Misc commands */ |
128 | #define LK_CMD_ENABLE_KEYCLICK 0x1b | 128 | #define LK_CMD_ENABLE_KEYCLICK 0x1b |
@@ -152,11 +152,8 @@ MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | |||
152 | 152 | ||
153 | #define LK_NUM_KEYCODES 256 | 153 | #define LK_NUM_KEYCODES 256 |
154 | #define LK_NUM_IGNORE_BYTES 6 | 154 | #define LK_NUM_IGNORE_BYTES 6 |
155 | typedef u_int16_t lk_keycode_t; | ||
156 | 155 | ||
157 | 156 | static unsigned short lkkbd_keycode[LK_NUM_KEYCODES] = { | |
158 | |||
159 | static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | ||
160 | [0x56] = KEY_F1, | 157 | [0x56] = KEY_F1, |
161 | [0x57] = KEY_F2, | 158 | [0x57] = KEY_F2, |
162 | [0x58] = KEY_F3, | 159 | [0x58] = KEY_F3, |
@@ -268,7 +265,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | |||
268 | }; | 265 | }; |
269 | 266 | ||
270 | #define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do { \ | 267 | #define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do { \ |
271 | if (test_bit (LED, (LK)->dev->led)) \ | 268 | if (test_bit(LED, (LK)->dev->led)) \ |
272 | VAR_ON |= BITS; \ | 269 | VAR_ON |= BITS; \ |
273 | else \ | 270 | else \ |
274 | VAR_OFF |= BITS; \ | 271 | VAR_OFF |= BITS; \ |
@@ -278,7 +275,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | |||
278 | * Per-keyboard data | 275 | * Per-keyboard data |
279 | */ | 276 | */ |
280 | struct lkkbd { | 277 | struct lkkbd { |
281 | lk_keycode_t keycode[LK_NUM_KEYCODES]; | 278 | unsigned short keycode[LK_NUM_KEYCODES]; |
282 | int ignore_bytes; | 279 | int ignore_bytes; |
283 | unsigned char id[LK_NUM_IGNORE_BYTES]; | 280 | unsigned char id[LK_NUM_IGNORE_BYTES]; |
284 | struct input_dev *dev; | 281 | struct input_dev *dev; |
@@ -301,26 +298,25 @@ static struct { | |||
301 | unsigned char *name; | 298 | unsigned char *name; |
302 | } lk_response[] = { | 299 | } lk_response[] = { |
303 | #define RESPONSE(x) { .value = (x), .name = #x, } | 300 | #define RESPONSE(x) { .value = (x), .name = #x, } |
304 | RESPONSE (LK_STUCK_KEY), | 301 | RESPONSE(LK_STUCK_KEY), |
305 | RESPONSE (LK_SELFTEST_FAILED), | 302 | RESPONSE(LK_SELFTEST_FAILED), |
306 | RESPONSE (LK_ALL_KEYS_UP), | 303 | RESPONSE(LK_ALL_KEYS_UP), |
307 | RESPONSE (LK_METRONOME), | 304 | RESPONSE(LK_METRONOME), |
308 | RESPONSE (LK_OUTPUT_ERROR), | 305 | RESPONSE(LK_OUTPUT_ERROR), |
309 | RESPONSE (LK_INPUT_ERROR), | 306 | RESPONSE(LK_INPUT_ERROR), |
310 | RESPONSE (LK_KBD_LOCKED), | 307 | RESPONSE(LK_KBD_LOCKED), |
311 | RESPONSE (LK_KBD_TEST_MODE_ACK), | 308 | RESPONSE(LK_KBD_TEST_MODE_ACK), |
312 | RESPONSE (LK_PREFIX_KEY_DOWN), | 309 | RESPONSE(LK_PREFIX_KEY_DOWN), |
313 | RESPONSE (LK_MODE_CHANGE_ACK), | 310 | RESPONSE(LK_MODE_CHANGE_ACK), |
314 | RESPONSE (LK_RESPONSE_RESERVED), | 311 | RESPONSE(LK_RESPONSE_RESERVED), |
315 | #undef RESPONSE | 312 | #undef RESPONSE |
316 | }; | 313 | }; |
317 | 314 | ||
318 | static unsigned char * | 315 | static unsigned char *response_name(unsigned char value) |
319 | response_name (unsigned char value) | ||
320 | { | 316 | { |
321 | int i; | 317 | int i; |
322 | 318 | ||
323 | for (i = 0; i < ARRAY_SIZE (lk_response); i++) | 319 | for (i = 0; i < ARRAY_SIZE(lk_response); i++) |
324 | if (lk_response[i].value == value) | 320 | if (lk_response[i].value == value) |
325 | return lk_response[i].name; | 321 | return lk_response[i].name; |
326 | 322 | ||
@@ -331,8 +327,7 @@ response_name (unsigned char value) | |||
331 | /* | 327 | /* |
332 | * Calculate volume parameter byte for a given volume. | 328 | * Calculate volume parameter byte for a given volume. |
333 | */ | 329 | */ |
334 | static unsigned char | 330 | static unsigned char volume_to_hw(int volume_percent) |
335 | volume_to_hw (int volume_percent) | ||
336 | { | 331 | { |
337 | unsigned char ret = 0; | 332 | unsigned char ret = 0; |
338 | 333 | ||
@@ -363,8 +358,7 @@ volume_to_hw (int volume_percent) | |||
363 | return ret; | 358 | return ret; |
364 | } | 359 | } |
365 | 360 | ||
366 | static void | 361 | static void lkkbd_detection_done(struct lkkbd *lk) |
367 | lkkbd_detection_done (struct lkkbd *lk) | ||
368 | { | 362 | { |
369 | int i; | 363 | int i; |
370 | 364 | ||
@@ -377,190 +371,202 @@ lkkbd_detection_done (struct lkkbd *lk) | |||
377 | * Print keyboard name and modify Compose=Alt on user's request. | 371 | * Print keyboard name and modify Compose=Alt on user's request. |
378 | */ | 372 | */ |
379 | switch (lk->id[4]) { | 373 | switch (lk->id[4]) { |
380 | case 1: | 374 | case 1: |
381 | strlcpy (lk->name, "DEC LK201 keyboard", | 375 | strlcpy(lk->name, "DEC LK201 keyboard", sizeof(lk->name)); |
382 | sizeof (lk->name)); | 376 | |
383 | 377 | if (lk201_compose_is_alt) | |
384 | if (lk201_compose_is_alt) | 378 | lk->keycode[0xb1] = KEY_LEFTALT; |
385 | lk->keycode[0xb1] = KEY_LEFTALT; | 379 | break; |
386 | break; | 380 | |
387 | 381 | case 2: | |
388 | case 2: | 382 | strlcpy(lk->name, "DEC LK401 keyboard", sizeof(lk->name)); |
389 | strlcpy (lk->name, "DEC LK401 keyboard", | 383 | break; |
390 | sizeof (lk->name)); | 384 | |
391 | break; | 385 | default: |
392 | 386 | strlcpy(lk->name, "Unknown DEC keyboard", sizeof(lk->name)); | |
393 | default: | 387 | printk(KERN_ERR |
394 | strlcpy (lk->name, "Unknown DEC keyboard", | 388 | "lkkbd: keyboard on %s is unknown, please report to " |
395 | sizeof (lk->name)); | 389 | "Jan-Benedict Glaw <jbglaw@lug-owl.de>\n", lk->phys); |
396 | printk (KERN_ERR "lkkbd: keyboard on %s is unknown, " | 390 | printk(KERN_ERR "lkkbd: keyboard ID'ed as:"); |
397 | "please report to Jan-Benedict Glaw " | 391 | for (i = 0; i < LK_NUM_IGNORE_BYTES; i++) |
398 | "<jbglaw@lug-owl.de>\n", lk->phys); | 392 | printk(" 0x%02x", lk->id[i]); |
399 | printk (KERN_ERR "lkkbd: keyboard ID'ed as:"); | 393 | printk("\n"); |
400 | for (i = 0; i < LK_NUM_IGNORE_BYTES; i++) | 394 | break; |
401 | printk (" 0x%02x", lk->id[i]); | ||
402 | printk ("\n"); | ||
403 | break; | ||
404 | } | 395 | } |
405 | printk (KERN_INFO "lkkbd: keyboard on %s identified as: %s\n", | 396 | |
406 | lk->phys, lk->name); | 397 | printk(KERN_INFO "lkkbd: keyboard on %s identified as: %s\n", |
398 | lk->phys, lk->name); | ||
407 | 399 | ||
408 | /* | 400 | /* |
409 | * Report errors during keyboard boot-up. | 401 | * Report errors during keyboard boot-up. |
410 | */ | 402 | */ |
411 | switch (lk->id[2]) { | 403 | switch (lk->id[2]) { |
412 | case 0x00: | 404 | case 0x00: |
413 | /* All okay */ | 405 | /* All okay */ |
414 | break; | 406 | break; |
415 | 407 | ||
416 | case LK_STUCK_KEY: | 408 | case LK_STUCK_KEY: |
417 | printk (KERN_ERR "lkkbd: Stuck key on keyboard at " | 409 | printk(KERN_ERR "lkkbd: Stuck key on keyboard at %s\n", |
418 | "%s\n", lk->phys); | 410 | lk->phys); |
419 | break; | 411 | break; |
420 | 412 | ||
421 | case LK_SELFTEST_FAILED: | 413 | case LK_SELFTEST_FAILED: |
422 | printk (KERN_ERR "lkkbd: Selftest failed on keyboard " | 414 | printk(KERN_ERR |
423 | "at %s, keyboard may not work " | 415 | "lkkbd: Selftest failed on keyboard at %s, " |
424 | "properly\n", lk->phys); | 416 | "keyboard may not work properly\n", lk->phys); |
425 | break; | 417 | break; |
426 | 418 | ||
427 | default: | 419 | default: |
428 | printk (KERN_ERR "lkkbd: Unknown error %02x on " | 420 | printk(KERN_ERR |
429 | "keyboard at %s\n", lk->id[2], | 421 | "lkkbd: Unknown error %02x on keyboard at %s\n", |
430 | lk->phys); | 422 | lk->id[2], lk->phys); |
431 | break; | 423 | break; |
432 | } | 424 | } |
433 | 425 | ||
434 | /* | 426 | /* |
435 | * Try to hint user if there's a stuck key. | 427 | * Try to hint user if there's a stuck key. |
436 | */ | 428 | */ |
437 | if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0) | 429 | if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0) |
438 | printk (KERN_ERR "Scancode of stuck key is 0x%02x, keycode " | 430 | printk(KERN_ERR |
439 | "is 0x%04x\n", lk->id[3], | 431 | "Scancode of stuck key is 0x%02x, keycode is 0x%04x\n", |
440 | lk->keycode[lk->id[3]]); | 432 | lk->id[3], lk->keycode[lk->id[3]]); |
441 | |||
442 | return; | ||
443 | } | 433 | } |
444 | 434 | ||
445 | /* | 435 | /* |
446 | * lkkbd_interrupt() is called by the low level driver when a character | 436 | * lkkbd_interrupt() is called by the low level driver when a character |
447 | * is received. | 437 | * is received. |
448 | */ | 438 | */ |
449 | static irqreturn_t | 439 | static irqreturn_t lkkbd_interrupt(struct serio *serio, |
450 | lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags) | 440 | unsigned char data, unsigned int flags) |
451 | { | 441 | { |
452 | struct lkkbd *lk = serio_get_drvdata (serio); | 442 | struct lkkbd *lk = serio_get_drvdata(serio); |
443 | struct input_dev *input_dev = lk->dev; | ||
444 | unsigned int keycode; | ||
453 | int i; | 445 | int i; |
454 | 446 | ||
455 | DBG (KERN_INFO "Got byte 0x%02x\n", data); | 447 | DBG(KERN_INFO "Got byte 0x%02x\n", data); |
456 | 448 | ||
457 | if (lk->ignore_bytes > 0) { | 449 | if (lk->ignore_bytes > 0) { |
458 | DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name); | 450 | DBG(KERN_INFO "Ignoring a byte on %s\n", lk->name); |
459 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; | 451 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; |
460 | 452 | ||
461 | if (lk->ignore_bytes == 0) | 453 | if (lk->ignore_bytes == 0) |
462 | lkkbd_detection_done (lk); | 454 | lkkbd_detection_done(lk); |
463 | 455 | ||
464 | return IRQ_HANDLED; | 456 | return IRQ_HANDLED; |
465 | } | 457 | } |
466 | 458 | ||
467 | switch (data) { | 459 | switch (data) { |
468 | case LK_ALL_KEYS_UP: | 460 | case LK_ALL_KEYS_UP: |
469 | for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++) | 461 | for (i = 0; i < ARRAY_SIZE(lkkbd_keycode); i++) |
470 | if (lk->keycode[i] != KEY_RESERVED) | 462 | input_report_key(input_dev, lk->keycode[i], 0); |
471 | input_report_key (lk->dev, lk->keycode[i], 0); | 463 | input_sync(input_dev); |
472 | input_sync (lk->dev); | 464 | break; |
473 | break; | 465 | |
474 | 466 | case 0x01: | |
475 | case 0x01: | 467 | DBG(KERN_INFO "Got 0x01, scheduling re-initialization\n"); |
476 | DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n"); | 468 | lk->ignore_bytes = LK_NUM_IGNORE_BYTES; |
477 | lk->ignore_bytes = LK_NUM_IGNORE_BYTES; | 469 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; |
478 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; | 470 | schedule_work(&lk->tq); |
479 | schedule_work (&lk->tq); | 471 | break; |
480 | break; | 472 | |
481 | 473 | case LK_METRONOME: | |
482 | case LK_METRONOME: | 474 | case LK_OUTPUT_ERROR: |
483 | case LK_OUTPUT_ERROR: | 475 | case LK_INPUT_ERROR: |
484 | case LK_INPUT_ERROR: | 476 | case LK_KBD_LOCKED: |
485 | case LK_KBD_LOCKED: | 477 | case LK_KBD_TEST_MODE_ACK: |
486 | case LK_KBD_TEST_MODE_ACK: | 478 | case LK_PREFIX_KEY_DOWN: |
487 | case LK_PREFIX_KEY_DOWN: | 479 | case LK_MODE_CHANGE_ACK: |
488 | case LK_MODE_CHANGE_ACK: | 480 | case LK_RESPONSE_RESERVED: |
489 | case LK_RESPONSE_RESERVED: | 481 | DBG(KERN_INFO "Got %s and don't know how to handle...\n", |
490 | DBG (KERN_INFO "Got %s and don't know how to handle...\n", | 482 | response_name(data)); |
491 | response_name (data)); | 483 | break; |
492 | break; | 484 | |
493 | 485 | default: | |
494 | default: | 486 | keycode = lk->keycode[data]; |
495 | if (lk->keycode[data] != KEY_RESERVED) { | 487 | if (keycode != KEY_RESERVED) { |
496 | if (!test_bit (lk->keycode[data], lk->dev->key)) | 488 | input_report_key(input_dev, keycode, |
497 | input_report_key (lk->dev, lk->keycode[data], 1); | 489 | !test_bit(keycode, input_dev->key)); |
498 | else | 490 | input_sync(input_dev); |
499 | input_report_key (lk->dev, lk->keycode[data], 0); | 491 | } else { |
500 | input_sync (lk->dev); | 492 | printk(KERN_WARNING |
501 | } else | 493 | "%s: Unknown key with scancode 0x%02x on %s.\n", |
502 | printk (KERN_WARNING "%s: Unknown key with " | 494 | __FILE__, data, lk->name); |
503 | "scancode 0x%02x on %s.\n", | 495 | } |
504 | __FILE__, data, lk->name); | ||
505 | } | 496 | } |
506 | 497 | ||
507 | return IRQ_HANDLED; | 498 | return IRQ_HANDLED; |
508 | } | 499 | } |
509 | 500 | ||
501 | static void lkkbd_toggle_leds(struct lkkbd *lk) | ||
502 | { | ||
503 | struct serio *serio = lk->serio; | ||
504 | unsigned char leds_on = 0; | ||
505 | unsigned char leds_off = 0; | ||
506 | |||
507 | CHECK_LED(lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | ||
508 | CHECK_LED(lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | ||
509 | CHECK_LED(lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | ||
510 | CHECK_LED(lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | ||
511 | if (leds_on != 0) { | ||
512 | serio_write(serio, LK_CMD_LED_ON); | ||
513 | serio_write(serio, leds_on); | ||
514 | } | ||
515 | if (leds_off != 0) { | ||
516 | serio_write(serio, LK_CMD_LED_OFF); | ||
517 | serio_write(serio, leds_off); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | static void lkkbd_toggle_keyclick(struct lkkbd *lk, bool on) | ||
522 | { | ||
523 | struct serio *serio = lk->serio; | ||
524 | |||
525 | if (on) { | ||
526 | DBG("%s: Activating key clicks\n", __func__); | ||
527 | serio_write(serio, LK_CMD_ENABLE_KEYCLICK); | ||
528 | serio_write(serio, volume_to_hw(lk->keyclick_volume)); | ||
529 | serio_write(serio, LK_CMD_ENABLE_CTRCLICK); | ||
530 | serio_write(serio, volume_to_hw(lk->ctrlclick_volume)); | ||
531 | } else { | ||
532 | DBG("%s: Deactivating key clicks\n", __func__); | ||
533 | serio_write(serio, LK_CMD_DISABLE_KEYCLICK); | ||
534 | serio_write(serio, LK_CMD_DISABLE_CTRCLICK); | ||
535 | } | ||
536 | |||
537 | } | ||
538 | |||
510 | /* | 539 | /* |
511 | * lkkbd_event() handles events from the input module. | 540 | * lkkbd_event() handles events from the input module. |
512 | */ | 541 | */ |
513 | static int | 542 | static int lkkbd_event(struct input_dev *dev, |
514 | lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | 543 | unsigned int type, unsigned int code, int value) |
515 | int value) | ||
516 | { | 544 | { |
517 | struct lkkbd *lk = input_get_drvdata (dev); | 545 | struct lkkbd *lk = input_get_drvdata(dev); |
518 | unsigned char leds_on = 0; | ||
519 | unsigned char leds_off = 0; | ||
520 | 546 | ||
521 | switch (type) { | 547 | switch (type) { |
522 | case EV_LED: | 548 | case EV_LED: |
523 | CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | 549 | lkkbd_toggle_leds(lk); |
524 | CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | 550 | return 0; |
525 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | 551 | |
526 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | 552 | case EV_SND: |
527 | if (leds_on != 0) { | 553 | switch (code) { |
528 | serio_write (lk->serio, LK_CMD_LED_ON); | 554 | case SND_CLICK: |
529 | serio_write (lk->serio, leds_on); | 555 | lkkbd_toggle_keyclick(lk, value); |
530 | } | ||
531 | if (leds_off != 0) { | ||
532 | serio_write (lk->serio, LK_CMD_LED_OFF); | ||
533 | serio_write (lk->serio, leds_off); | ||
534 | } | ||
535 | return 0; | 556 | return 0; |
536 | 557 | ||
537 | case EV_SND: | 558 | case SND_BELL: |
538 | switch (code) { | 559 | if (value != 0) |
539 | case SND_CLICK: | 560 | serio_write(lk->serio, LK_CMD_SOUND_BELL); |
540 | if (value == 0) { | 561 | |
541 | DBG ("%s: Deactivating key clicks\n", __func__); | 562 | return 0; |
542 | serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | 563 | } |
543 | serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | 564 | |
544 | } else { | 565 | break; |
545 | DBG ("%s: Activating key clicks\n", __func__); | 566 | |
546 | serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | 567 | default: |
547 | serio_write (lk->serio, volume_to_hw (lk->keyclick_volume)); | 568 | printk(KERN_ERR "%s(): Got unknown type %d, code %d, value %d\n", |
548 | serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | 569 | __func__, type, code, value); |
549 | serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); | ||
550 | } | ||
551 | return 0; | ||
552 | |||
553 | case SND_BELL: | ||
554 | if (value != 0) | ||
555 | serio_write (lk->serio, LK_CMD_SOUND_BELL); | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | break; | ||
560 | |||
561 | default: | ||
562 | printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n", | ||
563 | __func__, type, code, value); | ||
564 | } | 570 | } |
565 | 571 | ||
566 | return -1; | 572 | return -1; |
@@ -570,79 +576,56 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | |||
570 | * lkkbd_reinit() sets leds and beeps to a state the computer remembers they | 576 | * lkkbd_reinit() sets leds and beeps to a state the computer remembers they |
571 | * were in. | 577 | * were in. |
572 | */ | 578 | */ |
573 | static void | 579 | static void lkkbd_reinit(struct work_struct *work) |
574 | lkkbd_reinit (struct work_struct *work) | ||
575 | { | 580 | { |
576 | struct lkkbd *lk = container_of(work, struct lkkbd, tq); | 581 | struct lkkbd *lk = container_of(work, struct lkkbd, tq); |
577 | int division; | 582 | int division; |
578 | unsigned char leds_on = 0; | ||
579 | unsigned char leds_off = 0; | ||
580 | 583 | ||
581 | /* Ask for ID */ | 584 | /* Ask for ID */ |
582 | serio_write (lk->serio, LK_CMD_REQUEST_ID); | 585 | serio_write(lk->serio, LK_CMD_REQUEST_ID); |
583 | 586 | ||
584 | /* Reset parameters */ | 587 | /* Reset parameters */ |
585 | serio_write (lk->serio, LK_CMD_SET_DEFAULTS); | 588 | serio_write(lk->serio, LK_CMD_SET_DEFAULTS); |
586 | 589 | ||
587 | /* Set LEDs */ | 590 | /* Set LEDs */ |
588 | CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | 591 | lkkbd_toggle_leds(lk); |
589 | CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | ||
590 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | ||
591 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | ||
592 | if (leds_on != 0) { | ||
593 | serio_write (lk->serio, LK_CMD_LED_ON); | ||
594 | serio_write (lk->serio, leds_on); | ||
595 | } | ||
596 | if (leds_off != 0) { | ||
597 | serio_write (lk->serio, LK_CMD_LED_OFF); | ||
598 | serio_write (lk->serio, leds_off); | ||
599 | } | ||
600 | 592 | ||
601 | /* | 593 | /* |
602 | * Try to activate extended LK401 mode. This command will | 594 | * Try to activate extended LK401 mode. This command will |
603 | * only work with a LK401 keyboard and grants access to | 595 | * only work with a LK401 keyboard and grants access to |
604 | * LAlt, RAlt, RCompose and RShift. | 596 | * LAlt, RAlt, RCompose and RShift. |
605 | */ | 597 | */ |
606 | serio_write (lk->serio, LK_CMD_ENABLE_LK401); | 598 | serio_write(lk->serio, LK_CMD_ENABLE_LK401); |
607 | 599 | ||
608 | /* Set all keys to UPDOWN mode */ | 600 | /* Set all keys to UPDOWN mode */ |
609 | for (division = 1; division <= 14; division++) | 601 | for (division = 1; division <= 14; division++) |
610 | serio_write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN, | 602 | serio_write(lk->serio, |
611 | division)); | 603 | LK_CMD_SET_MODE(LK_MODE_UPDOWN, division)); |
612 | 604 | ||
613 | /* Enable bell and set volume */ | 605 | /* Enable bell and set volume */ |
614 | serio_write (lk->serio, LK_CMD_ENABLE_BELL); | 606 | serio_write(lk->serio, LK_CMD_ENABLE_BELL); |
615 | serio_write (lk->serio, volume_to_hw (lk->bell_volume)); | 607 | serio_write(lk->serio, volume_to_hw(lk->bell_volume)); |
616 | 608 | ||
617 | /* Enable/disable keyclick (and possibly set volume) */ | 609 | /* Enable/disable keyclick (and possibly set volume) */ |
618 | if (test_bit (SND_CLICK, lk->dev->snd)) { | 610 | lkkbd_toggle_keyclick(lk, test_bit(SND_CLICK, lk->dev->snd)); |
619 | serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | ||
620 | serio_write (lk->serio, volume_to_hw (lk->keyclick_volume)); | ||
621 | serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | ||
622 | serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); | ||
623 | } else { | ||
624 | serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | ||
625 | serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | ||
626 | } | ||
627 | 611 | ||
628 | /* Sound the bell if needed */ | 612 | /* Sound the bell if needed */ |
629 | if (test_bit (SND_BELL, lk->dev->snd)) | 613 | if (test_bit(SND_BELL, lk->dev->snd)) |
630 | serio_write (lk->serio, LK_CMD_SOUND_BELL); | 614 | serio_write(lk->serio, LK_CMD_SOUND_BELL); |
631 | } | 615 | } |
632 | 616 | ||
633 | /* | 617 | /* |
634 | * lkkbd_connect() probes for a LK keyboard and fills the necessary structures. | 618 | * lkkbd_connect() probes for a LK keyboard and fills the necessary structures. |
635 | */ | 619 | */ |
636 | static int | 620 | static int lkkbd_connect(struct serio *serio, struct serio_driver *drv) |
637 | lkkbd_connect (struct serio *serio, struct serio_driver *drv) | ||
638 | { | 621 | { |
639 | struct lkkbd *lk; | 622 | struct lkkbd *lk; |
640 | struct input_dev *input_dev; | 623 | struct input_dev *input_dev; |
641 | int i; | 624 | int i; |
642 | int err; | 625 | int err; |
643 | 626 | ||
644 | lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL); | 627 | lk = kzalloc(sizeof(struct lkkbd), GFP_KERNEL); |
645 | input_dev = input_allocate_device (); | 628 | input_dev = input_allocate_device(); |
646 | if (!lk || !input_dev) { | 629 | if (!lk || !input_dev) { |
647 | err = -ENOMEM; | 630 | err = -ENOMEM; |
648 | goto fail1; | 631 | goto fail1; |
@@ -650,14 +633,14 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
650 | 633 | ||
651 | lk->serio = serio; | 634 | lk->serio = serio; |
652 | lk->dev = input_dev; | 635 | lk->dev = input_dev; |
653 | INIT_WORK (&lk->tq, lkkbd_reinit); | 636 | INIT_WORK(&lk->tq, lkkbd_reinit); |
654 | lk->bell_volume = bell_volume; | 637 | lk->bell_volume = bell_volume; |
655 | lk->keyclick_volume = keyclick_volume; | 638 | lk->keyclick_volume = keyclick_volume; |
656 | lk->ctrlclick_volume = ctrlclick_volume; | 639 | lk->ctrlclick_volume = ctrlclick_volume; |
657 | memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES); | 640 | memcpy(lk->keycode, lkkbd_keycode, sizeof(lk->keycode)); |
658 | 641 | ||
659 | strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name)); | 642 | strlcpy(lk->name, "DEC LK keyboard", sizeof(lk->name)); |
660 | snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); | 643 | snprintf(lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); |
661 | 644 | ||
662 | input_dev->name = lk->name; | 645 | input_dev->name = lk->name; |
663 | input_dev->phys = lk->phys; | 646 | input_dev->phys = lk->phys; |
@@ -668,62 +651,61 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
668 | input_dev->dev.parent = &serio->dev; | 651 | input_dev->dev.parent = &serio->dev; |
669 | input_dev->event = lkkbd_event; | 652 | input_dev->event = lkkbd_event; |
670 | 653 | ||
671 | input_set_drvdata (input_dev, lk); | 654 | input_set_drvdata(input_dev, lk); |
672 | 655 | ||
673 | set_bit (EV_KEY, input_dev->evbit); | 656 | __set_bit(EV_KEY, input_dev->evbit); |
674 | set_bit (EV_LED, input_dev->evbit); | 657 | __set_bit(EV_LED, input_dev->evbit); |
675 | set_bit (EV_SND, input_dev->evbit); | 658 | __set_bit(EV_SND, input_dev->evbit); |
676 | set_bit (EV_REP, input_dev->evbit); | 659 | __set_bit(EV_REP, input_dev->evbit); |
677 | set_bit (LED_CAPSL, input_dev->ledbit); | 660 | __set_bit(LED_CAPSL, input_dev->ledbit); |
678 | set_bit (LED_SLEEP, input_dev->ledbit); | 661 | __set_bit(LED_SLEEP, input_dev->ledbit); |
679 | set_bit (LED_COMPOSE, input_dev->ledbit); | 662 | __set_bit(LED_COMPOSE, input_dev->ledbit); |
680 | set_bit (LED_SCROLLL, input_dev->ledbit); | 663 | __set_bit(LED_SCROLLL, input_dev->ledbit); |
681 | set_bit (SND_BELL, input_dev->sndbit); | 664 | __set_bit(SND_BELL, input_dev->sndbit); |
682 | set_bit (SND_CLICK, input_dev->sndbit); | 665 | __set_bit(SND_CLICK, input_dev->sndbit); |
683 | 666 | ||
684 | input_dev->keycode = lk->keycode; | 667 | input_dev->keycode = lk->keycode; |
685 | input_dev->keycodesize = sizeof (lk_keycode_t); | 668 | input_dev->keycodesize = sizeof(lk->keycode[0]); |
686 | input_dev->keycodemax = LK_NUM_KEYCODES; | 669 | input_dev->keycodemax = ARRAY_SIZE(lk->keycode); |
687 | 670 | ||
688 | for (i = 0; i < LK_NUM_KEYCODES; i++) | 671 | for (i = 0; i < LK_NUM_KEYCODES; i++) |
689 | __set_bit (lk->keycode[i], input_dev->keybit); | 672 | __set_bit(lk->keycode[i], input_dev->keybit); |
690 | __clear_bit(KEY_RESERVED, input_dev->keybit); | 673 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
691 | 674 | ||
692 | serio_set_drvdata (serio, lk); | 675 | serio_set_drvdata(serio, lk); |
693 | 676 | ||
694 | err = serio_open (serio, drv); | 677 | err = serio_open(serio, drv); |
695 | if (err) | 678 | if (err) |
696 | goto fail2; | 679 | goto fail2; |
697 | 680 | ||
698 | err = input_register_device (lk->dev); | 681 | err = input_register_device(lk->dev); |
699 | if (err) | 682 | if (err) |
700 | goto fail3; | 683 | goto fail3; |
701 | 684 | ||
702 | serio_write (lk->serio, LK_CMD_POWERCYCLE_RESET); | 685 | serio_write(lk->serio, LK_CMD_POWERCYCLE_RESET); |
703 | 686 | ||
704 | return 0; | 687 | return 0; |
705 | 688 | ||
706 | fail3: serio_close (serio); | 689 | fail3: serio_close(serio); |
707 | fail2: serio_set_drvdata (serio, NULL); | 690 | fail2: serio_set_drvdata(serio, NULL); |
708 | fail1: input_free_device (input_dev); | 691 | fail1: input_free_device(input_dev); |
709 | kfree (lk); | 692 | kfree(lk); |
710 | return err; | 693 | return err; |
711 | } | 694 | } |
712 | 695 | ||
713 | /* | 696 | /* |
714 | * lkkbd_disconnect() unregisters and closes behind us. | 697 | * lkkbd_disconnect() unregisters and closes behind us. |
715 | */ | 698 | */ |
716 | static void | 699 | static void lkkbd_disconnect(struct serio *serio) |
717 | lkkbd_disconnect (struct serio *serio) | ||
718 | { | 700 | { |
719 | struct lkkbd *lk = serio_get_drvdata (serio); | 701 | struct lkkbd *lk = serio_get_drvdata(serio); |
720 | 702 | ||
721 | input_get_device (lk->dev); | 703 | input_get_device(lk->dev); |
722 | input_unregister_device (lk->dev); | 704 | input_unregister_device(lk->dev); |
723 | serio_close (serio); | 705 | serio_close(serio); |
724 | serio_set_drvdata (serio, NULL); | 706 | serio_set_drvdata(serio, NULL); |
725 | input_put_device (lk->dev); | 707 | input_put_device(lk->dev); |
726 | kfree (lk); | 708 | kfree(lk); |
727 | } | 709 | } |
728 | 710 | ||
729 | static struct serio_device_id lkkbd_serio_ids[] = { | 711 | static struct serio_device_id lkkbd_serio_ids[] = { |
@@ -752,18 +734,16 @@ static struct serio_driver lkkbd_drv = { | |||
752 | /* | 734 | /* |
753 | * The functions for insering/removing us as a module. | 735 | * The functions for insering/removing us as a module. |
754 | */ | 736 | */ |
755 | static int __init | 737 | static int __init lkkbd_init(void) |
756 | lkkbd_init (void) | ||
757 | { | 738 | { |
758 | return serio_register_driver(&lkkbd_drv); | 739 | return serio_register_driver(&lkkbd_drv); |
759 | } | 740 | } |
760 | 741 | ||
761 | static void __exit | 742 | static void __exit lkkbd_exit(void) |
762 | lkkbd_exit (void) | ||
763 | { | 743 | { |
764 | serio_unregister_driver(&lkkbd_drv); | 744 | serio_unregister_driver(&lkkbd_drv); |
765 | } | 745 | } |
766 | 746 | ||
767 | module_init (lkkbd_init); | 747 | module_init(lkkbd_init); |
768 | module_exit (lkkbd_exit); | 748 | module_exit(lkkbd_exit); |
769 | 749 | ||
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 574eda2a4957..60ac4684f875 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/leds.h> | 32 | #include <linux/leds.h> |
33 | #include <linux/i2c/lm8323.h> | 33 | #include <linux/i2c/lm8323.h> |
34 | #include <linux/slab.h> | ||
34 | 35 | ||
35 | /* Commands to send to the chip. */ | 36 | /* Commands to send to the chip. */ |
36 | #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ | 37 | #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ |
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 9caed30f3bbb..b1ab29861e1c 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -192,11 +192,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) | |||
192 | static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) | 192 | static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) |
193 | { | 193 | { |
194 | struct locomokbd *locomokbd = dev_id; | 194 | struct locomokbd *locomokbd = dev_id; |
195 | u16 r; | ||
196 | |||
197 | r = locomo_readl(locomokbd->base + LOCOMO_KIC); | ||
198 | if ((r & 0x0001) == 0) | ||
199 | return IRQ_HANDLED; | ||
200 | |||
201 | locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */ | ||
202 | |||
195 | /** wait chattering delay **/ | 203 | /** wait chattering delay **/ |
196 | udelay(100); | 204 | udelay(100); |
197 | 205 | ||
198 | locomokbd_scankeyboard(locomokbd); | 206 | locomokbd_scankeyboard(locomokbd); |
199 | |||
200 | return IRQ_HANDLED; | 207 | return IRQ_HANDLED; |
201 | } | 208 | } |
202 | 209 | ||
@@ -210,6 +217,25 @@ static void locomokbd_timer_callback(unsigned long data) | |||
210 | locomokbd_scankeyboard(locomokbd); | 217 | locomokbd_scankeyboard(locomokbd); |
211 | } | 218 | } |
212 | 219 | ||
220 | static int locomokbd_open(struct input_dev *dev) | ||
221 | { | ||
222 | struct locomokbd *locomokbd = input_get_drvdata(dev); | ||
223 | u16 r; | ||
224 | |||
225 | r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010; | ||
226 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static void locomokbd_close(struct input_dev *dev) | ||
231 | { | ||
232 | struct locomokbd *locomokbd = input_get_drvdata(dev); | ||
233 | u16 r; | ||
234 | |||
235 | r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010; | ||
236 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | ||
237 | } | ||
238 | |||
213 | static int __devinit locomokbd_probe(struct locomo_dev *dev) | 239 | static int __devinit locomokbd_probe(struct locomo_dev *dev) |
214 | { | 240 | { |
215 | struct locomokbd *locomokbd; | 241 | struct locomokbd *locomokbd; |
@@ -253,6 +279,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) | |||
253 | input_dev->id.vendor = 0x0001; | 279 | input_dev->id.vendor = 0x0001; |
254 | input_dev->id.product = 0x0001; | 280 | input_dev->id.product = 0x0001; |
255 | input_dev->id.version = 0x0100; | 281 | input_dev->id.version = 0x0100; |
282 | input_dev->open = locomokbd_open; | ||
283 | input_dev->close = locomokbd_close; | ||
256 | input_dev->dev.parent = &dev->dev; | 284 | input_dev->dev.parent = &dev->dev; |
257 | 285 | ||
258 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | | 286 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | |
@@ -261,6 +289,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) | |||
261 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); | 289 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); |
262 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); | 290 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); |
263 | 291 | ||
292 | input_set_drvdata(input_dev, locomokbd); | ||
293 | |||
264 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); | 294 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); |
265 | for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) | 295 | for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) |
266 | set_bit(locomokbd->keycode[i], input_dev->keybit); | 296 | set_bit(locomokbd->keycode[i], input_dev->keybit); |
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 91cfe5170265..b443e088fd3c 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/input/matrix_keypad.h> | 24 | #include <linux/input/matrix_keypad.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | struct matrix_keypad { | 27 | struct matrix_keypad { |
27 | const struct matrix_keypad_platform_data *pdata; | 28 | const struct matrix_keypad_platform_data *pdata; |
@@ -29,11 +30,13 @@ struct matrix_keypad { | |||
29 | unsigned short *keycodes; | 30 | unsigned short *keycodes; |
30 | unsigned int row_shift; | 31 | unsigned int row_shift; |
31 | 32 | ||
33 | DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); | ||
34 | |||
32 | uint32_t last_key_state[MATRIX_MAX_COLS]; | 35 | uint32_t last_key_state[MATRIX_MAX_COLS]; |
33 | struct delayed_work work; | 36 | struct delayed_work work; |
37 | spinlock_t lock; | ||
34 | bool scan_pending; | 38 | bool scan_pending; |
35 | bool stopped; | 39 | bool stopped; |
36 | spinlock_t lock; | ||
37 | }; | 40 | }; |
38 | 41 | ||
39 | /* | 42 | /* |
@@ -213,38 +216,53 @@ static void matrix_keypad_stop(struct input_dev *dev) | |||
213 | } | 216 | } |
214 | 217 | ||
215 | #ifdef CONFIG_PM | 218 | #ifdef CONFIG_PM |
216 | static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state) | 219 | static int matrix_keypad_suspend(struct device *dev) |
217 | { | 220 | { |
221 | struct platform_device *pdev = to_platform_device(dev); | ||
218 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 222 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
219 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 223 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
220 | int i; | 224 | int i; |
221 | 225 | ||
222 | matrix_keypad_stop(keypad->input_dev); | 226 | matrix_keypad_stop(keypad->input_dev); |
223 | 227 | ||
224 | if (device_may_wakeup(&pdev->dev)) | 228 | if (device_may_wakeup(&pdev->dev)) { |
225 | for (i = 0; i < pdata->num_row_gpios; i++) | 229 | for (i = 0; i < pdata->num_row_gpios; i++) { |
226 | enable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); | 230 | if (!test_bit(i, keypad->disabled_gpios)) { |
231 | unsigned int gpio = pdata->row_gpios[i]; | ||
232 | |||
233 | if (enable_irq_wake(gpio_to_irq(gpio)) == 0) | ||
234 | __set_bit(i, keypad->disabled_gpios); | ||
235 | } | ||
236 | } | ||
237 | } | ||
227 | 238 | ||
228 | return 0; | 239 | return 0; |
229 | } | 240 | } |
230 | 241 | ||
231 | static int matrix_keypad_resume(struct platform_device *pdev) | 242 | static int matrix_keypad_resume(struct device *dev) |
232 | { | 243 | { |
244 | struct platform_device *pdev = to_platform_device(dev); | ||
233 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 245 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
234 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 246 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
235 | int i; | 247 | int i; |
236 | 248 | ||
237 | if (device_may_wakeup(&pdev->dev)) | 249 | if (device_may_wakeup(&pdev->dev)) { |
238 | for (i = 0; i < pdata->num_row_gpios; i++) | 250 | for (i = 0; i < pdata->num_row_gpios; i++) { |
239 | disable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); | 251 | if (test_and_clear_bit(i, keypad->disabled_gpios)) { |
252 | unsigned int gpio = pdata->row_gpios[i]; | ||
253 | |||
254 | disable_irq_wake(gpio_to_irq(gpio)); | ||
255 | } | ||
256 | } | ||
257 | } | ||
240 | 258 | ||
241 | matrix_keypad_start(keypad->input_dev); | 259 | matrix_keypad_start(keypad->input_dev); |
242 | 260 | ||
243 | return 0; | 261 | return 0; |
244 | } | 262 | } |
245 | #else | 263 | |
246 | #define matrix_keypad_suspend NULL | 264 | static const SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, |
247 | #define matrix_keypad_resume NULL | 265 | matrix_keypad_suspend, matrix_keypad_resume); |
248 | #endif | 266 | #endif |
249 | 267 | ||
250 | static int __devinit init_matrix_gpio(struct platform_device *pdev, | 268 | static int __devinit init_matrix_gpio(struct platform_device *pdev, |
@@ -356,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) | |||
356 | input_dev->name = pdev->name; | 374 | input_dev->name = pdev->name; |
357 | input_dev->id.bustype = BUS_HOST; | 375 | input_dev->id.bustype = BUS_HOST; |
358 | input_dev->dev.parent = &pdev->dev; | 376 | input_dev->dev.parent = &pdev->dev; |
359 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 377 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
378 | if (!pdata->no_autorepeat) | ||
379 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
360 | input_dev->open = matrix_keypad_start; | 380 | input_dev->open = matrix_keypad_start; |
361 | input_dev->close = matrix_keypad_stop; | 381 | input_dev->close = matrix_keypad_stop; |
362 | 382 | ||
@@ -417,11 +437,12 @@ static int __devexit matrix_keypad_remove(struct platform_device *pdev) | |||
417 | static struct platform_driver matrix_keypad_driver = { | 437 | static struct platform_driver matrix_keypad_driver = { |
418 | .probe = matrix_keypad_probe, | 438 | .probe = matrix_keypad_probe, |
419 | .remove = __devexit_p(matrix_keypad_remove), | 439 | .remove = __devexit_p(matrix_keypad_remove), |
420 | .suspend = matrix_keypad_suspend, | ||
421 | .resume = matrix_keypad_resume, | ||
422 | .driver = { | 440 | .driver = { |
423 | .name = "matrix-keypad", | 441 | .name = "matrix-keypad", |
424 | .owner = THIS_MODULE, | 442 | .owner = THIS_MODULE, |
443 | #ifdef CONFIG_PM | ||
444 | .pm = &matrix_keypad_pm_ops, | ||
445 | #endif | ||
425 | }, | 446 | }, |
426 | }; | 447 | }; |
427 | 448 | ||
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 3b5b948eba39..7fc8185e5c1b 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
19 | #include <linux/input.h> | 20 | #include <linux/input.h> |
20 | #include <linux/input/matrix_keypad.h> | 21 | #include <linux/input/matrix_keypad.h> |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index bba85add35a3..a72e61ddca91 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -34,13 +34,14 @@ | |||
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
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 <mach/gpio.h> | 38 | #include <mach/gpio.h> |
38 | #include <mach/keypad.h> | 39 | #include <plat/keypad.h> |
39 | #include <mach/menelaus.h> | 40 | #include <plat/menelaus.h> |
40 | #include <asm/irq.h> | 41 | #include <asm/irq.h> |
41 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
43 | #include <mach/mux.h> | 44 | #include <plat/mux.h> |
44 | 45 | ||
45 | #undef NEW_BOARD_LEARNING_MODE | 46 | #undef NEW_BOARD_LEARNING_MODE |
46 | 47 | ||
diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 78cccddbf551..1f1a5563f60a 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/slab.h> | ||
17 | 18 | ||
18 | struct opencores_kbd { | 19 | struct opencores_kbd { |
19 | struct input_dev *input; | 20 | struct input_dev *input; |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 79cd3e9fdf2e..0e53b3bc39af 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/input/matrix_keypad.h> | 28 | #include <linux/input/matrix_keypad.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include <asm/mach/arch.h> | 31 | #include <asm/mach/arch.h> |
31 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index 95fbba470e65..b7123a44b6ec 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include <mach/pxa930_rotary.h> | 18 | #include <mach/pxa930_rotary.h> |
18 | 19 | ||
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 191cc51d6cf8..31f30087b591 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c | |||
@@ -362,7 +362,7 @@ static int __devexit qt2160_remove(struct i2c_client *client) | |||
362 | return 0; | 362 | return 0; |
363 | } | 363 | } |
364 | 364 | ||
365 | static struct i2c_device_id qt2160_idtable[] = { | 365 | static const struct i2c_device_id qt2160_idtable[] = { |
366 | { "qt2160", 0, }, | 366 | { "qt2160", 0, }, |
367 | { } | 367 | { } |
368 | }; | 368 | }; |
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 887af79b7bff..d7dafd9425b6 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -18,17 +18,11 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/input/sh_keysc.h> | ||
22 | #include <linux/bitmap.h> | ||
21 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
22 | #include <linux/io.h> | 24 | #include <linux/io.h> |
23 | #include <asm/sh_keysc.h> | 25 | #include <linux/slab.h> |
24 | |||
25 | #define KYCR1_OFFS 0x00 | ||
26 | #define KYCR2_OFFS 0x04 | ||
27 | #define KYINDR_OFFS 0x08 | ||
28 | #define KYOUTDR_OFFS 0x0c | ||
29 | |||
30 | #define KYCR2_IRQ_LEVEL 0x10 | ||
31 | #define KYCR2_IRQ_DISABLED 0x00 | ||
32 | 26 | ||
33 | static const struct { | 27 | static const struct { |
34 | unsigned char kymd, keyout, keyin; | 28 | unsigned char kymd, keyout, keyin; |
@@ -36,84 +30,131 @@ static const struct { | |||
36 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, | 30 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, |
37 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, | 31 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, |
38 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, | 32 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, |
33 | [SH_KEYSC_MODE_4] = { 3, 6, 6 }, | ||
34 | [SH_KEYSC_MODE_5] = { 4, 6, 7 }, | ||
35 | [SH_KEYSC_MODE_6] = { 5, 7, 7 }, | ||
39 | }; | 36 | }; |
40 | 37 | ||
41 | struct sh_keysc_priv { | 38 | struct sh_keysc_priv { |
42 | void __iomem *iomem_base; | 39 | void __iomem *iomem_base; |
43 | struct clk *clk; | 40 | struct clk *clk; |
44 | unsigned long last_keys; | 41 | DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); |
45 | struct input_dev *input; | 42 | struct input_dev *input; |
46 | struct sh_keysc_info pdata; | 43 | struct sh_keysc_info pdata; |
47 | }; | 44 | }; |
48 | 45 | ||
46 | #define KYCR1 0 | ||
47 | #define KYCR2 1 | ||
48 | #define KYINDR 2 | ||
49 | #define KYOUTDR 3 | ||
50 | |||
51 | #define KYCR2_IRQ_LEVEL 0x10 | ||
52 | #define KYCR2_IRQ_DISABLED 0x00 | ||
53 | |||
54 | static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr) | ||
55 | { | ||
56 | return ioread16(p->iomem_base + (reg_nr << 2)); | ||
57 | } | ||
58 | |||
59 | static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr, | ||
60 | unsigned long value) | ||
61 | { | ||
62 | iowrite16(value, p->iomem_base + (reg_nr << 2)); | ||
63 | } | ||
64 | |||
65 | static void sh_keysc_level_mode(struct sh_keysc_priv *p, | ||
66 | unsigned long keys_set) | ||
67 | { | ||
68 | struct sh_keysc_info *pdata = &p->pdata; | ||
69 | |||
70 | sh_keysc_write(p, KYOUTDR, 0); | ||
71 | sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8)); | ||
72 | |||
73 | if (pdata->kycr2_delay) | ||
74 | udelay(pdata->kycr2_delay); | ||
75 | } | ||
76 | |||
77 | static void sh_keysc_map_dbg(struct device *dev, unsigned long *map, | ||
78 | const char *str) | ||
79 | { | ||
80 | int k; | ||
81 | |||
82 | for (k = 0; k < BITS_TO_LONGS(SH_KEYSC_MAXKEYS); k++) | ||
83 | dev_dbg(dev, "%s[%d] 0x%lx\n", str, k, map[k]); | ||
84 | } | ||
85 | |||
49 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | 86 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) |
50 | { | 87 | { |
51 | struct platform_device *pdev = dev_id; | 88 | struct platform_device *pdev = dev_id; |
52 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 89 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
53 | struct sh_keysc_info *pdata = &priv->pdata; | 90 | struct sh_keysc_info *pdata = &priv->pdata; |
54 | unsigned long keys, keys1, keys0, mask; | 91 | int keyout_nr = sh_keysc_mode[pdata->mode].keyout; |
92 | int keyin_nr = sh_keysc_mode[pdata->mode].keyin; | ||
93 | DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS); | ||
94 | DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS); | ||
95 | DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS); | ||
55 | unsigned char keyin_set, tmp; | 96 | unsigned char keyin_set, tmp; |
56 | int i, k; | 97 | int i, k, n; |
57 | 98 | ||
58 | dev_dbg(&pdev->dev, "isr!\n"); | 99 | dev_dbg(&pdev->dev, "isr!\n"); |
59 | 100 | ||
60 | keys1 = ~0; | 101 | bitmap_fill(keys1, SH_KEYSC_MAXKEYS); |
61 | keys0 = 0; | 102 | bitmap_zero(keys0, SH_KEYSC_MAXKEYS); |
62 | 103 | ||
63 | do { | 104 | do { |
64 | keys = 0; | 105 | bitmap_zero(keys, SH_KEYSC_MAXKEYS); |
65 | keyin_set = 0; | 106 | keyin_set = 0; |
66 | 107 | ||
67 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | 108 | sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); |
109 | |||
110 | for (i = 0; i < keyout_nr; i++) { | ||
111 | n = keyin_nr * i; | ||
68 | 112 | ||
69 | for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { | 113 | /* drive one KEYOUT pin low, read KEYIN pins */ |
70 | iowrite16(0xfff ^ (3 << (i * 2)), | 114 | sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2))); |
71 | priv->iomem_base + KYOUTDR_OFFS); | ||
72 | udelay(pdata->delay); | 115 | udelay(pdata->delay); |
73 | tmp = ioread16(priv->iomem_base + KYINDR_OFFS); | 116 | tmp = sh_keysc_read(priv, KYINDR); |
74 | keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i); | ||
75 | tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1; | ||
76 | keyin_set |= tmp; | ||
77 | } | ||
78 | 117 | ||
79 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 118 | /* set bit if key press has been detected */ |
80 | iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8), | 119 | for (k = 0; k < keyin_nr; k++) { |
81 | priv->iomem_base + KYCR2_OFFS); | 120 | if (tmp & (1 << k)) |
121 | __set_bit(n + k, keys); | ||
122 | } | ||
82 | 123 | ||
83 | if (pdata->kycr2_delay) | 124 | /* keep track of which KEYIN bits that have been set */ |
84 | udelay(pdata->kycr2_delay); | 125 | keyin_set |= tmp ^ ((1 << keyin_nr) - 1); |
126 | } | ||
85 | 127 | ||
86 | keys ^= ~0; | 128 | sh_keysc_level_mode(priv, keyin_set); |
87 | keys &= (1 << (sh_keysc_mode[pdata->mode].keyin * | ||
88 | sh_keysc_mode[pdata->mode].keyout)) - 1; | ||
89 | keys1 &= keys; | ||
90 | keys0 |= keys; | ||
91 | 129 | ||
92 | dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); | 130 | bitmap_complement(keys, keys, SH_KEYSC_MAXKEYS); |
131 | bitmap_and(keys1, keys1, keys, SH_KEYSC_MAXKEYS); | ||
132 | bitmap_or(keys0, keys0, keys, SH_KEYSC_MAXKEYS); | ||
93 | 133 | ||
94 | } while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01); | 134 | sh_keysc_map_dbg(&pdev->dev, keys, "keys"); |
95 | 135 | ||
96 | dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", | 136 | } while (sh_keysc_read(priv, KYCR2) & 0x01); |
97 | priv->last_keys, keys0, keys1); | 137 | |
138 | sh_keysc_map_dbg(&pdev->dev, priv->last_keys, "last_keys"); | ||
139 | sh_keysc_map_dbg(&pdev->dev, keys0, "keys0"); | ||
140 | sh_keysc_map_dbg(&pdev->dev, keys1, "keys1"); | ||
98 | 141 | ||
99 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { | 142 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { |
100 | k = pdata->keycodes[i]; | 143 | k = pdata->keycodes[i]; |
101 | if (!k) | 144 | if (!k) |
102 | continue; | 145 | continue; |
103 | 146 | ||
104 | mask = 1 << i; | 147 | if (test_bit(i, keys0) == test_bit(i, priv->last_keys)) |
105 | |||
106 | if (!((priv->last_keys ^ keys0) & mask)) | ||
107 | continue; | 148 | continue; |
108 | 149 | ||
109 | if ((keys1 | keys0) & mask) { | 150 | if (test_bit(i, keys1) || test_bit(i, keys0)) { |
110 | input_event(priv->input, EV_KEY, k, 1); | 151 | input_event(priv->input, EV_KEY, k, 1); |
111 | priv->last_keys |= mask; | 152 | __set_bit(i, priv->last_keys); |
112 | } | 153 | } |
113 | 154 | ||
114 | if (!(keys1 & mask)) { | 155 | if (!test_bit(i, keys1)) { |
115 | input_event(priv->input, EV_KEY, k, 0); | 156 | input_event(priv->input, EV_KEY, k, 0); |
116 | priv->last_keys &= ~mask; | 157 | __clear_bit(i, priv->last_keys); |
117 | } | 158 | } |
118 | 159 | ||
119 | } | 160 | } |
@@ -122,8 +163,6 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | |||
122 | return IRQ_HANDLED; | 163 | return IRQ_HANDLED; |
123 | } | 164 | } |
124 | 165 | ||
125 | #define res_size(res) ((res)->end - (res)->start + 1) | ||
126 | |||
127 | static int __devinit sh_keysc_probe(struct platform_device *pdev) | 166 | static int __devinit sh_keysc_probe(struct platform_device *pdev) |
128 | { | 167 | { |
129 | struct sh_keysc_priv *priv; | 168 | struct sh_keysc_priv *priv; |
@@ -164,7 +203,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
164 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); | 203 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); |
165 | pdata = &priv->pdata; | 204 | pdata = &priv->pdata; |
166 | 205 | ||
167 | priv->iomem_base = ioremap_nocache(res->start, res_size(res)); | 206 | priv->iomem_base = ioremap_nocache(res->start, resource_size(res)); |
168 | if (priv->iomem_base == NULL) { | 207 | if (priv->iomem_base == NULL) { |
169 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 208 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); |
170 | error = -ENXIO; | 209 | error = -ENXIO; |
@@ -220,10 +259,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
220 | 259 | ||
221 | clk_enable(priv->clk); | 260 | clk_enable(priv->clk); |
222 | 261 | ||
223 | iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | | 262 | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | |
224 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); | 263 | pdata->scan_timing); |
225 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 264 | sh_keysc_level_mode(priv, 0); |
226 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | ||
227 | 265 | ||
228 | device_init_wakeup(&pdev->dev, 1); | 266 | device_init_wakeup(&pdev->dev, 1); |
229 | 267 | ||
@@ -248,7 +286,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
248 | { | 286 | { |
249 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 287 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
250 | 288 | ||
251 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | 289 | sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); |
252 | 290 | ||
253 | input_unregister_device(priv->input); | 291 | input_unregister_device(priv->input); |
254 | free_irq(platform_get_irq(pdev, 0), pdev); | 292 | free_irq(platform_get_irq(pdev, 0), pdev); |
@@ -270,7 +308,7 @@ static int sh_keysc_suspend(struct device *dev) | |||
270 | int irq = platform_get_irq(pdev, 0); | 308 | int irq = platform_get_irq(pdev, 0); |
271 | unsigned short value; | 309 | unsigned short value; |
272 | 310 | ||
273 | value = ioread16(priv->iomem_base + KYCR1_OFFS); | 311 | value = sh_keysc_read(priv, KYCR1); |
274 | 312 | ||
275 | if (device_may_wakeup(dev)) { | 313 | if (device_may_wakeup(dev)) { |
276 | value |= 0x80; | 314 | value |= 0x80; |
@@ -279,7 +317,7 @@ static int sh_keysc_suspend(struct device *dev) | |||
279 | value &= ~0x80; | 317 | value &= ~0x80; |
280 | } | 318 | } |
281 | 319 | ||
282 | iowrite16(value, priv->iomem_base + KYCR1_OFFS); | 320 | sh_keysc_write(priv, KYCR1, value); |
283 | 321 | ||
284 | return 0; | 322 | return 0; |
285 | } | 323 | } |
@@ -295,7 +333,7 @@ static int sh_keysc_resume(struct device *dev) | |||
295 | return 0; | 333 | return 0; |
296 | } | 334 | } |
297 | 335 | ||
298 | static struct dev_pm_ops sh_keysc_dev_pm_ops = { | 336 | static const struct dev_pm_ops sh_keysc_dev_pm_ops = { |
299 | .suspend = sh_keysc_suspend, | 337 | .suspend = sh_keysc_suspend, |
300 | .resume = sh_keysc_resume, | 338 | .resume = sh_keysc_resume, |
301 | }; | 339 | }; |
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c index 42cb3faf7336..3910f269cfc8 100644 --- a/drivers/input/keyboard/tosakbd.c +++ b/drivers/input/keyboard/tosakbd.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | #include <mach/gpio.h> | 23 | #include <mach/gpio.h> |
23 | #include <mach/tosa.h> | 24 | #include <mach/tosa.h> |
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 9a2977c21696..7aa59e07b689 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -31,7 +31,8 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/input.h> | 32 | #include <linux/input.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/i2c/twl4030.h> | 34 | #include <linux/i2c/twl.h> |
35 | #include <linux/slab.h> | ||
35 | 36 | ||
36 | 37 | ||
37 | /* | 38 | /* |
@@ -133,7 +134,7 @@ struct twl4030_keypad { | |||
133 | static int twl4030_kpread(struct twl4030_keypad *kp, | 134 | static int twl4030_kpread(struct twl4030_keypad *kp, |
134 | u8 *data, u32 reg, u8 num_bytes) | 135 | u8 *data, u32 reg, u8 num_bytes) |
135 | { | 136 | { |
136 | int ret = twl4030_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes); | 137 | int ret = twl_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes); |
137 | 138 | ||
138 | if (ret < 0) | 139 | if (ret < 0) |
139 | dev_warn(kp->dbg_dev, | 140 | dev_warn(kp->dbg_dev, |
@@ -145,7 +146,7 @@ static int twl4030_kpread(struct twl4030_keypad *kp, | |||
145 | 146 | ||
146 | static int twl4030_kpwrite_u8(struct twl4030_keypad *kp, u8 data, u32 reg) | 147 | static int twl4030_kpwrite_u8(struct twl4030_keypad *kp, u8 data, u32 reg) |
147 | { | 148 | { |
148 | int ret = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg); | 149 | int ret = twl_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg); |
149 | 150 | ||
150 | if (ret < 0) | 151 | if (ret < 0) |
151 | dev_warn(kp->dbg_dev, | 152 | dev_warn(kp->dbg_dev, |
@@ -253,14 +254,6 @@ static irqreturn_t do_kp_irq(int irq, void *_kp) | |||
253 | u8 reg; | 254 | u8 reg; |
254 | int ret; | 255 | int ret; |
255 | 256 | ||
256 | #ifdef CONFIG_LOCKDEP | ||
257 | /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which | ||
258 | * we don't want and can't tolerate. Although it might be | ||
259 | * friendlier not to borrow this thread context... | ||
260 | */ | ||
261 | local_irq_enable(); | ||
262 | #endif | ||
263 | |||
264 | /* Read & Clear TWL4030 pending interrupt */ | 257 | /* Read & Clear TWL4030 pending interrupt */ |
265 | ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); | 258 | ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); |
266 | 259 | ||
@@ -403,7 +396,8 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) | |||
403 | * | 396 | * |
404 | * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... | 397 | * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... |
405 | */ | 398 | */ |
406 | error = request_irq(kp->irq, do_kp_irq, 0, pdev->name, kp); | 399 | error = request_threaded_irq(kp->irq, NULL, do_kp_irq, |
400 | 0, pdev->name, kp); | ||
407 | if (error) { | 401 | if (error) { |
408 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", | 402 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", |
409 | kp->irq); | 403 | kp->irq); |
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 6032def03707..4ef764cc493c 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #include <mach/w90p910_keypad.h> | 24 | #include <mach/w90p910_keypad.h> |
24 | 25 | ||
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c new file mode 100644 index 000000000000..40dabd8487b5 --- /dev/null +++ b/drivers/input/misc/88pm860x_onkey.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* | ||
2 | * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Marvell International Ltd. | ||
5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General | ||
8 | * Public License. See the file "COPYING" in the main directory of this | ||
9 | * archive for more details. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/input.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/mfd/88pm860x.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #define PM8607_WAKEUP 0x0b | ||
31 | |||
32 | #define LONG_ONKEY_EN (1 << 1) | ||
33 | #define ONKEY_STATUS (1 << 0) | ||
34 | |||
35 | struct pm860x_onkey_info { | ||
36 | struct input_dev *idev; | ||
37 | struct pm860x_chip *chip; | ||
38 | struct i2c_client *i2c; | ||
39 | struct device *dev; | ||
40 | int irq; | ||
41 | }; | ||
42 | |||
43 | /* 88PM860x gives us an interrupt when ONKEY is held */ | ||
44 | static irqreturn_t pm860x_onkey_handler(int irq, void *data) | ||
45 | { | ||
46 | struct pm860x_onkey_info *info = data; | ||
47 | int ret; | ||
48 | |||
49 | ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); | ||
50 | ret &= ONKEY_STATUS; | ||
51 | input_report_key(info->idev, KEY_POWER, ret); | ||
52 | input_sync(info->idev); | ||
53 | |||
54 | /* Enable 8-second long onkey detection */ | ||
55 | pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN); | ||
56 | return IRQ_HANDLED; | ||
57 | } | ||
58 | |||
59 | static int __devinit pm860x_onkey_probe(struct platform_device *pdev) | ||
60 | { | ||
61 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
62 | struct pm860x_onkey_info *info; | ||
63 | int irq, ret; | ||
64 | |||
65 | irq = platform_get_irq(pdev, 0); | ||
66 | if (irq < 0) { | ||
67 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | |||
71 | info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL); | ||
72 | if (!info) | ||
73 | return -ENOMEM; | ||
74 | info->chip = chip; | ||
75 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | ||
76 | info->dev = &pdev->dev; | ||
77 | info->irq = irq + chip->irq_base; | ||
78 | |||
79 | info->idev = input_allocate_device(); | ||
80 | if (!info->idev) { | ||
81 | dev_err(chip->dev, "Failed to allocate input dev\n"); | ||
82 | ret = -ENOMEM; | ||
83 | goto out; | ||
84 | } | ||
85 | |||
86 | info->idev->name = "88pm860x_on"; | ||
87 | info->idev->phys = "88pm860x_on/input0"; | ||
88 | info->idev->id.bustype = BUS_I2C; | ||
89 | info->idev->dev.parent = &pdev->dev; | ||
90 | info->irq = irq; | ||
91 | info->idev->evbit[0] = BIT_MASK(EV_KEY); | ||
92 | info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); | ||
93 | |||
94 | ret = input_register_device(info->idev); | ||
95 | if (ret) { | ||
96 | dev_err(chip->dev, "Can't register input device: %d\n", ret); | ||
97 | goto out_reg; | ||
98 | } | ||
99 | |||
100 | ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler, | ||
101 | IRQF_ONESHOT, "onkey", info); | ||
102 | if (ret < 0) { | ||
103 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
104 | info->irq, ret); | ||
105 | goto out_irq; | ||
106 | } | ||
107 | |||
108 | platform_set_drvdata(pdev, info); | ||
109 | return 0; | ||
110 | |||
111 | out_irq: | ||
112 | input_unregister_device(info->idev); | ||
113 | kfree(info); | ||
114 | return ret; | ||
115 | |||
116 | out_reg: | ||
117 | input_free_device(info->idev); | ||
118 | out: | ||
119 | kfree(info); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | static int __devexit pm860x_onkey_remove(struct platform_device *pdev) | ||
124 | { | ||
125 | struct pm860x_onkey_info *info = platform_get_drvdata(pdev); | ||
126 | |||
127 | free_irq(info->irq, info); | ||
128 | input_unregister_device(info->idev); | ||
129 | kfree(info); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static struct platform_driver pm860x_onkey_driver = { | ||
134 | .driver = { | ||
135 | .name = "88pm860x-onkey", | ||
136 | .owner = THIS_MODULE, | ||
137 | }, | ||
138 | .probe = pm860x_onkey_probe, | ||
139 | .remove = __devexit_p(pm860x_onkey_remove), | ||
140 | }; | ||
141 | |||
142 | static int __init pm860x_onkey_init(void) | ||
143 | { | ||
144 | return platform_driver_register(&pm860x_onkey_driver); | ||
145 | } | ||
146 | module_init(pm860x_onkey_init); | ||
147 | |||
148 | static void __exit pm860x_onkey_exit(void) | ||
149 | { | ||
150 | platform_driver_unregister(&pm860x_onkey_driver); | ||
151 | } | ||
152 | module_exit(pm860x_onkey_exit); | ||
153 | |||
154 | MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver"); | ||
155 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | ||
156 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index a9bb2544b2de..23140a3bb8e0 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -12,6 +12,16 @@ menuconfig INPUT_MISC | |||
12 | 12 | ||
13 | if INPUT_MISC | 13 | if INPUT_MISC |
14 | 14 | ||
15 | config INPUT_88PM860X_ONKEY | ||
16 | tristate "88PM860x ONKEY support" | ||
17 | depends on MFD_88PM860X | ||
18 | help | ||
19 | Support the ONKEY of Marvell 88PM860x PMICs as an input device | ||
20 | reporting power button status. | ||
21 | |||
22 | To compile this driver as a module, choose M here: the module | ||
23 | will be called 88pm860x_onkey. | ||
24 | |||
15 | config INPUT_PCSPKR | 25 | config INPUT_PCSPKR |
16 | tristate "PC Speaker support" | 26 | tristate "PC Speaker support" |
17 | depends on PCSPKR_PLATFORM | 27 | depends on PCSPKR_PLATFORM |
@@ -80,6 +90,7 @@ config INPUT_WISTRON_BTNS | |||
80 | tristate "x86 Wistron laptop button interface" | 90 | tristate "x86 Wistron laptop button interface" |
81 | depends on X86 && !X86_64 | 91 | depends on X86 && !X86_64 |
82 | select INPUT_POLLDEV | 92 | select INPUT_POLLDEV |
93 | select INPUT_SPARSEKMAP | ||
83 | select NEW_LEDS | 94 | select NEW_LEDS |
84 | select LEDS_CLASS | 95 | select LEDS_CLASS |
85 | select CHECK_SIGNATURE | 96 | select CHECK_SIGNATURE |
@@ -203,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON | |||
203 | To compile this driver as a module, choose M here. The module will | 214 | To compile this driver as a module, choose M here. The module will |
204 | be called twl4030_pwrbutton. | 215 | be called twl4030_pwrbutton. |
205 | 216 | ||
217 | config INPUT_TWL4030_VIBRA | ||
218 | tristate "Support for TWL4030 Vibrator" | ||
219 | depends on TWL4030_CORE | ||
220 | select TWL4030_CODEC | ||
221 | select INPUT_FF_MEMLESS | ||
222 | help | ||
223 | This option enables support for TWL4030 Vibrator Driver. | ||
224 | |||
225 | To compile this driver as a module, choose M here. The module will | ||
226 | be called twl4030_vibra. | ||
227 | |||
206 | config INPUT_UINPUT | 228 | config INPUT_UINPUT |
207 | tristate "User level driver support" | 229 | tristate "User level driver support" |
208 | help | 230 | help |
@@ -281,6 +303,7 @@ config INPUT_RB532_BUTTON | |||
281 | config INPUT_DM355EVM | 303 | config INPUT_DM355EVM |
282 | tristate "TI DaVinci DM355 EVM Keypad and IR Remote" | 304 | tristate "TI DaVinci DM355 EVM Keypad and IR Remote" |
283 | depends on MFD_DM355EVM_MSP | 305 | depends on MFD_DM355EVM_MSP |
306 | select INPUT_SPARSEKMAP | ||
284 | help | 307 | help |
285 | Supports the pushbuttons and IR remote used with | 308 | Supports the pushbuttons and IR remote used with |
286 | the DM355 EVM board. | 309 | the DM355 EVM board. |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index a8b84854fb7b..7e95a5d474dc 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o | ||
7 | obj-$(CONFIG_INPUT_APANEL) += apanel.o | 8 | obj-$(CONFIG_INPUT_APANEL) += apanel.o |
8 | obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o | 9 | obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o |
9 | obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o | 10 | obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o |
@@ -25,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o | |||
25 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | 26 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o |
26 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | 27 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o |
27 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o | 28 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o |
29 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o | ||
28 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 30 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
29 | obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o | 31 | obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o |
30 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 32 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c index 71b82434264d..a8d2b8db4e35 100644 --- a/drivers/input/misc/apanel.c +++ b/drivers/input/misc/apanel.c | |||
@@ -149,7 +149,7 @@ static void apanel_shutdown(struct i2c_client *client) | |||
149 | apanel_remove(client); | 149 | apanel_remove(client); |
150 | } | 150 | } |
151 | 151 | ||
152 | static struct i2c_device_id apanel_id[] = { | 152 | static const struct i2c_device_id apanel_id[] = { |
153 | { "fujitsu_apanel", 0 }, | 153 | { "fujitsu_apanel", 0 }, |
154 | { } | 154 | { } |
155 | }; | 155 | }; |
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c index e290fde35e74..e8bbc619f6df 100644 --- a/drivers/input/misc/ati_remote.c +++ b/drivers/input/misc/ati_remote.c | |||
@@ -98,10 +98,12 @@ | |||
98 | * Module and Version Information, Module Parameters | 98 | * Module and Version Information, Module Parameters |
99 | */ | 99 | */ |
100 | 100 | ||
101 | #define ATI_REMOTE_VENDOR_ID 0x0bc7 | 101 | #define ATI_REMOTE_VENDOR_ID 0x0bc7 |
102 | #define ATI_REMOTE_PRODUCT_ID 0x004 | 102 | #define LOLA_REMOTE_PRODUCT_ID 0x0002 |
103 | #define LOLA_REMOTE_PRODUCT_ID 0x002 | 103 | #define LOLA2_REMOTE_PRODUCT_ID 0x0003 |
104 | #define MEDION_REMOTE_PRODUCT_ID 0x006 | 104 | #define ATI_REMOTE_PRODUCT_ID 0x0004 |
105 | #define NVIDIA_REMOTE_PRODUCT_ID 0x0005 | ||
106 | #define MEDION_REMOTE_PRODUCT_ID 0x0006 | ||
105 | 107 | ||
106 | #define DRIVER_VERSION "2.2.1" | 108 | #define DRIVER_VERSION "2.2.1" |
107 | #define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>" | 109 | #define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>" |
@@ -142,8 +144,10 @@ MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec | |||
142 | #define err(format, arg...) printk(KERN_ERR format , ## arg) | 144 | #define err(format, arg...) printk(KERN_ERR format , ## arg) |
143 | 145 | ||
144 | static struct usb_device_id ati_remote_table[] = { | 146 | static struct usb_device_id ati_remote_table[] = { |
145 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) }, | ||
146 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, | 147 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, |
148 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID) }, | ||
149 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) }, | ||
150 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID) }, | ||
147 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) }, | 151 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) }, |
148 | {} /* Terminating entry */ | 152 | {} /* Terminating entry */ |
149 | }; | 153 | }; |
@@ -766,7 +770,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de | |||
766 | ati_remote->interface = interface; | 770 | ati_remote->interface = interface; |
767 | 771 | ||
768 | usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); | 772 | usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); |
769 | strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); | 773 | strlcat(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); |
770 | 774 | ||
771 | if (udev->manufacturer) | 775 | if (udev->manufacturer) |
772 | strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); | 776 | strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); |
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 0501f0e65157..2124b99378bb 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/usb/input.h> | 12 | #include <linux/usb/input.h> |
13 | #include <linux/slab.h> | ||
13 | 14 | ||
14 | #define DRIVER_DESC "ATI/Philips USB RF remote driver" | 15 | #define DRIVER_DESC "ATI/Philips USB RF remote driver" |
15 | #define DRIVER_VERSION "0.3" | 16 | #define DRIVER_VERSION "0.3" |
@@ -474,10 +475,11 @@ static void ati_remote2_complete_key(struct urb *urb) | |||
474 | } | 475 | } |
475 | 476 | ||
476 | static int ati_remote2_getkeycode(struct input_dev *idev, | 477 | static int ati_remote2_getkeycode(struct input_dev *idev, |
477 | int scancode, int *keycode) | 478 | unsigned int scancode, unsigned int *keycode) |
478 | { | 479 | { |
479 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 480 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
480 | int index, mode; | 481 | unsigned int mode; |
482 | int index; | ||
481 | 483 | ||
482 | mode = scancode >> 8; | 484 | mode = scancode >> 8; |
483 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 485 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) |
@@ -491,10 +493,12 @@ static int ati_remote2_getkeycode(struct input_dev *idev, | |||
491 | return 0; | 493 | return 0; |
492 | } | 494 | } |
493 | 495 | ||
494 | static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode) | 496 | static int ati_remote2_setkeycode(struct input_dev *idev, |
497 | unsigned int scancode, unsigned int keycode) | ||
495 | { | 498 | { |
496 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 499 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
497 | int index, mode, old_keycode; | 500 | unsigned int mode, old_keycode; |
501 | int index; | ||
498 | 502 | ||
499 | mode = scancode >> 8; | 503 | mode = scancode >> 8; |
500 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 504 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) |
@@ -504,9 +508,6 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc | |||
504 | if (index < 0) | 508 | if (index < 0) |
505 | return -EINVAL; | 509 | return -EINVAL; |
506 | 510 | ||
507 | if (keycode < KEY_RESERVED || keycode > KEY_MAX) | ||
508 | return -EINVAL; | ||
509 | |||
510 | old_keycode = ar2->keycode[mode][index]; | 511 | old_keycode = ar2->keycode[mode][index]; |
511 | ar2->keycode[mode][index] = keycode; | 512 | ar2->keycode[mode][index] = keycode; |
512 | __set_bit(keycode, idev->keybit); | 513 | __set_bit(keycode, idev->keybit); |
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 1b871917340a..dfaa9a045ed8 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c | |||
@@ -47,7 +47,7 @@ static acpi_status acpi_atlas_button_setup(acpi_handle region_handle, | |||
47 | 47 | ||
48 | static acpi_status acpi_atlas_button_handler(u32 function, | 48 | static acpi_status acpi_atlas_button_handler(u32 function, |
49 | acpi_physical_address address, | 49 | acpi_physical_address address, |
50 | u32 bit_width, acpi_integer *value, | 50 | u32 bit_width, u64 *value, |
51 | void *handler_context, void *region_context) | 51 | void *handler_context, void *region_context) |
52 | { | 52 | { |
53 | acpi_status status; | 53 | acpi_status status; |
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index 690f3fafa03b..4f72bdd69410 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/input.h> | 15 | #include <linux/input.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include <asm/portmux.h> | 18 | #include <asm/portmux.h> |
18 | #include <asm/bfin_rotary.h> | 19 | #include <asm/bfin_rotary.h> |
@@ -247,7 +248,7 @@ static int bfin_rotary_resume(struct device *dev) | |||
247 | return 0; | 248 | return 0; |
248 | } | 249 | } |
249 | 250 | ||
250 | static struct dev_pm_ops bfin_rotary_pm_ops = { | 251 | static const struct dev_pm_ops bfin_rotary_pm_ops = { |
251 | .suspend = bfin_rotary_suspend, | 252 | .suspend = bfin_rotary_suspend, |
252 | .resume = bfin_rotary_resume, | 253 | .resume = bfin_rotary_resume, |
253 | }; | 254 | }; |
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index ee73d7219c92..fd8407a29631 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | #define BUTTONS_POLL_INTERVAL 30 /* msec */ | 27 | #define BUTTONS_POLL_INTERVAL 30 /* msec */ |
27 | #define BUTTONS_COUNT_THRESHOLD 3 | 28 | #define BUTTONS_COUNT_THRESHOLD 3 |
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index f2b67dc81d80..19af682c24fb 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c | |||
@@ -10,7 +10,9 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/slab.h> | ||
13 | #include <linux/input.h> | 14 | #include <linux/input.h> |
15 | #include <linux/input/sparse-keymap.h> | ||
14 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
15 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
16 | 18 | ||
@@ -33,12 +35,8 @@ struct dm355evm_keys { | |||
33 | int irq; | 35 | int irq; |
34 | }; | 36 | }; |
35 | 37 | ||
36 | /* These initial keycodes can be remapped by dm355evm_setkeycode(). */ | 38 | /* These initial keycodes can be remapped */ |
37 | static struct { | 39 | static const struct key_entry dm355evm_keys[] = { |
38 | u16 event; | ||
39 | u16 keycode; | ||
40 | } dm355evm_keys[] = { | ||
41 | |||
42 | /* | 40 | /* |
43 | * Pushbuttons on the EVM board ... note that the labels for these | 41 | * Pushbuttons on the EVM board ... note that the labels for these |
44 | * are SW10/SW11/etc on the PC board. The left/right orientation | 42 | * are SW10/SW11/etc on the PC board. The left/right orientation |
@@ -47,11 +45,11 @@ static struct { | |||
47 | * is to the right. (That is, rotate the board counter-clockwise | 45 | * is to the right. (That is, rotate the board counter-clockwise |
48 | * by 90 degrees from the SW10/etc and "DM355 EVM" labels.) | 46 | * by 90 degrees from the SW10/etc and "DM355 EVM" labels.) |
49 | */ | 47 | */ |
50 | { 0x00d8, KEY_OK, }, /* SW12 */ | 48 | { KE_KEY, 0x00d8, { KEY_OK } }, /* SW12 */ |
51 | { 0x00b8, KEY_UP, }, /* SW13 */ | 49 | { KE_KEY, 0x00b8, { KEY_UP } }, /* SW13 */ |
52 | { 0x00e8, KEY_DOWN, }, /* SW11 */ | 50 | { KE_KEY, 0x00e8, { KEY_DOWN } }, /* SW11 */ |
53 | { 0x0078, KEY_LEFT, }, /* SW14 */ | 51 | { KE_KEY, 0x0078, { KEY_LEFT } }, /* SW14 */ |
54 | { 0x00f0, KEY_RIGHT, }, /* SW10 */ | 52 | { KE_KEY, 0x00f0, { KEY_RIGHT } }, /* SW10 */ |
55 | 53 | ||
56 | /* | 54 | /* |
57 | * IR buttons ... codes assigned to match the universal remote | 55 | * IR buttons ... codes assigned to match the universal remote |
@@ -65,35 +63,35 @@ static struct { | |||
65 | * RC5 codes are 14 bits, with two start bits (0x3 prefix) | 63 | * RC5 codes are 14 bits, with two start bits (0x3 prefix) |
66 | * and a toggle bit (masked out below). | 64 | * and a toggle bit (masked out below). |
67 | */ | 65 | */ |
68 | { 0x300c, KEY_POWER, }, /* NOTE: docs omit this */ | 66 | { KE_KEY, 0x300c, { KEY_POWER } }, /* NOTE: docs omit this */ |
69 | { 0x3000, KEY_NUMERIC_0, }, | 67 | { KE_KEY, 0x3000, { KEY_NUMERIC_0 } }, |
70 | { 0x3001, KEY_NUMERIC_1, }, | 68 | { KE_KEY, 0x3001, { KEY_NUMERIC_1 } }, |
71 | { 0x3002, KEY_NUMERIC_2, }, | 69 | { KE_KEY, 0x3002, { KEY_NUMERIC_2 } }, |
72 | { 0x3003, KEY_NUMERIC_3, }, | 70 | { KE_KEY, 0x3003, { KEY_NUMERIC_3 } }, |
73 | { 0x3004, KEY_NUMERIC_4, }, | 71 | { KE_KEY, 0x3004, { KEY_NUMERIC_4 } }, |
74 | { 0x3005, KEY_NUMERIC_5, }, | 72 | { KE_KEY, 0x3005, { KEY_NUMERIC_5 } }, |
75 | { 0x3006, KEY_NUMERIC_6, }, | 73 | { KE_KEY, 0x3006, { KEY_NUMERIC_6 } }, |
76 | { 0x3007, KEY_NUMERIC_7, }, | 74 | { KE_KEY, 0x3007, { KEY_NUMERIC_7 } }, |
77 | { 0x3008, KEY_NUMERIC_8, }, | 75 | { KE_KEY, 0x3008, { KEY_NUMERIC_8 } }, |
78 | { 0x3009, KEY_NUMERIC_9, }, | 76 | { KE_KEY, 0x3009, { KEY_NUMERIC_9 } }, |
79 | { 0x3022, KEY_ENTER, }, | 77 | { KE_KEY, 0x3022, { KEY_ENTER } }, |
80 | { 0x30ec, KEY_MODE, }, /* "tv/vcr/..." */ | 78 | { KE_KEY, 0x30ec, { KEY_MODE } }, /* "tv/vcr/..." */ |
81 | { 0x300f, KEY_SELECT, }, /* "info" */ | 79 | { KE_KEY, 0x300f, { KEY_SELECT } }, /* "info" */ |
82 | { 0x3020, KEY_CHANNELUP, }, /* "up" */ | 80 | { KE_KEY, 0x3020, { KEY_CHANNELUP } }, /* "up" */ |
83 | { 0x302e, KEY_MENU, }, /* "in/out" */ | 81 | { KE_KEY, 0x302e, { KEY_MENU } }, /* "in/out" */ |
84 | { 0x3011, KEY_VOLUMEDOWN, }, /* "left" */ | 82 | { KE_KEY, 0x3011, { KEY_VOLUMEDOWN } }, /* "left" */ |
85 | { 0x300d, KEY_MUTE, }, /* "ok" */ | 83 | { KE_KEY, 0x300d, { KEY_MUTE } }, /* "ok" */ |
86 | { 0x3010, KEY_VOLUMEUP, }, /* "right" */ | 84 | { KE_KEY, 0x3010, { KEY_VOLUMEUP } }, /* "right" */ |
87 | { 0x301e, KEY_SUBTITLE, }, /* "cc" */ | 85 | { KE_KEY, 0x301e, { KEY_SUBTITLE } }, /* "cc" */ |
88 | { 0x3021, KEY_CHANNELDOWN, }, /* "down" */ | 86 | { KE_KEY, 0x3021, { KEY_CHANNELDOWN } },/* "down" */ |
89 | { 0x3022, KEY_PREVIOUS, }, | 87 | { KE_KEY, 0x3022, { KEY_PREVIOUS } }, |
90 | { 0x3026, KEY_SLEEP, }, | 88 | { KE_KEY, 0x3026, { KEY_SLEEP } }, |
91 | { 0x3172, KEY_REWIND, }, /* NOTE: docs wrongly say 0x30ca */ | 89 | { KE_KEY, 0x3172, { KEY_REWIND } }, /* NOTE: docs wrongly say 0x30ca */ |
92 | { 0x3175, KEY_PLAY, }, | 90 | { KE_KEY, 0x3175, { KEY_PLAY } }, |
93 | { 0x3174, KEY_FASTFORWARD, }, | 91 | { KE_KEY, 0x3174, { KEY_FASTFORWARD } }, |
94 | { 0x3177, KEY_RECORD, }, | 92 | { KE_KEY, 0x3177, { KEY_RECORD } }, |
95 | { 0x3176, KEY_STOP, }, | 93 | { KE_KEY, 0x3176, { KEY_STOP } }, |
96 | { 0x3169, KEY_PAUSE, }, | 94 | { KE_KEY, 0x3169, { KEY_PAUSE } }, |
97 | }; | 95 | }; |
98 | 96 | ||
99 | /* | 97 | /* |
@@ -105,19 +103,18 @@ static struct { | |||
105 | */ | 103 | */ |
106 | static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | 104 | static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) |
107 | { | 105 | { |
108 | struct dm355evm_keys *keys = _keys; | 106 | static u16 last_event; |
109 | int status; | 107 | struct dm355evm_keys *keys = _keys; |
108 | const struct key_entry *ke; | ||
109 | unsigned int keycode; | ||
110 | int status; | ||
111 | u16 event; | ||
110 | 112 | ||
111 | /* For simplicity we ignore INPUT_COUNT and just read | 113 | /* For simplicity we ignore INPUT_COUNT and just read |
112 | * events until we get the "queue empty" indicator. | 114 | * events until we get the "queue empty" indicator. |
113 | * Reading INPUT_LOW decrements the count. | 115 | * Reading INPUT_LOW decrements the count. |
114 | */ | 116 | */ |
115 | for (;;) { | 117 | for (;;) { |
116 | static u16 last_event; | ||
117 | u16 event; | ||
118 | int keycode; | ||
119 | int i; | ||
120 | |||
121 | status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH); | 118 | status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH); |
122 | if (status < 0) { | 119 | if (status < 0) { |
123 | dev_dbg(keys->dev, "input high err %d\n", | 120 | dev_dbg(keys->dev, "input high err %d\n", |
@@ -156,14 +153,9 @@ static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | |||
156 | /* ignore the RC5 toggle bit */ | 153 | /* ignore the RC5 toggle bit */ |
157 | event &= ~0x0800; | 154 | event &= ~0x0800; |
158 | 155 | ||
159 | /* find the key, or leave it as unknown */ | 156 | /* find the key, or report it as unknown */ |
160 | keycode = KEY_UNKNOWN; | 157 | ke = sparse_keymap_entry_from_scancode(keys->input, event); |
161 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) { | 158 | keycode = ke ? ke->keycode : KEY_UNKNOWN; |
162 | if (dm355evm_keys[i].event != event) | ||
163 | continue; | ||
164 | keycode = dm355evm_keys[i].keycode; | ||
165 | break; | ||
166 | } | ||
167 | dev_dbg(keys->dev, | 159 | dev_dbg(keys->dev, |
168 | "input event 0x%04x--> keycode %d\n", | 160 | "input event 0x%04x--> keycode %d\n", |
169 | event, keycode); | 161 | event, keycode); |
@@ -174,36 +166,8 @@ static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | |||
174 | input_report_key(keys->input, keycode, 0); | 166 | input_report_key(keys->input, keycode, 0); |
175 | input_sync(keys->input); | 167 | input_sync(keys->input); |
176 | } | 168 | } |
177 | return IRQ_HANDLED; | ||
178 | } | ||
179 | 169 | ||
180 | static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode) | 170 | return IRQ_HANDLED; |
181 | { | ||
182 | u16 old_keycode; | ||
183 | unsigned i; | ||
184 | |||
185 | if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys)) | ||
186 | return -EINVAL; | ||
187 | |||
188 | old_keycode = dm355evm_keys[index].keycode; | ||
189 | dm355evm_keys[index].keycode = keycode; | ||
190 | set_bit(keycode, dev->keybit); | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) { | ||
193 | if (dm355evm_keys[index].keycode == old_keycode) | ||
194 | goto done; | ||
195 | } | ||
196 | clear_bit(old_keycode, dev->keybit); | ||
197 | done: | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static int dm355evm_getkeycode(struct input_dev *dev, int index, int *keycode) | ||
202 | { | ||
203 | if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys)) | ||
204 | return -EINVAL; | ||
205 | |||
206 | return dm355evm_keys[index].keycode; | ||
207 | } | 171 | } |
208 | 172 | ||
209 | /*----------------------------------------------------------------------*/ | 173 | /*----------------------------------------------------------------------*/ |
@@ -213,7 +177,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) | |||
213 | struct dm355evm_keys *keys; | 177 | struct dm355evm_keys *keys; |
214 | struct input_dev *input; | 178 | struct input_dev *input; |
215 | int status; | 179 | int status; |
216 | int i; | ||
217 | 180 | ||
218 | /* allocate instance struct and input dev */ | 181 | /* allocate instance struct and input dev */ |
219 | keys = kzalloc(sizeof *keys, GFP_KERNEL); | 182 | keys = kzalloc(sizeof *keys, GFP_KERNEL); |
@@ -242,31 +205,30 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) | |||
242 | input->id.product = 0x0355; | 205 | input->id.product = 0x0355; |
243 | input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV); | 206 | input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV); |
244 | 207 | ||
245 | input->evbit[0] = BIT(EV_KEY); | 208 | status = sparse_keymap_setup(input, dm355evm_keys, NULL); |
246 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) | 209 | if (status) |
247 | __set_bit(dm355evm_keys[i].keycode, input->keybit); | 210 | goto fail1; |
248 | |||
249 | input->setkeycode = dm355evm_setkeycode; | ||
250 | input->getkeycode = dm355evm_getkeycode; | ||
251 | 211 | ||
252 | /* REVISIT: flush the event queue? */ | 212 | /* REVISIT: flush the event queue? */ |
253 | 213 | ||
254 | status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq, | 214 | status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq, |
255 | IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys); | 215 | IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys); |
256 | if (status < 0) | 216 | if (status < 0) |
257 | goto fail1; | 217 | goto fail2; |
258 | 218 | ||
259 | /* register */ | 219 | /* register */ |
260 | status = input_register_device(input); | 220 | status = input_register_device(input); |
261 | if (status < 0) | 221 | if (status < 0) |
262 | goto fail2; | 222 | goto fail3; |
263 | 223 | ||
264 | platform_set_drvdata(pdev, keys); | 224 | platform_set_drvdata(pdev, keys); |
265 | 225 | ||
266 | return 0; | 226 | return 0; |
267 | 227 | ||
268 | fail2: | 228 | fail3: |
269 | free_irq(keys->irq, keys); | 229 | free_irq(keys->irq, keys); |
230 | fail2: | ||
231 | sparse_keymap_free(input); | ||
270 | fail1: | 232 | fail1: |
271 | input_free_device(input); | 233 | input_free_device(input); |
272 | kfree(keys); | 234 | kfree(keys); |
@@ -280,6 +242,7 @@ static int __devexit dm355evm_keys_remove(struct platform_device *pdev) | |||
280 | struct dm355evm_keys *keys = platform_get_drvdata(pdev); | 242 | struct dm355evm_keys *keys = platform_get_drvdata(pdev); |
281 | 243 | ||
282 | free_irq(keys->irq, keys); | 244 | free_irq(keys->irq, keys); |
245 | sparse_keymap_free(keys->input); | ||
283 | input_unregister_device(keys->input); | 246 | input_unregister_device(keys->input); |
284 | kfree(keys); | 247 | kfree(keys); |
285 | 248 | ||
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index ea821b546969..ad730e15afc0 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c | |||
@@ -35,7 +35,6 @@ | |||
35 | 35 | ||
36 | #include <linux/hp_sdc.h> | 36 | #include <linux/hp_sdc.h> |
37 | #include <linux/errno.h> | 37 | #include <linux/errno.h> |
38 | #include <linux/smp_lock.h> | ||
39 | #include <linux/types.h> | 38 | #include <linux/types.h> |
40 | #include <linux/init.h> | 39 | #include <linux/init.h> |
41 | #include <linux/module.h> | 40 | #include <linux/module.h> |
@@ -409,7 +408,6 @@ static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait) | |||
409 | 408 | ||
410 | static int hp_sdc_rtc_open(struct inode *inode, struct file *file) | 409 | static int hp_sdc_rtc_open(struct inode *inode, struct file *file) |
411 | { | 410 | { |
412 | cycle_kernel_lock(); | ||
413 | return 0; | 411 | return 0; |
414 | } | 412 | } |
415 | 413 | ||
diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c index 7ea969347ca9..99335c286250 100644 --- a/drivers/input/misc/pcap_keys.c +++ b/drivers/input/misc/pcap_keys.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/mfd/ezx-pcap.h> | 19 | #include <linux/mfd/ezx-pcap.h> |
20 | #include <linux/slab.h> | ||
20 | 21 | ||
21 | struct pcap_keys { | 22 | struct pcap_keys { |
22 | struct pcap_chip *pcap; | 23 | struct pcap_chip *pcap; |
diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c index 039dcb00ebd9..95562735728d 100644 --- a/drivers/input/misc/pcf50633-input.c +++ b/drivers/input/misc/pcf50633-input.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/input.h> | 22 | #include <linux/input.h> |
23 | #include <linux/slab.h> | ||
23 | 24 | ||
24 | #include <linux/mfd/pcf50633/core.h> | 25 | #include <linux/mfd/pcf50633/core.h> |
25 | 26 | ||
@@ -55,7 +56,6 @@ pcf50633_input_irq(int irq, void *data) | |||
55 | static int __devinit pcf50633_input_probe(struct platform_device *pdev) | 56 | static int __devinit pcf50633_input_probe(struct platform_device *pdev) |
56 | { | 57 | { |
57 | struct pcf50633_input *input; | 58 | struct pcf50633_input *input; |
58 | struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data; | ||
59 | struct input_dev *input_dev; | 59 | struct input_dev *input_dev; |
60 | int ret; | 60 | int ret; |
61 | 61 | ||
@@ -71,7 +71,7 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | platform_set_drvdata(pdev, input); | 73 | platform_set_drvdata(pdev, input); |
74 | input->pcf = pdata->pcf; | 74 | input->pcf = dev_to_pcf50633(pdev->dev.parent); |
75 | input->input_dev = input_dev; | 75 | input->input_dev = input_dev; |
76 | 76 | ||
77 | input_dev->name = "PCF50633 PMU events"; | 77 | input_dev->name = "PCF50633 PMU events"; |
@@ -85,9 +85,9 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev) | |||
85 | kfree(input); | 85 | kfree(input); |
86 | return ret; | 86 | return ret; |
87 | } | 87 | } |
88 | pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR, | 88 | pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYR, |
89 | pcf50633_input_irq, input); | 89 | pcf50633_input_irq, input); |
90 | pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF, | 90 | pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYF, |
91 | pcf50633_input_irq, input); | 91 | pcf50633_input_irq, input); |
92 | 92 | ||
93 | return 0; | 93 | return 0; |
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 21cb755a54fb..ea4e1fd12651 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c | |||
@@ -127,7 +127,7 @@ static void pcspkr_shutdown(struct platform_device *dev) | |||
127 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); | 127 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); |
128 | } | 128 | } |
129 | 129 | ||
130 | static struct dev_pm_ops pcspkr_pm_ops = { | 130 | static const struct dev_pm_ops pcspkr_pm_ops = { |
131 | .suspend = pcspkr_suspend, | 131 | .suspend = pcspkr_suspend, |
132 | }; | 132 | }; |
133 | 133 | ||
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index a53c4885fbad..668913d12044 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c | |||
@@ -338,7 +338,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i | |||
338 | pm->input = input_dev; | 338 | pm->input = input_dev; |
339 | 339 | ||
340 | usb_make_path(udev, pm->phys, sizeof(pm->phys)); | 340 | usb_make_path(udev, pm->phys, sizeof(pm->phys)); |
341 | strlcpy(pm->phys, "/input0", sizeof(pm->phys)); | 341 | strlcat(pm->phys, "/input0", sizeof(pm->phys)); |
342 | 342 | ||
343 | spin_lock_init(&pm->lock); | 343 | spin_lock_init(&pm->lock); |
344 | 344 | ||
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 3b9f588fc747..1f8e0108962e 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/rotary_encoder.h> | 24 | #include <linux/rotary_encoder.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | #define DRV_NAME "rotary-encoder" | 27 | #define DRV_NAME "rotary-encoder" |
27 | 28 | ||
@@ -152,6 +153,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
152 | goto exit_unregister_input; | 153 | goto exit_unregister_input; |
153 | } | 154 | } |
154 | 155 | ||
156 | err = gpio_direction_input(pdata->gpio_a); | ||
157 | if (err) { | ||
158 | dev_err(&pdev->dev, "unable to set GPIO %d for input\n", | ||
159 | pdata->gpio_a); | ||
160 | goto exit_unregister_input; | ||
161 | } | ||
162 | |||
155 | err = gpio_request(pdata->gpio_b, DRV_NAME); | 163 | err = gpio_request(pdata->gpio_b, DRV_NAME); |
156 | if (err) { | 164 | if (err) { |
157 | dev_err(&pdev->dev, "unable to request GPIO %d\n", | 165 | dev_err(&pdev->dev, "unable to request GPIO %d\n", |
@@ -159,6 +167,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
159 | goto exit_free_gpio_a; | 167 | goto exit_free_gpio_a; |
160 | } | 168 | } |
161 | 169 | ||
170 | err = gpio_direction_input(pdata->gpio_b); | ||
171 | if (err) { | ||
172 | dev_err(&pdev->dev, "unable to set GPIO %d for input\n", | ||
173 | pdata->gpio_b); | ||
174 | goto exit_free_gpio_a; | ||
175 | } | ||
176 | |||
162 | /* request the IRQs */ | 177 | /* request the IRQs */ |
163 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, | 178 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, |
164 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | 179 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, |
diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c index be3a15f5b25d..1a80c0dab83b 100644 --- a/drivers/input/misc/sgi_btns.c +++ b/drivers/input/misc/sgi_btns.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | #ifdef CONFIG_SGI_IP22 | 27 | #ifdef CONFIG_SGI_IP22 |
27 | #include <asm/sgi/ioc.h> | 28 | #include <asm/sgi/ioc.h> |
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index b064419b90a2..0d45422f8095 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/input.h> | 10 | #include <linux/input.h> |
11 | #include <linux/of_device.h> | 11 | #include <linux/of_device.h> |
12 | #include <linux/slab.h> | ||
12 | 13 | ||
13 | #include <asm/io.h> | 14 | #include <asm/io.h> |
14 | 15 | ||
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index f5fc9974a111..e9069b87fde2 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/input.h> | 27 | #include <linux/input.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/i2c/twl4030.h> | 30 | #include <linux/i2c/twl.h> |
31 | 31 | ||
32 | #define PWR_PWRON_IRQ (1 << 0) | 32 | #define PWR_PWRON_IRQ (1 << 0) |
33 | 33 | ||
@@ -39,18 +39,8 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr) | |||
39 | int err; | 39 | int err; |
40 | u8 value; | 40 | u8 value; |
41 | 41 | ||
42 | #ifdef CONFIG_LOCKDEP | 42 | err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value, |
43 | /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which | 43 | STS_HW_CONDITIONS); |
44 | * we don't want and can't tolerate since this is a threaded | ||
45 | * IRQ and can sleep due to the i2c reads it has to issue. | ||
46 | * Although it might be friendlier not to borrow this thread | ||
47 | * context... | ||
48 | */ | ||
49 | local_irq_enable(); | ||
50 | #endif | ||
51 | |||
52 | err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value, | ||
53 | STS_HW_CONDITIONS); | ||
54 | if (!err) { | 44 | if (!err) { |
55 | input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); | 45 | input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); |
56 | input_sync(pwr); | 46 | input_sync(pwr); |
@@ -80,7 +70,7 @@ static int __devinit twl4030_pwrbutton_probe(struct platform_device *pdev) | |||
80 | pwr->phys = "twl4030_pwrbutton/input0"; | 70 | pwr->phys = "twl4030_pwrbutton/input0"; |
81 | pwr->dev.parent = &pdev->dev; | 71 | pwr->dev.parent = &pdev->dev; |
82 | 72 | ||
83 | err = request_irq(irq, powerbutton_irq, | 73 | err = request_threaded_irq(irq, NULL, powerbutton_irq, |
84 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 74 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, |
85 | "twl4030_pwrbutton", pwr); | 75 | "twl4030_pwrbutton", pwr); |
86 | if (err < 0) { | 76 | if (err < 0) { |
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c new file mode 100644 index 000000000000..fee9eac8e04a --- /dev/null +++ b/drivers/input/misc/twl4030-vibra.c | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * twl4030-vibra.c - TWL4030 Vibrator driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Nokia Corporation | ||
5 | * | ||
6 | * Written by Henrik Saari <henrik.saari@nokia.com> | ||
7 | * Updates by Felipe Balbi <felipe.balbi@nokia.com> | ||
8 | * Input by Jari Vanhala <ext-jari.vanhala@nokia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
22 | * 02110-1301 USA | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/jiffies.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/workqueue.h> | ||
30 | #include <linux/i2c/twl.h> | ||
31 | #include <linux/mfd/twl4030-codec.h> | ||
32 | #include <linux/input.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | /* MODULE ID2 */ | ||
36 | #define LEDEN 0x00 | ||
37 | |||
38 | /* ForceFeedback */ | ||
39 | #define EFFECT_DIR_180_DEG 0x8000 /* range is 0 - 0xFFFF */ | ||
40 | |||
41 | struct vibra_info { | ||
42 | struct device *dev; | ||
43 | struct input_dev *input_dev; | ||
44 | |||
45 | struct workqueue_struct *workqueue; | ||
46 | struct work_struct play_work; | ||
47 | |||
48 | bool enabled; | ||
49 | int speed; | ||
50 | int direction; | ||
51 | |||
52 | bool coexist; | ||
53 | }; | ||
54 | |||
55 | static void vibra_disable_leds(void) | ||
56 | { | ||
57 | u8 reg; | ||
58 | |||
59 | /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */ | ||
60 | twl_i2c_read_u8(TWL4030_MODULE_LED, ®, LEDEN); | ||
61 | reg &= ~0x03; | ||
62 | twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg); | ||
63 | } | ||
64 | |||
65 | /* Powers H-Bridge and enables audio clk */ | ||
66 | static void vibra_enable(struct vibra_info *info) | ||
67 | { | ||
68 | u8 reg; | ||
69 | |||
70 | twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER); | ||
71 | |||
72 | /* turn H-Bridge on */ | ||
73 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
74 | ®, TWL4030_REG_VIBRA_CTL); | ||
75 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
76 | (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); | ||
77 | |||
78 | twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); | ||
79 | |||
80 | info->enabled = true; | ||
81 | } | ||
82 | |||
83 | static void vibra_disable(struct vibra_info *info) | ||
84 | { | ||
85 | u8 reg; | ||
86 | |||
87 | /* Power down H-Bridge */ | ||
88 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
89 | ®, TWL4030_REG_VIBRA_CTL); | ||
90 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
91 | (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); | ||
92 | |||
93 | twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); | ||
94 | twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); | ||
95 | |||
96 | info->enabled = false; | ||
97 | } | ||
98 | |||
99 | static void vibra_play_work(struct work_struct *work) | ||
100 | { | ||
101 | struct vibra_info *info = container_of(work, | ||
102 | struct vibra_info, play_work); | ||
103 | int dir; | ||
104 | int pwm; | ||
105 | u8 reg; | ||
106 | |||
107 | dir = info->direction; | ||
108 | pwm = info->speed; | ||
109 | |||
110 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
111 | ®, TWL4030_REG_VIBRA_CTL); | ||
112 | if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) { | ||
113 | |||
114 | if (!info->enabled) | ||
115 | vibra_enable(info); | ||
116 | |||
117 | /* set vibra rotation direction */ | ||
118 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
119 | ®, TWL4030_REG_VIBRA_CTL); | ||
120 | reg = (dir) ? (reg | TWL4030_VIBRA_DIR) : | ||
121 | (reg & ~TWL4030_VIBRA_DIR); | ||
122 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
123 | reg, TWL4030_REG_VIBRA_CTL); | ||
124 | |||
125 | /* set PWM, 1 = max, 255 = min */ | ||
126 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
127 | 256 - pwm, TWL4030_REG_VIBRA_SET); | ||
128 | } else { | ||
129 | if (info->enabled) | ||
130 | vibra_disable(info); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | /*** Input/ForceFeedback ***/ | ||
135 | |||
136 | static int vibra_play(struct input_dev *input, void *data, | ||
137 | struct ff_effect *effect) | ||
138 | { | ||
139 | struct vibra_info *info = input_get_drvdata(input); | ||
140 | |||
141 | info->speed = effect->u.rumble.strong_magnitude >> 8; | ||
142 | if (!info->speed) | ||
143 | info->speed = effect->u.rumble.weak_magnitude >> 9; | ||
144 | info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1; | ||
145 | queue_work(info->workqueue, &info->play_work); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int twl4030_vibra_open(struct input_dev *input) | ||
150 | { | ||
151 | struct vibra_info *info = input_get_drvdata(input); | ||
152 | |||
153 | info->workqueue = create_singlethread_workqueue("vibra"); | ||
154 | if (info->workqueue == NULL) { | ||
155 | dev_err(&input->dev, "couldn't create workqueue\n"); | ||
156 | return -ENOMEM; | ||
157 | } | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static void twl4030_vibra_close(struct input_dev *input) | ||
162 | { | ||
163 | struct vibra_info *info = input_get_drvdata(input); | ||
164 | |||
165 | cancel_work_sync(&info->play_work); | ||
166 | INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */ | ||
167 | destroy_workqueue(info->workqueue); | ||
168 | info->workqueue = NULL; | ||
169 | |||
170 | if (info->enabled) | ||
171 | vibra_disable(info); | ||
172 | } | ||
173 | |||
174 | /*** Module ***/ | ||
175 | #if CONFIG_PM | ||
176 | static int twl4030_vibra_suspend(struct device *dev) | ||
177 | { | ||
178 | struct platform_device *pdev = to_platform_device(dev); | ||
179 | struct vibra_info *info = platform_get_drvdata(pdev); | ||
180 | |||
181 | if (info->enabled) | ||
182 | vibra_disable(info); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int twl4030_vibra_resume(struct device *dev) | ||
188 | { | ||
189 | vibra_disable_leds(); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, | ||
194 | twl4030_vibra_suspend, twl4030_vibra_resume); | ||
195 | #endif | ||
196 | |||
197 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) | ||
198 | { | ||
199 | struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; | ||
200 | struct vibra_info *info; | ||
201 | int ret; | ||
202 | |||
203 | if (!pdata) { | ||
204 | dev_dbg(&pdev->dev, "platform_data not available\n"); | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
209 | if (!info) | ||
210 | return -ENOMEM; | ||
211 | |||
212 | info->dev = &pdev->dev; | ||
213 | info->coexist = pdata->coexist; | ||
214 | INIT_WORK(&info->play_work, vibra_play_work); | ||
215 | |||
216 | info->input_dev = input_allocate_device(); | ||
217 | if (info->input_dev == NULL) { | ||
218 | dev_err(&pdev->dev, "couldn't allocate input device\n"); | ||
219 | ret = -ENOMEM; | ||
220 | goto err_kzalloc; | ||
221 | } | ||
222 | |||
223 | input_set_drvdata(info->input_dev, info); | ||
224 | |||
225 | info->input_dev->name = "twl4030:vibrator"; | ||
226 | info->input_dev->id.version = 1; | ||
227 | info->input_dev->dev.parent = pdev->dev.parent; | ||
228 | info->input_dev->open = twl4030_vibra_open; | ||
229 | info->input_dev->close = twl4030_vibra_close; | ||
230 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); | ||
231 | |||
232 | ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); | ||
233 | if (ret < 0) { | ||
234 | dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); | ||
235 | goto err_ialloc; | ||
236 | } | ||
237 | |||
238 | ret = input_register_device(info->input_dev); | ||
239 | if (ret < 0) { | ||
240 | dev_dbg(&pdev->dev, "couldn't register input device\n"); | ||
241 | goto err_iff; | ||
242 | } | ||
243 | |||
244 | vibra_disable_leds(); | ||
245 | |||
246 | platform_set_drvdata(pdev, info); | ||
247 | return 0; | ||
248 | |||
249 | err_iff: | ||
250 | input_ff_destroy(info->input_dev); | ||
251 | err_ialloc: | ||
252 | input_free_device(info->input_dev); | ||
253 | err_kzalloc: | ||
254 | kfree(info); | ||
255 | return ret; | ||
256 | } | ||
257 | |||
258 | static int __devexit twl4030_vibra_remove(struct platform_device *pdev) | ||
259 | { | ||
260 | struct vibra_info *info = platform_get_drvdata(pdev); | ||
261 | |||
262 | /* this also free ff-memless and calls close if needed */ | ||
263 | input_unregister_device(info->input_dev); | ||
264 | kfree(info); | ||
265 | platform_set_drvdata(pdev, NULL); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static struct platform_driver twl4030_vibra_driver = { | ||
271 | .probe = twl4030_vibra_probe, | ||
272 | .remove = __devexit_p(twl4030_vibra_remove), | ||
273 | .driver = { | ||
274 | .name = "twl4030_codec_vibra", | ||
275 | .owner = THIS_MODULE, | ||
276 | #ifdef CONFIG_PM | ||
277 | .pm = &twl4030_vibra_pm_ops, | ||
278 | #endif | ||
279 | }, | ||
280 | }; | ||
281 | |||
282 | static int __init twl4030_vibra_init(void) | ||
283 | { | ||
284 | return platform_driver_register(&twl4030_vibra_driver); | ||
285 | } | ||
286 | module_init(twl4030_vibra_init); | ||
287 | |||
288 | static void __exit twl4030_vibra_exit(void) | ||
289 | { | ||
290 | platform_driver_unregister(&twl4030_vibra_driver); | ||
291 | } | ||
292 | module_exit(twl4030_vibra_exit); | ||
293 | |||
294 | MODULE_ALIAS("platform:twl4030_codec_vibra"); | ||
295 | |||
296 | MODULE_DESCRIPTION("TWL4030 Vibra driver"); | ||
297 | MODULE_LICENSE("GPL"); | ||
298 | MODULE_AUTHOR("Nokia Corporation"); | ||
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index d3f57245420a..1477466076ad 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/fs.h> | 37 | #include <linux/fs.h> |
39 | #include <linux/miscdevice.h> | 38 | #include <linux/miscdevice.h> |
40 | #include <linux/uinput.h> | 39 | #include <linux/uinput.h> |
@@ -284,7 +283,6 @@ static int uinput_open(struct inode *inode, struct file *file) | |||
284 | if (!newdev) | 283 | if (!newdev) |
285 | return -ENOMEM; | 284 | return -ENOMEM; |
286 | 285 | ||
287 | lock_kernel(); | ||
288 | mutex_init(&newdev->mutex); | 286 | mutex_init(&newdev->mutex); |
289 | spin_lock_init(&newdev->requests_lock); | 287 | spin_lock_init(&newdev->requests_lock); |
290 | init_waitqueue_head(&newdev->requests_waitq); | 288 | init_waitqueue_head(&newdev->requests_waitq); |
@@ -292,7 +290,7 @@ static int uinput_open(struct inode *inode, struct file *file) | |||
292 | newdev->state = UIST_NEW_DEVICE; | 290 | newdev->state = UIST_NEW_DEVICE; |
293 | 291 | ||
294 | file->private_data = newdev; | 292 | file->private_data = newdev; |
295 | unlock_kernel(); | 293 | nonseekable_open(inode, file); |
296 | 294 | ||
297 | return 0; | 295 | return 0; |
298 | } | 296 | } |
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c index 33309fe44e20..64f1de7960c6 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/input/misc/winbond-cir.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/io.h> | 56 | #include <linux/io.h> |
57 | #include <linux/bitrev.h> | 57 | #include <linux/bitrev.h> |
58 | #include <linux/bitops.h> | 58 | #include <linux/bitops.h> |
59 | #include <linux/slab.h> | ||
59 | 60 | ||
60 | #define DRVNAME "winbond-cir" | 61 | #define DRVNAME "winbond-cir" |
61 | 62 | ||
@@ -385,26 +386,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode) | |||
385 | } | 386 | } |
386 | 387 | ||
387 | static int | 388 | static int |
388 | wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 389 | wbcir_getkeycode(struct input_dev *dev, |
390 | unsigned int scancode, unsigned int *keycode) | ||
389 | { | 391 | { |
390 | struct wbcir_data *data = input_get_drvdata(dev); | 392 | struct wbcir_data *data = input_get_drvdata(dev); |
391 | 393 | ||
392 | *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode); | 394 | *keycode = wbcir_do_getkeycode(data, scancode); |
393 | return 0; | 395 | return 0; |
394 | } | 396 | } |
395 | 397 | ||
396 | static int | 398 | static int |
397 | wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode) | 399 | wbcir_setkeycode(struct input_dev *dev, |
400 | unsigned int scancode, unsigned int keycode) | ||
398 | { | 401 | { |
399 | struct wbcir_data *data = input_get_drvdata(dev); | 402 | struct wbcir_data *data = input_get_drvdata(dev); |
400 | struct wbcir_keyentry *keyentry; | 403 | struct wbcir_keyentry *keyentry; |
401 | struct wbcir_keyentry *new_keyentry; | 404 | struct wbcir_keyentry *new_keyentry; |
402 | unsigned long flags; | 405 | unsigned long flags; |
403 | unsigned int old_keycode = KEY_RESERVED; | 406 | unsigned int old_keycode = KEY_RESERVED; |
404 | u32 scancode = (u32)sscancode; | ||
405 | |||
406 | if (keycode < 0 || keycode > KEY_MAX) | ||
407 | return -EINVAL; | ||
408 | 407 | ||
409 | new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); | 408 | new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); |
410 | if (!new_keyentry) | 409 | if (!new_keyentry) |
@@ -538,6 +537,7 @@ wbcir_reset_irdata(struct wbcir_data *data) | |||
538 | data->irdata_count = 0; | 537 | data->irdata_count = 0; |
539 | data->irdata_off = 0; | 538 | data->irdata_off = 0; |
540 | data->irdata_error = 0; | 539 | data->irdata_error = 0; |
540 | data->idle_count = 0; | ||
541 | } | 541 | } |
542 | 542 | ||
543 | /* Adds one bit of irdata */ | 543 | /* Adds one bit of irdata */ |
@@ -768,7 +768,7 @@ wbcir_parse_rc6(struct device *dev, struct wbcir_data *data) | |||
768 | return; | 768 | return; |
769 | } | 769 | } |
770 | 770 | ||
771 | dev_info(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " | 771 | dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " |
772 | "toggle %u mode %u scan 0x%08X\n", | 772 | "toggle %u mode %u scan 0x%08X\n", |
773 | address, | 773 | address, |
774 | command, | 774 | command, |
@@ -1006,7 +1006,6 @@ wbcir_irq_handler(int irqno, void *cookie) | |||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | wbcir_reset_irdata(data); | 1008 | wbcir_reset_irdata(data); |
1009 | data->idle_count = 0; | ||
1010 | } | 1009 | } |
1011 | 1010 | ||
1012 | out: | 1011 | out: |
@@ -1018,7 +1017,7 @@ out: | |||
1018 | 1017 | ||
1019 | /***************************************************************************** | 1018 | /***************************************************************************** |
1020 | * | 1019 | * |
1021 | * SUSPEND/RESUME FUNCTIONS | 1020 | * SETUP/INIT/SUSPEND/RESUME FUNCTIONS |
1022 | * | 1021 | * |
1023 | *****************************************************************************/ | 1022 | *****************************************************************************/ |
1024 | 1023 | ||
@@ -1197,7 +1196,16 @@ finish: | |||
1197 | } | 1196 | } |
1198 | 1197 | ||
1199 | /* Disable interrupts */ | 1198 | /* Disable interrupts */ |
1199 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1200 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | 1200 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); |
1201 | |||
1202 | /* | ||
1203 | * ACPI will set the HW disable bit for SP3 which means that the | ||
1204 | * output signals are left in an undefined state which may cause | ||
1205 | * spurious interrupts which we need to ignore until the hardware | ||
1206 | * is reinitialized. | ||
1207 | */ | ||
1208 | disable_irq(data->irq); | ||
1201 | } | 1209 | } |
1202 | 1210 | ||
1203 | static int | 1211 | static int |
@@ -1207,37 +1215,15 @@ wbcir_suspend(struct pnp_dev *device, pm_message_t state) | |||
1207 | return 0; | 1215 | return 0; |
1208 | } | 1216 | } |
1209 | 1217 | ||
1210 | static int | ||
1211 | wbcir_resume(struct pnp_dev *device) | ||
1212 | { | ||
1213 | struct wbcir_data *data = pnp_get_drvdata(device); | ||
1214 | |||
1215 | /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ | ||
1216 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); | ||
1217 | |||
1218 | /* Clear CEIR_EN */ | ||
1219 | wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); | ||
1220 | |||
1221 | /* Enable interrupts */ | ||
1222 | wbcir_reset_irdata(data); | ||
1223 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); | ||
1224 | |||
1225 | return 0; | ||
1226 | } | ||
1227 | |||
1228 | |||
1229 | |||
1230 | /***************************************************************************** | ||
1231 | * | ||
1232 | * SETUP/INIT FUNCTIONS | ||
1233 | * | ||
1234 | *****************************************************************************/ | ||
1235 | |||
1236 | static void | 1218 | static void |
1237 | wbcir_cfg_ceir(struct wbcir_data *data) | 1219 | wbcir_init_hw(struct wbcir_data *data) |
1238 | { | 1220 | { |
1239 | u8 tmp; | 1221 | u8 tmp; |
1240 | 1222 | ||
1223 | /* Disable interrupts */ | ||
1224 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1225 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | ||
1226 | |||
1241 | /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ | 1227 | /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ |
1242 | tmp = protocol << 4; | 1228 | tmp = protocol << 4; |
1243 | if (invert) | 1229 | if (invert) |
@@ -1264,6 +1250,93 @@ wbcir_cfg_ceir(struct wbcir_data *data) | |||
1264 | * set SP3_IRRX_SW to binary 01, helpfully not documented | 1250 | * set SP3_IRRX_SW to binary 01, helpfully not documented |
1265 | */ | 1251 | */ |
1266 | outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); | 1252 | outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); |
1253 | |||
1254 | /* Enable extended mode */ | ||
1255 | wbcir_select_bank(data, WBCIR_BANK_2); | ||
1256 | outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); | ||
1257 | |||
1258 | /* | ||
1259 | * Configure baud generator, IR data will be sampled at | ||
1260 | * a bitrate of: (24Mhz * prescaler) / (divisor * 16). | ||
1261 | * | ||
1262 | * The ECIR registers include a flag to change the | ||
1263 | * 24Mhz clock freq to 48Mhz. | ||
1264 | * | ||
1265 | * It's not documented in the specs, but fifo levels | ||
1266 | * other than 16 seems to be unsupported. | ||
1267 | */ | ||
1268 | |||
1269 | /* prescaler 1.0, tx/rx fifo lvl 16 */ | ||
1270 | outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); | ||
1271 | |||
1272 | /* Set baud divisor to generate one byte per bit/cell */ | ||
1273 | switch (protocol) { | ||
1274 | case IR_PROTOCOL_RC5: | ||
1275 | outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1276 | break; | ||
1277 | case IR_PROTOCOL_RC6: | ||
1278 | outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1279 | break; | ||
1280 | case IR_PROTOCOL_NEC: | ||
1281 | outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1282 | break; | ||
1283 | } | ||
1284 | outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); | ||
1285 | |||
1286 | /* Set CEIR mode */ | ||
1287 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1288 | outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); | ||
1289 | inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ | ||
1290 | inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ | ||
1291 | |||
1292 | /* Disable RX demod, run-length encoding/decoding, set freq span */ | ||
1293 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1294 | outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); | ||
1295 | |||
1296 | /* Disable timer */ | ||
1297 | wbcir_select_bank(data, WBCIR_BANK_4); | ||
1298 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); | ||
1299 | |||
1300 | /* Enable MSR interrupt, Clear AUX_IRX */ | ||
1301 | wbcir_select_bank(data, WBCIR_BANK_5); | ||
1302 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); | ||
1303 | |||
1304 | /* Disable CRC */ | ||
1305 | wbcir_select_bank(data, WBCIR_BANK_6); | ||
1306 | outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); | ||
1307 | |||
1308 | /* Set RX/TX (de)modulation freq, not really used */ | ||
1309 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1310 | outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); | ||
1311 | outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); | ||
1312 | |||
1313 | /* Set invert and pin direction */ | ||
1314 | if (invert) | ||
1315 | outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1316 | else | ||
1317 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1318 | |||
1319 | /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ | ||
1320 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1321 | outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); | ||
1322 | |||
1323 | /* Clear AUX status bits */ | ||
1324 | outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); | ||
1325 | |||
1326 | /* Enable interrupts */ | ||
1327 | wbcir_reset_irdata(data); | ||
1328 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); | ||
1329 | } | ||
1330 | |||
1331 | static int | ||
1332 | wbcir_resume(struct pnp_dev *device) | ||
1333 | { | ||
1334 | struct wbcir_data *data = pnp_get_drvdata(device); | ||
1335 | |||
1336 | wbcir_init_hw(data); | ||
1337 | enable_irq(data->irq); | ||
1338 | |||
1339 | return 0; | ||
1267 | } | 1340 | } |
1268 | 1341 | ||
1269 | static int __devinit | 1342 | static int __devinit |
@@ -1393,86 +1466,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) | |||
1393 | 1466 | ||
1394 | device_init_wakeup(&device->dev, 1); | 1467 | device_init_wakeup(&device->dev, 1); |
1395 | 1468 | ||
1396 | wbcir_cfg_ceir(data); | 1469 | wbcir_init_hw(data); |
1397 | |||
1398 | /* Disable interrupts */ | ||
1399 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1400 | outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); | ||
1401 | |||
1402 | /* Enable extended mode */ | ||
1403 | wbcir_select_bank(data, WBCIR_BANK_2); | ||
1404 | outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); | ||
1405 | |||
1406 | /* | ||
1407 | * Configure baud generator, IR data will be sampled at | ||
1408 | * a bitrate of: (24Mhz * prescaler) / (divisor * 16). | ||
1409 | * | ||
1410 | * The ECIR registers include a flag to change the | ||
1411 | * 24Mhz clock freq to 48Mhz. | ||
1412 | * | ||
1413 | * It's not documented in the specs, but fifo levels | ||
1414 | * other than 16 seems to be unsupported. | ||
1415 | */ | ||
1416 | |||
1417 | /* prescaler 1.0, tx/rx fifo lvl 16 */ | ||
1418 | outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); | ||
1419 | |||
1420 | /* Set baud divisor to generate one byte per bit/cell */ | ||
1421 | switch (protocol) { | ||
1422 | case IR_PROTOCOL_RC5: | ||
1423 | outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1424 | break; | ||
1425 | case IR_PROTOCOL_RC6: | ||
1426 | outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1427 | break; | ||
1428 | case IR_PROTOCOL_NEC: | ||
1429 | outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); | ||
1430 | break; | ||
1431 | } | ||
1432 | outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); | ||
1433 | |||
1434 | /* Set CEIR mode */ | ||
1435 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1436 | outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); | ||
1437 | inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ | ||
1438 | inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ | ||
1439 | |||
1440 | /* Disable RX demod, run-length encoding/decoding, set freq span */ | ||
1441 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1442 | outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); | ||
1443 | |||
1444 | /* Disable timer */ | ||
1445 | wbcir_select_bank(data, WBCIR_BANK_4); | ||
1446 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); | ||
1447 | |||
1448 | /* Enable MSR interrupt, Clear AUX_IRX */ | ||
1449 | wbcir_select_bank(data, WBCIR_BANK_5); | ||
1450 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); | ||
1451 | |||
1452 | /* Disable CRC */ | ||
1453 | wbcir_select_bank(data, WBCIR_BANK_6); | ||
1454 | outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); | ||
1455 | |||
1456 | /* Set RX/TX (de)modulation freq, not really used */ | ||
1457 | wbcir_select_bank(data, WBCIR_BANK_7); | ||
1458 | outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); | ||
1459 | outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); | ||
1460 | |||
1461 | /* Set invert and pin direction */ | ||
1462 | if (invert) | ||
1463 | outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1464 | else | ||
1465 | outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); | ||
1466 | |||
1467 | /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ | ||
1468 | wbcir_select_bank(data, WBCIR_BANK_0); | ||
1469 | outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); | ||
1470 | |||
1471 | /* Clear AUX status bits */ | ||
1472 | outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); | ||
1473 | |||
1474 | /* Enable interrupts */ | ||
1475 | outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); | ||
1476 | 1470 | ||
1477 | return 0; | 1471 | return 0; |
1478 | 1472 | ||
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index a932179c4c9e..04d5a4a3181f 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/dmi.h> | 21 | #include <linux/dmi.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/input-polldev.h> | 23 | #include <linux/input-polldev.h> |
24 | #include <linux/input/sparse-keymap.h> | ||
24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
25 | #include <linux/jiffies.h> | 26 | #include <linux/jiffies.h> |
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -28,6 +29,7 @@ | |||
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
29 | #include <linux/preempt.h> | 30 | #include <linux/preempt.h> |
30 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/slab.h> | ||
31 | #include <linux/types.h> | 33 | #include <linux/types.h> |
32 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
33 | #include <linux/leds.h> | 35 | #include <linux/leds.h> |
@@ -224,19 +226,8 @@ static void bios_set_state(u8 subsys, int enable) | |||
224 | 226 | ||
225 | /* Hardware database */ | 227 | /* Hardware database */ |
226 | 228 | ||
227 | struct key_entry { | 229 | #define KE_WIFI (KE_LAST + 1) |
228 | char type; /* See KE_* below */ | 230 | #define KE_BLUETOOTH (KE_LAST + 2) |
229 | u8 code; | ||
230 | union { | ||
231 | u16 keycode; /* For KE_KEY */ | ||
232 | struct { /* For KE_SW */ | ||
233 | u8 code; | ||
234 | u8 value; | ||
235 | } sw; | ||
236 | }; | ||
237 | }; | ||
238 | |||
239 | enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; | ||
240 | 231 | ||
241 | #define FE_MAIL_LED 0x01 | 232 | #define FE_MAIL_LED 0x01 |
242 | #define FE_WIFI_LED 0x02 | 233 | #define FE_WIFI_LED 0x02 |
@@ -644,10 +635,10 @@ static struct key_entry keymap_prestigio[] __initdata = { | |||
644 | * a list of buttons and their key codes (reported when loading this module | 635 | * a list of buttons and their key codes (reported when loading this module |
645 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. | 636 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. |
646 | */ | 637 | */ |
647 | static struct dmi_system_id dmi_ids[] __initdata = { | 638 | static const struct dmi_system_id __initconst dmi_ids[] = { |
648 | { | 639 | { |
640 | /* Fujitsu-Siemens Amilo Pro V2000 */ | ||
649 | .callback = dmi_matched, | 641 | .callback = dmi_matched, |
650 | .ident = "Fujitsu-Siemens Amilo Pro V2000", | ||
651 | .matches = { | 642 | .matches = { |
652 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 643 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
653 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"), | 644 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"), |
@@ -655,8 +646,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
655 | .driver_data = keymap_fs_amilo_pro_v2000 | 646 | .driver_data = keymap_fs_amilo_pro_v2000 |
656 | }, | 647 | }, |
657 | { | 648 | { |
649 | /* Fujitsu-Siemens Amilo Pro Edition V3505 */ | ||
658 | .callback = dmi_matched, | 650 | .callback = dmi_matched, |
659 | .ident = "Fujitsu-Siemens Amilo Pro Edition V3505", | ||
660 | .matches = { | 651 | .matches = { |
661 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 652 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
662 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"), | 653 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"), |
@@ -664,8 +655,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
664 | .driver_data = keymap_fs_amilo_pro_v3505 | 655 | .driver_data = keymap_fs_amilo_pro_v3505 |
665 | }, | 656 | }, |
666 | { | 657 | { |
658 | /* Fujitsu-Siemens Amilo M7400 */ | ||
667 | .callback = dmi_matched, | 659 | .callback = dmi_matched, |
668 | .ident = "Fujitsu-Siemens Amilo M7400", | ||
669 | .matches = { | 660 | .matches = { |
670 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 661 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
671 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), | 662 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), |
@@ -673,8 +664,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
673 | .driver_data = keymap_fs_amilo_pro_v2000 | 664 | .driver_data = keymap_fs_amilo_pro_v2000 |
674 | }, | 665 | }, |
675 | { | 666 | { |
667 | /* Maxdata Pro 7000 DX */ | ||
676 | .callback = dmi_matched, | 668 | .callback = dmi_matched, |
677 | .ident = "Maxdata Pro 7000 DX", | ||
678 | .matches = { | 669 | .matches = { |
679 | DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), | 670 | DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), |
680 | DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), | 671 | DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), |
@@ -682,8 +673,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
682 | .driver_data = keymap_fs_amilo_pro_v2000 | 673 | .driver_data = keymap_fs_amilo_pro_v2000 |
683 | }, | 674 | }, |
684 | { | 675 | { |
676 | /* Fujitsu N3510 */ | ||
685 | .callback = dmi_matched, | 677 | .callback = dmi_matched, |
686 | .ident = "Fujitsu N3510", | ||
687 | .matches = { | 678 | .matches = { |
688 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 679 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
689 | DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), | 680 | DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), |
@@ -691,8 +682,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
691 | .driver_data = keymap_fujitsu_n3510 | 682 | .driver_data = keymap_fujitsu_n3510 |
692 | }, | 683 | }, |
693 | { | 684 | { |
685 | /* Acer Aspire 1500 */ | ||
694 | .callback = dmi_matched, | 686 | .callback = dmi_matched, |
695 | .ident = "Acer Aspire 1500", | ||
696 | .matches = { | 687 | .matches = { |
697 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 688 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
698 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), | 689 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), |
@@ -700,8 +691,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
700 | .driver_data = keymap_acer_aspire_1500 | 691 | .driver_data = keymap_acer_aspire_1500 |
701 | }, | 692 | }, |
702 | { | 693 | { |
694 | /* Acer Aspire 1600 */ | ||
703 | .callback = dmi_matched, | 695 | .callback = dmi_matched, |
704 | .ident = "Acer Aspire 1600", | ||
705 | .matches = { | 696 | .matches = { |
706 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 697 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
707 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), | 698 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), |
@@ -709,8 +700,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
709 | .driver_data = keymap_acer_aspire_1600 | 700 | .driver_data = keymap_acer_aspire_1600 |
710 | }, | 701 | }, |
711 | { | 702 | { |
703 | /* Acer Aspire 3020 */ | ||
712 | .callback = dmi_matched, | 704 | .callback = dmi_matched, |
713 | .ident = "Acer Aspire 3020", | ||
714 | .matches = { | 705 | .matches = { |
715 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 706 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
716 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), | 707 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), |
@@ -718,8 +709,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
718 | .driver_data = keymap_acer_aspire_5020 | 709 | .driver_data = keymap_acer_aspire_5020 |
719 | }, | 710 | }, |
720 | { | 711 | { |
712 | /* Acer Aspire 5020 */ | ||
721 | .callback = dmi_matched, | 713 | .callback = dmi_matched, |
722 | .ident = "Acer Aspire 5020", | ||
723 | .matches = { | 714 | .matches = { |
724 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 715 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
725 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), | 716 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), |
@@ -727,8 +718,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
727 | .driver_data = keymap_acer_aspire_5020 | 718 | .driver_data = keymap_acer_aspire_5020 |
728 | }, | 719 | }, |
729 | { | 720 | { |
721 | /* Acer TravelMate 2100 */ | ||
730 | .callback = dmi_matched, | 722 | .callback = dmi_matched, |
731 | .ident = "Acer TravelMate 2100", | ||
732 | .matches = { | 723 | .matches = { |
733 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 724 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
734 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), | 725 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), |
@@ -736,8 +727,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
736 | .driver_data = keymap_acer_aspire_5020 | 727 | .driver_data = keymap_acer_aspire_5020 |
737 | }, | 728 | }, |
738 | { | 729 | { |
730 | /* Acer TravelMate 2410 */ | ||
739 | .callback = dmi_matched, | 731 | .callback = dmi_matched, |
740 | .ident = "Acer TravelMate 2410", | ||
741 | .matches = { | 732 | .matches = { |
742 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 733 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
743 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), | 734 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), |
@@ -745,8 +736,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
745 | .driver_data = keymap_acer_travelmate_2410 | 736 | .driver_data = keymap_acer_travelmate_2410 |
746 | }, | 737 | }, |
747 | { | 738 | { |
739 | /* Acer TravelMate C300 */ | ||
748 | .callback = dmi_matched, | 740 | .callback = dmi_matched, |
749 | .ident = "Acer TravelMate C300", | ||
750 | .matches = { | 741 | .matches = { |
751 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 742 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
752 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), | 743 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), |
@@ -754,8 +745,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
754 | .driver_data = keymap_acer_travelmate_300 | 745 | .driver_data = keymap_acer_travelmate_300 |
755 | }, | 746 | }, |
756 | { | 747 | { |
748 | /* Acer TravelMate C100 */ | ||
757 | .callback = dmi_matched, | 749 | .callback = dmi_matched, |
758 | .ident = "Acer TravelMate C100", | ||
759 | .matches = { | 750 | .matches = { |
760 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 751 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
761 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), | 752 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), |
@@ -763,8 +754,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
763 | .driver_data = keymap_acer_travelmate_300 | 754 | .driver_data = keymap_acer_travelmate_300 |
764 | }, | 755 | }, |
765 | { | 756 | { |
757 | /* Acer TravelMate C110 */ | ||
766 | .callback = dmi_matched, | 758 | .callback = dmi_matched, |
767 | .ident = "Acer TravelMate C110", | ||
768 | .matches = { | 759 | .matches = { |
769 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 760 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
770 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), | 761 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), |
@@ -772,8 +763,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
772 | .driver_data = keymap_acer_travelmate_110 | 763 | .driver_data = keymap_acer_travelmate_110 |
773 | }, | 764 | }, |
774 | { | 765 | { |
766 | /* Acer TravelMate 380 */ | ||
775 | .callback = dmi_matched, | 767 | .callback = dmi_matched, |
776 | .ident = "Acer TravelMate 380", | ||
777 | .matches = { | 768 | .matches = { |
778 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 769 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
779 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), | 770 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), |
@@ -781,8 +772,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
781 | .driver_data = keymap_acer_travelmate_380 | 772 | .driver_data = keymap_acer_travelmate_380 |
782 | }, | 773 | }, |
783 | { | 774 | { |
775 | /* Acer TravelMate 370 */ | ||
784 | .callback = dmi_matched, | 776 | .callback = dmi_matched, |
785 | .ident = "Acer TravelMate 370", | ||
786 | .matches = { | 777 | .matches = { |
787 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 778 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
788 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), | 779 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), |
@@ -790,8 +781,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
790 | .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ | 781 | .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ |
791 | }, | 782 | }, |
792 | { | 783 | { |
784 | /* Acer TravelMate 220 */ | ||
793 | .callback = dmi_matched, | 785 | .callback = dmi_matched, |
794 | .ident = "Acer TravelMate 220", | ||
795 | .matches = { | 786 | .matches = { |
796 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 787 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
797 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), | 788 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), |
@@ -799,8 +790,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
799 | .driver_data = keymap_acer_travelmate_220 | 790 | .driver_data = keymap_acer_travelmate_220 |
800 | }, | 791 | }, |
801 | { | 792 | { |
793 | /* Acer TravelMate 260 */ | ||
802 | .callback = dmi_matched, | 794 | .callback = dmi_matched, |
803 | .ident = "Acer TravelMate 260", | ||
804 | .matches = { | 795 | .matches = { |
805 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 796 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
806 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), | 797 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), |
@@ -808,8 +799,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
808 | .driver_data = keymap_acer_travelmate_220 | 799 | .driver_data = keymap_acer_travelmate_220 |
809 | }, | 800 | }, |
810 | { | 801 | { |
802 | /* Acer TravelMate 230 */ | ||
811 | .callback = dmi_matched, | 803 | .callback = dmi_matched, |
812 | .ident = "Acer TravelMate 230", | ||
813 | .matches = { | 804 | .matches = { |
814 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 805 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
815 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), | 806 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), |
@@ -818,8 +809,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
818 | .driver_data = keymap_acer_travelmate_230 | 809 | .driver_data = keymap_acer_travelmate_230 |
819 | }, | 810 | }, |
820 | { | 811 | { |
812 | /* Acer TravelMate 280 */ | ||
821 | .callback = dmi_matched, | 813 | .callback = dmi_matched, |
822 | .ident = "Acer TravelMate 280", | ||
823 | .matches = { | 814 | .matches = { |
824 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 815 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
825 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), | 816 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), |
@@ -827,8 +818,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
827 | .driver_data = keymap_acer_travelmate_230 | 818 | .driver_data = keymap_acer_travelmate_230 |
828 | }, | 819 | }, |
829 | { | 820 | { |
821 | /* Acer TravelMate 240 */ | ||
830 | .callback = dmi_matched, | 822 | .callback = dmi_matched, |
831 | .ident = "Acer TravelMate 240", | ||
832 | .matches = { | 823 | .matches = { |
833 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 824 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
834 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), | 825 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), |
@@ -836,8 +827,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
836 | .driver_data = keymap_acer_travelmate_240 | 827 | .driver_data = keymap_acer_travelmate_240 |
837 | }, | 828 | }, |
838 | { | 829 | { |
830 | /* Acer TravelMate 250 */ | ||
839 | .callback = dmi_matched, | 831 | .callback = dmi_matched, |
840 | .ident = "Acer TravelMate 250", | ||
841 | .matches = { | 832 | .matches = { |
842 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 833 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
843 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), | 834 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), |
@@ -845,8 +836,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
845 | .driver_data = keymap_acer_travelmate_240 | 836 | .driver_data = keymap_acer_travelmate_240 |
846 | }, | 837 | }, |
847 | { | 838 | { |
839 | /* Acer TravelMate 2424NWXCi */ | ||
848 | .callback = dmi_matched, | 840 | .callback = dmi_matched, |
849 | .ident = "Acer TravelMate 2424NWXCi", | ||
850 | .matches = { | 841 | .matches = { |
851 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 842 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
852 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"), | 843 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"), |
@@ -854,8 +845,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
854 | .driver_data = keymap_acer_travelmate_240 | 845 | .driver_data = keymap_acer_travelmate_240 |
855 | }, | 846 | }, |
856 | { | 847 | { |
848 | /* Acer TravelMate 350 */ | ||
857 | .callback = dmi_matched, | 849 | .callback = dmi_matched, |
858 | .ident = "Acer TravelMate 350", | ||
859 | .matches = { | 850 | .matches = { |
860 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 851 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
861 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), | 852 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), |
@@ -863,8 +854,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
863 | .driver_data = keymap_acer_travelmate_350 | 854 | .driver_data = keymap_acer_travelmate_350 |
864 | }, | 855 | }, |
865 | { | 856 | { |
857 | /* Acer TravelMate 360 */ | ||
866 | .callback = dmi_matched, | 858 | .callback = dmi_matched, |
867 | .ident = "Acer TravelMate 360", | ||
868 | .matches = { | 859 | .matches = { |
869 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 860 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
870 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), | 861 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
@@ -872,8 +863,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
872 | .driver_data = keymap_acer_travelmate_360 | 863 | .driver_data = keymap_acer_travelmate_360 |
873 | }, | 864 | }, |
874 | { | 865 | { |
866 | /* Acer TravelMate 610 */ | ||
875 | .callback = dmi_matched, | 867 | .callback = dmi_matched, |
876 | .ident = "Acer TravelMate 610", | ||
877 | .matches = { | 868 | .matches = { |
878 | DMI_MATCH(DMI_SYS_VENDOR, "ACER"), | 869 | DMI_MATCH(DMI_SYS_VENDOR, "ACER"), |
879 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), | 870 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), |
@@ -881,8 +872,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
881 | .driver_data = keymap_acer_travelmate_610 | 872 | .driver_data = keymap_acer_travelmate_610 |
882 | }, | 873 | }, |
883 | { | 874 | { |
875 | /* Acer TravelMate 620 */ | ||
884 | .callback = dmi_matched, | 876 | .callback = dmi_matched, |
885 | .ident = "Acer TravelMate 620", | ||
886 | .matches = { | 877 | .matches = { |
887 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 878 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
888 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), | 879 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), |
@@ -890,8 +881,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
890 | .driver_data = keymap_acer_travelmate_630 | 881 | .driver_data = keymap_acer_travelmate_630 |
891 | }, | 882 | }, |
892 | { | 883 | { |
884 | /* Acer TravelMate 630 */ | ||
893 | .callback = dmi_matched, | 885 | .callback = dmi_matched, |
894 | .ident = "Acer TravelMate 630", | ||
895 | .matches = { | 886 | .matches = { |
896 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 887 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
897 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), | 888 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), |
@@ -899,8 +890,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
899 | .driver_data = keymap_acer_travelmate_630 | 890 | .driver_data = keymap_acer_travelmate_630 |
900 | }, | 891 | }, |
901 | { | 892 | { |
893 | /* AOpen 1559AS */ | ||
902 | .callback = dmi_matched, | 894 | .callback = dmi_matched, |
903 | .ident = "AOpen 1559AS", | ||
904 | .matches = { | 895 | .matches = { |
905 | DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), | 896 | DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), |
906 | DMI_MATCH(DMI_BOARD_NAME, "E2U"), | 897 | DMI_MATCH(DMI_BOARD_NAME, "E2U"), |
@@ -908,8 +899,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
908 | .driver_data = keymap_aopen_1559as | 899 | .driver_data = keymap_aopen_1559as |
909 | }, | 900 | }, |
910 | { | 901 | { |
902 | /* Medion MD 9783 */ | ||
911 | .callback = dmi_matched, | 903 | .callback = dmi_matched, |
912 | .ident = "Medion MD 9783", | ||
913 | .matches = { | 904 | .matches = { |
914 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | 905 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), |
915 | DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), | 906 | DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), |
@@ -917,8 +908,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
917 | .driver_data = keymap_wistron_ms2111 | 908 | .driver_data = keymap_wistron_ms2111 |
918 | }, | 909 | }, |
919 | { | 910 | { |
911 | /* Medion MD 40100 */ | ||
920 | .callback = dmi_matched, | 912 | .callback = dmi_matched, |
921 | .ident = "Medion MD 40100", | ||
922 | .matches = { | 913 | .matches = { |
923 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | 914 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), |
924 | DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), | 915 | DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), |
@@ -926,8 +917,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
926 | .driver_data = keymap_wistron_md40100 | 917 | .driver_data = keymap_wistron_md40100 |
927 | }, | 918 | }, |
928 | { | 919 | { |
920 | /* Medion MD 2900 */ | ||
929 | .callback = dmi_matched, | 921 | .callback = dmi_matched, |
930 | .ident = "Medion MD 2900", | ||
931 | .matches = { | 922 | .matches = { |
932 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | 923 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), |
933 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), | 924 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), |
@@ -935,8 +926,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
935 | .driver_data = keymap_wistron_md2900 | 926 | .driver_data = keymap_wistron_md2900 |
936 | }, | 927 | }, |
937 | { | 928 | { |
929 | /* Medion MD 42200 */ | ||
938 | .callback = dmi_matched, | 930 | .callback = dmi_matched, |
939 | .ident = "Medion MD 42200", | ||
940 | .matches = { | 931 | .matches = { |
941 | DMI_MATCH(DMI_SYS_VENDOR, "Medion"), | 932 | DMI_MATCH(DMI_SYS_VENDOR, "Medion"), |
942 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"), | 933 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"), |
@@ -944,8 +935,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
944 | .driver_data = keymap_fs_amilo_pro_v2000 | 935 | .driver_data = keymap_fs_amilo_pro_v2000 |
945 | }, | 936 | }, |
946 | { | 937 | { |
938 | /* Medion MD 96500 */ | ||
947 | .callback = dmi_matched, | 939 | .callback = dmi_matched, |
948 | .ident = "Medion MD 96500", | ||
949 | .matches = { | 940 | .matches = { |
950 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), | 941 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), |
951 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), | 942 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), |
@@ -953,8 +944,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
953 | .driver_data = keymap_wistron_md96500 | 944 | .driver_data = keymap_wistron_md96500 |
954 | }, | 945 | }, |
955 | { | 946 | { |
947 | /* Medion MD 95400 */ | ||
956 | .callback = dmi_matched, | 948 | .callback = dmi_matched, |
957 | .ident = "Medion MD 95400", | ||
958 | .matches = { | 949 | .matches = { |
959 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), | 950 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), |
960 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), | 951 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), |
@@ -962,8 +953,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
962 | .driver_data = keymap_wistron_md96500 | 953 | .driver_data = keymap_wistron_md96500 |
963 | }, | 954 | }, |
964 | { | 955 | { |
956 | /* Fujitsu Siemens Amilo D7820 */ | ||
965 | .callback = dmi_matched, | 957 | .callback = dmi_matched, |
966 | .ident = "Fujitsu Siemens Amilo D7820", | ||
967 | .matches = { | 958 | .matches = { |
968 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ | 959 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ |
969 | DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), | 960 | DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), |
@@ -971,8 +962,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
971 | .driver_data = keymap_fs_amilo_d88x0 | 962 | .driver_data = keymap_fs_amilo_d88x0 |
972 | }, | 963 | }, |
973 | { | 964 | { |
965 | /* Fujitsu Siemens Amilo D88x0 */ | ||
974 | .callback = dmi_matched, | 966 | .callback = dmi_matched, |
975 | .ident = "Fujitsu Siemens Amilo D88x0", | ||
976 | .matches = { | 967 | .matches = { |
977 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 968 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
978 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), | 969 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), |
@@ -1037,21 +1028,6 @@ static unsigned long jiffies_last_press; | |||
1037 | static bool wifi_enabled; | 1028 | static bool wifi_enabled; |
1038 | static bool bluetooth_enabled; | 1029 | static bool bluetooth_enabled; |
1039 | 1030 | ||
1040 | static void report_key(struct input_dev *dev, unsigned int keycode) | ||
1041 | { | ||
1042 | input_report_key(dev, keycode, 1); | ||
1043 | input_sync(dev); | ||
1044 | input_report_key(dev, keycode, 0); | ||
1045 | input_sync(dev); | ||
1046 | } | ||
1047 | |||
1048 | static void report_switch(struct input_dev *dev, unsigned int code, int value) | ||
1049 | { | ||
1050 | input_report_switch(dev, code, value); | ||
1051 | input_sync(dev); | ||
1052 | } | ||
1053 | |||
1054 | |||
1055 | /* led management */ | 1031 | /* led management */ |
1056 | static void wistron_mail_led_set(struct led_classdev *led_cdev, | 1032 | static void wistron_mail_led_set(struct led_classdev *led_cdev, |
1057 | enum led_brightness value) | 1033 | enum led_brightness value) |
@@ -1128,43 +1104,13 @@ static inline void wistron_led_resume(void) | |||
1128 | led_classdev_resume(&wistron_wifi_led); | 1104 | led_classdev_resume(&wistron_wifi_led); |
1129 | } | 1105 | } |
1130 | 1106 | ||
1131 | static struct key_entry *wistron_get_entry_by_scancode(int code) | ||
1132 | { | ||
1133 | struct key_entry *key; | ||
1134 | |||
1135 | for (key = keymap; key->type != KE_END; key++) | ||
1136 | if (code == key->code) | ||
1137 | return key; | ||
1138 | |||
1139 | return NULL; | ||
1140 | } | ||
1141 | |||
1142 | static struct key_entry *wistron_get_entry_by_keycode(int keycode) | ||
1143 | { | ||
1144 | struct key_entry *key; | ||
1145 | |||
1146 | for (key = keymap; key->type != KE_END; key++) | ||
1147 | if (key->type == KE_KEY && keycode == key->keycode) | ||
1148 | return key; | ||
1149 | |||
1150 | return NULL; | ||
1151 | } | ||
1152 | |||
1153 | static void handle_key(u8 code) | 1107 | static void handle_key(u8 code) |
1154 | { | 1108 | { |
1155 | const struct key_entry *key = wistron_get_entry_by_scancode(code); | 1109 | const struct key_entry *key = |
1110 | sparse_keymap_entry_from_scancode(wistron_idev->input, code); | ||
1156 | 1111 | ||
1157 | if (key) { | 1112 | if (key) { |
1158 | switch (key->type) { | 1113 | switch (key->type) { |
1159 | case KE_KEY: | ||
1160 | report_key(wistron_idev->input, key->keycode); | ||
1161 | break; | ||
1162 | |||
1163 | case KE_SW: | ||
1164 | report_switch(wistron_idev->input, | ||
1165 | key->sw.code, key->sw.value); | ||
1166 | break; | ||
1167 | |||
1168 | case KE_WIFI: | 1114 | case KE_WIFI: |
1169 | if (have_wifi) { | 1115 | if (have_wifi) { |
1170 | wifi_enabled = !wifi_enabled; | 1116 | wifi_enabled = !wifi_enabled; |
@@ -1180,7 +1126,9 @@ static void handle_key(u8 code) | |||
1180 | break; | 1126 | break; |
1181 | 1127 | ||
1182 | default: | 1128 | default: |
1183 | BUG(); | 1129 | sparse_keymap_report_entry(wistron_idev->input, |
1130 | key, 1, true); | ||
1131 | break; | ||
1184 | } | 1132 | } |
1185 | jiffies_last_press = jiffies; | 1133 | jiffies_last_press = jiffies; |
1186 | } else | 1134 | } else |
@@ -1220,42 +1168,39 @@ static void wistron_poll(struct input_polled_dev *dev) | |||
1220 | dev->poll_interval = POLL_INTERVAL_DEFAULT; | 1168 | dev->poll_interval = POLL_INTERVAL_DEFAULT; |
1221 | } | 1169 | } |
1222 | 1170 | ||
1223 | static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 1171 | static int __devinit wistron_setup_keymap(struct input_dev *dev, |
1172 | struct key_entry *entry) | ||
1224 | { | 1173 | { |
1225 | const struct key_entry *key = wistron_get_entry_by_scancode(scancode); | 1174 | switch (entry->type) { |
1226 | |||
1227 | if (key && key->type == KE_KEY) { | ||
1228 | *keycode = key->keycode; | ||
1229 | return 0; | ||
1230 | } | ||
1231 | 1175 | ||
1232 | return -EINVAL; | 1176 | /* if wifi or bluetooth are not available, create normal keys */ |
1233 | } | 1177 | case KE_WIFI: |
1178 | if (!have_wifi) { | ||
1179 | entry->type = KE_KEY; | ||
1180 | entry->keycode = KEY_WLAN; | ||
1181 | } | ||
1182 | break; | ||
1234 | 1183 | ||
1235 | static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) | 1184 | case KE_BLUETOOTH: |
1236 | { | 1185 | if (!have_bluetooth) { |
1237 | struct key_entry *key; | 1186 | entry->type = KE_KEY; |
1238 | int old_keycode; | 1187 | entry->keycode = KEY_BLUETOOTH; |
1239 | 1188 | } | |
1240 | if (keycode < 0 || keycode > KEY_MAX) | 1189 | break; |
1241 | return -EINVAL; | 1190 | |
1242 | 1191 | case KE_END: | |
1243 | key = wistron_get_entry_by_scancode(scancode); | 1192 | if (entry->code & FE_UNTESTED) |
1244 | if (key && key->type == KE_KEY) { | 1193 | printk(KERN_WARNING "Untested laptop multimedia keys, " |
1245 | old_keycode = key->keycode; | 1194 | "please report success or failure to " |
1246 | key->keycode = keycode; | 1195 | "eric.piel@tremplin-utc.net\n"); |
1247 | set_bit(keycode, dev->keybit); | 1196 | break; |
1248 | if (!wistron_get_entry_by_keycode(old_keycode)) | ||
1249 | clear_bit(old_keycode, dev->keybit); | ||
1250 | return 0; | ||
1251 | } | 1197 | } |
1252 | 1198 | ||
1253 | return -EINVAL; | 1199 | return 0; |
1254 | } | 1200 | } |
1255 | 1201 | ||
1256 | static int __devinit setup_input_dev(void) | 1202 | static int __devinit setup_input_dev(void) |
1257 | { | 1203 | { |
1258 | struct key_entry *key; | ||
1259 | struct input_dev *input_dev; | 1204 | struct input_dev *input_dev; |
1260 | int error; | 1205 | int error; |
1261 | 1206 | ||
@@ -1263,7 +1208,7 @@ static int __devinit setup_input_dev(void) | |||
1263 | if (!wistron_idev) | 1208 | if (!wistron_idev) |
1264 | return -ENOMEM; | 1209 | return -ENOMEM; |
1265 | 1210 | ||
1266 | wistron_idev->flush = wistron_flush; | 1211 | wistron_idev->open = wistron_flush; |
1267 | wistron_idev->poll = wistron_poll; | 1212 | wistron_idev->poll = wistron_poll; |
1268 | wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; | 1213 | wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; |
1269 | 1214 | ||
@@ -1273,56 +1218,21 @@ static int __devinit setup_input_dev(void) | |||
1273 | input_dev->id.bustype = BUS_HOST; | 1218 | input_dev->id.bustype = BUS_HOST; |
1274 | input_dev->dev.parent = &wistron_device->dev; | 1219 | input_dev->dev.parent = &wistron_device->dev; |
1275 | 1220 | ||
1276 | input_dev->getkeycode = wistron_getkeycode; | 1221 | error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap); |
1277 | input_dev->setkeycode = wistron_setkeycode; | 1222 | if (error) |
1278 | 1223 | goto err_free_dev; | |
1279 | for (key = keymap; key->type != KE_END; key++) { | ||
1280 | switch (key->type) { | ||
1281 | case KE_KEY: | ||
1282 | set_bit(EV_KEY, input_dev->evbit); | ||
1283 | set_bit(key->keycode, input_dev->keybit); | ||
1284 | break; | ||
1285 | |||
1286 | case KE_SW: | ||
1287 | set_bit(EV_SW, input_dev->evbit); | ||
1288 | set_bit(key->sw.code, input_dev->swbit); | ||
1289 | break; | ||
1290 | |||
1291 | /* if wifi or bluetooth are not available, create normal keys */ | ||
1292 | case KE_WIFI: | ||
1293 | if (!have_wifi) { | ||
1294 | key->type = KE_KEY; | ||
1295 | key->keycode = KEY_WLAN; | ||
1296 | key--; | ||
1297 | } | ||
1298 | break; | ||
1299 | |||
1300 | case KE_BLUETOOTH: | ||
1301 | if (!have_bluetooth) { | ||
1302 | key->type = KE_KEY; | ||
1303 | key->keycode = KEY_BLUETOOTH; | ||
1304 | key--; | ||
1305 | } | ||
1306 | break; | ||
1307 | |||
1308 | default: | ||
1309 | break; | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1313 | /* reads information flags on KE_END */ | ||
1314 | if (key->code & FE_UNTESTED) | ||
1315 | printk(KERN_WARNING "Untested laptop multimedia keys, " | ||
1316 | "please report success or failure to eric.piel" | ||
1317 | "@tremplin-utc.net\n"); | ||
1318 | 1224 | ||
1319 | error = input_register_polled_device(wistron_idev); | 1225 | error = input_register_polled_device(wistron_idev); |
1320 | if (error) { | 1226 | if (error) |
1321 | input_free_polled_device(wistron_idev); | 1227 | goto err_free_keymap; |
1322 | return error; | ||
1323 | } | ||
1324 | 1228 | ||
1325 | return 0; | 1229 | return 0; |
1230 | |||
1231 | err_free_keymap: | ||
1232 | sparse_keymap_free(input_dev); | ||
1233 | err_free_dev: | ||
1234 | input_free_polled_device(wistron_idev); | ||
1235 | return error; | ||
1326 | } | 1236 | } |
1327 | 1237 | ||
1328 | /* Driver core */ | 1238 | /* Driver core */ |
@@ -1371,6 +1281,7 @@ static int __devexit wistron_remove(struct platform_device *dev) | |||
1371 | { | 1281 | { |
1372 | wistron_led_remove(); | 1282 | wistron_led_remove(); |
1373 | input_unregister_polled_device(wistron_idev); | 1283 | input_unregister_polled_device(wistron_idev); |
1284 | sparse_keymap_free(wistron_idev->input); | ||
1374 | input_free_polled_device(wistron_idev); | 1285 | input_free_polled_device(wistron_idev); |
1375 | bios_detach(); | 1286 | bios_detach(); |
1376 | 1287 | ||
@@ -1418,7 +1329,7 @@ static struct platform_driver wistron_driver = { | |||
1418 | .driver = { | 1329 | .driver = { |
1419 | .name = "wistron-bios", | 1330 | .name = "wistron-bios", |
1420 | .owner = THIS_MODULE, | 1331 | .owner = THIS_MODULE, |
1421 | #if CONFIG_PM | 1332 | #ifdef CONFIG_PM |
1422 | .pm = &wistron_pm_ops, | 1333 | .pm = &wistron_pm_ops, |
1423 | #endif | 1334 | #endif |
1424 | }, | 1335 | }, |
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index ba4f5dd7c60e..c3d7ba5f5b47 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/slab.h> | ||
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
23 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
24 | #include <linux/input.h> | 25 | #include <linux/input.h> |
@@ -97,8 +98,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) | |||
97 | wm831x_on->dev->phys = "wm831x_on/input0"; | 98 | wm831x_on->dev->phys = "wm831x_on/input0"; |
98 | wm831x_on->dev->dev.parent = &pdev->dev; | 99 | wm831x_on->dev->dev.parent = &pdev->dev; |
99 | 100 | ||
100 | ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq, | 101 | ret = request_threaded_irq(irq, NULL, wm831x_on_irq, |
101 | IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on); | 102 | IRQF_TRIGGER_RISING, "wm831x_on", |
103 | wm831x_on); | ||
102 | if (ret < 0) { | 104 | if (ret < 0) { |
103 | dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); | 105 | dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); |
104 | goto err_input_dev; | 106 | goto err_input_dev; |
@@ -114,7 +116,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) | |||
114 | return 0; | 116 | return 0; |
115 | 117 | ||
116 | err_irq: | 118 | err_irq: |
117 | wm831x_free_irq(wm831x, irq, NULL); | 119 | free_irq(irq, wm831x_on); |
118 | err_input_dev: | 120 | err_input_dev: |
119 | input_free_device(wm831x_on->dev); | 121 | input_free_device(wm831x_on->dev); |
120 | err: | 122 | err: |
@@ -127,7 +129,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev) | |||
127 | struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); | 129 | struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); |
128 | int irq = platform_get_irq(pdev, 0); | 130 | int irq = platform_get_irq(pdev, 0); |
129 | 131 | ||
130 | wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on); | 132 | free_irq(irq, wm831x_on); |
131 | cancel_delayed_work_sync(&wm831x_on->work); | 133 | cancel_delayed_work_sync(&wm831x_on->work); |
132 | input_unregister_device(wm831x_on->dev); | 134 | input_unregister_device(wm831x_on->dev); |
133 | kfree(wm831x_on); | 135 | kfree(wm831x_on); |
diff --git a/drivers/input/misc/yealink.h b/drivers/input/misc/yealink.h index 48af0be9cbdf..1e0f52397010 100644 --- a/drivers/input/misc/yealink.h +++ b/drivers/input/misc/yealink.h | |||
@@ -127,7 +127,7 @@ struct yld_ctl_packet { | |||
127 | * yld_status struct. | 127 | * yld_status struct. |
128 | */ | 128 | */ |
129 | 129 | ||
130 | /* LCD, each segment must be driven seperately. | 130 | /* LCD, each segment must be driven separately. |
131 | * | 131 | * |
132 | * Layout: | 132 | * Layout: |
133 | * | 133 | * |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 3feeb3af8abd..c714ca2407f8 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS | |||
70 | config MOUSE_PS2_LIFEBOOK | 70 | config MOUSE_PS2_LIFEBOOK |
71 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED | 71 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED |
72 | default y | 72 | default y |
73 | depends on MOUSE_PS2 && X86 | 73 | depends on MOUSE_PS2 && X86 && DMI |
74 | help | 74 | help |
75 | Say Y here if you have a Fujitsu B-series Lifebook PS/2 | 75 | Say Y here if you have a Fujitsu B-series Lifebook PS/2 |
76 | TouchScreen connected to your system. | 76 | TouchScreen connected to your system. |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f36110689aae..99d58764ef03 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com> | 5 | * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com> |
6 | * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru> | 6 | * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru> |
7 | * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz> | 7 | * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz> |
8 | * Copyright (c) 2009 Sebastian Kapfer <sebastian_kapfer@gmx.net> | ||
8 | * | 9 | * |
9 | * ALPS detection, tap switching and status querying info is taken from | 10 | * ALPS detection, tap switching and status querying info is taken from |
10 | * tpconfig utility (by C. Scott Ananian and Bruce Kall). | 11 | * tpconfig utility (by C. Scott Ananian and Bruce Kall). |
@@ -14,6 +15,7 @@ | |||
14 | * the Free Software Foundation. | 15 | * the Free Software Foundation. |
15 | */ | 16 | */ |
16 | 17 | ||
18 | #include <linux/slab.h> | ||
17 | #include <linux/input.h> | 19 | #include <linux/input.h> |
18 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
19 | #include <linux/libps2.h> | 21 | #include <linux/libps2.h> |
@@ -28,13 +30,16 @@ | |||
28 | #define dbg(format, arg...) do {} while (0) | 30 | #define dbg(format, arg...) do {} while (0) |
29 | #endif | 31 | #endif |
30 | 32 | ||
31 | #define ALPS_DUALPOINT 0x01 | 33 | #define ALPS_OLDPROTO 0x01 /* old style input */ |
32 | #define ALPS_WHEEL 0x02 | 34 | #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */ |
33 | #define ALPS_FW_BK_1 0x04 | 35 | #define ALPS_PASS 0x04 /* device has a pass-through port */ |
34 | #define ALPS_4BTN 0x08 | 36 | |
35 | #define ALPS_OLDPROTO 0x10 | 37 | #define ALPS_WHEEL 0x08 /* hardware wheel present */ |
36 | #define ALPS_PASS 0x20 | 38 | #define ALPS_FW_BK_1 0x10 /* front & back buttons present */ |
37 | #define ALPS_FW_BK_2 0x40 | 39 | #define ALPS_FW_BK_2 0x20 /* front & back buttons present */ |
40 | #define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */ | ||
41 | #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with | ||
42 | 6-byte ALPS packet */ | ||
38 | 43 | ||
39 | static const struct alps_model_info alps_model_data[] = { | 44 | static const struct alps_model_info alps_model_data[] = { |
40 | { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ | 45 | { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ |
@@ -55,8 +60,12 @@ static const struct alps_model_info alps_model_data[] = { | |||
55 | { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ | 60 | { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ |
56 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, | 61 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, |
57 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ | 62 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ |
58 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */ | 63 | /* Dell Latitude E5500, E6400, E6500, Precision M4400 */ |
59 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 }, /* Dell Vostro 1400 */ | 64 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, |
65 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, | ||
66 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ | ||
67 | { { 0x52, 0x01, 0x14 }, 0xff, 0xff, | ||
68 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ | ||
60 | }; | 69 | }; |
61 | 70 | ||
62 | /* | 71 | /* |
@@ -66,42 +75,86 @@ static const struct alps_model_info alps_model_data[] = { | |||
66 | */ | 75 | */ |
67 | 76 | ||
68 | /* | 77 | /* |
69 | * ALPS abolute Mode - new format | 78 | * PS/2 packet format |
79 | * | ||
80 | * byte 0: 0 0 YSGN XSGN 1 M R L | ||
81 | * byte 1: X7 X6 X5 X4 X3 X2 X1 X0 | ||
82 | * byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 | ||
83 | * | ||
84 | * Note that the device never signals overflow condition. | ||
85 | * | ||
86 | * ALPS absolute Mode - new format | ||
70 | * | 87 | * |
71 | * byte 0: 1 ? ? ? 1 ? ? ? | 88 | * byte 0: 1 ? ? ? 1 ? ? ? |
72 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 | 89 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 |
73 | * byte 2: 0 x10 x9 x8 x7 ? fin ges | 90 | * byte 2: 0 x10 x9 x8 x7 ? fin ges |
74 | * byte 3: 0 y9 y8 y7 1 M R L | 91 | * byte 3: 0 y9 y8 y7 1 M R L |
75 | * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 | 92 | * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 |
76 | * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 | 93 | * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 |
77 | * | 94 | * |
95 | * Dualpoint device -- interleaved packet format | ||
96 | * | ||
97 | * byte 0: 1 1 0 0 1 1 1 1 | ||
98 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 | ||
99 | * byte 2: 0 x10 x9 x8 x7 0 fin ges | ||
100 | * byte 3: 0 0 YSGN XSGN 1 1 1 1 | ||
101 | * byte 4: X7 X6 X5 X4 X3 X2 X1 X0 | ||
102 | * byte 5: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 | ||
103 | * byte 6: 0 y9 y8 y7 1 m r l | ||
104 | * byte 7: 0 y6 y5 y4 y3 y2 y1 y0 | ||
105 | * byte 8: 0 z6 z5 z4 z3 z2 z1 z0 | ||
106 | * | ||
107 | * CAPITALS = stick, miniscules = touchpad | ||
108 | * | ||
78 | * ?'s can have different meanings on different models, | 109 | * ?'s can have different meanings on different models, |
79 | * such as wheel rotation, extra buttons, stick buttons | 110 | * such as wheel rotation, extra buttons, stick buttons |
80 | * on a dualpoint, etc. | 111 | * on a dualpoint, etc. |
81 | */ | 112 | */ |
82 | 113 | ||
114 | static bool alps_is_valid_first_byte(const struct alps_model_info *model, | ||
115 | unsigned char data) | ||
116 | { | ||
117 | return (data & model->mask0) == model->byte0; | ||
118 | } | ||
119 | |||
120 | static void alps_report_buttons(struct psmouse *psmouse, | ||
121 | struct input_dev *dev1, struct input_dev *dev2, | ||
122 | int left, int right, int middle) | ||
123 | { | ||
124 | struct input_dev *dev; | ||
125 | |||
126 | /* | ||
127 | * If shared button has already been reported on the | ||
128 | * other device (dev2) then this event should be also | ||
129 | * sent through that device. | ||
130 | */ | ||
131 | dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; | ||
132 | input_report_key(dev, BTN_LEFT, left); | ||
133 | |||
134 | dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; | ||
135 | input_report_key(dev, BTN_RIGHT, right); | ||
136 | |||
137 | dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; | ||
138 | input_report_key(dev, BTN_MIDDLE, middle); | ||
139 | |||
140 | /* | ||
141 | * Sync the _other_ device now, we'll do the first | ||
142 | * device later once we report the rest of the events. | ||
143 | */ | ||
144 | input_sync(dev2); | ||
145 | } | ||
146 | |||
83 | static void alps_process_packet(struct psmouse *psmouse) | 147 | static void alps_process_packet(struct psmouse *psmouse) |
84 | { | 148 | { |
85 | struct alps_data *priv = psmouse->private; | 149 | struct alps_data *priv = psmouse->private; |
150 | const struct alps_model_info *model = priv->i; | ||
86 | unsigned char *packet = psmouse->packet; | 151 | unsigned char *packet = psmouse->packet; |
87 | struct input_dev *dev = psmouse->dev; | 152 | struct input_dev *dev = psmouse->dev; |
88 | struct input_dev *dev2 = priv->dev2; | 153 | struct input_dev *dev2 = priv->dev2; |
89 | int x, y, z, ges, fin, left, right, middle; | 154 | int x, y, z, ges, fin, left, right, middle; |
90 | int back = 0, forward = 0; | 155 | int back = 0, forward = 0; |
91 | 156 | ||
92 | if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */ | 157 | if (model->flags & ALPS_OLDPROTO) { |
93 | input_report_key(dev2, BTN_LEFT, packet[0] & 1); | ||
94 | input_report_key(dev2, BTN_RIGHT, packet[0] & 2); | ||
95 | input_report_key(dev2, BTN_MIDDLE, packet[0] & 4); | ||
96 | input_report_rel(dev2, REL_X, | ||
97 | packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); | ||
98 | input_report_rel(dev2, REL_Y, | ||
99 | packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); | ||
100 | input_sync(dev2); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | if (priv->i->flags & ALPS_OLDPROTO) { | ||
105 | left = packet[2] & 0x10; | 158 | left = packet[2] & 0x10; |
106 | right = packet[2] & 0x08; | 159 | right = packet[2] & 0x08; |
107 | middle = 0; | 160 | middle = 0; |
@@ -117,12 +170,12 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
117 | z = packet[5]; | 170 | z = packet[5]; |
118 | } | 171 | } |
119 | 172 | ||
120 | if (priv->i->flags & ALPS_FW_BK_1) { | 173 | if (model->flags & ALPS_FW_BK_1) { |
121 | back = packet[0] & 0x10; | 174 | back = packet[0] & 0x10; |
122 | forward = packet[2] & 4; | 175 | forward = packet[2] & 4; |
123 | } | 176 | } |
124 | 177 | ||
125 | if (priv->i->flags & ALPS_FW_BK_2) { | 178 | if (model->flags & ALPS_FW_BK_2) { |
126 | back = packet[3] & 4; | 179 | back = packet[3] & 4; |
127 | forward = packet[2] & 4; | 180 | forward = packet[2] & 4; |
128 | if ((middle = forward && back)) | 181 | if ((middle = forward && back)) |
@@ -132,25 +185,21 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
132 | ges = packet[2] & 1; | 185 | ges = packet[2] & 1; |
133 | fin = packet[2] & 2; | 186 | fin = packet[2] & 2; |
134 | 187 | ||
135 | if ((priv->i->flags & ALPS_DUALPOINT) && z == 127) { | 188 | if ((model->flags & ALPS_DUALPOINT) && z == 127) { |
136 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); | 189 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); |
137 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); | 190 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); |
138 | 191 | ||
139 | input_report_key(dev2, BTN_LEFT, left); | 192 | alps_report_buttons(psmouse, dev2, dev, left, right, middle); |
140 | input_report_key(dev2, BTN_RIGHT, right); | ||
141 | input_report_key(dev2, BTN_MIDDLE, middle); | ||
142 | 193 | ||
143 | input_sync(dev); | ||
144 | input_sync(dev2); | 194 | input_sync(dev2); |
145 | return; | 195 | return; |
146 | } | 196 | } |
147 | 197 | ||
148 | input_report_key(dev, BTN_LEFT, left); | 198 | alps_report_buttons(psmouse, dev, dev2, left, right, middle); |
149 | input_report_key(dev, BTN_RIGHT, right); | ||
150 | input_report_key(dev, BTN_MIDDLE, middle); | ||
151 | 199 | ||
152 | /* Convert hardware tap to a reasonable Z value */ | 200 | /* Convert hardware tap to a reasonable Z value */ |
153 | if (ges && !fin) z = 40; | 201 | if (ges && !fin) |
202 | z = 40; | ||
154 | 203 | ||
155 | /* | 204 | /* |
156 | * A "tap and drag" operation is reported by the hardware as a transition | 205 | * A "tap and drag" operation is reported by the hardware as a transition |
@@ -166,8 +215,10 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
166 | } | 215 | } |
167 | priv->prev_fin = fin; | 216 | priv->prev_fin = fin; |
168 | 217 | ||
169 | if (z > 30) input_report_key(dev, BTN_TOUCH, 1); | 218 | if (z > 30) |
170 | if (z < 25) input_report_key(dev, BTN_TOUCH, 0); | 219 | input_report_key(dev, BTN_TOUCH, 1); |
220 | if (z < 25) | ||
221 | input_report_key(dev, BTN_TOUCH, 0); | ||
171 | 222 | ||
172 | if (z > 0) { | 223 | if (z > 0) { |
173 | input_report_abs(dev, ABS_X, x); | 224 | input_report_abs(dev, ABS_X, x); |
@@ -177,36 +228,186 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
177 | input_report_abs(dev, ABS_PRESSURE, z); | 228 | input_report_abs(dev, ABS_PRESSURE, z); |
178 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); | 229 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); |
179 | 230 | ||
180 | if (priv->i->flags & ALPS_WHEEL) | 231 | if (model->flags & ALPS_WHEEL) |
181 | input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07)); | 232 | input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07)); |
182 | 233 | ||
183 | if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { | 234 | if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { |
184 | input_report_key(dev, BTN_FORWARD, forward); | 235 | input_report_key(dev, BTN_FORWARD, forward); |
185 | input_report_key(dev, BTN_BACK, back); | 236 | input_report_key(dev, BTN_BACK, back); |
186 | } | 237 | } |
187 | 238 | ||
239 | if (model->flags & ALPS_FOUR_BUTTONS) { | ||
240 | input_report_key(dev, BTN_0, packet[2] & 4); | ||
241 | input_report_key(dev, BTN_1, packet[0] & 0x10); | ||
242 | input_report_key(dev, BTN_2, packet[3] & 4); | ||
243 | input_report_key(dev, BTN_3, packet[0] & 0x20); | ||
244 | } | ||
245 | |||
188 | input_sync(dev); | 246 | input_sync(dev); |
189 | } | 247 | } |
190 | 248 | ||
249 | static void alps_report_bare_ps2_packet(struct psmouse *psmouse, | ||
250 | unsigned char packet[], | ||
251 | bool report_buttons) | ||
252 | { | ||
253 | struct alps_data *priv = psmouse->private; | ||
254 | struct input_dev *dev2 = priv->dev2; | ||
255 | |||
256 | if (report_buttons) | ||
257 | alps_report_buttons(psmouse, dev2, psmouse->dev, | ||
258 | packet[0] & 1, packet[0] & 2, packet[0] & 4); | ||
259 | |||
260 | input_report_rel(dev2, REL_X, | ||
261 | packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); | ||
262 | input_report_rel(dev2, REL_Y, | ||
263 | packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); | ||
264 | |||
265 | input_sync(dev2); | ||
266 | } | ||
267 | |||
268 | static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | ||
269 | { | ||
270 | struct alps_data *priv = psmouse->private; | ||
271 | |||
272 | if (psmouse->pktcnt < 6) | ||
273 | return PSMOUSE_GOOD_DATA; | ||
274 | |||
275 | if (psmouse->pktcnt == 6) { | ||
276 | /* | ||
277 | * Start a timer to flush the packet if it ends up last | ||
278 | * 6-byte packet in the stream. Timer needs to fire | ||
279 | * psmouse core times out itself. 20 ms should be enough | ||
280 | * to decide if we are getting more data or not. | ||
281 | */ | ||
282 | mod_timer(&priv->timer, jiffies + msecs_to_jiffies(20)); | ||
283 | return PSMOUSE_GOOD_DATA; | ||
284 | } | ||
285 | |||
286 | del_timer(&priv->timer); | ||
287 | |||
288 | if (psmouse->packet[6] & 0x80) { | ||
289 | |||
290 | /* | ||
291 | * Highest bit is set - that means we either had | ||
292 | * complete ALPS packet and this is start of the | ||
293 | * next packet or we got garbage. | ||
294 | */ | ||
295 | |||
296 | if (((psmouse->packet[3] | | ||
297 | psmouse->packet[4] | | ||
298 | psmouse->packet[5]) & 0x80) || | ||
299 | (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) { | ||
300 | dbg("refusing packet %x %x %x %x " | ||
301 | "(suspected interleaved ps/2)\n", | ||
302 | psmouse->packet[3], psmouse->packet[4], | ||
303 | psmouse->packet[5], psmouse->packet[6]); | ||
304 | return PSMOUSE_BAD_DATA; | ||
305 | } | ||
306 | |||
307 | alps_process_packet(psmouse); | ||
308 | |||
309 | /* Continue with the next packet */ | ||
310 | psmouse->packet[0] = psmouse->packet[6]; | ||
311 | psmouse->pktcnt = 1; | ||
312 | |||
313 | } else { | ||
314 | |||
315 | /* | ||
316 | * High bit is 0 - that means that we indeed got a PS/2 | ||
317 | * packet in the middle of ALPS packet. | ||
318 | * | ||
319 | * There is also possibility that we got 6-byte ALPS | ||
320 | * packet followed by 3-byte packet from trackpoint. We | ||
321 | * can not distinguish between these 2 scenarios but | ||
322 | * becase the latter is unlikely to happen in course of | ||
323 | * normal operation (user would need to press all | ||
324 | * buttons on the pad and start moving trackpoint | ||
325 | * without touching the pad surface) we assume former. | ||
326 | * Even if we are wrong the wost thing that would happen | ||
327 | * the cursor would jump but we should not get protocol | ||
328 | * desynchronization. | ||
329 | */ | ||
330 | |||
331 | alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], | ||
332 | false); | ||
333 | |||
334 | /* | ||
335 | * Continue with the standard ALPS protocol handling, | ||
336 | * but make sure we won't process it as an interleaved | ||
337 | * packet again, which may happen if all buttons are | ||
338 | * pressed. To avoid this let's reset the 4th bit which | ||
339 | * is normally 1. | ||
340 | */ | ||
341 | psmouse->packet[3] = psmouse->packet[6] & 0xf7; | ||
342 | psmouse->pktcnt = 4; | ||
343 | } | ||
344 | |||
345 | return PSMOUSE_GOOD_DATA; | ||
346 | } | ||
347 | |||
348 | static void alps_flush_packet(unsigned long data) | ||
349 | { | ||
350 | struct psmouse *psmouse = (struct psmouse *)data; | ||
351 | |||
352 | serio_pause_rx(psmouse->ps2dev.serio); | ||
353 | |||
354 | if (psmouse->pktcnt == 6) { | ||
355 | |||
356 | /* | ||
357 | * We did not any more data in reasonable amount of time. | ||
358 | * Validate the last 3 bytes and process as a standard | ||
359 | * ALPS packet. | ||
360 | */ | ||
361 | if ((psmouse->packet[3] | | ||
362 | psmouse->packet[4] | | ||
363 | psmouse->packet[5]) & 0x80) { | ||
364 | dbg("refusing packet %x %x %x " | ||
365 | "(suspected interleaved ps/2)\n", | ||
366 | psmouse->packet[3], psmouse->packet[4], | ||
367 | psmouse->packet[5]); | ||
368 | } else { | ||
369 | alps_process_packet(psmouse); | ||
370 | } | ||
371 | psmouse->pktcnt = 0; | ||
372 | } | ||
373 | |||
374 | serio_continue_rx(psmouse->ps2dev.serio); | ||
375 | } | ||
376 | |||
191 | static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | 377 | static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) |
192 | { | 378 | { |
193 | struct alps_data *priv = psmouse->private; | 379 | struct alps_data *priv = psmouse->private; |
380 | const struct alps_model_info *model = priv->i; | ||
194 | 381 | ||
195 | if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ | 382 | if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ |
196 | if (psmouse->pktcnt == 3) { | 383 | if (psmouse->pktcnt == 3) { |
197 | alps_process_packet(psmouse); | 384 | alps_report_bare_ps2_packet(psmouse, psmouse->packet, |
385 | true); | ||
198 | return PSMOUSE_FULL_PACKET; | 386 | return PSMOUSE_FULL_PACKET; |
199 | } | 387 | } |
200 | return PSMOUSE_GOOD_DATA; | 388 | return PSMOUSE_GOOD_DATA; |
201 | } | 389 | } |
202 | 390 | ||
203 | if ((psmouse->packet[0] & priv->i->mask0) != priv->i->byte0) | 391 | /* Check for PS/2 packet stuffed in the middle of ALPS packet. */ |
392 | |||
393 | if ((model->flags & ALPS_PS2_INTERLEAVED) && | ||
394 | psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) { | ||
395 | return alps_handle_interleaved_ps2(psmouse); | ||
396 | } | ||
397 | |||
398 | if (!alps_is_valid_first_byte(model, psmouse->packet[0])) { | ||
399 | dbg("refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", | ||
400 | psmouse->packet[0], model->mask0, model->byte0); | ||
204 | return PSMOUSE_BAD_DATA; | 401 | return PSMOUSE_BAD_DATA; |
402 | } | ||
205 | 403 | ||
206 | /* Bytes 2 - 6 should have 0 in the highest bit */ | 404 | /* Bytes 2 - 6 should have 0 in the highest bit */ |
207 | if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 && | 405 | if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 && |
208 | (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) | 406 | (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { |
407 | dbg("refusing packet[%i] = %x\n", | ||
408 | psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]); | ||
209 | return PSMOUSE_BAD_DATA; | 409 | return PSMOUSE_BAD_DATA; |
410 | } | ||
210 | 411 | ||
211 | if (psmouse->pktcnt == 6) { | 412 | if (psmouse->pktcnt == 6) { |
212 | alps_process_packet(psmouse); | 413 | alps_process_packet(psmouse); |
@@ -393,15 +594,12 @@ static int alps_poll(struct psmouse *psmouse) | |||
393 | return 0; | 594 | return 0; |
394 | } | 595 | } |
395 | 596 | ||
396 | static int alps_hw_init(struct psmouse *psmouse, int *version) | 597 | static int alps_hw_init(struct psmouse *psmouse) |
397 | { | 598 | { |
398 | struct alps_data *priv = psmouse->private; | 599 | struct alps_data *priv = psmouse->private; |
600 | const struct alps_model_info *model = priv->i; | ||
399 | 601 | ||
400 | priv->i = alps_get_model(psmouse, version); | 602 | if ((model->flags & ALPS_PASS) && |
401 | if (!priv->i) | ||
402 | return -1; | ||
403 | |||
404 | if ((priv->i->flags & ALPS_PASS) && | ||
405 | alps_passthrough_mode(psmouse, true)) { | 603 | alps_passthrough_mode(psmouse, true)) { |
406 | return -1; | 604 | return -1; |
407 | } | 605 | } |
@@ -416,7 +614,7 @@ static int alps_hw_init(struct psmouse *psmouse, int *version) | |||
416 | return -1; | 614 | return -1; |
417 | } | 615 | } |
418 | 616 | ||
419 | if ((priv->i->flags & ALPS_PASS) && | 617 | if ((model->flags & ALPS_PASS) && |
420 | alps_passthrough_mode(psmouse, false)) { | 618 | alps_passthrough_mode(psmouse, false)) { |
421 | return -1; | 619 | return -1; |
422 | } | 620 | } |
@@ -432,12 +630,15 @@ static int alps_hw_init(struct psmouse *psmouse, int *version) | |||
432 | 630 | ||
433 | static int alps_reconnect(struct psmouse *psmouse) | 631 | static int alps_reconnect(struct psmouse *psmouse) |
434 | { | 632 | { |
633 | const struct alps_model_info *model; | ||
634 | |||
435 | psmouse_reset(psmouse); | 635 | psmouse_reset(psmouse); |
436 | 636 | ||
437 | if (alps_hw_init(psmouse, NULL)) | 637 | model = alps_get_model(psmouse, NULL); |
638 | if (!model) | ||
438 | return -1; | 639 | return -1; |
439 | 640 | ||
440 | return 0; | 641 | return alps_hw_init(psmouse); |
441 | } | 642 | } |
442 | 643 | ||
443 | static void alps_disconnect(struct psmouse *psmouse) | 644 | static void alps_disconnect(struct psmouse *psmouse) |
@@ -445,6 +646,7 @@ static void alps_disconnect(struct psmouse *psmouse) | |||
445 | struct alps_data *priv = psmouse->private; | 646 | struct alps_data *priv = psmouse->private; |
446 | 647 | ||
447 | psmouse_reset(psmouse); | 648 | psmouse_reset(psmouse); |
649 | del_timer_sync(&priv->timer); | ||
448 | input_unregister_device(priv->dev2); | 650 | input_unregister_device(priv->dev2); |
449 | kfree(priv); | 651 | kfree(priv); |
450 | } | 652 | } |
@@ -452,6 +654,7 @@ static void alps_disconnect(struct psmouse *psmouse) | |||
452 | int alps_init(struct psmouse *psmouse) | 654 | int alps_init(struct psmouse *psmouse) |
453 | { | 655 | { |
454 | struct alps_data *priv; | 656 | struct alps_data *priv; |
657 | const struct alps_model_info *model; | ||
455 | struct input_dev *dev1 = psmouse->dev, *dev2; | 658 | struct input_dev *dev1 = psmouse->dev, *dev2; |
456 | int version; | 659 | int version; |
457 | 660 | ||
@@ -461,35 +664,63 @@ int alps_init(struct psmouse *psmouse) | |||
461 | goto init_fail; | 664 | goto init_fail; |
462 | 665 | ||
463 | priv->dev2 = dev2; | 666 | priv->dev2 = dev2; |
667 | setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); | ||
668 | |||
464 | psmouse->private = priv; | 669 | psmouse->private = priv; |
465 | 670 | ||
466 | if (alps_hw_init(psmouse, &version)) | 671 | model = alps_get_model(psmouse, &version); |
672 | if (!model) | ||
673 | goto init_fail; | ||
674 | |||
675 | priv->i = model; | ||
676 | |||
677 | if (alps_hw_init(psmouse)) | ||
467 | goto init_fail; | 678 | goto init_fail; |
468 | 679 | ||
680 | /* | ||
681 | * Undo part of setup done for us by psmouse core since touchpad | ||
682 | * is not a relative device. | ||
683 | */ | ||
684 | __clear_bit(EV_REL, dev1->evbit); | ||
685 | __clear_bit(REL_X, dev1->relbit); | ||
686 | __clear_bit(REL_Y, dev1->relbit); | ||
687 | |||
688 | /* | ||
689 | * Now set up our capabilities. | ||
690 | */ | ||
469 | dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); | 691 | dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); |
470 | dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); | 692 | dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); |
471 | dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER); | 693 | dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER); |
472 | dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | 694 | dev1->keybit[BIT_WORD(BTN_LEFT)] |= |
473 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 695 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
474 | 696 | ||
475 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); | 697 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); |
476 | input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); | 698 | input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); |
477 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); | 699 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); |
478 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); | 700 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); |
479 | 701 | ||
480 | if (priv->i->flags & ALPS_WHEEL) { | 702 | if (model->flags & ALPS_WHEEL) { |
481 | dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); | 703 | dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); |
482 | dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL); | 704 | dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL); |
483 | } | 705 | } |
484 | 706 | ||
485 | if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { | 707 | if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { |
486 | dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD); | 708 | dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD); |
487 | dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK); | 709 | dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK); |
488 | } | 710 | } |
489 | 711 | ||
712 | if (model->flags & ALPS_FOUR_BUTTONS) { | ||
713 | dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0); | ||
714 | dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1); | ||
715 | dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2); | ||
716 | dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3); | ||
717 | } else { | ||
718 | dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE); | ||
719 | } | ||
720 | |||
490 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); | 721 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); |
491 | dev2->phys = priv->phys; | 722 | dev2->phys = priv->phys; |
492 | dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; | 723 | dev2->name = (model->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; |
493 | dev2->id.bustype = BUS_I8042; | 724 | dev2->id.bustype = BUS_I8042; |
494 | dev2->id.vendor = 0x0002; | 725 | dev2->id.vendor = 0x0002; |
495 | dev2->id.product = PSMOUSE_ALPS; | 726 | dev2->id.product = PSMOUSE_ALPS; |
@@ -497,9 +728,9 @@ int alps_init(struct psmouse *psmouse) | |||
497 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; | 728 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; |
498 | 729 | ||
499 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 730 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
500 | dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 731 | dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
501 | dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | 732 | dev2->keybit[BIT_WORD(BTN_LEFT)] = |
502 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 733 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); |
503 | 734 | ||
504 | if (input_register_device(priv->dev2)) | 735 | if (input_register_device(priv->dev2)) |
505 | goto init_fail; | 736 | goto init_fail; |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index bc87936fee1a..904ed8b3c8be 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
@@ -23,6 +23,7 @@ struct alps_data { | |||
23 | char phys[32]; /* Phys */ | 23 | char phys[32]; /* Phys */ |
24 | const struct alps_model_info *i;/* Info */ | 24 | const struct alps_model_info *i;/* Info */ |
25 | int prev_fin; /* Finger bit from previous packet */ | 25 | int prev_fin; /* Finger bit from previous packet */ |
26 | struct timer_list timer; | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | #ifdef CONFIG_MOUSE_PS2_ALPS | 29 | #ifdef CONFIG_MOUSE_PS2_ALPS |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 908b5b44052f..53ec7ddd1826 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -205,8 +205,8 @@ struct atp { | |||
205 | bool overflow_warned; | 205 | bool overflow_warned; |
206 | int x_old; /* last reported x/y, */ | 206 | int x_old; /* last reported x/y, */ |
207 | int y_old; /* used for smoothing */ | 207 | int y_old; /* used for smoothing */ |
208 | signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; | 208 | u8 xy_cur[ATP_XSENSORS + ATP_YSENSORS]; |
209 | signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; | 209 | u8 xy_old[ATP_XSENSORS + ATP_YSENSORS]; |
210 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; | 210 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; |
211 | int idlecount; /* number of empty packets */ | 211 | int idlecount; /* number of empty packets */ |
212 | struct work_struct work; | 212 | struct work_struct work; |
@@ -531,7 +531,7 @@ static void atp_complete_geyser_1_2(struct urb *urb) | |||
531 | 531 | ||
532 | for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { | 532 | for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { |
533 | /* accumulate the change */ | 533 | /* accumulate the change */ |
534 | signed char change = dev->xy_old[i] - dev->xy_cur[i]; | 534 | int change = dev->xy_old[i] - dev->xy_cur[i]; |
535 | dev->xy_acc[i] -= change; | 535 | dev->xy_acc[i] -= change; |
536 | 536 | ||
537 | /* prevent down drifting */ | 537 | /* prevent down drifting */ |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 0d1d33468b43..b89879bd860f 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -139,6 +139,7 @@ struct tp_finger { | |||
139 | /* trackpad finger data size, empirically at least ten fingers */ | 139 | /* trackpad finger data size, empirically at least ten fingers */ |
140 | #define SIZEOF_FINGER sizeof(struct tp_finger) | 140 | #define SIZEOF_FINGER sizeof(struct tp_finger) |
141 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) | 141 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) |
142 | #define MAX_FINGER_ORIENTATION 16384 | ||
142 | 143 | ||
143 | /* device-specific parameters */ | 144 | /* device-specific parameters */ |
144 | struct bcm5974_param { | 145 | struct bcm5974_param { |
@@ -284,6 +285,26 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
284 | input_set_abs_params(input_dev, ABS_Y, | 285 | input_set_abs_params(input_dev, ABS_Y, |
285 | 0, cfg->y.dim, cfg->y.fuzz, 0); | 286 | 0, cfg->y.dim, cfg->y.fuzz, 0); |
286 | 287 | ||
288 | /* finger touch area */ | ||
289 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
290 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
291 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, | ||
292 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
293 | /* finger approach area */ | ||
294 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, | ||
295 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
296 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, | ||
297 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
298 | /* finger orientation */ | ||
299 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, | ||
300 | -MAX_FINGER_ORIENTATION, | ||
301 | MAX_FINGER_ORIENTATION, 0, 0); | ||
302 | /* finger position */ | ||
303 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
304 | cfg->x.devmin, cfg->x.devmax, 0, 0); | ||
305 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
306 | cfg->y.devmin, cfg->y.devmax, 0, 0); | ||
307 | |||
287 | __set_bit(EV_KEY, input_dev->evbit); | 308 | __set_bit(EV_KEY, input_dev->evbit); |
288 | __set_bit(BTN_TOUCH, input_dev->keybit); | 309 | __set_bit(BTN_TOUCH, input_dev->keybit); |
289 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 310 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
@@ -310,13 +331,29 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
310 | return 0; | 331 | return 0; |
311 | } | 332 | } |
312 | 333 | ||
334 | static void report_finger_data(struct input_dev *input, | ||
335 | const struct bcm5974_config *cfg, | ||
336 | const struct tp_finger *f) | ||
337 | { | ||
338 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major)); | ||
339 | input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor)); | ||
340 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major)); | ||
341 | input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor)); | ||
342 | input_report_abs(input, ABS_MT_ORIENTATION, | ||
343 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); | ||
344 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); | ||
345 | input_report_abs(input, ABS_MT_POSITION_Y, | ||
346 | cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y)); | ||
347 | input_mt_sync(input); | ||
348 | } | ||
349 | |||
313 | /* report trackpad data as logical trackpad state */ | 350 | /* report trackpad data as logical trackpad state */ |
314 | static int report_tp_state(struct bcm5974 *dev, int size) | 351 | static int report_tp_state(struct bcm5974 *dev, int size) |
315 | { | 352 | { |
316 | const struct bcm5974_config *c = &dev->cfg; | 353 | const struct bcm5974_config *c = &dev->cfg; |
317 | const struct tp_finger *f; | 354 | const struct tp_finger *f; |
318 | struct input_dev *input = dev->input; | 355 | struct input_dev *input = dev->input; |
319 | int raw_p, raw_w, raw_x, raw_y, raw_n; | 356 | int raw_p, raw_w, raw_x, raw_y, raw_n, i; |
320 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; | 357 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; |
321 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | 358 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; |
322 | 359 | ||
@@ -329,6 +366,11 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
329 | 366 | ||
330 | /* always track the first finger; when detached, start over */ | 367 | /* always track the first finger; when detached, start over */ |
331 | if (raw_n) { | 368 | if (raw_n) { |
369 | |||
370 | /* report raw trackpad data */ | ||
371 | for (i = 0; i < raw_n; i++) | ||
372 | report_finger_data(input, c, &f[i]); | ||
373 | |||
332 | raw_p = raw2int(f->force_major); | 374 | raw_p = raw2int(f->force_major); |
333 | raw_w = raw2int(f->size_major); | 375 | raw_w = raw2int(f->size_major); |
334 | raw_x = raw2int(f->abs_x); | 376 | raw_x = raw2int(f->abs_x); |
@@ -761,7 +803,6 @@ static struct usb_driver bcm5974_driver = { | |||
761 | .disconnect = bcm5974_disconnect, | 803 | .disconnect = bcm5974_disconnect, |
762 | .suspend = bcm5974_suspend, | 804 | .suspend = bcm5974_suspend, |
763 | .resume = bcm5974_resume, | 805 | .resume = bcm5974_resume, |
764 | .reset_resume = bcm5974_resume, | ||
765 | .id_table = bcm5974_table, | 806 | .id_table = bcm5974_table, |
766 | .supports_autosuspend = 1, | 807 | .supports_autosuspend = 1, |
767 | }; | 808 | }; |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index fda35e615abf..112b4ee52ff2 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/input.h> | 16 | #include <linux/input.h> |
16 | #include <linux/serio.h> | 17 | #include <linux/serio.h> |
@@ -24,6 +25,10 @@ | |||
24 | printk(KERN_DEBUG format, ##arg); \ | 25 | printk(KERN_DEBUG format, ##arg); \ |
25 | } while (0) | 26 | } while (0) |
26 | 27 | ||
28 | static bool force_elantech; | ||
29 | module_param_named(force_elantech, force_elantech, bool, 0644); | ||
30 | MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default)."); | ||
31 | |||
27 | /* | 32 | /* |
28 | * Send a Synaptics style sliced query command | 33 | * Send a Synaptics style sliced query command |
29 | */ | 34 | */ |
@@ -180,14 +185,18 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
180 | int fingers; | 185 | int fingers; |
181 | static int old_fingers; | 186 | static int old_fingers; |
182 | 187 | ||
183 | if (etd->fw_version_maj == 0x01) { | 188 | if (etd->fw_version < 0x020000) { |
184 | /* byte 0: D U p1 p2 1 p3 R L | 189 | /* |
185 | byte 1: f 0 th tw x9 x8 y9 y8 */ | 190 | * byte 0: D U p1 p2 1 p3 R L |
191 | * byte 1: f 0 th tw x9 x8 y9 y8 | ||
192 | */ | ||
186 | fingers = ((packet[1] & 0x80) >> 7) + | 193 | fingers = ((packet[1] & 0x80) >> 7) + |
187 | ((packet[1] & 0x30) >> 4); | 194 | ((packet[1] & 0x30) >> 4); |
188 | } else { | 195 | } else { |
189 | /* byte 0: n1 n0 p2 p1 1 p3 R L | 196 | /* |
190 | byte 1: 0 0 0 0 x9 x8 y9 y8 */ | 197 | * byte 0: n1 n0 p2 p1 1 p3 R L |
198 | * byte 1: 0 0 0 0 x9 x8 y9 y8 | ||
199 | */ | ||
191 | fingers = (packet[0] & 0xc0) >> 6; | 200 | fingers = (packet[0] & 0xc0) >> 6; |
192 | } | 201 | } |
193 | 202 | ||
@@ -201,13 +210,15 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
201 | 210 | ||
202 | input_report_key(dev, BTN_TOUCH, fingers != 0); | 211 | input_report_key(dev, BTN_TOUCH, fingers != 0); |
203 | 212 | ||
204 | /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 | 213 | /* |
205 | byte 3: y7 y6 y5 y4 y3 y2 y1 y0 */ | 214 | * byte 2: x7 x6 x5 x4 x3 x2 x1 x0 |
215 | * byte 3: y7 y6 y5 y4 y3 y2 y1 y0 | ||
216 | */ | ||
206 | if (fingers) { | 217 | if (fingers) { |
207 | input_report_abs(dev, ABS_X, | 218 | input_report_abs(dev, ABS_X, |
208 | ((packet[1] & 0x0c) << 6) | packet[2]); | 219 | ((packet[1] & 0x0c) << 6) | packet[2]); |
209 | input_report_abs(dev, ABS_Y, ETP_YMAX_V1 - | 220 | input_report_abs(dev, ABS_Y, |
210 | (((packet[1] & 0x03) << 8) | packet[3])); | 221 | ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3])); |
211 | } | 222 | } |
212 | 223 | ||
213 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 224 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
@@ -216,7 +227,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
216 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 227 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
217 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 228 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
218 | 229 | ||
219 | if ((etd->fw_version_maj == 0x01) && | 230 | if (etd->fw_version < 0x020000 && |
220 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 231 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
221 | /* rocker up */ | 232 | /* rocker up */ |
222 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); | 233 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); |
@@ -246,34 +257,47 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
246 | 257 | ||
247 | switch (fingers) { | 258 | switch (fingers) { |
248 | case 1: | 259 | case 1: |
249 | /* byte 1: x15 x14 x13 x12 x11 x10 x9 x8 | 260 | /* |
250 | byte 2: x7 x6 x5 x4 x4 x2 x1 x0 */ | 261 | * byte 1: . . . . . x10 x9 x8 |
251 | input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]); | 262 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 |
252 | /* byte 4: y15 y14 y13 y12 y11 y10 y8 y8 | 263 | */ |
253 | byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */ | 264 | input_report_abs(dev, ABS_X, |
254 | input_report_abs(dev, ABS_Y, ETP_YMAX_V2 - | 265 | ((packet[1] & 0x07) << 8) | packet[2]); |
255 | ((packet[4] << 8) | packet[5])); | 266 | /* |
267 | * byte 4: . . . . . . y9 y8 | ||
268 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | ||
269 | */ | ||
270 | input_report_abs(dev, ABS_Y, | ||
271 | ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5])); | ||
256 | break; | 272 | break; |
257 | 273 | ||
258 | case 2: | 274 | case 2: |
259 | /* The coordinate of each finger is reported separately with | 275 | /* |
260 | a lower resolution for two finger touches */ | 276 | * The coordinate of each finger is reported separately |
261 | /* byte 0: . . ay8 ax8 . . . . | 277 | * with a lower resolution for two finger touches: |
262 | byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */ | 278 | * byte 0: . . ay8 ax8 . . . . |
279 | * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | ||
280 | */ | ||
263 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; | 281 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; |
264 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ | 282 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ |
265 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); | 283 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); |
266 | /* byte 3: . . by8 bx8 . . . . | 284 | /* |
267 | byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */ | 285 | * byte 3: . . by8 bx8 . . . . |
286 | * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 | ||
287 | */ | ||
268 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; | 288 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; |
269 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ | 289 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ |
270 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); | 290 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); |
271 | /* For compatibility with the X Synaptics driver scale up one | 291 | /* |
272 | coordinate and report as ordinary mouse movent */ | 292 | * For compatibility with the X Synaptics driver scale up |
293 | * one coordinate and report as ordinary mouse movent | ||
294 | */ | ||
273 | input_report_abs(dev, ABS_X, x1 << 2); | 295 | input_report_abs(dev, ABS_X, x1 << 2); |
274 | input_report_abs(dev, ABS_Y, y1 << 2); | 296 | input_report_abs(dev, ABS_Y, y1 << 2); |
275 | /* For compatibility with the proprietary X Elantech driver | 297 | /* |
276 | report both coordinates as hat coordinates */ | 298 | * For compatibility with the proprietary X Elantech driver |
299 | * report both coordinates as hat coordinates | ||
300 | */ | ||
277 | input_report_abs(dev, ABS_HAT0X, x1); | 301 | input_report_abs(dev, ABS_HAT0X, x1); |
278 | input_report_abs(dev, ABS_HAT0Y, y1); | 302 | input_report_abs(dev, ABS_HAT0Y, y1); |
279 | input_report_abs(dev, ABS_HAT1X, x2); | 303 | input_report_abs(dev, ABS_HAT1X, x2); |
@@ -297,7 +321,7 @@ static int elantech_check_parity_v1(struct psmouse *psmouse) | |||
297 | unsigned char p1, p2, p3; | 321 | unsigned char p1, p2, p3; |
298 | 322 | ||
299 | /* Parity bits are placed differently */ | 323 | /* Parity bits are placed differently */ |
300 | if (etd->fw_version_maj == 0x01) { | 324 | if (etd->fw_version < 0x020000) { |
301 | /* byte 0: D U p1 p2 1 p3 R L */ | 325 | /* byte 0: D U p1 p2 1 p3 R L */ |
302 | p1 = (packet[0] & 0x20) >> 5; | 326 | p1 = (packet[0] & 0x20) >> 5; |
303 | p2 = (packet[0] & 0x10) >> 4; | 327 | p2 = (packet[0] & 0x10) >> 4; |
@@ -420,6 +444,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
420 | 444 | ||
421 | __set_bit(EV_KEY, dev->evbit); | 445 | __set_bit(EV_KEY, dev->evbit); |
422 | __set_bit(EV_ABS, dev->evbit); | 446 | __set_bit(EV_ABS, dev->evbit); |
447 | __clear_bit(EV_REL, dev->evbit); | ||
423 | 448 | ||
424 | __set_bit(BTN_LEFT, dev->keybit); | 449 | __set_bit(BTN_LEFT, dev->keybit); |
425 | __set_bit(BTN_RIGHT, dev->keybit); | 450 | __set_bit(BTN_RIGHT, dev->keybit); |
@@ -432,7 +457,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
432 | switch (etd->hw_version) { | 457 | switch (etd->hw_version) { |
433 | case 1: | 458 | case 1: |
434 | /* Rocker button */ | 459 | /* Rocker button */ |
435 | if ((etd->fw_version_maj == 0x01) && | 460 | if (etd->fw_version < 0x020000 && |
436 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 461 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
437 | __set_bit(BTN_FORWARD, dev->keybit); | 462 | __set_bit(BTN_FORWARD, dev->keybit); |
438 | __set_bit(BTN_BACK, dev->keybit); | 463 | __set_bit(BTN_BACK, dev->keybit); |
@@ -594,8 +619,12 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
594 | param[0], param[1], param[2]); | 619 | param[0], param[1], param[2]); |
595 | 620 | ||
596 | if (param[0] == 0 || param[1] != 0) { | 621 | if (param[0] == 0 || param[1] != 0) { |
597 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); | 622 | if (!force_elantech) { |
598 | return -1; | 623 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); |
624 | return -1; | ||
625 | } | ||
626 | |||
627 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n"); | ||
599 | } | 628 | } |
600 | 629 | ||
601 | if (set_properties) { | 630 | if (set_properties) { |
@@ -657,14 +686,14 @@ int elantech_init(struct psmouse *psmouse) | |||
657 | pr_err("elantech.c: failed to query firmware version.\n"); | 686 | pr_err("elantech.c: failed to query firmware version.\n"); |
658 | goto init_fail; | 687 | goto init_fail; |
659 | } | 688 | } |
660 | etd->fw_version_maj = param[0]; | 689 | |
661 | etd->fw_version_min = param[2]; | 690 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; |
662 | 691 | ||
663 | /* | 692 | /* |
664 | * Assume every version greater than this is new EeePC style | 693 | * Assume every version greater than this is new EeePC style |
665 | * hardware with 6 byte packets | 694 | * hardware with 6 byte packets |
666 | */ | 695 | */ |
667 | if (etd->fw_version_maj >= 0x02 && etd->fw_version_min >= 0x30) { | 696 | if (etd->fw_version >= 0x020030) { |
668 | etd->hw_version = 2; | 697 | etd->hw_version = 2; |
669 | /* For now show extra debug information */ | 698 | /* For now show extra debug information */ |
670 | etd->debug = 1; | 699 | etd->debug = 1; |
@@ -674,8 +703,9 @@ int elantech_init(struct psmouse *psmouse) | |||
674 | etd->hw_version = 1; | 703 | etd->hw_version = 1; |
675 | etd->paritycheck = 1; | 704 | etd->paritycheck = 1; |
676 | } | 705 | } |
677 | pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n", | 706 | |
678 | etd->hw_version, etd->fw_version_maj, etd->fw_version_min); | 707 | pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d.%d\n", |
708 | etd->hw_version, param[0], param[1], param[2]); | ||
679 | 709 | ||
680 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { | 710 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { |
681 | pr_err("elantech.c: failed to query capabilities.\n"); | 711 | pr_err("elantech.c: failed to query capabilities.\n"); |
@@ -690,8 +720,8 @@ int elantech_init(struct psmouse *psmouse) | |||
690 | * a touch action starts causing the mouse cursor or scrolled page | 720 | * a touch action starts causing the mouse cursor or scrolled page |
691 | * to jump. Enable a workaround. | 721 | * to jump. Enable a workaround. |
692 | */ | 722 | */ |
693 | if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) { | 723 | if (etd->fw_version == 0x020022) { |
694 | pr_info("elantech.c: firmware version 2.34 detected, " | 724 | pr_info("elantech.c: firmware version 2.0.34 detected, " |
695 | "enabling jumpy cursor workaround\n"); | 725 | "enabling jumpy cursor workaround\n"); |
696 | etd->jumpy_cursor = 1; | 726 | etd->jumpy_cursor = 1; |
697 | } | 727 | } |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index feac5f7af966..ac57bde1bb9f 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -100,11 +100,10 @@ struct elantech_data { | |||
100 | unsigned char reg_26; | 100 | unsigned char reg_26; |
101 | unsigned char debug; | 101 | unsigned char debug; |
102 | unsigned char capabilities; | 102 | unsigned char capabilities; |
103 | unsigned char fw_version_maj; | ||
104 | unsigned char fw_version_min; | ||
105 | unsigned char hw_version; | ||
106 | unsigned char paritycheck; | 103 | unsigned char paritycheck; |
107 | unsigned char jumpy_cursor; | 104 | unsigned char jumpy_cursor; |
105 | unsigned char hw_version; | ||
106 | unsigned int fw_version; | ||
108 | unsigned char parity[256]; | 107 | unsigned char parity[256]; |
109 | }; | 108 | }; |
110 | 109 | ||
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index de1e553028b7..08d66d820d2b 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -30,6 +30,7 @@ | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #define DEBUG | 32 | #define DEBUG |
33 | #include <linux/slab.h> | ||
33 | #include <linux/input.h> | 34 | #include <linux/input.h> |
34 | #include <linux/serio.h> | 35 | #include <linux/serio.h> |
35 | #include <linux/libps2.h> | 36 | #include <linux/libps2.h> |
@@ -68,10 +69,6 @@ module_param(post_interrupt_delay, int, 0644); | |||
68 | MODULE_PARM_DESC(post_interrupt_delay, | 69 | MODULE_PARM_DESC(post_interrupt_delay, |
69 | "delay (ms) before recal after recal interrupt detected"); | 70 | "delay (ms) before recal after recal interrupt detected"); |
70 | 71 | ||
71 | static int autorecal = 1; | ||
72 | module_param(autorecal, int, 0644); | ||
73 | MODULE_PARM_DESC(autorecal, "enable recalibration in the driver"); | ||
74 | |||
75 | /* | 72 | /* |
76 | * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" | 73 | * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" |
77 | * above the pad and still have it send packets. This causes a jump cursor | 74 | * above the pad and still have it send packets. This causes a jump cursor |
@@ -427,22 +424,8 @@ static void hgpk_recalib_work(struct work_struct *work) | |||
427 | 424 | ||
428 | static int hgpk_register(struct psmouse *psmouse) | 425 | static int hgpk_register(struct psmouse *psmouse) |
429 | { | 426 | { |
430 | struct input_dev *dev = psmouse->dev; | ||
431 | int err; | 427 | int err; |
432 | 428 | ||
433 | /* unset the things that psmouse-base sets which we don't have */ | ||
434 | __clear_bit(BTN_MIDDLE, dev->keybit); | ||
435 | |||
436 | /* set the things we do have */ | ||
437 | __set_bit(EV_KEY, dev->evbit); | ||
438 | __set_bit(EV_REL, dev->evbit); | ||
439 | |||
440 | __set_bit(REL_X, dev->relbit); | ||
441 | __set_bit(REL_Y, dev->relbit); | ||
442 | |||
443 | __set_bit(BTN_LEFT, dev->keybit); | ||
444 | __set_bit(BTN_RIGHT, dev->keybit); | ||
445 | |||
446 | /* register handlers */ | 429 | /* register handlers */ |
447 | psmouse->protocol_handler = hgpk_process_byte; | 430 | psmouse->protocol_handler = hgpk_process_byte; |
448 | psmouse->poll = hgpk_poll; | 431 | psmouse->poll = hgpk_poll; |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 82811558ec33..c31ad11df6bb 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/serio.h> | 16 | #include <linux/serio.h> |
17 | #include <linux/libps2.h> | 17 | #include <linux/libps2.h> |
18 | #include <linux/dmi.h> | 18 | #include <linux/dmi.h> |
19 | #include <linux/slab.h> | ||
19 | 20 | ||
20 | #include "psmouse.h" | 21 | #include "psmouse.h" |
21 | #include "lifebook.h" | 22 | #include "lifebook.h" |
@@ -25,11 +26,13 @@ struct lifebook_data { | |||
25 | char phys[32]; | 26 | char phys[32]; |
26 | }; | 27 | }; |
27 | 28 | ||
29 | static bool lifebook_present; | ||
30 | |||
28 | static const char *desired_serio_phys; | 31 | static const char *desired_serio_phys; |
29 | 32 | ||
30 | static int lifebook_set_serio_phys(const struct dmi_system_id *d) | 33 | static int lifebook_limit_serio3(const struct dmi_system_id *d) |
31 | { | 34 | { |
32 | desired_serio_phys = d->driver_data; | 35 | desired_serio_phys = "isa0060/serio3"; |
33 | return 0; | 36 | return 0; |
34 | } | 37 | } |
35 | 38 | ||
@@ -41,53 +44,58 @@ static int lifebook_set_6byte_proto(const struct dmi_system_id *d) | |||
41 | return 0; | 44 | return 0; |
42 | } | 45 | } |
43 | 46 | ||
44 | static const struct dmi_system_id lifebook_dmi_table[] = { | 47 | static const struct dmi_system_id __initconst lifebook_dmi_table[] = { |
45 | { | 48 | { |
46 | .ident = "FLORA-ie 55mi", | 49 | /* FLORA-ie 55mi */ |
47 | .matches = { | 50 | .matches = { |
48 | DMI_MATCH(DMI_PRODUCT_NAME, "FLORA-ie 55mi"), | 51 | DMI_MATCH(DMI_PRODUCT_NAME, "FLORA-ie 55mi"), |
49 | }, | 52 | }, |
50 | }, | 53 | }, |
51 | { | 54 | { |
52 | .ident = "LifeBook B", | 55 | /* LifeBook B */ |
56 | .matches = { | ||
57 | DMI_MATCH(DMI_PRODUCT_NAME, "Lifebook B Series"), | ||
58 | }, | ||
59 | }, | ||
60 | { | ||
61 | /* LifeBook B */ | ||
53 | .matches = { | 62 | .matches = { |
54 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), | 63 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), |
55 | }, | 64 | }, |
56 | }, | 65 | }, |
57 | { | 66 | { |
58 | .ident = "Lifebook B", | 67 | /* Lifebook B */ |
59 | .matches = { | 68 | .matches = { |
60 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), | 69 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), |
61 | }, | 70 | }, |
62 | }, | 71 | }, |
63 | { | 72 | { |
64 | .ident = "Lifebook B-2130", | 73 | /* Lifebook B-2130 */ |
65 | .matches = { | 74 | .matches = { |
66 | DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"), | 75 | DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"), |
67 | }, | 76 | }, |
68 | }, | 77 | }, |
69 | { | 78 | { |
70 | .ident = "Lifebook B213x/B2150", | 79 | /* Lifebook B213x/B2150 */ |
71 | .matches = { | 80 | .matches = { |
72 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), | 81 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), |
73 | }, | 82 | }, |
74 | }, | 83 | }, |
75 | { | 84 | { |
76 | .ident = "Zephyr", | 85 | /* Zephyr */ |
77 | .matches = { | 86 | .matches = { |
78 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), | 87 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), |
79 | }, | 88 | }, |
80 | }, | 89 | }, |
81 | { | 90 | { |
82 | .ident = "CF-18", | 91 | /* Panasonic CF-18 */ |
83 | .matches = { | 92 | .matches = { |
84 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), | 93 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), |
85 | }, | 94 | }, |
86 | .callback = lifebook_set_serio_phys, | 95 | .callback = lifebook_limit_serio3, |
87 | .driver_data = "isa0060/serio3", | ||
88 | }, | 96 | }, |
89 | { | 97 | { |
90 | .ident = "Panasonic CF-28", | 98 | /* Panasonic CF-28 */ |
91 | .matches = { | 99 | .matches = { |
92 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | 100 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), |
93 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"), | 101 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"), |
@@ -95,7 +103,7 @@ static const struct dmi_system_id lifebook_dmi_table[] = { | |||
95 | .callback = lifebook_set_6byte_proto, | 103 | .callback = lifebook_set_6byte_proto, |
96 | }, | 104 | }, |
97 | { | 105 | { |
98 | .ident = "Panasonic CF-29", | 106 | /* Panasonic CF-29 */ |
99 | .matches = { | 107 | .matches = { |
100 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | 108 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), |
101 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), | 109 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), |
@@ -103,14 +111,14 @@ static const struct dmi_system_id lifebook_dmi_table[] = { | |||
103 | .callback = lifebook_set_6byte_proto, | 111 | .callback = lifebook_set_6byte_proto, |
104 | }, | 112 | }, |
105 | { | 113 | { |
106 | .ident = "CF-72", | 114 | /* Panasonic CF-72 */ |
107 | .matches = { | 115 | .matches = { |
108 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"), | 116 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"), |
109 | }, | 117 | }, |
110 | .callback = lifebook_set_6byte_proto, | 118 | .callback = lifebook_set_6byte_proto, |
111 | }, | 119 | }, |
112 | { | 120 | { |
113 | .ident = "Lifebook B142", | 121 | /* Lifebook B142 */ |
114 | .matches = { | 122 | .matches = { |
115 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), | 123 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), |
116 | }, | 124 | }, |
@@ -118,6 +126,11 @@ static const struct dmi_system_id lifebook_dmi_table[] = { | |||
118 | { } | 126 | { } |
119 | }; | 127 | }; |
120 | 128 | ||
129 | void __init lifebook_module_init(void) | ||
130 | { | ||
131 | lifebook_present = dmi_check_system(lifebook_dmi_table); | ||
132 | } | ||
133 | |||
121 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | 134 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) |
122 | { | 135 | { |
123 | struct lifebook_data *priv = psmouse->private; | 136 | struct lifebook_data *priv = psmouse->private; |
@@ -198,10 +211,10 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) | |||
198 | return -1; | 211 | return -1; |
199 | 212 | ||
200 | /* | 213 | /* |
201 | Enable absolute output -- ps2_command fails always but if | 214 | * Enable absolute output -- ps2_command fails always but if |
202 | you leave this call out the touchsreen will never send | 215 | * you leave this call out the touchsreen will never send |
203 | absolute coordinates | 216 | * absolute coordinates |
204 | */ | 217 | */ |
205 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; | 218 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; |
206 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | 219 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); |
207 | 220 | ||
@@ -243,7 +256,7 @@ static void lifebook_disconnect(struct psmouse *psmouse) | |||
243 | 256 | ||
244 | int lifebook_detect(struct psmouse *psmouse, bool set_properties) | 257 | int lifebook_detect(struct psmouse *psmouse, bool set_properties) |
245 | { | 258 | { |
246 | if (!dmi_check_system(lifebook_dmi_table)) | 259 | if (!lifebook_present) |
247 | return -1; | 260 | return -1; |
248 | 261 | ||
249 | if (desired_serio_phys && | 262 | if (desired_serio_phys && |
@@ -283,8 +296,8 @@ static int lifebook_create_relative_device(struct psmouse *psmouse) | |||
283 | 296 | ||
284 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 297 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
285 | dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 298 | dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
286 | dev2->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | | 299 | dev2->keybit[BIT_WORD(BTN_LEFT)] = |
287 | BIT_MASK(BTN_RIGHT); | 300 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
288 | 301 | ||
289 | error = input_register_device(priv->dev2); | 302 | error = input_register_device(priv->dev2); |
290 | if (error) | 303 | if (error) |
@@ -309,6 +322,7 @@ int lifebook_init(struct psmouse *psmouse) | |||
309 | 322 | ||
310 | dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); | 323 | dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); |
311 | dev1->relbit[0] = 0; | 324 | dev1->relbit[0] = 0; |
325 | dev1->keybit[BIT_WORD(BTN_MOUSE)] = 0; | ||
312 | dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 326 | dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
313 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); | 327 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); |
314 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); | 328 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); |
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index 407cb226bc0a..4c4326c6f504 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h | |||
@@ -12,9 +12,13 @@ | |||
12 | #define _LIFEBOOK_H | 12 | #define _LIFEBOOK_H |
13 | 13 | ||
14 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK | 14 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK |
15 | void lifebook_module_init(void); | ||
15 | int lifebook_detect(struct psmouse *psmouse, bool set_properties); | 16 | int lifebook_detect(struct psmouse *psmouse, bool set_properties); |
16 | int lifebook_init(struct psmouse *psmouse); | 17 | int lifebook_init(struct psmouse *psmouse); |
17 | #else | 18 | #else |
19 | inline void lifebook_module_init(void) | ||
20 | { | ||
21 | } | ||
18 | inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) | 22 | inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) |
19 | { | 23 | { |
20 | return -ENOSYS; | 24 | return -ENOSYS; |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index ab5dc5f5fd83..543c240a85f2 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -404,8 +404,8 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
404 | } | 404 | } |
405 | } | 405 | } |
406 | 406 | ||
407 | if (buttons < 3) | 407 | if (buttons >= 3) |
408 | __clear_bit(BTN_MIDDLE, psmouse->dev->keybit); | 408 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
409 | 409 | ||
410 | if (model_info) | 410 | if (model_info) |
411 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); | 411 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 07c53798301a..a3c97315a473 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -110,6 +110,7 @@ static struct workqueue_struct *kpsmoused_wq; | |||
110 | struct psmouse_protocol { | 110 | struct psmouse_protocol { |
111 | enum psmouse_type type; | 111 | enum psmouse_type type; |
112 | bool maxproto; | 112 | bool maxproto; |
113 | bool ignore_parity; /* Protocol should ignore parity errors from KBC */ | ||
113 | const char *name; | 114 | const char *name; |
114 | const char *alias; | 115 | const char *alias; |
115 | int (*detect)(struct psmouse *, bool); | 116 | int (*detect)(struct psmouse *, bool); |
@@ -288,7 +289,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
288 | if (psmouse->state == PSMOUSE_IGNORE) | 289 | if (psmouse->state == PSMOUSE_IGNORE) |
289 | goto out; | 290 | goto out; |
290 | 291 | ||
291 | if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) { | 292 | if (unlikely((flags & SERIO_TIMEOUT) || |
293 | ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { | ||
294 | |||
292 | if (psmouse->state == PSMOUSE_ACTIVATED) | 295 | if (psmouse->state == PSMOUSE_ACTIVATED) |
293 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", | 296 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", |
294 | flags & SERIO_TIMEOUT ? " timeout" : "", | 297 | flags & SERIO_TIMEOUT ? " timeout" : "", |
@@ -425,6 +428,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties) | |||
425 | return -1; | 428 | return -1; |
426 | 429 | ||
427 | if (set_properties) { | 430 | if (set_properties) { |
431 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
428 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); | 432 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
429 | __set_bit(BTN_SIDE, psmouse->dev->keybit); | 433 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
430 | __set_bit(REL_WHEEL, psmouse->dev->relbit); | 434 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
@@ -460,8 +464,10 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) | |||
460 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 464 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
461 | __set_bit(REL_WHEEL, psmouse->dev->relbit); | 465 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
462 | 466 | ||
463 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 467 | if (!psmouse->vendor) |
464 | if (!psmouse->name) psmouse->name = "Wheel Mouse"; | 468 | psmouse->vendor = "Generic"; |
469 | if (!psmouse->name) | ||
470 | psmouse->name = "Wheel Mouse"; | ||
465 | psmouse->pktsize = 4; | 471 | psmouse->pktsize = 4; |
466 | } | 472 | } |
467 | 473 | ||
@@ -504,8 +510,10 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) | |||
504 | __set_bit(BTN_SIDE, psmouse->dev->keybit); | 510 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
505 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); | 511 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
506 | 512 | ||
507 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 513 | if (!psmouse->vendor) |
508 | if (!psmouse->name) psmouse->name = "Explorer Mouse"; | 514 | psmouse->vendor = "Generic"; |
515 | if (!psmouse->name) | ||
516 | psmouse->name = "Explorer Mouse"; | ||
509 | psmouse->pktsize = 4; | 517 | psmouse->pktsize = 4; |
510 | } | 518 | } |
511 | 519 | ||
@@ -536,6 +544,7 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties) | |||
536 | return -1; | 544 | return -1; |
537 | 545 | ||
538 | if (set_properties) { | 546 | if (set_properties) { |
547 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
539 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); | 548 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
540 | 549 | ||
541 | psmouse->vendor = "Kensington"; | 550 | psmouse->vendor = "Kensington"; |
@@ -551,8 +560,16 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties) | |||
551 | static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) | 560 | static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) |
552 | { | 561 | { |
553 | if (set_properties) { | 562 | if (set_properties) { |
554 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 563 | if (!psmouse->vendor) |
555 | if (!psmouse->name) psmouse->name = "Mouse"; | 564 | psmouse->vendor = "Generic"; |
565 | if (!psmouse->name) | ||
566 | psmouse->name = "Mouse"; | ||
567 | |||
568 | /* | ||
569 | * We have no way of figuring true number of buttons so let's | ||
570 | * assume that the device has 3. | ||
571 | */ | ||
572 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
556 | } | 573 | } |
557 | 574 | ||
558 | return 0; | 575 | return 0; |
@@ -567,6 +584,8 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties) | |||
567 | if (set_properties) { | 584 | if (set_properties) { |
568 | psmouse->vendor = "Cortron"; | 585 | psmouse->vendor = "Cortron"; |
569 | psmouse->name = "PS/2 Trackball"; | 586 | psmouse->name = "PS/2 Trackball"; |
587 | |||
588 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
570 | __set_bit(BTN_SIDE, psmouse->dev->keybit); | 589 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
571 | } | 590 | } |
572 | 591 | ||
@@ -611,8 +630,15 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
611 | synaptics_hardware = true; | 630 | synaptics_hardware = true; |
612 | 631 | ||
613 | if (max_proto > PSMOUSE_IMEX) { | 632 | if (max_proto > PSMOUSE_IMEX) { |
614 | if (!set_properties || synaptics_init(psmouse) == 0) | 633 | /* |
634 | * Try activating protocol, but check if support is enabled first, since | ||
635 | * we try detecting Synaptics even when protocol is disabled. | ||
636 | */ | ||
637 | if (synaptics_supported() && | ||
638 | (!set_properties || synaptics_init(psmouse) == 0)) { | ||
615 | return PSMOUSE_SYNAPTICS; | 639 | return PSMOUSE_SYNAPTICS; |
640 | } | ||
641 | |||
616 | /* | 642 | /* |
617 | * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). | 643 | * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). |
618 | * Unfortunately Logitech/Genius probes confuse some firmware versions so | 644 | * Unfortunately Logitech/Genius probes confuse some firmware versions so |
@@ -667,19 +693,6 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
667 | max_proto = PSMOUSE_IMEX; | 693 | max_proto = PSMOUSE_IMEX; |
668 | } | 694 | } |
669 | 695 | ||
670 | /* | ||
671 | * Try Finger Sensing Pad | ||
672 | */ | ||
673 | if (max_proto > PSMOUSE_IMEX) { | ||
674 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
675 | if (!set_properties || fsp_init(psmouse) == 0) | ||
676 | return PSMOUSE_FSP; | ||
677 | /* | ||
678 | * Init failed, try basic relative protocols | ||
679 | */ | ||
680 | max_proto = PSMOUSE_IMEX; | ||
681 | } | ||
682 | } | ||
683 | 696 | ||
684 | if (max_proto > PSMOUSE_IMEX) { | 697 | if (max_proto > PSMOUSE_IMEX) { |
685 | if (genius_detect(psmouse, set_properties) == 0) | 698 | if (genius_detect(psmouse, set_properties) == 0) |
@@ -696,6 +709,21 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
696 | } | 709 | } |
697 | 710 | ||
698 | /* | 711 | /* |
712 | * Try Finger Sensing Pad. We do it here because its probe upsets | ||
713 | * Trackpoint devices (causing TP_READ_ID command to time out). | ||
714 | */ | ||
715 | if (max_proto > PSMOUSE_IMEX) { | ||
716 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
717 | if (!set_properties || fsp_init(psmouse) == 0) | ||
718 | return PSMOUSE_FSP; | ||
719 | /* | ||
720 | * Init failed, try basic relative protocols | ||
721 | */ | ||
722 | max_proto = PSMOUSE_IMEX; | ||
723 | } | ||
724 | } | ||
725 | |||
726 | /* | ||
699 | * Reset to defaults in case the device got confused by extended | 727 | * Reset to defaults in case the device got confused by extended |
700 | * protocol probes. Note that we follow up with full reset because | 728 | * protocol probes. Note that we follow up with full reset because |
701 | * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. | 729 | * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. |
@@ -734,6 +762,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
734 | .name = "PS/2", | 762 | .name = "PS/2", |
735 | .alias = "bare", | 763 | .alias = "bare", |
736 | .maxproto = true, | 764 | .maxproto = true, |
765 | .ignore_parity = true, | ||
737 | .detect = ps2bare_detect, | 766 | .detect = ps2bare_detect, |
738 | }, | 767 | }, |
739 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | 768 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP |
@@ -761,6 +790,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
761 | .name = "ImPS/2", | 790 | .name = "ImPS/2", |
762 | .alias = "imps", | 791 | .alias = "imps", |
763 | .maxproto = true, | 792 | .maxproto = true, |
793 | .ignore_parity = true, | ||
764 | .detect = intellimouse_detect, | 794 | .detect = intellimouse_detect, |
765 | }, | 795 | }, |
766 | { | 796 | { |
@@ -768,6 +798,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
768 | .name = "ImExPS/2", | 798 | .name = "ImExPS/2", |
769 | .alias = "exps", | 799 | .alias = "exps", |
770 | .maxproto = true, | 800 | .maxproto = true, |
801 | .ignore_parity = true, | ||
771 | .detect = im_explorer_detect, | 802 | .detect = im_explorer_detect, |
772 | }, | 803 | }, |
773 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 804 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
@@ -1116,12 +1147,22 @@ static void psmouse_cleanup(struct serio *serio) | |||
1116 | psmouse_deactivate(parent); | 1147 | psmouse_deactivate(parent); |
1117 | } | 1148 | } |
1118 | 1149 | ||
1119 | psmouse_deactivate(psmouse); | 1150 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
1151 | |||
1152 | /* | ||
1153 | * Disable stream mode so cleanup routine can proceed undisturbed. | ||
1154 | */ | ||
1155 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) | ||
1156 | printk(KERN_WARNING "psmouse.c: Failed to disable mouse on %s\n", | ||
1157 | psmouse->ps2dev.serio->phys); | ||
1120 | 1158 | ||
1121 | if (psmouse->cleanup) | 1159 | if (psmouse->cleanup) |
1122 | psmouse->cleanup(psmouse); | 1160 | psmouse->cleanup(psmouse); |
1123 | 1161 | ||
1124 | psmouse_reset(psmouse); | 1162 | /* |
1163 | * Reset the mouse to defaults (bare PS/2 protocol). | ||
1164 | */ | ||
1165 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); | ||
1125 | 1166 | ||
1126 | /* | 1167 | /* |
1127 | * Some boxes, such as HP nx7400, get terribly confused if mouse | 1168 | * Some boxes, such as HP nx7400, get terribly confused if mouse |
@@ -1184,15 +1225,17 @@ static void psmouse_disconnect(struct serio *serio) | |||
1184 | mutex_unlock(&psmouse_mutex); | 1225 | mutex_unlock(&psmouse_mutex); |
1185 | } | 1226 | } |
1186 | 1227 | ||
1187 | static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto) | 1228 | static int psmouse_switch_protocol(struct psmouse *psmouse, |
1229 | const struct psmouse_protocol *proto) | ||
1188 | { | 1230 | { |
1231 | const struct psmouse_protocol *selected_proto; | ||
1189 | struct input_dev *input_dev = psmouse->dev; | 1232 | struct input_dev *input_dev = psmouse->dev; |
1190 | 1233 | ||
1191 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; | 1234 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; |
1192 | 1235 | ||
1193 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 1236 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
1194 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | | 1237 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] = |
1195 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 1238 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
1196 | input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 1239 | input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
1197 | 1240 | ||
1198 | psmouse->set_rate = psmouse_set_rate; | 1241 | psmouse->set_rate = psmouse_set_rate; |
@@ -1209,10 +1252,14 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse | |||
1209 | return -1; | 1252 | return -1; |
1210 | 1253 | ||
1211 | psmouse->type = proto->type; | 1254 | psmouse->type = proto->type; |
1212 | } | 1255 | selected_proto = proto; |
1213 | else | 1256 | } else { |
1214 | psmouse->type = psmouse_extensions(psmouse, | 1257 | psmouse->type = psmouse_extensions(psmouse, |
1215 | psmouse_max_proto, true); | 1258 | psmouse_max_proto, true); |
1259 | selected_proto = psmouse_protocol_by_type(psmouse->type); | ||
1260 | } | ||
1261 | |||
1262 | psmouse->ignore_parity = selected_proto->ignore_parity; | ||
1216 | 1263 | ||
1217 | /* | 1264 | /* |
1218 | * If mouse's packet size is 3 there is no point in polling the | 1265 | * If mouse's packet size is 3 there is no point in polling the |
@@ -1232,7 +1279,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse | |||
1232 | psmouse->resync_time = 0; | 1279 | psmouse->resync_time = 0; |
1233 | 1280 | ||
1234 | snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", | 1281 | snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", |
1235 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); | 1282 | selected_proto->name, psmouse->vendor, psmouse->name); |
1236 | 1283 | ||
1237 | input_dev->name = psmouse->devname; | 1284 | input_dev->name = psmouse->devname; |
1238 | input_dev->phys = psmouse->phys; | 1285 | input_dev->phys = psmouse->phys; |
@@ -1347,6 +1394,7 @@ static int psmouse_reconnect(struct serio *serio) | |||
1347 | struct psmouse *psmouse = serio_get_drvdata(serio); | 1394 | struct psmouse *psmouse = serio_get_drvdata(serio); |
1348 | struct psmouse *parent = NULL; | 1395 | struct psmouse *parent = NULL; |
1349 | struct serio_driver *drv = serio->drv; | 1396 | struct serio_driver *drv = serio->drv; |
1397 | unsigned char type; | ||
1350 | int rc = -1; | 1398 | int rc = -1; |
1351 | 1399 | ||
1352 | if (!drv || !psmouse) { | 1400 | if (!drv || !psmouse) { |
@@ -1366,10 +1414,15 @@ static int psmouse_reconnect(struct serio *serio) | |||
1366 | if (psmouse->reconnect) { | 1414 | if (psmouse->reconnect) { |
1367 | if (psmouse->reconnect(psmouse)) | 1415 | if (psmouse->reconnect(psmouse)) |
1368 | goto out; | 1416 | goto out; |
1369 | } else if (psmouse_probe(psmouse) < 0 || | 1417 | } else { |
1370 | psmouse->type != psmouse_extensions(psmouse, | 1418 | psmouse_reset(psmouse); |
1371 | psmouse_max_proto, false)) { | 1419 | |
1372 | goto out; | 1420 | if (psmouse_probe(psmouse) < 0) |
1421 | goto out; | ||
1422 | |||
1423 | type = psmouse_extensions(psmouse, psmouse_max_proto, false); | ||
1424 | if (psmouse->type != type) | ||
1425 | goto out; | ||
1373 | } | 1426 | } |
1374 | 1427 | ||
1375 | /* ok, the device type (and capabilities) match the old one, | 1428 | /* ok, the device type (and capabilities) match the old one, |
@@ -1431,24 +1484,10 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *de | |||
1431 | struct serio *serio = to_serio_port(dev); | 1484 | struct serio *serio = to_serio_port(dev); |
1432 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); | 1485 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); |
1433 | struct psmouse *psmouse; | 1486 | struct psmouse *psmouse; |
1434 | int retval; | ||
1435 | |||
1436 | retval = serio_pin_driver(serio); | ||
1437 | if (retval) | ||
1438 | return retval; | ||
1439 | |||
1440 | if (serio->drv != &psmouse_drv) { | ||
1441 | retval = -ENODEV; | ||
1442 | goto out; | ||
1443 | } | ||
1444 | 1487 | ||
1445 | psmouse = serio_get_drvdata(serio); | 1488 | psmouse = serio_get_drvdata(serio); |
1446 | 1489 | ||
1447 | retval = attr->show(psmouse, attr->data, buf); | 1490 | return attr->show(psmouse, attr->data, buf); |
1448 | |||
1449 | out: | ||
1450 | serio_unpin_driver(serio); | ||
1451 | return retval; | ||
1452 | } | 1491 | } |
1453 | 1492 | ||
1454 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, | 1493 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, |
@@ -1459,18 +1498,9 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1459 | struct psmouse *psmouse, *parent = NULL; | 1498 | struct psmouse *psmouse, *parent = NULL; |
1460 | int retval; | 1499 | int retval; |
1461 | 1500 | ||
1462 | retval = serio_pin_driver(serio); | ||
1463 | if (retval) | ||
1464 | return retval; | ||
1465 | |||
1466 | if (serio->drv != &psmouse_drv) { | ||
1467 | retval = -ENODEV; | ||
1468 | goto out_unpin; | ||
1469 | } | ||
1470 | |||
1471 | retval = mutex_lock_interruptible(&psmouse_mutex); | 1501 | retval = mutex_lock_interruptible(&psmouse_mutex); |
1472 | if (retval) | 1502 | if (retval) |
1473 | goto out_unpin; | 1503 | goto out; |
1474 | 1504 | ||
1475 | psmouse = serio_get_drvdata(serio); | 1505 | psmouse = serio_get_drvdata(serio); |
1476 | 1506 | ||
@@ -1500,8 +1530,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1500 | 1530 | ||
1501 | out_unlock: | 1531 | out_unlock: |
1502 | mutex_unlock(&psmouse_mutex); | 1532 | mutex_unlock(&psmouse_mutex); |
1503 | out_unpin: | 1533 | out: |
1504 | serio_unpin_driver(serio); | ||
1505 | return retval; | 1534 | return retval; |
1506 | } | 1535 | } |
1507 | 1536 | ||
@@ -1563,9 +1592,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1563 | } | 1592 | } |
1564 | 1593 | ||
1565 | mutex_unlock(&psmouse_mutex); | 1594 | mutex_unlock(&psmouse_mutex); |
1566 | serio_unpin_driver(serio); | ||
1567 | serio_unregister_child_port(serio); | 1595 | serio_unregister_child_port(serio); |
1568 | serio_pin_driver_uninterruptible(serio); | ||
1569 | mutex_lock(&psmouse_mutex); | 1596 | mutex_lock(&psmouse_mutex); |
1570 | 1597 | ||
1571 | if (serio->drv != &psmouse_drv) { | 1598 | if (serio->drv != &psmouse_drv) { |
@@ -1680,6 +1707,9 @@ static int __init psmouse_init(void) | |||
1680 | { | 1707 | { |
1681 | int err; | 1708 | int err; |
1682 | 1709 | ||
1710 | lifebook_module_init(); | ||
1711 | synaptics_module_init(); | ||
1712 | |||
1683 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); | 1713 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); |
1684 | if (!kpsmoused_wq) { | 1714 | if (!kpsmoused_wq) { |
1685 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); | 1715 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index e053bdd137ff..593e910bfc7a 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -47,6 +47,7 @@ struct psmouse { | |||
47 | unsigned char pktcnt; | 47 | unsigned char pktcnt; |
48 | unsigned char pktsize; | 48 | unsigned char pktsize; |
49 | unsigned char type; | 49 | unsigned char type; |
50 | bool ignore_parity; | ||
50 | bool acks_disable_command; | 51 | bool acks_disable_command; |
51 | unsigned int model; | 52 | unsigned int model; |
52 | unsigned long last; | 53 | unsigned long last; |
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index 1e827ad0afbe..943cfec15665 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
23 | #include <mach/pxa930_trkball.h> | 24 | #include <mach/pxa930_trkball.h> |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index f84cbd97c884..1242775fee19 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Finger Sensing Pad PS/2 mouse driver. | 2 | * Finger Sensing Pad PS/2 mouse driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. | 4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. |
5 | * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation. | 5 | * Copyright (C) 2005-2010 Tai-hwa Liang, Sentelic Corporation. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/libps2.h> | 26 | #include <linux/libps2.h> |
27 | #include <linux/serio.h> | 27 | #include <linux/serio.h> |
28 | #include <linux/jiffies.h> | 28 | #include <linux/jiffies.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include "psmouse.h" | 31 | #include "psmouse.h" |
31 | #include "sentelic.h" | 32 | #include "sentelic.h" |
@@ -658,9 +659,9 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
658 | if (packet[3] & BIT(1)) | 659 | if (packet[3] & BIT(1)) |
659 | button_status |= 0x0f; /* wheel up */ | 660 | button_status |= 0x0f; /* wheel up */ |
660 | if (packet[3] & BIT(2)) | 661 | if (packet[3] & BIT(2)) |
661 | button_status |= BIT(5);/* horizontal left */ | 662 | button_status |= BIT(4);/* horizontal left */ |
662 | if (packet[3] & BIT(3)) | 663 | if (packet[3] & BIT(3)) |
663 | button_status |= BIT(4);/* horizontal right */ | 664 | button_status |= BIT(5);/* horizontal right */ |
664 | /* push back to packet queue */ | 665 | /* push back to packet queue */ |
665 | if (button_status != 0) | 666 | if (button_status != 0) |
666 | packet[3] = button_status; | 667 | packet[3] = button_status; |
@@ -836,6 +837,7 @@ int fsp_init(struct psmouse *psmouse) | |||
836 | priv->flags |= FSPDRV_FLAG_EN_OPC; | 837 | priv->flags |= FSPDRV_FLAG_EN_OPC; |
837 | 838 | ||
838 | /* Set up various supported input event bits */ | 839 | /* Set up various supported input event bits */ |
840 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
839 | __set_bit(BTN_BACK, psmouse->dev->keybit); | 841 | __set_bit(BTN_BACK, psmouse->dev->keybit); |
840 | __set_bit(BTN_FORWARD, psmouse->dev->keybit); | 842 | __set_bit(BTN_FORWARD, psmouse->dev->keybit); |
841 | __set_bit(REL_WHEEL, psmouse->dev->relbit); | 843 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f4a61252bcc9..ebd7a99efeae 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -24,9 +24,11 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/dmi.h> | ||
27 | #include <linux/input.h> | 28 | #include <linux/input.h> |
28 | #include <linux/serio.h> | 29 | #include <linux/serio.h> |
29 | #include <linux/libps2.h> | 30 | #include <linux/libps2.h> |
31 | #include <linux/slab.h> | ||
30 | #include "psmouse.h" | 32 | #include "psmouse.h" |
31 | #include "synaptics.h" | 33 | #include "synaptics.h" |
32 | 34 | ||
@@ -135,7 +137,8 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
135 | if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) | 137 | if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) |
136 | return -1; | 138 | return -1; |
137 | priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 139 | priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
138 | priv->ext_cap = 0; | 140 | priv->ext_cap = priv->ext_cap_0c = 0; |
141 | |||
139 | if (!SYN_CAP_VALID(priv->capabilities)) | 142 | if (!SYN_CAP_VALID(priv->capabilities)) |
140 | return -1; | 143 | return -1; |
141 | 144 | ||
@@ -148,7 +151,7 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
148 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { | 151 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { |
149 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { | 152 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { |
150 | printk(KERN_ERR "Synaptics claims to have extended capabilities," | 153 | printk(KERN_ERR "Synaptics claims to have extended capabilities," |
151 | " but I'm not able to read them."); | 154 | " but I'm not able to read them.\n"); |
152 | } else { | 155 | } else { |
153 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 156 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
154 | 157 | ||
@@ -160,6 +163,16 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
160 | priv->ext_cap &= 0xff0fff; | 163 | priv->ext_cap &= 0xff0fff; |
161 | } | 164 | } |
162 | } | 165 | } |
166 | |||
167 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { | ||
168 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { | ||
169 | printk(KERN_ERR "Synaptics claims to have extended capability 0x0c," | ||
170 | " but I'm not able to read it.\n"); | ||
171 | } else { | ||
172 | priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | ||
173 | } | ||
174 | } | ||
175 | |||
163 | return 0; | 176 | return 0; |
164 | } | 177 | } |
165 | 178 | ||
@@ -346,7 +359,15 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data | |||
346 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 359 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
347 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 360 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
348 | 361 | ||
349 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | 362 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
363 | /* | ||
364 | * Clickpad's button is transmitted as middle button, | ||
365 | * however, since it is primary button, we will report | ||
366 | * it as BTN_LEFT. | ||
367 | */ | ||
368 | hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; | ||
369 | |||
370 | } else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | ||
350 | hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; | 371 | hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; |
351 | if (hw->w == 2) | 372 | if (hw->w == 2) |
352 | hw->scroll = (signed char)(buf[1]); | 373 | hw->scroll = (signed char)(buf[1]); |
@@ -591,6 +612,12 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
591 | 612 | ||
592 | dev->absres[ABS_X] = priv->x_res; | 613 | dev->absres[ABS_X] = priv->x_res; |
593 | dev->absres[ABS_Y] = priv->y_res; | 614 | dev->absres[ABS_Y] = priv->y_res; |
615 | |||
616 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | ||
617 | /* Clickpads report only left button */ | ||
618 | __clear_bit(BTN_RIGHT, dev->keybit); | ||
619 | __clear_bit(BTN_MIDDLE, dev->keybit); | ||
620 | } | ||
594 | } | 621 | } |
595 | 622 | ||
596 | static void synaptics_disconnect(struct psmouse *psmouse) | 623 | static void synaptics_disconnect(struct psmouse *psmouse) |
@@ -629,25 +656,26 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
629 | return 0; | 656 | return 0; |
630 | } | 657 | } |
631 | 658 | ||
632 | #if defined(__i386__) | 659 | static bool impaired_toshiba_kbc; |
633 | #include <linux/dmi.h> | 660 | |
634 | static const struct dmi_system_id toshiba_dmi_table[] = { | 661 | static const struct dmi_system_id __initconst toshiba_dmi_table[] = { |
662 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
635 | { | 663 | { |
636 | .ident = "Toshiba Satellite", | 664 | /* Toshiba Satellite */ |
637 | .matches = { | 665 | .matches = { |
638 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 666 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
639 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), | 667 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), |
640 | }, | 668 | }, |
641 | }, | 669 | }, |
642 | { | 670 | { |
643 | .ident = "Toshiba Dynabook", | 671 | /* Toshiba Dynabook */ |
644 | .matches = { | 672 | .matches = { |
645 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 673 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
646 | DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"), | 674 | DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"), |
647 | }, | 675 | }, |
648 | }, | 676 | }, |
649 | { | 677 | { |
650 | .ident = "Toshiba Portege M300", | 678 | /* Toshiba Portege M300 */ |
651 | .matches = { | 679 | .matches = { |
652 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 680 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
653 | DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), | 681 | DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), |
@@ -655,7 +683,7 @@ static const struct dmi_system_id toshiba_dmi_table[] = { | |||
655 | 683 | ||
656 | }, | 684 | }, |
657 | { | 685 | { |
658 | .ident = "Toshiba Portege M300", | 686 | /* Toshiba Portege M300 */ |
659 | .matches = { | 687 | .matches = { |
660 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 688 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
661 | DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"), | 689 | DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"), |
@@ -664,8 +692,13 @@ static const struct dmi_system_id toshiba_dmi_table[] = { | |||
664 | 692 | ||
665 | }, | 693 | }, |
666 | { } | 694 | { } |
667 | }; | ||
668 | #endif | 695 | #endif |
696 | }; | ||
697 | |||
698 | void __init synaptics_module_init(void) | ||
699 | { | ||
700 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | ||
701 | } | ||
669 | 702 | ||
670 | int synaptics_init(struct psmouse *psmouse) | 703 | int synaptics_init(struct psmouse *psmouse) |
671 | { | 704 | { |
@@ -689,10 +722,10 @@ int synaptics_init(struct psmouse *psmouse) | |||
689 | 722 | ||
690 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 723 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
691 | 724 | ||
692 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n", | 725 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", |
693 | SYN_ID_MODEL(priv->identity), | 726 | SYN_ID_MODEL(priv->identity), |
694 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | 727 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), |
695 | priv->model_id, priv->capabilities, priv->ext_cap); | 728 | priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c); |
696 | 729 | ||
697 | set_input_params(psmouse->dev, priv); | 730 | set_input_params(psmouse->dev, priv); |
698 | 731 | ||
@@ -718,18 +751,16 @@ int synaptics_init(struct psmouse *psmouse) | |||
718 | if (SYN_CAP_PASS_THROUGH(priv->capabilities)) | 751 | if (SYN_CAP_PASS_THROUGH(priv->capabilities)) |
719 | synaptics_pt_create(psmouse); | 752 | synaptics_pt_create(psmouse); |
720 | 753 | ||
721 | #if defined(__i386__) | ||
722 | /* | 754 | /* |
723 | * Toshiba's KBC seems to have trouble handling data from | 755 | * Toshiba's KBC seems to have trouble handling data from |
724 | * Synaptics as full rate, switch to lower rate which is roughly | 756 | * Synaptics as full rate, switch to lower rate which is roughly |
725 | * thye same as rate of standard PS/2 mouse. | 757 | * thye same as rate of standard PS/2 mouse. |
726 | */ | 758 | */ |
727 | if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) { | 759 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { |
728 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", | 760 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", |
729 | dmi_get_system_info(DMI_PRODUCT_NAME)); | 761 | dmi_get_system_info(DMI_PRODUCT_NAME)); |
730 | psmouse->rate = 40; | 762 | psmouse->rate = 40; |
731 | } | 763 | } |
732 | #endif | ||
733 | 764 | ||
734 | return 0; | 765 | return 0; |
735 | 766 | ||
@@ -738,12 +769,26 @@ int synaptics_init(struct psmouse *psmouse) | |||
738 | return -1; | 769 | return -1; |
739 | } | 770 | } |
740 | 771 | ||
772 | bool synaptics_supported(void) | ||
773 | { | ||
774 | return true; | ||
775 | } | ||
776 | |||
741 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 777 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
742 | 778 | ||
779 | void __init synaptics_module_init(void) | ||
780 | { | ||
781 | } | ||
782 | |||
743 | int synaptics_init(struct psmouse *psmouse) | 783 | int synaptics_init(struct psmouse *psmouse) |
744 | { | 784 | { |
745 | return -ENOSYS; | 785 | return -ENOSYS; |
746 | } | 786 | } |
747 | 787 | ||
788 | bool synaptics_supported(void) | ||
789 | { | ||
790 | return false; | ||
791 | } | ||
792 | |||
748 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 793 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
749 | 794 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 871f6fe377f9..ae37c5d162a4 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 | 18 | #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 |
19 | #define SYN_QUE_RESOLUTION 0x08 | 19 | #define SYN_QUE_RESOLUTION 0x08 |
20 | #define SYN_QUE_EXT_CAPAB 0x09 | 20 | #define SYN_QUE_EXT_CAPAB 0x09 |
21 | #define SYN_QUE_EXT_CAPAB_0C 0x0c | ||
21 | 22 | ||
22 | /* synatics modes */ | 23 | /* synatics modes */ |
23 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) | 24 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) |
@@ -48,6 +49,8 @@ | |||
48 | #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) | 49 | #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) |
49 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) | 50 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) |
50 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) | 51 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) |
52 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) | ||
53 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) | ||
51 | 54 | ||
52 | /* synaptics modes query bits */ | 55 | /* synaptics modes query bits */ |
53 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 56 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
@@ -96,6 +99,7 @@ struct synaptics_data { | |||
96 | unsigned long int model_id; /* Model-ID */ | 99 | unsigned long int model_id; /* Model-ID */ |
97 | unsigned long int capabilities; /* Capabilities */ | 100 | unsigned long int capabilities; /* Capabilities */ |
98 | unsigned long int ext_cap; /* Extended Capabilities */ | 101 | unsigned long int ext_cap; /* Extended Capabilities */ |
102 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ | ||
99 | unsigned long int identity; /* Identification */ | 103 | unsigned long int identity; /* Identification */ |
100 | int x_res; /* X resolution in units/mm */ | 104 | int x_res; /* X resolution in units/mm */ |
101 | int y_res; /* Y resolution in units/mm */ | 105 | int y_res; /* Y resolution in units/mm */ |
@@ -105,8 +109,10 @@ struct synaptics_data { | |||
105 | int scroll; | 109 | int scroll; |
106 | }; | 110 | }; |
107 | 111 | ||
112 | void synaptics_module_init(void); | ||
108 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); | 113 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); |
109 | int synaptics_init(struct psmouse *psmouse); | 114 | int synaptics_init(struct psmouse *psmouse); |
110 | void synaptics_reset(struct psmouse *psmouse); | 115 | void synaptics_reset(struct psmouse *psmouse); |
116 | bool synaptics_supported(void); | ||
111 | 117 | ||
112 | #endif /* _SYNAPTICS_H */ | 118 | #endif /* _SYNAPTICS_H */ |
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index 7283c78044af..8291e7399ffa 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/input.h> | 17 | #include <linux/input.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | #include <linux/slab.h> | ||
20 | 21 | ||
21 | #define DRIVER_NAME "synaptics_i2c" | 22 | #define DRIVER_NAME "synaptics_i2c" |
22 | /* maximum product id is 15 characters */ | 23 | /* maximum product id is 15 characters */ |
@@ -420,8 +421,8 @@ static void synaptics_i2c_check_params(struct synaptics_i2c *touch) | |||
420 | } | 421 | } |
421 | 422 | ||
422 | /* Control the Device polling rate / Work Handler sleep time */ | 423 | /* Control the Device polling rate / Work Handler sleep time */ |
423 | unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch, | 424 | static unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch, |
424 | bool have_data) | 425 | bool have_data) |
425 | { | 426 | { |
426 | unsigned long delay, nodata_count_thres; | 427 | unsigned long delay, nodata_count_thres; |
427 | 428 | ||
@@ -520,7 +521,7 @@ static void synaptics_i2c_set_input_params(struct synaptics_i2c *touch) | |||
520 | __set_bit(BTN_LEFT, input->keybit); | 521 | __set_bit(BTN_LEFT, input->keybit); |
521 | } | 522 | } |
522 | 523 | ||
523 | struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client) | 524 | static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client) |
524 | { | 525 | { |
525 | struct synaptics_i2c *touch; | 526 | struct synaptics_i2c *touch; |
526 | 527 | ||
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c index 0308a0faa94d..88121c59c3cc 100644 --- a/drivers/input/mouse/touchkit_ps2.c +++ b/drivers/input/mouse/touchkit_ps2.c | |||
@@ -26,7 +26,6 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/slab.h> | ||
30 | 29 | ||
31 | #include <linux/input.h> | 30 | #include <linux/input.h> |
32 | #include <linux/serio.h> | 31 | #include <linux/serio.h> |
@@ -86,7 +85,8 @@ int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties) | |||
86 | 85 | ||
87 | if (set_properties) { | 86 | if (set_properties) { |
88 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 87 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
89 | __set_bit(BTN_TOUCH, dev->keybit); | 88 | dev->keybit[BIT_WORD(BTN_MOUSE)] = 0; |
89 | dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
90 | input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); | 90 | input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); |
91 | input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); | 91 | input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); |
92 | 92 | ||
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index e354362f2971..0643e49ca603 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Trademarks are the property of their respective owners. | 8 | * Trademarks are the property of their respective owners. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/slab.h> | ||
11 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
12 | #include <linux/serio.h> | 13 | #include <linux/serio.h> |
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
@@ -284,7 +285,6 @@ static int trackpoint_reconnect(struct psmouse *psmouse) | |||
284 | 285 | ||
285 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | 286 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) |
286 | { | 287 | { |
287 | struct trackpoint_data *priv; | ||
288 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 288 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
289 | unsigned char firmware_id; | 289 | unsigned char firmware_id; |
290 | unsigned char button_info; | 290 | unsigned char button_info; |
@@ -301,8 +301,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
301 | button_info = 0; | 301 | button_info = 0; |
302 | } | 302 | } |
303 | 303 | ||
304 | psmouse->private = priv = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); | 304 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); |
305 | if (!priv) | 305 | if (!psmouse->private) |
306 | return -1; | 306 | return -1; |
307 | 307 | ||
308 | psmouse->vendor = "IBM"; | 308 | psmouse->vendor = "IBM"; |
@@ -311,7 +311,10 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
311 | psmouse->reconnect = trackpoint_reconnect; | 311 | psmouse->reconnect = trackpoint_reconnect; |
312 | psmouse->disconnect = trackpoint_disconnect; | 312 | psmouse->disconnect = trackpoint_disconnect; |
313 | 313 | ||
314 | trackpoint_defaults(priv); | 314 | if ((button_info & 0x0f) >= 3) |
315 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
316 | |||
317 | trackpoint_defaults(psmouse->private); | ||
315 | trackpoint_sync(psmouse); | 318 | trackpoint_sync(psmouse); |
316 | 319 | ||
317 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); | 320 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); |
@@ -319,7 +322,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
319 | printk(KERN_ERR | 322 | printk(KERN_ERR |
320 | "trackpoint.c: failed to create sysfs attributes, error: %d\n", | 323 | "trackpoint.c: failed to create sysfs attributes, error: %d\n", |
321 | error); | 324 | error); |
322 | kfree(priv); | 325 | kfree(psmouse->private); |
326 | psmouse->private = NULL; | ||
323 | return -1; | 327 | return -1; |
324 | } | 328 | } |
325 | 329 | ||
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 70111443678e..bf2c0c80d6cc 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -86,27 +86,28 @@ | |||
86 | 86 | ||
87 | #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet" | 87 | #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet" |
88 | 88 | ||
89 | MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); | 89 | MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); |
90 | MODULE_DESCRIPTION (DRIVER_DESC); | 90 | MODULE_DESCRIPTION(DRIVER_DESC); |
91 | MODULE_LICENSE ("GPL"); | 91 | MODULE_LICENSE("GPL"); |
92 | 92 | ||
93 | #undef VSXXXAA_DEBUG | 93 | #undef VSXXXAA_DEBUG |
94 | #ifdef VSXXXAA_DEBUG | 94 | #ifdef VSXXXAA_DEBUG |
95 | #define DBG(x...) printk (x) | 95 | #define DBG(x...) printk(x) |
96 | #else | 96 | #else |
97 | #define DBG(x...) do {} while (0) | 97 | #define DBG(x...) do {} while (0) |
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | #define VSXXXAA_INTRO_MASK 0x80 | 100 | #define VSXXXAA_INTRO_MASK 0x80 |
101 | #define VSXXXAA_INTRO_HEAD 0x80 | 101 | #define VSXXXAA_INTRO_HEAD 0x80 |
102 | #define IS_HDR_BYTE(x) (((x) & VSXXXAA_INTRO_MASK) \ | 102 | #define IS_HDR_BYTE(x) \ |
103 | == VSXXXAA_INTRO_HEAD) | 103 | (((x) & VSXXXAA_INTRO_MASK) == VSXXXAA_INTRO_HEAD) |
104 | 104 | ||
105 | #define VSXXXAA_PACKET_MASK 0xe0 | 105 | #define VSXXXAA_PACKET_MASK 0xe0 |
106 | #define VSXXXAA_PACKET_REL 0x80 | 106 | #define VSXXXAA_PACKET_REL 0x80 |
107 | #define VSXXXAA_PACKET_ABS 0xc0 | 107 | #define VSXXXAA_PACKET_ABS 0xc0 |
108 | #define VSXXXAA_PACKET_POR 0xa0 | 108 | #define VSXXXAA_PACKET_POR 0xa0 |
109 | #define MATCH_PACKET_TYPE(data, type) (((data) & VSXXXAA_PACKET_MASK) == (type)) | 109 | #define MATCH_PACKET_TYPE(data, type) \ |
110 | (((data) & VSXXXAA_PACKET_MASK) == (type)) | ||
110 | 111 | ||
111 | 112 | ||
112 | 113 | ||
@@ -123,52 +124,50 @@ struct vsxxxaa { | |||
123 | char phys[32]; | 124 | char phys[32]; |
124 | }; | 125 | }; |
125 | 126 | ||
126 | static void | 127 | static void vsxxxaa_drop_bytes(struct vsxxxaa *mouse, int num) |
127 | vsxxxaa_drop_bytes (struct vsxxxaa *mouse, int num) | ||
128 | { | 128 | { |
129 | if (num >= mouse->count) | 129 | if (num >= mouse->count) { |
130 | mouse->count = 0; | 130 | mouse->count = 0; |
131 | else { | 131 | } else { |
132 | memmove (mouse->buf, mouse->buf + num - 1, BUFLEN - num); | 132 | memmove(mouse->buf, mouse->buf + num - 1, BUFLEN - num); |
133 | mouse->count -= num; | 133 | mouse->count -= num; |
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | static void | 137 | static void vsxxxaa_queue_byte(struct vsxxxaa *mouse, unsigned char byte) |
138 | vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte) | ||
139 | { | 138 | { |
140 | if (mouse->count == BUFLEN) { | 139 | if (mouse->count == BUFLEN) { |
141 | printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n", | 140 | printk(KERN_ERR "%s on %s: Dropping a byte of full buffer.\n", |
142 | mouse->name, mouse->phys); | 141 | mouse->name, mouse->phys); |
143 | vsxxxaa_drop_bytes (mouse, 1); | 142 | vsxxxaa_drop_bytes(mouse, 1); |
144 | } | 143 | } |
145 | DBG (KERN_INFO "Queueing byte 0x%02x\n", byte); | 144 | |
145 | DBG(KERN_INFO "Queueing byte 0x%02x\n", byte); | ||
146 | 146 | ||
147 | mouse->buf[mouse->count++] = byte; | 147 | mouse->buf[mouse->count++] = byte; |
148 | } | 148 | } |
149 | 149 | ||
150 | static void | 150 | static void vsxxxaa_detection_done(struct vsxxxaa *mouse) |
151 | vsxxxaa_detection_done (struct vsxxxaa *mouse) | ||
152 | { | 151 | { |
153 | switch (mouse->type) { | 152 | switch (mouse->type) { |
154 | case 0x02: | 153 | case 0x02: |
155 | strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse", | 154 | strlcpy(mouse->name, "DEC VSXXX-AA/-GA mouse", |
156 | sizeof (mouse->name)); | 155 | sizeof(mouse->name)); |
157 | break; | 156 | break; |
158 | 157 | ||
159 | case 0x04: | 158 | case 0x04: |
160 | strlcpy (mouse->name, "DEC VSXXX-AB digitizer", | 159 | strlcpy(mouse->name, "DEC VSXXX-AB digitizer", |
161 | sizeof (mouse->name)); | 160 | sizeof(mouse->name)); |
162 | break; | 161 | break; |
163 | 162 | ||
164 | default: | 163 | default: |
165 | snprintf (mouse->name, sizeof (mouse->name), | 164 | snprintf(mouse->name, sizeof(mouse->name), |
166 | "unknown DEC pointer device (type = 0x%02x)", | 165 | "unknown DEC pointer device (type = 0x%02x)", |
167 | mouse->type); | 166 | mouse->type); |
168 | break; | 167 | break; |
169 | } | 168 | } |
170 | 169 | ||
171 | printk (KERN_INFO | 170 | printk(KERN_INFO |
172 | "Found %s version 0x%02x from country 0x%02x on port %s\n", | 171 | "Found %s version 0x%02x from country 0x%02x on port %s\n", |
173 | mouse->name, mouse->version, mouse->country, mouse->phys); | 172 | mouse->name, mouse->version, mouse->country, mouse->phys); |
174 | } | 173 | } |
@@ -176,42 +175,38 @@ vsxxxaa_detection_done (struct vsxxxaa *mouse) | |||
176 | /* | 175 | /* |
177 | * Returns number of bytes to be dropped, 0 if packet is okay. | 176 | * Returns number of bytes to be dropped, 0 if packet is okay. |
178 | */ | 177 | */ |
179 | static int | 178 | static int vsxxxaa_check_packet(struct vsxxxaa *mouse, int packet_len) |
180 | vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len) | ||
181 | { | 179 | { |
182 | int i; | 180 | int i; |
183 | 181 | ||
184 | /* First byte must be a header byte */ | 182 | /* First byte must be a header byte */ |
185 | if (!IS_HDR_BYTE (mouse->buf[0])) { | 183 | if (!IS_HDR_BYTE(mouse->buf[0])) { |
186 | DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]); | 184 | DBG("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]); |
187 | return 1; | 185 | return 1; |
188 | } | 186 | } |
189 | 187 | ||
190 | /* Check all following bytes */ | 188 | /* Check all following bytes */ |
191 | if (packet_len > 1) { | 189 | for (i = 1; i < packet_len; i++) { |
192 | for (i = 1; i < packet_len; i++) { | 190 | if (IS_HDR_BYTE(mouse->buf[i])) { |
193 | if (IS_HDR_BYTE (mouse->buf[i])) { | 191 | printk(KERN_ERR |
194 | printk (KERN_ERR "Need to drop %d bytes " | 192 | "Need to drop %d bytes of a broken packet.\n", |
195 | "of a broken packet.\n", | 193 | i - 1); |
196 | i - 1); | 194 | DBG(KERN_INFO "check: len=%d, b[%d]=0x%02x\n", |
197 | DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n", | 195 | packet_len, i, mouse->buf[i]); |
198 | packet_len, i, mouse->buf[i]); | 196 | return i - 1; |
199 | return i - 1; | ||
200 | } | ||
201 | } | 197 | } |
202 | } | 198 | } |
203 | 199 | ||
204 | return 0; | 200 | return 0; |
205 | } | 201 | } |
206 | 202 | ||
207 | static __inline__ int | 203 | static inline int vsxxxaa_smells_like_packet(struct vsxxxaa *mouse, |
208 | vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len) | 204 | unsigned char type, size_t len) |
209 | { | 205 | { |
210 | return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type); | 206 | return mouse->count >= len && MATCH_PACKET_TYPE(mouse->buf[0], type); |
211 | } | 207 | } |
212 | 208 | ||
213 | static void | 209 | static void vsxxxaa_handle_REL_packet(struct vsxxxaa *mouse) |
214 | vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse) | ||
215 | { | 210 | { |
216 | struct input_dev *dev = mouse->dev; | 211 | struct input_dev *dev = mouse->dev; |
217 | unsigned char *buf = mouse->buf; | 212 | unsigned char *buf = mouse->buf; |
@@ -232,43 +227,42 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse) | |||
232 | * 0, bit 4 of byte 0 is direction. | 227 | * 0, bit 4 of byte 0 is direction. |
233 | */ | 228 | */ |
234 | dx = buf[1] & 0x7f; | 229 | dx = buf[1] & 0x7f; |
235 | dx *= ((buf[0] >> 4) & 0x01)? 1: -1; | 230 | dx *= ((buf[0] >> 4) & 0x01) ? 1 : -1; |
236 | 231 | ||
237 | /* | 232 | /* |
238 | * Low 7 bit of byte 2 are abs(dy), bit 7 is | 233 | * Low 7 bit of byte 2 are abs(dy), bit 7 is |
239 | * 0, bit 3 of byte 0 is direction. | 234 | * 0, bit 3 of byte 0 is direction. |
240 | */ | 235 | */ |
241 | dy = buf[2] & 0x7f; | 236 | dy = buf[2] & 0x7f; |
242 | dy *= ((buf[0] >> 3) & 0x01)? -1: 1; | 237 | dy *= ((buf[0] >> 3) & 0x01) ? -1 : 1; |
243 | 238 | ||
244 | /* | 239 | /* |
245 | * Get button state. It's the low three bits | 240 | * Get button state. It's the low three bits |
246 | * (for three buttons) of byte 0. | 241 | * (for three buttons) of byte 0. |
247 | */ | 242 | */ |
248 | left = (buf[0] & 0x04)? 1: 0; | 243 | left = buf[0] & 0x04; |
249 | middle = (buf[0] & 0x02)? 1: 0; | 244 | middle = buf[0] & 0x02; |
250 | right = (buf[0] & 0x01)? 1: 0; | 245 | right = buf[0] & 0x01; |
251 | 246 | ||
252 | vsxxxaa_drop_bytes (mouse, 3); | 247 | vsxxxaa_drop_bytes(mouse, 3); |
253 | 248 | ||
254 | DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n", | 249 | DBG(KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n", |
255 | mouse->name, mouse->phys, dx, dy, | 250 | mouse->name, mouse->phys, dx, dy, |
256 | left? "L": "l", middle? "M": "m", right? "R": "r"); | 251 | left ? "L" : "l", middle ? "M" : "m", right ? "R" : "r"); |
257 | 252 | ||
258 | /* | 253 | /* |
259 | * Report what we've found so far... | 254 | * Report what we've found so far... |
260 | */ | 255 | */ |
261 | input_report_key (dev, BTN_LEFT, left); | 256 | input_report_key(dev, BTN_LEFT, left); |
262 | input_report_key (dev, BTN_MIDDLE, middle); | 257 | input_report_key(dev, BTN_MIDDLE, middle); |
263 | input_report_key (dev, BTN_RIGHT, right); | 258 | input_report_key(dev, BTN_RIGHT, right); |
264 | input_report_key (dev, BTN_TOUCH, 0); | 259 | input_report_key(dev, BTN_TOUCH, 0); |
265 | input_report_rel (dev, REL_X, dx); | 260 | input_report_rel(dev, REL_X, dx); |
266 | input_report_rel (dev, REL_Y, dy); | 261 | input_report_rel(dev, REL_Y, dy); |
267 | input_sync (dev); | 262 | input_sync(dev); |
268 | } | 263 | } |
269 | 264 | ||
270 | static void | 265 | static void vsxxxaa_handle_ABS_packet(struct vsxxxaa *mouse) |
271 | vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse) | ||
272 | { | 266 | { |
273 | struct input_dev *dev = mouse->dev; | 267 | struct input_dev *dev = mouse->dev; |
274 | unsigned char *buf = mouse->buf; | 268 | unsigned char *buf = mouse->buf; |
@@ -296,32 +290,31 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse) | |||
296 | /* | 290 | /* |
297 | * Get button state. It's bits <4..1> of byte 0. | 291 | * Get button state. It's bits <4..1> of byte 0. |
298 | */ | 292 | */ |
299 | left = (buf[0] & 0x02)? 1: 0; | 293 | left = buf[0] & 0x02; |
300 | middle = (buf[0] & 0x04)? 1: 0; | 294 | middle = buf[0] & 0x04; |
301 | right = (buf[0] & 0x08)? 1: 0; | 295 | right = buf[0] & 0x08; |
302 | touch = (buf[0] & 0x10)? 1: 0; | 296 | touch = buf[0] & 0x10; |
303 | 297 | ||
304 | vsxxxaa_drop_bytes (mouse, 5); | 298 | vsxxxaa_drop_bytes(mouse, 5); |
305 | 299 | ||
306 | DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n", | 300 | DBG(KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n", |
307 | mouse->name, mouse->phys, x, y, | 301 | mouse->name, mouse->phys, x, y, |
308 | left? "L": "l", middle? "M": "m", | 302 | left ? "L" : "l", middle ? "M" : "m", |
309 | right? "R": "r", touch? "T": "t"); | 303 | right ? "R" : "r", touch ? "T" : "t"); |
310 | 304 | ||
311 | /* | 305 | /* |
312 | * Report what we've found so far... | 306 | * Report what we've found so far... |
313 | */ | 307 | */ |
314 | input_report_key (dev, BTN_LEFT, left); | 308 | input_report_key(dev, BTN_LEFT, left); |
315 | input_report_key (dev, BTN_MIDDLE, middle); | 309 | input_report_key(dev, BTN_MIDDLE, middle); |
316 | input_report_key (dev, BTN_RIGHT, right); | 310 | input_report_key(dev, BTN_RIGHT, right); |
317 | input_report_key (dev, BTN_TOUCH, touch); | 311 | input_report_key(dev, BTN_TOUCH, touch); |
318 | input_report_abs (dev, ABS_X, x); | 312 | input_report_abs(dev, ABS_X, x); |
319 | input_report_abs (dev, ABS_Y, y); | 313 | input_report_abs(dev, ABS_Y, y); |
320 | input_sync (dev); | 314 | input_sync(dev); |
321 | } | 315 | } |
322 | 316 | ||
323 | static void | 317 | static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse) |
324 | vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) | ||
325 | { | 318 | { |
326 | struct input_dev *dev = mouse->dev; | 319 | struct input_dev *dev = mouse->dev; |
327 | unsigned char *buf = mouse->buf; | 320 | unsigned char *buf = mouse->buf; |
@@ -356,24 +349,24 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) | |||
356 | * (for three buttons) of byte 0. Maybe even the bit <3> | 349 | * (for three buttons) of byte 0. Maybe even the bit <3> |
357 | * has some meaning if a tablet is attached. | 350 | * has some meaning if a tablet is attached. |
358 | */ | 351 | */ |
359 | left = (buf[0] & 0x04)? 1: 0; | 352 | left = buf[0] & 0x04; |
360 | middle = (buf[0] & 0x02)? 1: 0; | 353 | middle = buf[0] & 0x02; |
361 | right = (buf[0] & 0x01)? 1: 0; | 354 | right = buf[0] & 0x01; |
362 | 355 | ||
363 | vsxxxaa_drop_bytes (mouse, 4); | 356 | vsxxxaa_drop_bytes(mouse, 4); |
364 | vsxxxaa_detection_done (mouse); | 357 | vsxxxaa_detection_done(mouse); |
365 | 358 | ||
366 | if (error <= 0x1f) { | 359 | if (error <= 0x1f) { |
367 | /* No (serious) error. Report buttons */ | 360 | /* No (serious) error. Report buttons */ |
368 | input_report_key (dev, BTN_LEFT, left); | 361 | input_report_key(dev, BTN_LEFT, left); |
369 | input_report_key (dev, BTN_MIDDLE, middle); | 362 | input_report_key(dev, BTN_MIDDLE, middle); |
370 | input_report_key (dev, BTN_RIGHT, right); | 363 | input_report_key(dev, BTN_RIGHT, right); |
371 | input_report_key (dev, BTN_TOUCH, 0); | 364 | input_report_key(dev, BTN_TOUCH, 0); |
372 | input_sync (dev); | 365 | input_sync(dev); |
373 | 366 | ||
374 | if (error != 0) | 367 | if (error != 0) |
375 | printk (KERN_INFO "Your %s on %s reports error=0x%02x\n", | 368 | printk(KERN_INFO "Your %s on %s reports error=0x%02x\n", |
376 | mouse->name, mouse->phys, error); | 369 | mouse->name, mouse->phys, error); |
377 | 370 | ||
378 | } | 371 | } |
379 | 372 | ||
@@ -381,18 +374,18 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) | |||
381 | * If the mouse was hot-plugged, we need to force differential mode | 374 | * If the mouse was hot-plugged, we need to force differential mode |
382 | * now... However, give it a second to recover from it's reset. | 375 | * now... However, give it a second to recover from it's reset. |
383 | */ | 376 | */ |
384 | printk (KERN_NOTICE "%s on %s: Forceing standard packet format, " | 377 | printk(KERN_NOTICE |
385 | "incremental streaming mode and 72 samples/sec\n", | 378 | "%s on %s: Forcing standard packet format, " |
386 | mouse->name, mouse->phys); | 379 | "incremental streaming mode and 72 samples/sec\n", |
387 | serio_write (mouse->serio, 'S'); /* Standard format */ | 380 | mouse->name, mouse->phys); |
388 | mdelay (50); | 381 | serio_write(mouse->serio, 'S'); /* Standard format */ |
389 | serio_write (mouse->serio, 'R'); /* Incremental */ | 382 | mdelay(50); |
390 | mdelay (50); | 383 | serio_write(mouse->serio, 'R'); /* Incremental */ |
391 | serio_write (mouse->serio, 'L'); /* 72 samples/sec */ | 384 | mdelay(50); |
385 | serio_write(mouse->serio, 'L'); /* 72 samples/sec */ | ||
392 | } | 386 | } |
393 | 387 | ||
394 | static void | 388 | static void vsxxxaa_parse_buffer(struct vsxxxaa *mouse) |
395 | vsxxxaa_parse_buffer (struct vsxxxaa *mouse) | ||
396 | { | 389 | { |
397 | unsigned char *buf = mouse->buf; | 390 | unsigned char *buf = mouse->buf; |
398 | int stray_bytes; | 391 | int stray_bytes; |
@@ -409,122 +402,107 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse) | |||
409 | * activity on the mouse. | 402 | * activity on the mouse. |
410 | */ | 403 | */ |
411 | while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) { | 404 | while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) { |
412 | printk (KERN_ERR "%s on %s: Dropping a byte to regain " | 405 | printk(KERN_ERR "%s on %s: Dropping a byte to regain " |
413 | "sync with mouse data stream...\n", | 406 | "sync with mouse data stream...\n", |
414 | mouse->name, mouse->phys); | 407 | mouse->name, mouse->phys); |
415 | vsxxxaa_drop_bytes (mouse, 1); | 408 | vsxxxaa_drop_bytes(mouse, 1); |
416 | } | 409 | } |
417 | 410 | ||
418 | /* | 411 | /* |
419 | * Check for packets we know about. | 412 | * Check for packets we know about. |
420 | */ | 413 | */ |
421 | 414 | ||
422 | if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) { | 415 | if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_REL, 3)) { |
423 | /* Check for broken packet */ | 416 | /* Check for broken packet */ |
424 | stray_bytes = vsxxxaa_check_packet (mouse, 3); | 417 | stray_bytes = vsxxxaa_check_packet(mouse, 3); |
425 | if (stray_bytes > 0) { | 418 | if (!stray_bytes) |
426 | printk (KERN_ERR "Dropping %d bytes now...\n", | 419 | vsxxxaa_handle_REL_packet(mouse); |
427 | stray_bytes); | ||
428 | vsxxxaa_drop_bytes (mouse, stray_bytes); | ||
429 | continue; | ||
430 | } | ||
431 | |||
432 | vsxxxaa_handle_REL_packet (mouse); | ||
433 | continue; /* More to parse? */ | ||
434 | } | ||
435 | 420 | ||
436 | if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) { | 421 | } else if (vsxxxaa_smells_like_packet(mouse, |
422 | VSXXXAA_PACKET_ABS, 5)) { | ||
437 | /* Check for broken packet */ | 423 | /* Check for broken packet */ |
438 | stray_bytes = vsxxxaa_check_packet (mouse, 5); | 424 | stray_bytes = vsxxxaa_check_packet(mouse, 5); |
439 | if (stray_bytes > 0) { | 425 | if (!stray_bytes) |
440 | printk (KERN_ERR "Dropping %d bytes now...\n", | 426 | vsxxxaa_handle_ABS_packet(mouse); |
441 | stray_bytes); | ||
442 | vsxxxaa_drop_bytes (mouse, stray_bytes); | ||
443 | continue; | ||
444 | } | ||
445 | |||
446 | vsxxxaa_handle_ABS_packet (mouse); | ||
447 | continue; /* More to parse? */ | ||
448 | } | ||
449 | 427 | ||
450 | if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) { | 428 | } else if (vsxxxaa_smells_like_packet(mouse, |
429 | VSXXXAA_PACKET_POR, 4)) { | ||
451 | /* Check for broken packet */ | 430 | /* Check for broken packet */ |
452 | stray_bytes = vsxxxaa_check_packet (mouse, 4); | 431 | stray_bytes = vsxxxaa_check_packet(mouse, 4); |
453 | if (stray_bytes > 0) { | 432 | if (!stray_bytes) |
454 | printk (KERN_ERR "Dropping %d bytes now...\n", | 433 | vsxxxaa_handle_POR_packet(mouse); |
455 | stray_bytes); | 434 | |
456 | vsxxxaa_drop_bytes (mouse, stray_bytes); | 435 | } else { |
457 | continue; | 436 | break; /* No REL, ABS or POR packet found */ |
458 | } | 437 | } |
459 | 438 | ||
460 | vsxxxaa_handle_POR_packet (mouse); | 439 | if (stray_bytes > 0) { |
461 | continue; /* More to parse? */ | 440 | printk(KERN_ERR "Dropping %d bytes now...\n", |
441 | stray_bytes); | ||
442 | vsxxxaa_drop_bytes(mouse, stray_bytes); | ||
462 | } | 443 | } |
463 | 444 | ||
464 | break; /* No REL, ABS or POR packet found */ | ||
465 | } while (1); | 445 | } while (1); |
466 | } | 446 | } |
467 | 447 | ||
468 | static irqreturn_t | 448 | static irqreturn_t vsxxxaa_interrupt(struct serio *serio, |
469 | vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags) | 449 | unsigned char data, unsigned int flags) |
470 | { | 450 | { |
471 | struct vsxxxaa *mouse = serio_get_drvdata (serio); | 451 | struct vsxxxaa *mouse = serio_get_drvdata(serio); |
472 | 452 | ||
473 | vsxxxaa_queue_byte (mouse, data); | 453 | vsxxxaa_queue_byte(mouse, data); |
474 | vsxxxaa_parse_buffer (mouse); | 454 | vsxxxaa_parse_buffer(mouse); |
475 | 455 | ||
476 | return IRQ_HANDLED; | 456 | return IRQ_HANDLED; |
477 | } | 457 | } |
478 | 458 | ||
479 | static void | 459 | static void vsxxxaa_disconnect(struct serio *serio) |
480 | vsxxxaa_disconnect (struct serio *serio) | ||
481 | { | 460 | { |
482 | struct vsxxxaa *mouse = serio_get_drvdata (serio); | 461 | struct vsxxxaa *mouse = serio_get_drvdata(serio); |
483 | 462 | ||
484 | serio_close (serio); | 463 | serio_close(serio); |
485 | serio_set_drvdata (serio, NULL); | 464 | serio_set_drvdata(serio, NULL); |
486 | input_unregister_device (mouse->dev); | 465 | input_unregister_device(mouse->dev); |
487 | kfree (mouse); | 466 | kfree(mouse); |
488 | } | 467 | } |
489 | 468 | ||
490 | static int | 469 | static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv) |
491 | vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | ||
492 | { | 470 | { |
493 | struct vsxxxaa *mouse; | 471 | struct vsxxxaa *mouse; |
494 | struct input_dev *input_dev; | 472 | struct input_dev *input_dev; |
495 | int err = -ENOMEM; | 473 | int err = -ENOMEM; |
496 | 474 | ||
497 | mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL); | 475 | mouse = kzalloc(sizeof(struct vsxxxaa), GFP_KERNEL); |
498 | input_dev = input_allocate_device (); | 476 | input_dev = input_allocate_device(); |
499 | if (!mouse || !input_dev) | 477 | if (!mouse || !input_dev) |
500 | goto fail1; | 478 | goto fail1; |
501 | 479 | ||
502 | mouse->dev = input_dev; | 480 | mouse->dev = input_dev; |
503 | mouse->serio = serio; | 481 | mouse->serio = serio; |
504 | strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer", | 482 | strlcat(mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer", |
505 | sizeof (mouse->name)); | 483 | sizeof(mouse->name)); |
506 | snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys); | 484 | snprintf(mouse->phys, sizeof(mouse->phys), "%s/input0", serio->phys); |
507 | 485 | ||
508 | input_dev->name = mouse->name; | 486 | input_dev->name = mouse->name; |
509 | input_dev->phys = mouse->phys; | 487 | input_dev->phys = mouse->phys; |
510 | input_dev->id.bustype = BUS_RS232; | 488 | input_dev->id.bustype = BUS_RS232; |
511 | input_dev->dev.parent = &serio->dev; | 489 | input_dev->dev.parent = &serio->dev; |
512 | 490 | ||
513 | set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ | 491 | __set_bit(EV_KEY, input_dev->evbit); /* We have buttons */ |
514 | set_bit (EV_REL, input_dev->evbit); | 492 | __set_bit(EV_REL, input_dev->evbit); |
515 | set_bit (EV_ABS, input_dev->evbit); | 493 | __set_bit(EV_ABS, input_dev->evbit); |
516 | set_bit (BTN_LEFT, input_dev->keybit); /* We have 3 buttons */ | 494 | __set_bit(BTN_LEFT, input_dev->keybit); /* We have 3 buttons */ |
517 | set_bit (BTN_MIDDLE, input_dev->keybit); | 495 | __set_bit(BTN_MIDDLE, input_dev->keybit); |
518 | set_bit (BTN_RIGHT, input_dev->keybit); | 496 | __set_bit(BTN_RIGHT, input_dev->keybit); |
519 | set_bit (BTN_TOUCH, input_dev->keybit); /* ...and Tablet */ | 497 | __set_bit(BTN_TOUCH, input_dev->keybit); /* ...and Tablet */ |
520 | set_bit (REL_X, input_dev->relbit); | 498 | __set_bit(REL_X, input_dev->relbit); |
521 | set_bit (REL_Y, input_dev->relbit); | 499 | __set_bit(REL_Y, input_dev->relbit); |
522 | input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0); | 500 | input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0); |
523 | input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0); | 501 | input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0); |
524 | 502 | ||
525 | serio_set_drvdata (serio, mouse); | 503 | serio_set_drvdata(serio, mouse); |
526 | 504 | ||
527 | err = serio_open (serio, drv); | 505 | err = serio_open(serio, drv); |
528 | if (err) | 506 | if (err) |
529 | goto fail2; | 507 | goto fail2; |
530 | 508 | ||
@@ -532,18 +510,18 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | |||
532 | * Request selftest. Standard packet format and differential | 510 | * Request selftest. Standard packet format and differential |
533 | * mode will be requested after the device ID'ed successfully. | 511 | * mode will be requested after the device ID'ed successfully. |
534 | */ | 512 | */ |
535 | serio_write (serio, 'T'); /* Test */ | 513 | serio_write(serio, 'T'); /* Test */ |
536 | 514 | ||
537 | err = input_register_device (input_dev); | 515 | err = input_register_device(input_dev); |
538 | if (err) | 516 | if (err) |
539 | goto fail3; | 517 | goto fail3; |
540 | 518 | ||
541 | return 0; | 519 | return 0; |
542 | 520 | ||
543 | fail3: serio_close (serio); | 521 | fail3: serio_close(serio); |
544 | fail2: serio_set_drvdata (serio, NULL); | 522 | fail2: serio_set_drvdata(serio, NULL); |
545 | fail1: input_free_device (input_dev); | 523 | fail1: input_free_device(input_dev); |
546 | kfree (mouse); | 524 | kfree(mouse); |
547 | return err; | 525 | return err; |
548 | } | 526 | } |
549 | 527 | ||
@@ -570,18 +548,16 @@ static struct serio_driver vsxxxaa_drv = { | |||
570 | .disconnect = vsxxxaa_disconnect, | 548 | .disconnect = vsxxxaa_disconnect, |
571 | }; | 549 | }; |
572 | 550 | ||
573 | static int __init | 551 | static int __init vsxxxaa_init(void) |
574 | vsxxxaa_init (void) | ||
575 | { | 552 | { |
576 | return serio_register_driver(&vsxxxaa_drv); | 553 | return serio_register_driver(&vsxxxaa_drv); |
577 | } | 554 | } |
578 | 555 | ||
579 | static void __exit | 556 | static void __exit vsxxxaa_exit(void) |
580 | vsxxxaa_exit (void) | ||
581 | { | 557 | { |
582 | serio_unregister_driver(&vsxxxaa_drv); | 558 | serio_unregister_driver(&vsxxxaa_drv); |
583 | } | 559 | } |
584 | 560 | ||
585 | module_init (vsxxxaa_init); | 561 | module_init(vsxxxaa_init); |
586 | module_exit (vsxxxaa_exit); | 562 | module_exit(vsxxxaa_exit); |
587 | 563 | ||
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index a13d80f7da17..f34b22bce4ff 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/poll.h> | 18 | #include <linux/poll.h> |
20 | #include <linux/module.h> | 19 | #include <linux/module.h> |
21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
@@ -542,10 +541,8 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
542 | if (i >= MOUSEDEV_MINORS) | 541 | if (i >= MOUSEDEV_MINORS) |
543 | return -ENODEV; | 542 | return -ENODEV; |
544 | 543 | ||
545 | lock_kernel(); | ||
546 | error = mutex_lock_interruptible(&mousedev_table_mutex); | 544 | error = mutex_lock_interruptible(&mousedev_table_mutex); |
547 | if (error) { | 545 | if (error) { |
548 | unlock_kernel(); | ||
549 | return error; | 546 | return error; |
550 | } | 547 | } |
551 | mousedev = mousedev_table[i]; | 548 | mousedev = mousedev_table[i]; |
@@ -554,7 +551,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
554 | mutex_unlock(&mousedev_table_mutex); | 551 | mutex_unlock(&mousedev_table_mutex); |
555 | 552 | ||
556 | if (!mousedev) { | 553 | if (!mousedev) { |
557 | unlock_kernel(); | ||
558 | return -ENODEV; | 554 | return -ENODEV; |
559 | } | 555 | } |
560 | 556 | ||
@@ -575,7 +571,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
575 | goto err_free_client; | 571 | goto err_free_client; |
576 | 572 | ||
577 | file->private_data = client; | 573 | file->private_data = client; |
578 | unlock_kernel(); | ||
579 | return 0; | 574 | return 0; |
580 | 575 | ||
581 | err_free_client: | 576 | err_free_client: |
@@ -583,7 +578,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
583 | kfree(client); | 578 | kfree(client); |
584 | err_put_mousedev: | 579 | err_put_mousedev: |
585 | put_device(&mousedev->dev); | 580 | put_device(&mousedev->dev); |
586 | unlock_kernel(); | ||
587 | return error; | 581 | return error; |
588 | } | 582 | } |
589 | 583 | ||
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index aa533ceffe34..7e319d65ec57 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -201,4 +201,12 @@ config SERIO_XILINX_XPS_PS2 | |||
201 | To compile this driver as a module, choose M here: the | 201 | To compile this driver as a module, choose M here: the |
202 | module will be called xilinx_ps2. | 202 | module will be called xilinx_ps2. |
203 | 203 | ||
204 | config SERIO_ALTERA_PS2 | ||
205 | tristate "Altera UP PS/2 controller" | ||
206 | help | ||
207 | Say Y here if you have Altera University Program PS/2 ports. | ||
208 | |||
209 | To compile this driver as a module, choose M here: the | ||
210 | module will be called altera_ps2. | ||
211 | |||
204 | endif | 212 | endif |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 9b6c8135955f..bf945f789d05 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -22,3 +22,4 @@ obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o | |||
22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o | 22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o |
23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o | 23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o |
24 | obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o | 24 | obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o |
25 | obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o | ||
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c new file mode 100644 index 000000000000..7998560a1904 --- /dev/null +++ b/drivers/input/serio/altera_ps2.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * Altera University Program PS2 controller driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw> | ||
5 | * | ||
6 | * Based on sa1111ps2.c, which is: | ||
7 | * Copyright (C) 2002 Russell King | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/input.h> | ||
17 | #include <linux/serio.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #define DRV_NAME "altera_ps2" | ||
24 | |||
25 | struct ps2if { | ||
26 | struct serio *io; | ||
27 | struct resource *iomem_res; | ||
28 | void __iomem *base; | ||
29 | unsigned irq; | ||
30 | }; | ||
31 | |||
32 | /* | ||
33 | * Read all bytes waiting in the PS2 port. There should be | ||
34 | * at the most one, but we loop for safety. | ||
35 | */ | ||
36 | static irqreturn_t altera_ps2_rxint(int irq, void *dev_id) | ||
37 | { | ||
38 | struct ps2if *ps2if = dev_id; | ||
39 | unsigned int status; | ||
40 | int handled = IRQ_NONE; | ||
41 | |||
42 | while ((status = readl(ps2if->base)) & 0xffff0000) { | ||
43 | serio_interrupt(ps2if->io, status & 0xff, 0); | ||
44 | handled = IRQ_HANDLED; | ||
45 | } | ||
46 | |||
47 | return handled; | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * Write a byte to the PS2 port. | ||
52 | */ | ||
53 | static int altera_ps2_write(struct serio *io, unsigned char val) | ||
54 | { | ||
55 | struct ps2if *ps2if = io->port_data; | ||
56 | |||
57 | writel(val, ps2if->base); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int altera_ps2_open(struct serio *io) | ||
62 | { | ||
63 | struct ps2if *ps2if = io->port_data; | ||
64 | |||
65 | /* clear fifo */ | ||
66 | while (readl(ps2if->base) & 0xffff0000) | ||
67 | /* empty */; | ||
68 | |||
69 | writel(1, ps2if->base + 4); /* enable rx irq */ | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static void altera_ps2_close(struct serio *io) | ||
74 | { | ||
75 | struct ps2if *ps2if = io->port_data; | ||
76 | |||
77 | writel(0, ps2if->base); /* disable rx irq */ | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | * Add one device to this driver. | ||
82 | */ | ||
83 | static int __devinit altera_ps2_probe(struct platform_device *pdev) | ||
84 | { | ||
85 | struct ps2if *ps2if; | ||
86 | struct serio *serio; | ||
87 | int error, irq; | ||
88 | |||
89 | ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL); | ||
90 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
91 | if (!ps2if || !serio) { | ||
92 | error = -ENOMEM; | ||
93 | goto err_free_mem; | ||
94 | } | ||
95 | |||
96 | serio->id.type = SERIO_8042; | ||
97 | serio->write = altera_ps2_write; | ||
98 | serio->open = altera_ps2_open; | ||
99 | serio->close = altera_ps2_close; | ||
100 | strlcpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name)); | ||
101 | strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys)); | ||
102 | serio->port_data = ps2if; | ||
103 | serio->dev.parent = &pdev->dev; | ||
104 | ps2if->io = serio; | ||
105 | |||
106 | ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
107 | if (ps2if->iomem_res == NULL) { | ||
108 | error = -ENOENT; | ||
109 | goto err_free_mem; | ||
110 | } | ||
111 | |||
112 | |||
113 | irq = platform_get_irq(pdev, 0); | ||
114 | if (irq < 0) { | ||
115 | error = -ENXIO; | ||
116 | goto err_free_mem; | ||
117 | } | ||
118 | ps2if->irq = irq; | ||
119 | |||
120 | if (!request_mem_region(ps2if->iomem_res->start, | ||
121 | resource_size(ps2if->iomem_res), pdev->name)) { | ||
122 | error = -EBUSY; | ||
123 | goto err_free_mem; | ||
124 | } | ||
125 | |||
126 | ps2if->base = ioremap(ps2if->iomem_res->start, | ||
127 | resource_size(ps2if->iomem_res)); | ||
128 | if (!ps2if->base) { | ||
129 | error = -ENOMEM; | ||
130 | goto err_free_res; | ||
131 | } | ||
132 | |||
133 | error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if); | ||
134 | if (error) { | ||
135 | dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n", | ||
136 | ps2if->irq, error); | ||
137 | goto err_unmap; | ||
138 | } | ||
139 | |||
140 | dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq); | ||
141 | |||
142 | serio_register_port(ps2if->io); | ||
143 | platform_set_drvdata(pdev, ps2if); | ||
144 | |||
145 | return 0; | ||
146 | |||
147 | err_unmap: | ||
148 | iounmap(ps2if->base); | ||
149 | err_free_res: | ||
150 | release_mem_region(ps2if->iomem_res->start, | ||
151 | resource_size(ps2if->iomem_res)); | ||
152 | err_free_mem: | ||
153 | kfree(ps2if); | ||
154 | kfree(serio); | ||
155 | return error; | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Remove one device from this driver. | ||
160 | */ | ||
161 | static int __devexit altera_ps2_remove(struct platform_device *pdev) | ||
162 | { | ||
163 | struct ps2if *ps2if = platform_get_drvdata(pdev); | ||
164 | |||
165 | platform_set_drvdata(pdev, NULL); | ||
166 | serio_unregister_port(ps2if->io); | ||
167 | free_irq(ps2if->irq, ps2if); | ||
168 | iounmap(ps2if->base); | ||
169 | release_mem_region(ps2if->iomem_res->start, | ||
170 | resource_size(ps2if->iomem_res)); | ||
171 | kfree(ps2if); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Our device driver structure | ||
178 | */ | ||
179 | static struct platform_driver altera_ps2_driver = { | ||
180 | .probe = altera_ps2_probe, | ||
181 | .remove = __devexit_p(altera_ps2_remove), | ||
182 | .driver = { | ||
183 | .name = DRV_NAME, | ||
184 | .owner = THIS_MODULE, | ||
185 | }, | ||
186 | }; | ||
187 | |||
188 | static int __init altera_ps2_init(void) | ||
189 | { | ||
190 | return platform_driver_register(&altera_ps2_driver); | ||
191 | } | ||
192 | |||
193 | static void __exit altera_ps2_exit(void) | ||
194 | { | ||
195 | platform_driver_unregister(&altera_ps2_driver); | ||
196 | } | ||
197 | |||
198 | module_init(altera_ps2_init); | ||
199 | module_exit(altera_ps2_exit); | ||
200 | |||
201 | MODULE_DESCRIPTION("Altera University Program PS2 controller driver"); | ||
202 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | ||
203 | MODULE_LICENSE("GPL"); | ||
204 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 89b394183a75..92563a681d65 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c | |||
@@ -107,7 +107,7 @@ static void amba_kmi_close(struct serio *io) | |||
107 | clk_disable(kmi->clk); | 107 | clk_disable(kmi->clk); |
108 | } | 108 | } |
109 | 109 | ||
110 | static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id) | 110 | static int __devinit amba_kmi_probe(struct amba_device *dev, struct amba_id *id) |
111 | { | 111 | { |
112 | struct amba_kmi_port *kmi; | 112 | struct amba_kmi_port *kmi; |
113 | struct serio *io; | 113 | struct serio *io; |
@@ -134,7 +134,7 @@ static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id) | |||
134 | io->port_data = kmi; | 134 | io->port_data = kmi; |
135 | io->dev.parent = &dev->dev; | 135 | io->dev.parent = &dev->dev; |
136 | 136 | ||
137 | kmi->io = io; | 137 | kmi->io = io; |
138 | kmi->base = ioremap(dev->res.start, resource_size(&dev->res)); | 138 | kmi->base = ioremap(dev->res.start, resource_size(&dev->res)); |
139 | if (!kmi->base) { | 139 | if (!kmi->base) { |
140 | ret = -ENOMEM; | 140 | ret = -ENOMEM; |
@@ -162,7 +162,7 @@ static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id) | |||
162 | return ret; | 162 | return ret; |
163 | } | 163 | } |
164 | 164 | ||
165 | static int amba_kmi_remove(struct amba_device *dev) | 165 | static int __devexit amba_kmi_remove(struct amba_device *dev) |
166 | { | 166 | { |
167 | struct amba_kmi_port *kmi = amba_get_drvdata(dev); | 167 | struct amba_kmi_port *kmi = amba_get_drvdata(dev); |
168 | 168 | ||
@@ -197,10 +197,11 @@ static struct amba_id amba_kmi_idtable[] = { | |||
197 | static struct amba_driver ambakmi_driver = { | 197 | static struct amba_driver ambakmi_driver = { |
198 | .drv = { | 198 | .drv = { |
199 | .name = "kmi-pl050", | 199 | .name = "kmi-pl050", |
200 | .owner = THIS_MODULE, | ||
200 | }, | 201 | }, |
201 | .id_table = amba_kmi_idtable, | 202 | .id_table = amba_kmi_idtable, |
202 | .probe = amba_kmi_probe, | 203 | .probe = amba_kmi_probe, |
203 | .remove = amba_kmi_remove, | 204 | .remove = __devexit_p(amba_kmi_remove), |
204 | .resume = amba_kmi_resume, | 205 | .resume = amba_kmi_resume, |
205 | }; | 206 | }; |
206 | 207 | ||
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index a6fb7a3dcc46..6ee8f0ddad51 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | /* PSIF register offsets */ | 23 | /* PSIF register offsets */ |
23 | #define PSIF_CR 0x00 | 24 | #define PSIF_CR 0x00 |
@@ -137,7 +138,7 @@ static int psif_write(struct serio *io, unsigned char val) | |||
137 | spin_lock_irqsave(&psif->lock, flags); | 138 | spin_lock_irqsave(&psif->lock, flags); |
138 | 139 | ||
139 | while (!(psif_readl(psif, SR) & PSIF_BIT(TXEMPTY)) && timeout--) | 140 | while (!(psif_readl(psif, SR) & PSIF_BIT(TXEMPTY)) && timeout--) |
140 | msleep(10); | 141 | udelay(50); |
141 | 142 | ||
142 | if (timeout >= 0) { | 143 | if (timeout >= 0) { |
143 | psif_writel(psif, THR, val); | 144 | psif_writel(psif, THR, val); |
@@ -352,6 +353,7 @@ static struct platform_driver psif_driver = { | |||
352 | .remove = __exit_p(psif_remove), | 353 | .remove = __exit_p(psif_remove), |
353 | .driver = { | 354 | .driver = { |
354 | .name = "atmel_psif", | 355 | .name = "atmel_psif", |
356 | .owner = THIS_MODULE, | ||
355 | }, | 357 | }, |
356 | .suspend = psif_suspend, | 358 | .suspend = psif_suspend, |
357 | .resume = psif_resume, | 359 | .resume = psif_resume, |
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index d1380fc72cc6..4a3084695c00 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/slab.h> | ||
38 | 39 | ||
39 | #include <asm/io.h> | 40 | #include <asm/io.h> |
40 | 41 | ||
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index bd0f92d9f40f..3c287dd879d3 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org> | 6 | * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org> |
7 | * | 7 | * |
8 | * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c | 8 | * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c |
9 | * Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca> | 9 | * Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca> |
10 | * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org> | 10 | * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org> |
11 | * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr> | 11 | * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr> |
12 | * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr> | 12 | * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr> |
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/slab.h> | ||
27 | #include <linux/serio.h> | 28 | #include <linux/serio.h> |
28 | #include <linux/input.h> | 29 | #include <linux/input.h> |
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
@@ -326,7 +327,7 @@ static void gscps2_close(struct serio *port) | |||
326 | * @return: success/error report | 327 | * @return: success/error report |
327 | */ | 328 | */ |
328 | 329 | ||
329 | static int __init gscps2_probe(struct parisc_device *dev) | 330 | static int __devinit gscps2_probe(struct parisc_device *dev) |
330 | { | 331 | { |
331 | struct gscps2port *ps2port; | 332 | struct gscps2port *ps2port; |
332 | struct serio *serio; | 333 | struct serio *serio; |
@@ -443,7 +444,7 @@ static struct parisc_driver parisc_ps2_driver = { | |||
443 | .name = "gsc_ps2", | 444 | .name = "gsc_ps2", |
444 | .id_table = gscps2_device_tbl, | 445 | .id_table = gscps2_device_tbl, |
445 | .probe = gscps2_probe, | 446 | .probe = gscps2_probe, |
446 | .remove = gscps2_remove, | 447 | .remove = __devexit_p(gscps2_remove), |
447 | }; | 448 | }; |
448 | 449 | ||
449 | static int __init gscps2_init(void) | 450 | static int __init gscps2_init(void) |
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 7ba9f2b2c041..c92f4edfee7b 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/module.h> | 58 | #include <linux/module.h> |
59 | #include <linux/init.h> | 59 | #include <linux/init.h> |
60 | #include <linux/interrupt.h> | 60 | #include <linux/interrupt.h> |
61 | #include <linux/slab.h> | ||
61 | #include <linux/timer.h> | 62 | #include <linux/timer.h> |
62 | #include <linux/list.h> | 63 | #include <linux/list.h> |
63 | 64 | ||
@@ -993,10 +994,8 @@ int hil_mlc_unregister(hil_mlc *mlc) | |||
993 | 994 | ||
994 | static int __init hil_mlc_init(void) | 995 | static int __init hil_mlc_init(void) |
995 | { | 996 | { |
996 | init_timer(&hil_mlcs_kicker); | 997 | setup_timer(&hil_mlcs_kicker, &hil_mlcs_timer, 0); |
997 | hil_mlcs_kicker.expires = jiffies + HZ; | 998 | mod_timer(&hil_mlcs_kicker, jiffies + HZ); |
998 | hil_mlcs_kicker.function = &hil_mlcs_timer; | ||
999 | add_timer(&hil_mlcs_kicker); | ||
1000 | 999 | ||
1001 | tasklet_enable(&hil_mlcs_tasklet); | 1000 | tasklet_enable(&hil_mlcs_tasklet); |
1002 | 1001 | ||
@@ -1005,7 +1004,7 @@ static int __init hil_mlc_init(void) | |||
1005 | 1004 | ||
1006 | static void __exit hil_mlc_exit(void) | 1005 | static void __exit hil_mlc_exit(void) |
1007 | { | 1006 | { |
1008 | del_timer(&hil_mlcs_kicker); | 1007 | del_timer_sync(&hil_mlcs_kicker); |
1009 | 1008 | ||
1010 | tasklet_disable(&hil_mlcs_tasklet); | 1009 | tasklet_disable(&hil_mlcs_tasklet); |
1011 | tasklet_kill(&hil_mlcs_tasklet); | 1010 | tasklet_kill(&hil_mlcs_tasklet); |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 1c9410d1822c..bcc2d30ec245 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -955,7 +955,7 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d) | |||
955 | INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); | 955 | INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); |
956 | 956 | ||
957 | ret = hp_sdc_init(); | 957 | ret = hp_sdc_init(); |
958 | /* after sucessfull initialization give SDC some time to settle | 958 | /* after successfull initialization give SDC some time to settle |
959 | * and then load the hp_sdc_mlc upper layer driver */ | 959 | * and then load the hp_sdc_mlc upper layer driver */ |
960 | if (!ret) | 960 | if (!ret) |
961 | schedule_delayed_work(&moduleloader_work, | 961 | schedule_delayed_work(&moduleloader_work, |
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index 820e51673b26..7d2b820ef58d 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c | |||
@@ -125,7 +125,7 @@ static void hp_sdc_mlc_isr (int irq, void *dev_id, | |||
125 | break; | 125 | break; |
126 | 126 | ||
127 | default: | 127 | default: |
128 | printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data); | 128 | printk(KERN_WARNING PREFIX "Unknown HIL Error status (%x)!\n", data); |
129 | break; | 129 | break; |
130 | } | 130 | } |
131 | 131 | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2bcf1ace27c0..ead0494721d0 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -67,10 +67,12 @@ static inline void i8042_write_command(int val) | |||
67 | 67 | ||
68 | #include <linux/dmi.h> | 68 | #include <linux/dmi.h> |
69 | 69 | ||
70 | static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | 70 | static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { |
71 | { | 71 | { |
72 | /* AUX LOOP command does not raise AUX IRQ */ | 72 | /* |
73 | .ident = "Arima-Rioworks HDAMB", | 73 | * Arima-Rioworks HDAMB - |
74 | * AUX LOOP command does not raise AUX IRQ | ||
75 | */ | ||
74 | .matches = { | 76 | .matches = { |
75 | DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), | 77 | DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), |
76 | DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), | 78 | DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), |
@@ -78,7 +80,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
78 | }, | 80 | }, |
79 | }, | 81 | }, |
80 | { | 82 | { |
81 | .ident = "ASUS G1S", | 83 | /* ASUS G1S */ |
82 | .matches = { | 84 | .matches = { |
83 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), | 85 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), |
84 | DMI_MATCH(DMI_BOARD_NAME, "G1S"), | 86 | DMI_MATCH(DMI_BOARD_NAME, "G1S"), |
@@ -86,8 +88,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
86 | }, | 88 | }, |
87 | }, | 89 | }, |
88 | { | 90 | { |
89 | /* AUX LOOP command does not raise AUX IRQ */ | 91 | /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */ |
90 | .ident = "ASUS P65UP5", | ||
91 | .matches = { | 92 | .matches = { |
92 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | 93 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
93 | DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), | 94 | DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), |
@@ -95,7 +96,6 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
95 | }, | 96 | }, |
96 | }, | 97 | }, |
97 | { | 98 | { |
98 | .ident = "Compaq Proliant 8500", | ||
99 | .matches = { | 99 | .matches = { |
100 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), | 100 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), |
101 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), | 101 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), |
@@ -103,7 +103,6 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
103 | }, | 103 | }, |
104 | }, | 104 | }, |
105 | { | 105 | { |
106 | .ident = "Compaq Proliant DL760", | ||
107 | .matches = { | 106 | .matches = { |
108 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), | 107 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), |
109 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), | 108 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), |
@@ -111,7 +110,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
111 | }, | 110 | }, |
112 | }, | 111 | }, |
113 | { | 112 | { |
114 | .ident = "OQO Model 01", | 113 | /* OQO Model 01 */ |
115 | .matches = { | 114 | .matches = { |
116 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), | 115 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), |
117 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), | 116 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), |
@@ -119,8 +118,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
119 | }, | 118 | }, |
120 | }, | 119 | }, |
121 | { | 120 | { |
122 | /* AUX LOOP does not work properly */ | 121 | /* ULI EV4873 - AUX LOOP does not work properly */ |
123 | .ident = "ULI EV4873", | ||
124 | .matches = { | 122 | .matches = { |
125 | DMI_MATCH(DMI_SYS_VENDOR, "ULI"), | 123 | DMI_MATCH(DMI_SYS_VENDOR, "ULI"), |
126 | DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), | 124 | DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), |
@@ -128,7 +126,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
128 | }, | 126 | }, |
129 | }, | 127 | }, |
130 | { | 128 | { |
131 | .ident = "Microsoft Virtual Machine", | 129 | /* Microsoft Virtual Machine */ |
132 | .matches = { | 130 | .matches = { |
133 | DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), | 131 | DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), |
134 | DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), | 132 | DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), |
@@ -136,7 +134,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
136 | }, | 134 | }, |
137 | }, | 135 | }, |
138 | { | 136 | { |
139 | .ident = "Medion MAM 2070", | 137 | /* Medion MAM 2070 */ |
140 | .matches = { | 138 | .matches = { |
141 | DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), | 139 | DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), |
142 | DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), | 140 | DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), |
@@ -144,7 +142,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
144 | }, | 142 | }, |
145 | }, | 143 | }, |
146 | { | 144 | { |
147 | .ident = "Blue FB5601", | 145 | /* Blue FB5601 */ |
148 | .matches = { | 146 | .matches = { |
149 | DMI_MATCH(DMI_SYS_VENDOR, "blue"), | 147 | DMI_MATCH(DMI_SYS_VENDOR, "blue"), |
150 | DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), | 148 | DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), |
@@ -152,7 +150,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
152 | }, | 150 | }, |
153 | }, | 151 | }, |
154 | { | 152 | { |
155 | .ident = "Gigabyte M912", | 153 | /* Gigabyte M912 */ |
156 | .matches = { | 154 | .matches = { |
157 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | 155 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), |
158 | DMI_MATCH(DMI_PRODUCT_NAME, "M912"), | 156 | DMI_MATCH(DMI_PRODUCT_NAME, "M912"), |
@@ -160,7 +158,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
160 | }, | 158 | }, |
161 | }, | 159 | }, |
162 | { | 160 | { |
163 | .ident = "HP DV9700", | 161 | /* Gigabyte M1022M netbook */ |
162 | .matches = { | ||
163 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."), | ||
164 | DMI_MATCH(DMI_BOARD_NAME, "M1022E"), | ||
165 | DMI_MATCH(DMI_BOARD_VERSION, "1.02"), | ||
166 | }, | ||
167 | }, | ||
168 | { | ||
164 | .matches = { | 169 | .matches = { |
165 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 170 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
166 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), | 171 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), |
@@ -177,72 +182,72 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
177 | * ... apparently some Toshibas don't like MUX mode either and | 182 | * ... apparently some Toshibas don't like MUX mode either and |
178 | * die horrible death on reboot. | 183 | * die horrible death on reboot. |
179 | */ | 184 | */ |
180 | static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | 185 | static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { |
181 | { | 186 | { |
182 | .ident = "Fujitsu Lifebook P7010/P7010D", | 187 | /* Fujitsu Lifebook P7010/P7010D */ |
183 | .matches = { | 188 | .matches = { |
184 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 189 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
185 | DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), | 190 | DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), |
186 | }, | 191 | }, |
187 | }, | 192 | }, |
188 | { | 193 | { |
189 | .ident = "Fujitsu Lifebook P7010", | 194 | /* Fujitsu Lifebook P7010 */ |
190 | .matches = { | 195 | .matches = { |
191 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 196 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
192 | DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), | 197 | DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), |
193 | }, | 198 | }, |
194 | }, | 199 | }, |
195 | { | 200 | { |
196 | .ident = "Fujitsu Lifebook P5020D", | 201 | /* Fujitsu Lifebook P5020D */ |
197 | .matches = { | 202 | .matches = { |
198 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 203 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
199 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), | 204 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), |
200 | }, | 205 | }, |
201 | }, | 206 | }, |
202 | { | 207 | { |
203 | .ident = "Fujitsu Lifebook S2000", | 208 | /* Fujitsu Lifebook S2000 */ |
204 | .matches = { | 209 | .matches = { |
205 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 210 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
206 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), | 211 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), |
207 | }, | 212 | }, |
208 | }, | 213 | }, |
209 | { | 214 | { |
210 | .ident = "Fujitsu Lifebook S6230", | 215 | /* Fujitsu Lifebook S6230 */ |
211 | .matches = { | 216 | .matches = { |
212 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 217 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
213 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), | 218 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), |
214 | }, | 219 | }, |
215 | }, | 220 | }, |
216 | { | 221 | { |
217 | .ident = "Fujitsu T70H", | 222 | /* Fujitsu T70H */ |
218 | .matches = { | 223 | .matches = { |
219 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 224 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
220 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), | 225 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), |
221 | }, | 226 | }, |
222 | }, | 227 | }, |
223 | { | 228 | { |
224 | .ident = "Fujitsu-Siemens Lifebook T3010", | 229 | /* Fujitsu-Siemens Lifebook T3010 */ |
225 | .matches = { | 230 | .matches = { |
226 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 231 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
227 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), | 232 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), |
228 | }, | 233 | }, |
229 | }, | 234 | }, |
230 | { | 235 | { |
231 | .ident = "Fujitsu-Siemens Lifebook E4010", | 236 | /* Fujitsu-Siemens Lifebook E4010 */ |
232 | .matches = { | 237 | .matches = { |
233 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 238 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
234 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), | 239 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), |
235 | }, | 240 | }, |
236 | }, | 241 | }, |
237 | { | 242 | { |
238 | .ident = "Fujitsu-Siemens Amilo Pro 2010", | 243 | /* Fujitsu-Siemens Amilo Pro 2010 */ |
239 | .matches = { | 244 | .matches = { |
240 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 245 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
241 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), | 246 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), |
242 | }, | 247 | }, |
243 | }, | 248 | }, |
244 | { | 249 | { |
245 | .ident = "Fujitsu-Siemens Amilo Pro 2030", | 250 | /* Fujitsu-Siemens Amilo Pro 2030 */ |
246 | .matches = { | 251 | .matches = { |
247 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 252 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
248 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), | 253 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), |
@@ -253,7 +258,7 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
253 | * No data is coming from the touchscreen unless KBC | 258 | * No data is coming from the touchscreen unless KBC |
254 | * is in legacy mode. | 259 | * is in legacy mode. |
255 | */ | 260 | */ |
256 | .ident = "Panasonic CF-29", | 261 | /* Panasonic CF-29 */ |
257 | .matches = { | 262 | .matches = { |
258 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | 263 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), |
259 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), | 264 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), |
@@ -261,10 +266,10 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
261 | }, | 266 | }, |
262 | { | 267 | { |
263 | /* | 268 | /* |
264 | * Errors on MUX ports are reported without raising AUXDATA | 269 | * HP Pavilion DV4017EA - |
270 | * errors on MUX ports are reported without raising AUXDATA | ||
265 | * causing "spurious NAK" messages. | 271 | * causing "spurious NAK" messages. |
266 | */ | 272 | */ |
267 | .ident = "HP Pavilion DV4017EA", | ||
268 | .matches = { | 273 | .matches = { |
269 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 274 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
270 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), | 275 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), |
@@ -272,9 +277,9 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
272 | }, | 277 | }, |
273 | { | 278 | { |
274 | /* | 279 | /* |
275 | * Like DV4017EA does not raise AUXERR for errors on MUX ports. | 280 | * HP Pavilion ZT1000 - |
281 | * like DV4017EA does not raise AUXERR for errors on MUX ports. | ||
276 | */ | 282 | */ |
277 | .ident = "HP Pavilion ZT1000", | ||
278 | .matches = { | 283 | .matches = { |
279 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 284 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
280 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), | 285 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), |
@@ -283,44 +288,41 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
283 | }, | 288 | }, |
284 | { | 289 | { |
285 | /* | 290 | /* |
286 | * Like DV4017EA does not raise AUXERR for errors on MUX ports. | 291 | * HP Pavilion DV4270ca - |
292 | * like DV4017EA does not raise AUXERR for errors on MUX ports. | ||
287 | */ | 293 | */ |
288 | .ident = "HP Pavilion DV4270ca", | ||
289 | .matches = { | 294 | .matches = { |
290 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 295 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
291 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), | 296 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), |
292 | }, | 297 | }, |
293 | }, | 298 | }, |
294 | { | 299 | { |
295 | .ident = "Toshiba P10", | ||
296 | .matches = { | 300 | .matches = { |
297 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 301 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
298 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), | 302 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), |
299 | }, | 303 | }, |
300 | }, | 304 | }, |
301 | { | 305 | { |
302 | .ident = "Toshiba Equium A110", | ||
303 | .matches = { | 306 | .matches = { |
304 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 307 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
305 | DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), | 308 | DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), |
306 | }, | 309 | }, |
307 | }, | 310 | }, |
308 | { | 311 | { |
309 | .ident = "Alienware Sentia", | ||
310 | .matches = { | 312 | .matches = { |
311 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), | 313 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), |
312 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), | 314 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), |
313 | }, | 315 | }, |
314 | }, | 316 | }, |
315 | { | 317 | { |
316 | .ident = "Sharp Actius MM20", | 318 | /* Sharp Actius MM20 */ |
317 | .matches = { | 319 | .matches = { |
318 | DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), | 320 | DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), |
319 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), | 321 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), |
320 | }, | 322 | }, |
321 | }, | 323 | }, |
322 | { | 324 | { |
323 | .ident = "Sony Vaio FS-115b", | 325 | /* Sony Vaio FS-115b */ |
324 | .matches = { | 326 | .matches = { |
325 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 327 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |
326 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), | 328 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), |
@@ -328,73 +330,72 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
328 | }, | 330 | }, |
329 | { | 331 | { |
330 | /* | 332 | /* |
331 | * Reset and GET ID commands issued via KBD port are | 333 | * Sony Vaio FZ-240E - |
334 | * reset and GET ID commands issued via KBD port are | ||
332 | * sometimes being delivered to AUX3. | 335 | * sometimes being delivered to AUX3. |
333 | */ | 336 | */ |
334 | .ident = "Sony Vaio FZ-240E", | ||
335 | .matches = { | 337 | .matches = { |
336 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 338 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |
337 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), | 339 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), |
338 | }, | 340 | }, |
339 | }, | 341 | }, |
340 | { | 342 | { |
341 | .ident = "Amoi M636/A737", | 343 | /* Amoi M636/A737 */ |
342 | .matches = { | 344 | .matches = { |
343 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), | 345 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), |
344 | DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), | 346 | DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), |
345 | }, | 347 | }, |
346 | }, | 348 | }, |
347 | { | 349 | { |
348 | .ident = "Lenovo 3000 n100", | 350 | /* Lenovo 3000 n100 */ |
349 | .matches = { | 351 | .matches = { |
350 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 352 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
351 | DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), | 353 | DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), |
352 | }, | 354 | }, |
353 | }, | 355 | }, |
354 | { | 356 | { |
355 | .ident = "Acer Aspire 1360", | ||
356 | .matches = { | 357 | .matches = { |
357 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 358 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
358 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), | 359 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), |
359 | }, | 360 | }, |
360 | }, | 361 | }, |
361 | { | 362 | { |
362 | .ident = "Gericom Bellagio", | 363 | /* Gericom Bellagio */ |
363 | .matches = { | 364 | .matches = { |
364 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), | 365 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), |
365 | DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), | 366 | DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), |
366 | }, | 367 | }, |
367 | }, | 368 | }, |
368 | { | 369 | { |
369 | .ident = "IBM 2656", | 370 | /* IBM 2656 */ |
370 | .matches = { | 371 | .matches = { |
371 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | 372 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), |
372 | DMI_MATCH(DMI_PRODUCT_NAME, "2656"), | 373 | DMI_MATCH(DMI_PRODUCT_NAME, "2656"), |
373 | }, | 374 | }, |
374 | }, | 375 | }, |
375 | { | 376 | { |
376 | .ident = "Dell XPS M1530", | 377 | /* Dell XPS M1530 */ |
377 | .matches = { | 378 | .matches = { |
378 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 379 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
379 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), | 380 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), |
380 | }, | 381 | }, |
381 | }, | 382 | }, |
382 | { | 383 | { |
383 | .ident = "Compal HEL80I", | 384 | /* Compal HEL80I */ |
384 | .matches = { | 385 | .matches = { |
385 | DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), | 386 | DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), |
386 | DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), | 387 | DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), |
387 | }, | 388 | }, |
388 | }, | 389 | }, |
389 | { | 390 | { |
390 | .ident = "Dell Vostro 1510", | 391 | /* Dell Vostro 1510 */ |
391 | .matches = { | 392 | .matches = { |
392 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 393 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
393 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), | 394 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), |
394 | }, | 395 | }, |
395 | }, | 396 | }, |
396 | { | 397 | { |
397 | .ident = "Acer Aspire 5536", | 398 | /* Acer Aspire 5536 */ |
398 | .matches = { | 399 | .matches = { |
399 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 400 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
400 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), | 401 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), |
@@ -404,65 +405,72 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
404 | { } | 405 | { } |
405 | }; | 406 | }; |
406 | 407 | ||
407 | static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { | 408 | static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { |
408 | { | 409 | { |
409 | .ident = "MSI Wind U-100", | 410 | /* MSI Wind U-100 */ |
410 | .matches = { | 411 | .matches = { |
411 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), | 412 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), |
412 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), | 413 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), |
413 | }, | 414 | }, |
414 | }, | 415 | }, |
415 | { | 416 | { |
416 | .ident = "LG Electronics X110", | 417 | /* LG Electronics X110 */ |
417 | .matches = { | 418 | .matches = { |
418 | DMI_MATCH(DMI_BOARD_NAME, "X110"), | 419 | DMI_MATCH(DMI_BOARD_NAME, "X110"), |
419 | DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), | 420 | DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), |
420 | }, | 421 | }, |
421 | }, | 422 | }, |
422 | { | 423 | { |
423 | .ident = "Acer Aspire One 150", | 424 | /* Acer Aspire One 150 */ |
424 | .matches = { | 425 | .matches = { |
425 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 426 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
426 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), | 427 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), |
427 | }, | 428 | }, |
428 | }, | 429 | }, |
429 | { | 430 | { |
430 | .ident = "Advent 4211", | 431 | /* Advent 4211 */ |
431 | .matches = { | 432 | .matches = { |
432 | DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), | 433 | DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), |
433 | DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), | 434 | DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), |
434 | }, | 435 | }, |
435 | }, | 436 | }, |
436 | { | 437 | { |
437 | .ident = "Medion Akoya Mini E1210", | 438 | /* Medion Akoya Mini E1210 */ |
438 | .matches = { | 439 | .matches = { |
439 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), | 440 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), |
440 | DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), | 441 | DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), |
441 | }, | 442 | }, |
442 | }, | 443 | }, |
443 | { | 444 | { |
444 | .ident = "Mivvy M310", | 445 | /* Medion Akoya E1222 */ |
446 | .matches = { | ||
447 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), | ||
448 | DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), | ||
449 | }, | ||
450 | }, | ||
451 | { | ||
452 | /* Mivvy M310 */ | ||
445 | .matches = { | 453 | .matches = { |
446 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), | 454 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), |
447 | DMI_MATCH(DMI_PRODUCT_NAME, "N10"), | 455 | DMI_MATCH(DMI_PRODUCT_NAME, "N10"), |
448 | }, | 456 | }, |
449 | }, | 457 | }, |
450 | { | 458 | { |
451 | .ident = "Dell Vostro 1320", | 459 | /* Dell Vostro 1320 */ |
452 | .matches = { | 460 | .matches = { |
453 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 461 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
454 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), | 462 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), |
455 | }, | 463 | }, |
456 | }, | 464 | }, |
457 | { | 465 | { |
458 | .ident = "Dell Vostro 1520", | 466 | /* Dell Vostro 1520 */ |
459 | .matches = { | 467 | .matches = { |
460 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 468 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
461 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), | 469 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), |
462 | }, | 470 | }, |
463 | }, | 471 | }, |
464 | { | 472 | { |
465 | .ident = "Dell Vostro 1720", | 473 | /* Dell Vostro 1720 */ |
466 | .matches = { | 474 | .matches = { |
467 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 475 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
468 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), | 476 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), |
@@ -472,16 +480,16 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { | |||
472 | }; | 480 | }; |
473 | 481 | ||
474 | #ifdef CONFIG_PNP | 482 | #ifdef CONFIG_PNP |
475 | static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | 483 | static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = { |
476 | { | 484 | { |
477 | .ident = "Intel MBO Desktop D845PESV", | 485 | /* Intel MBO Desktop D845PESV */ |
478 | .matches = { | 486 | .matches = { |
479 | DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), | 487 | DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), |
480 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | 488 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), |
481 | }, | 489 | }, |
482 | }, | 490 | }, |
483 | { | 491 | { |
484 | .ident = "MSI Wind U-100", | 492 | /* MSI Wind U-100 */ |
485 | .matches = { | 493 | .matches = { |
486 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), | 494 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), |
487 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), | 495 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), |
@@ -490,27 +498,23 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | |||
490 | { } | 498 | { } |
491 | }; | 499 | }; |
492 | 500 | ||
493 | static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = { | 501 | static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { |
494 | { | 502 | { |
495 | .ident = "Portable", | ||
496 | .matches = { | 503 | .matches = { |
497 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 504 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
498 | }, | 505 | }, |
499 | }, | 506 | }, |
500 | { | 507 | { |
501 | .ident = "Laptop", | ||
502 | .matches = { | 508 | .matches = { |
503 | DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ | 509 | DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ |
504 | }, | 510 | }, |
505 | }, | 511 | }, |
506 | { | 512 | { |
507 | .ident = "Notebook", | ||
508 | .matches = { | 513 | .matches = { |
509 | DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ | 514 | DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ |
510 | }, | 515 | }, |
511 | }, | 516 | }, |
512 | { | 517 | { |
513 | .ident = "Sub-Notebook", | ||
514 | .matches = { | 518 | .matches = { |
515 | DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ | 519 | DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ |
516 | }, | 520 | }, |
@@ -525,58 +529,65 @@ static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = { | |||
525 | * Originally, this was just confined to older laptops, but a few Acer laptops | 529 | * Originally, this was just confined to older laptops, but a few Acer laptops |
526 | * have turned up in 2007 that also need this again. | 530 | * have turned up in 2007 that also need this again. |
527 | */ | 531 | */ |
528 | static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { | 532 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { |
533 | { | ||
534 | /* Acer Aspire 5610 */ | ||
535 | .matches = { | ||
536 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
537 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), | ||
538 | }, | ||
539 | }, | ||
529 | { | 540 | { |
530 | .ident = "Acer Aspire 5630", | 541 | /* Acer Aspire 5630 */ |
531 | .matches = { | 542 | .matches = { |
532 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 543 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
533 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), | 544 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), |
534 | }, | 545 | }, |
535 | }, | 546 | }, |
536 | { | 547 | { |
537 | .ident = "Acer Aspire 5650", | 548 | /* Acer Aspire 5650 */ |
538 | .matches = { | 549 | .matches = { |
539 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 550 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
540 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), | 551 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), |
541 | }, | 552 | }, |
542 | }, | 553 | }, |
543 | { | 554 | { |
544 | .ident = "Acer Aspire 5680", | 555 | /* Acer Aspire 5680 */ |
545 | .matches = { | 556 | .matches = { |
546 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 557 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
547 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), | 558 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), |
548 | }, | 559 | }, |
549 | }, | 560 | }, |
550 | { | 561 | { |
551 | .ident = "Acer Aspire 5720", | 562 | /* Acer Aspire 5720 */ |
552 | .matches = { | 563 | .matches = { |
553 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 564 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
554 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), | 565 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), |
555 | }, | 566 | }, |
556 | }, | 567 | }, |
557 | { | 568 | { |
558 | .ident = "Acer Aspire 9110", | 569 | /* Acer Aspire 9110 */ |
559 | .matches = { | 570 | .matches = { |
560 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 571 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
561 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), | 572 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), |
562 | }, | 573 | }, |
563 | }, | 574 | }, |
564 | { | 575 | { |
565 | .ident = "Acer TravelMate 660", | 576 | /* Acer TravelMate 660 */ |
566 | .matches = { | 577 | .matches = { |
567 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 578 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
568 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), | 579 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), |
569 | }, | 580 | }, |
570 | }, | 581 | }, |
571 | { | 582 | { |
572 | .ident = "Acer TravelMate 2490", | 583 | /* Acer TravelMate 2490 */ |
573 | .matches = { | 584 | .matches = { |
574 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 585 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
575 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), | 586 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), |
576 | }, | 587 | }, |
577 | }, | 588 | }, |
578 | { | 589 | { |
579 | .ident = "Acer TravelMate 4280", | 590 | /* Acer TravelMate 4280 */ |
580 | .matches = { | 591 | .matches = { |
581 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 592 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
582 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), | 593 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), |
@@ -620,6 +631,9 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * | |||
620 | strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); | 631 | strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); |
621 | } | 632 | } |
622 | 633 | ||
634 | /* Keyboard ports are always supposed to be wakeup-enabled */ | ||
635 | device_set_wakeup_enable(&dev->dev, true); | ||
636 | |||
623 | i8042_pnp_kbd_devices++; | 637 | i8042_pnp_kbd_devices++; |
624 | return 0; | 638 | return 0; |
625 | } | 639 | } |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 1df02d25aca5..6440a8f55686 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/rcupdate.h> | 21 | #include <linux/rcupdate.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/i8042.h> | 23 | #include <linux/i8042.h> |
24 | #include <linux/slab.h> | ||
24 | 25 | ||
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | 27 | ||
@@ -38,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); | |||
38 | 39 | ||
39 | static bool i8042_nomux; | 40 | static bool i8042_nomux; |
40 | module_param_named(nomux, i8042_nomux, bool, 0); | 41 | module_param_named(nomux, i8042_nomux, bool, 0); |
41 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present."); | 42 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present."); |
42 | 43 | ||
43 | static bool i8042_unlock; | 44 | static bool i8042_unlock; |
44 | module_param_named(unlock, i8042_unlock, bool, 0); | 45 | module_param_named(unlock, i8042_unlock, bool, 0); |
@@ -126,6 +127,8 @@ static unsigned char i8042_suppress_kbd_ack; | |||
126 | static struct platform_device *i8042_platform_device; | 127 | static struct platform_device *i8042_platform_device; |
127 | 128 | ||
128 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); | 129 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); |
130 | static bool (*i8042_platform_filter)(unsigned char data, unsigned char str, | ||
131 | struct serio *serio); | ||
129 | 132 | ||
130 | void i8042_lock_chip(void) | 133 | void i8042_lock_chip(void) |
131 | { | 134 | { |
@@ -139,6 +142,48 @@ void i8042_unlock_chip(void) | |||
139 | } | 142 | } |
140 | EXPORT_SYMBOL(i8042_unlock_chip); | 143 | EXPORT_SYMBOL(i8042_unlock_chip); |
141 | 144 | ||
145 | int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str, | ||
146 | struct serio *serio)) | ||
147 | { | ||
148 | unsigned long flags; | ||
149 | int ret = 0; | ||
150 | |||
151 | spin_lock_irqsave(&i8042_lock, flags); | ||
152 | |||
153 | if (i8042_platform_filter) { | ||
154 | ret = -EBUSY; | ||
155 | goto out; | ||
156 | } | ||
157 | |||
158 | i8042_platform_filter = filter; | ||
159 | |||
160 | out: | ||
161 | spin_unlock_irqrestore(&i8042_lock, flags); | ||
162 | return ret; | ||
163 | } | ||
164 | EXPORT_SYMBOL(i8042_install_filter); | ||
165 | |||
166 | int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str, | ||
167 | struct serio *port)) | ||
168 | { | ||
169 | unsigned long flags; | ||
170 | int ret = 0; | ||
171 | |||
172 | spin_lock_irqsave(&i8042_lock, flags); | ||
173 | |||
174 | if (i8042_platform_filter != filter) { | ||
175 | ret = -EINVAL; | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | i8042_platform_filter = NULL; | ||
180 | |||
181 | out: | ||
182 | spin_unlock_irqrestore(&i8042_lock, flags); | ||
183 | return ret; | ||
184 | } | ||
185 | EXPORT_SYMBOL(i8042_remove_filter); | ||
186 | |||
142 | /* | 187 | /* |
143 | * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to | 188 | * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to |
144 | * be ready for reading values from it / writing values to it. | 189 | * be ready for reading values from it / writing values to it. |
@@ -369,6 +414,31 @@ static void i8042_stop(struct serio *serio) | |||
369 | } | 414 | } |
370 | 415 | ||
371 | /* | 416 | /* |
417 | * i8042_filter() filters out unwanted bytes from the input data stream. | ||
418 | * It is called from i8042_interrupt and thus is running with interrupts | ||
419 | * off and i8042_lock held. | ||
420 | */ | ||
421 | static bool i8042_filter(unsigned char data, unsigned char str, | ||
422 | struct serio *serio) | ||
423 | { | ||
424 | if (unlikely(i8042_suppress_kbd_ack)) { | ||
425 | if ((~str & I8042_STR_AUXDATA) && | ||
426 | (data == 0xfa || data == 0xfe)) { | ||
427 | i8042_suppress_kbd_ack--; | ||
428 | dbg("Extra keyboard ACK - filtered out\n"); | ||
429 | return true; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) { | ||
434 | dbg("Filtered out by platform filter\n"); | ||
435 | return true; | ||
436 | } | ||
437 | |||
438 | return false; | ||
439 | } | ||
440 | |||
441 | /* | ||
372 | * i8042_interrupt() is the most important function in this driver - | 442 | * i8042_interrupt() is the most important function in this driver - |
373 | * it handles the interrupts from the i8042, and sends incoming bytes | 443 | * it handles the interrupts from the i8042, and sends incoming bytes |
374 | * to the upper layers. | 444 | * to the upper layers. |
@@ -377,13 +447,16 @@ static void i8042_stop(struct serio *serio) | |||
377 | static irqreturn_t i8042_interrupt(int irq, void *dev_id) | 447 | static irqreturn_t i8042_interrupt(int irq, void *dev_id) |
378 | { | 448 | { |
379 | struct i8042_port *port; | 449 | struct i8042_port *port; |
450 | struct serio *serio; | ||
380 | unsigned long flags; | 451 | unsigned long flags; |
381 | unsigned char str, data; | 452 | unsigned char str, data; |
382 | unsigned int dfl; | 453 | unsigned int dfl; |
383 | unsigned int port_no; | 454 | unsigned int port_no; |
455 | bool filtered; | ||
384 | int ret = 1; | 456 | int ret = 1; |
385 | 457 | ||
386 | spin_lock_irqsave(&i8042_lock, flags); | 458 | spin_lock_irqsave(&i8042_lock, flags); |
459 | |||
387 | str = i8042_read_status(); | 460 | str = i8042_read_status(); |
388 | if (unlikely(~str & I8042_STR_OBF)) { | 461 | if (unlikely(~str & I8042_STR_OBF)) { |
389 | spin_unlock_irqrestore(&i8042_lock, flags); | 462 | spin_unlock_irqrestore(&i8042_lock, flags); |
@@ -391,8 +464,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
391 | ret = 0; | 464 | ret = 0; |
392 | goto out; | 465 | goto out; |
393 | } | 466 | } |
467 | |||
394 | data = i8042_read_data(); | 468 | data = i8042_read_data(); |
395 | spin_unlock_irqrestore(&i8042_lock, flags); | ||
396 | 469 | ||
397 | if (i8042_mux_present && (str & I8042_STR_AUXDATA)) { | 470 | if (i8042_mux_present && (str & I8042_STR_AUXDATA)) { |
398 | static unsigned long last_transmit; | 471 | static unsigned long last_transmit; |
@@ -441,21 +514,19 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
441 | } | 514 | } |
442 | 515 | ||
443 | port = &i8042_ports[port_no]; | 516 | port = &i8042_ports[port_no]; |
517 | serio = port->exists ? port->serio : NULL; | ||
444 | 518 | ||
445 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)", | 519 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)", |
446 | data, port_no, irq, | 520 | data, port_no, irq, |
447 | dfl & SERIO_PARITY ? ", bad parity" : "", | 521 | dfl & SERIO_PARITY ? ", bad parity" : "", |
448 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); | 522 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); |
449 | 523 | ||
450 | if (unlikely(i8042_suppress_kbd_ack)) | 524 | filtered = i8042_filter(data, str, serio); |
451 | if (port_no == I8042_KBD_PORT_NO && | 525 | |
452 | (data == 0xfa || data == 0xfe)) { | 526 | spin_unlock_irqrestore(&i8042_lock, flags); |
453 | i8042_suppress_kbd_ack--; | ||
454 | goto out; | ||
455 | } | ||
456 | 527 | ||
457 | if (likely(port->exists)) | 528 | if (likely(port->exists && !filtered)) |
458 | serio_interrupt(port->serio, data, dfl); | 529 | serio_interrupt(serio, data, dfl); |
459 | 530 | ||
460 | out: | 531 | out: |
461 | return IRQ_RETVAL(ret); | 532 | return IRQ_RETVAL(ret); |
@@ -1091,9 +1162,17 @@ static int i8042_pm_restore(struct device *dev) | |||
1091 | return 0; | 1162 | return 0; |
1092 | } | 1163 | } |
1093 | 1164 | ||
1165 | static int i8042_pm_thaw(struct device *dev) | ||
1166 | { | ||
1167 | i8042_interrupt(0, NULL); | ||
1168 | |||
1169 | return 0; | ||
1170 | } | ||
1171 | |||
1094 | static const struct dev_pm_ops i8042_pm_ops = { | 1172 | static const struct dev_pm_ops i8042_pm_ops = { |
1095 | .suspend = i8042_pm_reset, | 1173 | .suspend = i8042_pm_reset, |
1096 | .resume = i8042_pm_restore, | 1174 | .resume = i8042_pm_restore, |
1175 | .thaw = i8042_pm_thaw, | ||
1097 | .poweroff = i8042_pm_reset, | 1176 | .poweroff = i8042_pm_reset, |
1098 | .restore = i8042_pm_restore, | 1177 | .restore = i8042_pm_restore, |
1099 | }; | 1178 | }; |
@@ -1308,6 +1387,8 @@ static int __init i8042_probe(struct platform_device *dev) | |||
1308 | { | 1387 | { |
1309 | int error; | 1388 | int error; |
1310 | 1389 | ||
1390 | i8042_platform_device = dev; | ||
1391 | |||
1311 | error = i8042_controller_selftest(); | 1392 | error = i8042_controller_selftest(); |
1312 | if (error) | 1393 | if (error) |
1313 | return error; | 1394 | return error; |
@@ -1343,6 +1424,7 @@ static int __init i8042_probe(struct platform_device *dev) | |||
1343 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ | 1424 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ |
1344 | i8042_free_irqs(); | 1425 | i8042_free_irqs(); |
1345 | i8042_controller_reset(); | 1426 | i8042_controller_reset(); |
1427 | i8042_platform_device = NULL; | ||
1346 | 1428 | ||
1347 | return error; | 1429 | return error; |
1348 | } | 1430 | } |
@@ -1352,6 +1434,7 @@ static int __devexit i8042_remove(struct platform_device *dev) | |||
1352 | i8042_unregister_ports(); | 1434 | i8042_unregister_ports(); |
1353 | i8042_free_irqs(); | 1435 | i8042_free_irqs(); |
1354 | i8042_controller_reset(); | 1436 | i8042_controller_reset(); |
1437 | i8042_platform_device = NULL; | ||
1355 | 1438 | ||
1356 | return 0; | 1439 | return 0; |
1357 | } | 1440 | } |
@@ -1370,6 +1453,7 @@ static struct platform_driver i8042_driver = { | |||
1370 | 1453 | ||
1371 | static int __init i8042_init(void) | 1454 | static int __init i8042_init(void) |
1372 | { | 1455 | { |
1456 | struct platform_device *pdev; | ||
1373 | int err; | 1457 | int err; |
1374 | 1458 | ||
1375 | dbg_init(); | 1459 | dbg_init(); |
@@ -1382,31 +1466,18 @@ static int __init i8042_init(void) | |||
1382 | if (err) | 1466 | if (err) |
1383 | goto err_platform_exit; | 1467 | goto err_platform_exit; |
1384 | 1468 | ||
1385 | i8042_platform_device = platform_device_alloc("i8042", -1); | 1469 | pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); |
1386 | if (!i8042_platform_device) { | 1470 | if (IS_ERR(pdev)) { |
1387 | err = -ENOMEM; | 1471 | err = PTR_ERR(pdev); |
1388 | goto err_platform_exit; | 1472 | goto err_platform_exit; |
1389 | } | 1473 | } |
1390 | 1474 | ||
1391 | err = platform_device_add(i8042_platform_device); | ||
1392 | if (err) | ||
1393 | goto err_free_device; | ||
1394 | |||
1395 | err = platform_driver_probe(&i8042_driver, i8042_probe); | ||
1396 | if (err) | ||
1397 | goto err_del_device; | ||
1398 | |||
1399 | panic_blink = i8042_panic_blink; | 1475 | panic_blink = i8042_panic_blink; |
1400 | 1476 | ||
1401 | return 0; | 1477 | return 0; |
1402 | 1478 | ||
1403 | err_del_device: | ||
1404 | platform_device_del(i8042_platform_device); | ||
1405 | err_free_device: | ||
1406 | platform_device_put(i8042_platform_device); | ||
1407 | err_platform_exit: | 1479 | err_platform_exit: |
1408 | i8042_platform_exit(); | 1480 | i8042_platform_exit(); |
1409 | |||
1410 | return err; | 1481 | return err; |
1411 | } | 1482 | } |
1412 | 1483 | ||
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index f3876acc3e83..980af94ba9c8 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/slab.h> | ||
18 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
19 | #include <linux/input.h> | 18 | #include <linux/input.h> |
20 | #include <linux/serio.h> | 19 | #include <linux/serio.h> |
diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index b089977e0ef9..26b45936f9fd 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | #include <linux/module.h> | 47 | #include <linux/module.h> |
48 | #include <linux/parport.h> | 48 | #include <linux/parport.h> |
49 | #include <linux/slab.h> | ||
49 | #include <linux/init.h> | 50 | #include <linux/init.h> |
50 | #include <linux/serio.h> | 51 | #include <linux/serio.h> |
51 | 52 | ||
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 1dacbe0d9348..43494742541c 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
16 | #include <linux/input.h> | 16 | #include <linux/input.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
20 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
@@ -186,7 +187,7 @@ static void __devexit pcips2_remove(struct pci_dev *dev) | |||
186 | pci_disable_device(dev); | 187 | pci_disable_device(dev); |
187 | } | 188 | } |
188 | 189 | ||
189 | static struct pci_device_id pcips2_ids[] = { | 190 | static const struct pci_device_id pcips2_ids[] = { |
190 | { | 191 | { |
191 | .vendor = 0x14f2, /* MOBILITY */ | 192 | .vendor = 0x14f2, /* MOBILITY */ |
192 | .device = 0x0123, /* Keyboard */ | 193 | .device = 0x0123, /* Keyboard */ |
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index e36a0901646c..5eb84b3b67fb 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/bitops.h> | 37 | #include <linux/bitops.h> |
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/slab.h> | ||
39 | 40 | ||
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index ed045c99f84b..9da6fbcaaa7e 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/err.h> | 34 | #include <linux/err.h> |
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/io.h> | 36 | #include <linux/io.h> |
37 | #include <linux/slab.h> | ||
37 | 38 | ||
38 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
39 | #include <mach/hardware.h> | 40 | #include <mach/hardware.h> |
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index f412c69478a8..d55874e5d1c2 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c | |||
@@ -180,8 +180,8 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if) | |||
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | static inline unsigned int | 183 | static unsigned int __devinit ps2_test_one(struct ps2if *ps2if, |
184 | ps2_test_one(struct ps2if *ps2if, unsigned int mask) | 184 | unsigned int mask) |
185 | { | 185 | { |
186 | unsigned int val; | 186 | unsigned int val; |
187 | 187 | ||
@@ -197,7 +197,7 @@ ps2_test_one(struct ps2if *ps2if, unsigned int mask) | |||
197 | * Test the keyboard interface. We basically check to make sure that | 197 | * Test the keyboard interface. We basically check to make sure that |
198 | * we can drive each line to the keyboard independently of each other. | 198 | * we can drive each line to the keyboard independently of each other. |
199 | */ | 199 | */ |
200 | static int __init ps2_test(struct ps2if *ps2if) | 200 | static int __devinit ps2_test(struct ps2if *ps2if) |
201 | { | 201 | { |
202 | unsigned int stat; | 202 | unsigned int stat; |
203 | int ret = 0; | 203 | int ret = 0; |
@@ -312,7 +312,7 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) | |||
312 | /* | 312 | /* |
313 | * Remove one device from this driver. | 313 | * Remove one device from this driver. |
314 | */ | 314 | */ |
315 | static int ps2_remove(struct sa1111_dev *dev) | 315 | static int __devexit ps2_remove(struct sa1111_dev *dev) |
316 | { | 316 | { |
317 | struct ps2if *ps2if = sa1111_get_drvdata(dev); | 317 | struct ps2if *ps2if = sa1111_get_drvdata(dev); |
318 | 318 | ||
@@ -335,7 +335,7 @@ static struct sa1111_driver ps2_driver = { | |||
335 | }, | 335 | }, |
336 | .devid = SA1111_DEVID_PS2, | 336 | .devid = SA1111_DEVID_PS2, |
337 | .probe = ps2_probe, | 337 | .probe = ps2_probe, |
338 | .remove = ps2_remove, | 338 | .remove = __devexit_p(ps2_remove), |
339 | }; | 339 | }; |
340 | 340 | ||
341 | static int __init ps2_init(void) | 341 | static int __init ps2_init(void) |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 0236f0d5fd91..c3b626e9eae7 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
29 | #include <linux/stddef.h> | 31 | #include <linux/stddef.h> |
30 | #include <linux/module.h> | 32 | #include <linux/module.h> |
31 | #include <linux/serio.h> | 33 | #include <linux/serio.h> |
@@ -119,11 +121,10 @@ static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) | |||
119 | 121 | ||
120 | error = device_bind_driver(&serio->dev); | 122 | error = device_bind_driver(&serio->dev); |
121 | if (error) { | 123 | if (error) { |
122 | printk(KERN_WARNING | 124 | dev_warn(&serio->dev, |
123 | "serio: device_bind_driver() failed " | 125 | "device_bind_driver() failed for %s (%s) and %s, error: %d\n", |
124 | "for %s (%s) and %s, error: %d\n", | 126 | serio->phys, serio->name, |
125 | serio->phys, serio->name, | 127 | drv->description, error); |
126 | drv->description, error); | ||
127 | serio_disconnect_driver(serio); | 128 | serio_disconnect_driver(serio); |
128 | serio->dev.driver = NULL; | 129 | serio->dev.driver = NULL; |
129 | return error; | 130 | return error; |
@@ -138,9 +139,9 @@ static void serio_find_driver(struct serio *serio) | |||
138 | 139 | ||
139 | error = device_attach(&serio->dev); | 140 | error = device_attach(&serio->dev); |
140 | if (error < 0) | 141 | if (error < 0) |
141 | printk(KERN_WARNING | 142 | dev_warn(&serio->dev, |
142 | "serio: device_attach() failed for %s (%s), error: %d\n", | 143 | "device_attach() failed for %s (%s), error: %d\n", |
143 | serio->phys, serio->name, error); | 144 | serio->phys, serio->name, error); |
144 | } | 145 | } |
145 | 146 | ||
146 | 147 | ||
@@ -194,17 +195,14 @@ static int serio_queue_event(void *object, struct module *owner, | |||
194 | 195 | ||
195 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); | 196 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); |
196 | if (!event) { | 197 | if (!event) { |
197 | printk(KERN_ERR | 198 | pr_err("Not enough memory to queue event %d\n", event_type); |
198 | "serio: Not enough memory to queue event %d\n", | ||
199 | event_type); | ||
200 | retval = -ENOMEM; | 199 | retval = -ENOMEM; |
201 | goto out; | 200 | goto out; |
202 | } | 201 | } |
203 | 202 | ||
204 | if (!try_module_get(owner)) { | 203 | if (!try_module_get(owner)) { |
205 | printk(KERN_WARNING | 204 | pr_warning("Can't get module reference, dropping event %d\n", |
206 | "serio: Can't get module reference, dropping event %d\n", | 205 | event_type); |
207 | event_type); | ||
208 | kfree(event); | 206 | kfree(event); |
209 | retval = -EINVAL; | 207 | retval = -EINVAL; |
210 | goto out; | 208 | goto out; |
@@ -230,14 +228,12 @@ static void serio_free_event(struct serio_event *event) | |||
230 | 228 | ||
231 | static void serio_remove_duplicate_events(struct serio_event *event) | 229 | static void serio_remove_duplicate_events(struct serio_event *event) |
232 | { | 230 | { |
233 | struct list_head *node, *next; | 231 | struct serio_event *e, *next; |
234 | struct serio_event *e; | ||
235 | unsigned long flags; | 232 | unsigned long flags; |
236 | 233 | ||
237 | spin_lock_irqsave(&serio_event_lock, flags); | 234 | spin_lock_irqsave(&serio_event_lock, flags); |
238 | 235 | ||
239 | list_for_each_safe(node, next, &serio_event_list) { | 236 | list_for_each_entry_safe(e, next, &serio_event_list, node) { |
240 | e = list_entry(node, struct serio_event, node); | ||
241 | if (event->object == e->object) { | 237 | if (event->object == e->object) { |
242 | /* | 238 | /* |
243 | * If this event is of different type we should not | 239 | * If this event is of different type we should not |
@@ -247,7 +243,7 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
247 | if (event->type != e->type) | 243 | if (event->type != e->type) |
248 | break; | 244 | break; |
249 | 245 | ||
250 | list_del_init(node); | 246 | list_del_init(&e->node); |
251 | serio_free_event(e); | 247 | serio_free_event(e); |
252 | } | 248 | } |
253 | } | 249 | } |
@@ -258,23 +254,18 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
258 | 254 | ||
259 | static struct serio_event *serio_get_event(void) | 255 | static struct serio_event *serio_get_event(void) |
260 | { | 256 | { |
261 | struct serio_event *event; | 257 | struct serio_event *event = NULL; |
262 | struct list_head *node; | ||
263 | unsigned long flags; | 258 | unsigned long flags; |
264 | 259 | ||
265 | spin_lock_irqsave(&serio_event_lock, flags); | 260 | spin_lock_irqsave(&serio_event_lock, flags); |
266 | 261 | ||
267 | if (list_empty(&serio_event_list)) { | 262 | if (!list_empty(&serio_event_list)) { |
268 | spin_unlock_irqrestore(&serio_event_lock, flags); | 263 | event = list_first_entry(&serio_event_list, |
269 | return NULL; | 264 | struct serio_event, node); |
265 | list_del_init(&event->node); | ||
270 | } | 266 | } |
271 | 267 | ||
272 | node = serio_event_list.next; | ||
273 | event = list_entry(node, struct serio_event, node); | ||
274 | list_del_init(node); | ||
275 | |||
276 | spin_unlock_irqrestore(&serio_event_lock, flags); | 268 | spin_unlock_irqrestore(&serio_event_lock, flags); |
277 | |||
278 | return event; | 269 | return event; |
279 | } | 270 | } |
280 | 271 | ||
@@ -284,38 +275,30 @@ static void serio_handle_event(void) | |||
284 | 275 | ||
285 | mutex_lock(&serio_mutex); | 276 | mutex_lock(&serio_mutex); |
286 | 277 | ||
287 | /* | 278 | while ((event = serio_get_event())) { |
288 | * Note that we handle only one event here to give swsusp | ||
289 | * a chance to freeze kseriod thread. Serio events should | ||
290 | * be pretty rare so we are not concerned about taking | ||
291 | * performance hit. | ||
292 | */ | ||
293 | if ((event = serio_get_event())) { | ||
294 | 279 | ||
295 | switch (event->type) { | 280 | switch (event->type) { |
296 | case SERIO_REGISTER_PORT: | ||
297 | serio_add_port(event->object); | ||
298 | break; | ||
299 | 281 | ||
300 | case SERIO_RECONNECT_PORT: | 282 | case SERIO_REGISTER_PORT: |
301 | serio_reconnect_port(event->object); | 283 | serio_add_port(event->object); |
302 | break; | 284 | break; |
303 | 285 | ||
304 | case SERIO_RESCAN_PORT: | 286 | case SERIO_RECONNECT_PORT: |
305 | serio_disconnect_port(event->object); | 287 | serio_reconnect_port(event->object); |
306 | serio_find_driver(event->object); | 288 | break; |
307 | break; | ||
308 | 289 | ||
309 | case SERIO_RECONNECT_CHAIN: | 290 | case SERIO_RESCAN_PORT: |
310 | serio_reconnect_chain(event->object); | 291 | serio_disconnect_port(event->object); |
311 | break; | 292 | serio_find_driver(event->object); |
293 | break; | ||
312 | 294 | ||
313 | case SERIO_ATTACH_DRIVER: | 295 | case SERIO_RECONNECT_CHAIN: |
314 | serio_attach_driver(event->object); | 296 | serio_reconnect_chain(event->object); |
315 | break; | 297 | break; |
316 | 298 | ||
317 | default: | 299 | case SERIO_ATTACH_DRIVER: |
318 | break; | 300 | serio_attach_driver(event->object); |
301 | break; | ||
319 | } | 302 | } |
320 | 303 | ||
321 | serio_remove_duplicate_events(event); | 304 | serio_remove_duplicate_events(event); |
@@ -331,16 +314,14 @@ static void serio_handle_event(void) | |||
331 | */ | 314 | */ |
332 | static void serio_remove_pending_events(void *object) | 315 | static void serio_remove_pending_events(void *object) |
333 | { | 316 | { |
334 | struct list_head *node, *next; | 317 | struct serio_event *event, *next; |
335 | struct serio_event *event; | ||
336 | unsigned long flags; | 318 | unsigned long flags; |
337 | 319 | ||
338 | spin_lock_irqsave(&serio_event_lock, flags); | 320 | spin_lock_irqsave(&serio_event_lock, flags); |
339 | 321 | ||
340 | list_for_each_safe(node, next, &serio_event_list) { | 322 | list_for_each_entry_safe(event, next, &serio_event_list, node) { |
341 | event = list_entry(node, struct serio_event, node); | ||
342 | if (event->object == object) { | 323 | if (event->object == object) { |
343 | list_del_init(node); | 324 | list_del_init(&event->node); |
344 | serio_free_event(event); | 325 | serio_free_event(event); |
345 | } | 326 | } |
346 | } | 327 | } |
@@ -380,14 +361,12 @@ static struct serio *serio_get_pending_child(struct serio *parent) | |||
380 | 361 | ||
381 | static int serio_thread(void *nothing) | 362 | static int serio_thread(void *nothing) |
382 | { | 363 | { |
383 | set_freezable(); | ||
384 | do { | 364 | do { |
385 | serio_handle_event(); | 365 | serio_handle_event(); |
386 | wait_event_freezable(serio_wait, | 366 | wait_event_interruptible(serio_wait, |
387 | kthread_should_stop() || !list_empty(&serio_event_list)); | 367 | kthread_should_stop() || !list_empty(&serio_event_list)); |
388 | } while (!kthread_should_stop()); | 368 | } while (!kthread_should_stop()); |
389 | 369 | ||
390 | printk(KERN_DEBUG "serio: kseriod exiting\n"); | ||
391 | return 0; | 370 | return 0; |
392 | } | 371 | } |
393 | 372 | ||
@@ -452,6 +431,11 @@ static struct attribute_group serio_id_attr_group = { | |||
452 | .attrs = serio_device_id_attrs, | 431 | .attrs = serio_device_id_attrs, |
453 | }; | 432 | }; |
454 | 433 | ||
434 | static const struct attribute_group *serio_device_attr_groups[] = { | ||
435 | &serio_id_attr_group, | ||
436 | NULL | ||
437 | }; | ||
438 | |||
455 | static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 439 | static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
456 | { | 440 | { |
457 | struct serio *serio = to_serio_port(dev); | 441 | struct serio *serio = to_serio_port(dev); |
@@ -539,6 +523,7 @@ static void serio_init_port(struct serio *serio) | |||
539 | (long)atomic_inc_return(&serio_no) - 1); | 523 | (long)atomic_inc_return(&serio_no) - 1); |
540 | serio->dev.bus = &serio_bus; | 524 | serio->dev.bus = &serio_bus; |
541 | serio->dev.release = serio_release_port; | 525 | serio->dev.release = serio_release_port; |
526 | serio->dev.groups = serio_device_attr_groups; | ||
542 | if (serio->parent) { | 527 | if (serio->parent) { |
543 | serio->dev.parent = &serio->parent->dev; | 528 | serio->dev.parent = &serio->parent->dev; |
544 | serio->depth = serio->parent->depth + 1; | 529 | serio->depth = serio->parent->depth + 1; |
@@ -562,21 +547,15 @@ static void serio_add_port(struct serio *serio) | |||
562 | } | 547 | } |
563 | 548 | ||
564 | list_add_tail(&serio->node, &serio_list); | 549 | list_add_tail(&serio->node, &serio_list); |
550 | |||
565 | if (serio->start) | 551 | if (serio->start) |
566 | serio->start(serio); | 552 | serio->start(serio); |
553 | |||
567 | error = device_add(&serio->dev); | 554 | error = device_add(&serio->dev); |
568 | if (error) | 555 | if (error) |
569 | printk(KERN_ERR | 556 | dev_err(&serio->dev, |
570 | "serio: device_add() failed for %s (%s), error: %d\n", | 557 | "device_add() failed for %s (%s), error: %d\n", |
571 | serio->phys, serio->name, error); | 558 | serio->phys, serio->name, error); |
572 | else { | ||
573 | serio->registered = true; | ||
574 | error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | ||
575 | if (error) | ||
576 | printk(KERN_ERR | ||
577 | "serio: sysfs_create_group() failed for %s (%s), error: %d\n", | ||
578 | serio->phys, serio->name, error); | ||
579 | } | ||
580 | } | 559 | } |
581 | 560 | ||
582 | /* | 561 | /* |
@@ -603,11 +582,8 @@ static void serio_destroy_port(struct serio *serio) | |||
603 | serio->parent = NULL; | 582 | serio->parent = NULL; |
604 | } | 583 | } |
605 | 584 | ||
606 | if (serio->registered) { | 585 | if (device_is_registered(&serio->dev)) |
607 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | ||
608 | device_del(&serio->dev); | 586 | device_del(&serio->dev); |
609 | serio->registered = false; | ||
610 | } | ||
611 | 587 | ||
612 | list_del_init(&serio->node); | 588 | list_del_init(&serio->node); |
613 | serio_remove_pending_events(serio); | 589 | serio_remove_pending_events(serio); |
@@ -805,9 +781,8 @@ static void serio_attach_driver(struct serio_driver *drv) | |||
805 | 781 | ||
806 | error = driver_attach(&drv->driver); | 782 | error = driver_attach(&drv->driver); |
807 | if (error) | 783 | if (error) |
808 | printk(KERN_WARNING | 784 | pr_warning("driver_attach() failed for %s with error %d\n", |
809 | "serio: driver_attach() failed for %s with error %d\n", | 785 | drv->driver.name, error); |
810 | drv->driver.name, error); | ||
811 | } | 786 | } |
812 | 787 | ||
813 | int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) | 788 | int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) |
@@ -827,8 +802,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons | |||
827 | 802 | ||
828 | error = driver_register(&drv->driver); | 803 | error = driver_register(&drv->driver); |
829 | if (error) { | 804 | if (error) { |
830 | printk(KERN_ERR | 805 | pr_err("driver_register() failed for %s, error: %d\n", |
831 | "serio: driver_register() failed for %s, error: %d\n", | ||
832 | drv->driver.name, error); | 806 | drv->driver.name, error); |
833 | return error; | 807 | return error; |
834 | } | 808 | } |
@@ -994,7 +968,7 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
994 | 968 | ||
995 | if (likely(serio->drv)) { | 969 | if (likely(serio->drv)) { |
996 | ret = serio->drv->interrupt(serio, data, dfl); | 970 | ret = serio->drv->interrupt(serio, data, dfl); |
997 | } else if (!dfl && serio->registered) { | 971 | } else if (!dfl && device_is_registered(&serio->dev)) { |
998 | serio_rescan(serio); | 972 | serio_rescan(serio); |
999 | ret = IRQ_HANDLED; | 973 | ret = IRQ_HANDLED; |
1000 | } | 974 | } |
@@ -1025,7 +999,7 @@ static int __init serio_init(void) | |||
1025 | 999 | ||
1026 | error = bus_register(&serio_bus); | 1000 | error = bus_register(&serio_bus); |
1027 | if (error) { | 1001 | if (error) { |
1028 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); | 1002 | pr_err("Failed to register serio bus, error: %d\n", error); |
1029 | return error; | 1003 | return error; |
1030 | } | 1004 | } |
1031 | 1005 | ||
@@ -1033,7 +1007,7 @@ static int __init serio_init(void) | |||
1033 | if (IS_ERR(serio_task)) { | 1007 | if (IS_ERR(serio_task)) { |
1034 | bus_unregister(&serio_bus); | 1008 | bus_unregister(&serio_bus); |
1035 | error = PTR_ERR(serio_task); | 1009 | error = PTR_ERR(serio_task); |
1036 | printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error); | 1010 | pr_err("Failed to start kseriod, error: %d\n", error); |
1037 | return error; | 1011 | return error; |
1038 | } | 1012 | } |
1039 | 1013 | ||
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 27fdaaffbb40..998664854440 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
81 | struct serio_raw_list *list; | 81 | struct serio_raw_list *list; |
82 | int retval = 0; | 82 | int retval = 0; |
83 | 83 | ||
84 | lock_kernel(); | ||
85 | retval = mutex_lock_interruptible(&serio_raw_mutex); | 84 | retval = mutex_lock_interruptible(&serio_raw_mutex); |
86 | if (retval) | 85 | if (retval) |
87 | goto out_bkl; | 86 | return retval; |
88 | 87 | ||
89 | if (!(serio_raw = serio_raw_locate(iminor(inode)))) { | 88 | serio_raw = serio_raw_locate(iminor(inode)); |
89 | if (!serio_raw) { | ||
90 | retval = -ENODEV; | 90 | retval = -ENODEV; |
91 | goto out; | 91 | goto out; |
92 | } | 92 | } |
@@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
96 | goto out; | 96 | goto out; |
97 | } | 97 | } |
98 | 98 | ||
99 | if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { | 99 | list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL); |
100 | if (!list) { | ||
100 | retval = -ENOMEM; | 101 | retval = -ENOMEM; |
101 | goto out; | 102 | goto out; |
102 | } | 103 | } |
@@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
109 | 110 | ||
110 | out: | 111 | out: |
111 | mutex_unlock(&serio_raw_mutex); | 112 | mutex_unlock(&serio_raw_mutex); |
112 | out_bkl: | ||
113 | unlock_kernel(); | ||
114 | return retval; | 113 | return retval; |
115 | } | 114 | } |
116 | 115 | ||
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index ebb22f88c842..f84f8e32e3f1 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/serio.h> | 19 | #include <linux/serio.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/slab.h> | ||
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/list.h> | 24 | #include <linux/list.h> |
24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
@@ -270,7 +271,7 @@ static int __devinit xps2_of_probe(struct of_device *ofdev, | |||
270 | drvdata->irq = r_irq.start; | 271 | drvdata->irq = r_irq.start; |
271 | 272 | ||
272 | phys_addr = r_mem.start; | 273 | phys_addr = r_mem.start; |
273 | remap_size = r_mem.end - r_mem.start + 1; | 274 | remap_size = resource_size(&r_mem); |
274 | if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) { | 275 | if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) { |
275 | dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", | 276 | dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", |
276 | (unsigned long long)phys_addr); | 277 | (unsigned long long)phys_addr); |
@@ -344,7 +345,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) | |||
344 | if (of_address_to_resource(of_dev->node, 0, &r_mem)) | 345 | if (of_address_to_resource(of_dev->node, 0, &r_mem)) |
345 | dev_err(dev, "invalid address\n"); | 346 | dev_err(dev, "invalid address\n"); |
346 | else | 347 | else |
347 | release_mem_region(r_mem.start, r_mem.end - r_mem.start + 1); | 348 | release_mem_region(r_mem.start, resource_size(&r_mem)); |
348 | 349 | ||
349 | kfree(drvdata); | 350 | kfree(drvdata); |
350 | 351 | ||
@@ -354,7 +355,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) | |||
354 | } | 355 | } |
355 | 356 | ||
356 | /* Match table for of_platform binding */ | 357 | /* Match table for of_platform binding */ |
357 | static struct of_device_id xps2_of_match[] __devinitdata = { | 358 | static const struct of_device_id xps2_of_match[] __devinitconst = { |
358 | { .compatible = "xlnx,xps-ps2-1.00.a", }, | 359 | { .compatible = "xlnx,xps-ps2-1.00.a", }, |
359 | { /* end of list */ }, | 360 | { /* end of list */ }, |
360 | }; | 361 | }; |
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c new file mode 100644 index 000000000000..014248344763 --- /dev/null +++ b/drivers/input/sparse-keymap.c | |||
@@ -0,0 +1,267 @@ | |||
1 | /* | ||
2 | * Generic support for sparse keymaps | ||
3 | * | ||
4 | * Copyright (c) 2009 Dmitry Torokhov | ||
5 | * | ||
6 | * Derived from wistron button driver: | ||
7 | * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> | ||
8 | * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> | ||
9 | * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License version 2 as published by | ||
13 | * the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/input.h> | ||
17 | #include <linux/input/sparse-keymap.h> | ||
18 | #include <linux/slab.h> | ||
19 | |||
20 | MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); | ||
21 | MODULE_DESCRIPTION("Generic support for sparse keymaps"); | ||
22 | MODULE_LICENSE("GPL v2"); | ||
23 | MODULE_VERSION("0.1"); | ||
24 | |||
25 | /** | ||
26 | * sparse_keymap_entry_from_scancode - perform sparse keymap lookup | ||
27 | * @dev: Input device using sparse keymap | ||
28 | * @code: Scan code | ||
29 | * | ||
30 | * This function is used to perform &struct key_entry lookup in an | ||
31 | * input device using sparse keymap. | ||
32 | */ | ||
33 | struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev, | ||
34 | unsigned int code) | ||
35 | { | ||
36 | struct key_entry *key; | ||
37 | |||
38 | for (key = dev->keycode; key->type != KE_END; key++) | ||
39 | if (code == key->code) | ||
40 | return key; | ||
41 | |||
42 | return NULL; | ||
43 | } | ||
44 | EXPORT_SYMBOL(sparse_keymap_entry_from_scancode); | ||
45 | |||
46 | /** | ||
47 | * sparse_keymap_entry_from_keycode - perform sparse keymap lookup | ||
48 | * @dev: Input device using sparse keymap | ||
49 | * @keycode: Key code | ||
50 | * | ||
51 | * This function is used to perform &struct key_entry lookup in an | ||
52 | * input device using sparse keymap. | ||
53 | */ | ||
54 | struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, | ||
55 | unsigned int keycode) | ||
56 | { | ||
57 | struct key_entry *key; | ||
58 | |||
59 | for (key = dev->keycode; key->type != KE_END; key++) | ||
60 | if (key->type == KE_KEY && keycode == key->keycode) | ||
61 | return key; | ||
62 | |||
63 | return NULL; | ||
64 | } | ||
65 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); | ||
66 | |||
67 | static int sparse_keymap_getkeycode(struct input_dev *dev, | ||
68 | unsigned int scancode, | ||
69 | unsigned int *keycode) | ||
70 | { | ||
71 | const struct key_entry *key; | ||
72 | |||
73 | if (dev->keycode) { | ||
74 | key = sparse_keymap_entry_from_scancode(dev, scancode); | ||
75 | if (key && key->type == KE_KEY) { | ||
76 | *keycode = key->keycode; | ||
77 | return 0; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
84 | static int sparse_keymap_setkeycode(struct input_dev *dev, | ||
85 | unsigned int scancode, | ||
86 | unsigned int keycode) | ||
87 | { | ||
88 | struct key_entry *key; | ||
89 | int old_keycode; | ||
90 | |||
91 | if (dev->keycode) { | ||
92 | key = sparse_keymap_entry_from_scancode(dev, scancode); | ||
93 | if (key && key->type == KE_KEY) { | ||
94 | old_keycode = key->keycode; | ||
95 | key->keycode = keycode; | ||
96 | set_bit(keycode, dev->keybit); | ||
97 | if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) | ||
98 | clear_bit(old_keycode, dev->keybit); | ||
99 | return 0; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | return -EINVAL; | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * sparse_keymap_setup - set up sparse keymap for an input device | ||
108 | * @dev: Input device | ||
109 | * @keymap: Keymap in form of array of &key_entry structures ending | ||
110 | * with %KE_END type entry | ||
111 | * @setup: Function that can be used to adjust keymap entries | ||
112 | * depending on device's deeds, may be %NULL | ||
113 | * | ||
114 | * The function calculates size and allocates copy of the original | ||
115 | * keymap after which sets up input device event bits appropriately. | ||
116 | * Before destroying input device allocated keymap should be freed | ||
117 | * with a call to sparse_keymap_free(). | ||
118 | */ | ||
119 | int sparse_keymap_setup(struct input_dev *dev, | ||
120 | const struct key_entry *keymap, | ||
121 | int (*setup)(struct input_dev *, struct key_entry *)) | ||
122 | { | ||
123 | size_t map_size = 1; /* to account for the last KE_END entry */ | ||
124 | const struct key_entry *e; | ||
125 | struct key_entry *map, *entry; | ||
126 | int i; | ||
127 | int error; | ||
128 | |||
129 | for (e = keymap; e->type != KE_END; e++) | ||
130 | map_size++; | ||
131 | |||
132 | map = kcalloc(map_size, sizeof (struct key_entry), GFP_KERNEL); | ||
133 | if (!map) | ||
134 | return -ENOMEM; | ||
135 | |||
136 | memcpy(map, keymap, map_size * sizeof (struct key_entry)); | ||
137 | |||
138 | for (i = 0; i < map_size; i++) { | ||
139 | entry = &map[i]; | ||
140 | |||
141 | if (setup) { | ||
142 | error = setup(dev, entry); | ||
143 | if (error) | ||
144 | goto err_out; | ||
145 | } | ||
146 | |||
147 | switch (entry->type) { | ||
148 | case KE_KEY: | ||
149 | __set_bit(EV_KEY, dev->evbit); | ||
150 | __set_bit(entry->keycode, dev->keybit); | ||
151 | break; | ||
152 | |||
153 | case KE_SW: | ||
154 | __set_bit(EV_SW, dev->evbit); | ||
155 | __set_bit(entry->sw.code, dev->swbit); | ||
156 | break; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | dev->keycode = map; | ||
161 | dev->keycodemax = map_size; | ||
162 | dev->getkeycode = sparse_keymap_getkeycode; | ||
163 | dev->setkeycode = sparse_keymap_setkeycode; | ||
164 | |||
165 | return 0; | ||
166 | |||
167 | err_out: | ||
168 | kfree(map); | ||
169 | return error; | ||
170 | |||
171 | } | ||
172 | EXPORT_SYMBOL(sparse_keymap_setup); | ||
173 | |||
174 | /** | ||
175 | * sparse_keymap_free - free memory allocated for sparse keymap | ||
176 | * @dev: Input device using sparse keymap | ||
177 | * | ||
178 | * This function is used to free memory allocated by sparse keymap | ||
179 | * in an input device that was set up by sparse_keymap_setup(). | ||
180 | * NOTE: It is safe to cal this function while input device is | ||
181 | * still registered (however the drivers should care not to try to | ||
182 | * use freed keymap and thus have to shut off interrups/polling | ||
183 | * before freeing the keymap). | ||
184 | */ | ||
185 | void sparse_keymap_free(struct input_dev *dev) | ||
186 | { | ||
187 | unsigned long flags; | ||
188 | |||
189 | /* | ||
190 | * Take event lock to prevent racing with input_get_keycode() | ||
191 | * and input_set_keycode() if we are called while input device | ||
192 | * is still registered. | ||
193 | */ | ||
194 | spin_lock_irqsave(&dev->event_lock, flags); | ||
195 | |||
196 | kfree(dev->keycode); | ||
197 | dev->keycode = NULL; | ||
198 | dev->keycodemax = 0; | ||
199 | |||
200 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
201 | } | ||
202 | EXPORT_SYMBOL(sparse_keymap_free); | ||
203 | |||
204 | /** | ||
205 | * sparse_keymap_report_entry - report event corresponding to given key entry | ||
206 | * @dev: Input device for which event should be reported | ||
207 | * @ke: key entry describing event | ||
208 | * @value: Value that should be reported (ignored by %KE_SW entries) | ||
209 | * @autorelease: Signals whether release event should be emitted for %KE_KEY | ||
210 | * entries right after reporting press event, ignored by all other | ||
211 | * entries | ||
212 | * | ||
213 | * This function is used to report input event described by given | ||
214 | * &struct key_entry. | ||
215 | */ | ||
216 | void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke, | ||
217 | unsigned int value, bool autorelease) | ||
218 | { | ||
219 | switch (ke->type) { | ||
220 | case KE_KEY: | ||
221 | input_report_key(dev, ke->keycode, value); | ||
222 | input_sync(dev); | ||
223 | if (value && autorelease) { | ||
224 | input_report_key(dev, ke->keycode, 0); | ||
225 | input_sync(dev); | ||
226 | } | ||
227 | break; | ||
228 | |||
229 | case KE_SW: | ||
230 | value = ke->sw.value; | ||
231 | /* fall through */ | ||
232 | |||
233 | case KE_VSW: | ||
234 | input_report_switch(dev, ke->sw.code, value); | ||
235 | break; | ||
236 | } | ||
237 | } | ||
238 | EXPORT_SYMBOL(sparse_keymap_report_entry); | ||
239 | |||
240 | /** | ||
241 | * sparse_keymap_report_event - report event corresponding to given scancode | ||
242 | * @dev: Input device using sparse keymap | ||
243 | * @code: Scan code | ||
244 | * @value: Value that should be reported (ignored by %KE_SW entries) | ||
245 | * @autorelease: Signals whether release event should be emitted for %KE_KEY | ||
246 | * entries right after reporting press event, ignored by all other | ||
247 | * entries | ||
248 | * | ||
249 | * This function is used to perform lookup in an input device using sparse | ||
250 | * keymap and report corresponding event. Returns %true if lookup was | ||
251 | * successful and %false otherwise. | ||
252 | */ | ||
253 | bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code, | ||
254 | unsigned int value, bool autorelease) | ||
255 | { | ||
256 | const struct key_entry *ke = | ||
257 | sparse_keymap_entry_from_scancode(dev, code); | ||
258 | |||
259 | if (ke) { | ||
260 | sparse_keymap_report_entry(dev, ke, value, autorelease); | ||
261 | return true; | ||
262 | } | ||
263 | |||
264 | return false; | ||
265 | } | ||
266 | EXPORT_SYMBOL(sparse_keymap_report_event); | ||
267 | |||
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 7d005a3616d7..4be039d7dcad 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
@@ -362,7 +362,7 @@ static const int macroKeyEvents[] = { | |||
362 | }; | 362 | }; |
363 | 363 | ||
364 | /*********************************************************************** | 364 | /*********************************************************************** |
365 | * Map values to strings and back. Every map shoudl have the following | 365 | * Map values to strings and back. Every map should have the following |
366 | * as its last element: { NULL, AIPTEK_INVALID_VALUE }. | 366 | * as its last element: { NULL, AIPTEK_INVALID_VALUE }. |
367 | */ | 367 | */ |
368 | #define AIPTEK_INVALID_VALUE -1 | 368 | #define AIPTEK_INVALID_VALUE -1 |
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index 3d32d3f4e486..866a9ee1af1a 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c | |||
@@ -92,7 +92,7 @@ Scott Hill shill@gtcocalcomp.com | |||
92 | /* DATA STRUCTURES */ | 92 | /* DATA STRUCTURES */ |
93 | 93 | ||
94 | /* Device table */ | 94 | /* Device table */ |
95 | static struct usb_device_id gtco_usbid_table [] = { | 95 | static const struct usb_device_id gtco_usbid_table[] = { |
96 | { USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, | 96 | { USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, |
97 | { USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, | 97 | { USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, |
98 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, | 98 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 9114ae1c7488..8fef1b689c69 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/input/tablet/wacom.h | 2 | * drivers/input/tablet/wacom.h |
3 | * | 3 | * |
4 | * USB Wacom Graphire and Wacom Intuos tablet support | 4 | * USB Wacom tablet support |
5 | * | 5 | * |
6 | * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> | 6 | * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> |
7 | * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> | 7 | * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> |
@@ -69,6 +69,9 @@ | |||
69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) | 69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) |
70 | * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 | 70 | * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 |
71 | * v1.51 (pc) - Added support for Intuos4 | 71 | * v1.51 (pc) - Added support for Intuos4 |
72 | * v1.52 (pc) - Query Wacom data upon system resume | ||
73 | * - add defines for features->type | ||
74 | * - add new devices (0x9F, 0xE2, and 0XE3) | ||
72 | */ | 75 | */ |
73 | 76 | ||
74 | /* | 77 | /* |
@@ -82,6 +85,7 @@ | |||
82 | #include <linux/kernel.h> | 85 | #include <linux/kernel.h> |
83 | #include <linux/slab.h> | 86 | #include <linux/slab.h> |
84 | #include <linux/module.h> | 87 | #include <linux/module.h> |
88 | #include <linux/mod_devicetable.h> | ||
85 | #include <linux/init.h> | 89 | #include <linux/init.h> |
86 | #include <linux/usb/input.h> | 90 | #include <linux/usb/input.h> |
87 | #include <asm/unaligned.h> | 91 | #include <asm/unaligned.h> |
@@ -89,9 +93,9 @@ | |||
89 | /* | 93 | /* |
90 | * Version Information | 94 | * Version Information |
91 | */ | 95 | */ |
92 | #define DRIVER_VERSION "v1.51" | 96 | #define DRIVER_VERSION "v1.52" |
93 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 97 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
94 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 98 | #define DRIVER_DESC "USB Wacom tablet driver" |
95 | #define DRIVER_LICENSE "GPL" | 99 | #define DRIVER_LICENSE "GPL" |
96 | 100 | ||
97 | MODULE_AUTHOR(DRIVER_AUTHOR); | 101 | MODULE_AUTHOR(DRIVER_AUTHOR); |
@@ -117,6 +121,8 @@ struct wacom_combo { | |||
117 | struct urb *urb; | 121 | struct urb *urb; |
118 | }; | 122 | }; |
119 | 123 | ||
124 | extern const struct usb_device_id wacom_ids[]; | ||
125 | |||
120 | extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); | 126 | extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); |
121 | extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); | 127 | extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); |
122 | extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); | 128 | extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); |
@@ -133,11 +139,11 @@ extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
133 | extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 139 | extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
134 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 140 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
135 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 141 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
142 | extern void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
143 | extern void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
136 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 144 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
137 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 145 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
138 | extern __u16 wacom_le16_to_cpu(unsigned char *data); | 146 | extern __u16 wacom_le16_to_cpu(unsigned char *data); |
139 | extern __u16 wacom_be16_to_cpu(unsigned char *data); | 147 | extern __u16 wacom_be16_to_cpu(unsigned char *data); |
140 | extern struct wacom_features *get_wacom_feature(const struct usb_device_id *id); | ||
141 | extern const struct usb_device_id *get_device_table(void); | ||
142 | 148 | ||
143 | #endif | 149 | #endif |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index ea30c983a33e..f46502589e4e 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/input/tablet/wacom_sys.c | 2 | * drivers/input/tablet/wacom_sys.c |
3 | * | 3 | * |
4 | * USB Wacom Graphire and Wacom Intuos tablet support - system specific code | 4 | * USB Wacom tablet support - system specific code |
5 | */ | 5 | */ |
6 | 6 | ||
7 | /* | 7 | /* |
@@ -209,8 +209,10 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
209 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | | 209 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | |
210 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | 210 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); |
211 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | 211 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | |
212 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | | ||
212 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); | 213 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); |
213 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); | 214 | input_set_abs_params(input_dev, ABS_DISTANCE, |
215 | 0, wacom_wac->features.distance_max, 0, 0); | ||
214 | } | 216 | } |
215 | 217 | ||
216 | void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 218 | void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
@@ -256,10 +258,12 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
256 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | | 258 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | |
257 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); | 259 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); |
258 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | 260 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | |
261 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | | ||
259 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | | 262 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | |
260 | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | | 263 | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | |
261 | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); | 264 | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); |
262 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); | 265 | input_set_abs_params(input_dev, ABS_DISTANCE, |
266 | 0, wacom_wac->features.distance_max, 0, 0); | ||
263 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); | 267 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); |
264 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); | 268 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); |
265 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); | 269 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); |
@@ -269,7 +273,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
269 | 273 | ||
270 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 274 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
271 | { | 275 | { |
272 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); | 276 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | |
277 | BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_STYLUS2); | ||
273 | } | 278 | } |
274 | 279 | ||
275 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 280 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
@@ -277,12 +282,34 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
277 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); | 282 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); |
278 | } | 283 | } |
279 | 284 | ||
285 | void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
286 | { | ||
287 | struct wacom_features *features = &wacom_wac->features; | ||
288 | |||
289 | if (features->device_type == BTN_TOOL_DOUBLETAP || | ||
290 | features->device_type == BTN_TOOL_TRIPLETAP) { | ||
291 | input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0); | ||
292 | input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0); | ||
293 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
298 | { | ||
299 | if (wacom_wac->features.device_type == BTN_TOOL_TRIPLETAP) { | ||
300 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); | ||
301 | input_dev->evbit[0] |= BIT_MASK(EV_MSC); | ||
302 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | ||
303 | } | ||
304 | } | ||
305 | |||
280 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | 306 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, |
281 | struct wacom_wac *wacom_wac) | 307 | struct wacom_features *features) |
282 | { | 308 | { |
283 | struct usb_device *dev = interface_to_usbdev(intf); | 309 | struct usb_device *dev = interface_to_usbdev(intf); |
284 | struct wacom_features *features = wacom_wac->features; | 310 | char limit = 0; |
285 | char limit = 0, result = 0; | 311 | /* result has to be defined as int for some devices */ |
312 | int result = 0; | ||
286 | int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; | 313 | int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; |
287 | unsigned char *report; | 314 | unsigned char *report; |
288 | 315 | ||
@@ -328,13 +355,24 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
328 | case HID_USAGE_X: | 355 | case HID_USAGE_X: |
329 | if (usage == WCM_DESKTOP) { | 356 | if (usage == WCM_DESKTOP) { |
330 | if (finger) { | 357 | if (finger) { |
331 | features->touch_x_max = | 358 | features->device_type = BTN_TOOL_DOUBLETAP; |
332 | features->touch_y_max = | 359 | if (features->type == TABLETPC2FG) { |
333 | wacom_le16_to_cpu(&report[i + 3]); | 360 | /* need to reset back */ |
361 | features->pktlen = WACOM_PKGLEN_TPC2FG; | ||
362 | features->device_type = BTN_TOOL_TRIPLETAP; | ||
363 | } | ||
334 | features->x_max = | 364 | features->x_max = |
365 | wacom_le16_to_cpu(&report[i + 3]); | ||
366 | features->x_phy = | ||
335 | wacom_le16_to_cpu(&report[i + 6]); | 367 | wacom_le16_to_cpu(&report[i + 6]); |
336 | i += 7; | 368 | features->unit = report[i + 9]; |
369 | features->unitExpo = report[i + 11]; | ||
370 | i += 12; | ||
337 | } else if (pen) { | 371 | } else if (pen) { |
372 | /* penabled only accepts exact bytes of data */ | ||
373 | if (features->type == TABLETPC2FG) | ||
374 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | ||
375 | features->device_type = BTN_TOOL_PEN; | ||
338 | features->x_max = | 376 | features->x_max = |
339 | wacom_le16_to_cpu(&report[i + 3]); | 377 | wacom_le16_to_cpu(&report[i + 3]); |
340 | i += 4; | 378 | i += 4; |
@@ -350,10 +388,35 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
350 | break; | 388 | break; |
351 | 389 | ||
352 | case HID_USAGE_Y: | 390 | case HID_USAGE_Y: |
353 | if (usage == WCM_DESKTOP) | 391 | if (usage == WCM_DESKTOP) { |
354 | features->y_max = | 392 | if (finger) { |
355 | wacom_le16_to_cpu(&report[i + 3]); | 393 | features->device_type = BTN_TOOL_DOUBLETAP; |
356 | i += 4; | 394 | if (features->type == TABLETPC2FG) { |
395 | /* need to reset back */ | ||
396 | features->pktlen = WACOM_PKGLEN_TPC2FG; | ||
397 | features->device_type = BTN_TOOL_TRIPLETAP; | ||
398 | features->y_max = | ||
399 | wacom_le16_to_cpu(&report[i + 3]); | ||
400 | features->y_phy = | ||
401 | wacom_le16_to_cpu(&report[i + 6]); | ||
402 | i += 7; | ||
403 | } else { | ||
404 | features->y_max = | ||
405 | features->x_max; | ||
406 | features->y_phy = | ||
407 | wacom_le16_to_cpu(&report[i + 3]); | ||
408 | i += 4; | ||
409 | } | ||
410 | } else if (pen) { | ||
411 | /* penabled only accepts exact bytes of data */ | ||
412 | if (features->type == TABLETPC2FG) | ||
413 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | ||
414 | features->device_type = BTN_TOOL_PEN; | ||
415 | features->y_max = | ||
416 | wacom_le16_to_cpu(&report[i + 3]); | ||
417 | i += 4; | ||
418 | } | ||
419 | } | ||
357 | break; | 420 | break; |
358 | 421 | ||
359 | case HID_USAGE_FINGER: | 422 | case HID_USAGE_FINGER: |
@@ -376,7 +439,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
376 | break; | 439 | break; |
377 | 440 | ||
378 | case HID_COLLECTION: | 441 | case HID_COLLECTION: |
379 | /* reset UsagePage ans Finger */ | 442 | /* reset UsagePage and Finger */ |
380 | finger = usage = 0; | 443 | finger = usage = 0; |
381 | break; | 444 | break; |
382 | } | 445 | } |
@@ -388,57 +451,123 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
388 | return result; | 451 | return result; |
389 | } | 452 | } |
390 | 453 | ||
391 | static int wacom_query_tablet_data(struct usb_interface *intf) | 454 | static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features) |
392 | { | 455 | { |
393 | unsigned char *rep_data; | 456 | unsigned char *rep_data; |
394 | int limit = 0; | 457 | int limit = 0, report_id = 2; |
395 | int error; | 458 | int error = -ENOMEM; |
396 | 459 | ||
397 | rep_data = kmalloc(2, GFP_KERNEL); | 460 | rep_data = kmalloc(2, GFP_KERNEL); |
398 | if (!rep_data) | 461 | if (!rep_data) |
399 | return -ENOMEM; | 462 | return error; |
400 | 463 | ||
401 | do { | 464 | /* ask to report tablet data if it is 2FGT or not a Tablet PC */ |
402 | rep_data[0] = 2; | 465 | if (features->device_type == BTN_TOOL_TRIPLETAP) { |
403 | rep_data[1] = 2; | 466 | do { |
404 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | 467 | rep_data[0] = 3; |
405 | 2, rep_data, 2); | 468 | rep_data[1] = 4; |
406 | if (error >= 0) | 469 | report_id = 3; |
407 | error = usb_get_report(intf, | 470 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, |
408 | WAC_HID_FEATURE_REPORT, 2, | 471 | report_id, rep_data, 2); |
409 | rep_data, 2); | 472 | if (error >= 0) |
410 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | 473 | error = usb_get_report(intf, |
474 | WAC_HID_FEATURE_REPORT, report_id, | ||
475 | rep_data, 3); | ||
476 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); | ||
477 | } else if (features->type != TABLETPC && features->type != TABLETPC2FG) { | ||
478 | do { | ||
479 | rep_data[0] = 2; | ||
480 | rep_data[1] = 2; | ||
481 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | ||
482 | report_id, rep_data, 2); | ||
483 | if (error >= 0) | ||
484 | error = usb_get_report(intf, | ||
485 | WAC_HID_FEATURE_REPORT, report_id, | ||
486 | rep_data, 2); | ||
487 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | ||
488 | } | ||
411 | 489 | ||
412 | kfree(rep_data); | 490 | kfree(rep_data); |
413 | 491 | ||
414 | return error < 0 ? error : 0; | 492 | return error < 0 ? error : 0; |
415 | } | 493 | } |
416 | 494 | ||
495 | static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | ||
496 | struct wacom_features *features) | ||
497 | { | ||
498 | int error = 0; | ||
499 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
500 | struct hid_descriptor *hid_desc; | ||
501 | |||
502 | /* default device to penabled */ | ||
503 | features->device_type = BTN_TOOL_PEN; | ||
504 | |||
505 | /* only Tablet PCs need to retrieve the info */ | ||
506 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) | ||
507 | goto out; | ||
508 | |||
509 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | ||
510 | if (usb_get_extra_descriptor(&interface->endpoint[0], | ||
511 | HID_DEVICET_REPORT, &hid_desc)) { | ||
512 | printk("wacom: can not retrieve extra class descriptor\n"); | ||
513 | error = 1; | ||
514 | goto out; | ||
515 | } | ||
516 | } | ||
517 | error = wacom_parse_hid(intf, hid_desc, features); | ||
518 | if (error) | ||
519 | goto out; | ||
520 | |||
521 | /* touch device found but size is not defined. use default */ | ||
522 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
523 | features->x_max = 1023; | ||
524 | features->y_max = 1023; | ||
525 | } | ||
526 | |||
527 | out: | ||
528 | return error; | ||
529 | } | ||
530 | |||
417 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 531 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
418 | { | 532 | { |
419 | struct usb_device *dev = interface_to_usbdev(intf); | 533 | struct usb_device *dev = interface_to_usbdev(intf); |
420 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
421 | struct usb_endpoint_descriptor *endpoint; | 534 | struct usb_endpoint_descriptor *endpoint; |
422 | struct wacom *wacom; | 535 | struct wacom *wacom; |
423 | struct wacom_wac *wacom_wac; | 536 | struct wacom_wac *wacom_wac; |
424 | struct wacom_features *features; | 537 | struct wacom_features *features; |
425 | struct input_dev *input_dev; | 538 | struct input_dev *input_dev; |
426 | int error = -ENOMEM; | 539 | int error; |
427 | struct hid_descriptor *hid_desc; | 540 | |
541 | if (!id->driver_info) | ||
542 | return -EINVAL; | ||
428 | 543 | ||
429 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 544 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
430 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); | 545 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); |
431 | input_dev = input_allocate_device(); | 546 | input_dev = input_allocate_device(); |
432 | if (!wacom || !input_dev || !wacom_wac) | 547 | if (!wacom || !input_dev || !wacom_wac) { |
548 | error = -ENOMEM; | ||
433 | goto fail1; | 549 | goto fail1; |
550 | } | ||
434 | 551 | ||
435 | wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); | 552 | wacom_wac->features = *((struct wacom_features *)id->driver_info); |
436 | if (!wacom_wac->data) | 553 | features = &wacom_wac->features; |
554 | if (features->pktlen > WACOM_PKGLEN_MAX) { | ||
555 | error = -EINVAL; | ||
437 | goto fail1; | 556 | goto fail1; |
557 | } | ||
558 | |||
559 | wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, | ||
560 | GFP_KERNEL, &wacom->data_dma); | ||
561 | if (!wacom_wac->data) { | ||
562 | error = -ENOMEM; | ||
563 | goto fail1; | ||
564 | } | ||
438 | 565 | ||
439 | wacom->irq = usb_alloc_urb(0, GFP_KERNEL); | 566 | wacom->irq = usb_alloc_urb(0, GFP_KERNEL); |
440 | if (!wacom->irq) | 567 | if (!wacom->irq) { |
568 | error = -ENOMEM; | ||
441 | goto fail2; | 569 | goto fail2; |
570 | } | ||
442 | 571 | ||
443 | wacom->usbdev = dev; | 572 | wacom->usbdev = dev; |
444 | wacom->dev = input_dev; | 573 | wacom->dev = input_dev; |
@@ -447,11 +576,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
447 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); | 576 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); |
448 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | 577 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); |
449 | 578 | ||
450 | wacom_wac->features = features = get_wacom_feature(id); | ||
451 | BUG_ON(features->pktlen > 10); | ||
452 | |||
453 | input_dev->name = wacom_wac->features->name; | ||
454 | wacom->wacom_wac = wacom_wac; | ||
455 | usb_to_input_id(dev, &input_dev->id); | 579 | usb_to_input_id(dev, &input_dev->id); |
456 | 580 | ||
457 | input_dev->dev.parent = &intf->dev; | 581 | input_dev->dev.parent = &intf->dev; |
@@ -463,47 +587,37 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
463 | 587 | ||
464 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 588 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
465 | 589 | ||
466 | /* Initialize touch_x_max and touch_y_max in case it is not defined */ | 590 | /* Retrieve the physical and logical size for OEM devices */ |
467 | if (wacom_wac->features->type == TABLETPC) { | 591 | error = wacom_retrieve_hid_descriptor(intf, features); |
468 | features->touch_x_max = 1023; | 592 | if (error) |
469 | features->touch_y_max = 1023; | 593 | goto fail2; |
470 | } else { | ||
471 | features->touch_x_max = 0; | ||
472 | features->touch_y_max = 0; | ||
473 | } | ||
474 | 594 | ||
475 | /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ | 595 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
476 | if (wacom_wac->features->type == TABLETPC) { | 596 | |
477 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | 597 | if (features->type == TABLETPC || features->type == TABLETPC2FG) { |
478 | if (usb_get_extra_descriptor(&interface->endpoint[0], | 598 | /* Append the device type to the name */ |
479 | HID_DEVICET_REPORT, &hid_desc)) { | 599 | strlcat(wacom_wac->name, |
480 | printk("wacom: can not retrive extra class descriptor\n"); | 600 | features->device_type == BTN_TOOL_PEN ? |
481 | goto fail2; | 601 | " Pen" : " Finger", |
482 | } | 602 | sizeof(wacom_wac->name)); |
483 | } | ||
484 | error = wacom_parse_hid(intf, hid_desc, wacom_wac); | ||
485 | if (error) | ||
486 | goto fail2; | ||
487 | } | 603 | } |
488 | 604 | ||
605 | input_dev->name = wacom_wac->name; | ||
606 | wacom->wacom_wac = wacom_wac; | ||
607 | |||
489 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 608 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
490 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | | 609 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); |
491 | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); | 610 | |
492 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); | 611 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); |
493 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); | 612 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); |
494 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); | 613 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); |
495 | if (features->type == TABLETPC) { | ||
496 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); | ||
497 | input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0); | ||
498 | input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0); | ||
499 | } | ||
500 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | 614 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); |
501 | 615 | ||
502 | wacom_init_input_dev(input_dev, wacom_wac); | 616 | wacom_init_input_dev(input_dev, wacom_wac); |
503 | 617 | ||
504 | usb_fill_int_urb(wacom->irq, dev, | 618 | usb_fill_int_urb(wacom->irq, dev, |
505 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | 619 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
506 | wacom_wac->data, wacom_wac->features->pktlen, | 620 | wacom_wac->data, features->pktlen, |
507 | wacom_sys_irq, wacom, endpoint->bInterval); | 621 | wacom_sys_irq, wacom, endpoint->bInterval); |
508 | wacom->irq->transfer_dma = wacom->data_dma; | 622 | wacom->irq->transfer_dma = wacom->data_dma; |
509 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 623 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
@@ -512,18 +626,14 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
512 | if (error) | 626 | if (error) |
513 | goto fail3; | 627 | goto fail3; |
514 | 628 | ||
515 | /* | 629 | /* Note that if query fails it is not a hard failure */ |
516 | * Ask the tablet to report tablet data if it is not a Tablet PC. | 630 | wacom_query_tablet_data(intf, features); |
517 | * Note that if query fails it is not a hard failure. | ||
518 | */ | ||
519 | if (wacom_wac->features->type != TABLETPC) | ||
520 | wacom_query_tablet_data(intf); | ||
521 | 631 | ||
522 | usb_set_intfdata(intf, wacom); | 632 | usb_set_intfdata(intf, wacom); |
523 | return 0; | 633 | return 0; |
524 | 634 | ||
525 | fail3: usb_free_urb(wacom->irq); | 635 | fail3: usb_free_urb(wacom->irq); |
526 | fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); | 636 | fail2: usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); |
527 | fail1: input_free_device(input_dev); | 637 | fail1: input_free_device(input_dev); |
528 | kfree(wacom); | 638 | kfree(wacom); |
529 | kfree(wacom_wac); | 639 | kfree(wacom_wac); |
@@ -539,7 +649,7 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
539 | usb_kill_urb(wacom->irq); | 649 | usb_kill_urb(wacom->irq); |
540 | input_unregister_device(wacom->dev); | 650 | input_unregister_device(wacom->dev); |
541 | usb_free_urb(wacom->irq); | 651 | usb_free_urb(wacom->irq); |
542 | usb_buffer_free(interface_to_usbdev(intf), 10, | 652 | usb_buffer_free(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, |
543 | wacom->wacom_wac->data, wacom->data_dma); | 653 | wacom->wacom_wac->data, wacom->data_dma); |
544 | kfree(wacom->wacom_wac); | 654 | kfree(wacom->wacom_wac); |
545 | kfree(wacom); | 655 | kfree(wacom); |
@@ -559,13 +669,19 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message) | |||
559 | static int wacom_resume(struct usb_interface *intf) | 669 | static int wacom_resume(struct usb_interface *intf) |
560 | { | 670 | { |
561 | struct wacom *wacom = usb_get_intfdata(intf); | 671 | struct wacom *wacom = usb_get_intfdata(intf); |
672 | struct wacom_features *features = &wacom->wacom_wac->features; | ||
562 | int rv; | 673 | int rv; |
563 | 674 | ||
564 | mutex_lock(&wacom->lock); | 675 | mutex_lock(&wacom->lock); |
676 | |||
677 | /* switch to wacom mode first */ | ||
678 | wacom_query_tablet_data(intf, features); | ||
679 | |||
565 | if (wacom->open) | 680 | if (wacom->open) |
566 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); | 681 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); |
567 | else | 682 | else |
568 | rv = 0; | 683 | rv = 0; |
684 | |||
569 | mutex_unlock(&wacom->lock); | 685 | mutex_unlock(&wacom->lock); |
570 | 686 | ||
571 | return rv; | 687 | return rv; |
@@ -578,6 +694,7 @@ static int wacom_reset_resume(struct usb_interface *intf) | |||
578 | 694 | ||
579 | static struct usb_driver wacom_driver = { | 695 | static struct usb_driver wacom_driver = { |
580 | .name = "wacom", | 696 | .name = "wacom", |
697 | .id_table = wacom_ids, | ||
581 | .probe = wacom_probe, | 698 | .probe = wacom_probe, |
582 | .disconnect = wacom_disconnect, | 699 | .disconnect = wacom_disconnect, |
583 | .suspend = wacom_suspend, | 700 | .suspend = wacom_suspend, |
@@ -589,7 +706,7 @@ static struct usb_driver wacom_driver = { | |||
589 | static int __init wacom_init(void) | 706 | static int __init wacom_init(void) |
590 | { | 707 | { |
591 | int result; | 708 | int result; |
592 | wacom_driver.id_table = get_device_table(); | 709 | |
593 | result = usb_register(&wacom_driver); | 710 | result = usb_register(&wacom_driver); |
594 | if (result == 0) | 711 | if (result == 0) |
595 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | 712 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index c896d6a21b7e..4a852d815c68 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/input/tablet/wacom_wac.c | 2 | * drivers/input/tablet/wacom_wac.c |
3 | * | 3 | * |
4 | * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code | 4 | * USB Wacom tablet support - Wacom specific code |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | 7 | ||
@@ -55,23 +55,23 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) | |||
55 | 55 | ||
56 | static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | 56 | static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) |
57 | { | 57 | { |
58 | struct wacom_features *features = &wacom->features; | ||
58 | unsigned char *data = wacom->data; | 59 | unsigned char *data = wacom->data; |
59 | int prox, pressure; | 60 | int prox, pressure; |
60 | 61 | ||
61 | if (data[0] != 2) { | 62 | if (data[0] != WACOM_REPORT_PENABLED) { |
62 | dbg("wacom_pl_irq: received unknown report #%d", data[0]); | 63 | dbg("wacom_pl_irq: received unknown report #%d", data[0]); |
63 | return 0; | 64 | return 0; |
64 | } | 65 | } |
65 | 66 | ||
66 | prox = data[1] & 0x40; | 67 | prox = data[1] & 0x40; |
67 | 68 | ||
68 | wacom->id[0] = ERASER_DEVICE_ID; | ||
69 | if (prox) { | 69 | if (prox) { |
70 | 70 | wacom->id[0] = ERASER_DEVICE_ID; | |
71 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); | 71 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); |
72 | if (wacom->features->pressure_max > 255) | 72 | if (features->pressure_max > 255) |
73 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); | 73 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); |
74 | pressure += (wacom->features->pressure_max + 1) / 2; | 74 | pressure += (features->pressure_max + 1) / 2; |
75 | 75 | ||
76 | /* | 76 | /* |
77 | * if going from out of proximity into proximity select between the eraser | 77 | * if going from out of proximity into proximity select between the eraser |
@@ -128,7 +128,7 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) | |||
128 | { | 128 | { |
129 | unsigned char *data = wacom->data; | 129 | unsigned char *data = wacom->data; |
130 | 130 | ||
131 | if (data[0] != 2) { | 131 | if (data[0] != WACOM_REPORT_PENABLED) { |
132 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); | 132 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); |
133 | return 0; | 133 | return 0; |
134 | } | 134 | } |
@@ -153,16 +153,19 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) | |||
153 | 153 | ||
154 | static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | 154 | static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) |
155 | { | 155 | { |
156 | struct wacom_features *features = &wacom->features; | ||
156 | unsigned char *data = wacom->data; | 157 | unsigned char *data = wacom->data; |
157 | int x, y, rw; | 158 | int x, y, rw; |
159 | static int penData = 0; | ||
158 | 160 | ||
159 | if (data[0] != 2) { | 161 | if (data[0] != WACOM_REPORT_PENABLED) { |
160 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); | 162 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); |
161 | return 0; | 163 | return 0; |
162 | } | 164 | } |
163 | 165 | ||
164 | if (data[1] & 0x80) { | 166 | if (data[1] & 0x80) { |
165 | /* in prox and not a pad data */ | 167 | /* in prox and not a pad data */ |
168 | penData = 1; | ||
166 | 169 | ||
167 | switch ((data[1] >> 5) & 3) { | 170 | switch ((data[1] >> 5) & 3) { |
168 | 171 | ||
@@ -178,8 +181,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
178 | 181 | ||
179 | case 2: /* Mouse with wheel */ | 182 | case 2: /* Mouse with wheel */ |
180 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); | 183 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); |
181 | if (wacom->features->type == WACOM_G4 || | 184 | if (features->type == WACOM_G4 || features->type == WACOM_MO) { |
182 | wacom->features->type == WACOM_MO) { | ||
183 | rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); | 185 | rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); |
184 | wacom_report_rel(wcombo, REL_WHEEL, -rw); | 186 | wacom_report_rel(wcombo, REL_WHEEL, -rw); |
185 | } else | 187 | } else |
@@ -191,8 +193,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
191 | wacom->id[0] = CURSOR_DEVICE_ID; | 193 | wacom->id[0] = CURSOR_DEVICE_ID; |
192 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | 194 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); |
193 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | 195 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); |
194 | if (wacom->features->type == WACOM_G4 || | 196 | if (features->type == WACOM_G4 || features->type == WACOM_MO) |
195 | wacom->features->type == WACOM_MO) | ||
196 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); | 197 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); |
197 | else | 198 | else |
198 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); | 199 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); |
@@ -229,10 +230,14 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
229 | } | 230 | } |
230 | 231 | ||
231 | /* send pad data */ | 232 | /* send pad data */ |
232 | switch (wacom->features->type) { | 233 | switch (features->type) { |
233 | case WACOM_G4: | 234 | case WACOM_G4: |
234 | if (data[7] & 0xf8) { | 235 | if (data[7] & 0xf8) { |
235 | wacom_input_sync(wcombo); /* sync last event */ | 236 | if (penData) { |
237 | wacom_input_sync(wcombo); /* sync last event */ | ||
238 | if (!wacom->id[0]) | ||
239 | penData = 0; | ||
240 | } | ||
236 | wacom->id[1] = PAD_DEVICE_ID; | 241 | wacom->id[1] = PAD_DEVICE_ID; |
237 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 242 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
238 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 243 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
@@ -242,10 +247,15 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
242 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 247 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
243 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 248 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
244 | } else if (wacom->id[1]) { | 249 | } else if (wacom->id[1]) { |
245 | wacom_input_sync(wcombo); /* sync last event */ | 250 | if (penData) { |
251 | wacom_input_sync(wcombo); /* sync last event */ | ||
252 | if (!wacom->id[0]) | ||
253 | penData = 0; | ||
254 | } | ||
246 | wacom->id[1] = 0; | 255 | wacom->id[1] = 0; |
247 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 256 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
248 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 257 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
258 | wacom_report_rel(wcombo, REL_WHEEL, 0); | ||
249 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | 259 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); |
250 | wacom_report_abs(wcombo, ABS_MISC, 0); | 260 | wacom_report_abs(wcombo, ABS_MISC, 0); |
251 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 261 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
@@ -253,7 +263,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
253 | break; | 263 | break; |
254 | case WACOM_MO: | 264 | case WACOM_MO: |
255 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { | 265 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { |
256 | wacom_input_sync(wcombo); /* sync last event */ | 266 | if (penData) { |
267 | wacom_input_sync(wcombo); /* sync last event */ | ||
268 | if (!wacom->id[0]) | ||
269 | penData = 0; | ||
270 | } | ||
257 | wacom->id[1] = PAD_DEVICE_ID; | 271 | wacom->id[1] = PAD_DEVICE_ID; |
258 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 272 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
259 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 273 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
@@ -264,7 +278,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
264 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 278 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
265 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 279 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
266 | } else if (wacom->id[1]) { | 280 | } else if (wacom->id[1]) { |
267 | wacom_input_sync(wcombo); /* sync last event */ | 281 | if (penData) { |
282 | wacom_input_sync(wcombo); /* sync last event */ | ||
283 | if (!wacom->id[0]) | ||
284 | penData = 0; | ||
285 | } | ||
268 | wacom->id[1] = 0; | 286 | wacom->id[1] = 0; |
269 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 287 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
270 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 288 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
@@ -282,11 +300,12 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
282 | 300 | ||
283 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | 301 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) |
284 | { | 302 | { |
303 | struct wacom_features *features = &wacom->features; | ||
285 | unsigned char *data = wacom->data; | 304 | unsigned char *data = wacom->data; |
286 | int idx = 0; | 305 | int idx = 0; |
287 | 306 | ||
288 | /* tool number */ | 307 | /* tool number */ |
289 | if (wacom->features->type == INTUOS) | 308 | if (features->type == INTUOS) |
290 | idx = data[1] & 0x01; | 309 | idx = data[1] & 0x01; |
291 | 310 | ||
292 | /* Enter report */ | 311 | /* Enter report */ |
@@ -384,7 +403,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
384 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 403 | wacom_report_key(wcombo, BTN_STYLUS2, 0); |
385 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 404 | wacom_report_key(wcombo, BTN_TOUCH, 0); |
386 | wacom_report_abs(wcombo, ABS_WHEEL, 0); | 405 | wacom_report_abs(wcombo, ABS_WHEEL, 0); |
387 | if (wacom->features->type >= INTUOS3S) | 406 | if (features->type >= INTUOS3S) |
388 | wacom_report_abs(wcombo, ABS_Z, 0); | 407 | wacom_report_abs(wcombo, ABS_Z, 0); |
389 | } | 408 | } |
390 | wacom_report_key(wcombo, wacom->tool[idx], 0); | 409 | wacom_report_key(wcombo, wacom->tool[idx], 0); |
@@ -398,13 +417,14 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
398 | 417 | ||
399 | static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) | 418 | static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) |
400 | { | 419 | { |
420 | struct wacom_features *features = &wacom->features; | ||
401 | unsigned char *data = wacom->data; | 421 | unsigned char *data = wacom->data; |
402 | unsigned int t; | 422 | unsigned int t; |
403 | 423 | ||
404 | /* general pen packet */ | 424 | /* general pen packet */ |
405 | if ((data[1] & 0xb8) == 0xa0) { | 425 | if ((data[1] & 0xb8) == 0xa0) { |
406 | t = (data[6] << 2) | ((data[7] >> 6) & 3); | 426 | t = (data[6] << 2) | ((data[7] >> 6) & 3); |
407 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) | 427 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) |
408 | t = (t << 1) | (data[1] & 1); | 428 | t = (t << 1) | (data[1] & 1); |
409 | wacom_report_abs(wcombo, ABS_PRESSURE, t); | 429 | wacom_report_abs(wcombo, ABS_PRESSURE, t); |
410 | wacom_report_abs(wcombo, ABS_TILT_X, | 430 | wacom_report_abs(wcombo, ABS_TILT_X, |
@@ -428,26 +448,28 @@ static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) | |||
428 | 448 | ||
429 | static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | 449 | static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) |
430 | { | 450 | { |
451 | struct wacom_features *features = &wacom->features; | ||
431 | unsigned char *data = wacom->data; | 452 | unsigned char *data = wacom->data; |
432 | unsigned int t; | 453 | unsigned int t; |
433 | int idx = 0, result; | 454 | int idx = 0, result; |
434 | 455 | ||
435 | if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { | 456 | if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_INTUOSREAD |
457 | && data[0] != WACOM_REPORT_INTUOSWRITE && data[0] != WACOM_REPORT_INTUOSPAD) { | ||
436 | dbg("wacom_intuos_irq: received unknown report #%d", data[0]); | 458 | dbg("wacom_intuos_irq: received unknown report #%d", data[0]); |
437 | return 0; | 459 | return 0; |
438 | } | 460 | } |
439 | 461 | ||
440 | /* tool number */ | 462 | /* tool number */ |
441 | if (wacom->features->type == INTUOS) | 463 | if (features->type == INTUOS) |
442 | idx = data[1] & 0x01; | 464 | idx = data[1] & 0x01; |
443 | 465 | ||
444 | /* pad packets. Works as a second tool and is always in prox */ | 466 | /* pad packets. Works as a second tool and is always in prox */ |
445 | if (data[0] == 12) { | 467 | if (data[0] == WACOM_REPORT_INTUOSPAD) { |
446 | /* initiate the pad as a device */ | 468 | /* initiate the pad as a device */ |
447 | if (wacom->tool[1] != BTN_TOOL_FINGER) | 469 | if (wacom->tool[1] != BTN_TOOL_FINGER) |
448 | wacom->tool[1] = BTN_TOOL_FINGER; | 470 | wacom->tool[1] = BTN_TOOL_FINGER; |
449 | 471 | ||
450 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { | 472 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
451 | wacom_report_key(wcombo, BTN_0, (data[2] & 0x01)); | 473 | wacom_report_key(wcombo, BTN_0, (data[2] & 0x01)); |
452 | wacom_report_key(wcombo, BTN_1, (data[3] & 0x01)); | 474 | wacom_report_key(wcombo, BTN_1, (data[3] & 0x01)); |
453 | wacom_report_key(wcombo, BTN_2, (data[3] & 0x02)); | 475 | wacom_report_key(wcombo, BTN_2, (data[3] & 0x02)); |
@@ -461,7 +483,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
461 | /* Out of proximity, clear wheel value. */ | 483 | /* Out of proximity, clear wheel value. */ |
462 | wacom_report_abs(wcombo, ABS_WHEEL, 0); | 484 | wacom_report_abs(wcombo, ABS_WHEEL, 0); |
463 | } | 485 | } |
464 | if (wacom->features->type != INTUOS4S) { | 486 | if (features->type != INTUOS4S) { |
465 | wacom_report_key(wcombo, BTN_7, (data[3] & 0x40)); | 487 | wacom_report_key(wcombo, BTN_7, (data[3] & 0x40)); |
466 | wacom_report_key(wcombo, BTN_8, (data[3] & 0x80)); | 488 | wacom_report_key(wcombo, BTN_8, (data[3] & 0x80)); |
467 | } | 489 | } |
@@ -509,18 +531,20 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
509 | return 0; | 531 | return 0; |
510 | 532 | ||
511 | /* Only large Intuos support Lense Cursor */ | 533 | /* Only large Intuos support Lense Cursor */ |
512 | if ((wacom->tool[idx] == BTN_TOOL_LENS) | 534 | if (wacom->tool[idx] == BTN_TOOL_LENS && |
513 | && ((wacom->features->type == INTUOS3) | 535 | (features->type == INTUOS3 || |
514 | || (wacom->features->type == INTUOS3S) | 536 | features->type == INTUOS3S || |
515 | || (wacom->features->type == INTUOS4) | 537 | features->type == INTUOS4 || |
516 | || (wacom->features->type == INTUOS4S))) | 538 | features->type == INTUOS4S)) { |
539 | |||
517 | return 0; | 540 | return 0; |
541 | } | ||
518 | 542 | ||
519 | /* Cintiq doesn't send data when RDY bit isn't set */ | 543 | /* Cintiq doesn't send data when RDY bit isn't set */ |
520 | if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) | 544 | if (features->type == CINTIQ && !(data[1] & 0x40)) |
521 | return 0; | 545 | return 0; |
522 | 546 | ||
523 | if (wacom->features->type >= INTUOS3S) { | 547 | if (features->type >= INTUOS3S) { |
524 | wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); | 548 | wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); |
525 | wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); | 549 | wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); |
526 | wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); | 550 | wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); |
@@ -538,7 +562,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
538 | 562 | ||
539 | if (data[1] & 0x02) { | 563 | if (data[1] & 0x02) { |
540 | /* Rotation packet */ | 564 | /* Rotation packet */ |
541 | if (wacom->features->type >= INTUOS3S) { | 565 | if (features->type >= INTUOS3S) { |
542 | /* I3 marker pen rotation */ | 566 | /* I3 marker pen rotation */ |
543 | t = (data[6] << 3) | ((data[7] >> 5) & 7); | 567 | t = (data[6] << 3) | ((data[7] >> 5) & 7); |
544 | t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : | 568 | t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : |
@@ -551,7 +575,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
551 | ((t - 1) / 2) : -t / 2); | 575 | ((t - 1) / 2) : -t / 2); |
552 | } | 576 | } |
553 | 577 | ||
554 | } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) { | 578 | } else if (!(data[1] & 0x10) && features->type < INTUOS3S) { |
555 | /* 4D mouse packet */ | 579 | /* 4D mouse packet */ |
556 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); | 580 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); |
557 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); | 581 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); |
@@ -564,7 +588,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
564 | 588 | ||
565 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { | 589 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { |
566 | /* I4 mouse */ | 590 | /* I4 mouse */ |
567 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { | 591 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
568 | wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01); | 592 | wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01); |
569 | wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02); | 593 | wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02); |
570 | wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04); | 594 | wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04); |
@@ -585,13 +609,13 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
585 | - ((data[8] & 0x02) >> 1)); | 609 | - ((data[8] & 0x02) >> 1)); |
586 | 610 | ||
587 | /* I3 2D mouse side buttons */ | 611 | /* I3 2D mouse side buttons */ |
588 | if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { | 612 | if (features->type >= INTUOS3S && features->type <= INTUOS3L) { |
589 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); | 613 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); |
590 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); | 614 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); |
591 | } | 615 | } |
592 | } | 616 | } |
593 | } else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || | 617 | } else if ((features->type < INTUOS3S || features->type == INTUOS3L || |
594 | wacom->features->type == INTUOS4L) && | 618 | features->type == INTUOS4L) && |
595 | wacom->tool[idx] == BTN_TOOL_LENS) { | 619 | wacom->tool[idx] == BTN_TOOL_LENS) { |
596 | /* Lens cursor packets */ | 620 | /* Lens cursor packets */ |
597 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); | 621 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); |
@@ -608,95 +632,164 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
608 | return 1; | 632 | return 1; |
609 | } | 633 | } |
610 | 634 | ||
635 | |||
636 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) | ||
637 | { | ||
638 | wacom_report_abs(wcombo, ABS_X, | ||
639 | (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); | ||
640 | wacom_report_abs(wcombo, ABS_Y, | ||
641 | (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); | ||
642 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
643 | wacom_report_key(wcombo, wacom->tool[idx], 1); | ||
644 | if (idx) | ||
645 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
646 | else | ||
647 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
648 | } | ||
649 | |||
650 | static void wacom_tpc_touch_out(struct wacom_wac *wacom, void *wcombo, int idx) | ||
651 | { | ||
652 | wacom_report_abs(wcombo, ABS_X, 0); | ||
653 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
654 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
655 | wacom_report_key(wcombo, wacom->tool[idx], 0); | ||
656 | if (idx) | ||
657 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
658 | else | ||
659 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
660 | return; | ||
661 | } | ||
662 | |||
663 | static void wacom_tpc_touch_in(struct wacom_wac *wacom, void *wcombo) | ||
664 | { | ||
665 | char *data = wacom->data; | ||
666 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | ||
667 | static int firstFinger = 0; | ||
668 | static int secondFinger = 0; | ||
669 | |||
670 | wacom->tool[0] = BTN_TOOL_DOUBLETAP; | ||
671 | wacom->id[0] = TOUCH_DEVICE_ID; | ||
672 | wacom->tool[1] = BTN_TOOL_TRIPLETAP; | ||
673 | |||
674 | if (urb->actual_length != WACOM_PKGLEN_TPC1FG) { | ||
675 | switch (data[0]) { | ||
676 | case WACOM_REPORT_TPC1FG: | ||
677 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
678 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
679 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | ||
680 | wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); | ||
681 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
682 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
683 | break; | ||
684 | case WACOM_REPORT_TPC2FG: | ||
685 | /* keep this byte to send proper out-prox event */ | ||
686 | wacom->id[1] = data[1] & 0x03; | ||
687 | |||
688 | if (data[1] & 0x01) { | ||
689 | wacom_tpc_finger_in(wacom, wcombo, data, 0); | ||
690 | firstFinger = 1; | ||
691 | } else if (firstFinger) { | ||
692 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
693 | } | ||
694 | |||
695 | if (data[1] & 0x02) { | ||
696 | /* sync first finger data */ | ||
697 | if (firstFinger) | ||
698 | wacom_input_sync(wcombo); | ||
699 | |||
700 | wacom_tpc_finger_in(wacom, wcombo, data, 1); | ||
701 | secondFinger = 1; | ||
702 | } else if (secondFinger) { | ||
703 | /* sync first finger data */ | ||
704 | if (firstFinger) | ||
705 | wacom_input_sync(wcombo); | ||
706 | |||
707 | wacom_tpc_touch_out(wacom, wcombo, 1); | ||
708 | secondFinger = 0; | ||
709 | } | ||
710 | if (!(data[1] & 0x01)) | ||
711 | firstFinger = 0; | ||
712 | break; | ||
713 | } | ||
714 | } else { | ||
715 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | ||
716 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | ||
717 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
718 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
719 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
720 | } | ||
721 | return; | ||
722 | } | ||
723 | |||
611 | static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | 724 | static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) |
612 | { | 725 | { |
726 | struct wacom_features *features = &wacom->features; | ||
613 | char *data = wacom->data; | 727 | char *data = wacom->data; |
614 | int prox = 0, pressure; | 728 | int prox = 0, pressure, idx = -1; |
615 | static int stylusInProx, touchInProx = 1, touchOut; | 729 | static int stylusInProx, touchInProx = 1, touchOut; |
616 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | 730 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; |
617 | 731 | ||
618 | dbg("wacom_tpc_irq: received report #%d", data[0]); | 732 | dbg("wacom_tpc_irq: received report #%d", data[0]); |
619 | 733 | ||
620 | if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */ | 734 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG || /* single touch */ |
621 | if (urb->actual_length == 5) { /* with touch */ | 735 | data[0] == WACOM_REPORT_TPC1FG || /* single touch */ |
622 | prox = data[0] & 0x03; | 736 | data[0] == WACOM_REPORT_TPC2FG) { /* 2FG touch */ |
737 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG) { /* with touch */ | ||
738 | prox = data[0] & 0x01; | ||
623 | } else { /* with capacity */ | 739 | } else { /* with capacity */ |
624 | prox = data[1] & 0x03; | 740 | if (data[0] == WACOM_REPORT_TPC1FG) |
741 | /* single touch */ | ||
742 | prox = data[1] & 0x01; | ||
743 | else | ||
744 | /* 2FG touch data */ | ||
745 | prox = data[1] & 0x03; | ||
625 | } | 746 | } |
626 | 747 | ||
627 | if (!stylusInProx) { /* stylus not in prox */ | 748 | if (!stylusInProx) { /* stylus not in prox */ |
628 | if (prox) { | 749 | if (prox) { |
629 | if (touchInProx) { | 750 | if (touchInProx) { |
630 | wacom->tool[1] = BTN_TOOL_DOUBLETAP; | 751 | wacom_tpc_touch_in(wacom, wcombo); |
631 | wacom->id[0] = TOUCH_DEVICE_ID; | ||
632 | if (urb->actual_length != 5) { | ||
633 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
634 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
635 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | ||
636 | wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); | ||
637 | } else { | ||
638 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | ||
639 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | ||
640 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
641 | } | ||
642 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
643 | wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); | ||
644 | touchOut = 1; | 752 | touchOut = 1; |
645 | return 1; | 753 | return 1; |
646 | } | 754 | } |
647 | } else { | 755 | } else { |
648 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 756 | /* 2FGT out-prox */ |
649 | wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); | 757 | if (data[0] == WACOM_REPORT_TPC2FG) { |
650 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 758 | idx = (wacom->id[1] & 0x01) - 1; |
759 | if (idx == 0) { | ||
760 | wacom_tpc_touch_out(wacom, wcombo, idx); | ||
761 | /* sync first finger event */ | ||
762 | if (wacom->id[1] & 0x02) | ||
763 | wacom_input_sync(wcombo); | ||
764 | } | ||
765 | idx = (wacom->id[1] & 0x02) - 1; | ||
766 | if (idx == 1) | ||
767 | wacom_tpc_touch_out(wacom, wcombo, idx); | ||
768 | } else /* one finger touch */ | ||
769 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
651 | touchOut = 0; | 770 | touchOut = 0; |
652 | touchInProx = 1; | 771 | touchInProx = 1; |
653 | return 1; | 772 | return 1; |
654 | } | 773 | } |
655 | } else if (touchOut || !prox) { /* force touch out-prox */ | 774 | } else if (touchOut || !prox) { /* force touch out-prox */ |
656 | wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); | 775 | wacom_tpc_touch_out(wacom, wcombo, 0); |
657 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
658 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
659 | touchOut = 0; | 776 | touchOut = 0; |
660 | touchInProx = 1; | 777 | touchInProx = 1; |
661 | return 1; | 778 | return 1; |
662 | } | 779 | } |
663 | } else if (data[0] == 2) { /* Penabled */ | 780 | } else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */ |
664 | prox = data[1] & 0x20; | 781 | prox = data[1] & 0x20; |
665 | 782 | ||
666 | touchInProx = 0; | 783 | touchInProx = 0; |
667 | 784 | ||
668 | wacom->id[0] = ERASER_DEVICE_ID; | ||
669 | |||
670 | /* | ||
671 | * if going from out of proximity into proximity select between the eraser | ||
672 | * and the pen based on the state of the stylus2 button, choose eraser if | ||
673 | * pressed else choose pen. if not a proximity change from out to in, send | ||
674 | * an out of proximity for previous tool then a in for new tool. | ||
675 | */ | ||
676 | if (prox) { /* in prox */ | 785 | if (prox) { /* in prox */ |
677 | if (!wacom->tool[0]) { | 786 | if (!wacom->id[0]) { |
678 | /* Going into proximity select tool */ | 787 | /* Going into proximity select tool */ |
679 | wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 788 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
680 | if (wacom->tool[1] == BTN_TOOL_PEN) | 789 | if (wacom->tool[0] == BTN_TOOL_PEN) |
681 | wacom->id[0] = STYLUS_DEVICE_ID; | 790 | wacom->id[0] = STYLUS_DEVICE_ID; |
682 | } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) { | 791 | else |
683 | /* | 792 | wacom->id[0] = ERASER_DEVICE_ID; |
684 | * was entered with stylus2 pressed | ||
685 | * report out proximity for previous tool | ||
686 | */ | ||
687 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
688 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
689 | wacom_input_sync(wcombo); | ||
690 | |||
691 | /* set new tool */ | ||
692 | wacom->tool[1] = BTN_TOOL_PEN; | ||
693 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
694 | return 0; | ||
695 | } | ||
696 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | ||
697 | /* Unknown tool selected default to pen tool */ | ||
698 | wacom->tool[1] = BTN_TOOL_PEN; | ||
699 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
700 | } | 793 | } |
701 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 794 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
702 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | 795 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); |
@@ -704,19 +797,23 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
704 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | 797 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); |
705 | pressure = ((data[7] & 0x01) << 8) | data[6]; | 798 | pressure = ((data[7] & 0x01) << 8) | data[6]; |
706 | if (pressure < 0) | 799 | if (pressure < 0) |
707 | pressure = wacom->features->pressure_max + pressure + 1; | 800 | pressure = features->pressure_max + pressure + 1; |
708 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | 801 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); |
709 | wacom_report_key(wcombo, BTN_TOUCH, pressure); | 802 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); |
710 | } else { | 803 | } else { |
804 | wacom_report_abs(wcombo, ABS_X, 0); | ||
805 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
711 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | 806 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); |
712 | wacom_report_key(wcombo, BTN_STYLUS, 0); | 807 | wacom_report_key(wcombo, BTN_STYLUS, 0); |
713 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 808 | wacom_report_key(wcombo, BTN_STYLUS2, 0); |
714 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 809 | wacom_report_key(wcombo, BTN_TOUCH, 0); |
810 | wacom->id[0] = 0; | ||
811 | /* pen is out so touch can be enabled now */ | ||
812 | touchInProx = 1; | ||
715 | } | 813 | } |
716 | wacom_report_key(wcombo, wacom->tool[1], prox); | 814 | wacom_report_key(wcombo, wacom->tool[0], prox); |
717 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 815 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); |
718 | stylusInProx = prox; | 816 | stylusInProx = prox; |
719 | wacom->tool[0] = prox; | ||
720 | return 1; | 817 | return 1; |
721 | } | 818 | } |
722 | return 0; | 819 | return 0; |
@@ -724,7 +821,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
724 | 821 | ||
725 | int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | 822 | int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) |
726 | { | 823 | { |
727 | switch (wacom_wac->features->type) { | 824 | switch (wacom_wac->features.type) { |
728 | case PENPARTNER: | 825 | case PENPARTNER: |
729 | return wacom_penpartner_irq(wacom_wac, wcombo); | 826 | return wacom_penpartner_irq(wacom_wac, wcombo); |
730 | 827 | ||
@@ -751,6 +848,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | |||
751 | return wacom_intuos_irq(wacom_wac, wcombo); | 848 | return wacom_intuos_irq(wacom_wac, wcombo); |
752 | 849 | ||
753 | case TABLETPC: | 850 | case TABLETPC: |
851 | case TABLETPC2FG: | ||
754 | return wacom_tpc_irq(wacom_wac, wcombo); | 852 | return wacom_tpc_irq(wacom_wac, wcombo); |
755 | 853 | ||
756 | default: | 854 | default: |
@@ -761,7 +859,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | |||
761 | 859 | ||
762 | void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 860 | void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
763 | { | 861 | { |
764 | switch (wacom_wac->features->type) { | 862 | switch (wacom_wac->features.type) { |
765 | case WACOM_MO: | 863 | case WACOM_MO: |
766 | input_dev_mo(input_dev, wacom_wac); | 864 | input_dev_mo(input_dev, wacom_wac); |
767 | case WACOM_G4: | 865 | case WACOM_G4: |
@@ -791,9 +889,17 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
791 | input_dev_i4s(input_dev, wacom_wac); | 889 | input_dev_i4s(input_dev, wacom_wac); |
792 | input_dev_i(input_dev, wacom_wac); | 890 | input_dev_i(input_dev, wacom_wac); |
793 | break; | 891 | break; |
892 | case TABLETPC2FG: | ||
893 | input_dev_tpc2fg(input_dev, wacom_wac); | ||
894 | /* fall through */ | ||
895 | case TABLETPC: | ||
896 | input_dev_tpc(input_dev, wacom_wac); | ||
897 | if (wacom_wac->features.device_type != BTN_TOOL_PEN) | ||
898 | break; /* no need to process stylus stuff */ | ||
899 | |||
900 | /* fall through */ | ||
794 | case PL: | 901 | case PL: |
795 | case PTU: | 902 | case PTU: |
796 | case TABLETPC: | ||
797 | input_dev_pl(input_dev, wacom_wac); | 903 | input_dev_pl(input_dev, wacom_wac); |
798 | /* fall through */ | 904 | /* fall through */ |
799 | case PENPARTNER: | 905 | case PENPARTNER: |
@@ -803,147 +909,201 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
803 | return; | 909 | return; |
804 | } | 910 | } |
805 | 911 | ||
806 | static struct wacom_features wacom_features[] = { | 912 | static const struct wacom_features wacom_features_0x00 = |
807 | { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER }, | 913 | { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }; |
808 | { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE }, | 914 | static const struct wacom_features wacom_features_0x10 = |
809 | { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE }, | 915 | { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; |
810 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE }, | 916 | static const struct wacom_features wacom_features_0x11 = |
811 | { "Wacom Graphire3", 8, 10208, 7424, 511, 63, GRAPHIRE }, | 917 | { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; |
812 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, | 918 | static const struct wacom_features wacom_features_0x12 = |
813 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, | 919 | { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }; |
814 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, | 920 | static const struct wacom_features wacom_features_0x13 = |
815 | { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO }, | 921 | { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }; |
816 | { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO }, | 922 | static const struct wacom_features wacom_features_0x14 = |
817 | { "Wacom Bamboo1 Medium",8, 16704, 12064, 511, 63, GRAPHIRE }, | 923 | { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; |
818 | { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 924 | static const struct wacom_features wacom_features_0x15 = |
819 | { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, | 925 | { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }; |
820 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 926 | static const struct wacom_features wacom_features_0x16 = |
821 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, | 927 | { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }; |
822 | { "Wacom PenPartner2", 8, 3250, 2320, 511, 63, GRAPHIRE }, | 928 | static const struct wacom_features wacom_features_0x17 = |
823 | { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, | 929 | { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; |
824 | { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 930 | static const struct wacom_features wacom_features_0x18 = |
825 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, | 931 | { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }; |
826 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 932 | static const struct wacom_features wacom_features_0x19 = |
827 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, | 933 | { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; |
828 | { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, | 934 | static const struct wacom_features wacom_features_0x60 = |
829 | { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, | 935 | { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; |
830 | { "Wacom PL400", 8, 5408, 4056, 255, 0, PL }, | 936 | static const struct wacom_features wacom_features_0x61 = |
831 | { "Wacom PL500", 8, 6144, 4608, 255, 0, PL }, | 937 | { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }; |
832 | { "Wacom PL600", 8, 6126, 4604, 255, 0, PL }, | 938 | static const struct wacom_features wacom_features_0x62 = |
833 | { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL }, | 939 | { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; |
834 | { "Wacom PL550", 8, 6144, 4608, 511, 0, PL }, | 940 | static const struct wacom_features wacom_features_0x63 = |
835 | { "Wacom PL800", 8, 7220, 5780, 511, 0, PL }, | 941 | { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }; |
836 | { "Wacom PL700", 8, 6758, 5406, 511, 0, PL }, | 942 | static const struct wacom_features wacom_features_0x64 = |
837 | { "Wacom PL510", 8, 6282, 4762, 511, 0, PL }, | 943 | { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }; |
838 | { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, | 944 | static const struct wacom_features wacom_features_0x65 = |
839 | { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, | 945 | { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; |
840 | { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, | 946 | static const struct wacom_features wacom_features_0x69 = |
841 | { "Wacom DTF720a", 8, 6858, 5506, 511, 0, PL }, | 947 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; |
842 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU }, | 948 | static const struct wacom_features wacom_features_0x20 = |
843 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, | 949 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; |
844 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 950 | static const struct wacom_features wacom_features_0x21 = |
845 | { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, | 951 | { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; |
846 | { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, | 952 | static const struct wacom_features wacom_features_0x22 = |
847 | { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, | 953 | { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; |
848 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S }, | 954 | static const struct wacom_features wacom_features_0x23 = |
849 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 }, | 955 | { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; |
850 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 }, | 956 | static const struct wacom_features wacom_features_0x24 = |
851 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, | 957 | { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; |
852 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, | 958 | static const struct wacom_features wacom_features_0x30 = |
853 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, | 959 | { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }; |
854 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, | 960 | static const struct wacom_features wacom_features_0x31 = |
855 | { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S }, | 961 | { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }; |
856 | { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4 }, | 962 | static const struct wacom_features wacom_features_0x32 = |
857 | { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L }, | 963 | { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }; |
858 | { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L }, | 964 | static const struct wacom_features wacom_features_0x33 = |
859 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, | 965 | { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }; |
860 | { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, | 966 | static const struct wacom_features wacom_features_0x34 = |
861 | { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, | 967 | { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }; |
862 | { "Wacom DTU1931", 8, 37832, 30305, 511, 0, PL }, | 968 | static const struct wacom_features wacom_features_0x35 = |
863 | { "Wacom ISDv4 90", 8, 26202, 16325, 255, 0, TABLETPC }, | 969 | { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }; |
864 | { "Wacom ISDv4 93", 8, 26202, 16325, 255, 0, TABLETPC }, | 970 | static const struct wacom_features wacom_features_0x37 = |
865 | { "Wacom ISDv4 9A", 8, 26202, 16325, 255, 0, TABLETPC }, | 971 | { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }; |
866 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 972 | static const struct wacom_features wacom_features_0x38 = |
867 | { } | 973 | { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; |
868 | }; | 974 | static const struct wacom_features wacom_features_0x39 = |
869 | 975 | { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }; | |
870 | static struct usb_device_id wacom_ids[] = { | 976 | static const struct wacom_features wacom_features_0xC4 = |
871 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, | 977 | { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; |
872 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, | 978 | static const struct wacom_features wacom_features_0xC0 = |
873 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, | 979 | { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; |
874 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, | 980 | static const struct wacom_features wacom_features_0xC2 = |
875 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, | 981 | { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; |
876 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, | 982 | static const struct wacom_features wacom_features_0x03 = |
877 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, | 983 | { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }; |
878 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, | 984 | static const struct wacom_features wacom_features_0x41 = |
879 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, | 985 | { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; |
880 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, | 986 | static const struct wacom_features wacom_features_0x42 = |
881 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) }, | 987 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; |
882 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, | 988 | static const struct wacom_features wacom_features_0x43 = |
883 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, | 989 | { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; |
884 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, | 990 | static const struct wacom_features wacom_features_0x44 = |
885 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, | 991 | { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; |
886 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, | 992 | static const struct wacom_features wacom_features_0x45 = |
887 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, | 993 | { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; |
888 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, | 994 | static const struct wacom_features wacom_features_0xB0 = |
889 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, | 995 | { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }; |
890 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, | 996 | static const struct wacom_features wacom_features_0xB1 = |
891 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, | 997 | { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }; |
892 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, | 998 | static const struct wacom_features wacom_features_0xB2 = |
893 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, | 999 | { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }; |
894 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, | 1000 | static const struct wacom_features wacom_features_0xB3 = |
895 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, | 1001 | { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }; |
896 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, | 1002 | static const struct wacom_features wacom_features_0xB4 = |
897 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, | 1003 | { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }; |
898 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, | 1004 | static const struct wacom_features wacom_features_0xB5 = |
899 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, | 1005 | { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }; |
900 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) }, | 1006 | static const struct wacom_features wacom_features_0xB7 = |
901 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) }, | 1007 | { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }; |
902 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) }, | 1008 | static const struct wacom_features wacom_features_0xB8 = |
903 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) }, | 1009 | { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }; |
904 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) }, | 1010 | static const struct wacom_features wacom_features_0xB9 = |
905 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) }, | 1011 | { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }; |
906 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, | 1012 | static const struct wacom_features wacom_features_0xBA = |
907 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, | 1013 | { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; |
908 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, | 1014 | static const struct wacom_features wacom_features_0xBB = |
909 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, | 1015 | { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; |
910 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, | 1016 | static const struct wacom_features wacom_features_0x3F = |
911 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, | 1017 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; |
912 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, | 1018 | static const struct wacom_features wacom_features_0xC5 = |
913 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, | 1019 | { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }; |
914 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, | 1020 | static const struct wacom_features wacom_features_0xC6 = |
915 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, | 1021 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; |
916 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, | 1022 | static const struct wacom_features wacom_features_0xC7 = |
917 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, | 1023 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; |
918 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, | 1024 | static const struct wacom_features wacom_features_0x90 = |
919 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, | 1025 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; |
920 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, | 1026 | static const struct wacom_features wacom_features_0x93 = |
921 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, | 1027 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; |
922 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, | 1028 | static const struct wacom_features wacom_features_0x9A = |
923 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | 1029 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; |
924 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, | 1030 | static const struct wacom_features wacom_features_0x9F = |
925 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, | 1031 | { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; |
926 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) }, | 1032 | static const struct wacom_features wacom_features_0xE2 = |
927 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, | 1033 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; |
928 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, | 1034 | static const struct wacom_features wacom_features_0xE3 = |
929 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, | 1035 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; |
930 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 1036 | static const struct wacom_features wacom_features_0x47 = |
1037 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; | ||
1038 | |||
1039 | #define USB_DEVICE_WACOM(prod) \ | ||
1040 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | ||
1041 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | ||
1042 | |||
1043 | const struct usb_device_id wacom_ids[] = { | ||
1044 | { USB_DEVICE_WACOM(0x00) }, | ||
1045 | { USB_DEVICE_WACOM(0x10) }, | ||
1046 | { USB_DEVICE_WACOM(0x11) }, | ||
1047 | { USB_DEVICE_WACOM(0x12) }, | ||
1048 | { USB_DEVICE_WACOM(0x13) }, | ||
1049 | { USB_DEVICE_WACOM(0x14) }, | ||
1050 | { USB_DEVICE_WACOM(0x15) }, | ||
1051 | { USB_DEVICE_WACOM(0x16) }, | ||
1052 | { USB_DEVICE_WACOM(0x17) }, | ||
1053 | { USB_DEVICE_WACOM(0x18) }, | ||
1054 | { USB_DEVICE_WACOM(0x19) }, | ||
1055 | { USB_DEVICE_WACOM(0x60) }, | ||
1056 | { USB_DEVICE_WACOM(0x61) }, | ||
1057 | { USB_DEVICE_WACOM(0x62) }, | ||
1058 | { USB_DEVICE_WACOM(0x63) }, | ||
1059 | { USB_DEVICE_WACOM(0x64) }, | ||
1060 | { USB_DEVICE_WACOM(0x65) }, | ||
1061 | { USB_DEVICE_WACOM(0x69) }, | ||
1062 | { USB_DEVICE_WACOM(0x20) }, | ||
1063 | { USB_DEVICE_WACOM(0x21) }, | ||
1064 | { USB_DEVICE_WACOM(0x22) }, | ||
1065 | { USB_DEVICE_WACOM(0x23) }, | ||
1066 | { USB_DEVICE_WACOM(0x24) }, | ||
1067 | { USB_DEVICE_WACOM(0x30) }, | ||
1068 | { USB_DEVICE_WACOM(0x31) }, | ||
1069 | { USB_DEVICE_WACOM(0x32) }, | ||
1070 | { USB_DEVICE_WACOM(0x33) }, | ||
1071 | { USB_DEVICE_WACOM(0x34) }, | ||
1072 | { USB_DEVICE_WACOM(0x35) }, | ||
1073 | { USB_DEVICE_WACOM(0x37) }, | ||
1074 | { USB_DEVICE_WACOM(0x38) }, | ||
1075 | { USB_DEVICE_WACOM(0x39) }, | ||
1076 | { USB_DEVICE_WACOM(0xC4) }, | ||
1077 | { USB_DEVICE_WACOM(0xC0) }, | ||
1078 | { USB_DEVICE_WACOM(0xC2) }, | ||
1079 | { USB_DEVICE_WACOM(0x03) }, | ||
1080 | { USB_DEVICE_WACOM(0x41) }, | ||
1081 | { USB_DEVICE_WACOM(0x42) }, | ||
1082 | { USB_DEVICE_WACOM(0x43) }, | ||
1083 | { USB_DEVICE_WACOM(0x44) }, | ||
1084 | { USB_DEVICE_WACOM(0x45) }, | ||
1085 | { USB_DEVICE_WACOM(0xB0) }, | ||
1086 | { USB_DEVICE_WACOM(0xB1) }, | ||
1087 | { USB_DEVICE_WACOM(0xB2) }, | ||
1088 | { USB_DEVICE_WACOM(0xB3) }, | ||
1089 | { USB_DEVICE_WACOM(0xB4) }, | ||
1090 | { USB_DEVICE_WACOM(0xB5) }, | ||
1091 | { USB_DEVICE_WACOM(0xB7) }, | ||
1092 | { USB_DEVICE_WACOM(0xB8) }, | ||
1093 | { USB_DEVICE_WACOM(0xB9) }, | ||
1094 | { USB_DEVICE_WACOM(0xBA) }, | ||
1095 | { USB_DEVICE_WACOM(0xBB) }, | ||
1096 | { USB_DEVICE_WACOM(0x3F) }, | ||
1097 | { USB_DEVICE_WACOM(0xC5) }, | ||
1098 | { USB_DEVICE_WACOM(0xC6) }, | ||
1099 | { USB_DEVICE_WACOM(0xC7) }, | ||
1100 | { USB_DEVICE_WACOM(0x90) }, | ||
1101 | { USB_DEVICE_WACOM(0x93) }, | ||
1102 | { USB_DEVICE_WACOM(0x9A) }, | ||
1103 | { USB_DEVICE_WACOM(0x9F) }, | ||
1104 | { USB_DEVICE_WACOM(0xE2) }, | ||
1105 | { USB_DEVICE_WACOM(0xE3) }, | ||
1106 | { USB_DEVICE_WACOM(0x47) }, | ||
931 | { } | 1107 | { } |
932 | }; | 1108 | }; |
933 | |||
934 | const struct usb_device_id *get_device_table(void) | ||
935 | { | ||
936 | const struct usb_device_id *id_table = wacom_ids; | ||
937 | |||
938 | return id_table; | ||
939 | } | ||
940 | |||
941 | struct wacom_features * get_wacom_feature(const struct usb_device_id *id) | ||
942 | { | ||
943 | int index = id - wacom_ids; | ||
944 | struct wacom_features *wf = &wacom_features[index]; | ||
945 | |||
946 | return wf; | ||
947 | } | ||
948 | |||
949 | MODULE_DEVICE_TABLE(usb, wacom_ids); | 1109 | MODULE_DEVICE_TABLE(usb, wacom_ids); |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index c10235aba7e5..b50cf04e61a8 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -9,12 +9,32 @@ | |||
9 | #ifndef WACOM_WAC_H | 9 | #ifndef WACOM_WAC_H |
10 | #define WACOM_WAC_H | 10 | #define WACOM_WAC_H |
11 | 11 | ||
12 | /* maximum packet length for USB devices */ | ||
13 | #define WACOM_PKGLEN_MAX 32 | ||
14 | |||
15 | /* packet length for individual models */ | ||
16 | #define WACOM_PKGLEN_PENPRTN 7 | ||
17 | #define WACOM_PKGLEN_GRAPHIRE 8 | ||
18 | #define WACOM_PKGLEN_BBFUN 9 | ||
19 | #define WACOM_PKGLEN_INTUOS 10 | ||
20 | #define WACOM_PKGLEN_TPC1FG 5 | ||
21 | #define WACOM_PKGLEN_TPC2FG 14 | ||
22 | |||
23 | /* device IDs */ | ||
12 | #define STYLUS_DEVICE_ID 0x02 | 24 | #define STYLUS_DEVICE_ID 0x02 |
13 | #define TOUCH_DEVICE_ID 0x03 | 25 | #define TOUCH_DEVICE_ID 0x03 |
14 | #define CURSOR_DEVICE_ID 0x06 | 26 | #define CURSOR_DEVICE_ID 0x06 |
15 | #define ERASER_DEVICE_ID 0x0A | 27 | #define ERASER_DEVICE_ID 0x0A |
16 | #define PAD_DEVICE_ID 0x0F | 28 | #define PAD_DEVICE_ID 0x0F |
17 | 29 | ||
30 | /* wacom data packet report IDs */ | ||
31 | #define WACOM_REPORT_PENABLED 2 | ||
32 | #define WACOM_REPORT_INTUOSREAD 5 | ||
33 | #define WACOM_REPORT_INTUOSWRITE 6 | ||
34 | #define WACOM_REPORT_INTUOSPAD 12 | ||
35 | #define WACOM_REPORT_TPC1FG 6 | ||
36 | #define WACOM_REPORT_TPC2FG 13 | ||
37 | |||
18 | enum { | 38 | enum { |
19 | PENPARTNER = 0, | 39 | PENPARTNER = 0, |
20 | GRAPHIRE, | 40 | GRAPHIRE, |
@@ -32,27 +52,32 @@ enum { | |||
32 | WACOM_BEE, | 52 | WACOM_BEE, |
33 | WACOM_MO, | 53 | WACOM_MO, |
34 | TABLETPC, | 54 | TABLETPC, |
55 | TABLETPC2FG, | ||
35 | MAX_TYPE | 56 | MAX_TYPE |
36 | }; | 57 | }; |
37 | 58 | ||
38 | struct wacom_features { | 59 | struct wacom_features { |
39 | char *name; | 60 | const char *name; |
40 | int pktlen; | 61 | int pktlen; |
41 | int x_max; | 62 | int x_max; |
42 | int y_max; | 63 | int y_max; |
43 | int pressure_max; | 64 | int pressure_max; |
44 | int distance_max; | 65 | int distance_max; |
45 | int type; | 66 | int type; |
46 | int touch_x_max; | 67 | int device_type; |
47 | int touch_y_max; | 68 | int x_phy; |
69 | int y_phy; | ||
70 | unsigned char unit; | ||
71 | unsigned char unitExpo; | ||
48 | }; | 72 | }; |
49 | 73 | ||
50 | struct wacom_wac { | 74 | struct wacom_wac { |
75 | char name[64]; | ||
51 | unsigned char *data; | 76 | unsigned char *data; |
52 | int tool[2]; | 77 | int tool[2]; |
53 | int id[2]; | 78 | int id[2]; |
54 | __u32 serial[2]; | 79 | __u32 serial[2]; |
55 | struct wacom_features *features; | 80 | struct wacom_features features; |
56 | }; | 81 | }; |
57 | 82 | ||
58 | #endif | 83 | #endif |
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c new file mode 100644 index 000000000000..b3aebc2166ba --- /dev/null +++ b/drivers/input/touchscreen/88pm860x-ts.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * Touchscreen driver for Marvell 88PM860x | ||
3 | * | ||
4 | * Copyright (C) 2009 Marvell International Ltd. | ||
5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/mfd/88pm860x.h> | ||
17 | #include <linux/slab.h> | ||
18 | |||
19 | #define MEAS_LEN (8) | ||
20 | #define ACCURATE_BIT (12) | ||
21 | |||
22 | /* touch register */ | ||
23 | #define MEAS_EN3 (0x52) | ||
24 | |||
25 | #define MEAS_TSIX_1 (0x8D) | ||
26 | #define MEAS_TSIX_2 (0x8E) | ||
27 | #define MEAS_TSIY_1 (0x8F) | ||
28 | #define MEAS_TSIY_2 (0x90) | ||
29 | #define MEAS_TSIZ1_1 (0x91) | ||
30 | #define MEAS_TSIZ1_2 (0x92) | ||
31 | #define MEAS_TSIZ2_1 (0x93) | ||
32 | #define MEAS_TSIZ2_2 (0x94) | ||
33 | |||
34 | /* bit definitions of touch */ | ||
35 | #define MEAS_PD_EN (1 << 3) | ||
36 | #define MEAS_TSIX_EN (1 << 4) | ||
37 | #define MEAS_TSIY_EN (1 << 5) | ||
38 | #define MEAS_TSIZ1_EN (1 << 6) | ||
39 | #define MEAS_TSIZ2_EN (1 << 7) | ||
40 | |||
41 | struct pm860x_touch { | ||
42 | struct input_dev *idev; | ||
43 | struct i2c_client *i2c; | ||
44 | struct pm860x_chip *chip; | ||
45 | int irq; | ||
46 | int res_x; /* resistor of Xplate */ | ||
47 | }; | ||
48 | |||
49 | static irqreturn_t pm860x_touch_handler(int irq, void *data) | ||
50 | { | ||
51 | struct pm860x_touch *touch = data; | ||
52 | struct pm860x_chip *chip = touch->chip; | ||
53 | unsigned char buf[MEAS_LEN]; | ||
54 | int x, y, pen_down; | ||
55 | int z1, z2, rt = 0; | ||
56 | int ret; | ||
57 | |||
58 | ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf); | ||
59 | if (ret < 0) | ||
60 | goto out; | ||
61 | |||
62 | pen_down = buf[1] & (1 << 6); | ||
63 | x = ((buf[0] & 0xFF) << 4) | (buf[1] & 0x0F); | ||
64 | y = ((buf[2] & 0xFF) << 4) | (buf[3] & 0x0F); | ||
65 | z1 = ((buf[4] & 0xFF) << 4) | (buf[5] & 0x0F); | ||
66 | z2 = ((buf[6] & 0xFF) << 4) | (buf[7] & 0x0F); | ||
67 | |||
68 | if (pen_down) { | ||
69 | if ((x != 0) && (z1 != 0) && (touch->res_x != 0)) { | ||
70 | rt = z2 / z1 - 1; | ||
71 | rt = (rt * touch->res_x * x) >> ACCURATE_BIT; | ||
72 | dev_dbg(chip->dev, "z1:%d, z2:%d, rt:%d\n", | ||
73 | z1, z2, rt); | ||
74 | } | ||
75 | input_report_abs(touch->idev, ABS_X, x); | ||
76 | input_report_abs(touch->idev, ABS_Y, y); | ||
77 | input_report_abs(touch->idev, ABS_PRESSURE, rt); | ||
78 | input_report_key(touch->idev, BTN_TOUCH, 1); | ||
79 | dev_dbg(chip->dev, "pen down at [%d, %d].\n", x, y); | ||
80 | } else { | ||
81 | input_report_abs(touch->idev, ABS_PRESSURE, 0); | ||
82 | input_report_key(touch->idev, BTN_TOUCH, 0); | ||
83 | dev_dbg(chip->dev, "pen release\n"); | ||
84 | } | ||
85 | input_sync(touch->idev); | ||
86 | |||
87 | out: | ||
88 | return IRQ_HANDLED; | ||
89 | } | ||
90 | |||
91 | static int pm860x_touch_open(struct input_dev *dev) | ||
92 | { | ||
93 | struct pm860x_touch *touch = input_get_drvdata(dev); | ||
94 | int data, ret; | ||
95 | |||
96 | data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN | ||
97 | | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; | ||
98 | ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data); | ||
99 | if (ret < 0) | ||
100 | goto out; | ||
101 | return 0; | ||
102 | out: | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | static void pm860x_touch_close(struct input_dev *dev) | ||
107 | { | ||
108 | struct pm860x_touch *touch = input_get_drvdata(dev); | ||
109 | int data; | ||
110 | |||
111 | data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN | ||
112 | | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN; | ||
113 | pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); | ||
114 | } | ||
115 | |||
116 | static int __devinit pm860x_touch_probe(struct platform_device *pdev) | ||
117 | { | ||
118 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
119 | struct pm860x_platform_data *pm860x_pdata = \ | ||
120 | pdev->dev.parent->platform_data; | ||
121 | struct pm860x_touch_pdata *pdata = NULL; | ||
122 | struct pm860x_touch *touch; | ||
123 | int irq, ret; | ||
124 | |||
125 | irq = platform_get_irq(pdev, 0); | ||
126 | if (irq < 0) { | ||
127 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
131 | if (!pm860x_pdata) { | ||
132 | dev_err(&pdev->dev, "platform data is missing\n"); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | pdata = pm860x_pdata->touch; | ||
137 | if (!pdata) { | ||
138 | dev_err(&pdev->dev, "touchscreen data is missing\n"); | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | |||
142 | touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); | ||
143 | if (touch == NULL) | ||
144 | return -ENOMEM; | ||
145 | dev_set_drvdata(&pdev->dev, touch); | ||
146 | |||
147 | touch->idev = input_allocate_device(); | ||
148 | if (touch->idev == NULL) { | ||
149 | dev_err(&pdev->dev, "Failed to allocate input device!\n"); | ||
150 | ret = -ENOMEM; | ||
151 | goto out; | ||
152 | } | ||
153 | |||
154 | touch->idev->name = "88pm860x-touch"; | ||
155 | touch->idev->phys = "88pm860x/input0"; | ||
156 | touch->idev->id.bustype = BUS_I2C; | ||
157 | touch->idev->dev.parent = &pdev->dev; | ||
158 | touch->idev->open = pm860x_touch_open; | ||
159 | touch->idev->close = pm860x_touch_close; | ||
160 | touch->chip = chip; | ||
161 | touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | ||
162 | touch->irq = irq + chip->irq_base; | ||
163 | touch->res_x = pdata->res_x; | ||
164 | input_set_drvdata(touch->idev, touch); | ||
165 | |||
166 | ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, | ||
167 | IRQF_ONESHOT, "touch", touch); | ||
168 | if (ret < 0) | ||
169 | goto out_irq; | ||
170 | |||
171 | __set_bit(EV_ABS, touch->idev->evbit); | ||
172 | __set_bit(ABS_X, touch->idev->absbit); | ||
173 | __set_bit(ABS_Y, touch->idev->absbit); | ||
174 | __set_bit(ABS_PRESSURE, touch->idev->absbit); | ||
175 | __set_bit(EV_SYN, touch->idev->evbit); | ||
176 | __set_bit(EV_KEY, touch->idev->evbit); | ||
177 | __set_bit(BTN_TOUCH, touch->idev->keybit); | ||
178 | |||
179 | input_set_abs_params(touch->idev, ABS_X, 0, 1 << ACCURATE_BIT, 0, 0); | ||
180 | input_set_abs_params(touch->idev, ABS_Y, 0, 1 << ACCURATE_BIT, 0, 0); | ||
181 | input_set_abs_params(touch->idev, ABS_PRESSURE, 0, 1 << ACCURATE_BIT, | ||
182 | 0, 0); | ||
183 | |||
184 | ret = input_register_device(touch->idev); | ||
185 | if (ret < 0) { | ||
186 | dev_err(chip->dev, "Failed to register touch!\n"); | ||
187 | goto out_rg; | ||
188 | } | ||
189 | |||
190 | platform_set_drvdata(pdev, touch); | ||
191 | return 0; | ||
192 | out_rg: | ||
193 | free_irq(touch->irq, touch); | ||
194 | out_irq: | ||
195 | input_free_device(touch->idev); | ||
196 | out: | ||
197 | kfree(touch); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | static int __devexit pm860x_touch_remove(struct platform_device *pdev) | ||
202 | { | ||
203 | struct pm860x_touch *touch = platform_get_drvdata(pdev); | ||
204 | |||
205 | input_unregister_device(touch->idev); | ||
206 | free_irq(touch->irq, touch); | ||
207 | platform_set_drvdata(pdev, NULL); | ||
208 | kfree(touch); | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static struct platform_driver pm860x_touch_driver = { | ||
213 | .driver = { | ||
214 | .name = "88pm860x-touch", | ||
215 | .owner = THIS_MODULE, | ||
216 | }, | ||
217 | .probe = pm860x_touch_probe, | ||
218 | .remove = __devexit_p(pm860x_touch_remove), | ||
219 | }; | ||
220 | |||
221 | static int __init pm860x_touch_init(void) | ||
222 | { | ||
223 | return platform_driver_register(&pm860x_touch_driver); | ||
224 | } | ||
225 | module_init(pm860x_touch_init); | ||
226 | |||
227 | static void __exit pm860x_touch_exit(void) | ||
228 | { | ||
229 | platform_driver_unregister(&pm860x_touch_driver); | ||
230 | } | ||
231 | module_exit(pm860x_touch_exit); | ||
232 | |||
233 | MODULE_DESCRIPTION("Touchscreen driver for Marvell Semiconductor 88PM860x"); | ||
234 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | ||
235 | MODULE_LICENSE("GPL"); | ||
236 | MODULE_ALIAS("platform:88pm860x-touch"); | ||
237 | |||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 8cc453c85ea7..8a8fa4d2d6a8 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -11,18 +11,31 @@ menuconfig INPUT_TOUCHSCREEN | |||
11 | 11 | ||
12 | if INPUT_TOUCHSCREEN | 12 | if INPUT_TOUCHSCREEN |
13 | 13 | ||
14 | config TOUCHSCREEN_88PM860X | ||
15 | tristate "Marvell 88PM860x touchscreen" | ||
16 | depends on MFD_88PM860X | ||
17 | help | ||
18 | Say Y here if you have a 88PM860x PMIC and want to enable | ||
19 | support for the built-in touchscreen. | ||
20 | |||
21 | If unsure, say N. | ||
22 | |||
23 | To compile this driver as a module, choose M here: the | ||
24 | module will be called 88pm860x-ts. | ||
25 | |||
14 | config TOUCHSCREEN_ADS7846 | 26 | config TOUCHSCREEN_ADS7846 |
15 | tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" | 27 | tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens" |
16 | depends on SPI_MASTER | 28 | depends on SPI_MASTER |
17 | depends on HWMON = n || HWMON | 29 | depends on HWMON = n || HWMON |
18 | help | 30 | help |
19 | Say Y here if you have a touchscreen interface using the | 31 | Say Y here if you have a touchscreen interface using the |
20 | ADS7846/TSC2046 or ADS7843 controller, and your board-specific | 32 | ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller, |
21 | setup code includes that in its table of SPI devices. | 33 | and your board-specific setup code includes that in its |
34 | table of SPI devices. | ||
22 | 35 | ||
23 | If HWMON is selected, and the driver is told the reference voltage | 36 | If HWMON is selected, and the driver is told the reference voltage |
24 | on your board, you will also get hwmon interfaces for the voltage | 37 | on your board, you will also get hwmon interfaces for the voltage |
25 | (and on ads7846/tsc2046, temperature) sensors of this chip. | 38 | (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip. |
26 | 39 | ||
27 | If unsure, say N (but it's safe to say "Y"). | 40 | If unsure, say N (but it's safe to say "Y"). |
28 | 41 | ||
@@ -90,7 +103,6 @@ config TOUCHSCREEN_CORGI | |||
90 | tristate "SharpSL (Corgi and Spitz series) touchscreen driver (DEPRECATED)" | 103 | tristate "SharpSL (Corgi and Spitz series) touchscreen driver (DEPRECATED)" |
91 | depends on PXA_SHARPSL | 104 | depends on PXA_SHARPSL |
92 | select CORGI_SSP_DEPRECATED | 105 | select CORGI_SSP_DEPRECATED |
93 | default y | ||
94 | help | 106 | help |
95 | Say Y here to enable the driver for the touchscreen on the | 107 | Say Y here to enable the driver for the touchscreen on the |
96 | Sharp SL-C7xx and SL-Cxx00 series of PDAs. | 108 | Sharp SL-C7xx and SL-Cxx00 series of PDAs. |
@@ -111,6 +123,18 @@ config TOUCHSCREEN_DA9034 | |||
111 | Say Y here to enable the support for the touchscreen found | 123 | Say Y here to enable the support for the touchscreen found |
112 | on Dialog Semiconductor DA9034 PMIC. | 124 | on Dialog Semiconductor DA9034 PMIC. |
113 | 125 | ||
126 | config TOUCHSCREEN_DYNAPRO | ||
127 | tristate "Dynapro serial touchscreen" | ||
128 | select SERIO | ||
129 | help | ||
130 | Say Y here if you have a Dynapro serial touchscreen connected to | ||
131 | your system. | ||
132 | |||
133 | If unsure, say N. | ||
134 | |||
135 | To compile this driver as a module, choose M here: the | ||
136 | module will be called dynapro. | ||
137 | |||
114 | config TOUCHSCREEN_EETI | 138 | config TOUCHSCREEN_EETI |
115 | tristate "EETI touchscreen panel support" | 139 | tristate "EETI touchscreen panel support" |
116 | depends on I2C | 140 | depends on I2C |
@@ -133,6 +157,18 @@ config TOUCHSCREEN_FUJITSU | |||
133 | To compile this driver as a module, choose M here: the | 157 | To compile this driver as a module, choose M here: the |
134 | module will be called fujitsu-ts. | 158 | module will be called fujitsu-ts. |
135 | 159 | ||
160 | config TOUCHSCREEN_S3C2410 | ||
161 | tristate "Samsung S3C2410 touchscreen input driver" | ||
162 | depends on ARCH_S3C2410 | ||
163 | select S3C24XX_ADC | ||
164 | help | ||
165 | Say Y here if you have the s3c2410 touchscreen. | ||
166 | |||
167 | If unsure, say N. | ||
168 | |||
169 | To compile this driver as a module, choose M here: the | ||
170 | module will be called s3c2410_ts. | ||
171 | |||
136 | config TOUCHSCREEN_GUNZE | 172 | config TOUCHSCREEN_GUNZE |
137 | tristate "Gunze AHL-51S touchscreen" | 173 | tristate "Gunze AHL-51S touchscreen" |
138 | select SERIO | 174 | select SERIO |
@@ -297,7 +333,7 @@ config TOUCHSCREEN_TOUCHWIN | |||
297 | 333 | ||
298 | config TOUCHSCREEN_ATMEL_TSADCC | 334 | config TOUCHSCREEN_ATMEL_TSADCC |
299 | tristate "Atmel Touchscreen Interface" | 335 | tristate "Atmel Touchscreen Interface" |
300 | depends on ARCH_AT91SAM9RL | 336 | depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 |
301 | help | 337 | help |
302 | Say Y here if you have a 4-wire touchscreen connected to the | 338 | Say Y here if you have a 4-wire touchscreen connected to the |
303 | ADC Controller on your Atmel SoC (such as the AT91SAM9RL). | 339 | ADC Controller on your Atmel SoC (such as the AT91SAM9RL). |
@@ -418,6 +454,7 @@ config TOUCHSCREEN_USB_COMPOSITE | |||
418 | - IdealTEK URTC1000 | 454 | - IdealTEK URTC1000 |
419 | - GoTop Super_Q2/GogoPen/PenPower tablets | 455 | - GoTop Super_Q2/GogoPen/PenPower tablets |
420 | - JASTEC USB Touch Controller/DigiTech DTR-02U | 456 | - JASTEC USB Touch Controller/DigiTech DTR-02U |
457 | - Zytronic controllers | ||
421 | 458 | ||
422 | Have a look at <http://linux.chapter7.ch/touchkit/> for | 459 | Have a look at <http://linux.chapter7.ch/touchkit/> for |
423 | a usage description and the required user-space stuff. | 460 | a usage description and the required user-space stuff. |
@@ -425,6 +462,18 @@ config TOUCHSCREEN_USB_COMPOSITE | |||
425 | To compile this driver as a module, choose M here: the | 462 | To compile this driver as a module, choose M here: the |
426 | module will be called usbtouchscreen. | 463 | module will be called usbtouchscreen. |
427 | 464 | ||
465 | config TOUCHSCREEN_MC13783 | ||
466 | tristate "Freescale MC13783 touchscreen input driver" | ||
467 | depends on MFD_MC13783 | ||
468 | help | ||
469 | Say Y here if you have an Freescale MC13783 PMIC on your | ||
470 | board and want to use its touchscreen | ||
471 | |||
472 | If unsure, say N. | ||
473 | |||
474 | To compile this driver as a module, choose M here: the | ||
475 | module will be called mc13783_ts. | ||
476 | |||
428 | config TOUCHSCREEN_USB_EGALAX | 477 | config TOUCHSCREEN_USB_EGALAX |
429 | default y | 478 | default y |
430 | bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED | 479 | bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED |
@@ -490,6 +539,21 @@ config TOUCHSCREEN_USB_E2I | |||
490 | bool "e2i Touchscreen controller (e.g. from Mimo 740)" | 539 | bool "e2i Touchscreen controller (e.g. from Mimo 740)" |
491 | depends on TOUCHSCREEN_USB_COMPOSITE | 540 | depends on TOUCHSCREEN_USB_COMPOSITE |
492 | 541 | ||
542 | config TOUCHSCREEN_USB_ZYTRONIC | ||
543 | default y | ||
544 | bool "Zytronic controller" if EMBEDDED | ||
545 | depends on TOUCHSCREEN_USB_COMPOSITE | ||
546 | |||
547 | config TOUCHSCREEN_USB_ETT_TC5UH | ||
548 | default y | ||
549 | bool "ET&T TC5UH touchscreen controler support" if EMBEDDED | ||
550 | depends on TOUCHSCREEN_USB_COMPOSITE | ||
551 | |||
552 | config TOUCHSCREEN_USB_NEXIO | ||
553 | default y | ||
554 | bool "NEXIO/iNexio device support" if EMBEDDED | ||
555 | depends on TOUCHSCREEN_USB_COMPOSITE | ||
556 | |||
493 | config TOUCHSCREEN_TOUCHIT213 | 557 | config TOUCHSCREEN_TOUCHIT213 |
494 | tristate "Sahara TouchIT-213 touchscreen" | 558 | tristate "Sahara TouchIT-213 touchscreen" |
495 | select SERIO | 559 | select SERIO |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 15fa62cffc77..7fef7d5cca23 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -6,17 +6,20 @@ | |||
6 | 6 | ||
7 | wm97xx-ts-y := wm97xx-core.o | 7 | wm97xx-ts-y := wm97xx-core.o |
8 | 8 | ||
9 | obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o | ||
9 | obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o | 10 | obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o |
10 | obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o | 11 | obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o |
11 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | 12 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o |
12 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o | 13 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o |
13 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 14 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
14 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o | 15 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o |
16 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o | ||
15 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 17 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
16 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | 18 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o |
17 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 19 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
18 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 20 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
19 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | 21 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o |
22 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o | ||
20 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o | 23 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o |
21 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o | 24 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o |
22 | obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o | 25 | obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o |
@@ -25,7 +28,9 @@ obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o | |||
25 | obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o | 28 | obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o |
26 | obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o | 29 | obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o |
27 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o | 30 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o |
31 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | ||
28 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o | 32 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o |
33 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o | ||
29 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o | 34 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o |
30 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o | 35 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o |
31 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o | 36 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o |
@@ -41,4 +46,3 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o | |||
41 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o | 46 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o |
42 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o | 47 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o |
43 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o | 48 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o |
44 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | ||
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index eb83939c705e..0d2d7e54b465 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/spi/ad7877.h> | 46 | #include <linux/spi/ad7877.h> |
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | 48 | ||
49 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) | 49 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(100) |
50 | 50 | ||
51 | #define MAX_SPI_FREQ_HZ 20000000 | 51 | #define MAX_SPI_FREQ_HZ 20000000 |
52 | #define MAX_12BIT ((1<<12)-1) | 52 | #define MAX_12BIT ((1<<12)-1) |
@@ -156,9 +156,14 @@ struct ser_req { | |||
156 | u16 reset; | 156 | u16 reset; |
157 | u16 ref_on; | 157 | u16 ref_on; |
158 | u16 command; | 158 | u16 command; |
159 | u16 sample; | ||
160 | struct spi_message msg; | 159 | struct spi_message msg; |
161 | struct spi_transfer xfer[6]; | 160 | struct spi_transfer xfer[6]; |
161 | |||
162 | /* | ||
163 | * DMA (thus cache coherency maintenance) requires the | ||
164 | * transfer buffers to live in their own cache lines. | ||
165 | */ | ||
166 | u16 sample ____cacheline_aligned; | ||
162 | }; | 167 | }; |
163 | 168 | ||
164 | struct ad7877 { | 169 | struct ad7877 { |
@@ -182,8 +187,6 @@ struct ad7877 { | |||
182 | u8 averaging; | 187 | u8 averaging; |
183 | u8 pen_down_acc_interval; | 188 | u8 pen_down_acc_interval; |
184 | 189 | ||
185 | u16 conversion_data[AD7877_NR_SENSE]; | ||
186 | |||
187 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; | 190 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; |
188 | struct spi_message msg; | 191 | struct spi_message msg; |
189 | 192 | ||
@@ -195,6 +198,12 @@ struct ad7877 { | |||
195 | spinlock_t lock; | 198 | spinlock_t lock; |
196 | struct timer_list timer; /* P: lock */ | 199 | struct timer_list timer; /* P: lock */ |
197 | unsigned pending:1; /* P: lock */ | 200 | unsigned pending:1; /* P: lock */ |
201 | |||
202 | /* | ||
203 | * DMA (thus cache coherency maintenance) requires the | ||
204 | * transfer buffers to live in their own cache lines. | ||
205 | */ | ||
206 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; | ||
198 | }; | 207 | }; |
199 | 208 | ||
200 | static int gpio3; | 209 | static int gpio3; |
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index c21e6d3a8844..794d070c6900 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/workqueue.h> | 47 | #include <linux/workqueue.h> |
48 | #include <linux/spi/spi.h> | 48 | #include <linux/spi/spi.h> |
49 | #include <linux/i2c.h> | 49 | #include <linux/i2c.h> |
50 | #include <linux/gpio.h> | ||
50 | 51 | ||
51 | #include <linux/spi/ad7879.h> | 52 | #include <linux/spi/ad7879.h> |
52 | 53 | ||
@@ -132,7 +133,9 @@ struct ad7879 { | |||
132 | struct input_dev *input; | 133 | struct input_dev *input; |
133 | struct work_struct work; | 134 | struct work_struct work; |
134 | struct timer_list timer; | 135 | struct timer_list timer; |
135 | 136 | #ifdef CONFIG_GPIOLIB | |
137 | struct gpio_chip gc; | ||
138 | #endif | ||
136 | struct mutex mutex; | 139 | struct mutex mutex; |
137 | unsigned disabled:1; /* P: mutex */ | 140 | unsigned disabled:1; /* P: mutex */ |
138 | 141 | ||
@@ -150,11 +153,9 @@ struct ad7879 { | |||
150 | u8 median; | 153 | u8 median; |
151 | u16 x_plate_ohms; | 154 | u16 x_plate_ohms; |
152 | u16 pressure_max; | 155 | u16 pressure_max; |
153 | u16 gpio_init; | ||
154 | u16 cmd_crtl1; | 156 | u16 cmd_crtl1; |
155 | u16 cmd_crtl2; | 157 | u16 cmd_crtl2; |
156 | u16 cmd_crtl3; | 158 | u16 cmd_crtl3; |
157 | unsigned gpio:1; | ||
158 | }; | 159 | }; |
159 | 160 | ||
160 | static int ad7879_read(bus_device *, u8); | 161 | static int ad7879_read(bus_device *, u8); |
@@ -237,24 +238,6 @@ static irqreturn_t ad7879_irq(int irq, void *handle) | |||
237 | 238 | ||
238 | static void ad7879_setup(struct ad7879 *ts) | 239 | static void ad7879_setup(struct ad7879 *ts) |
239 | { | 240 | { |
240 | ts->cmd_crtl3 = AD7879_YPLUS_BIT | | ||
241 | AD7879_XPLUS_BIT | | ||
242 | AD7879_Z2_BIT | | ||
243 | AD7879_Z1_BIT | | ||
244 | AD7879_TEMPMASK_BIT | | ||
245 | AD7879_AUXVBATMASK_BIT | | ||
246 | AD7879_GPIOALERTMASK_BIT; | ||
247 | |||
248 | ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR | | ||
249 | AD7879_AVG(ts->averaging) | | ||
250 | AD7879_MFS(ts->median) | | ||
251 | AD7879_FCD(ts->first_conversion_delay) | | ||
252 | ts->gpio_init; | ||
253 | |||
254 | ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 | | ||
255 | AD7879_ACQ(ts->acquisition_time) | | ||
256 | AD7879_TMR(ts->pen_down_acc_interval); | ||
257 | |||
258 | ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); | 241 | ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); |
259 | ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3); | 242 | ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3); |
260 | ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1); | 243 | ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1); |
@@ -324,48 +307,132 @@ static ssize_t ad7879_disable_store(struct device *dev, | |||
324 | 307 | ||
325 | static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store); | 308 | static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store); |
326 | 309 | ||
327 | static ssize_t ad7879_gpio_show(struct device *dev, | 310 | static struct attribute *ad7879_attributes[] = { |
328 | struct device_attribute *attr, char *buf) | 311 | &dev_attr_disable.attr, |
312 | NULL | ||
313 | }; | ||
314 | |||
315 | static const struct attribute_group ad7879_attr_group = { | ||
316 | .attrs = ad7879_attributes, | ||
317 | }; | ||
318 | |||
319 | #ifdef CONFIG_GPIOLIB | ||
320 | static int ad7879_gpio_direction_input(struct gpio_chip *chip, | ||
321 | unsigned gpio) | ||
329 | { | 322 | { |
330 | struct ad7879 *ts = dev_get_drvdata(dev); | 323 | struct ad7879 *ts = container_of(chip, struct ad7879, gc); |
324 | int err; | ||
331 | 325 | ||
332 | return sprintf(buf, "%u\n", ts->gpio); | 326 | mutex_lock(&ts->mutex); |
327 | ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL; | ||
328 | err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); | ||
329 | mutex_unlock(&ts->mutex); | ||
330 | |||
331 | return err; | ||
333 | } | 332 | } |
334 | 333 | ||
335 | static ssize_t ad7879_gpio_store(struct device *dev, | 334 | static int ad7879_gpio_direction_output(struct gpio_chip *chip, |
336 | struct device_attribute *attr, | 335 | unsigned gpio, int level) |
337 | const char *buf, size_t count) | ||
338 | { | 336 | { |
339 | struct ad7879 *ts = dev_get_drvdata(dev); | 337 | struct ad7879 *ts = container_of(chip, struct ad7879, gc); |
340 | unsigned long val; | 338 | int err; |
341 | int error; | ||
342 | 339 | ||
343 | error = strict_strtoul(buf, 10, &val); | 340 | mutex_lock(&ts->mutex); |
344 | if (error) | 341 | ts->cmd_crtl2 &= ~AD7879_GPIODIR; |
345 | return error; | 342 | ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIOPOL; |
343 | if (level) | ||
344 | ts->cmd_crtl2 |= AD7879_GPIO_DATA; | ||
345 | else | ||
346 | ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; | ||
347 | |||
348 | err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); | ||
349 | mutex_unlock(&ts->mutex); | ||
350 | |||
351 | return err; | ||
352 | } | ||
353 | |||
354 | static int ad7879_gpio_get_value(struct gpio_chip *chip, unsigned gpio) | ||
355 | { | ||
356 | struct ad7879 *ts = container_of(chip, struct ad7879, gc); | ||
357 | u16 val; | ||
346 | 358 | ||
347 | mutex_lock(&ts->mutex); | 359 | mutex_lock(&ts->mutex); |
348 | ts->gpio = !!val; | 360 | val = ad7879_read(ts->bus, AD7879_REG_CTRL2); |
349 | error = ad7879_write(ts->bus, AD7879_REG_CTRL2, | ||
350 | ts->gpio ? | ||
351 | ts->cmd_crtl2 & ~AD7879_GPIO_DATA : | ||
352 | ts->cmd_crtl2 | AD7879_GPIO_DATA); | ||
353 | mutex_unlock(&ts->mutex); | 361 | mutex_unlock(&ts->mutex); |
354 | 362 | ||
355 | return error ? : count; | 363 | return !!(val & AD7879_GPIO_DATA); |
356 | } | 364 | } |
357 | 365 | ||
358 | static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store); | 366 | static void ad7879_gpio_set_value(struct gpio_chip *chip, |
367 | unsigned gpio, int value) | ||
368 | { | ||
369 | struct ad7879 *ts = container_of(chip, struct ad7879, gc); | ||
359 | 370 | ||
360 | static struct attribute *ad7879_attributes[] = { | 371 | mutex_lock(&ts->mutex); |
361 | &dev_attr_disable.attr, | 372 | if (value) |
362 | &dev_attr_gpio.attr, | 373 | ts->cmd_crtl2 |= AD7879_GPIO_DATA; |
363 | NULL | 374 | else |
364 | }; | 375 | ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; |
365 | 376 | ||
366 | static const struct attribute_group ad7879_attr_group = { | 377 | ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); |
367 | .attrs = ad7879_attributes, | 378 | mutex_unlock(&ts->mutex); |
368 | }; | 379 | } |
380 | |||
381 | static int __devinit ad7879_gpio_add(struct device *dev) | ||
382 | { | ||
383 | struct ad7879 *ts = dev_get_drvdata(dev); | ||
384 | struct ad7879_platform_data *pdata = dev->platform_data; | ||
385 | int ret = 0; | ||
386 | |||
387 | if (pdata->gpio_export) { | ||
388 | ts->gc.direction_input = ad7879_gpio_direction_input; | ||
389 | ts->gc.direction_output = ad7879_gpio_direction_output; | ||
390 | ts->gc.get = ad7879_gpio_get_value; | ||
391 | ts->gc.set = ad7879_gpio_set_value; | ||
392 | ts->gc.can_sleep = 1; | ||
393 | ts->gc.base = pdata->gpio_base; | ||
394 | ts->gc.ngpio = 1; | ||
395 | ts->gc.label = "AD7879-GPIO"; | ||
396 | ts->gc.owner = THIS_MODULE; | ||
397 | ts->gc.dev = dev; | ||
398 | |||
399 | ret = gpiochip_add(&ts->gc); | ||
400 | if (ret) | ||
401 | dev_err(dev, "failed to register gpio %d\n", | ||
402 | ts->gc.base); | ||
403 | } | ||
404 | |||
405 | return ret; | ||
406 | } | ||
407 | |||
408 | /* | ||
409 | * We mark ad7879_gpio_remove inline so there is a chance the code | ||
410 | * gets discarded when not needed. We can't do __devinit/__devexit | ||
411 | * markup since it is used in both probe and remove methods. | ||
412 | */ | ||
413 | static inline void ad7879_gpio_remove(struct device *dev) | ||
414 | { | ||
415 | struct ad7879 *ts = dev_get_drvdata(dev); | ||
416 | struct ad7879_platform_data *pdata = dev->platform_data; | ||
417 | int ret; | ||
418 | |||
419 | if (pdata->gpio_export) { | ||
420 | ret = gpiochip_remove(&ts->gc); | ||
421 | if (ret) | ||
422 | dev_err(dev, "failed to remove gpio %d\n", | ||
423 | ts->gc.base); | ||
424 | } | ||
425 | } | ||
426 | #else | ||
427 | static inline int ad7879_gpio_add(struct device *dev) | ||
428 | { | ||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static inline void ad7879_gpio_remove(struct device *dev) | ||
433 | { | ||
434 | } | ||
435 | #endif | ||
369 | 436 | ||
370 | static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | 437 | static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) |
371 | { | 438 | { |
@@ -403,12 +470,6 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
403 | ts->pen_down_acc_interval = pdata->pen_down_acc_interval; | 470 | ts->pen_down_acc_interval = pdata->pen_down_acc_interval; |
404 | ts->median = pdata->median; | 471 | ts->median = pdata->median; |
405 | 472 | ||
406 | if (pdata->gpio_output) | ||
407 | ts->gpio_init = AD7879_GPIO_EN | | ||
408 | (pdata->gpio_default ? 0 : AD7879_GPIO_DATA); | ||
409 | else | ||
410 | ts->gpio_init = AD7879_GPIO_EN | AD7879_GPIODIR; | ||
411 | |||
412 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev)); | 473 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev)); |
413 | 474 | ||
414 | input_dev->name = "AD7879 Touchscreen"; | 475 | input_dev->name = "AD7879 Touchscreen"; |
@@ -446,6 +507,23 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
446 | goto err_free_mem; | 507 | goto err_free_mem; |
447 | } | 508 | } |
448 | 509 | ||
510 | ts->cmd_crtl3 = AD7879_YPLUS_BIT | | ||
511 | AD7879_XPLUS_BIT | | ||
512 | AD7879_Z2_BIT | | ||
513 | AD7879_Z1_BIT | | ||
514 | AD7879_TEMPMASK_BIT | | ||
515 | AD7879_AUXVBATMASK_BIT | | ||
516 | AD7879_GPIOALERTMASK_BIT; | ||
517 | |||
518 | ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR | | ||
519 | AD7879_AVG(ts->averaging) | | ||
520 | AD7879_MFS(ts->median) | | ||
521 | AD7879_FCD(ts->first_conversion_delay); | ||
522 | |||
523 | ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 | | ||
524 | AD7879_ACQ(ts->acquisition_time) | | ||
525 | AD7879_TMR(ts->pen_down_acc_interval); | ||
526 | |||
449 | ad7879_setup(ts); | 527 | ad7879_setup(ts); |
450 | 528 | ||
451 | err = request_irq(bus->irq, ad7879_irq, | 529 | err = request_irq(bus->irq, ad7879_irq, |
@@ -460,15 +538,21 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
460 | if (err) | 538 | if (err) |
461 | goto err_free_irq; | 539 | goto err_free_irq; |
462 | 540 | ||
463 | err = input_register_device(input_dev); | 541 | err = ad7879_gpio_add(&bus->dev); |
464 | if (err) | 542 | if (err) |
465 | goto err_remove_attr; | 543 | goto err_remove_attr; |
466 | 544 | ||
545 | err = input_register_device(input_dev); | ||
546 | if (err) | ||
547 | goto err_remove_gpio; | ||
548 | |||
467 | dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n", | 549 | dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n", |
468 | revid >> 8, bus->irq); | 550 | revid >> 8, bus->irq); |
469 | 551 | ||
470 | return 0; | 552 | return 0; |
471 | 553 | ||
554 | err_remove_gpio: | ||
555 | ad7879_gpio_remove(&bus->dev); | ||
472 | err_remove_attr: | 556 | err_remove_attr: |
473 | sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group); | 557 | sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group); |
474 | err_free_irq: | 558 | err_free_irq: |
@@ -481,6 +565,7 @@ err_free_mem: | |||
481 | 565 | ||
482 | static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts) | 566 | static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts) |
483 | { | 567 | { |
568 | ad7879_gpio_remove(&bus->dev); | ||
484 | ad7879_disable(ts); | 569 | ad7879_disable(ts); |
485 | sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group); | 570 | sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group); |
486 | free_irq(ts->bus->irq, ts); | 571 | free_irq(ts->bus->irq, ts); |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 09c810999b92..532279cda0e4 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -27,15 +27,16 @@ | |||
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <linux/spi/spi.h> | 28 | #include <linux/spi/spi.h> |
29 | #include <linux/spi/ads7846.h> | 29 | #include <linux/spi/ads7846.h> |
30 | #include <linux/regulator/consumer.h> | ||
30 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
31 | 32 | ||
32 | |||
33 | /* | 33 | /* |
34 | * This code has been heavily tested on a Nokia 770, and lightly | 34 | * This code has been heavily tested on a Nokia 770, and lightly |
35 | * tested on other ads7846 devices (OSK/Mistral, Lubbock). | 35 | * tested on other ads7846 devices (OSK/Mistral, Lubbock, Spitz). |
36 | * TSC2046 is just newer ads7846 silicon. | 36 | * TSC2046 is just newer ads7846 silicon. |
37 | * Support for ads7843 tested on Atmel at91sam926x-EK. | 37 | * Support for ads7843 tested on Atmel at91sam926x-EK. |
38 | * Support for ads7845 has only been stubbed in. | 38 | * Support for ads7845 has only been stubbed in. |
39 | * Support for Analog Devices AD7873 and AD7843 tested. | ||
39 | * | 40 | * |
40 | * IRQ handling needs a workaround because of a shortcoming in handling | 41 | * IRQ handling needs a workaround because of a shortcoming in handling |
41 | * edge triggered IRQs on some platforms like the OMAP1/2. These | 42 | * edge triggered IRQs on some platforms like the OMAP1/2. These |
@@ -43,7 +44,7 @@ | |||
43 | * have to maintain our own SW IRQ disabled status. This should be | 44 | * have to maintain our own SW IRQ disabled status. This should be |
44 | * removed as soon as the affected platform's IRQ handling is fixed. | 45 | * removed as soon as the affected platform's IRQ handling is fixed. |
45 | * | 46 | * |
46 | * app note sbaa036 talks in more detail about accurate sampling... | 47 | * App note sbaa036 talks in more detail about accurate sampling... |
47 | * that ought to help in situations like LCDs inducing noise (which | 48 | * that ought to help in situations like LCDs inducing noise (which |
48 | * can also be helped by using synch signals) and more generally. | 49 | * can also be helped by using synch signals) and more generally. |
49 | * This driver tries to utilize the measures described in the app | 50 | * This driver tries to utilize the measures described in the app |
@@ -86,6 +87,7 @@ struct ads7846 { | |||
86 | char name[32]; | 87 | char name[32]; |
87 | 88 | ||
88 | struct spi_device *spi; | 89 | struct spi_device *spi; |
90 | struct regulator *reg; | ||
89 | 91 | ||
90 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) | 92 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) |
91 | struct attribute_group *attr_group; | 93 | struct attribute_group *attr_group; |
@@ -566,10 +568,8 @@ static void ads7846_rx(void *ads) | |||
566 | * once more the measurement | 568 | * once more the measurement |
567 | */ | 569 | */ |
568 | if (packet->tc.ignore || Rt > ts->pressure_max) { | 570 | if (packet->tc.ignore || Rt > ts->pressure_max) { |
569 | #ifdef VERBOSE | 571 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", |
570 | pr_debug("%s: ignored %d pressure %d\n", | 572 | packet->tc.ignore, Rt); |
571 | dev_name(&ts->spi->dev), packet->tc.ignore, Rt); | ||
572 | #endif | ||
573 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | 573 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), |
574 | HRTIMER_MODE_REL); | 574 | HRTIMER_MODE_REL); |
575 | return; | 575 | return; |
@@ -598,9 +598,7 @@ static void ads7846_rx(void *ads) | |||
598 | if (!ts->pendown) { | 598 | if (!ts->pendown) { |
599 | input_report_key(input, BTN_TOUCH, 1); | 599 | input_report_key(input, BTN_TOUCH, 1); |
600 | ts->pendown = 1; | 600 | ts->pendown = 1; |
601 | #ifdef VERBOSE | 601 | dev_vdbg(&ts->spi->dev, "DOWN\n"); |
602 | dev_dbg(&ts->spi->dev, "DOWN\n"); | ||
603 | #endif | ||
604 | } | 602 | } |
605 | 603 | ||
606 | if (ts->swap_xy) | 604 | if (ts->swap_xy) |
@@ -608,12 +606,10 @@ static void ads7846_rx(void *ads) | |||
608 | 606 | ||
609 | input_report_abs(input, ABS_X, x); | 607 | input_report_abs(input, ABS_X, x); |
610 | input_report_abs(input, ABS_Y, y); | 608 | input_report_abs(input, ABS_Y, y); |
611 | input_report_abs(input, ABS_PRESSURE, Rt); | 609 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); |
612 | 610 | ||
613 | input_sync(input); | 611 | input_sync(input); |
614 | #ifdef VERBOSE | 612 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); |
615 | dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); | ||
616 | #endif | ||
617 | } | 613 | } |
618 | 614 | ||
619 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | 615 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), |
@@ -723,9 +719,7 @@ static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) | |||
723 | input_sync(input); | 719 | input_sync(input); |
724 | 720 | ||
725 | ts->pendown = 0; | 721 | ts->pendown = 0; |
726 | #ifdef VERBOSE | 722 | dev_vdbg(&ts->spi->dev, "UP\n"); |
727 | dev_dbg(&ts->spi->dev, "UP\n"); | ||
728 | #endif | ||
729 | } | 723 | } |
730 | 724 | ||
731 | /* measurement cycle ended */ | 725 | /* measurement cycle ended */ |
@@ -797,6 +791,8 @@ static void ads7846_disable(struct ads7846 *ts) | |||
797 | } | 791 | } |
798 | } | 792 | } |
799 | 793 | ||
794 | regulator_disable(ts->reg); | ||
795 | |||
800 | /* we know the chip's in lowpower mode since we always | 796 | /* we know the chip's in lowpower mode since we always |
801 | * leave it that way after every request | 797 | * leave it that way after every request |
802 | */ | 798 | */ |
@@ -808,6 +804,8 @@ static void ads7846_enable(struct ads7846 *ts) | |||
808 | if (!ts->disabled) | 804 | if (!ts->disabled) |
809 | return; | 805 | return; |
810 | 806 | ||
807 | regulator_enable(ts->reg); | ||
808 | |||
811 | ts->disabled = 0; | 809 | ts->disabled = 0; |
812 | ts->irq_disabled = 0; | 810 | ts->irq_disabled = 0; |
813 | enable_irq(ts->spi->irq); | 811 | enable_irq(ts->spi->irq); |
@@ -824,6 +822,9 @@ static int ads7846_suspend(struct spi_device *spi, pm_message_t message) | |||
824 | 822 | ||
825 | spin_unlock_irq(&ts->lock); | 823 | spin_unlock_irq(&ts->lock); |
826 | 824 | ||
825 | if (device_may_wakeup(&ts->spi->dev)) | ||
826 | enable_irq_wake(ts->spi->irq); | ||
827 | |||
827 | return 0; | 828 | return 0; |
828 | 829 | ||
829 | } | 830 | } |
@@ -832,6 +833,9 @@ static int ads7846_resume(struct spi_device *spi) | |||
832 | { | 833 | { |
833 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 834 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
834 | 835 | ||
836 | if (device_may_wakeup(&ts->spi->dev)) | ||
837 | disable_irq_wake(ts->spi->irq); | ||
838 | |||
835 | spin_lock_irq(&ts->lock); | 839 | spin_lock_irq(&ts->lock); |
836 | 840 | ||
837 | ts->is_suspended = 0; | 841 | ts->is_suspended = 0; |
@@ -987,6 +991,15 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
987 | 991 | ||
988 | vref = pdata->keep_vref_on; | 992 | vref = pdata->keep_vref_on; |
989 | 993 | ||
994 | if (ts->model == 7873) { | ||
995 | /* The AD7873 is almost identical to the ADS7846 | ||
996 | * keep VREF off during differential/ratiometric | ||
997 | * conversion modes | ||
998 | */ | ||
999 | ts->model = 7846; | ||
1000 | vref = 0; | ||
1001 | } | ||
1002 | |||
990 | /* set up the transfers to read touchscreen state; this assumes we | 1003 | /* set up the transfers to read touchscreen state; this assumes we |
991 | * use formula #2 for pressure, not #3. | 1004 | * use formula #2 for pressure, not #3. |
992 | */ | 1005 | */ |
@@ -1148,6 +1161,19 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1148 | 1161 | ||
1149 | ts->last_msg = m; | 1162 | ts->last_msg = m; |
1150 | 1163 | ||
1164 | ts->reg = regulator_get(&spi->dev, "vcc"); | ||
1165 | if (IS_ERR(ts->reg)) { | ||
1166 | dev_err(&spi->dev, "unable to get regulator: %ld\n", | ||
1167 | PTR_ERR(ts->reg)); | ||
1168 | goto err_free_gpio; | ||
1169 | } | ||
1170 | |||
1171 | err = regulator_enable(ts->reg); | ||
1172 | if (err) { | ||
1173 | dev_err(&spi->dev, "unable to enable regulator: %d\n", err); | ||
1174 | goto err_put_regulator; | ||
1175 | } | ||
1176 | |||
1151 | if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, | 1177 | if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, |
1152 | spi->dev.driver->name, ts)) { | 1178 | spi->dev.driver->name, ts)) { |
1153 | dev_info(&spi->dev, | 1179 | dev_info(&spi->dev, |
@@ -1157,7 +1183,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1157 | spi->dev.driver->name, ts); | 1183 | spi->dev.driver->name, ts); |
1158 | if (err) { | 1184 | if (err) { |
1159 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 1185 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
1160 | goto err_free_gpio; | 1186 | goto err_disable_regulator; |
1161 | } | 1187 | } |
1162 | } | 1188 | } |
1163 | 1189 | ||
@@ -1181,6 +1207,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1181 | if (err) | 1207 | if (err) |
1182 | goto err_remove_attr_group; | 1208 | goto err_remove_attr_group; |
1183 | 1209 | ||
1210 | device_init_wakeup(&spi->dev, pdata->wakeup); | ||
1211 | |||
1184 | return 0; | 1212 | return 0; |
1185 | 1213 | ||
1186 | err_remove_attr_group: | 1214 | err_remove_attr_group: |
@@ -1189,6 +1217,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1189 | ads784x_hwmon_unregister(spi, ts); | 1217 | ads784x_hwmon_unregister(spi, ts); |
1190 | err_free_irq: | 1218 | err_free_irq: |
1191 | free_irq(spi->irq, ts); | 1219 | free_irq(spi->irq, ts); |
1220 | err_disable_regulator: | ||
1221 | regulator_disable(ts->reg); | ||
1222 | err_put_regulator: | ||
1223 | regulator_put(ts->reg); | ||
1192 | err_free_gpio: | 1224 | err_free_gpio: |
1193 | if (ts->gpio_pendown != -1) | 1225 | if (ts->gpio_pendown != -1) |
1194 | gpio_free(ts->gpio_pendown); | 1226 | gpio_free(ts->gpio_pendown); |
@@ -1206,6 +1238,8 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
1206 | { | 1238 | { |
1207 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 1239 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
1208 | 1240 | ||
1241 | device_init_wakeup(&spi->dev, false); | ||
1242 | |||
1209 | ads784x_hwmon_unregister(spi, ts); | 1243 | ads784x_hwmon_unregister(spi, ts); |
1210 | input_unregister_device(ts->input); | 1244 | input_unregister_device(ts->input); |
1211 | 1245 | ||
@@ -1217,6 +1251,9 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
1217 | /* suspend left the IRQ disabled */ | 1251 | /* suspend left the IRQ disabled */ |
1218 | enable_irq(ts->spi->irq); | 1252 | enable_irq(ts->spi->irq); |
1219 | 1253 | ||
1254 | regulator_disable(ts->reg); | ||
1255 | regulator_put(ts->reg); | ||
1256 | |||
1220 | if (ts->gpio_pendown != -1) | 1257 | if (ts->gpio_pendown != -1) |
1221 | gpio_free(ts->gpio_pendown); | 1258 | gpio_free(ts->gpio_pendown); |
1222 | 1259 | ||
diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c index 35377f583e28..fa8e56bd9094 100644 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ b/drivers/input/touchscreen/atmel-wm97xx.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #define AC97C_ICA 0x10 | 24 | #define AC97C_ICA 0x10 |
24 | #define AC97C_CBRHR 0x30 | 25 | #define AC97C_CBRHR 0x30 |
@@ -59,7 +60,7 @@ | |||
59 | #define ATMEL_WM97XX_AC97C_IRQ (29) | 60 | #define ATMEL_WM97XX_AC97C_IRQ (29) |
60 | #define ATMEL_WM97XX_GPIO_DEFAULT (32+16) /* Pin 16 on port B. */ | 61 | #define ATMEL_WM97XX_GPIO_DEFAULT (32+16) /* Pin 16 on port B. */ |
61 | #else | 62 | #else |
62 | #error Unkown CPU, this driver only supports AT32AP700X CPUs. | 63 | #error Unknown CPU, this driver only supports AT32AP700X CPUs. |
63 | #endif | 64 | #endif |
64 | 65 | ||
65 | struct continuous { | 66 | struct continuous { |
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c index 9c7fce4d74d0..3d9b5166ebe9 100644 --- a/drivers/input/touchscreen/atmel_tsadcc.c +++ b/drivers/input/touchscreen/atmel_tsadcc.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <mach/board.h> | ||
26 | #include <mach/cpu.h> | ||
25 | 27 | ||
26 | /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */ | 28 | /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */ |
27 | 29 | ||
@@ -36,7 +38,9 @@ | |||
36 | #define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */ | 38 | #define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */ |
37 | #define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */ | 39 | #define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */ |
38 | #define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */ | 40 | #define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */ |
41 | #define ATMEL_TSADCC_PRES (1 << 7) /* Pressure Measurement Selection */ | ||
39 | #define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ | 42 | #define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ |
43 | #define ATMEL_TSADCC_EPRESCAL (0xff << 8) /* Prescalar Rate Selection (Extended) */ | ||
40 | #define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */ | 44 | #define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */ |
41 | #define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */ | 45 | #define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */ |
42 | #define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */ | 46 | #define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */ |
@@ -84,7 +88,13 @@ | |||
84 | #define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */ | 88 | #define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */ |
85 | #define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */ | 89 | #define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */ |
86 | 90 | ||
87 | #define ADC_CLOCK 1000000 | 91 | #define ATMEL_TSADCC_XPOS 0x50 |
92 | #define ATMEL_TSADCC_Z1DAT 0x54 | ||
93 | #define ATMEL_TSADCC_Z2DAT 0x58 | ||
94 | |||
95 | #define PRESCALER_VAL(x) ((x) >> 8) | ||
96 | |||
97 | #define ADC_DEFAULT_CLOCK 100000 | ||
88 | 98 | ||
89 | struct atmel_tsadcc { | 99 | struct atmel_tsadcc { |
90 | struct input_dev *input; | 100 | struct input_dev *input; |
@@ -172,6 +182,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) | |||
172 | struct atmel_tsadcc *ts_dev; | 182 | struct atmel_tsadcc *ts_dev; |
173 | struct input_dev *input_dev; | 183 | struct input_dev *input_dev; |
174 | struct resource *res; | 184 | struct resource *res; |
185 | struct at91_tsadcc_data *pdata = pdev->dev.platform_data; | ||
175 | int err = 0; | 186 | int err = 0; |
176 | unsigned int prsc; | 187 | unsigned int prsc; |
177 | unsigned int reg; | 188 | unsigned int reg; |
@@ -242,31 +253,49 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) | |||
242 | input_dev->phys = ts_dev->phys; | 253 | input_dev->phys = ts_dev->phys; |
243 | input_dev->dev.parent = &pdev->dev; | 254 | input_dev->dev.parent = &pdev->dev; |
244 | 255 | ||
245 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 256 | __set_bit(EV_ABS, input_dev->evbit); |
246 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
247 | |||
248 | input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0); | 257 | input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0); |
249 | input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0); | 258 | input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0); |
250 | 259 | ||
260 | input_set_capability(input_dev, EV_KEY, BTN_TOUCH); | ||
261 | |||
251 | /* clk_enable() always returns 0, no need to check it */ | 262 | /* clk_enable() always returns 0, no need to check it */ |
252 | clk_enable(ts_dev->clk); | 263 | clk_enable(ts_dev->clk); |
253 | 264 | ||
254 | prsc = clk_get_rate(ts_dev->clk); | 265 | prsc = clk_get_rate(ts_dev->clk); |
255 | dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc); | 266 | dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc); |
256 | 267 | ||
257 | prsc = prsc / ADC_CLOCK / 2 - 1; | 268 | if (!pdata) |
269 | goto err_fail; | ||
270 | |||
271 | if (!pdata->adc_clock) | ||
272 | pdata->adc_clock = ADC_DEFAULT_CLOCK; | ||
273 | |||
274 | prsc = (prsc / (2 * pdata->adc_clock)) - 1; | ||
275 | |||
276 | /* saturate if this value is too high */ | ||
277 | if (cpu_is_at91sam9rl()) { | ||
278 | if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL)) | ||
279 | prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL); | ||
280 | } else { | ||
281 | if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL)) | ||
282 | prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL); | ||
283 | } | ||
284 | |||
285 | dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc); | ||
258 | 286 | ||
259 | reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE | | 287 | reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE | |
260 | ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */ | 288 | ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */ |
261 | ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */ | 289 | ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */ |
262 | ((prsc << 8) & ATMEL_TSADCC_PRESCAL) | /* PRESCAL */ | 290 | (prsc << 8) | |
263 | ((0x13 << 16) & ATMEL_TSADCC_STARTUP) | /* STARTUP */ | 291 | ((0x26 << 16) & ATMEL_TSADCC_STARTUP) | |
264 | ((0x0F << 28) & ATMEL_TSADCC_PENDBC); /* PENDBC */ | 292 | ((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC); |
265 | 293 | ||
266 | atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST); | 294 | atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST); |
267 | atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); | 295 | atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); |
268 | atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); | 296 | atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); |
269 | atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM); | 297 | atmel_tsadcc_write(ATMEL_TSADCC_TSR, |
298 | (pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM); | ||
270 | 299 | ||
271 | atmel_tsadcc_read(ATMEL_TSADCC_SR); | 300 | atmel_tsadcc_read(ATMEL_TSADCC_SR); |
272 | atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); | 301 | atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); |
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c index 3ffd4c4b170c..2b72a5923c16 100644 --- a/drivers/input/touchscreen/da9034-ts.c +++ b/drivers/input/touchscreen/da9034-ts.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/workqueue.h> | 20 | #include <linux/workqueue.h> |
21 | #include <linux/mfd/da903x.h> | 21 | #include <linux/mfd/da903x.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #define DA9034_MANUAL_CTRL 0x50 | 24 | #define DA9034_MANUAL_CTRL 0x50 |
24 | #define DA9034_LDO_ADC_EN (1 << 4) | 25 | #define DA9034_LDO_ADC_EN (1 << 4) |
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c new file mode 100644 index 000000000000..455353908bdf --- /dev/null +++ b/drivers/input/touchscreen/dynapro.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /* | ||
2 | * Dynapro serial touchscreen driver | ||
3 | * | ||
4 | * Copyright (c) 2009 Tias Guns | ||
5 | * Based on the inexio driver (c) Vojtech Pavlik and Dan Streetman and | ||
6 | * Richard Lemon | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License version 2 as published by | ||
13 | * the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * 2009/09/19 Tias Guns <tias@ulyssis.org> | ||
18 | * Copied inexio.c and edited for Dynapro protocol (from retired Xorg module) | ||
19 | */ | ||
20 | |||
21 | #include <linux/errno.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/input.h> | ||
26 | #include <linux/serio.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | #define DRIVER_DESC "Dynapro serial touchscreen driver" | ||
30 | |||
31 | MODULE_AUTHOR("Tias Guns <tias@ulyssis.org>"); | ||
32 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | |||
35 | /* | ||
36 | * Definitions & global arrays. | ||
37 | */ | ||
38 | |||
39 | #define DYNAPRO_FORMAT_TOUCH_BIT 0x40 | ||
40 | #define DYNAPRO_FORMAT_LENGTH 3 | ||
41 | #define DYNAPRO_RESPONSE_BEGIN_BYTE 0x80 | ||
42 | |||
43 | #define DYNAPRO_MIN_XC 0 | ||
44 | #define DYNAPRO_MAX_XC 0x3ff | ||
45 | #define DYNAPRO_MIN_YC 0 | ||
46 | #define DYNAPRO_MAX_YC 0x3ff | ||
47 | |||
48 | #define DYNAPRO_GET_XC(data) (data[1] | ((data[0] & 0x38) << 4)) | ||
49 | #define DYNAPRO_GET_YC(data) (data[2] | ((data[0] & 0x07) << 7)) | ||
50 | #define DYNAPRO_GET_TOUCHED(data) (DYNAPRO_FORMAT_TOUCH_BIT & data[0]) | ||
51 | |||
52 | /* | ||
53 | * Per-touchscreen data. | ||
54 | */ | ||
55 | |||
56 | struct dynapro { | ||
57 | struct input_dev *dev; | ||
58 | struct serio *serio; | ||
59 | int idx; | ||
60 | unsigned char data[DYNAPRO_FORMAT_LENGTH]; | ||
61 | char phys[32]; | ||
62 | }; | ||
63 | |||
64 | static void dynapro_process_data(struct dynapro *pdynapro) | ||
65 | { | ||
66 | struct input_dev *dev = pdynapro->dev; | ||
67 | |||
68 | if (DYNAPRO_FORMAT_LENGTH == ++pdynapro->idx) { | ||
69 | input_report_abs(dev, ABS_X, DYNAPRO_GET_XC(pdynapro->data)); | ||
70 | input_report_abs(dev, ABS_Y, DYNAPRO_GET_YC(pdynapro->data)); | ||
71 | input_report_key(dev, BTN_TOUCH, | ||
72 | DYNAPRO_GET_TOUCHED(pdynapro->data)); | ||
73 | input_sync(dev); | ||
74 | |||
75 | pdynapro->idx = 0; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | static irqreturn_t dynapro_interrupt(struct serio *serio, | ||
80 | unsigned char data, unsigned int flags) | ||
81 | { | ||
82 | struct dynapro *pdynapro = serio_get_drvdata(serio); | ||
83 | |||
84 | pdynapro->data[pdynapro->idx] = data; | ||
85 | |||
86 | if (DYNAPRO_RESPONSE_BEGIN_BYTE & pdynapro->data[0]) | ||
87 | dynapro_process_data(pdynapro); | ||
88 | else | ||
89 | dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n", | ||
90 | pdynapro->data[0]); | ||
91 | |||
92 | return IRQ_HANDLED; | ||
93 | } | ||
94 | |||
95 | static void dynapro_disconnect(struct serio *serio) | ||
96 | { | ||
97 | struct dynapro *pdynapro = serio_get_drvdata(serio); | ||
98 | |||
99 | input_get_device(pdynapro->dev); | ||
100 | input_unregister_device(pdynapro->dev); | ||
101 | serio_close(serio); | ||
102 | serio_set_drvdata(serio, NULL); | ||
103 | input_put_device(pdynapro->dev); | ||
104 | kfree(pdynapro); | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * dynapro_connect() is the routine that is called when someone adds a | ||
109 | * new serio device that supports dynapro protocol and registers it as | ||
110 | * an input device. This is usually accomplished using inputattach. | ||
111 | */ | ||
112 | |||
113 | static int dynapro_connect(struct serio *serio, struct serio_driver *drv) | ||
114 | { | ||
115 | struct dynapro *pdynapro; | ||
116 | struct input_dev *input_dev; | ||
117 | int err; | ||
118 | |||
119 | pdynapro = kzalloc(sizeof(struct dynapro), GFP_KERNEL); | ||
120 | input_dev = input_allocate_device(); | ||
121 | if (!pdynapro || !input_dev) { | ||
122 | err = -ENOMEM; | ||
123 | goto fail1; | ||
124 | } | ||
125 | |||
126 | pdynapro->serio = serio; | ||
127 | pdynapro->dev = input_dev; | ||
128 | snprintf(pdynapro->phys, sizeof(pdynapro->phys), | ||
129 | "%s/input0", serio->phys); | ||
130 | |||
131 | input_dev->name = "Dynapro Serial TouchScreen"; | ||
132 | input_dev->phys = pdynapro->phys; | ||
133 | input_dev->id.bustype = BUS_RS232; | ||
134 | input_dev->id.vendor = SERIO_DYNAPRO; | ||
135 | input_dev->id.product = 0; | ||
136 | input_dev->id.version = 0x0001; | ||
137 | input_dev->dev.parent = &serio->dev; | ||
138 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
139 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
140 | input_set_abs_params(pdynapro->dev, ABS_X, | ||
141 | DYNAPRO_MIN_XC, DYNAPRO_MAX_XC, 0, 0); | ||
142 | input_set_abs_params(pdynapro->dev, ABS_Y, | ||
143 | DYNAPRO_MIN_YC, DYNAPRO_MAX_YC, 0, 0); | ||
144 | |||
145 | serio_set_drvdata(serio, pdynapro); | ||
146 | |||
147 | err = serio_open(serio, drv); | ||
148 | if (err) | ||
149 | goto fail2; | ||
150 | |||
151 | err = input_register_device(pdynapro->dev); | ||
152 | if (err) | ||
153 | goto fail3; | ||
154 | |||
155 | return 0; | ||
156 | |||
157 | fail3: serio_close(serio); | ||
158 | fail2: serio_set_drvdata(serio, NULL); | ||
159 | fail1: input_free_device(input_dev); | ||
160 | kfree(pdynapro); | ||
161 | return err; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * The serio driver structure. | ||
166 | */ | ||
167 | |||
168 | static struct serio_device_id dynapro_serio_ids[] = { | ||
169 | { | ||
170 | .type = SERIO_RS232, | ||
171 | .proto = SERIO_DYNAPRO, | ||
172 | .id = SERIO_ANY, | ||
173 | .extra = SERIO_ANY, | ||
174 | }, | ||
175 | { 0 } | ||
176 | }; | ||
177 | |||
178 | MODULE_DEVICE_TABLE(serio, dynapro_serio_ids); | ||
179 | |||
180 | static struct serio_driver dynapro_drv = { | ||
181 | .driver = { | ||
182 | .name = "dynapro", | ||
183 | }, | ||
184 | .description = DRIVER_DESC, | ||
185 | .id_table = dynapro_serio_ids, | ||
186 | .interrupt = dynapro_interrupt, | ||
187 | .connect = dynapro_connect, | ||
188 | .disconnect = dynapro_disconnect, | ||
189 | }; | ||
190 | |||
191 | /* | ||
192 | * The functions for inserting/removing us as a module. | ||
193 | */ | ||
194 | |||
195 | static int __init dynapro_init(void) | ||
196 | { | ||
197 | return serio_register_driver(&dynapro_drv); | ||
198 | } | ||
199 | |||
200 | static void __exit dynapro_exit(void) | ||
201 | { | ||
202 | serio_unregister_driver(&dynapro_drv); | ||
203 | } | ||
204 | |||
205 | module_init(dynapro_init); | ||
206 | module_exit(dynapro_exit); | ||
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 9029bd3f34e5..75f8b73010fa 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/timer.h> | 33 | #include <linux/timer.h> |
34 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
35 | #include <linux/input/eeti_ts.h> | 35 | #include <linux/input/eeti_ts.h> |
36 | #include <linux/slab.h> | ||
36 | 37 | ||
37 | static int flip_x; | 38 | static int flip_x; |
38 | module_param(flip_x, bool, 0644); | 39 | module_param(flip_x, bool, 0644); |
@@ -123,14 +124,25 @@ static irqreturn_t eeti_ts_isr(int irq, void *dev_id) | |||
123 | return IRQ_HANDLED; | 124 | return IRQ_HANDLED; |
124 | } | 125 | } |
125 | 126 | ||
126 | static int eeti_ts_open(struct input_dev *dev) | 127 | static void eeti_ts_start(struct eeti_ts_priv *priv) |
127 | { | 128 | { |
128 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | ||
129 | |||
130 | enable_irq(priv->irq); | 129 | enable_irq(priv->irq); |
131 | 130 | ||
132 | /* Read the events once to arm the IRQ */ | 131 | /* Read the events once to arm the IRQ */ |
133 | eeti_ts_read(&priv->work); | 132 | eeti_ts_read(&priv->work); |
133 | } | ||
134 | |||
135 | static void eeti_ts_stop(struct eeti_ts_priv *priv) | ||
136 | { | ||
137 | disable_irq(priv->irq); | ||
138 | cancel_work_sync(&priv->work); | ||
139 | } | ||
140 | |||
141 | static int eeti_ts_open(struct input_dev *dev) | ||
142 | { | ||
143 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | ||
144 | |||
145 | eeti_ts_start(priv); | ||
134 | 146 | ||
135 | return 0; | 147 | return 0; |
136 | } | 148 | } |
@@ -139,8 +151,7 @@ static void eeti_ts_close(struct input_dev *dev) | |||
139 | { | 151 | { |
140 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | 152 | struct eeti_ts_priv *priv = input_get_drvdata(dev); |
141 | 153 | ||
142 | disable_irq(priv->irq); | 154 | eeti_ts_stop(priv); |
143 | cancel_work_sync(&priv->work); | ||
144 | } | 155 | } |
145 | 156 | ||
146 | static int __devinit eeti_ts_probe(struct i2c_client *client, | 157 | static int __devinit eeti_ts_probe(struct i2c_client *client, |
@@ -152,10 +163,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
152 | unsigned int irq_flags; | 163 | unsigned int irq_flags; |
153 | int err = -ENOMEM; | 164 | int err = -ENOMEM; |
154 | 165 | ||
155 | /* In contrast to what's described in the datasheet, there seems | 166 | /* |
167 | * In contrast to what's described in the datasheet, there seems | ||
156 | * to be no way of probing the presence of that device using I2C | 168 | * to be no way of probing the presence of that device using I2C |
157 | * commands. So we need to blindly believe it is there, and wait | 169 | * commands. So we need to blindly believe it is there, and wait |
158 | * for interrupts to occur. */ | 170 | * for interrupts to occur. |
171 | */ | ||
159 | 172 | ||
160 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 173 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
161 | if (!priv) { | 174 | if (!priv) { |
@@ -211,9 +224,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
211 | goto err2; | 224 | goto err2; |
212 | } | 225 | } |
213 | 226 | ||
214 | /* Disable the irq for now. It will be enabled once the input device | 227 | /* |
215 | * is opened. */ | 228 | * Disable the device for now. It will be enabled once the |
216 | disable_irq(priv->irq); | 229 | * input device is opened. |
230 | */ | ||
231 | eeti_ts_stop(priv); | ||
217 | 232 | ||
218 | device_init_wakeup(&client->dev, 0); | 233 | device_init_wakeup(&client->dev, 0); |
219 | return 0; | 234 | return 0; |
@@ -234,6 +249,12 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
234 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 249 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
235 | 250 | ||
236 | free_irq(priv->irq, priv); | 251 | free_irq(priv->irq, priv); |
252 | /* | ||
253 | * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it | ||
254 | * so that device still works if we reload the driver. | ||
255 | */ | ||
256 | enable_irq(priv->irq); | ||
257 | |||
237 | input_unregister_device(priv->input); | 258 | input_unregister_device(priv->input); |
238 | i2c_set_clientdata(client, NULL); | 259 | i2c_set_clientdata(client, NULL); |
239 | kfree(priv); | 260 | kfree(priv); |
@@ -245,6 +266,14 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
245 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 266 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) |
246 | { | 267 | { |
247 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 268 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
269 | struct input_dev *input_dev = priv->input; | ||
270 | |||
271 | mutex_lock(&input_dev->mutex); | ||
272 | |||
273 | if (input_dev->users) | ||
274 | eeti_ts_stop(priv); | ||
275 | |||
276 | mutex_unlock(&input_dev->mutex); | ||
248 | 277 | ||
249 | if (device_may_wakeup(&client->dev)) | 278 | if (device_may_wakeup(&client->dev)) |
250 | enable_irq_wake(priv->irq); | 279 | enable_irq_wake(priv->irq); |
@@ -255,10 +284,18 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
255 | static int eeti_ts_resume(struct i2c_client *client) | 284 | static int eeti_ts_resume(struct i2c_client *client) |
256 | { | 285 | { |
257 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 286 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
287 | struct input_dev *input_dev = priv->input; | ||
258 | 288 | ||
259 | if (device_may_wakeup(&client->dev)) | 289 | if (device_may_wakeup(&client->dev)) |
260 | disable_irq_wake(priv->irq); | 290 | disable_irq_wake(priv->irq); |
261 | 291 | ||
292 | mutex_lock(&input_dev->mutex); | ||
293 | |||
294 | if (input_dev->users) | ||
295 | eeti_ts_start(priv); | ||
296 | |||
297 | mutex_unlock(&input_dev->mutex); | ||
298 | |||
262 | return 0; | 299 | return 0; |
263 | } | 300 | } |
264 | #else | 301 | #else |
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 8f38c5e55ce6..486d31ba9c09 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
@@ -72,45 +72,49 @@ static void elo_process_data_10(struct elo *elo, unsigned char data) | |||
72 | struct input_dev *dev = elo->dev; | 72 | struct input_dev *dev = elo->dev; |
73 | 73 | ||
74 | elo->data[elo->idx] = data; | 74 | elo->data[elo->idx] = data; |
75 | switch (elo->idx++) { | ||
76 | case 0: | ||
77 | elo->csum = 0xaa; | ||
78 | if (data != ELO10_LEAD_BYTE) { | ||
79 | pr_debug("elo: unsynchronized data: 0x%02x\n", data); | ||
80 | elo->idx = 0; | ||
81 | } | ||
82 | break; | ||
83 | 75 | ||
84 | case 9: | 76 | switch (elo->idx++) { |
77 | case 0: | ||
78 | elo->csum = 0xaa; | ||
79 | if (data != ELO10_LEAD_BYTE) { | ||
80 | dev_dbg(&elo->serio->dev, | ||
81 | "unsynchronized data: 0x%02x\n", data); | ||
85 | elo->idx = 0; | 82 | elo->idx = 0; |
86 | if (data != elo->csum) { | 83 | } |
87 | pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n", | 84 | break; |
88 | data, elo->csum); | 85 | |
89 | break; | 86 | case 9: |
90 | } | 87 | elo->idx = 0; |
91 | if (elo->data[1] != elo->expected_packet) { | 88 | if (data != elo->csum) { |
92 | if (elo->data[1] != ELO10_TOUCH_PACKET) | 89 | dev_dbg(&elo->serio->dev, |
93 | pr_debug("elo: unexpected packet: 0x%02x\n", | 90 | "bad checksum: 0x%02x, expected 0x%02x\n", |
94 | elo->data[1]); | 91 | data, elo->csum); |
95 | break; | 92 | break; |
96 | } | 93 | } |
97 | if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) { | 94 | if (elo->data[1] != elo->expected_packet) { |
98 | input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); | 95 | if (elo->data[1] != ELO10_TOUCH_PACKET) |
99 | input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); | 96 | dev_dbg(&elo->serio->dev, |
100 | if (elo->data[2] & ELO10_PRESSURE) | 97 | "unexpected packet: 0x%02x\n", |
101 | input_report_abs(dev, ABS_PRESSURE, | 98 | elo->data[1]); |
102 | (elo->data[8] << 8) | elo->data[7]); | ||
103 | input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH); | ||
104 | input_sync(dev); | ||
105 | } else if (elo->data[1] == ELO10_ACK_PACKET) { | ||
106 | if (elo->data[2] == '0') | ||
107 | elo->expected_packet = ELO10_TOUCH_PACKET; | ||
108 | complete(&elo->cmd_done); | ||
109 | } else { | ||
110 | memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN); | ||
111 | elo->expected_packet = ELO10_ACK_PACKET; | ||
112 | } | ||
113 | break; | 99 | break; |
100 | } | ||
101 | if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) { | ||
102 | input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); | ||
103 | input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); | ||
104 | if (elo->data[2] & ELO10_PRESSURE) | ||
105 | input_report_abs(dev, ABS_PRESSURE, | ||
106 | (elo->data[8] << 8) | elo->data[7]); | ||
107 | input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH); | ||
108 | input_sync(dev); | ||
109 | } else if (elo->data[1] == ELO10_ACK_PACKET) { | ||
110 | if (elo->data[2] == '0') | ||
111 | elo->expected_packet = ELO10_TOUCH_PACKET; | ||
112 | complete(&elo->cmd_done); | ||
113 | } else { | ||
114 | memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN); | ||
115 | elo->expected_packet = ELO10_ACK_PACKET; | ||
116 | } | ||
117 | break; | ||
114 | } | 118 | } |
115 | elo->csum += data; | 119 | elo->csum += data; |
116 | } | 120 | } |
@@ -123,42 +127,53 @@ static void elo_process_data_6(struct elo *elo, unsigned char data) | |||
123 | 127 | ||
124 | switch (elo->idx++) { | 128 | switch (elo->idx++) { |
125 | 129 | ||
126 | case 0: if ((data & 0xc0) != 0xc0) elo->idx = 0; break; | 130 | case 0: |
127 | case 1: if ((data & 0xc0) != 0x80) elo->idx = 0; break; | 131 | if ((data & 0xc0) != 0xc0) |
128 | case 2: if ((data & 0xc0) != 0x40) elo->idx = 0; break; | 132 | elo->idx = 0; |
129 | 133 | break; | |
130 | case 3: | ||
131 | if (data & 0xc0) { | ||
132 | elo->idx = 0; | ||
133 | break; | ||
134 | } | ||
135 | 134 | ||
136 | input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f)); | 135 | case 1: |
137 | input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f)); | 136 | if ((data & 0xc0) != 0x80) |
137 | elo->idx = 0; | ||
138 | break; | ||
138 | 139 | ||
139 | if (elo->id == 2) { | 140 | case 2: |
140 | input_report_key(dev, BTN_TOUCH, 1); | 141 | if ((data & 0xc0) != 0x40) |
141 | input_sync(dev); | 142 | elo->idx = 0; |
142 | elo->idx = 0; | 143 | break; |
143 | } | ||
144 | 144 | ||
145 | case 3: | ||
146 | if (data & 0xc0) { | ||
147 | elo->idx = 0; | ||
145 | break; | 148 | break; |
149 | } | ||
146 | 150 | ||
147 | case 4: | 151 | input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f)); |
148 | if (data) { | 152 | input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f)); |
149 | input_sync(dev); | ||
150 | elo->idx = 0; | ||
151 | } | ||
152 | break; | ||
153 | 153 | ||
154 | case 5: | 154 | if (elo->id == 2) { |
155 | if ((data & 0xf0) == 0) { | 155 | input_report_key(dev, BTN_TOUCH, 1); |
156 | input_report_abs(dev, ABS_PRESSURE, elo->data[5]); | ||
157 | input_report_key(dev, BTN_TOUCH, !!elo->data[5]); | ||
158 | } | ||
159 | input_sync(dev); | 156 | input_sync(dev); |
160 | elo->idx = 0; | 157 | elo->idx = 0; |
161 | break; | 158 | } |
159 | |||
160 | break; | ||
161 | |||
162 | case 4: | ||
163 | if (data) { | ||
164 | input_sync(dev); | ||
165 | elo->idx = 0; | ||
166 | } | ||
167 | break; | ||
168 | |||
169 | case 5: | ||
170 | if ((data & 0xf0) == 0) { | ||
171 | input_report_abs(dev, ABS_PRESSURE, elo->data[5]); | ||
172 | input_report_key(dev, BTN_TOUCH, !!elo->data[5]); | ||
173 | } | ||
174 | input_sync(dev); | ||
175 | elo->idx = 0; | ||
176 | break; | ||
162 | } | 177 | } |
163 | } | 178 | } |
164 | 179 | ||
@@ -170,17 +185,17 @@ static void elo_process_data_3(struct elo *elo, unsigned char data) | |||
170 | 185 | ||
171 | switch (elo->idx++) { | 186 | switch (elo->idx++) { |
172 | 187 | ||
173 | case 0: | 188 | case 0: |
174 | if ((data & 0x7f) != 0x01) | 189 | if ((data & 0x7f) != 0x01) |
175 | elo->idx = 0; | ||
176 | break; | ||
177 | case 2: | ||
178 | input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80)); | ||
179 | input_report_abs(dev, ABS_X, elo->data[1]); | ||
180 | input_report_abs(dev, ABS_Y, elo->data[2]); | ||
181 | input_sync(dev); | ||
182 | elo->idx = 0; | 190 | elo->idx = 0; |
183 | break; | 191 | break; |
192 | case 2: | ||
193 | input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80)); | ||
194 | input_report_abs(dev, ABS_X, elo->data[1]); | ||
195 | input_report_abs(dev, ABS_Y, elo->data[2]); | ||
196 | input_sync(dev); | ||
197 | elo->idx = 0; | ||
198 | break; | ||
184 | } | 199 | } |
185 | } | 200 | } |
186 | 201 | ||
@@ -189,19 +204,19 @@ static irqreturn_t elo_interrupt(struct serio *serio, | |||
189 | { | 204 | { |
190 | struct elo *elo = serio_get_drvdata(serio); | 205 | struct elo *elo = serio_get_drvdata(serio); |
191 | 206 | ||
192 | switch(elo->id) { | 207 | switch (elo->id) { |
193 | case 0: | 208 | case 0: |
194 | elo_process_data_10(elo, data); | 209 | elo_process_data_10(elo, data); |
195 | break; | 210 | break; |
196 | 211 | ||
197 | case 1: | 212 | case 1: |
198 | case 2: | 213 | case 2: |
199 | elo_process_data_6(elo, data); | 214 | elo_process_data_6(elo, data); |
200 | break; | 215 | break; |
201 | 216 | ||
202 | case 3: | 217 | case 3: |
203 | elo_process_data_3(elo, data); | 218 | elo_process_data_3(elo, data); |
204 | break; | 219 | break; |
205 | } | 220 | } |
206 | 221 | ||
207 | return IRQ_HANDLED; | 222 | return IRQ_HANDLED; |
@@ -261,10 +276,10 @@ static int elo_setup_10(struct elo *elo) | |||
261 | if (packet[3] & ELO10_PRESSURE) | 276 | if (packet[3] & ELO10_PRESSURE) |
262 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 277 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
263 | 278 | ||
264 | printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, " | 279 | dev_info(&elo->serio->dev, |
265 | "features: 0x%02x, controller: 0x%02x\n", | 280 | "%sTouch touchscreen, fw: %02x.%02x, features: 0x%02x, controller: 0x%02x\n", |
266 | elo_types[(packet[1] -'0') & 0x03], | 281 | elo_types[(packet[1] -'0') & 0x03], |
267 | packet[5], packet[4], packet[3], packet[7]); | 282 | packet[5], packet[4], packet[3], packet[7]); |
268 | 283 | ||
269 | return 0; | 284 | return 0; |
270 | } | 285 | } |
@@ -330,24 +345,24 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) | |||
330 | 345 | ||
331 | switch (elo->id) { | 346 | switch (elo->id) { |
332 | 347 | ||
333 | case 0: /* 10-byte protocol */ | 348 | case 0: /* 10-byte protocol */ |
334 | if (elo_setup_10(elo)) | 349 | if (elo_setup_10(elo)) |
335 | goto fail3; | 350 | goto fail3; |
336 | 351 | ||
337 | break; | 352 | break; |
338 | 353 | ||
339 | case 1: /* 6-byte protocol */ | 354 | case 1: /* 6-byte protocol */ |
340 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); | 355 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); |
341 | 356 | ||
342 | case 2: /* 4-byte protocol */ | 357 | case 2: /* 4-byte protocol */ |
343 | input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); | 358 | input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); |
344 | input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); | 359 | input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); |
345 | break; | 360 | break; |
346 | 361 | ||
347 | case 3: /* 3-byte protocol */ | 362 | case 3: /* 3-byte protocol */ |
348 | input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); | 363 | input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); |
349 | input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); | 364 | input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); |
350 | break; | 365 | break; |
351 | } | 366 | } |
352 | 367 | ||
353 | err = input_register_device(elo->dev); | 368 | err = input_register_device(elo->dev); |
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index c8b7e8a45c4d..4b0a061811ff 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
23 | #include <mach/jornada720.h> | 24 | #include <mach/jornada720.h> |
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 8fc3b08deb3b..b6b8b1c7ecea 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * | 14 | * |
15 | * Notes: | 15 | * Notes: |
16 | * This is a wm97xx extended touch driver to capture touch | 16 | * This is a wm97xx extended touch driver to capture touch |
17 | * data in a continuous manner on the Intel XScale archictecture | 17 | * data in a continuous manner on the Intel XScale architecture |
18 | * | 18 | * |
19 | * Features: | 19 | * Features: |
20 | * - codecs supported:- WM9705, WM9712, WM9713 | 20 | * - codecs supported:- WM9705, WM9712, WM9713 |
@@ -131,7 +131,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
131 | /* When the AC97 queue has been drained we need to allow time | 131 | /* When the AC97 queue has been drained we need to allow time |
132 | * to buffer up samples otherwise we end up spinning polling | 132 | * to buffer up samples otherwise we end up spinning polling |
133 | * for samples. The controller can't have a suitably low | 133 | * for samples. The controller can't have a suitably low |
134 | * threashold set to use the notifications it gives. | 134 | * threshold set to use the notifications it gives. |
135 | */ | 135 | */ |
136 | schedule_timeout_uninterruptible(1); | 136 | schedule_timeout_uninterruptible(1); |
137 | 137 | ||
@@ -153,6 +153,9 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
153 | if (pressure) | 153 | if (pressure) |
154 | p = MODR; | 154 | p = MODR; |
155 | 155 | ||
156 | dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n", | ||
157 | x, y, p); | ||
158 | |||
156 | /* are samples valid */ | 159 | /* are samples valid */ |
157 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || | 160 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || |
158 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || | 161 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || |
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c new file mode 100644 index 000000000000..c5bc62d85bb6 --- /dev/null +++ b/drivers/input/touchscreen/mc13783_ts.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /* | ||
2 | * Driver for the Freescale Semiconductor MC13783 touchscreen. | ||
3 | * | ||
4 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
5 | * Copyright (C) 2009 Sascha Hauer, Pengutronix | ||
6 | * | ||
7 | * Initial development of this code was funded by | ||
8 | * Phytec Messtechnik GmbH, http://www.phytec.de/ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License version 2 as published by | ||
12 | * the Free Software Foundation. | ||
13 | */ | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/mfd/mc13783.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/init.h> | ||
22 | |||
23 | #define MC13783_TS_NAME "mc13783-ts" | ||
24 | |||
25 | #define DEFAULT_SAMPLE_TOLERANCE 300 | ||
26 | |||
27 | static unsigned int sample_tolerance = DEFAULT_SAMPLE_TOLERANCE; | ||
28 | module_param(sample_tolerance, uint, S_IRUGO | S_IWUSR); | ||
29 | MODULE_PARM_DESC(sample_tolerance, | ||
30 | "If the minimal and maximal value read out for one axis (out " | ||
31 | "of three) differ by this value (default: " | ||
32 | __stringify(DEFAULT_SAMPLE_TOLERANCE) ") or more, the reading " | ||
33 | "is supposed to be wrong and is discarded. Set to 0 to " | ||
34 | "disable this check."); | ||
35 | |||
36 | struct mc13783_ts_priv { | ||
37 | struct input_dev *idev; | ||
38 | struct mc13783 *mc13783; | ||
39 | struct delayed_work work; | ||
40 | struct workqueue_struct *workq; | ||
41 | unsigned int sample[4]; | ||
42 | }; | ||
43 | |||
44 | static irqreturn_t mc13783_ts_handler(int irq, void *data) | ||
45 | { | ||
46 | struct mc13783_ts_priv *priv = data; | ||
47 | |||
48 | mc13783_irq_ack(priv->mc13783, irq); | ||
49 | |||
50 | /* | ||
51 | * Kick off reading coordinates. Note that if work happens already | ||
52 | * be queued for future execution (it rearms itself) it will not | ||
53 | * be rescheduled for immediate execution here. However the rearm | ||
54 | * delay is HZ / 50 which is acceptable. | ||
55 | */ | ||
56 | queue_delayed_work(priv->workq, &priv->work, 0); | ||
57 | |||
58 | return IRQ_HANDLED; | ||
59 | } | ||
60 | |||
61 | #define sort3(a0, a1, a2) ({ \ | ||
62 | if (a0 > a1) \ | ||
63 | swap(a0, a1); \ | ||
64 | if (a1 > a2) \ | ||
65 | swap(a1, a2); \ | ||
66 | if (a0 > a1) \ | ||
67 | swap(a0, a1); \ | ||
68 | }) | ||
69 | |||
70 | static void mc13783_ts_report_sample(struct mc13783_ts_priv *priv) | ||
71 | { | ||
72 | struct input_dev *idev = priv->idev; | ||
73 | int x0, x1, x2, y0, y1, y2; | ||
74 | int cr0, cr1; | ||
75 | |||
76 | /* | ||
77 | * the values are 10-bit wide only, but the two least significant | ||
78 | * bits are for future 12 bit use and reading yields 0 | ||
79 | */ | ||
80 | x0 = priv->sample[0] & 0xfff; | ||
81 | x1 = priv->sample[1] & 0xfff; | ||
82 | x2 = priv->sample[2] & 0xfff; | ||
83 | y0 = priv->sample[3] & 0xfff; | ||
84 | y1 = (priv->sample[0] >> 12) & 0xfff; | ||
85 | y2 = (priv->sample[1] >> 12) & 0xfff; | ||
86 | cr0 = (priv->sample[2] >> 12) & 0xfff; | ||
87 | cr1 = (priv->sample[3] >> 12) & 0xfff; | ||
88 | |||
89 | dev_dbg(&idev->dev, | ||
90 | "x: (% 4d,% 4d,% 4d) y: (% 4d, % 4d,% 4d) cr: (% 4d, % 4d)\n", | ||
91 | x0, x1, x2, y0, y1, y2, cr0, cr1); | ||
92 | |||
93 | sort3(x0, x1, x2); | ||
94 | sort3(y0, y1, y2); | ||
95 | |||
96 | cr0 = (cr0 + cr1) / 2; | ||
97 | |||
98 | if (!cr0 || !sample_tolerance || | ||
99 | (x2 - x0 < sample_tolerance && | ||
100 | y2 - y0 < sample_tolerance)) { | ||
101 | /* report the median coordinate and average pressure */ | ||
102 | if (cr0) { | ||
103 | input_report_abs(idev, ABS_X, x1); | ||
104 | input_report_abs(idev, ABS_Y, y1); | ||
105 | |||
106 | dev_dbg(&idev->dev, "report (%d, %d, %d)\n", | ||
107 | x1, y1, 0x1000 - cr0); | ||
108 | queue_delayed_work(priv->workq, &priv->work, HZ / 50); | ||
109 | } else | ||
110 | dev_dbg(&idev->dev, "report release\n"); | ||
111 | |||
112 | input_report_abs(idev, ABS_PRESSURE, | ||
113 | cr0 ? 0x1000 - cr0 : cr0); | ||
114 | input_report_key(idev, BTN_TOUCH, cr0); | ||
115 | input_sync(idev); | ||
116 | } else | ||
117 | dev_dbg(&idev->dev, "discard event\n"); | ||
118 | } | ||
119 | |||
120 | static void mc13783_ts_work(struct work_struct *work) | ||
121 | { | ||
122 | struct mc13783_ts_priv *priv = | ||
123 | container_of(work, struct mc13783_ts_priv, work.work); | ||
124 | unsigned int mode = MC13783_ADC_MODE_TS; | ||
125 | unsigned int channel = 12; | ||
126 | |||
127 | if (mc13783_adc_do_conversion(priv->mc13783, | ||
128 | mode, channel, priv->sample) == 0) | ||
129 | mc13783_ts_report_sample(priv); | ||
130 | } | ||
131 | |||
132 | static int mc13783_ts_open(struct input_dev *dev) | ||
133 | { | ||
134 | struct mc13783_ts_priv *priv = input_get_drvdata(dev); | ||
135 | int ret; | ||
136 | |||
137 | mc13783_lock(priv->mc13783); | ||
138 | |||
139 | mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS); | ||
140 | |||
141 | ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS, | ||
142 | mc13783_ts_handler, MC13783_TS_NAME, priv); | ||
143 | if (ret) | ||
144 | goto out; | ||
145 | |||
146 | ret = mc13783_reg_rmw(priv->mc13783, MC13783_ADC0, | ||
147 | MC13783_ADC0_TSMOD_MASK, MC13783_ADC0_TSMOD0); | ||
148 | if (ret) | ||
149 | mc13783_irq_free(priv->mc13783, MC13783_IRQ_TS, priv); | ||
150 | out: | ||
151 | mc13783_unlock(priv->mc13783); | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | static void mc13783_ts_close(struct input_dev *dev) | ||
156 | { | ||
157 | struct mc13783_ts_priv *priv = input_get_drvdata(dev); | ||
158 | |||
159 | mc13783_lock(priv->mc13783); | ||
160 | mc13783_reg_rmw(priv->mc13783, MC13783_ADC0, | ||
161 | MC13783_ADC0_TSMOD_MASK, 0); | ||
162 | mc13783_irq_free(priv->mc13783, MC13783_IRQ_TS, priv); | ||
163 | mc13783_unlock(priv->mc13783); | ||
164 | |||
165 | cancel_delayed_work_sync(&priv->work); | ||
166 | } | ||
167 | |||
168 | static int __init mc13783_ts_probe(struct platform_device *pdev) | ||
169 | { | ||
170 | struct mc13783_ts_priv *priv; | ||
171 | struct input_dev *idev; | ||
172 | int ret = -ENOMEM; | ||
173 | |||
174 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
175 | idev = input_allocate_device(); | ||
176 | if (!priv || !idev) | ||
177 | goto err_free_mem; | ||
178 | |||
179 | INIT_DELAYED_WORK(&priv->work, mc13783_ts_work); | ||
180 | priv->mc13783 = dev_get_drvdata(pdev->dev.parent); | ||
181 | priv->idev = idev; | ||
182 | |||
183 | /* | ||
184 | * We need separate workqueue because mc13783_adc_do_conversion | ||
185 | * uses keventd and thus would deadlock. | ||
186 | */ | ||
187 | priv->workq = create_singlethread_workqueue("mc13783_ts"); | ||
188 | if (!priv->workq) | ||
189 | goto err_free_mem; | ||
190 | |||
191 | idev->name = MC13783_TS_NAME; | ||
192 | idev->dev.parent = &pdev->dev; | ||
193 | |||
194 | idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
195 | idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
196 | input_set_abs_params(idev, ABS_X, 0, 0xfff, 0, 0); | ||
197 | input_set_abs_params(idev, ABS_Y, 0, 0xfff, 0, 0); | ||
198 | input_set_abs_params(idev, ABS_PRESSURE, 0, 0xfff, 0, 0); | ||
199 | |||
200 | idev->open = mc13783_ts_open; | ||
201 | idev->close = mc13783_ts_close; | ||
202 | |||
203 | input_set_drvdata(idev, priv); | ||
204 | |||
205 | ret = input_register_device(priv->idev); | ||
206 | if (ret) { | ||
207 | dev_err(&pdev->dev, | ||
208 | "register input device failed with %d\n", ret); | ||
209 | goto err_destroy_wq; | ||
210 | } | ||
211 | |||
212 | platform_set_drvdata(pdev, priv); | ||
213 | return 0; | ||
214 | |||
215 | err_destroy_wq: | ||
216 | destroy_workqueue(priv->workq); | ||
217 | err_free_mem: | ||
218 | input_free_device(idev); | ||
219 | kfree(priv); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int __devexit mc13783_ts_remove(struct platform_device *pdev) | ||
224 | { | ||
225 | struct mc13783_ts_priv *priv = platform_get_drvdata(pdev); | ||
226 | |||
227 | platform_set_drvdata(pdev, NULL); | ||
228 | |||
229 | destroy_workqueue(priv->workq); | ||
230 | input_unregister_device(priv->idev); | ||
231 | kfree(priv); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct platform_driver mc13783_ts_driver = { | ||
237 | .remove = __devexit_p(mc13783_ts_remove), | ||
238 | .driver = { | ||
239 | .owner = THIS_MODULE, | ||
240 | .name = MC13783_TS_NAME, | ||
241 | }, | ||
242 | }; | ||
243 | |||
244 | static int __init mc13783_ts_init(void) | ||
245 | { | ||
246 | return platform_driver_probe(&mc13783_ts_driver, &mc13783_ts_probe); | ||
247 | } | ||
248 | module_init(mc13783_ts_init); | ||
249 | |||
250 | static void __exit mc13783_ts_exit(void) | ||
251 | { | ||
252 | platform_driver_unregister(&mc13783_ts_driver); | ||
253 | } | ||
254 | module_exit(mc13783_ts_exit); | ||
255 | |||
256 | MODULE_DESCRIPTION("MC13783 input touchscreen driver"); | ||
257 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
258 | MODULE_LICENSE("GPL v2"); | ||
259 | MODULE_ALIAS("platform:" MC13783_TS_NAME); | ||
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 4c28b89757f9..ce8ab0269f6f 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/input.h> | 21 | #include <linux/input.h> |
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/slab.h> | ||
23 | 24 | ||
24 | /* Registers */ | 25 | /* Registers */ |
25 | #define MCS5000_TS_STATUS 0x00 | 26 | #define MCS5000_TS_STATUS 0x00 |
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index 141dd584330e..defe5dd3627c 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/slab.h> | ||
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
27 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
28 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c index 67fcd33595de..ea6ef16e59b4 100644 --- a/drivers/input/touchscreen/pcap_ts.c +++ b/drivers/input/touchscreen/pcap_ts.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
18 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
19 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
@@ -233,7 +234,7 @@ static int pcap_ts_resume(struct device *dev) | |||
233 | return 0; | 234 | return 0; |
234 | } | 235 | } |
235 | 236 | ||
236 | static struct dev_pm_ops pcap_ts_pm_ops = { | 237 | static const struct dev_pm_ops pcap_ts_pm_ops = { |
237 | .suspend = pcap_ts_suspend, | 238 | .suspend = pcap_ts_suspend, |
238 | .resume = pcap_ts_resume, | 239 | .resume = pcap_ts_resume, |
239 | }; | 240 | }; |
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c new file mode 100644 index 000000000000..98a7d1279486 --- /dev/null +++ b/drivers/input/touchscreen/s3c2410_ts.c | |||
@@ -0,0 +1,459 @@ | |||
1 | /* | ||
2 | * Samsung S3C24XX touchscreen driver | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the term of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | * Copyright 2004 Arnaud Patard <arnaud.patard@rtp-net.org> | ||
19 | * Copyright 2008 Ben Dooks <ben-linux@fluff.org> | ||
20 | * Copyright 2009 Simtec Electronics <linux@simtec.co.uk> | ||
21 | * | ||
22 | * Additional work by Herbert Pötzl <herbert@13thfloor.at> and | ||
23 | * Harald Welte <laforge@openmoko.org> | ||
24 | */ | ||
25 | |||
26 | #include <linux/errno.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/platform_device.h> | ||
35 | #include <linux/clk.h> | ||
36 | #include <linux/io.h> | ||
37 | |||
38 | #include <plat/adc.h> | ||
39 | #include <plat/regs-adc.h> | ||
40 | |||
41 | #include <mach/regs-gpio.h> | ||
42 | #include <mach/ts.h> | ||
43 | |||
44 | #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) | ||
45 | |||
46 | #define INT_DOWN (0) | ||
47 | #define INT_UP (1 << 8) | ||
48 | |||
49 | #define WAIT4INT (S3C2410_ADCTSC_YM_SEN | \ | ||
50 | S3C2410_ADCTSC_YP_SEN | \ | ||
51 | S3C2410_ADCTSC_XP_SEN | \ | ||
52 | S3C2410_ADCTSC_XY_PST(3)) | ||
53 | |||
54 | #define AUTOPST (S3C2410_ADCTSC_YM_SEN | \ | ||
55 | S3C2410_ADCTSC_YP_SEN | \ | ||
56 | S3C2410_ADCTSC_XP_SEN | \ | ||
57 | S3C2410_ADCTSC_AUTO_PST | \ | ||
58 | S3C2410_ADCTSC_XY_PST(0)) | ||
59 | |||
60 | /* Per-touchscreen data. */ | ||
61 | |||
62 | /** | ||
63 | * struct s3c2410ts - driver touchscreen state. | ||
64 | * @client: The ADC client we registered with the core driver. | ||
65 | * @dev: The device we are bound to. | ||
66 | * @input: The input device we registered with the input subsystem. | ||
67 | * @clock: The clock for the adc. | ||
68 | * @io: Pointer to the IO base. | ||
69 | * @xp: The accumulated X position data. | ||
70 | * @yp: The accumulated Y position data. | ||
71 | * @irq_tc: The interrupt number for pen up/down interrupt | ||
72 | * @count: The number of samples collected. | ||
73 | * @shift: The log2 of the maximum count to read in one go. | ||
74 | */ | ||
75 | struct s3c2410ts { | ||
76 | struct s3c_adc_client *client; | ||
77 | struct device *dev; | ||
78 | struct input_dev *input; | ||
79 | struct clk *clock; | ||
80 | void __iomem *io; | ||
81 | unsigned long xp; | ||
82 | unsigned long yp; | ||
83 | int irq_tc; | ||
84 | int count; | ||
85 | int shift; | ||
86 | }; | ||
87 | |||
88 | static struct s3c2410ts ts; | ||
89 | |||
90 | /** | ||
91 | * s3c2410_ts_connect - configure gpio for s3c2410 systems | ||
92 | * | ||
93 | * Configure the GPIO for the S3C2410 system, where we have external FETs | ||
94 | * connected to the device (later systems such as the S3C2440 integrate | ||
95 | * these into the device). | ||
96 | */ | ||
97 | static inline void s3c2410_ts_connect(void) | ||
98 | { | ||
99 | s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON); | ||
100 | s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON); | ||
101 | s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON); | ||
102 | s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON); | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * get_down - return the down state of the pen | ||
107 | * @data0: The data read from ADCDAT0 register. | ||
108 | * @data1: The data read from ADCDAT1 register. | ||
109 | * | ||
110 | * Return non-zero if both readings show that the pen is down. | ||
111 | */ | ||
112 | static inline bool get_down(unsigned long data0, unsigned long data1) | ||
113 | { | ||
114 | /* returns true if both data values show stylus down */ | ||
115 | return (!(data0 & S3C2410_ADCDAT0_UPDOWN) && | ||
116 | !(data1 & S3C2410_ADCDAT0_UPDOWN)); | ||
117 | } | ||
118 | |||
119 | static void touch_timer_fire(unsigned long data) | ||
120 | { | ||
121 | unsigned long data0; | ||
122 | unsigned long data1; | ||
123 | bool down; | ||
124 | |||
125 | data0 = readl(ts.io + S3C2410_ADCDAT0); | ||
126 | data1 = readl(ts.io + S3C2410_ADCDAT1); | ||
127 | |||
128 | down = get_down(data0, data1); | ||
129 | |||
130 | if (down) { | ||
131 | if (ts.count == (1 << ts.shift)) { | ||
132 | ts.xp >>= ts.shift; | ||
133 | ts.yp >>= ts.shift; | ||
134 | |||
135 | dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n", | ||
136 | __func__, ts.xp, ts.yp, ts.count); | ||
137 | |||
138 | input_report_abs(ts.input, ABS_X, ts.xp); | ||
139 | input_report_abs(ts.input, ABS_Y, ts.yp); | ||
140 | |||
141 | input_report_key(ts.input, BTN_TOUCH, 1); | ||
142 | input_sync(ts.input); | ||
143 | |||
144 | ts.xp = 0; | ||
145 | ts.yp = 0; | ||
146 | ts.count = 0; | ||
147 | } | ||
148 | |||
149 | s3c_adc_start(ts.client, 0, 1 << ts.shift); | ||
150 | } else { | ||
151 | ts.xp = 0; | ||
152 | ts.yp = 0; | ||
153 | ts.count = 0; | ||
154 | |||
155 | input_report_key(ts.input, BTN_TOUCH, 0); | ||
156 | input_sync(ts.input); | ||
157 | |||
158 | writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static DEFINE_TIMER(touch_timer, touch_timer_fire, 0, 0); | ||
163 | |||
164 | /** | ||
165 | * stylus_irq - touchscreen stylus event interrupt | ||
166 | * @irq: The interrupt number | ||
167 | * @dev_id: The device ID. | ||
168 | * | ||
169 | * Called when the IRQ_TC is fired for a pen up or down event. | ||
170 | */ | ||
171 | static irqreturn_t stylus_irq(int irq, void *dev_id) | ||
172 | { | ||
173 | unsigned long data0; | ||
174 | unsigned long data1; | ||
175 | bool down; | ||
176 | |||
177 | data0 = readl(ts.io + S3C2410_ADCDAT0); | ||
178 | data1 = readl(ts.io + S3C2410_ADCDAT1); | ||
179 | |||
180 | down = get_down(data0, data1); | ||
181 | |||
182 | /* TODO we should never get an interrupt with down set while | ||
183 | * the timer is running, but maybe we ought to verify that the | ||
184 | * timer isn't running anyways. */ | ||
185 | |||
186 | if (down) | ||
187 | s3c_adc_start(ts.client, 0, 1 << ts.shift); | ||
188 | else | ||
189 | dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count); | ||
190 | |||
191 | return IRQ_HANDLED; | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * s3c24xx_ts_conversion - ADC conversion callback | ||
196 | * @client: The client that was registered with the ADC core. | ||
197 | * @data0: The reading from ADCDAT0. | ||
198 | * @data1: The reading from ADCDAT1. | ||
199 | * @left: The number of samples left. | ||
200 | * | ||
201 | * Called when a conversion has finished. | ||
202 | */ | ||
203 | static void s3c24xx_ts_conversion(struct s3c_adc_client *client, | ||
204 | unsigned data0, unsigned data1, | ||
205 | unsigned *left) | ||
206 | { | ||
207 | dev_dbg(ts.dev, "%s: %d,%d\n", __func__, data0, data1); | ||
208 | |||
209 | ts.xp += data0; | ||
210 | ts.yp += data1; | ||
211 | |||
212 | ts.count++; | ||
213 | |||
214 | /* From tests, it seems that it is unlikely to get a pen-up | ||
215 | * event during the conversion process which means we can | ||
216 | * ignore any pen-up events with less than the requisite | ||
217 | * count done. | ||
218 | * | ||
219 | * In several thousand conversions, no pen-ups where detected | ||
220 | * before count completed. | ||
221 | */ | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * s3c24xx_ts_select - ADC selection callback. | ||
226 | * @client: The client that was registered with the ADC core. | ||
227 | * @select: The reason for select. | ||
228 | * | ||
229 | * Called when the ADC core selects (or deslects) us as a client. | ||
230 | */ | ||
231 | static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select) | ||
232 | { | ||
233 | if (select) { | ||
234 | writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, | ||
235 | ts.io + S3C2410_ADCTSC); | ||
236 | } else { | ||
237 | mod_timer(&touch_timer, jiffies+1); | ||
238 | writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC); | ||
239 | } | ||
240 | } | ||
241 | |||
242 | /** | ||
243 | * s3c2410ts_probe - device core probe entry point | ||
244 | * @pdev: The device we are being bound to. | ||
245 | * | ||
246 | * Initialise, find and allocate any resources we need to run and then | ||
247 | * register with the ADC and input systems. | ||
248 | */ | ||
249 | static int __devinit s3c2410ts_probe(struct platform_device *pdev) | ||
250 | { | ||
251 | struct s3c2410_ts_mach_info *info; | ||
252 | struct device *dev = &pdev->dev; | ||
253 | struct input_dev *input_dev; | ||
254 | struct resource *res; | ||
255 | int ret = -EINVAL; | ||
256 | |||
257 | /* Initialise input stuff */ | ||
258 | memset(&ts, 0, sizeof(struct s3c2410ts)); | ||
259 | |||
260 | ts.dev = dev; | ||
261 | |||
262 | info = pdev->dev.platform_data; | ||
263 | if (!info) { | ||
264 | dev_err(dev, "no platform data, cannot attach\n"); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | |||
268 | dev_dbg(dev, "initialising touchscreen\n"); | ||
269 | |||
270 | ts.clock = clk_get(dev, "adc"); | ||
271 | if (IS_ERR(ts.clock)) { | ||
272 | dev_err(dev, "cannot get adc clock source\n"); | ||
273 | return -ENOENT; | ||
274 | } | ||
275 | |||
276 | clk_enable(ts.clock); | ||
277 | dev_dbg(dev, "got and enabled clocks\n"); | ||
278 | |||
279 | ts.irq_tc = ret = platform_get_irq(pdev, 0); | ||
280 | if (ret < 0) { | ||
281 | dev_err(dev, "no resource for interrupt\n"); | ||
282 | goto err_clk; | ||
283 | } | ||
284 | |||
285 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
286 | if (!res) { | ||
287 | dev_err(dev, "no resource for registers\n"); | ||
288 | ret = -ENOENT; | ||
289 | goto err_clk; | ||
290 | } | ||
291 | |||
292 | ts.io = ioremap(res->start, resource_size(res)); | ||
293 | if (ts.io == NULL) { | ||
294 | dev_err(dev, "cannot map registers\n"); | ||
295 | ret = -ENOMEM; | ||
296 | goto err_clk; | ||
297 | } | ||
298 | |||
299 | /* Configure the touchscreen external FETs on the S3C2410 */ | ||
300 | if (!platform_get_device_id(pdev)->driver_data) | ||
301 | s3c2410_ts_connect(); | ||
302 | |||
303 | ts.client = s3c_adc_register(pdev, s3c24xx_ts_select, | ||
304 | s3c24xx_ts_conversion, 1); | ||
305 | if (IS_ERR(ts.client)) { | ||
306 | dev_err(dev, "failed to register adc client\n"); | ||
307 | ret = PTR_ERR(ts.client); | ||
308 | goto err_iomap; | ||
309 | } | ||
310 | |||
311 | /* Initialise registers */ | ||
312 | if ((info->delay & 0xffff) > 0) | ||
313 | writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY); | ||
314 | |||
315 | writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); | ||
316 | |||
317 | input_dev = input_allocate_device(); | ||
318 | if (!input_dev) { | ||
319 | dev_err(dev, "Unable to allocate the input device !!\n"); | ||
320 | ret = -ENOMEM; | ||
321 | goto err_iomap; | ||
322 | } | ||
323 | |||
324 | ts.input = input_dev; | ||
325 | ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
326 | ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
327 | input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0); | ||
328 | input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0); | ||
329 | |||
330 | ts.input->name = "S3C24XX TouchScreen"; | ||
331 | ts.input->id.bustype = BUS_HOST; | ||
332 | ts.input->id.vendor = 0xDEAD; | ||
333 | ts.input->id.product = 0xBEEF; | ||
334 | ts.input->id.version = 0x0102; | ||
335 | |||
336 | ts.shift = info->oversampling_shift; | ||
337 | |||
338 | ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED, | ||
339 | "s3c2410_ts_pen", ts.input); | ||
340 | if (ret) { | ||
341 | dev_err(dev, "cannot get TC interrupt\n"); | ||
342 | goto err_inputdev; | ||
343 | } | ||
344 | |||
345 | dev_info(dev, "driver attached, registering input device\n"); | ||
346 | |||
347 | /* All went ok, so register to the input system */ | ||
348 | ret = input_register_device(ts.input); | ||
349 | if (ret < 0) { | ||
350 | dev_err(dev, "failed to register input device\n"); | ||
351 | ret = -EIO; | ||
352 | goto err_tcirq; | ||
353 | } | ||
354 | |||
355 | return 0; | ||
356 | |||
357 | err_tcirq: | ||
358 | free_irq(ts.irq_tc, ts.input); | ||
359 | err_inputdev: | ||
360 | input_unregister_device(ts.input); | ||
361 | err_iomap: | ||
362 | iounmap(ts.io); | ||
363 | err_clk: | ||
364 | del_timer_sync(&touch_timer); | ||
365 | clk_put(ts.clock); | ||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | /** | ||
370 | * s3c2410ts_remove - device core removal entry point | ||
371 | * @pdev: The device we are being removed from. | ||
372 | * | ||
373 | * Free up our state ready to be removed. | ||
374 | */ | ||
375 | static int __devexit s3c2410ts_remove(struct platform_device *pdev) | ||
376 | { | ||
377 | free_irq(ts.irq_tc, ts.input); | ||
378 | del_timer_sync(&touch_timer); | ||
379 | |||
380 | clk_disable(ts.clock); | ||
381 | clk_put(ts.clock); | ||
382 | |||
383 | input_unregister_device(ts.input); | ||
384 | iounmap(ts.io); | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | #ifdef CONFIG_PM | ||
390 | static int s3c2410ts_suspend(struct device *dev) | ||
391 | { | ||
392 | writel(TSC_SLEEP, ts.io + S3C2410_ADCTSC); | ||
393 | disable_irq(ts.irq_tc); | ||
394 | clk_disable(ts.clock); | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static int s3c2410ts_resume(struct device *dev) | ||
400 | { | ||
401 | struct platform_device *pdev = to_platform_device(dev); | ||
402 | struct s3c2410_ts_mach_info *info = pdev->dev.platform_data; | ||
403 | |||
404 | clk_enable(ts.clock); | ||
405 | enable_irq(ts.irq_tc); | ||
406 | |||
407 | /* Initialise registers */ | ||
408 | if ((info->delay & 0xffff) > 0) | ||
409 | writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY); | ||
410 | |||
411 | writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static struct dev_pm_ops s3c_ts_pmops = { | ||
417 | .suspend = s3c2410ts_suspend, | ||
418 | .resume = s3c2410ts_resume, | ||
419 | }; | ||
420 | #endif | ||
421 | |||
422 | static struct platform_device_id s3cts_driver_ids[] = { | ||
423 | { "s3c2410-ts", 0 }, | ||
424 | { "s3c2440-ts", 1 }, | ||
425 | { } | ||
426 | }; | ||
427 | MODULE_DEVICE_TABLE(platform, s3cts_driver_ids); | ||
428 | |||
429 | static struct platform_driver s3c_ts_driver = { | ||
430 | .driver = { | ||
431 | .name = "s3c24xx-ts", | ||
432 | .owner = THIS_MODULE, | ||
433 | #ifdef CONFIG_PM | ||
434 | .pm = &s3c_ts_pmops, | ||
435 | #endif | ||
436 | }, | ||
437 | .id_table = s3cts_driver_ids, | ||
438 | .probe = s3c2410ts_probe, | ||
439 | .remove = __devexit_p(s3c2410ts_remove), | ||
440 | }; | ||
441 | |||
442 | static int __init s3c2410ts_init(void) | ||
443 | { | ||
444 | return platform_driver_register(&s3c_ts_driver); | ||
445 | } | ||
446 | |||
447 | static void __exit s3c2410ts_exit(void) | ||
448 | { | ||
449 | platform_driver_unregister(&s3c_ts_driver); | ||
450 | } | ||
451 | |||
452 | module_init(s3c2410ts_init); | ||
453 | module_exit(s3c2410ts_exit); | ||
454 | |||
455 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, " | ||
456 | "Ben Dooks <ben@simtec.co.uk>, " | ||
457 | "Simtec Electronics <linux@simtec.co.uk>"); | ||
458 | MODULE_DESCRIPTION("S3C24XX Touchscreen driver"); | ||
459 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 7ef0d1420d3c..be23780e8a3e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c | |||
@@ -358,7 +358,7 @@ static int __devexit tsc2007_remove(struct i2c_client *client) | |||
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
360 | 360 | ||
361 | static struct i2c_device_id tsc2007_idtable[] = { | 361 | static const struct i2c_device_id tsc2007_idtable[] = { |
362 | { "tsc2007", 0 }, | 362 | { "tsc2007", 0 }, |
363 | { } | 363 | { } |
364 | }; | 364 | }; |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 095f84b1f56e..028a5363eea1 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/suspend.h> | 28 | #include <linux/suspend.h> |
29 | #include <linux/slab.h> | ||
30 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
31 | #include <linux/freezer.h> | 30 | #include <linux/freezer.h> |
32 | #include <linux/ucb1400.h> | 31 | #include <linux/ucb1400.h> |
@@ -355,10 +354,13 @@ static int ucb1400_ts_probe(struct platform_device *dev) | |||
355 | goto err; | 354 | goto err; |
356 | } | 355 | } |
357 | 356 | ||
358 | error = ucb1400_ts_detect_irq(ucb); | 357 | /* Only in case the IRQ line wasn't supplied, try detecting it */ |
359 | if (error) { | 358 | if (ucb->irq < 0) { |
360 | printk(KERN_ERR "UCB1400: IRQ probe failed\n"); | 359 | error = ucb1400_ts_detect_irq(ucb); |
361 | goto err_free_devs; | 360 | if (error) { |
361 | printk(KERN_ERR "UCB1400: IRQ probe failed\n"); | ||
362 | goto err_free_devs; | ||
363 | } | ||
362 | } | 364 | } |
363 | 365 | ||
364 | init_waitqueue_head(&ucb->ts_wait); | 366 | init_waitqueue_head(&ucb->ts_wait); |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 68ece5801a58..99330bbdbac7 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -14,6 +14,8 @@ | |||
14 | * - General Touch | 14 | * - General Touch |
15 | * - GoTop Super_Q2/GogoPen/PenPower tablets | 15 | * - GoTop Super_Q2/GogoPen/PenPower tablets |
16 | * - JASTEC USB touch controller/DigiTech DTR-02U | 16 | * - JASTEC USB touch controller/DigiTech DTR-02U |
17 | * - Zytronic capacitive touchscreen | ||
18 | * - NEXIO/iNexio | ||
17 | * | 19 | * |
18 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> | 20 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> |
19 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | 21 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) |
@@ -73,6 +75,15 @@ struct usbtouch_device_info { | |||
73 | int min_press, max_press; | 75 | int min_press, max_press; |
74 | int rept_size; | 76 | int rept_size; |
75 | 77 | ||
78 | /* | ||
79 | * Always service the USB devices irq not just when the input device is | ||
80 | * open. This is useful when devices have a watchdog which prevents us | ||
81 | * from periodically polling the device. Leave this unset unless your | ||
82 | * touchscreen device requires it, as it does consume more of the USB | ||
83 | * bandwidth. | ||
84 | */ | ||
85 | bool irq_always; | ||
86 | |||
76 | void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); | 87 | void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); |
77 | 88 | ||
78 | /* | 89 | /* |
@@ -85,6 +96,7 @@ struct usbtouch_device_info { | |||
85 | 96 | ||
86 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); | 97 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); |
87 | int (*init) (struct usbtouch_usb *usbtouch); | 98 | int (*init) (struct usbtouch_usb *usbtouch); |
99 | void (*exit) (struct usbtouch_usb *usbtouch); | ||
88 | }; | 100 | }; |
89 | 101 | ||
90 | /* a usbtouch device */ | 102 | /* a usbtouch device */ |
@@ -94,11 +106,12 @@ struct usbtouch_usb { | |||
94 | unsigned char *buffer; | 106 | unsigned char *buffer; |
95 | int buf_len; | 107 | int buf_len; |
96 | struct urb *irq; | 108 | struct urb *irq; |
97 | struct usb_device *udev; | 109 | struct usb_interface *interface; |
98 | struct input_dev *input; | 110 | struct input_dev *input; |
99 | struct usbtouch_device_info *type; | 111 | struct usbtouch_device_info *type; |
100 | char name[128]; | 112 | char name[128]; |
101 | char phys[64]; | 113 | char phys[64]; |
114 | void *priv; | ||
102 | 115 | ||
103 | int x, y; | 116 | int x, y; |
104 | int touch, press; | 117 | int touch, press; |
@@ -121,6 +134,9 @@ enum { | |||
121 | DEVTYPE_GOTOP, | 134 | DEVTYPE_GOTOP, |
122 | DEVTYPE_JASTEC, | 135 | DEVTYPE_JASTEC, |
123 | DEVTYPE_E2I, | 136 | DEVTYPE_E2I, |
137 | DEVTYPE_ZYTRONIC, | ||
138 | DEVTYPE_TC5UH, | ||
139 | DEVTYPE_NEXIO, | ||
124 | }; | 140 | }; |
125 | 141 | ||
126 | #define USB_DEVICE_HID_CLASS(vend, prod) \ | 142 | #define USB_DEVICE_HID_CLASS(vend, prod) \ |
@@ -132,7 +148,7 @@ enum { | |||
132 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ | 148 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ |
133 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE | 149 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE |
134 | 150 | ||
135 | static struct usb_device_id usbtouch_devices[] = { | 151 | static const struct usb_device_id usbtouch_devices[] = { |
136 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX | 152 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX |
137 | /* ignore the HID capable devices, handled by usbhid */ | 153 | /* ignore the HID capable devices, handled by usbhid */ |
138 | {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, | 154 | {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, |
@@ -201,6 +217,23 @@ static struct usb_device_id usbtouch_devices[] = { | |||
201 | #ifdef CONFIG_TOUCHSCREEN_USB_E2I | 217 | #ifdef CONFIG_TOUCHSCREEN_USB_E2I |
202 | {USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I}, | 218 | {USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I}, |
203 | #endif | 219 | #endif |
220 | |||
221 | #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC | ||
222 | {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC}, | ||
223 | #endif | ||
224 | |||
225 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | ||
226 | {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, | ||
227 | #endif | ||
228 | |||
229 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
230 | /* data interface only */ | ||
231 | {USB_DEVICE_AND_INTERFACE_INFO(0x10f0, 0x2002, 0x0a, 0x00, 0x00), | ||
232 | .driver_info = DEVTYPE_NEXIO}, | ||
233 | {USB_DEVICE_AND_INTERFACE_INFO(0x1870, 0x0001, 0x0a, 0x00, 0x00), | ||
234 | .driver_info = DEVTYPE_NEXIO}, | ||
235 | #endif | ||
236 | |||
204 | {} | 237 | {} |
205 | }; | 238 | }; |
206 | 239 | ||
@@ -213,8 +246,9 @@ static struct usb_device_id usbtouch_devices[] = { | |||
213 | static int e2i_init(struct usbtouch_usb *usbtouch) | 246 | static int e2i_init(struct usbtouch_usb *usbtouch) |
214 | { | 247 | { |
215 | int ret; | 248 | int ret; |
249 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
216 | 250 | ||
217 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 251 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
218 | 0x01, 0x02, 0x0000, 0x0081, | 252 | 0x01, 0x02, 0x0000, 0x0081, |
219 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 253 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
220 | 254 | ||
@@ -323,8 +357,9 @@ static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
323 | static int mtouch_init(struct usbtouch_usb *usbtouch) | 357 | static int mtouch_init(struct usbtouch_usb *usbtouch) |
324 | { | 358 | { |
325 | int ret, i; | 359 | int ret, i; |
360 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
326 | 361 | ||
327 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 362 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
328 | MTOUCHUSB_RESET, | 363 | MTOUCHUSB_RESET, |
329 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 364 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
330 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | 365 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
@@ -335,7 +370,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
335 | msleep(150); | 370 | msleep(150); |
336 | 371 | ||
337 | for (i = 0; i < 3; i++) { | 372 | for (i = 0; i < 3; i++) { |
338 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 373 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
339 | MTOUCHUSB_ASYNC_REPORT, | 374 | MTOUCHUSB_ASYNC_REPORT, |
340 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 375 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
341 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); | 376 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); |
@@ -468,7 +503,7 @@ static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
468 | 503 | ||
469 | static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) | 504 | static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) |
470 | { | 505 | { |
471 | struct usb_device *dev = usbtouch->udev; | 506 | struct usb_device *dev = interface_to_usbdev(usbtouch->interface); |
472 | int ret = -ENOMEM; | 507 | int ret = -ENOMEM; |
473 | unsigned char *buf; | 508 | unsigned char *buf; |
474 | 509 | ||
@@ -538,6 +573,19 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
538 | } | 573 | } |
539 | #endif | 574 | #endif |
540 | 575 | ||
576 | /***************************************************************************** | ||
577 | * ET&T TC5UH part | ||
578 | */ | ||
579 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | ||
580 | static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | ||
581 | { | ||
582 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; | ||
583 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; | ||
584 | dev->touch = pkt[0] & 0x01; | ||
585 | |||
586 | return 1; | ||
587 | } | ||
588 | #endif | ||
541 | 589 | ||
542 | /***************************************************************************** | 590 | /***************************************************************************** |
543 | * IdealTEK URTC1000 Part | 591 | * IdealTEK URTC1000 Part |
@@ -584,8 +632,8 @@ static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
584 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH | 632 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH |
585 | static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 633 | static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
586 | { | 634 | { |
587 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1] ; | 635 | dev->x = (pkt[2] << 8) | pkt[1]; |
588 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3] ; | 636 | dev->y = (pkt[4] << 8) | pkt[3]; |
589 | dev->press = pkt[5] & 0xff; | 637 | dev->press = pkt[5] & 0xff; |
590 | dev->touch = pkt[0] & 0x01; | 638 | dev->touch = pkt[0] & 0x01; |
591 | 639 | ||
@@ -621,6 +669,262 @@ static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
621 | } | 669 | } |
622 | #endif | 670 | #endif |
623 | 671 | ||
672 | /***************************************************************************** | ||
673 | * Zytronic Part | ||
674 | */ | ||
675 | #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC | ||
676 | static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | ||
677 | { | ||
678 | switch (pkt[0]) { | ||
679 | case 0x3A: /* command response */ | ||
680 | dbg("%s: Command response %d", __func__, pkt[1]); | ||
681 | break; | ||
682 | |||
683 | case 0xC0: /* down */ | ||
684 | dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7); | ||
685 | dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7); | ||
686 | dev->touch = 1; | ||
687 | dbg("%s: down %d,%d", __func__, dev->x, dev->y); | ||
688 | return 1; | ||
689 | |||
690 | case 0x80: /* up */ | ||
691 | dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7); | ||
692 | dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7); | ||
693 | dev->touch = 0; | ||
694 | dbg("%s: up %d,%d", __func__, dev->x, dev->y); | ||
695 | return 1; | ||
696 | |||
697 | default: | ||
698 | dbg("%s: Unknown return %d", __func__, pkt[0]); | ||
699 | break; | ||
700 | } | ||
701 | |||
702 | return 0; | ||
703 | } | ||
704 | #endif | ||
705 | |||
706 | /***************************************************************************** | ||
707 | * NEXIO Part | ||
708 | */ | ||
709 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
710 | |||
711 | #define NEXIO_TIMEOUT 5000 | ||
712 | #define NEXIO_BUFSIZE 1024 | ||
713 | #define NEXIO_THRESHOLD 50 | ||
714 | |||
715 | struct nexio_priv { | ||
716 | struct urb *ack; | ||
717 | unsigned char *ack_buf; | ||
718 | }; | ||
719 | |||
720 | struct nexio_touch_packet { | ||
721 | u8 flags; /* 0xe1 = touch, 0xe1 = release */ | ||
722 | __be16 data_len; /* total bytes of touch data */ | ||
723 | __be16 x_len; /* bytes for X axis */ | ||
724 | __be16 y_len; /* bytes for Y axis */ | ||
725 | u8 data[]; | ||
726 | } __attribute__ ((packed)); | ||
727 | |||
728 | static unsigned char nexio_ack_pkt[2] = { 0xaa, 0x02 }; | ||
729 | static unsigned char nexio_init_pkt[4] = { 0x82, 0x04, 0x0a, 0x0f }; | ||
730 | |||
731 | static void nexio_ack_complete(struct urb *urb) | ||
732 | { | ||
733 | } | ||
734 | |||
735 | static int nexio_init(struct usbtouch_usb *usbtouch) | ||
736 | { | ||
737 | struct usb_device *dev = interface_to_usbdev(usbtouch->interface); | ||
738 | struct usb_host_interface *interface = usbtouch->interface->cur_altsetting; | ||
739 | struct nexio_priv *priv; | ||
740 | int ret = -ENOMEM; | ||
741 | int actual_len, i; | ||
742 | unsigned char *buf; | ||
743 | char *firmware_ver = NULL, *device_name = NULL; | ||
744 | int input_ep = 0, output_ep = 0; | ||
745 | |||
746 | /* find first input and output endpoint */ | ||
747 | for (i = 0; i < interface->desc.bNumEndpoints; i++) { | ||
748 | if (!input_ep && | ||
749 | usb_endpoint_dir_in(&interface->endpoint[i].desc)) | ||
750 | input_ep = interface->endpoint[i].desc.bEndpointAddress; | ||
751 | if (!output_ep && | ||
752 | usb_endpoint_dir_out(&interface->endpoint[i].desc)) | ||
753 | output_ep = interface->endpoint[i].desc.bEndpointAddress; | ||
754 | } | ||
755 | if (!input_ep || !output_ep) | ||
756 | return -ENXIO; | ||
757 | |||
758 | buf = kmalloc(NEXIO_BUFSIZE, GFP_KERNEL); | ||
759 | if (!buf) | ||
760 | goto out_buf; | ||
761 | |||
762 | /* two empty reads */ | ||
763 | for (i = 0; i < 2; i++) { | ||
764 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), | ||
765 | buf, NEXIO_BUFSIZE, &actual_len, | ||
766 | NEXIO_TIMEOUT); | ||
767 | if (ret < 0) | ||
768 | goto out_buf; | ||
769 | } | ||
770 | |||
771 | /* send init command */ | ||
772 | memcpy(buf, nexio_init_pkt, sizeof(nexio_init_pkt)); | ||
773 | ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, output_ep), | ||
774 | buf, sizeof(nexio_init_pkt), &actual_len, | ||
775 | NEXIO_TIMEOUT); | ||
776 | if (ret < 0) | ||
777 | goto out_buf; | ||
778 | |||
779 | /* read replies */ | ||
780 | for (i = 0; i < 3; i++) { | ||
781 | memset(buf, 0, NEXIO_BUFSIZE); | ||
782 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), | ||
783 | buf, NEXIO_BUFSIZE, &actual_len, | ||
784 | NEXIO_TIMEOUT); | ||
785 | if (ret < 0 || actual_len < 1 || buf[1] != actual_len) | ||
786 | continue; | ||
787 | switch (buf[0]) { | ||
788 | case 0x83: /* firmware version */ | ||
789 | if (!firmware_ver) | ||
790 | firmware_ver = kstrdup(&buf[2], GFP_KERNEL); | ||
791 | break; | ||
792 | case 0x84: /* device name */ | ||
793 | if (!device_name) | ||
794 | device_name = kstrdup(&buf[2], GFP_KERNEL); | ||
795 | break; | ||
796 | } | ||
797 | } | ||
798 | |||
799 | printk(KERN_INFO "Nexio device: %s, firmware version: %s\n", | ||
800 | device_name, firmware_ver); | ||
801 | |||
802 | kfree(firmware_ver); | ||
803 | kfree(device_name); | ||
804 | |||
805 | /* prepare ACK URB */ | ||
806 | ret = -ENOMEM; | ||
807 | |||
808 | usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL); | ||
809 | if (!usbtouch->priv) | ||
810 | goto out_buf; | ||
811 | |||
812 | priv = usbtouch->priv; | ||
813 | |||
814 | priv->ack_buf = kmalloc(sizeof(nexio_ack_pkt), GFP_KERNEL); | ||
815 | if (!priv->ack_buf) | ||
816 | goto err_priv; | ||
817 | |||
818 | memcpy(priv->ack_buf, nexio_ack_pkt, sizeof(nexio_ack_pkt)); | ||
819 | |||
820 | priv->ack = usb_alloc_urb(0, GFP_KERNEL); | ||
821 | if (!priv->ack) { | ||
822 | dbg("%s - usb_alloc_urb failed: usbtouch->ack", __func__); | ||
823 | goto err_ack_buf; | ||
824 | } | ||
825 | |||
826 | usb_fill_bulk_urb(priv->ack, dev, usb_sndbulkpipe(dev, output_ep), | ||
827 | priv->ack_buf, sizeof(nexio_ack_pkt), | ||
828 | nexio_ack_complete, usbtouch); | ||
829 | ret = 0; | ||
830 | goto out_buf; | ||
831 | |||
832 | err_ack_buf: | ||
833 | kfree(priv->ack_buf); | ||
834 | err_priv: | ||
835 | kfree(priv); | ||
836 | out_buf: | ||
837 | kfree(buf); | ||
838 | return ret; | ||
839 | } | ||
840 | |||
841 | static void nexio_exit(struct usbtouch_usb *usbtouch) | ||
842 | { | ||
843 | struct nexio_priv *priv = usbtouch->priv; | ||
844 | |||
845 | usb_kill_urb(priv->ack); | ||
846 | usb_free_urb(priv->ack); | ||
847 | kfree(priv->ack_buf); | ||
848 | kfree(priv); | ||
849 | } | ||
850 | |||
851 | static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt) | ||
852 | { | ||
853 | int x, y, begin_x, begin_y, end_x, end_y, w, h, ret; | ||
854 | struct nexio_touch_packet *packet = (void *) pkt; | ||
855 | struct nexio_priv *priv = usbtouch->priv; | ||
856 | |||
857 | /* got touch data? */ | ||
858 | if ((pkt[0] & 0xe0) != 0xe0) | ||
859 | return 0; | ||
860 | |||
861 | /* send ACK */ | ||
862 | ret = usb_submit_urb(priv->ack, GFP_ATOMIC); | ||
863 | |||
864 | if (!usbtouch->type->max_xc) { | ||
865 | usbtouch->type->max_xc = 2 * be16_to_cpu(packet->x_len); | ||
866 | input_set_abs_params(usbtouch->input, ABS_X, 0, | ||
867 | 2 * be16_to_cpu(packet->x_len), 0, 0); | ||
868 | usbtouch->type->max_yc = 2 * be16_to_cpu(packet->y_len); | ||
869 | input_set_abs_params(usbtouch->input, ABS_Y, 0, | ||
870 | 2 * be16_to_cpu(packet->y_len), 0, 0); | ||
871 | } | ||
872 | /* | ||
873 | * The device reports state of IR sensors on X and Y axes. | ||
874 | * Each byte represents "darkness" percentage (0-100) of one element. | ||
875 | * 17" touchscreen reports only 64 x 52 bytes so the resolution is low. | ||
876 | * This also means that there's a limited multi-touch capability but | ||
877 | * it's disabled (and untested) here as there's no X driver for that. | ||
878 | */ | ||
879 | begin_x = end_x = begin_y = end_y = -1; | ||
880 | for (x = 0; x < be16_to_cpu(packet->x_len); x++) { | ||
881 | if (begin_x == -1 && packet->data[x] > NEXIO_THRESHOLD) { | ||
882 | begin_x = x; | ||
883 | continue; | ||
884 | } | ||
885 | if (end_x == -1 && begin_x != -1 && packet->data[x] < NEXIO_THRESHOLD) { | ||
886 | end_x = x - 1; | ||
887 | for (y = be16_to_cpu(packet->x_len); | ||
888 | y < be16_to_cpu(packet->data_len); y++) { | ||
889 | if (begin_y == -1 && packet->data[y] > NEXIO_THRESHOLD) { | ||
890 | begin_y = y - be16_to_cpu(packet->x_len); | ||
891 | continue; | ||
892 | } | ||
893 | if (end_y == -1 && | ||
894 | begin_y != -1 && packet->data[y] < NEXIO_THRESHOLD) { | ||
895 | end_y = y - 1 - be16_to_cpu(packet->x_len); | ||
896 | w = end_x - begin_x; | ||
897 | h = end_y - begin_y; | ||
898 | #if 0 | ||
899 | /* multi-touch */ | ||
900 | input_report_abs(usbtouch->input, | ||
901 | ABS_MT_TOUCH_MAJOR, max(w,h)); | ||
902 | input_report_abs(usbtouch->input, | ||
903 | ABS_MT_TOUCH_MINOR, min(x,h)); | ||
904 | input_report_abs(usbtouch->input, | ||
905 | ABS_MT_POSITION_X, 2*begin_x+w); | ||
906 | input_report_abs(usbtouch->input, | ||
907 | ABS_MT_POSITION_Y, 2*begin_y+h); | ||
908 | input_report_abs(usbtouch->input, | ||
909 | ABS_MT_ORIENTATION, w > h); | ||
910 | input_mt_sync(usbtouch->input); | ||
911 | #endif | ||
912 | /* single touch */ | ||
913 | usbtouch->x = 2 * begin_x + w; | ||
914 | usbtouch->y = 2 * begin_y + h; | ||
915 | usbtouch->touch = packet->flags & 0x01; | ||
916 | begin_y = end_y = -1; | ||
917 | return 1; | ||
918 | } | ||
919 | } | ||
920 | begin_x = end_x = -1; | ||
921 | } | ||
922 | |||
923 | } | ||
924 | return 0; | ||
925 | } | ||
926 | #endif | ||
927 | |||
624 | 928 | ||
625 | /***************************************************************************** | 929 | /***************************************************************************** |
626 | * the different device descriptors | 930 | * the different device descriptors |
@@ -742,9 +1046,9 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
742 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH | 1046 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH |
743 | [DEVTYPE_GENERAL_TOUCH] = { | 1047 | [DEVTYPE_GENERAL_TOUCH] = { |
744 | .min_xc = 0x0, | 1048 | .min_xc = 0x0, |
745 | .max_xc = 0x0500, | 1049 | .max_xc = 0x7fff, |
746 | .min_yc = 0x0, | 1050 | .min_yc = 0x0, |
747 | .max_yc = 0x0500, | 1051 | .max_yc = 0x7fff, |
748 | .rept_size = 7, | 1052 | .rept_size = 7, |
749 | .read_data = general_touch_read_data, | 1053 | .read_data = general_touch_read_data, |
750 | }, | 1054 | }, |
@@ -783,6 +1087,39 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
783 | .read_data = e2i_read_data, | 1087 | .read_data = e2i_read_data, |
784 | }, | 1088 | }, |
785 | #endif | 1089 | #endif |
1090 | |||
1091 | #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC | ||
1092 | [DEVTYPE_ZYTRONIC] = { | ||
1093 | .min_xc = 0x0, | ||
1094 | .max_xc = 0x03ff, | ||
1095 | .min_yc = 0x0, | ||
1096 | .max_yc = 0x03ff, | ||
1097 | .rept_size = 5, | ||
1098 | .read_data = zytronic_read_data, | ||
1099 | .irq_always = true, | ||
1100 | }, | ||
1101 | #endif | ||
1102 | |||
1103 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | ||
1104 | [DEVTYPE_TC5UH] = { | ||
1105 | .min_xc = 0x0, | ||
1106 | .max_xc = 0x0fff, | ||
1107 | .min_yc = 0x0, | ||
1108 | .max_yc = 0x0fff, | ||
1109 | .rept_size = 5, | ||
1110 | .read_data = tc5uh_read_data, | ||
1111 | }, | ||
1112 | #endif | ||
1113 | |||
1114 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
1115 | [DEVTYPE_NEXIO] = { | ||
1116 | .rept_size = 128, | ||
1117 | .irq_always = true, | ||
1118 | .read_data = nexio_read_data, | ||
1119 | .init = nexio_init, | ||
1120 | .exit = nexio_exit, | ||
1121 | }, | ||
1122 | #endif | ||
786 | }; | 1123 | }; |
787 | 1124 | ||
788 | 1125 | ||
@@ -908,6 +1245,7 @@ static void usbtouch_irq(struct urb *urb) | |||
908 | case -ECONNRESET: | 1245 | case -ECONNRESET: |
909 | case -ENOENT: | 1246 | case -ENOENT: |
910 | case -ESHUTDOWN: | 1247 | case -ESHUTDOWN: |
1248 | case -EPIPE: | ||
911 | /* this urb is terminated, clean up */ | 1249 | /* this urb is terminated, clean up */ |
912 | dbg("%s - urb shutting down with status: %d", | 1250 | dbg("%s - urb shutting down with status: %d", |
913 | __func__, urb->status); | 1251 | __func__, urb->status); |
@@ -931,10 +1269,12 @@ static int usbtouch_open(struct input_dev *input) | |||
931 | { | 1269 | { |
932 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); | 1270 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); |
933 | 1271 | ||
934 | usbtouch->irq->dev = usbtouch->udev; | 1272 | usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface); |
935 | 1273 | ||
936 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) | 1274 | if (!usbtouch->type->irq_always) { |
937 | return -EIO; | 1275 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) |
1276 | return -EIO; | ||
1277 | } | ||
938 | 1278 | ||
939 | return 0; | 1279 | return 0; |
940 | } | 1280 | } |
@@ -943,7 +1283,8 @@ static void usbtouch_close(struct input_dev *input) | |||
943 | { | 1283 | { |
944 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); | 1284 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); |
945 | 1285 | ||
946 | usb_kill_urb(usbtouch->irq); | 1286 | if (!usbtouch->type->irq_always) |
1287 | usb_kill_urb(usbtouch->irq); | ||
947 | } | 1288 | } |
948 | 1289 | ||
949 | 1290 | ||
@@ -955,13 +1296,23 @@ static void usbtouch_free_buffers(struct usb_device *udev, | |||
955 | kfree(usbtouch->buffer); | 1296 | kfree(usbtouch->buffer); |
956 | } | 1297 | } |
957 | 1298 | ||
1299 | static struct usb_endpoint_descriptor * | ||
1300 | usbtouch_get_input_endpoint(struct usb_host_interface *interface) | ||
1301 | { | ||
1302 | int i; | ||
1303 | |||
1304 | for (i = 0; i < interface->desc.bNumEndpoints; i++) | ||
1305 | if (usb_endpoint_dir_in(&interface->endpoint[i].desc)) | ||
1306 | return &interface->endpoint[i].desc; | ||
1307 | |||
1308 | return NULL; | ||
1309 | } | ||
958 | 1310 | ||
959 | static int usbtouch_probe(struct usb_interface *intf, | 1311 | static int usbtouch_probe(struct usb_interface *intf, |
960 | const struct usb_device_id *id) | 1312 | const struct usb_device_id *id) |
961 | { | 1313 | { |
962 | struct usbtouch_usb *usbtouch; | 1314 | struct usbtouch_usb *usbtouch; |
963 | struct input_dev *input_dev; | 1315 | struct input_dev *input_dev; |
964 | struct usb_host_interface *interface; | ||
965 | struct usb_endpoint_descriptor *endpoint; | 1316 | struct usb_endpoint_descriptor *endpoint; |
966 | struct usb_device *udev = interface_to_usbdev(intf); | 1317 | struct usb_device *udev = interface_to_usbdev(intf); |
967 | struct usbtouch_device_info *type; | 1318 | struct usbtouch_device_info *type; |
@@ -971,8 +1322,9 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
971 | if (id->driver_info == DEVTYPE_IGNORE) | 1322 | if (id->driver_info == DEVTYPE_IGNORE) |
972 | return -ENODEV; | 1323 | return -ENODEV; |
973 | 1324 | ||
974 | interface = intf->cur_altsetting; | 1325 | endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting); |
975 | endpoint = &interface->endpoint[0].desc; | 1326 | if (!endpoint) |
1327 | return -ENXIO; | ||
976 | 1328 | ||
977 | usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); | 1329 | usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); |
978 | input_dev = input_allocate_device(); | 1330 | input_dev = input_allocate_device(); |
@@ -1001,7 +1353,7 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1001 | goto out_free_buffers; | 1353 | goto out_free_buffers; |
1002 | } | 1354 | } |
1003 | 1355 | ||
1004 | usbtouch->udev = udev; | 1356 | usbtouch->interface = intf; |
1005 | usbtouch->input = input_dev; | 1357 | usbtouch->input = input_dev; |
1006 | 1358 | ||
1007 | if (udev->manufacturer) | 1359 | if (udev->manufacturer) |
@@ -1040,12 +1392,18 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1040 | input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, | 1392 | input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, |
1041 | type->max_press, 0, 0); | 1393 | type->max_press, 0, 0); |
1042 | 1394 | ||
1043 | usb_fill_int_urb(usbtouch->irq, usbtouch->udev, | 1395 | if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) |
1044 | usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), | 1396 | usb_fill_int_urb(usbtouch->irq, udev, |
1397 | usb_rcvintpipe(udev, endpoint->bEndpointAddress), | ||
1045 | usbtouch->data, type->rept_size, | 1398 | usbtouch->data, type->rept_size, |
1046 | usbtouch_irq, usbtouch, endpoint->bInterval); | 1399 | usbtouch_irq, usbtouch, endpoint->bInterval); |
1400 | else | ||
1401 | usb_fill_bulk_urb(usbtouch->irq, udev, | ||
1402 | usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), | ||
1403 | usbtouch->data, type->rept_size, | ||
1404 | usbtouch_irq, usbtouch); | ||
1047 | 1405 | ||
1048 | usbtouch->irq->dev = usbtouch->udev; | 1406 | usbtouch->irq->dev = udev; |
1049 | usbtouch->irq->transfer_dma = usbtouch->data_dma; | 1407 | usbtouch->irq->transfer_dma = usbtouch->data_dma; |
1050 | usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1408 | usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1051 | 1409 | ||
@@ -1054,20 +1412,37 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1054 | err = type->init(usbtouch); | 1412 | err = type->init(usbtouch); |
1055 | if (err) { | 1413 | if (err) { |
1056 | dbg("%s - type->init() failed, err: %d", __func__, err); | 1414 | dbg("%s - type->init() failed, err: %d", __func__, err); |
1057 | goto out_free_buffers; | 1415 | goto out_free_urb; |
1058 | } | 1416 | } |
1059 | } | 1417 | } |
1060 | 1418 | ||
1061 | err = input_register_device(usbtouch->input); | 1419 | err = input_register_device(usbtouch->input); |
1062 | if (err) { | 1420 | if (err) { |
1063 | dbg("%s - input_register_device failed, err: %d", __func__, err); | 1421 | dbg("%s - input_register_device failed, err: %d", __func__, err); |
1064 | goto out_free_buffers; | 1422 | goto out_do_exit; |
1065 | } | 1423 | } |
1066 | 1424 | ||
1067 | usb_set_intfdata(intf, usbtouch); | 1425 | usb_set_intfdata(intf, usbtouch); |
1068 | 1426 | ||
1427 | if (usbtouch->type->irq_always) { | ||
1428 | err = usb_submit_urb(usbtouch->irq, GFP_KERNEL); | ||
1429 | if (err) { | ||
1430 | err("%s - usb_submit_urb failed with result: %d", | ||
1431 | __func__, err); | ||
1432 | goto out_unregister_input; | ||
1433 | } | ||
1434 | } | ||
1435 | |||
1069 | return 0; | 1436 | return 0; |
1070 | 1437 | ||
1438 | out_unregister_input: | ||
1439 | input_unregister_device(input_dev); | ||
1440 | input_dev = NULL; | ||
1441 | out_do_exit: | ||
1442 | if (type->exit) | ||
1443 | type->exit(usbtouch); | ||
1444 | out_free_urb: | ||
1445 | usb_free_urb(usbtouch->irq); | ||
1071 | out_free_buffers: | 1446 | out_free_buffers: |
1072 | usbtouch_free_buffers(udev, usbtouch); | 1447 | usbtouch_free_buffers(udev, usbtouch); |
1073 | out_free: | 1448 | out_free: |
@@ -1087,9 +1462,11 @@ static void usbtouch_disconnect(struct usb_interface *intf) | |||
1087 | 1462 | ||
1088 | dbg("%s - usbtouch is initialized, cleaning up", __func__); | 1463 | dbg("%s - usbtouch is initialized, cleaning up", __func__); |
1089 | usb_set_intfdata(intf, NULL); | 1464 | usb_set_intfdata(intf, NULL); |
1090 | usb_kill_urb(usbtouch->irq); | 1465 | /* this will stop IO via close */ |
1091 | input_unregister_device(usbtouch->input); | 1466 | input_unregister_device(usbtouch->input); |
1092 | usb_free_urb(usbtouch->irq); | 1467 | usb_free_urb(usbtouch->irq); |
1468 | if (usbtouch->type->exit) | ||
1469 | usbtouch->type->exit(usbtouch); | ||
1093 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); | 1470 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); |
1094 | kfree(usbtouch); | 1471 | kfree(usbtouch); |
1095 | } | 1472 | } |
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c index 6ccbdbbf33fe..cc18265be1a8 100644 --- a/drivers/input/touchscreen/w90p910_ts.c +++ b/drivers/input/touchscreen/w90p910_ts.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/input.h> | 17 | #include <linux/input.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/slab.h> | ||
19 | 20 | ||
20 | /* ADC controller bit defines */ | 21 | /* ADC controller bit defines */ |
21 | #define ADC_DELAY 0xf00 | 22 | #define ADC_DELAY 0xf00 |
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index f944918466e5..5109bf3dd858 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/wm97xx.h> | 48 | #include <linux/wm97xx.h> |
49 | #include <linux/uaccess.h> | 49 | #include <linux/uaccess.h> |
50 | #include <linux/io.h> | 50 | #include <linux/io.h> |
51 | #include <linux/slab.h> | ||
51 | 52 | ||
52 | #define TS_NAME "wm97xx" | 53 | #define TS_NAME "wm97xx" |
53 | #define WM_CORE_VERSION "1.00" | 54 | #define WM_CORE_VERSION "1.00" |
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index 41e4359c277c..048849867643 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c | |||
@@ -96,7 +96,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
96 | /* When the AC97 queue has been drained we need to allow time | 96 | /* When the AC97 queue has been drained we need to allow time |
97 | * to buffer up samples otherwise we end up spinning polling | 97 | * to buffer up samples otherwise we end up spinning polling |
98 | * for samples. The controller can't have a suitably low | 98 | * for samples. The controller can't have a suitably low |
99 | * threashold set to use the notifications it gives. | 99 | * threshold set to use the notifications it gives. |
100 | */ | 100 | */ |
101 | msleep(1); | 101 | msleep(1); |
102 | 102 | ||
@@ -118,6 +118,9 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
118 | if (pressure) | 118 | if (pressure) |
119 | p = MODR; | 119 | p = MODR; |
120 | 120 | ||
121 | dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n", | ||
122 | x, y, p); | ||
123 | |||
121 | /* are samples valid */ | 124 | /* are samples valid */ |
122 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || | 125 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || |
123 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || | 126 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || |
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index b115726dc088..e14081675bb2 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c | |||
@@ -21,7 +21,11 @@ | |||
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
24 | #include <linux/slab.h> | ||
25 | |||
24 | #include <asm/xen/hypervisor.h> | 26 | #include <asm/xen/hypervisor.h> |
27 | |||
28 | #include <xen/xen.h> | ||
25 | #include <xen/events.h> | 29 | #include <xen/events.h> |
26 | #include <xen/page.h> | 30 | #include <xen/page.h> |
27 | #include <xen/interface/io/fbif.h> | 31 | #include <xen/interface/io/fbif.h> |
@@ -318,7 +322,7 @@ InitWait: | |||
318 | } | 322 | } |
319 | } | 323 | } |
320 | 324 | ||
321 | static struct xenbus_device_id xenkbd_ids[] = { | 325 | static const struct xenbus_device_id xenkbd_ids[] = { |
322 | { "vkbd" }, | 326 | { "vkbd" }, |
323 | { "" } | 327 | { "" } |
324 | }; | 328 | }; |