All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
To: Lee Jones <lee.jones@linaro.org>, Samuel Ortiz <sameo@linux.intel.com>
Cc: "Benoît Cousson" <b-cousson@ti.com>,
	"Tony Lindgren" <tony@atomide.com>,
	"Jonathan Cameron" <jic23@cam.ac.uk>,
	"Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
	"Felipe Balbi" <balbi@ti.com>,
	linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org,
	linux-iio@vger.kernel.org, linux-input@vger.kernel.org,
	"Sebastian Andrzej Siewior" <bigeasy@linutronix.de>
Subject: [PATCH 18/22] input/ti_am335x_adc: use only FIFO0 and clean up a little
Date: Tue, 11 Jun 2013 13:31:04 +0200	[thread overview]
Message-ID: <1370950268-7224-19-git-send-email-bigeasy@linutronix.de> (raw)
In-Reply-To: <1370950268-7224-1-git-send-email-bigeasy@linutronix.de>

The driver programs a threshold of "coordinate_readouts" say 5. The
REG_FIFO0THR registers says it should it be programmed to "threshold
minus one". The driver does not expect just 5 coordinates but 5 * 2 + 2.
Multiplied by two because 5 for X and 5 for Y and plus 2 because we have
two Z.
The whole thing kind of works because It reads the 5 coordinates for X
and Y from FIFO0 and FIFO1 and the last element in each FIFO is ignored
within the loop and read later.
Nothing guaranties that FIFO1 is ready by the time it is read. In fact I
could see that that FIFO1 reaturns for Y channels 8,9, 10, 12, 6 and for
Y channel 7 for Z. The problem is that channel 7 and channel 12 got
somehow mixed up.
The other Problem is that FIFO1 is also used by the IIO part leading to
wrong results if both (tsc & adc) are used.

The patch tries to clean up the whole thing a little:
- Remove the +1 and -1 in REG_STEPCONFIG, REG_STEPDELAY and its counter
  part in the for loop. This is just confusing.

- Use only FIFO0 in TSC. The fifo has space for 64 entries so should be
  fine.

- Read the whole FIFO in one function and check the channel.

- in case we dawdle around, make sure we only read a multiple of our
  coordinate set. On the second interrupt we will cleanup the remaining
  enties.

Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/iio/adc/ti_am335x_adc.c           |    2 +-
 drivers/input/touchscreen/ti_am335x_tsc.c |   78 +++++++++++++++--------------
 include/linux/mfd/ti_am335x_tscadc.h      |    4 +-
 3 files changed, 44 insertions(+), 40 deletions(-)

diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 4bec91e..307a7c0 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -75,7 +75,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
 
 	stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
 
-	for (i = (steps + 1); i <= TOTAL_STEPS; i++) {
+	for (i = steps; i < TOTAL_STEPS; i++) {
 		tiadc_writel(adc_dev, REG_STEPCONFIG(i),
 				stepconfig | STEPCONFIG_INP(channels));
 		tiadc_writel(adc_dev, REG_STEPDELAY(i),
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index d6643cb..29febe9 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -120,11 +120,9 @@ static int titsc_config_wires(struct titsc *ts_dev)
 static void titsc_step_config(struct titsc *ts_dev)
 {
 	unsigned int	config;
-	unsigned int	stepenable = 0;
-	int i, total_steps;
-
-	/* Configure the Step registers */
-	total_steps = 2 * ts_dev->coordinate_readouts;
+	int i;
+	int end_step;
+	u32 stepenable;
 
 	config = STEPCONFIG_MODE_HWSYNC |
 			STEPCONFIG_AVG_16 | ts_dev->bit_xp;
@@ -142,7 +140,9 @@ static void titsc_step_config(struct titsc *ts_dev)
 		break;
 	}
 
-	for (i = 1; i <= ts_dev->coordinate_readouts; i++) {
+	/* 1 … coordinate_readouts is for X */
+	end_step = ts_dev->coordinate_readouts;
+	for (i = 0; i < end_step; i++) {
 		titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
 		titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
 	}
@@ -150,7 +150,7 @@ static void titsc_step_config(struct titsc *ts_dev)
 	config = 0;
 	config = STEPCONFIG_MODE_HWSYNC |
 			STEPCONFIG_AVG_16 | ts_dev->bit_yn |
-			STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1;
+			STEPCONFIG_INM_ADCREFM;
 	switch (ts_dev->wires) {
 	case 4:
 		config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
@@ -164,12 +164,13 @@ static void titsc_step_config(struct titsc *ts_dev)
 		break;
 	}
 
-	for (i = (ts_dev->coordinate_readouts + 1); i <= total_steps; i++) {
+	/* coordinate_readouts … coordinate_readouts * 2 is for Y */
+	end_step = ts_dev->coordinate_readouts * 2;
+	for (i = ts_dev->coordinate_readouts; i < end_step; i++) {
 		titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
 		titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
 	}
 
-	config = 0;
 	/* Charge step configuration */
 	config = ts_dev->bit_xp | ts_dev->bit_yn |
 			STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR |
@@ -178,35 +179,39 @@ static void titsc_step_config(struct titsc *ts_dev)
 	titsc_writel(ts_dev, REG_CHARGECONFIG, config);
 	titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
 
-	config = 0;
-	/* Configure to calculate pressure */
+	/* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */
 	config = STEPCONFIG_MODE_HWSYNC |
 			STEPCONFIG_AVG_16 | ts_dev->bit_yp |
 			ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
 			STEPCONFIG_INP(ts_dev->inp_xp);
-	titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config);
-	titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1),
+	titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
+	titsc_writel(ts_dev, REG_STEPDELAY(end_step),
 			STEPCONFIG_OPENDLY);
 
-	config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1;
-	titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config);
-	titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
+	end_step++;
+	config |= STEPCONFIG_INP(ts_dev->inp_yn);
+	titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
+	titsc_writel(ts_dev, REG_STEPDELAY(end_step),
 			STEPCONFIG_OPENDLY);
 
 	/* The steps1 … end and bit 0 for TS_Charge */
-	stepenable = (1 << (total_steps + 2)) - 1;
+	stepenable = (1 << (end_step + 2)) - 1;
 	am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
 }
 
 static void titsc_read_coordinates(struct titsc *ts_dev,
-				    unsigned int *x, unsigned int *y)
+		u32 *x, u32 *y, u32 *z1, u32 *z2)
 {
 	unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT);
 	unsigned int prev_val_x = ~0, prev_val_y = ~0;
 	unsigned int prev_diff_x = ~0, prev_diff_y = ~0;
 	unsigned int read, diff;
 	unsigned int i, channel;
+	unsigned int creads = ts_dev->coordinate_readouts;
 
+	*z1 = *z2 = 0;
+	if (fifocount % (creads * 2 + 2))
+		fifocount -= fifocount % (creads * 2 + 2);
 	/*
 	 * Delta filter is used to remove large variations in sampled
 	 * values from ADC. The filter tries to predict where the next
@@ -215,32 +220,32 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
 	 * algorithm compares the difference with that of a present value,
 	 * if true the value is reported to the sub system.
 	 */
-	for (i = 0; i < fifocount - 1; i++) {
+	for (i = 0; i < fifocount; i++) {
 		read = titsc_readl(ts_dev, REG_FIFO0);
-		channel = read & 0xf0000;
-		channel = channel >> 0x10;
-		if ((channel >= 0) && (channel < ts_dev->coordinate_readouts)) {
-			read &= 0xfff;
+
+		channel = (read & 0xf0000) >> 16;
+		read &= 0xfff;
+		if (channel < creads) {
 			diff = abs(read - prev_val_x);
 			if (diff < prev_diff_x) {
 				prev_diff_x = diff;
 				*x = read;
 			}
 			prev_val_x = read;
-		}
 
-		read = titsc_readl(ts_dev, REG_FIFO1);
-		channel = read & 0xf0000;
-		channel = channel >> 0x10;
-		if ((channel >= ts_dev->coordinate_readouts) &&
-			(channel < (2 * ts_dev->coordinate_readouts - 1))) {
-			read &= 0xfff;
+		} else if (channel < creads * 2) {
 			diff = abs(read - prev_val_y);
 			if (diff < prev_diff_y) {
 				prev_diff_y = diff;
 				*y = read;
 			}
 			prev_val_y = read;
+
+		} else if (channel < creads * 2 + 1) {
+			*z1 = read;
+
+		} else if (channel < creads * 2 + 2) {
+			*z2 = read;
 		}
 	}
 }
@@ -256,10 +261,8 @@ static irqreturn_t titsc_irq(int irq, void *dev)
 
 	status = titsc_readl(ts_dev, REG_IRQSTATUS);
 	if (status & IRQENB_FIFO0THRES) {
-		titsc_read_coordinates(ts_dev, &x, &y);
 
-		z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
-		z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
+		titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
 
 		if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
 			/*
@@ -267,10 +270,10 @@ static irqreturn_t titsc_irq(int irq, void *dev)
 			 * Resistance(touch) = x plate resistance *
 			 * x postion/4096 * ((z2 / z1) - 1)
 			 */
-			z = z2 - z1;
+			z = z1 - z2;
 			z *= x;
 			z *= ts_dev->x_plate_resistance;
-			z /= z1;
+			z /= z2;
 			z = (z + 2047) >> 12;
 
 			if (z <= MAX_12BIT) {
@@ -391,7 +394,8 @@ static int titsc_probe(struct platform_device *pdev)
 		goto err_free_irq;
 	}
 	titsc_step_config(ts_dev);
-	titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->coordinate_readouts);
+	titsc_writel(ts_dev, REG_FIFO0THR,
+			ts_dev->coordinate_readouts * 2 + 2 - 1);
 
 	input_dev->name = "ti-tsc";
 	input_dev->dev.parent = &pdev->dev;
@@ -468,7 +472,7 @@ static int titsc_resume(struct device *dev)
 	}
 	titsc_step_config(ts_dev);
 	titsc_writel(ts_dev, REG_FIFO0THR,
-			ts_dev->coordinate_readouts);
+			ts_dev->coordinate_readouts * 2 + 2 - 1);
 	return 0;
 }
 
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index cd8686b..fe6223c 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -30,8 +30,8 @@
 #define REG_IDLECONFIG		0x058
 #define REG_CHARGECONFIG	0x05C
 #define REG_CHARGEDELAY		0x060
-#define REG_STEPCONFIG(n)	(0x64 + ((n - 1) * 8))
-#define REG_STEPDELAY(n)	(0x68 + ((n - 1) * 8))
+#define REG_STEPCONFIG(n)	(0x64 + ((n) * 8))
+#define REG_STEPDELAY(n)	(0x68 + ((n) * 8))
 #define REG_FIFO0CNT		0xE4
 #define REG_FIFO0THR		0xE8
 #define REG_FIFO1CNT		0xF0
-- 
1.7.10.4


  parent reply	other threads:[~2013-06-11 11:41 UTC|newest]

Thread overview: 99+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-11 11:30 am335x: TSC & ADC reworking including DT pieces, take 4 Sebastian Andrzej Siewior
2013-06-11 11:30 ` Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 01/22] mfd/ti_am335x_tscadc: remove regmap Sebastian Andrzej Siewior
2013-06-11 14:23   ` Samuel Ortiz
2013-06-11 14:34     ` Sebastian Andrzej Siewior
2013-06-11 14:34       ` Sebastian Andrzej Siewior
2013-06-14 13:53       ` Mark Brown
2013-06-14 13:53         ` Mark Brown
2013-06-17 11:41         ` Sebastian Andrzej Siewior
2013-06-17 11:41           ` Sebastian Andrzej Siewior
2013-06-17 16:03           ` Mark Brown
2013-06-17 16:03             ` Mark Brown
2013-07-04  9:02             ` Sebastian Andrzej Siewior
2013-07-04  9:02               ` Sebastian Andrzej Siewior
2013-07-04 10:45               ` Mark Brown
2013-07-04 11:15                 ` Sebastian Andrzej Siewior
2013-07-04 11:15                   ` Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 02/22] mfd & input & iio/ti_am335x_adc: use one structure for ti_tscadc_dev Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 03/22] input/ti_am33x_tsc: Step enable bits made configurable Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 04/22] input/ti_am33x_tsc: Order of TSC wires, " Sebastian Andrzej Siewior
2013-06-11 14:23   ` Samuel Ortiz
2013-06-11 14:23     ` Samuel Ortiz
2013-06-11 14:35     ` Sebastian Andrzej Siewior
2013-07-04 11:14   ` Sekhar Nori
2013-07-04 11:14     ` Sekhar Nori
2013-07-04 11:33     ` Sebastian Andrzej Siewior
2013-07-04 11:33       ` Sebastian Andrzej Siewior
2013-07-04 13:39       ` Sekhar Nori
2013-07-04 13:39         ` Sekhar Nori
2013-07-04 13:50         ` Sebastian Andrzej Siewior
2013-07-04 14:27           ` Sekhar Nori
2013-06-11 11:30 ` [PATCH 05/22] input/ti_am33x_tsc: remove unwanted fifo flush Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 06/22] input/ti_am33x_tsc: Add DT support Sebastian Andrzej Siewior
2013-06-11 11:30   ` Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 07/22] input/ti_am33x_tsc: remove platform_data support Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 08/22] iio/ti_am335x_adc: Add DT support Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 09/22] iio/ti_am335x_adc: remove platform_data support Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 10/22] mfd/ti_am335x_tscadc: Add DT support Sebastian Andrzej Siewior
2013-06-11 14:23   ` Samuel Ortiz
2013-06-11 14:42     ` Sebastian Andrzej Siewior
2013-06-11 14:42       ` Sebastian Andrzej Siewior
2013-06-11 15:05       ` Samuel Ortiz
2013-06-11 15:41         ` Sebastian Andrzej Siewior
2013-06-11 15:41           ` Sebastian Andrzej Siewior
2013-06-11 18:42           ` Lee Jones
2013-06-11 18:42             ` Lee Jones
2013-06-11 17:10       ` Lee Jones
2013-06-11 17:10         ` Lee Jones
2013-06-11 11:30 ` [PATCH 11/22] mfd/ti_am335x_tscadc: remove platform_data support Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 12/22] iio/ti_tscadc: provide datasheet_name and scan_type Sebastian Andrzej Siewior
2013-06-11 11:30 ` [PATCH 13/22] mfd/ti_tscadc: deal with partial activation Sebastian Andrzej Siewior
2013-06-11 11:31 ` [PATCH 14/22] arm/am33xx: add TSC/ADC mfd device support Sebastian Andrzej Siewior
2013-07-04 13:49   ` Sekhar Nori
2013-07-04 13:49     ` Sekhar Nori
2013-07-04 13:51     ` Sebastian Andrzej Siewior
2013-07-04 13:51       ` Sebastian Andrzej Siewior
2013-06-11 11:31 ` [PATCH 15/22] input & mfd: ti_am335x_tsc remove remaining platform data pieces Sebastian Andrzej Siewior
2013-06-11 11:31 ` [PATCH 16/22] mfd & input/ti_am335x_tsc: rename device from tsc to TI-am335x-tsc Sebastian Andrzej Siewior
2013-06-11 11:31 ` [PATCH 17/22] mfd & iio/ti_am335x_adc: rename device from tiadc to TI-am335x-adc Sebastian Andrzej Siewior
2013-06-11 11:31   ` Sebastian Andrzej Siewior
2013-06-11 11:31 ` Sebastian Andrzej Siewior [this message]
2013-06-11 11:31 ` [PATCH 19/22] input/ti_am335x_tsc: ACK the HW_PEN irq in ISR Sebastian Andrzej Siewior
2013-06-11 11:31 ` [PATCH 20/22] input/ti_am335x_tsc: return IRQ_NONE if there was no IRQ for us Sebastian Andrzej Siewior
2013-06-11 11:31 ` [PATCH 21/22] iio/ti_am335x_adc: Allow to specify input line Sebastian Andrzej Siewior
2013-06-11 11:31 ` [PATCH 22/22] iio/ti_am335x_adc: check if we found the value Sebastian Andrzej Siewior
2013-06-11 12:05 ` am335x: TSC & ADC reworking including DT pieces, take 4 Lee Jones
2013-06-11 12:05   ` Lee Jones
2013-06-11 13:53   ` Lars-Peter Clausen
2013-06-11 13:53     ` Lars-Peter Clausen
2013-06-11 14:23 ` Samuel Ortiz
2013-06-11 15:29   ` Sebastian Andrzej Siewior
2013-06-11 15:29     ` Sebastian Andrzej Siewior
2013-06-11 16:10     ` Samuel Ortiz
2013-06-11 16:10       ` Samuel Ortiz
2013-06-11 16:18       ` Sebastian Andrzej Siewior
2013-06-11 16:18         ` Sebastian Andrzej Siewior
2013-06-14 13:57     ` Mark Brown
2013-06-14 13:57       ` Mark Brown
2013-06-11 16:04   ` Dmitry Torokhov
2013-06-11 16:04     ` Dmitry Torokhov
2013-06-11 16:15     ` Samuel Ortiz
2013-06-11 16:15       ` Samuel Ortiz
2013-06-11 16:27       ` Jonathan Cameron
2013-06-11 16:27         ` Jonathan Cameron
2013-06-11 17:01         ` Lars-Peter Clausen
2013-06-11 17:01           ` Lars-Peter Clausen
2013-06-11 17:55         ` Samuel Ortiz
2013-06-11 17:55           ` Samuel Ortiz
2013-06-12 13:29           ` Sebastian Andrzej Siewior
2013-06-12 13:50             ` Samuel Ortiz
2013-06-12 13:50               ` Samuel Ortiz
2013-06-12 14:02               ` Sebastian Andrzej Siewior
2013-06-12 14:02                 ` Sebastian Andrzej Siewior
2013-06-12 14:41                 ` Samuel Ortiz
2013-06-12 15:00                   ` Sebastian Andrzej Siewior
2013-06-11 18:02   ` Jonathan Cameron
2013-06-11 18:02     ` Jonathan Cameron
  -- strict thread matches above, loose matches on Subject: below --
2013-06-05 16:24 AM335x tsc & adc, dt + cleanup take 3 Sebastian Andrzej Siewior
     [not found] ` <1370449495-29981-1-git-send-email-bigeasy-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2013-06-05 16:24   ` [PATCH 18/22] input/ti_am335x_adc: use only FIFO0 and clean up a little Sebastian Andrzej Siewior
2013-06-05 16:24     ` Sebastian Andrzej Siewior

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=1370950268-7224-19-git-send-email-bigeasy@linutronix.de \
    --to=bigeasy@linutronix.de \
    --cc=b-cousson@ti.com \
    --cc=balbi@ti.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jic23@cam.ac.uk \
    --cc=lee.jones@linaro.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=sameo@linux.intel.com \
    --cc=tony@atomide.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.