diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2015-03-09 08:32:43 +0300 |
---|---|---|
committer | Zefan Li <lizefan@huawei.com> | 2015-06-19 06:40:26 +0300 |
commit | 13f2db83510a5fec40e5cefefe1369a632165e74 (patch) | |
tree | 0d695c389011c6b59319fe363551393c9421fbce /drivers/input | |
parent | 154e0eca0bf43d289fffa96b116702ab7377e75d (diff) | |
download | linux-13f2db83510a5fec40e5cefefe1369a632165e74.tar.xz |
Input: synaptics - handle spurious release of trackstick buttons
commit ebc80840b850db72f7ae84fbcf77630ae5409629 upstream.
The Fimware 8.1 has a bug in which the extra buttons are only sent when the
ExtBit is 1. This should be fixed in a future FW update which should have
a bump of the minor version.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Acked-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Zefan Li <lizefan@huawei.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/mouse/synaptics.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 65244987b0d3..6d6198a3d52f 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -674,14 +674,36 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, } } -static void synaptics_report_buttons(struct psmouse *psmouse, - const struct synaptics_hw_state *hw) +static void synaptics_report_ext_buttons(struct psmouse *psmouse, + const struct synaptics_hw_state *hw) { struct input_dev *dev = psmouse->dev; struct synaptics_data *priv = psmouse->private; int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; int i; + if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) + return; + + /* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */ + if (SYN_ID_FULL(priv->identity) == 0x801 && + !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) + return; + + for (i = 0; i < ext_bits; i++) { + input_report_key(dev, BTN_0 + 2 * i, + hw->ext_buttons & (1 << i)); + input_report_key(dev, BTN_1 + 2 * i, + hw->ext_buttons & (1 << (i + ext_bits))); + } +} + +static void synaptics_report_buttons(struct psmouse *psmouse, + const struct synaptics_hw_state *hw) +{ + struct input_dev *dev = psmouse->dev; + struct synaptics_data *priv = psmouse->private; + input_report_key(dev, BTN_LEFT, hw->left); input_report_key(dev, BTN_RIGHT, hw->right); @@ -693,12 +715,7 @@ static void synaptics_report_buttons(struct psmouse *psmouse, input_report_key(dev, BTN_BACK, hw->down); } - for (i = 0; i < ext_bits; i++) { - input_report_key(dev, BTN_0 + 2 * i, - hw->ext_buttons & (1 << i)); - input_report_key(dev, BTN_1 + 2 * i, - hw->ext_buttons & (1 << (i + ext_bits))); - } + synaptics_report_ext_buttons(psmouse, hw); } static void synaptics_report_slot(struct input_dev *dev, int slot, |