Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26352
b: refs/heads/master
c: c9e617a
h: refs/heads/master
v: v3
  • Loading branch information
Imre Deak authored and Dmitry Torokhov committed Apr 12, 2006
1 parent 6d6fbe5 commit 6b81368
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 35 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: 7de90a8cb9c51145d7f60d8db17ce0fa07d1b281
refs/heads/master: c9e617a563ad646239270fa2222cdb06966cf1fa
82 changes: 48 additions & 34 deletions trunk/drivers/input/touchscreen/ads7846.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ struct ads7846 {
// FIXME remove "irq_disabled"
unsigned irq_disabled:1; /* P: lock */
unsigned disabled:1;

int (*get_pendown_state)(void);
};

/* leave chip selected when we're done, for quicker re-select? */
Expand Down Expand Up @@ -175,6 +177,12 @@ struct ser_req {
static void ads7846_enable(struct ads7846 *ts);
static void ads7846_disable(struct ads7846 *ts);

static int device_suspended(struct device *dev)
{
struct ads7846 *ts = dev_get_drvdata(dev);
return dev->power.power_state.event != PM_EVENT_ON || ts->disabled;
}

static int ads7846_read12_ser(struct device *dev, unsigned command)
{
struct spi_device *spi = to_spi_device(dev);
Expand Down Expand Up @@ -227,8 +235,10 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
for (i = 0; i < 6; i++)
spi_message_add_tail(&req->xfer[i], &req->msg);

ts->irq_disabled = 1;
disable_irq(spi->irq);
status = spi_sync(spi, &req->msg);
ts->irq_disabled = 0;
enable_irq(spi->irq);

if (req->msg.status)
Expand Down Expand Up @@ -333,7 +343,7 @@ static void ads7846_rx(void *ads)
if (x == MAX_12BIT)
x = 0;

if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
if (likely(x && z1 && !device_suspended(&ts->spi->dev))) {
/* compute touch pressure resistance using equation #2 */
Rt = z2;
Rt -= z1;
Expand Down Expand Up @@ -377,20 +387,10 @@ static void ads7846_rx(void *ads)
x, y, Rt, Rt ? "" : " UP");
#endif

/* don't retrigger while we're suspended */
spin_lock_irqsave(&ts->lock, flags);

ts->pendown = (Rt != 0);
ts->pending = 0;

if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
if (ts->pendown)
mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
else if (ts->irq_disabled) {
ts->irq_disabled = 0;
enable_irq(ts->spi->irq);
}
}
mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);

spin_unlock_irqrestore(&ts->lock, flags);
}
Expand Down Expand Up @@ -431,10 +431,25 @@ static void ads7846_timer(unsigned long handle)
struct ads7846 *ts = (void *)handle;
int status = 0;

ts->msg_idx = 0;
status = spi_async(ts->spi, &ts->msg[0]);
if (status)
dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
spin_lock_irq(&ts->lock);

if (unlikely(ts->msg_idx && !ts->pendown)) {
/* measurment cycle ended */
if (!device_suspended(&ts->spi->dev)) {
ts->irq_disabled = 0;
enable_irq(ts->spi->irq);
}
ts->pending = 0;
ts->msg_idx = 0;
} else {
/* pen is still down, continue with the measurement */
ts->msg_idx = 0;
status = spi_async(ts->spi, &ts->msg[0]);
if (status)
dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
}

spin_unlock_irq(&ts->lock);
}

static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
Expand All @@ -443,7 +458,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
unsigned long flags;

spin_lock_irqsave(&ts->lock, flags);
if (likely(!ts->irq_disabled && !ts->disabled)) {
if (likely(ts->get_pendown_state())) {
if (!ts->irq_disabled) {
/* REVISIT irq logic for many ARM chips has cloned a
* bug wherein disabling an irq in its handler won't
Expand All @@ -452,10 +467,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
* that state here.
*/
ts->irq_disabled = 1;

disable_irq(ts->spi->irq);
}
if (!ts->pending) {
ts->pending = 1;
mod_timer(&ts->timer, jiffies);
}
Expand All @@ -473,20 +485,17 @@ static void ads7846_disable(struct ads7846 *ts)
if (ts->disabled)
return;

ts->disabled = 1;

/* are we waiting for IRQ, or polling? */
if (!ts->pendown) {
if (!ts->irq_disabled) {
ts->irq_disabled = 1;
disable_irq(ts->spi->irq);
}
if (!ts->pending) {
ts->irq_disabled = 1;
disable_irq(ts->spi->irq);
} else {
/* polling; force a final SPI completion;
* that will clean things up neatly
/* the timer will run at least once more, and
* leave everything in a clean state, IRQ disabled
*/
if (!ts->pending)
mod_timer(&ts->timer, jiffies);

while (ts->pendown || ts->pending) {
while (ts->pending) {
spin_unlock_irq(&ts->lock);
msleep(1);
spin_lock_irq(&ts->lock);
Expand All @@ -497,7 +506,6 @@ static void ads7846_disable(struct ads7846 *ts)
* leave it that way after every request
*/

ts->disabled = 1;
}

/* Must be called with ts->lock held */
Expand Down Expand Up @@ -566,6 +574,11 @@ static int __devinit ads7846_probe(struct spi_device *spi)
return -EINVAL;
}

if (pdata->get_pendown_state == NULL) {
dev_dbg(&spi->dev, "no get_pendown_state function?\n");
return -EINVAL;
}

/* We'd set the wordsize to 12 bits ... except that some controllers
* will then treat the 8 bit command words as 12 bits (and drop the
* four MSBs of the 12 bit result). Result: inputs must be shifted
Expand Down Expand Up @@ -596,6 +609,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
ts->debounce_max = pdata->debounce_max ? : 1;
ts->debounce_tol = pdata->debounce_tol ? : 10;
ts->get_pendown_state = pdata->get_pendown_state;

snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);

Expand Down Expand Up @@ -786,8 +800,8 @@ static int __devexit ads7846_remove(struct spi_device *spi)
device_remove_file(&spi->dev, &dev_attr_vaux);

free_irq(ts->spi->irq, ts);
if (ts->irq_disabled)
enable_irq(ts->spi->irq);
/* suspend left the IRQ disabled */
enable_irq(ts->spi->irq);

kfree(ts);

Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/spi/ads7846.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ struct ads7846_platform_data {

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

int (*get_pendown_state)(void);
};

0 comments on commit 6b81368

Please sign in to comment.