Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26354
b: refs/heads/master
c: d5b415c
h: refs/heads/master
v: v3
  • Loading branch information
Imre Deak authored and Dmitry Torokhov committed Apr 26, 2006
1 parent a9e6006 commit cf69f12
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ae82d5ab05068fccef2329f4607670f24c41606f
refs/heads/master: d5b415c95f0e6510451f1446cea832c1f77bd7ea
72 changes: 57 additions & 15 deletions trunk/drivers/input/touchscreen/ads7846.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct ts_event {
__be16 x;
__be16 y;
__be16 z1, z2;
int ignore;
};

struct ads7846 {
Expand All @@ -81,19 +82,23 @@ struct ads7846 {
u16 model;
u16 vref_delay_usecs;
u16 x_plate_ohms;
u16 pressure_max;

u8 read_x, read_y, read_z1, read_z2, pwrdown;
u16 dummy; /* for the pwrdown read */
struct ts_event tc;

struct spi_transfer xfer[10];
struct spi_message msg[5];
struct spi_message *last_msg;
int msg_idx;
int read_cnt;
int read_rep;
int last_read;

u16 debounce_max;
u16 debounce_tol;
u16 debounce_rep;

spinlock_t lock;
struct timer_list timer; /* P: lock */
Expand Down Expand Up @@ -354,6 +359,14 @@ static void ads7846_rx(void *ads)
} else
Rt = 0;

/* Sample found inconsistent by debouncing or pressure is beyond
* the maximum. Don't report it to user space, repeat at least
* once more the measurement */
if (ts->tc.ignore || Rt > ts->pressure_max) {
mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
return;
}

/* NOTE: "pendown" is inferred from pressure; we don't rely on
* being able to check nPENIRQ status, or "friendly" trigger modes
* (both-edges is much better than just-falling or low-level).
Expand Down Expand Up @@ -402,25 +415,45 @@ static void ads7846_debounce(void *ads)
struct ads7846 *ts = ads;
struct spi_message *m;
struct spi_transfer *t;
u16 val;
int val;
int status;

m = &ts->msg[ts->msg_idx];
t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
val = (*(u16 *)t->rx_buf) >> 3;

if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol
&& ts->read_cnt < ts->debounce_max)) {
/* Repeat it, if this was the first read or the read wasn't
* consistent enough
*/
ts->read_cnt++;
ts->last_read = val;
if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) {
/* Repeat it, if this was the first read or the read
* wasn't consistent enough. */
if (ts->read_cnt < ts->debounce_max) {
ts->last_read = val;
ts->read_cnt++;
} else {
/* Maximum number of debouncing reached and still
* not enough number of consistent readings. Abort
* the whole sample, repeat it in the next sampling
* period.
*/
ts->tc.ignore = 1;
ts->read_cnt = 0;
/* Last message will contain ads7846_rx() as the
* completion function.
*/
m = ts->last_msg;
}
/* Start over collecting consistent readings. */
ts->read_rep = 0;
} else {
/* Go for the next read */
ts->msg_idx++;
ts->read_cnt = 0;
m++;
if (++ts->read_rep > ts->debounce_rep) {
/* Got a good reading for this coordinate,
* go for the next one. */
ts->tc.ignore = 0;
ts->msg_idx++;
ts->read_cnt = 0;
ts->read_rep = 0;
m++;
} else
/* Read more values that are consistent. */
ts->read_cnt++;
}
status = spi_async(ts->spi, m);
if (status)
Expand Down Expand Up @@ -609,8 +642,15 @@ static int __devinit ads7846_probe(struct spi_device *spi)
ts->model = pdata->model ? : 7846;
ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
ts->debounce_max = pdata->debounce_max ? : 1;
ts->debounce_tol = pdata->debounce_tol ? : 10;
ts->pressure_max = pdata->pressure_max ? : ~0;
if (pdata->debounce_max) {
ts->debounce_max = pdata->debounce_max;
ts->debounce_tol = pdata->debounce_tol;
ts->debounce_rep = pdata->debounce_rep;
if (ts->debounce_rep > ts->debounce_max + 1)
ts->debounce_rep = ts->debounce_max - 1;
} else
ts->debounce_tol = ~0;
ts->get_pendown_state = pdata->get_pendown_state;

snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
Expand Down Expand Up @@ -728,6 +768,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
m->complete = ads7846_rx;
m->context = ts;

ts->last_msg = m;

if (request_irq(spi->irq, ads7846_irq,
SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING,
spi->dev.bus_id, ts)) {
Expand Down
6 changes: 4 additions & 2 deletions trunk/include/linux/spi/ads7846.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ struct ads7846_platform_data {
u16 y_min, y_max;
u16 pressure_min, pressure_max;

u16 debounce_max; /* max number of readings per sample */
u16 debounce_max; /* max number of additional readings
* per sample */
u16 debounce_tol; /* tolerance used for filtering */

u16 debounce_rep; /* additional consecutive good readings
* required after the first two */
int (*get_pendown_state)(void);
};

0 comments on commit cf69f12

Please sign in to comment.