aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/mouse/synaptics.c47
-rw-r--r--drivers/input/mouse/synaptics.h5
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
582static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet) 582static 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
596static void synaptics_pt_activate(struct psmouse *psmouse) 600static 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
868static void synaptics_report_buttons(struct psmouse *psmouse, 891static 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 */