diff options
-rw-r--r-- | drivers/input/touchscreen/ads7846.c | 65 | ||||
-rw-r--r-- | include/linux/spi/ads7846.h | 8 |
2 files changed, 72 insertions, 1 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 1c9069cd3ba..103ee6ad299 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; } diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 3387e44dfd1..a44fa7a02bd 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; |