/*
* 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
*
* 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.
#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)
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;
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;
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;
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,