Skip to content

Commit

Permalink
Input: ads7846 - introduce sample settling delay
Browse files Browse the repository at this point in the history
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 <semih.hazar@indefia.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
  • Loading branch information
Semih Hazar authored and Dmitry Torokhov committed Jul 18, 2007
1 parent 4994cd8 commit e4f4886
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
65 changes: 64 additions & 1 deletion drivers/input/touchscreen/ads7846.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ struct ads7846 {
u16 dummy; /* for the pwrdown read */
struct ts_event tc;

struct spi_transfer xfer[10];
struct spi_transfer xfer[18];
struct spi_message msg[5];
struct spi_message *last_msg;
int msg_idx;
Expand Down Expand Up @@ -936,6 +936,24 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->len = 2;
spi_message_add_tail(x, m);

/* the first sample after switching drivers can be low quality;
* optionally discard it, using a second one after the signals
* have had enough time to stabilize.
*/
if (pdata->settle_delay_usecs) {
x->delay_usecs = pdata->settle_delay_usecs;

x++;
x->tx_buf = &ts->read_y;
x->len = 1;
spi_message_add_tail(x, m);

x++;
x->rx_buf = &ts->tc.y;
x->len = 2;
spi_message_add_tail(x, m);
}

m->complete = ads7846_rx_val;
m->context = ts;

Expand All @@ -954,6 +972,21 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->len = 2;
spi_message_add_tail(x, m);

/* ... maybe discard first sample ... */
if (pdata->settle_delay_usecs) {
x->delay_usecs = pdata->settle_delay_usecs;

x++;
x->tx_buf = &ts->read_x;
x->len = 1;
spi_message_add_tail(x, m);

x++;
x->rx_buf = &ts->tc.x;
x->len = 2;
spi_message_add_tail(x, m);
}

m->complete = ads7846_rx_val;
m->context = ts;

Expand All @@ -973,6 +1006,21 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->len = 2;
spi_message_add_tail(x, m);

/* ... maybe discard first sample ... */
if (pdata->settle_delay_usecs) {
x->delay_usecs = pdata->settle_delay_usecs;

x++;
x->tx_buf = &ts->read_z1;
x->len = 1;
spi_message_add_tail(x, m);

x++;
x->rx_buf = &ts->tc.z1;
x->len = 2;
spi_message_add_tail(x, m);
}

m->complete = ads7846_rx_val;
m->context = ts;

Expand All @@ -990,6 +1038,21 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->len = 2;
spi_message_add_tail(x, m);

/* ... maybe discard first sample ... */
if (pdata->settle_delay_usecs) {
x->delay_usecs = pdata->settle_delay_usecs;

x++;
x->tx_buf = &ts->read_z2;
x->len = 1;
spi_message_add_tail(x, m);

x++;
x->rx_buf = &ts->tc.z2;
x->len = 2;
spi_message_add_tail(x, m);
}

m->complete = ads7846_rx_val;
m->context = ts;
}
Expand Down
8 changes: 8 additions & 0 deletions include/linux/spi/ads7846.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit e4f4886

Please sign in to comment.