Inter-revision diff: patch 12

Comparing v4 (message) to v2 (message)

--- v4
+++ v2
@@ -1,53 +1,190 @@
-Write each object using a single bulk i2c write transfer.
+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>
-Reviewed-by: Joonyoung Shim <jy0922.shim@samsung.com>
 ---
- drivers/input/touchscreen/atmel_mxt_ts.c |   24 ++++++++++++------------
- 1 files changed, 12 insertions(+), 12 deletions(-)
+ 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 2e49488..efce50f 100644
+index 0d0dab6..731293b 100644
 --- a/drivers/input/touchscreen/atmel_mxt_ts.c
 +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
-@@ -653,7 +653,8 @@ static int mxt_check_reg_init(struct mxt_data *data)
- 	struct mxt_object *object;
+@@ -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;
- 	int index = 0;
--	int i, j, config_offset;
-+	int i, size;
-+	int ret;
+-	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;
  
- 	if (!pdata->config) {
- 		dev_dbg(dev, "No cfg data defined, skipping reg init\n");
-@@ -666,18 +667,17 @@ static int mxt_check_reg_init(struct mxt_data *data)
- 		if (!mxt_object_writable(object->type))
- 			continue;
++	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;
  
--		for (j = 0;
--		     j < (object->size + 1) * (object->instances + 1);
--		     j++) {
--			config_offset = index + j;
--			if (config_offset > pdata->config_length) {
--				dev_err(dev, "Not enough config data!\n");
--				return -EINVAL;
--			}
--			mxt_write_object(data, object->type, j,
--					 pdata->config[config_offset]);
-+		size = (object->size + 1) * (object->instances + 1);
-+		if (index + size > pdata->config_length) {
-+			dev_err(dev, "Not enough config data!\n");
-+			return -EINVAL;
- 		}
--		index += (object->size + 1) * (object->instances + 1);
+ 	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];
 +
-+		ret = __mxt_write_reg(data->client, object->start_address,
-+				size, &pdata->config[index]);
-+		if (ret)
-+			return ret;
-+		index += size;
- 	}
++	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);
++	}
  
- 	return 0;
+-	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
+
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help