lkml.org 
[lkml]   [2012]   [Mar]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 12/16 v2] Input: atmel_mxt_ts - simplify event reporting
Date
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).

Also, the atmel pad reports "amplitude", which is reported to userspace
using the "PRESSURE" event type. The variables now reflect this.

Note: this driver does not really do MT-B properly. Each input report
(a goup 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>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 121 +++++++++---------------------
1 files changed, 35 insertions(+), 86 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0d0dab6..731293b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -195,6 +195,7 @@
#define MXT_BOOT_STATUS_MASK 0x3f

/* Touch status */
+#define MXT_UNGRIP (1 << 0)
#define MXT_SUPPRESS (1 << 1)
#define MXT_AMP (1 << 2)
#define MXT_VECTOR (1 << 3)
@@ -239,14 +240,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;
@@ -254,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;
@@ -488,97 +480,54 @@ static int mxt_write_object(struct mxt_data *data,
return mxt_write_reg(data->client, reg + offset, 1, &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_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;
+ u8 status;
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;
+ int amplitude;

+ status = message->message[0];
x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
y = (message->message[2] << 4) | ((message->message[3] & 0xf));
if (data->max_x < 1024)
- x = x >> 2;
+ x >>= 2;
if (data->max_y < 1024)
- y = y >> 2;
+ y >>= 2;

area = message->message[4];
- pressure = message->message[5];
-
- dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id,
- status & MXT_MOVE ? "moved" : "pressed",
- x, y, 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;
+ amplitude = message->message[5];
+
+ dev_dbg(dev,
+ "[%d] %c%c%c%c%c%c%c%c x: %d y: %d area: %d amp: %d\n",
+ id,
+ (status & MXT_DETECT) ? 'D' : '.',
+ (status & MXT_PRESS) ? 'P' : '.',
+ (status & MXT_RELEASE) ? 'R' : '.',
+ (status & MXT_MOVE) ? 'M' : '.',
+ (status & MXT_VECTOR) ? 'V' : '.',
+ (status & MXT_AMP) ? 'A' : '.',
+ (status & MXT_SUPPRESS) ? 'S' : '.',
+ (status & MXT_UNGRIP) ? 'U' : '.',
+ x, y, area, amplitude);
+
+ 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, amplitude);
+ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
+ }

- 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)
--
1.7.7.3


\
 
 \ /
  Last update: 2012-03-29 18:55    [from the cache]
©2003-2011 Jasper Spaans