diff options
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 154 |
1 files changed, 92 insertions, 62 deletions
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"); |