Input: atmel_mxt_ts - simplify event reporting
authorDaniel Kurtz <djkurtz@chromium.org>
Thu, 28 Jun 2012 13:08:17 +0000 (21:08 +0800)
committerHenrik Rydberg <rydberg@euromail.se>
Fri, 29 Jun 2012 13:58:05 +0000 (15:58 +0200)
Instead of carrying around per-finger state in the driver instance, just
report each finger as it arrives to the input layer, and let the input
layer (evdev) hold the event state (which it does anyway).

Note: this driver does not really do MT-B properly. Each input report
(a group of input events followed by a SYN_REPORT) only contains data for
a single contact.  When multiple fingers are present on a device, each is
properly reported in its own MT_SLOT.  However, there is only ever one
MT_SLOT per SYN_REPORT.  This is fixed in a subsequent patch.

This patch was tested with an mXT224E.

Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
drivers/input/touchscreen/atmel_mxt_ts.c

index f2c1fbe2556e3543d5a0125ffb79c1ccb12ff482..c37584de49ca404f847407aea3bc9a3f5310f0fd 100644 (file)
@@ -239,14 +239,6 @@ struct mxt_message {
        u8 message[7];
 };
 
-struct mxt_finger {
-       int status;
-       int x;
-       int y;
-       int area;
-       int pressure;
-};
-
 /* Each client has this additional data */
 struct mxt_data {
        struct i2c_client *client;
@@ -255,7 +247,6 @@ struct mxt_data {
        const struct mxt_platform_data *pdata;
        struct mxt_object *object_table;
        struct mxt_info info;
-       struct mxt_finger finger[MXT_MAX_FINGER];
        unsigned int irq;
        unsigned int max_x;
        unsigned int max_y;
@@ -519,75 +510,17 @@ static int mxt_write_object(struct mxt_data *data,
        return mxt_write_reg(data->client, reg + offset, val);
 }
 
-static void mxt_input_report(struct mxt_data *data, int single_id)
-{
-       struct mxt_finger *finger = data->finger;
-       struct input_dev *input_dev = data->input_dev;
-       int status = finger[single_id].status;
-       int finger_num = 0;
-       int id;
-
-       for (id = 0; id < MXT_MAX_FINGER; id++) {
-               if (!finger[id].status)
-                       continue;
-
-               input_mt_slot(input_dev, id);
-               input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
-                               finger[id].status != MXT_RELEASE);
-
-               if (finger[id].status != MXT_RELEASE) {
-                       finger_num++;
-                       input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
-                                       finger[id].area);
-                       input_report_abs(input_dev, ABS_MT_POSITION_X,
-                                       finger[id].x);
-                       input_report_abs(input_dev, ABS_MT_POSITION_Y,
-                                       finger[id].y);
-                       input_report_abs(input_dev, ABS_MT_PRESSURE,
-                                       finger[id].pressure);
-               } else {
-                       finger[id].status = 0;
-               }
-       }
-
-       input_report_key(input_dev, BTN_TOUCH, finger_num > 0);
-
-       if (status != MXT_RELEASE) {
-               input_report_abs(input_dev, ABS_X, finger[single_id].x);
-               input_report_abs(input_dev, ABS_Y, finger[single_id].y);
-               input_report_abs(input_dev,
-                                ABS_PRESSURE, finger[single_id].pressure);
-       }
-
-       input_sync(input_dev);
-}
-
 static void mxt_input_touchevent(struct mxt_data *data,
                                      struct mxt_message *message, int id)
 {
-       struct mxt_finger *finger = data->finger;
        struct device *dev = &data->client->dev;
        u8 status = message->message[0];
+       struct input_dev *input_dev = data->input_dev;
        int x;
        int y;
        int area;
        int pressure;
 
-       /* Check the touch is present on the screen */
-       if (!(status & MXT_DETECT)) {
-               if (status & MXT_RELEASE) {
-                       dev_dbg(dev, "[%d] released\n", id);
-
-                       finger[id].status = MXT_RELEASE;
-                       mxt_input_report(data, id);
-               }
-               return;
-       }
-
-       /* Check only AMP detection */
-       if (!(status & (MXT_PRESS | MXT_MOVE)))
-               return;
-
        x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
        y = (message->message[2] << 4) | ((message->message[3] & 0xf));
        if (data->max_x < 1024)
@@ -601,15 +534,19 @@ static void mxt_input_touchevent(struct mxt_data *data,
        dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id,
                status & MXT_MOVE ? "moved" : "pressed",
                x, y, area);
+       input_mt_slot(input_dev, id);
+       input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+                                  status & MXT_DETECT);
+
+       if (status & MXT_DETECT) {
+               input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+               input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+               input_report_abs(input_dev, ABS_MT_PRESSURE, pressure);
+               input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
+       }
 
-       finger[id].status = status & MXT_MOVE ?
-                               MXT_MOVE : MXT_PRESS;
-       finger[id].x = x;
-       finger[id].y = y;
-       finger[id].area = area;
-       finger[id].pressure = pressure;
-
-       mxt_input_report(data, id);
+       input_mt_report_pointer_emulation(input_dev, false);
+       input_sync(input_dev);
 }
 
 static irqreturn_t mxt_interrupt(int irq, void *dev_id)