From e4f48861993294c27849076741eb0c090482560b Mon Sep 17 00:00:00 2001 From: Semih Hazar Date: Wed, 18 Jul 2007 00:35:56 -0400 Subject: Input: ads7846 - introduce sample settling delay The ads7846 driver has support for filtering, but when the chip gets deselected between samples this causes noise. This patch adds support for an optional settling delay time, so that two consecutive samples will be taken with the specified delay time apart. This ensures that the chip won't be deselected, so the noise won't appear. Filtering can still be done, but will have less work to do since each time a new sample is taken the same delay applies. Signed-off-by: Semih Hazar Signed-off-by: David Brownell Signed-off-by: Dmitry Torokhov --- include/linux/spi/ads7846.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux/spi/ads7846.h') diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 3387e44dfd13..a44fa7a02bd9 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -16,6 +16,14 @@ struct ads7846_platform_data { u16 vref_delay_usecs; /* 0 for external vref; etc */ int keep_vref_on:1; /* set to keep vref on for differential * measurements as well */ + + /* Settling time of the analog signals; a function of Vcc and the + * capacitance on the X/Y drivers. If set to non-zero, two samples + * are taken with settle_delay us apart, and the second one is used. + * ~150 uSec with 0.01uF caps. + */ + u16 settle_delay_usecs; + u16 x_plate_ohms; u16 y_plate_ohms; -- cgit v1.2.3 From 1d25891f3241103d14ea78236504474a138b8ada Mon Sep 17 00:00:00 2001 From: Semih Hazar Date: Wed, 18 Jul 2007 00:36:04 -0400 Subject: Input: ads7846 - re-check pendown status before reporting events Pendown status from the PENIRQ pin is currently read only at the beginning of a sample set. If the pen is lifted just after sampling has began then sampled values become wrong. This patch adds an optional platform penirq_recheck_delay attribute. If non-zero, samples are only reported to the input subsystem if PENIRQ is still active that long after the samples taken. Signed-off-by: Semih Hazar Signed-off-by: David Brownell Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 15 +++++++++++++++ include/linux/spi/ads7846.h | 6 ++++++ 2 files changed, 21 insertions(+) (limited to 'include/linux/spi/ads7846.h') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 103ee6ad299e..96581d08774f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -107,6 +107,8 @@ struct ads7846 { u16 debounce_tol; u16 debounce_rep; + u16 penirq_recheck_delay_usecs; + spinlock_t lock; struct hrtimer timer; unsigned pendown:1; /* P: lock */ @@ -553,6 +555,15 @@ static void ads7846_rx(void *ads) return; } + /* Maybe check the pendown state before reporting. This discards + * false readings when the pen is lifted. + */ + if (ts->penirq_recheck_delay_usecs) { + udelay(ts->penirq_recheck_delay_usecs); + if (!ts->get_pendown_state()) + Rt = 0; + } + /* NOTE: We can't rely on the pressure to determine the pen down * state, even this controller has a pressure sensor. The pressure * value can fluctuate for quite a while after lifting the pen and @@ -896,6 +907,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->filter = ads7846_no_filter; ts->get_pendown_state = pdata->get_pendown_state; + if (pdata->penirq_recheck_delay_usecs) + ts->penirq_recheck_delay_usecs = + pdata->penirq_recheck_delay_usecs; + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); input_dev->name = "ADS784x Touchscreen"; diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index a44fa7a02bd9..334d31411629 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -24,6 +24,12 @@ struct ads7846_platform_data { */ u16 settle_delay_usecs; + /* If set to non-zero, after samples are taken this delay is applied + * and penirq is rechecked, to help avoid false events. This value + * is affected by the material used to build the touch layer. + */ + u16 penirq_recheck_delay_usecs; + u16 x_plate_ohms; u16 y_plate_ohms; -- cgit v1.2.3