diff options
| -rw-r--r-- | drivers/input/mouse/synaptics.c | 47 | ||||
| -rw-r--r-- | drivers/input/mouse/synaptics.h | 5 |
2 files changed, 41 insertions, 11 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 9d599eb79f17..ecc7811cbd46 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -579,18 +579,22 @@ static int synaptics_is_pt_packet(unsigned char *buf) | |||
| 579 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; | 579 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; |
| 580 | } | 580 | } |
| 581 | 581 | ||
| 582 | static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet) | 582 | static void synaptics_pass_pt_packet(struct psmouse *psmouse, |
| 583 | struct serio *ptport, | ||
| 584 | unsigned char *packet) | ||
| 583 | { | 585 | { |
| 586 | struct synaptics_data *priv = psmouse->private; | ||
| 584 | struct psmouse *child = serio_get_drvdata(ptport); | 587 | struct psmouse *child = serio_get_drvdata(ptport); |
| 585 | 588 | ||
| 586 | if (child && child->state == PSMOUSE_ACTIVATED) { | 589 | if (child && child->state == PSMOUSE_ACTIVATED) { |
| 587 | serio_interrupt(ptport, packet[1], 0); | 590 | serio_interrupt(ptport, packet[1] | priv->pt_buttons, 0); |
| 588 | serio_interrupt(ptport, packet[4], 0); | 591 | serio_interrupt(ptport, packet[4], 0); |
| 589 | serio_interrupt(ptport, packet[5], 0); | 592 | serio_interrupt(ptport, packet[5], 0); |
| 590 | if (child->pktsize == 4) | 593 | if (child->pktsize == 4) |
| 591 | serio_interrupt(ptport, packet[2], 0); | 594 | serio_interrupt(ptport, packet[2], 0); |
| 592 | } else | 595 | } else { |
| 593 | serio_interrupt(ptport, packet[1], 0); | 596 | serio_interrupt(ptport, packet[1], 0); |
| 597 | } | ||
| 594 | } | 598 | } |
| 595 | 599 | ||
| 596 | static void synaptics_pt_activate(struct psmouse *psmouse) | 600 | static void synaptics_pt_activate(struct psmouse *psmouse) |
| @@ -847,6 +851,7 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse, | |||
| 847 | struct input_dev *dev = psmouse->dev; | 851 | struct input_dev *dev = psmouse->dev; |
| 848 | struct synaptics_data *priv = psmouse->private; | 852 | struct synaptics_data *priv = psmouse->private; |
| 849 | int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; | 853 | int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; |
| 854 | char buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
| 850 | int i; | 855 | int i; |
| 851 | 856 | ||
| 852 | if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) | 857 | if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) |
| @@ -857,12 +862,30 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse, | |||
| 857 | !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) | 862 | !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) |
| 858 | return; | 863 | return; |
| 859 | 864 | ||
| 860 | for (i = 0; i < ext_bits; i++) { | 865 | if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) { |
| 861 | input_report_key(dev, BTN_0 + 2 * i, | 866 | for (i = 0; i < ext_bits; i++) { |
| 862 | hw->ext_buttons & (1 << i)); | 867 | input_report_key(dev, BTN_0 + 2 * i, |
| 863 | input_report_key(dev, BTN_1 + 2 * i, | 868 | hw->ext_buttons & (1 << i)); |
| 864 | hw->ext_buttons & (1 << (i + ext_bits))); | 869 | input_report_key(dev, BTN_1 + 2 * i, |
| 870 | hw->ext_buttons & (1 << (i + ext_bits))); | ||
| 871 | } | ||
| 872 | return; | ||
| 865 | } | 873 | } |
| 874 | |||
| 875 | /* | ||
| 876 | * This generation of touchpads has the trackstick buttons | ||
| 877 | * physically wired to the touchpad. Re-route them through | ||
| 878 | * the pass-through interface. | ||
| 879 | */ | ||
| 880 | if (!priv->pt_port) | ||
| 881 | return; | ||
| 882 | |||
| 883 | /* The trackstick expects at most 3 buttons */ | ||
| 884 | priv->pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons) | | ||
| 885 | SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 | | ||
| 886 | SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2; | ||
| 887 | |||
| 888 | synaptics_pass_pt_packet(psmouse, priv->pt_port, buf); | ||
| 866 | } | 889 | } |
| 867 | 890 | ||
| 868 | static void synaptics_report_buttons(struct psmouse *psmouse, | 891 | static void synaptics_report_buttons(struct psmouse *psmouse, |
| @@ -1459,7 +1482,8 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
| 1459 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && | 1482 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && |
| 1460 | synaptics_is_pt_packet(psmouse->packet)) { | 1483 | synaptics_is_pt_packet(psmouse->packet)) { |
| 1461 | if (priv->pt_port) | 1484 | if (priv->pt_port) |
| 1462 | synaptics_pass_pt_packet(priv->pt_port, psmouse->packet); | 1485 | synaptics_pass_pt_packet(psmouse, priv->pt_port, |
| 1486 | psmouse->packet); | ||
| 1463 | } else | 1487 | } else |
| 1464 | synaptics_process_packet(psmouse); | 1488 | synaptics_process_packet(psmouse); |
| 1465 | 1489 | ||
| @@ -1561,8 +1585,9 @@ static void set_input_params(struct psmouse *psmouse, | |||
| 1561 | __set_bit(BTN_BACK, dev->keybit); | 1585 | __set_bit(BTN_BACK, dev->keybit); |
| 1562 | } | 1586 | } |
| 1563 | 1587 | ||
| 1564 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | 1588 | if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) |
| 1565 | __set_bit(BTN_0 + i, dev->keybit); | 1589 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) |
| 1590 | __set_bit(BTN_0 + i, dev->keybit); | ||
| 1566 | 1591 | ||
| 1567 | __clear_bit(EV_REL, dev->evbit); | 1592 | __clear_bit(EV_REL, dev->evbit); |
| 1568 | __clear_bit(REL_X, dev->relbit); | 1593 | __clear_bit(REL_X, dev->relbit); |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 8d3761ce8f54..f39539c70219 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
| @@ -111,6 +111,10 @@ | |||
| 111 | #define SYN_CAP_EXT_BUTTONS_STICK(ex10) ((ex10) & 0x010000) | 111 | #define SYN_CAP_EXT_BUTTONS_STICK(ex10) ((ex10) & 0x010000) |
| 112 | #define SYN_CAP_SECUREPAD(ex10) ((ex10) & 0x020000) | 112 | #define SYN_CAP_SECUREPAD(ex10) ((ex10) & 0x020000) |
| 113 | 113 | ||
| 114 | #define SYN_CAP_EXT_BUTTON_STICK_L(eb) (!!((eb) & 0x01)) | ||
| 115 | #define SYN_CAP_EXT_BUTTON_STICK_M(eb) (!!((eb) & 0x02)) | ||
| 116 | #define SYN_CAP_EXT_BUTTON_STICK_R(eb) (!!((eb) & 0x04)) | ||
| 117 | |||
| 114 | /* synaptics modes query bits */ | 118 | /* synaptics modes query bits */ |
| 115 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 119 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
| 116 | #define SYN_MODE_RATE(m) ((m) & (1 << 6)) | 120 | #define SYN_MODE_RATE(m) ((m) & (1 << 6)) |
| @@ -192,6 +196,7 @@ struct synaptics_data { | |||
| 192 | bool disable_gesture; /* disable gestures */ | 196 | bool disable_gesture; /* disable gestures */ |
| 193 | 197 | ||
| 194 | struct serio *pt_port; /* Pass-through serio port */ | 198 | struct serio *pt_port; /* Pass-through serio port */ |
| 199 | unsigned char pt_buttons; /* Pass-through buttons */ | ||
| 195 | 200 | ||
| 196 | struct synaptics_mt_state mt_state; /* Current mt finger state */ | 201 | struct synaptics_mt_state mt_state; /* Current mt finger state */ |
| 197 | bool mt_state_lost; /* mt_state may be incorrect */ | 202 | bool mt_state_lost; /* mt_state may be incorrect */ |
