All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Harring <ferringb@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: richard.rojfors@pelagicore.com
Subject: [PATCH] tsc2007: suppress successive pen down states to avoid false reads
Date: Sun, 3 Oct 2010 19:42:57 -0700	[thread overview]
Message-ID: <20101004024257.GA24952@hrair> (raw)

[-- Attachment #1: Type: text/plain, Size: 4029 bytes --]

For the russellville platform, this makes the tsc2007 actually usable.

This patch has been kicking around MeeGo 1.0 for a while; not sure why it never
made it's way to upstream, but pushing it up that way now.

Signed-off-by: Brian Harring <ferringb@gmail.com>
---
 drivers/input/touchscreen/tsc2007.c |   68 ++++++++++++++++++++++++++---------
 1 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index be23780..05314fd 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -29,6 +29,7 @@
 
 #define TS_POLL_DELAY			1 /* ms delay between samples */
 #define TS_POLL_PERIOD			1 /* ms delay between samples */
+#define TS_SLOW_POLL_PERIOD		20 /* ms delay between pen down check */
 
 #define TSC2007_MEASURE_TEMP0		(0x0 << 4)
 #define TSC2007_MEASURE_AUX		(0x2 << 4)
@@ -77,6 +78,7 @@ struct tsc2007 {
 	u16			x_plate_ohms;
 
 	bool			pendown;
+	bool			ignore_next_irq;
 	int			irq;
 
 	int			(*get_pendown_state)(void);
@@ -228,14 +230,39 @@ static void tsc2007_work(struct work_struct *work)
 	if (ts->pendown)
 		schedule_delayed_work(&ts->work,
 				      msecs_to_jiffies(TS_POLL_PERIOD));
-	else
-		enable_irq(ts->irq);
+	else {
+		/* if we don't have the get pen down state callback we
+		 * ignore the next IRQ because it is provoked when we checked
+		 * the touch pressure.
+		 * If the user really touches the screen we will get a new
+		 * interrupt anyway so it is safe to ignore it
+		 *
+		 * This is basically implementing this part of the manual:
+		 * "In both cases previously listed, it is recommended that
+		 *  whenever the host writes to the TSC2007, the master
+		 *  processor masks the interrupt associated to PENIRQ.
+		 *  This masking prevents false triggering of interrupts when
+		 *  the PENIRQ line is disabled in the cases previously listed."
+		 */
+		if (!ts->get_pendown_state)
+			ts->ignore_next_irq = true;
+		if (ts->irq)
+			enable_irq(ts->irq);
+		else
+			schedule_delayed_work(&ts->work,
+					msecs_to_jiffies(TS_SLOW_POLL_PERIOD));
+	}
 }
 
 static irqreturn_t tsc2007_irq(int irq, void *handle)
 {
 	struct tsc2007 *ts = handle;
 
+	if (ts->ignore_next_irq) {
+		ts->ignore_next_irq = false;
+		return IRQ_HANDLED;
+	}
+
 	if (!ts->get_pendown_state || likely(ts->get_pendown_state())) {
 		disable_irq_nosync(ts->irq);
 		schedule_delayed_work(&ts->work,
@@ -250,15 +277,18 @@ static irqreturn_t tsc2007_irq(int irq, void *handle)
 
 static void tsc2007_free_irq(struct tsc2007 *ts)
 {
-	free_irq(ts->irq, ts);
-	if (cancel_delayed_work_sync(&ts->work)) {
-		/*
-		 * Work was pending, therefore we need to enable
-		 * IRQ here to balance the disable_irq() done in the
-		 * interrupt handler.
-		 */
-		enable_irq(ts->irq);
-	}
+	if (ts->irq) {
+		free_irq(ts->irq, ts);
+		if (cancel_delayed_work_sync(&ts->work)) {
+			/*
+			 * Work was pending, therefore we need to enable
+			 * IRQ here to balance the disable_irq() done in the
+			 * interrupt handler.
+			 */
+			enable_irq(ts->irq);
+		}
+	} else
+		cancel_delayed_work_sync(&ts->work);
 }
 
 static int __devinit tsc2007_probe(struct i2c_client *client,
@@ -312,12 +342,16 @@ static int __devinit tsc2007_probe(struct i2c_client *client,
 	if (pdata->init_platform_hw)
 		pdata->init_platform_hw();
 
-	err = request_irq(ts->irq, tsc2007_irq, 0,
-			client->dev.driver->name, ts);
-	if (err < 0) {
-		dev_err(&client->dev, "irq %d busy?\n", ts->irq);
-		goto err_free_mem;
-	}
+
+	if (ts->irq) {
+		err = request_irq(ts->irq, tsc2007_irq, 0,
+				client->dev.driver->name, ts);
+		if (err < 0) {
+			dev_err(&client->dev, "irq %d busy?\n", ts->irq);
+			goto err_free_mem;
+		}
+	} else
+		schedule_delayed_work(&ts->work, TS_SLOW_POLL_PERIOD);
 
 	/* Prepare for touch readings - power down ADC and enable PENIRQ */
 	err = tsc2007_xfer(ts, PWRDOWN);
-- 
1.7.2


[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

                 reply	other threads:[~2010-10-04  2:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20101004024257.GA24952@hrair \
    --to=ferringb@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=richard.rojfors@pelagicore.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.