linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Kurtz <djkurtz@chromium.org>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Joonyoung Shim <jy0922.shim@samsung.com>,
	Iiro Valkonen <iiro.valkonen@atmel.com>,
	Henrik Rydberg <rydberg@euromail.se>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Benson Leung <bleung@chromium.org>,
	Yufeng Shen <miletus@chromium.org>,
	Daniel Kurtz <djkurtz@chromium.org>
Subject: [PATCH 18/20] Input: atmel_mxt_ts - read num messages, then all messages
Date: Tue, 13 Mar 2012 20:04:21 +0800	[thread overview]
Message-ID: <1331640263-18935-19-git-send-email-djkurtz@chromium.org> (raw)
In-Reply-To: <1331640263-18935-1-git-send-email-djkurtz@chromium.org>

Implement the MXT DMA method of reading messages.
On an interrupt, the T44 report always contains the number of messages
pending to be read.  So, read 1 byte from T44 in 1 i2c transaction, then
read the N pending messages in a second transaction.

The end result is a much much faster read time for all pending messages.
Using 400kHz i2c, it is possible to read 10 pending messages (e.g. for 10
moving contatcts) in less than 2.8ms, which is well less than the typical
10-15ms update rate.

Note: There is a possible optimization here.  The T44 byte is guaranteed
to always be right before the T5 address.  Thus, it should be possible
to always fetch the T44 message count and the first message in a single
transaction.  This would eliminate the overhead of a second complete read
transaction for the case where there is only a single pending message.
(This is actually the most common case, for instance with just 1-contact
on the device touch surface). This optimization, however, is not done in
this patch.

Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   92 ++++++++++++++++++++----------
 1 files changed, 61 insertions(+), 31 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 88a474e..dafc030 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -251,8 +251,10 @@ struct mxt_data {
 	unsigned int max_y;
 
 	/* Cached parameters from object table */
+	u16 T5_address;
 	u8 T9_reportid_min;
 	u8 T9_reportid_max;
+	u16 T44_address;
 };
 
 static bool mxt_object_readable(unsigned int type)
@@ -486,21 +488,6 @@ static int mxt_read_object(struct mxt_data *data, struct mxt_object *object,
 			    val);
 }
 
-static int mxt_read_message(struct mxt_data *data,
-				 struct mxt_message *message)
-{
-	struct mxt_object *object;
-	u16 reg;
-
-	object = mxt_get_object(data, MXT_GEN_MESSAGE_T5);
-	if (!object)
-		return -EINVAL;
-
-	reg = object->start_address;
-	return mxt_read_reg(data->client, reg, sizeof(struct mxt_message),
-			    message);
-}
-
 static int mxt_write_object(struct mxt_data *data,
 				 u8 type, u8 offset, u8 val)
 {
@@ -515,6 +502,19 @@ static int mxt_write_object(struct mxt_data *data,
 	return mxt_write_reg(data->client, reg + offset, 1, &val);
 }
 
+static int mxt_read_num_messages(struct mxt_data *data, u8 *count)
+{
+	/* TODO: Optimization: read first message along with message count */
+	return mxt_read_reg(data->client, data->T44_address, 1, count);
+}
+
+static int mxt_read_messages(struct mxt_data *data, u8 count,
+			     struct mxt_message *messages)
+{
+	return mxt_read_reg(data->client, data->T5_address,
+			    sizeof(struct mxt_message) * count, messages);
+}
+
 static void mxt_input_touchevent(struct mxt_data *data,
 				 struct mxt_message *message)
 {
@@ -575,26 +575,50 @@ static void mxt_input_touchevent(struct mxt_data *data,
 	input_sync(input_dev);
 }
 
-static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+static int mxt_proc_messages(struct mxt_data *data, u8 count)
 {
-	struct mxt_data *data = dev_id;
-	struct mxt_message message;
 	struct device *dev = &data->client->dev;
+	struct mxt_message messages[count], *msg;
+	int ret;
 
-	do {
-		if (mxt_read_message(data, &message)) {
-			dev_err(dev, "Failed to read message\n");
-			goto end;
-		}
+	ret = mxt_read_messages(data, count, messages);
+	if (ret) {
+		dev_err(dev, "Failed to read %u messages (%d).\n", count, ret);
+		return ret;
+	}
+
+	for (msg = messages; msg < &messages[count]; msg++) {
+		mxt_dump_message(dev, msg);
+
+		if (msg->reportid >= data->T9_reportid_min &&
+		    msg->reportid <= data->T9_reportid_max)
+			mxt_input_touchevent(data, msg);
+	}
+
+	return 0;
+}
+
+static int mxt_handle_messages(struct mxt_data *data)
+{
+	struct device *dev = &data->client->dev;
+	int ret;
+	u8 count;
 
-		if (message.reportid >= data->T9_reportid_min &&
-		    message.reportid <= data->T9_reportid_max)
-			mxt_input_touchevent(data, &message);
-		else
-			mxt_dump_message(dev, &message);
-	} while (message.reportid != 0xff);
+	ret = mxt_read_num_messages(data, &count);
+	if (ret) {
+		dev_err(dev, "Failed to read message count (%d).\n", ret);
+		return ret;
+	}
 
-end:
+	if (count > 0)
+		ret = mxt_proc_messages(data, count);
+
+	return ret;
+}
+
+static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+{
+	mxt_handle_messages(dev_id);
 	return IRQ_HANDLED;
 }
 
@@ -642,7 +666,7 @@ static int mxt_make_highchg(struct mxt_data *data)
 
 	/* Read dummy message to make high CHG pin */
 	do {
-		error = mxt_read_message(data, &message);
+		error = mxt_read_messages(data, 1, &message);
 		if (error)
 			return error;
 	} while (message.reportid != 0xff && --count);
@@ -743,11 +767,17 @@ static int mxt_get_object_table(struct mxt_data *data)
 
 		/* Save data for objects used when processing interrupts */
 		switch (object->type) {
+		case MXT_GEN_MESSAGE_T5:
+			data->T5_address = object->start_address;
+			break;
 		case MXT_TOUCH_MULTI_T9:
 			data->T9_reportid_max = object->max_reportid;
 			data->T9_reportid_min = data->T9_reportid_max -
 						object->num_report_ids + 1;
 			break;
+		case MXT_SPT_MESSAGECOUNT_T44:
+			data->T44_address = object->start_address;
+			break;
 		}
 	}
 
-- 
1.7.7.3


  parent reply	other threads:[~2012-03-13 12:04 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-13 12:04 [PATCH 00/20] cleanup atmel_mxt_ts Daniel Kurtz
2012-03-13 12:04 ` [PATCH 01/20] Input: atmel_mxt_ts - use CONFIG_PM_SLEEP Daniel Kurtz
2012-03-13 12:04 ` [PATCH 02/20] Input: atmel_mxt_ts - only allow root to update firmware Daniel Kurtz
2012-03-20 14:38   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 03/20] Input: atmel_mxt_ts - verify object size in mxt_write_object Daniel Kurtz
2012-03-14  1:33   ` Joonyoung Shim
2012-03-14  2:13     ` Daniel Kurtz
2012-03-14  2:37     ` Joonyoung Shim
2012-03-13 12:04 ` [PATCH 04/20] Input: atmel_mxt_ts - refactor mxt_read/write_reg to take a length Daniel Kurtz
2012-03-13 12:04 ` [PATCH 05/20] Input: atmel_mxt_ts - dump mxt_read/write_reg Daniel Kurtz
2012-03-20 14:43   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 06/20] Input: atmel_mxt_ts - allow writing to object sysfs entry Daniel Kurtz
2012-03-19  8:04   ` Henrik Rydberg
2012-03-19  8:26     ` Daniel Kurtz
2012-03-20 14:51   ` Nick Dyer
2012-03-20 23:03   ` Alan Cox
2012-03-20 23:32     ` Nick Dyer
2012-03-13 12:04 ` [PATCH 07/20] Input: atmel_mxt_ts - add backupnv " Daniel Kurtz
2012-03-20 15:01   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 08/20] Input: atmel_mxt_ts - store actual size and instance Daniel Kurtz
2012-03-20 15:05   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 09/20] Input: atmel_mxt_ts - do not read extra (checksum) byte Daniel Kurtz
2012-03-20 15:07   ` Nick Dyer
2012-03-22 10:18     ` Bowens, Alan
2012-03-13 12:04 ` [PATCH 10/20] Input: atmel_mxt_ts - dump each message on just 1 line Daniel Kurtz
2012-03-20 15:08   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 11/20] Input: atmel_mxt_ts - refactor mxt_object_show Daniel Kurtz
2012-03-20 15:11   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 12/20] Input: atmel_mxt_ts - simplify event reporting Daniel Kurtz
2012-03-19  8:26   ` Henrik Rydberg
2012-03-19  9:06     ` Daniel Kurtz
2012-03-20 15:13   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 13/20] Input: atmel_mxt_ts - parse vector field of data packets Daniel Kurtz
2012-03-20 15:23   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 14/20] Input: atmel_mxt_ts - refactor reading object table Daniel Kurtz
2012-03-20 15:19   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 15/20] Input: atmel_mxt_ts - optimize writing of object table entries Daniel Kurtz
2012-03-13 12:04 ` [PATCH 16/20] Input: atmel_mxt_ts - refactor get info Daniel Kurtz
2012-03-20 15:21   ` Nick Dyer
2012-03-13 12:04 ` [PATCH 17/20] Input: atmel_mxt_ts - use cached T9 reportid range in isr Daniel Kurtz
2012-03-20 15:30   ` Nick Dyer
2012-03-13 12:04 ` Daniel Kurtz [this message]
2012-03-14  2:32   ` [PATCH 18/20] Input: atmel_mxt_ts - read num messages, then all messages Joonyoung Shim
2012-03-14  3:13     ` Daniel Kurtz
2012-03-20 15:28       ` Nick Dyer
2012-03-13 12:04 ` [PATCH 19/20] Input: atmel_mxt_ts - remove mxt_make_highchg and parse T6 report Daniel Kurtz
2012-03-20 15:38   ` Nick Dyer
2012-03-29 15:20     ` Daniel Kurtz
2012-03-30  7:00       ` Nick Dyer
2012-03-13 12:04 ` [PATCH 20/20] Input: atmel_mxt_ts - send all MT-B slots in one input report Daniel Kurtz
2012-03-20 15:39   ` Nick Dyer
2012-03-14  2:43 ` [PATCH 00/20] cleanup atmel_mxt_ts Joonyoung Shim
2012-03-14 17:00 ` Valkonen, Iiro
2012-03-20 14:33 ` Nick Dyer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1331640263-18935-19-git-send-email-djkurtz@chromium.org \
    --to=djkurtz@chromium.org \
    --cc=bleung@chromium.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=iiro.valkonen@atmel.com \
    --cc=jy0922.shim@samsung.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miletus@chromium.org \
    --cc=rydberg@euromail.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).