]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/input/touchscreen/egalax_ts.c
KARO: cleanup after merge of Freescale 3.10.17 stuff
[karo-tx-linux.git] / drivers / input / touchscreen / egalax_ts.c
index db214af0ebd21aa19fbf081c132988b0639f5242..c8057847d71d475a02450cb294d08b9cc17419bc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver for EETI eGalax Multiple Touch Controller
  *
- * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
  *
  * based on max11801_ts.c
  *
@@ -34,7 +34,7 @@
  * which can only report one point at a given time.
  * This driver will ignore events in this mode.
  */
-#define REPORT_MODE_SINGLE             0x1
+#define REPORT_MODE_MOUSE              0x1
 /*
  * Vendor Mode: this mode is used to transfer some vendor specific
  * messages.
@@ -46,8 +46,6 @@
 
 #define MAX_SUPPORT_POINTS             5
 
-#define EVENT_MODE             0
-#define EVENT_STATUS           1
 #define EVENT_VALID_OFFSET     7
 #define EVENT_VALID_MASK       (0x1 << EVENT_VALID_OFFSET)
 #define EVENT_ID_OFFSET                2
 
 #define MAX_I2C_DATA_LEN       10
 
-#define EGALAX_MAX_X   32767
-#define EGALAX_MAX_Y   32767
+#define EGALAX_MAX_X   32760
+#define EGALAX_MAX_Y   32760
 #define EGALAX_MAX_TRIES 100
 
-struct egalax_pointer {
-       bool valid;
-       bool status;
-       u16 x;
-       u16 y;
-};
-
 struct egalax_ts {
        struct i2c_client               *client;
        struct input_dev                *input_dev;
-       struct egalax_pointer           events[MAX_SUPPORT_POINTS];
 };
 
 static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
@@ -79,9 +69,8 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
        struct egalax_ts *ts = dev_id;
        struct input_dev *input_dev = ts->input_dev;
        struct i2c_client *client = ts->client;
-       struct egalax_pointer *events = ts->events;
        u8 buf[MAX_I2C_DATA_LEN];
-       int i, id, ret, x, y;
+       int id, ret, x, y, z;
        int tries = 0;
        bool down, valid;
        u8 state;
@@ -93,38 +82,15 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
        if (ret < 0)
                return IRQ_HANDLED;
 
-       dev_dbg(&client->dev, "recv ret:%d", ret);
-       for (i = 0; i < MAX_I2C_DATA_LEN; i++)
-               dev_dbg(&client->dev, " %x ", buf[i]);
-
-       if (buf[0] != REPORT_MODE_VENDOR
-           && buf[0] != REPORT_MODE_SINGLE
-           && buf[0] != REPORT_MODE_MTTOUCH) {
-               /* invalid point */
-               return IRQ_HANDLED;
-       }
-
-       if (buf[0] == REPORT_MODE_VENDOR) {
-               dev_dbg(&client->dev, "vendor message, ignored\n");
+       if (buf[0] != REPORT_MODE_MTTOUCH) {
+               /* ignore mouse events and vendor events */
                return IRQ_HANDLED;
        }
 
        state = buf[1];
        x = (buf[3] << 8) | buf[2];
        y = (buf[5] << 8) | buf[4];
-
-       /* Currently, the panel Freescale using on SMD board _NOT_
-        * support single pointer mode. All event are going to
-        * multiple pointer mode.  Add single pointer mode according
-        * to EETI eGalax I2C programming manual.
-        */
-       if (buf[0] == REPORT_MODE_SINGLE) {
-               input_report_abs(input_dev, ABS_X, x);
-               input_report_abs(input_dev, ABS_Y, y);
-               input_report_key(input_dev, BTN_TOUCH, !!state);
-               input_sync(input_dev);
-               return IRQ_HANDLED;
-       }
+       z = (buf[7] << 8) | buf[6];
 
        valid = state & EVENT_VALID_MASK;
        id = (state & EVENT_ID_MASK) >> EVENT_ID_OFFSET;
@@ -135,50 +101,19 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
                return IRQ_HANDLED;
        }
 
+       input_mt_slot(input_dev, id);
+       input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, down);
+
+       dev_dbg(&client->dev, "%s id:%d x:%d y:%d z:%d",
+               down ? "down" : "up", id, x, y, z);
+
        if (down) {
-               events[id].valid = valid;
-               events[id].status = down;
-               events[id].x = x;
-               events[id].y = y;
-
-#ifdef CONFIG_TOUCHSCREEN_EGALAX_SINGLE_TOUCH
-               input_report_abs(input_dev, ABS_X, x);
-               input_report_abs(input_dev, ABS_Y, y);
-               input_event(ts->input_dev, EV_KEY, BTN_TOUCH, 1);
-               input_report_abs(input_dev, ABS_PRESSURE, 1);
-#endif
-       } else {
-               dev_dbg(&client->dev, "release id:%d\n", id);
-               events[id].valid = 0;
-               events[id].status = 0;
-#ifdef CONFIG_TOUCHSCREEN_EGALAX_SINGLE_TOUCH
-               input_report_key(input_dev, BTN_TOUCH, 0);
-               input_report_abs(input_dev, ABS_PRESSURE, 0);
-#else
-               input_report_abs(input_dev, ABS_MT_TRACKING_ID, id);
-               input_event(input_dev, EV_ABS, ABS_MT_TOUCH_MAJOR, 0);
-               input_mt_sync(input_dev);
-#endif
+               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, z);
        }
 
-#ifndef CONFIG_TOUCHSCREEN_EGALAX_SINGLE_TOUCH
-       /* report all pointers */
-       for (i = 0; i < MAX_SUPPORT_POINTS; i++) {
-               if (!events[i].valid)
-                       continue;
-               dev_dbg(&client->dev, "report id:%d valid:%d x:%d y:%d",
-                       i, valid, x, y);
-                       input_report_abs(input_dev,
-                                ABS_MT_TRACKING_ID, i);
-               input_report_abs(input_dev,
-                                ABS_MT_TOUCH_MAJOR, 1);
-               input_report_abs(input_dev,
-                                ABS_MT_POSITION_X, events[i].x);
-               input_report_abs(input_dev,
-                                ABS_MT_POSITION_Y, events[i].y);
-               input_mt_sync(input_dev);
-       }
-#endif
+       input_mt_report_pointer_emulation(input_dev, true);
        input_sync(input_dev);
 
        return IRQ_HANDLED;
@@ -264,34 +199,21 @@ static int egalax_ts_probe(struct i2c_client *client,
                return error;
        }
 
-       input_dev->name = "eGalax Touch Screen";
-       input_dev->phys = "I2C",
+       input_dev->name = "EETI eGalax Touch Screen";
        input_dev->id.bustype = BUS_I2C;
-       input_dev->id.vendor = 0x0EEF;
-       input_dev->id.product = 0x0020;
-       input_dev->id.version = 0x0001;
-       input_dev->dev.parent = &client->dev;
 
        __set_bit(EV_ABS, input_dev->evbit);
        __set_bit(EV_KEY, input_dev->evbit);
        __set_bit(BTN_TOUCH, input_dev->keybit);
-       __set_bit(ABS_X, input_dev->absbit);
-       __set_bit(ABS_Y, input_dev->absbit);
-       __set_bit(ABS_PRESSURE, input_dev->absbit);
+
        input_set_abs_params(input_dev, ABS_X, 0, EGALAX_MAX_X, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, EGALAX_MAX_Y, 0, 0);
-       input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0);
-
-#ifndef CONFIG_TOUCHSCREEN_EGALAX_SINGLE_TOUCH
-       input_set_abs_params(input_dev, ABS_MT_POSITION_X,
-                               0, EGALAX_MAX_X, 0, 0);
-       input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
-                               0, EGALAX_MAX_Y, 0, 0);
-       input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
-       input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
-       input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
-                            MAX_SUPPORT_POINTS, 0, 0);
-#endif
+       input_set_abs_params(input_dev,
+                            ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0);
+       input_set_abs_params(input_dev,
+                            ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0);
+       input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0);
+
        input_set_drvdata(input_dev, ts);
 
        error = devm_request_threaded_irq(&client->dev, client->irq, NULL,