diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-14 12:49:16 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-14 12:49:16 -0500 |
| commit | e7de369050534025b33aab1033358bf47a577e4d (patch) | |
| tree | fed44f469923690b98f9de2c87e6d1de76f71dc9 | |
| parent | 87530db5ec7d519c7ba334e414307c5130ae2da8 (diff) | |
| parent | eab9edd27f7ceaad6b57085817d63287bda15190 (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
| -rw-r--r-- | drivers/input/mouse/alps.c | 38 | ||||
| -rw-r--r-- | drivers/input/mouse/logips2pp.c | 2 | ||||
| -rw-r--r-- | drivers/input/mouse/psmouse-base.c | 316 | ||||
| -rw-r--r-- | drivers/input/mouse/psmouse.h | 9 | ||||
| -rw-r--r-- | drivers/input/mouse/synaptics.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 7 | ||||
| -rw-r--r-- | drivers/usb/input/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/usb/input/hid-core.c | 30 | ||||
| -rw-r--r-- | drivers/usb/input/hid-input.c | 179 | ||||
| -rw-r--r-- | drivers/usb/input/hid.h | 30 | ||||
| -rw-r--r-- | drivers/usb/input/pid.c | 2 | ||||
| -rw-r--r-- | drivers/usb/input/wacom.c | 14 |
12 files changed, 551 insertions, 88 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 24474335dfd1..2141501e9f2e 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
| @@ -348,6 +348,40 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable) | |||
| 348 | return 0; | 348 | return 0; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | /* | ||
| 352 | * alps_poll() - poll the touchpad for current motion packet. | ||
| 353 | * Used in resync. | ||
| 354 | */ | ||
| 355 | static int alps_poll(struct psmouse *psmouse) | ||
| 356 | { | ||
| 357 | struct alps_data *priv = psmouse->private; | ||
| 358 | unsigned char buf[6]; | ||
| 359 | int poll_failed; | ||
| 360 | |||
| 361 | if (priv->i->flags & ALPS_PASS) | ||
| 362 | alps_passthrough_mode(psmouse, 1); | ||
| 363 | |||
| 364 | poll_failed = ps2_command(&psmouse->ps2dev, buf, | ||
| 365 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; | ||
| 366 | |||
| 367 | if (priv->i->flags & ALPS_PASS) | ||
| 368 | alps_passthrough_mode(psmouse, 0); | ||
| 369 | |||
| 370 | if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) | ||
| 371 | return -1; | ||
| 372 | |||
| 373 | if ((psmouse->badbyte & 0xc8) == 0x08) { | ||
| 374 | /* | ||
| 375 | * Poll the track stick ... | ||
| 376 | */ | ||
| 377 | if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8))) | ||
| 378 | return -1; | ||
| 379 | } | ||
| 380 | |||
| 381 | memcpy(psmouse->packet, buf, sizeof(buf)); | ||
| 382 | return 0; | ||
| 383 | } | ||
| 384 | |||
| 351 | static int alps_reconnect(struct psmouse *psmouse) | 385 | static int alps_reconnect(struct psmouse *psmouse) |
| 352 | { | 386 | { |
| 353 | struct alps_data *priv = psmouse->private; | 387 | struct alps_data *priv = psmouse->private; |
| @@ -451,10 +485,14 @@ int alps_init(struct psmouse *psmouse) | |||
| 451 | input_register_device(priv->dev2); | 485 | input_register_device(priv->dev2); |
| 452 | 486 | ||
| 453 | psmouse->protocol_handler = alps_process_byte; | 487 | psmouse->protocol_handler = alps_process_byte; |
| 488 | psmouse->poll = alps_poll; | ||
| 454 | psmouse->disconnect = alps_disconnect; | 489 | psmouse->disconnect = alps_disconnect; |
| 455 | psmouse->reconnect = alps_reconnect; | 490 | psmouse->reconnect = alps_reconnect; |
| 456 | psmouse->pktsize = 6; | 491 | psmouse->pktsize = 6; |
| 457 | 492 | ||
| 493 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ | ||
| 494 | psmouse->resync_time = 0; | ||
| 495 | |||
| 458 | return 0; | 496 | return 0; |
| 459 | 497 | ||
| 460 | init_fail: | 498 | init_fail: |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 025a71de5404..c88520d3d13c 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
| @@ -117,7 +117,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha | |||
| 117 | if (psmouse_sliced_command(psmouse, command)) | 117 | if (psmouse_sliced_command(psmouse, command)) |
| 118 | return -1; | 118 | return -1; |
| 119 | 119 | ||
| 120 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL)) | 120 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300)) |
| 121 | return -1; | 121 | return -1; |
| 122 | 122 | ||
| 123 | return 0; | 123 | return 0; |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 4d5ecc04c5b6..7665fd9ce559 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -54,10 +54,14 @@ static unsigned int psmouse_smartscroll = 1; | |||
| 54 | module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); | 54 | module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); |
| 55 | MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); | 55 | MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); |
| 56 | 56 | ||
| 57 | static unsigned int psmouse_resetafter; | 57 | static unsigned int psmouse_resetafter = 5; |
| 58 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); | 58 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); |
| 59 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); | 59 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); |
| 60 | 60 | ||
| 61 | static unsigned int psmouse_resync_time = 5; | ||
| 62 | module_param_named(resync_time, psmouse_resync_time, uint, 0644); | ||
| 63 | MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never)."); | ||
| 64 | |||
| 61 | PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO, | 65 | PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO, |
| 62 | NULL, | 66 | NULL, |
| 63 | psmouse_attr_show_protocol, psmouse_attr_set_protocol); | 67 | psmouse_attr_show_protocol, psmouse_attr_set_protocol); |
| @@ -70,12 +74,16 @@ PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO, | |||
| 70 | PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO, | 74 | PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO, |
| 71 | (void *) offsetof(struct psmouse, resetafter), | 75 | (void *) offsetof(struct psmouse, resetafter), |
| 72 | psmouse_show_int_attr, psmouse_set_int_attr); | 76 | psmouse_show_int_attr, psmouse_set_int_attr); |
| 77 | PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO, | ||
| 78 | (void *) offsetof(struct psmouse, resync_time), | ||
| 79 | psmouse_show_int_attr, psmouse_set_int_attr); | ||
| 73 | 80 | ||
| 74 | static struct attribute *psmouse_attributes[] = { | 81 | static struct attribute *psmouse_attributes[] = { |
| 75 | &psmouse_attr_protocol.dattr.attr, | 82 | &psmouse_attr_protocol.dattr.attr, |
| 76 | &psmouse_attr_rate.dattr.attr, | 83 | &psmouse_attr_rate.dattr.attr, |
| 77 | &psmouse_attr_resolution.dattr.attr, | 84 | &psmouse_attr_resolution.dattr.attr, |
| 78 | &psmouse_attr_resetafter.dattr.attr, | 85 | &psmouse_attr_resetafter.dattr.attr, |
| 86 | &psmouse_attr_resync_time.dattr.attr, | ||
| 79 | NULL | 87 | NULL |
| 80 | }; | 88 | }; |
| 81 | 89 | ||
| @@ -98,6 +106,8 @@ __obsolete_setup("psmouse_rate="); | |||
| 98 | */ | 106 | */ |
| 99 | static DECLARE_MUTEX(psmouse_sem); | 107 | static DECLARE_MUTEX(psmouse_sem); |
| 100 | 108 | ||
| 109 | static struct workqueue_struct *kpsmoused_wq; | ||
| 110 | |||
| 101 | struct psmouse_protocol { | 111 | struct psmouse_protocol { |
| 102 | enum psmouse_type type; | 112 | enum psmouse_type type; |
| 103 | char *name; | 113 | char *name; |
| @@ -178,15 +188,79 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg | |||
| 178 | } | 188 | } |
| 179 | 189 | ||
| 180 | /* | 190 | /* |
| 181 | * psmouse_interrupt() handles incoming characters, either gathering them into | 191 | * __psmouse_set_state() sets new psmouse state and resets all flags. |
| 182 | * packets or passing them to the command routine as command output. | 192 | */ |
| 193 | |||
| 194 | static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) | ||
| 195 | { | ||
| 196 | psmouse->state = new_state; | ||
| 197 | psmouse->pktcnt = psmouse->out_of_sync = 0; | ||
| 198 | psmouse->ps2dev.flags = 0; | ||
| 199 | psmouse->last = jiffies; | ||
| 200 | } | ||
| 201 | |||
| 202 | |||
| 203 | /* | ||
| 204 | * psmouse_set_state() sets new psmouse state and resets all flags and | ||
| 205 | * counters while holding serio lock so fighting with interrupt handler | ||
| 206 | * is not a concern. | ||
| 207 | */ | ||
| 208 | |||
| 209 | static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) | ||
| 210 | { | ||
| 211 | serio_pause_rx(psmouse->ps2dev.serio); | ||
| 212 | __psmouse_set_state(psmouse, new_state); | ||
| 213 | serio_continue_rx(psmouse->ps2dev.serio); | ||
| 214 | } | ||
| 215 | |||
| 216 | /* | ||
| 217 | * psmouse_handle_byte() processes one byte of the input data stream | ||
| 218 | * by calling corresponding protocol handler. | ||
| 219 | */ | ||
| 220 | |||
| 221 | static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs) | ||
| 222 | { | ||
| 223 | psmouse_ret_t rc = psmouse->protocol_handler(psmouse, regs); | ||
| 224 | |||
| 225 | switch (rc) { | ||
| 226 | case PSMOUSE_BAD_DATA: | ||
| 227 | if (psmouse->state == PSMOUSE_ACTIVATED) { | ||
| 228 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", | ||
| 229 | psmouse->name, psmouse->phys, psmouse->pktcnt); | ||
| 230 | if (++psmouse->out_of_sync == psmouse->resetafter) { | ||
| 231 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
| 232 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); | ||
| 233 | serio_reconnect(psmouse->ps2dev.serio); | ||
| 234 | return -1; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | psmouse->pktcnt = 0; | ||
| 238 | break; | ||
| 239 | |||
| 240 | case PSMOUSE_FULL_PACKET: | ||
| 241 | psmouse->pktcnt = 0; | ||
| 242 | if (psmouse->out_of_sync) { | ||
| 243 | psmouse->out_of_sync = 0; | ||
| 244 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", | ||
| 245 | psmouse->name, psmouse->phys); | ||
| 246 | } | ||
| 247 | break; | ||
| 248 | |||
| 249 | case PSMOUSE_GOOD_DATA: | ||
| 250 | break; | ||
| 251 | } | ||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | /* | ||
| 256 | * psmouse_interrupt() handles incoming characters, either passing them | ||
| 257 | * for normal processing or gathering them as command response. | ||
| 183 | */ | 258 | */ |
| 184 | 259 | ||
| 185 | static irqreturn_t psmouse_interrupt(struct serio *serio, | 260 | static irqreturn_t psmouse_interrupt(struct serio *serio, |
| 186 | unsigned char data, unsigned int flags, struct pt_regs *regs) | 261 | unsigned char data, unsigned int flags, struct pt_regs *regs) |
| 187 | { | 262 | { |
| 188 | struct psmouse *psmouse = serio_get_drvdata(serio); | 263 | struct psmouse *psmouse = serio_get_drvdata(serio); |
| 189 | psmouse_ret_t rc; | ||
| 190 | 264 | ||
| 191 | if (psmouse->state == PSMOUSE_IGNORE) | 265 | if (psmouse->state == PSMOUSE_IGNORE) |
| 192 | goto out; | 266 | goto out; |
| @@ -208,67 +282,58 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
| 208 | if (ps2_handle_response(&psmouse->ps2dev, data)) | 282 | if (ps2_handle_response(&psmouse->ps2dev, data)) |
| 209 | goto out; | 283 | goto out; |
| 210 | 284 | ||
| 211 | if (psmouse->state == PSMOUSE_INITIALIZING) | 285 | if (psmouse->state <= PSMOUSE_RESYNCING) |
| 212 | goto out; | 286 | goto out; |
| 213 | 287 | ||
| 214 | if (psmouse->state == PSMOUSE_ACTIVATED && | 288 | if (psmouse->state == PSMOUSE_ACTIVATED && |
| 215 | psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { | 289 | psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { |
| 216 | printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", | 290 | printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", |
| 217 | psmouse->name, psmouse->phys, psmouse->pktcnt); | 291 | psmouse->name, psmouse->phys, psmouse->pktcnt); |
| 218 | psmouse->pktcnt = 0; | 292 | psmouse->badbyte = psmouse->packet[0]; |
| 293 | __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); | ||
| 294 | queue_work(kpsmoused_wq, &psmouse->resync_work); | ||
| 295 | goto out; | ||
| 219 | } | 296 | } |
| 220 | 297 | ||
| 221 | psmouse->last = jiffies; | ||
| 222 | psmouse->packet[psmouse->pktcnt++] = data; | 298 | psmouse->packet[psmouse->pktcnt++] = data; |
| 223 | 299 | /* | |
| 224 | if (psmouse->packet[0] == PSMOUSE_RET_BAT) { | 300 | * Check if this is a new device announcement (0xAA 0x00) |
| 301 | */ | ||
| 302 | if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) { | ||
| 225 | if (psmouse->pktcnt == 1) | 303 | if (psmouse->pktcnt == 1) |
| 226 | goto out; | 304 | goto out; |
| 227 | 305 | ||
| 228 | if (psmouse->pktcnt == 2) { | 306 | if (psmouse->packet[1] == PSMOUSE_RET_ID) { |
| 229 | if (psmouse->packet[1] == PSMOUSE_RET_ID) { | 307 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
| 230 | psmouse->state = PSMOUSE_IGNORE; | 308 | serio_reconnect(serio); |
| 231 | serio_reconnect(serio); | 309 | goto out; |
| 232 | goto out; | ||
| 233 | } | ||
| 234 | if (psmouse->type == PSMOUSE_SYNAPTICS) { | ||
| 235 | /* neither 0xAA nor 0x00 are valid first bytes | ||
| 236 | * for a packet in absolute mode | ||
| 237 | */ | ||
| 238 | psmouse->pktcnt = 0; | ||
| 239 | goto out; | ||
| 240 | } | ||
| 241 | } | 310 | } |
| 242 | } | 311 | /* |
| 243 | 312 | * Not a new device, try processing first byte normally | |
| 244 | rc = psmouse->protocol_handler(psmouse, regs); | 313 | */ |
| 314 | psmouse->pktcnt = 1; | ||
| 315 | if (psmouse_handle_byte(psmouse, regs)) | ||
| 316 | goto out; | ||
| 245 | 317 | ||
| 246 | switch (rc) { | 318 | psmouse->packet[psmouse->pktcnt++] = data; |
| 247 | case PSMOUSE_BAD_DATA: | 319 | } |
| 248 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", | ||
| 249 | psmouse->name, psmouse->phys, psmouse->pktcnt); | ||
| 250 | psmouse->pktcnt = 0; | ||
| 251 | 320 | ||
| 252 | if (++psmouse->out_of_sync == psmouse->resetafter) { | 321 | /* |
| 253 | psmouse->state = PSMOUSE_IGNORE; | 322 | * See if we need to force resync because mouse was idle for too long |
| 254 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); | 323 | */ |
| 255 | serio_reconnect(psmouse->ps2dev.serio); | 324 | if (psmouse->state == PSMOUSE_ACTIVATED && |
| 256 | } | 325 | psmouse->pktcnt == 1 && psmouse->resync_time && |
| 257 | break; | 326 | time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) { |
| 327 | psmouse->badbyte = psmouse->packet[0]; | ||
| 328 | __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); | ||
| 329 | queue_work(kpsmoused_wq, &psmouse->resync_work); | ||
| 330 | goto out; | ||
| 331 | } | ||
| 258 | 332 | ||
| 259 | case PSMOUSE_FULL_PACKET: | 333 | psmouse->last = jiffies; |
| 260 | psmouse->pktcnt = 0; | 334 | psmouse_handle_byte(psmouse, regs); |
| 261 | if (psmouse->out_of_sync) { | ||
| 262 | psmouse->out_of_sync = 0; | ||
| 263 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", | ||
| 264 | psmouse->name, psmouse->phys); | ||
| 265 | } | ||
| 266 | break; | ||
| 267 | 335 | ||
| 268 | case PSMOUSE_GOOD_DATA: | 336 | out: |
| 269 | break; | ||
| 270 | } | ||
| 271 | out: | ||
| 272 | return IRQ_HANDLED; | 337 | return IRQ_HANDLED; |
| 273 | } | 338 | } |
| 274 | 339 | ||
| @@ -752,21 +817,6 @@ static void psmouse_initialize(struct psmouse *psmouse) | |||
| 752 | } | 817 | } |
| 753 | 818 | ||
| 754 | /* | 819 | /* |
| 755 | * psmouse_set_state() sets new psmouse state and resets all flags and | ||
| 756 | * counters while holding serio lock so fighting with interrupt handler | ||
| 757 | * is not a concern. | ||
| 758 | */ | ||
| 759 | |||
| 760 | static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) | ||
| 761 | { | ||
| 762 | serio_pause_rx(psmouse->ps2dev.serio); | ||
| 763 | psmouse->state = new_state; | ||
| 764 | psmouse->pktcnt = psmouse->out_of_sync = 0; | ||
| 765 | psmouse->ps2dev.flags = 0; | ||
| 766 | serio_continue_rx(psmouse->ps2dev.serio); | ||
| 767 | } | ||
| 768 | |||
| 769 | /* | ||
| 770 | * psmouse_activate() enables the mouse so that we get motion reports from it. | 820 | * psmouse_activate() enables the mouse so that we get motion reports from it. |
| 771 | */ | 821 | */ |
| 772 | 822 | ||
| @@ -794,6 +844,111 @@ static void psmouse_deactivate(struct psmouse *psmouse) | |||
| 794 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 844 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
| 795 | } | 845 | } |
| 796 | 846 | ||
| 847 | /* | ||
| 848 | * psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it. | ||
| 849 | */ | ||
| 850 | |||
| 851 | static int psmouse_poll(struct psmouse *psmouse) | ||
| 852 | { | ||
| 853 | return ps2_command(&psmouse->ps2dev, psmouse->packet, | ||
| 854 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)); | ||
| 855 | } | ||
| 856 | |||
| 857 | |||
| 858 | /* | ||
| 859 | * psmouse_resync() attempts to re-validate current protocol. | ||
| 860 | */ | ||
| 861 | |||
| 862 | static void psmouse_resync(void *p) | ||
| 863 | { | ||
| 864 | struct psmouse *psmouse = p, *parent = NULL; | ||
| 865 | struct serio *serio = psmouse->ps2dev.serio; | ||
| 866 | psmouse_ret_t rc = PSMOUSE_GOOD_DATA; | ||
| 867 | int failed = 0, enabled = 0; | ||
| 868 | int i; | ||
| 869 | |||
| 870 | down(&psmouse_sem); | ||
| 871 | |||
| 872 | if (psmouse->state != PSMOUSE_RESYNCING) | ||
| 873 | goto out; | ||
| 874 | |||
| 875 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | ||
| 876 | parent = serio_get_drvdata(serio->parent); | ||
| 877 | psmouse_deactivate(parent); | ||
| 878 | } | ||
| 879 | |||
| 880 | /* | ||
| 881 | * Some mice don't ACK commands sent while they are in the middle of | ||
| 882 | * transmitting motion packet. To avoid delay we use ps2_sendbyte() | ||
| 883 | * instead of ps2_command() which would wait for 200ms for an ACK | ||
| 884 | * that may never come. | ||
| 885 | * As an additional quirk ALPS touchpads may not only forget to ACK | ||
| 886 | * disable command but will stop reporting taps, so if we see that | ||
| 887 | * mouse at least once ACKs disable we will do full reconnect if ACK | ||
| 888 | * is missing. | ||
| 889 | */ | ||
| 890 | psmouse->num_resyncs++; | ||
| 891 | |||
| 892 | if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) { | ||
| 893 | if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command) | ||
| 894 | failed = 1; | ||
| 895 | } else | ||
| 896 | psmouse->acks_disable_command = 1; | ||
| 897 | |||
| 898 | /* | ||
| 899 | * Poll the mouse. If it was reset the packet will be shorter than | ||
| 900 | * psmouse->pktsize and ps2_command will fail. We do not expect and | ||
| 901 | * do not handle scenario when mouse "upgrades" its protocol while | ||
| 902 | * disconnected since it would require additional delay. If we ever | ||
| 903 | * see a mouse that does it we'll adjust the code. | ||
| 904 | */ | ||
| 905 | if (!failed) { | ||
| 906 | if (psmouse->poll(psmouse)) | ||
| 907 | failed = 1; | ||
| 908 | else { | ||
| 909 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
| 910 | for (i = 0; i < psmouse->pktsize; i++) { | ||
| 911 | psmouse->pktcnt++; | ||
| 912 | rc = psmouse->protocol_handler(psmouse, NULL); | ||
| 913 | if (rc != PSMOUSE_GOOD_DATA) | ||
| 914 | break; | ||
| 915 | } | ||
| 916 | if (rc != PSMOUSE_FULL_PACKET) | ||
| 917 | failed = 1; | ||
| 918 | psmouse_set_state(psmouse, PSMOUSE_RESYNCING); | ||
| 919 | } | ||
| 920 | } | ||
| 921 | /* | ||
| 922 | * Now try to enable mouse. We try to do that even if poll failed and also | ||
| 923 | * repeat our attempts 5 times, otherwise we may be left out with disabled | ||
| 924 | * mouse. | ||
| 925 | */ | ||
| 926 | for (i = 0; i < 5; i++) { | ||
| 927 | if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { | ||
| 928 | enabled = 1; | ||
| 929 | break; | ||
| 930 | } | ||
| 931 | msleep(200); | ||
| 932 | } | ||
| 933 | |||
| 934 | if (!enabled) { | ||
| 935 | printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n", | ||
| 936 | psmouse->ps2dev.serio->phys); | ||
| 937 | failed = 1; | ||
| 938 | } | ||
| 939 | |||
| 940 | if (failed) { | ||
| 941 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
| 942 | printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n"); | ||
| 943 | serio_reconnect(serio); | ||
| 944 | } else | ||
| 945 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | ||
| 946 | |||
| 947 | if (parent) | ||
| 948 | psmouse_activate(parent); | ||
| 949 | out: | ||
| 950 | up(&psmouse_sem); | ||
| 951 | } | ||
| 797 | 952 | ||
| 798 | /* | 953 | /* |
| 799 | * psmouse_cleanup() resets the mouse into power-on state. | 954 | * psmouse_cleanup() resets the mouse into power-on state. |
| @@ -822,6 +977,11 @@ static void psmouse_disconnect(struct serio *serio) | |||
| 822 | 977 | ||
| 823 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 978 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
| 824 | 979 | ||
| 980 | /* make sure we don't have a resync in progress */ | ||
| 981 | up(&psmouse_sem); | ||
| 982 | flush_workqueue(kpsmoused_wq); | ||
| 983 | down(&psmouse_sem); | ||
| 984 | |||
| 825 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | 985 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { |
| 826 | parent = serio_get_drvdata(serio->parent); | 986 | parent = serio_get_drvdata(serio->parent); |
| 827 | psmouse_deactivate(parent); | 987 | psmouse_deactivate(parent); |
| @@ -859,6 +1019,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto | |||
| 859 | 1019 | ||
| 860 | psmouse->set_rate = psmouse_set_rate; | 1020 | psmouse->set_rate = psmouse_set_rate; |
| 861 | psmouse->set_resolution = psmouse_set_resolution; | 1021 | psmouse->set_resolution = psmouse_set_resolution; |
| 1022 | psmouse->poll = psmouse_poll; | ||
| 862 | psmouse->protocol_handler = psmouse_process_byte; | 1023 | psmouse->protocol_handler = psmouse_process_byte; |
| 863 | psmouse->pktsize = 3; | 1024 | psmouse->pktsize = 3; |
| 864 | 1025 | ||
| @@ -874,6 +1035,23 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto | |||
| 874 | else | 1035 | else |
| 875 | psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); | 1036 | psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); |
| 876 | 1037 | ||
| 1038 | /* | ||
| 1039 | * If mouse's packet size is 3 there is no point in polling the | ||
| 1040 | * device in hopes to detect protocol reset - we won't get less | ||
| 1041 | * than 3 bytes response anyhow. | ||
| 1042 | */ | ||
| 1043 | if (psmouse->pktsize == 3) | ||
| 1044 | psmouse->resync_time = 0; | ||
| 1045 | |||
| 1046 | /* | ||
| 1047 | * Some smart KVMs fake response to POLL command returning just | ||
| 1048 | * 3 bytes and messing up our resync logic, so if initial poll | ||
| 1049 | * fails we won't try polling the device anymore. Hopefully | ||
| 1050 | * such KVM will maintain initially selected protocol. | ||
| 1051 | */ | ||
| 1052 | if (psmouse->resync_time && psmouse->poll(psmouse)) | ||
| 1053 | psmouse->resync_time = 0; | ||
| 1054 | |||
| 877 | sprintf(psmouse->devname, "%s %s %s", | 1055 | sprintf(psmouse->devname, "%s %s %s", |
| 878 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); | 1056 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); |
| 879 | 1057 | ||
| @@ -914,6 +1092,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
| 914 | goto out; | 1092 | goto out; |
| 915 | 1093 | ||
| 916 | ps2_init(&psmouse->ps2dev, serio); | 1094 | ps2_init(&psmouse->ps2dev, serio); |
| 1095 | INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse); | ||
| 917 | psmouse->dev = input_dev; | 1096 | psmouse->dev = input_dev; |
| 918 | sprintf(psmouse->phys, "%s/input0", serio->phys); | 1097 | sprintf(psmouse->phys, "%s/input0", serio->phys); |
| 919 | 1098 | ||
| @@ -934,6 +1113,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
| 934 | psmouse->rate = psmouse_rate; | 1113 | psmouse->rate = psmouse_rate; |
| 935 | psmouse->resolution = psmouse_resolution; | 1114 | psmouse->resolution = psmouse_resolution; |
| 936 | psmouse->resetafter = psmouse_resetafter; | 1115 | psmouse->resetafter = psmouse_resetafter; |
| 1116 | psmouse->resync_time = parent ? 0 : psmouse_resync_time; | ||
| 937 | psmouse->smartscroll = psmouse_smartscroll; | 1117 | psmouse->smartscroll = psmouse_smartscroll; |
| 938 | 1118 | ||
| 939 | psmouse_switch_protocol(psmouse, NULL); | 1119 | psmouse_switch_protocol(psmouse, NULL); |
| @@ -1278,13 +1458,21 @@ static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) | |||
| 1278 | 1458 | ||
| 1279 | static int __init psmouse_init(void) | 1459 | static int __init psmouse_init(void) |
| 1280 | { | 1460 | { |
| 1461 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); | ||
| 1462 | if (!kpsmoused_wq) { | ||
| 1463 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); | ||
| 1464 | return -ENOMEM; | ||
| 1465 | } | ||
| 1466 | |||
| 1281 | serio_register_driver(&psmouse_drv); | 1467 | serio_register_driver(&psmouse_drv); |
| 1468 | |||
| 1282 | return 0; | 1469 | return 0; |
| 1283 | } | 1470 | } |
| 1284 | 1471 | ||
| 1285 | static void __exit psmouse_exit(void) | 1472 | static void __exit psmouse_exit(void) |
| 1286 | { | 1473 | { |
| 1287 | serio_unregister_driver(&psmouse_drv); | 1474 | serio_unregister_driver(&psmouse_drv); |
| 1475 | destroy_workqueue(kpsmoused_wq); | ||
| 1288 | } | 1476 | } |
| 1289 | 1477 | ||
| 1290 | module_init(psmouse_init); | 1478 | module_init(psmouse_init); |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 7c4192bd1279..4d9107fba6a1 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #define PSMOUSE_CMD_GETINFO 0x03e9 | 7 | #define PSMOUSE_CMD_GETINFO 0x03e9 |
| 8 | #define PSMOUSE_CMD_SETSTREAM 0x00ea | 8 | #define PSMOUSE_CMD_SETSTREAM 0x00ea |
| 9 | #define PSMOUSE_CMD_SETPOLL 0x00f0 | 9 | #define PSMOUSE_CMD_SETPOLL 0x00f0 |
| 10 | #define PSMOUSE_CMD_POLL 0x03eb | 10 | #define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */ |
| 11 | #define PSMOUSE_CMD_GETID 0x02f2 | 11 | #define PSMOUSE_CMD_GETID 0x02f2 |
| 12 | #define PSMOUSE_CMD_SETRATE 0x10f3 | 12 | #define PSMOUSE_CMD_SETRATE 0x10f3 |
| 13 | #define PSMOUSE_CMD_ENABLE 0x00f4 | 13 | #define PSMOUSE_CMD_ENABLE 0x00f4 |
| @@ -23,6 +23,7 @@ | |||
| 23 | enum psmouse_state { | 23 | enum psmouse_state { |
| 24 | PSMOUSE_IGNORE, | 24 | PSMOUSE_IGNORE, |
| 25 | PSMOUSE_INITIALIZING, | 25 | PSMOUSE_INITIALIZING, |
| 26 | PSMOUSE_RESYNCING, | ||
| 26 | PSMOUSE_CMD_MODE, | 27 | PSMOUSE_CMD_MODE, |
| 27 | PSMOUSE_ACTIVATED, | 28 | PSMOUSE_ACTIVATED, |
| 28 | }; | 29 | }; |
| @@ -38,15 +39,19 @@ struct psmouse { | |||
| 38 | void *private; | 39 | void *private; |
| 39 | struct input_dev *dev; | 40 | struct input_dev *dev; |
| 40 | struct ps2dev ps2dev; | 41 | struct ps2dev ps2dev; |
| 42 | struct work_struct resync_work; | ||
| 41 | char *vendor; | 43 | char *vendor; |
| 42 | char *name; | 44 | char *name; |
| 43 | unsigned char packet[8]; | 45 | unsigned char packet[8]; |
| 46 | unsigned char badbyte; | ||
| 44 | unsigned char pktcnt; | 47 | unsigned char pktcnt; |
| 45 | unsigned char pktsize; | 48 | unsigned char pktsize; |
| 46 | unsigned char type; | 49 | unsigned char type; |
| 50 | unsigned char acks_disable_command; | ||
| 47 | unsigned int model; | 51 | unsigned int model; |
| 48 | unsigned long last; | 52 | unsigned long last; |
| 49 | unsigned long out_of_sync; | 53 | unsigned long out_of_sync; |
| 54 | unsigned long num_resyncs; | ||
| 50 | enum psmouse_state state; | 55 | enum psmouse_state state; |
| 51 | char devname[64]; | 56 | char devname[64]; |
| 52 | char phys[32]; | 57 | char phys[32]; |
| @@ -54,6 +59,7 @@ struct psmouse { | |||
| 54 | unsigned int rate; | 59 | unsigned int rate; |
| 55 | unsigned int resolution; | 60 | unsigned int resolution; |
| 56 | unsigned int resetafter; | 61 | unsigned int resetafter; |
| 62 | unsigned int resync_time; | ||
| 57 | unsigned int smartscroll; /* Logitech only */ | 63 | unsigned int smartscroll; /* Logitech only */ |
| 58 | 64 | ||
| 59 | psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); | 65 | psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); |
| @@ -62,6 +68,7 @@ struct psmouse { | |||
| 62 | 68 | ||
| 63 | int (*reconnect)(struct psmouse *psmouse); | 69 | int (*reconnect)(struct psmouse *psmouse); |
| 64 | void (*disconnect)(struct psmouse *psmouse); | 70 | void (*disconnect)(struct psmouse *psmouse); |
| 71 | int (*poll)(struct psmouse *psmouse); | ||
| 65 | 72 | ||
| 66 | void (*pt_activate)(struct psmouse *psmouse); | 73 | void (*pt_activate)(struct psmouse *psmouse); |
| 67 | void (*pt_deactivate)(struct psmouse *psmouse); | 74 | void (*pt_deactivate)(struct psmouse *psmouse); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 97cdfd6acaca..2051bec2c394 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -652,6 +652,8 @@ int synaptics_init(struct psmouse *psmouse) | |||
| 652 | psmouse->disconnect = synaptics_disconnect; | 652 | psmouse->disconnect = synaptics_disconnect; |
| 653 | psmouse->reconnect = synaptics_reconnect; | 653 | psmouse->reconnect = synaptics_reconnect; |
| 654 | psmouse->pktsize = 6; | 654 | psmouse->pktsize = 6; |
| 655 | /* Synaptics can usually stay in sync without extra help */ | ||
| 656 | psmouse->resync_time = 0; | ||
| 655 | 657 | ||
| 656 | if (SYN_CAP_PASS_THROUGH(priv->capabilities)) | 658 | if (SYN_CAP_PASS_THROUGH(priv->capabilities)) |
| 657 | synaptics_pt_create(psmouse); | 659 | synaptics_pt_create(psmouse); |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2d2f9fb3aded..a4c6f3522723 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
| @@ -173,6 +173,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
| 173 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), | 173 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), |
| 174 | }, | 174 | }, |
| 175 | }, | 175 | }, |
| 176 | { | ||
| 177 | .ident = "Sony Vaio FS-115b", | ||
| 178 | .matches = { | ||
| 179 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
| 180 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), | ||
| 181 | }, | ||
| 182 | }, | ||
| 176 | { } | 183 | { } |
| 177 | }; | 184 | }; |
| 178 | 185 | ||
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 509dd0a04c54..5246b35301de 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
| @@ -37,6 +37,16 @@ config USB_HIDINPUT | |||
| 37 | 37 | ||
| 38 | If unsure, say Y. | 38 | If unsure, say Y. |
| 39 | 39 | ||
| 40 | config USB_HIDINPUT_POWERBOOK | ||
| 41 | bool "Enable support for iBook/PowerBook special keys" | ||
| 42 | default n | ||
| 43 | depends on USB_HIDINPUT | ||
| 44 | help | ||
| 45 | Say Y here if you want support for the special keys (Fn, Numlock) on | ||
| 46 | Apple iBooks and PowerBooks. | ||
| 47 | |||
| 48 | If unsure, say N. | ||
| 49 | |||
| 40 | config HID_FF | 50 | config HID_FF |
| 41 | bool "Force feedback support (EXPERIMENTAL)" | 51 | bool "Force feedback support (EXPERIMENTAL)" |
| 42 | depends on USB_HIDINPUT && EXPERIMENTAL | 52 | depends on USB_HIDINPUT && EXPERIMENTAL |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 5f52979af1c7..a91e72c41415 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
| @@ -1450,6 +1450,9 @@ void hid_init_reports(struct hid_device *hid) | |||
| 1450 | #define USB_VENDOR_ID_APPLE 0x05ac | 1450 | #define USB_VENDOR_ID_APPLE 0x05ac |
| 1451 | #define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 | 1451 | #define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 |
| 1452 | 1452 | ||
| 1453 | #define USB_VENDOR_ID_CHERRY 0x046a | ||
| 1454 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 | ||
| 1455 | |||
| 1453 | /* | 1456 | /* |
| 1454 | * Alphabetically sorted blacklist by quirk type. | 1457 | * Alphabetically sorted blacklist by quirk type. |
| 1455 | */ | 1458 | */ |
| @@ -1580,6 +1583,16 @@ static const struct hid_blacklist { | |||
| 1580 | { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, | 1583 | { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, |
| 1581 | { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, | 1584 | { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, |
| 1582 | 1585 | ||
| 1586 | { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, | ||
| 1587 | |||
| 1588 | { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
| 1589 | { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
| 1590 | { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
| 1591 | { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
| 1592 | { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
| 1593 | { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
| 1594 | { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
| 1595 | |||
| 1583 | { 0, 0 } | 1596 | { 0, 0 } |
| 1584 | }; | 1597 | }; |
| 1585 | 1598 | ||
| @@ -1626,6 +1639,20 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) | |||
| 1626 | usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); | 1639 | usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); |
| 1627 | } | 1640 | } |
| 1628 | 1641 | ||
| 1642 | /* | ||
| 1643 | * Cherry Cymotion keyboard have an invalid HID report descriptor, | ||
| 1644 | * that needs fixing before we can parse it. | ||
| 1645 | */ | ||
| 1646 | |||
| 1647 | static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize) | ||
| 1648 | { | ||
| 1649 | if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { | ||
| 1650 | info("Fixing up Cherry Cymotion report descriptor"); | ||
| 1651 | rdesc[11] = rdesc[16] = 0xff; | ||
| 1652 | rdesc[12] = rdesc[17] = 0x03; | ||
| 1653 | } | ||
| 1654 | } | ||
| 1655 | |||
| 1629 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) | 1656 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) |
| 1630 | { | 1657 | { |
| 1631 | struct usb_host_interface *interface = intf->cur_altsetting; | 1658 | struct usb_host_interface *interface = intf->cur_altsetting; |
| @@ -1673,6 +1700,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
| 1673 | return NULL; | 1700 | return NULL; |
| 1674 | } | 1701 | } |
| 1675 | 1702 | ||
| 1703 | if ((quirks & HID_QUIRK_CYMOTION)) | ||
| 1704 | hid_fixup_cymotion_descriptor(rdesc, rsize); | ||
| 1705 | |||
| 1676 | #ifdef DEBUG_DATA | 1706 | #ifdef DEBUG_DATA |
| 1677 | printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); | 1707 | printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); |
| 1678 | for (n = 0; n < rsize; n++) | 1708 | for (n = 0; n < rsize; n++) |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 192a03b28971..cb0d80f49252 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
| @@ -73,6 +73,160 @@ static const struct { | |||
| 73 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) | 73 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) |
| 74 | #define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0) | 74 | #define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0) |
| 75 | 75 | ||
| 76 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | ||
| 77 | |||
| 78 | struct hidinput_key_translation { | ||
| 79 | u16 from; | ||
| 80 | u16 to; | ||
| 81 | u8 flags; | ||
| 82 | }; | ||
| 83 | |||
| 84 | #define POWERBOOK_FLAG_FKEY 0x01 | ||
| 85 | |||
| 86 | static struct hidinput_key_translation powerbook_fn_keys[] = { | ||
| 87 | { KEY_BACKSPACE, KEY_DELETE }, | ||
| 88 | { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY }, | ||
| 89 | { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY }, | ||
| 90 | { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY }, | ||
| 91 | { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY }, | ||
| 92 | { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY }, | ||
| 93 | { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY }, | ||
| 94 | { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY }, | ||
| 95 | { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY }, | ||
| 96 | { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY }, | ||
| 97 | { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY }, | ||
| 98 | { KEY_UP, KEY_PAGEUP }, | ||
| 99 | { KEY_DOWN, KEY_PAGEDOWN }, | ||
| 100 | { KEY_LEFT, KEY_HOME }, | ||
| 101 | { KEY_RIGHT, KEY_END }, | ||
| 102 | { } | ||
| 103 | }; | ||
| 104 | |||
| 105 | static struct hidinput_key_translation powerbook_numlock_keys[] = { | ||
| 106 | { KEY_J, KEY_KP1 }, | ||
| 107 | { KEY_K, KEY_KP2 }, | ||
| 108 | { KEY_L, KEY_KP3 }, | ||
| 109 | { KEY_U, KEY_KP4 }, | ||
| 110 | { KEY_I, KEY_KP5 }, | ||
| 111 | { KEY_O, KEY_KP6 }, | ||
| 112 | { KEY_7, KEY_KP7 }, | ||
| 113 | { KEY_8, KEY_KP8 }, | ||
| 114 | { KEY_9, KEY_KP9 }, | ||
| 115 | { KEY_M, KEY_KP0 }, | ||
| 116 | { KEY_DOT, KEY_KPDOT }, | ||
| 117 | { KEY_SLASH, KEY_KPPLUS }, | ||
| 118 | { KEY_SEMICOLON, KEY_KPMINUS }, | ||
| 119 | { KEY_P, KEY_KPASTERISK }, | ||
| 120 | { KEY_MINUS, KEY_KPEQUAL }, | ||
| 121 | { KEY_0, KEY_KPSLASH }, | ||
| 122 | { KEY_F6, KEY_NUMLOCK }, | ||
| 123 | { KEY_KPENTER, KEY_KPENTER }, | ||
| 124 | { KEY_BACKSPACE, KEY_BACKSPACE }, | ||
| 125 | { } | ||
| 126 | }; | ||
| 127 | |||
| 128 | static int usbhid_pb_fnmode = 1; | ||
| 129 | module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); | ||
| 130 | MODULE_PARM_DESC(pb_fnmode, | ||
| 131 | "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); | ||
| 132 | |||
| 133 | static struct hidinput_key_translation *find_translation(struct hidinput_key_translation *table, u16 from) | ||
| 134 | { | ||
| 135 | struct hidinput_key_translation *trans; | ||
| 136 | |||
| 137 | /* Look for the translation */ | ||
| 138 | for (trans = table; trans->from; trans++) | ||
| 139 | if (trans->from == from) | ||
| 140 | return trans; | ||
| 141 | |||
| 142 | return NULL; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | ||
| 146 | struct hid_usage *usage, __s32 value) | ||
| 147 | { | ||
| 148 | struct hidinput_key_translation *trans; | ||
| 149 | |||
| 150 | if (usage->code == KEY_FN) { | ||
| 151 | if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON; | ||
| 152 | else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON; | ||
| 153 | |||
| 154 | input_event(input, usage->type, usage->code, value); | ||
| 155 | |||
| 156 | return 1; | ||
| 157 | } | ||
| 158 | |||
| 159 | if (usbhid_pb_fnmode) { | ||
| 160 | int do_translate; | ||
| 161 | |||
| 162 | trans = find_translation(powerbook_fn_keys, usage->code); | ||
| 163 | if (trans) { | ||
| 164 | if (test_bit(usage->code, hid->pb_pressed_fn)) | ||
| 165 | do_translate = 1; | ||
| 166 | else if (trans->flags & POWERBOOK_FLAG_FKEY) | ||
| 167 | do_translate = | ||
| 168 | (usbhid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || | ||
| 169 | (usbhid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); | ||
| 170 | else | ||
| 171 | do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); | ||
| 172 | |||
| 173 | if (do_translate) { | ||
| 174 | if (value) | ||
| 175 | set_bit(usage->code, hid->pb_pressed_fn); | ||
| 176 | else | ||
| 177 | clear_bit(usage->code, hid->pb_pressed_fn); | ||
| 178 | |||
| 179 | input_event(input, usage->type, trans->to, value); | ||
| 180 | |||
| 181 | return 1; | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | if (test_bit(usage->code, hid->pb_pressed_numlock) || | ||
| 186 | test_bit(LED_NUML, input->led)) { | ||
| 187 | trans = find_translation(powerbook_numlock_keys, usage->code); | ||
| 188 | |||
| 189 | if (trans) { | ||
| 190 | if (value) | ||
| 191 | set_bit(usage->code, hid->pb_pressed_numlock); | ||
| 192 | else | ||
| 193 | clear_bit(usage->code, hid->pb_pressed_numlock); | ||
| 194 | |||
| 195 | input_event(input, usage->type, trans->to, value); | ||
| 196 | } | ||
| 197 | |||
| 198 | return 1; | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | return 0; | ||
| 203 | } | ||
| 204 | |||
| 205 | static void hidinput_pb_setup(struct input_dev *input) | ||
| 206 | { | ||
| 207 | struct hidinput_key_translation *trans; | ||
| 208 | |||
| 209 | set_bit(KEY_NUMLOCK, input->keybit); | ||
| 210 | |||
| 211 | /* Enable all needed keys */ | ||
| 212 | for (trans = powerbook_fn_keys; trans->from; trans++) | ||
| 213 | set_bit(trans->to, input->keybit); | ||
| 214 | |||
| 215 | for (trans = powerbook_numlock_keys; trans->from; trans++) | ||
| 216 | set_bit(trans->to, input->keybit); | ||
| 217 | } | ||
| 218 | #else | ||
| 219 | static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | ||
| 220 | struct hid_usage *usage, __s32 value) | ||
| 221 | { | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | static inline void hidinput_pb_setup(struct input_dev *input) | ||
| 226 | { | ||
| 227 | } | ||
| 228 | #endif | ||
| 229 | |||
| 76 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, | 230 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, |
| 77 | struct hid_usage *usage) | 231 | struct hid_usage *usage) |
| 78 | { | 232 | { |
| @@ -135,8 +289,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
| 135 | case HID_UP_SIMULATION: | 289 | case HID_UP_SIMULATION: |
| 136 | 290 | ||
| 137 | switch (usage->hid & 0xffff) { | 291 | switch (usage->hid & 0xffff) { |
| 138 | case 0xba: map_abs(ABS_RUDDER); break; | 292 | case 0xba: map_abs(ABS_RUDDER); break; |
| 139 | case 0xbb: map_abs(ABS_THROTTLE); break; | 293 | case 0xbb: map_abs(ABS_THROTTLE); break; |
| 294 | case 0xc4: map_abs(ABS_GAS); break; | ||
| 295 | case 0xc5: map_abs(ABS_BRAKE); break; | ||
| 296 | case 0xc8: map_abs(ABS_WHEEL); break; | ||
| 140 | default: goto ignore; | 297 | default: goto ignore; |
| 141 | } | 298 | } |
| 142 | break; | 299 | break; |
| @@ -289,11 +446,19 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
| 289 | case 0x226: map_key_clear(KEY_STOP); break; | 446 | case 0x226: map_key_clear(KEY_STOP); break; |
| 290 | case 0x227: map_key_clear(KEY_REFRESH); break; | 447 | case 0x227: map_key_clear(KEY_REFRESH); break; |
| 291 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; | 448 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; |
| 449 | case 0x233: map_key_clear(KEY_SCROLLUP); break; | ||
| 450 | case 0x234: map_key_clear(KEY_SCROLLDOWN); break; | ||
| 292 | case 0x238: map_rel(REL_HWHEEL); break; | 451 | case 0x238: map_rel(REL_HWHEEL); break; |
| 293 | case 0x279: map_key_clear(KEY_REDO); break; | 452 | case 0x279: map_key_clear(KEY_REDO); break; |
| 294 | case 0x289: map_key_clear(KEY_REPLY); break; | 453 | case 0x289: map_key_clear(KEY_REPLY); break; |
| 295 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | 454 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; |
| 296 | case 0x28c: map_key_clear(KEY_SEND); break; | 455 | case 0x28c: map_key_clear(KEY_SEND); break; |
| 456 | |||
| 457 | /* Reported on a Cherry Cymotion keyboard */ | ||
| 458 | case 0x301: map_key_clear(KEY_PROG1); break; | ||
| 459 | case 0x302: map_key_clear(KEY_PROG2); break; | ||
| 460 | case 0x303: map_key_clear(KEY_PROG3); break; | ||
| 461 | |||
| 297 | default: goto ignore; | 462 | default: goto ignore; |
| 298 | } | 463 | } |
| 299 | break; | 464 | break; |
| @@ -325,7 +490,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
| 325 | 490 | ||
| 326 | set_bit(EV_REP, input->evbit); | 491 | set_bit(EV_REP, input->evbit); |
| 327 | switch(usage->hid & HID_USAGE) { | 492 | switch(usage->hid & HID_USAGE) { |
| 328 | case 0x003: map_key_clear(KEY_FN); break; | 493 | case 0x003: |
| 494 | /* The fn key on Apple PowerBooks */ | ||
| 495 | map_key_clear(KEY_FN); | ||
| 496 | hidinput_pb_setup(input); | ||
| 497 | break; | ||
| 498 | |||
| 329 | default: goto ignore; | 499 | default: goto ignore; |
| 330 | } | 500 | } |
| 331 | break; | 501 | break; |
| @@ -482,6 +652,9 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
| 482 | return; | 652 | return; |
| 483 | } | 653 | } |
| 484 | 654 | ||
| 655 | if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value)) | ||
| 656 | return; | ||
| 657 | |||
| 485 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 658 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
| 486 | int hat_dir = usage->hat_dir; | 659 | int hat_dir = usage->hat_dir; |
| 487 | if (!hat_dir) | 660 | if (!hat_dir) |
| @@ -524,7 +697,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
| 524 | return; | 697 | return; |
| 525 | } | 698 | } |
| 526 | 699 | ||
| 527 | if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ | 700 | if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ |
| 528 | return; | 701 | return; |
| 529 | 702 | ||
| 530 | input_event(input, usage->type, usage->code, value); | 703 | input_event(input, usage->type, usage->code, value); |
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index ee48a2276104..8b0d4346ce9c 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h | |||
| @@ -235,17 +235,20 @@ struct hid_item { | |||
| 235 | * HID device quirks. | 235 | * HID device quirks. |
| 236 | */ | 236 | */ |
| 237 | 237 | ||
| 238 | #define HID_QUIRK_INVERT 0x001 | 238 | #define HID_QUIRK_INVERT 0x00000001 |
| 239 | #define HID_QUIRK_NOTOUCH 0x002 | 239 | #define HID_QUIRK_NOTOUCH 0x00000002 |
| 240 | #define HID_QUIRK_IGNORE 0x004 | 240 | #define HID_QUIRK_IGNORE 0x00000004 |
| 241 | #define HID_QUIRK_NOGET 0x008 | 241 | #define HID_QUIRK_NOGET 0x00000008 |
| 242 | #define HID_QUIRK_HIDDEV 0x010 | 242 | #define HID_QUIRK_HIDDEV 0x00000010 |
| 243 | #define HID_QUIRK_BADPAD 0x020 | 243 | #define HID_QUIRK_BADPAD 0x00000020 |
| 244 | #define HID_QUIRK_MULTI_INPUT 0x040 | 244 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
| 245 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080 | 245 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 |
| 246 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100 | 246 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 |
| 247 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 | 247 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 |
| 248 | #define HID_QUIRK_2WHEEL_POWERMOUSE 0x400 | 248 | #define HID_QUIRK_2WHEEL_POWERMOUSE 0x00000400 |
| 249 | #define HID_QUIRK_CYMOTION 0x00000800 | ||
| 250 | #define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 | ||
| 251 | #define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 | ||
| 249 | 252 | ||
| 250 | /* | 253 | /* |
| 251 | * This is the global environment of the parser. This information is | 254 | * This is the global environment of the parser. This information is |
| @@ -431,6 +434,11 @@ struct hid_device { /* device report descriptor */ | |||
| 431 | void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */ | 434 | void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */ |
| 432 | int (*ff_event)(struct hid_device *hid, struct input_dev *input, | 435 | int (*ff_event)(struct hid_device *hid, struct input_dev *input, |
| 433 | unsigned int type, unsigned int code, int value); | 436 | unsigned int type, unsigned int code, int value); |
| 437 | |||
| 438 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | ||
| 439 | unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; | ||
| 440 | unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; | ||
| 441 | #endif | ||
| 434 | }; | 442 | }; |
| 435 | 443 | ||
| 436 | #define HID_GLOBAL_STACK_SIZE 4 | 444 | #define HID_GLOBAL_STACK_SIZE 4 |
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c index 19e015d171aa..d9d9f656b8c9 100644 --- a/drivers/usb/input/pid.c +++ b/drivers/usb/input/pid.c | |||
| @@ -259,7 +259,7 @@ static int hid_pid_upload_effect(struct input_dev *dev, | |||
| 259 | int hid_pid_init(struct hid_device *hid) | 259 | int hid_pid_init(struct hid_device *hid) |
| 260 | { | 260 | { |
| 261 | struct hid_ff_pid *private; | 261 | struct hid_ff_pid *private; |
| 262 | struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list); | 262 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); |
| 263 | struct input_dev *input_dev = hidinput->input; | 263 | struct input_dev *input_dev = hidinput->input; |
| 264 | 264 | ||
| 265 | private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL); | 265 | private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL); |
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index 48df4cfd5a42..d3e15df9e815 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c | |||
| @@ -95,7 +95,7 @@ MODULE_LICENSE(DRIVER_LICENSE); | |||
| 95 | enum { | 95 | enum { |
| 96 | PENPARTNER = 0, | 96 | PENPARTNER = 0, |
| 97 | GRAPHIRE, | 97 | GRAPHIRE, |
| 98 | G4, | 98 | WACOM_G4, |
| 99 | PL, | 99 | PL, |
| 100 | INTUOS, | 100 | INTUOS, |
| 101 | INTUOS3, | 101 | INTUOS3, |
| @@ -373,7 +373,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
| 373 | 373 | ||
| 374 | case 2: /* Mouse with wheel */ | 374 | case 2: /* Mouse with wheel */ |
| 375 | input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); | 375 | input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); |
| 376 | if (wacom->features->type == G4) { | 376 | if (wacom->features->type == WACOM_G4) { |
| 377 | rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); | 377 | rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); |
| 378 | input_report_rel(dev, REL_WHEEL, rw); | 378 | input_report_rel(dev, REL_WHEEL, rw); |
| 379 | } else | 379 | } else |
| @@ -385,7 +385,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
| 385 | id = CURSOR_DEVICE_ID; | 385 | id = CURSOR_DEVICE_ID; |
| 386 | input_report_key(dev, BTN_LEFT, data[1] & 0x01); | 386 | input_report_key(dev, BTN_LEFT, data[1] & 0x01); |
| 387 | input_report_key(dev, BTN_RIGHT, data[1] & 0x02); | 387 | input_report_key(dev, BTN_RIGHT, data[1] & 0x02); |
| 388 | if (wacom->features->type == G4) | 388 | if (wacom->features->type == WACOM_G4) |
| 389 | input_report_abs(dev, ABS_DISTANCE, data[6]); | 389 | input_report_abs(dev, ABS_DISTANCE, data[6]); |
| 390 | else | 390 | else |
| 391 | input_report_abs(dev, ABS_DISTANCE, data[7]); | 391 | input_report_abs(dev, ABS_DISTANCE, data[7]); |
| @@ -410,7 +410,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
| 410 | input_sync(dev); | 410 | input_sync(dev); |
| 411 | 411 | ||
| 412 | /* send pad data */ | 412 | /* send pad data */ |
| 413 | if (wacom->features->type == G4) { | 413 | if (wacom->features->type == WACOM_G4) { |
| 414 | /* fist time sending pad data */ | 414 | /* fist time sending pad data */ |
| 415 | if (wacom->tool[1] != BTN_TOOL_FINGER) { | 415 | if (wacom->tool[1] != BTN_TOOL_FINGER) { |
| 416 | wacom->id[1] = 0; | 416 | wacom->id[1] = 0; |
| @@ -713,8 +713,8 @@ static struct wacom_features wacom_features[] = { | |||
| 713 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq }, | 713 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
| 714 | { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq }, | 714 | { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
| 715 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq }, | 715 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
| 716 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, G4, wacom_graphire_irq }, | 716 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, WACOM_G4, wacom_graphire_irq }, |
| 717 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, G4, wacom_graphire_irq }, | 717 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, WACOM_G4, wacom_graphire_irq }, |
| 718 | { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, | 718 | { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
| 719 | { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq }, | 719 | { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq }, |
| 720 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, | 720 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
| @@ -859,7 +859,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 859 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); | 859 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); |
| 860 | 860 | ||
| 861 | switch (wacom->features->type) { | 861 | switch (wacom->features->type) { |
| 862 | case G4: | 862 | case WACOM_G4: |
| 863 | input_dev->evbit[0] |= BIT(EV_MSC); | 863 | input_dev->evbit[0] |= BIT(EV_MSC); |
| 864 | input_dev->mscbit[0] |= BIT(MSC_SERIAL); | 864 | input_dev->mscbit[0] |= BIT(MSC_SERIAL); |
| 865 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); | 865 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); |
