aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/mouse/psmouse-base.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 074bc647509d..f0b16eb4a32a 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -70,6 +70,10 @@ static bool psmouse_smartscroll = true;
module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);
MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
+static bool psmouse_a4tech_2wheels;
+module_param_named(a4tech_workaround, psmouse_a4tech_2wheels, bool, 0644);
+MODULE_PARM_DESC(a4tech_workaround, "A4Tech second scroll wheel workaround, 1 = enabled, 0 = disabled (default).");
+
static unsigned int psmouse_resetafter = 5;
module_param_named(resetafter, psmouse_resetafter, uint, 0644);
MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
@@ -150,6 +154,7 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
{
struct input_dev *dev = psmouse->dev;
u8 *packet = psmouse->packet;
+ int wheel;
if (psmouse->pktcnt < psmouse->pktsize)
return PSMOUSE_GOOD_DATA;
@@ -175,8 +180,18 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
break;
case 0x00:
case 0xC0:
- input_report_rel(dev, REL_WHEEL,
- -sign_extend32(packet[3], 3));
+ wheel = sign_extend32(packet[3], 3);
+
+ /*
+ * Some A4Tech mice have two scroll wheels, with first
+ * one reporting +/-1 in the lower nibble, and second
+ * one reporting +/-2.
+ */
+ if (psmouse_a4tech_2wheels && abs(wheel) > 1)
+ input_report_rel(dev, REL_HWHEEL, wheel / 2);
+ else
+ input_report_rel(dev, REL_WHEEL, -wheel);
+
input_report_key(dev, BTN_SIDE, BIT(4));
input_report_key(dev, BTN_EXTRA, BIT(5));
break;