ANDROID: goldfish_events: no extra EV_SYN; register goldfish
authorLingfeng Yang <lfy@google.com>
Fri, 18 Dec 2015 20:04:43 +0000 (12:04 -0800)
committerJin Qian <jinqian@google.com>
Thu, 17 Nov 2016 20:26:51 +0000 (12:26 -0800)
If we send SYN_REPORT on every single
multitouch event, it breaks the multitouch.

The multitouch becomes janky and
having to click 2-3 times to
do stuff (plus randomly activating notification
bars when not clicking)

If we suppress these SYN_REPORTS,
multitouch will work fine, plus the events
will have a protocol that looks nice.

In addition, we need to register Goldfish Events
as a multitouch device by issuing
input_mt_init_slots, otherwise
input_handle_abs_event in drivers/input/input.c
will silently drop all ABS_MT_SLOT events,
making it so that touches with more than 1 finger
do not work properly.

Signed-off-by: "Lingfeng Yang" <lfy@google.com>
Change-Id: Ib2350f7d1732449d246f6f0d9b7b08f02cc7c2dd
(cherry picked from commit 6cf40d0a16330e1ef42bdf07d9aba6c16ee11fbc)

drivers/input/keyboard/goldfish_events.c

index f6e643b589b616c61d1751005fedb3288f0ad82c..c877e56a9bd5760f0ef9151460a6fd5f7d99a6b2 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -24,6 +25,8 @@
 #include <linux/io.h>
 #include <linux/acpi.h>
 
+#define GOLDFISH_MAX_FINGERS 5
+
 enum {
        REG_READ        = 0x00,
        REG_SET_PAGE    = 0x00,
@@ -52,7 +55,21 @@ static irqreturn_t events_interrupt(int irq, void *dev_id)
        value = __raw_readl(edev->addr + REG_READ);
 
        input_event(edev->input, type, code, value);
-       input_sync(edev->input);
+       // Send an extra (EV_SYN, SYN_REPORT, 0x0) event
+       // if a key was pressed. Some keyboard device
+        // drivers may only send the EV_KEY event and
+        // not EV_SYN.
+        // Note that sending an extra SYN_REPORT is not
+        // necessary nor correct protocol with other
+        // devices such as touchscreens, which will send
+        // their own SYN_REPORT's when sufficient event
+        // information has been collected (e.g., for
+        // touchscreens, when pressure and X/Y coordinates
+       // have been received). Hence, we will only send
+       // this extra SYN_REPORT if type == EV_KEY.
+       if (type == EV_KEY) {
+               input_sync(edev->input);
+       }
        return IRQ_HANDLED;
 }
 
@@ -154,6 +171,15 @@ static int events_probe(struct platform_device *pdev)
 
        input_dev->name = edev->name;
        input_dev->id.bustype = BUS_HOST;
+       // Set the Goldfish Device to be multi-touch.
+       // In the Ranchu kernel, there is multi-touch-specific
+       // code for handling ABS_MT_SLOT events.
+       // See drivers/input/input.c:input_handle_abs_event.
+       // If we do not issue input_mt_init_slots,
+        // the kernel will filter out needed ABS_MT_SLOT
+        // events when we touch the screen in more than one place,
+        // preventing multi-touch with more than one finger from working.
+       input_mt_init_slots(input_dev, GOLDFISH_MAX_FINGERS, 0);
 
        events_import_bits(edev, input_dev->evbit, EV_SYN, EV_MAX);
        events_import_bits(edev, input_dev->keybit, EV_KEY, KEY_MAX);