aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/ads7846.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@nokia.com>2006-04-11 23:44:05 -0400
committerDmitry Torokhov <dtor_core@ameritech.net>2006-04-11 23:44:05 -0400
commitc9e617a563ad646239270fa2222cdb06966cf1fa (patch)
tree7598f9bc96914b4540b1d682eb2e9876343c272a /drivers/input/touchscreen/ads7846.c
parent7de90a8cb9c51145d7f60d8db17ce0fa07d1b281 (diff)
Input: ads7846 - handle IRQs that were latched during disabled IRQs
The pen down IRQ will toggle during each X,Y,Z measurement cycle. Even though the IRQ is disabled it will be latched and delivered when after enable_irq. Thus in the IRQ handler we must avoid starting a new measurement cycle when such an "unwanted" IRQ happens. Add a get_pendown_state platform function, which will probably determine this by reading the current GPIO level of the pen IRQ pin. Move the IRQ reenabling from the SPI RX function to the timer. After the last power down message the pen IRQ pin is still active for a while and get_pendown_state would report incorrectly a pen down state. When suspending we should check the ts->pending flag instead of ts->pendown, since the timer can be pending regardless of ts->pendown. Also if ts->pending is set we can be sure that the timer is running, so no need to rearm it. Similarly if ts->pending is not set we can be sure that the IRQ is enabled (and the timer is not). Signed-off-by: Imre Deak <imre.deak@nokia.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/touchscreen/ads7846.c')
-rw-r--r--drivers/input/touchscreen/ads7846.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index fec3b9b22309..e7cabf12c8dc 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -102,6 +102,8 @@ struct ads7846 {
102// FIXME remove "irq_disabled" 102// FIXME remove "irq_disabled"
103 unsigned irq_disabled:1; /* P: lock */ 103 unsigned irq_disabled:1; /* P: lock */
104 unsigned disabled:1; 104 unsigned disabled:1;
105
106 int (*get_pendown_state)(void);
105}; 107};
106 108
107/* leave chip selected when we're done, for quicker re-select? */ 109/* leave chip selected when we're done, for quicker re-select? */
@@ -175,6 +177,12 @@ struct ser_req {
175static void ads7846_enable(struct ads7846 *ts); 177static void ads7846_enable(struct ads7846 *ts);
176static void ads7846_disable(struct ads7846 *ts); 178static void ads7846_disable(struct ads7846 *ts);
177 179
180static int device_suspended(struct device *dev)
181{
182 struct ads7846 *ts = dev_get_drvdata(dev);
183 return dev->power.power_state.event != PM_EVENT_ON || ts->disabled;
184}
185
178static int ads7846_read12_ser(struct device *dev, unsigned command) 186static int ads7846_read12_ser(struct device *dev, unsigned command)
179{ 187{
180 struct spi_device *spi = to_spi_device(dev); 188 struct spi_device *spi = to_spi_device(dev);
@@ -227,8 +235,10 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
227 for (i = 0; i < 6; i++) 235 for (i = 0; i < 6; i++)
228 spi_message_add_tail(&req->xfer[i], &req->msg); 236 spi_message_add_tail(&req->xfer[i], &req->msg);
229 237
238 ts->irq_disabled = 1;
230 disable_irq(spi->irq); 239 disable_irq(spi->irq);
231 status = spi_sync(spi, &req->msg); 240 status = spi_sync(spi, &req->msg);
241 ts->irq_disabled = 0;
232 enable_irq(spi->irq); 242 enable_irq(spi->irq);
233 243
234 if (req->msg.status) 244 if (req->msg.status)
@@ -333,7 +343,7 @@ static void ads7846_rx(void *ads)
333 if (x == MAX_12BIT) 343 if (x == MAX_12BIT)
334 x = 0; 344 x = 0;
335 345
336 if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) { 346 if (likely(x && z1 && !device_suspended(&ts->spi->dev))) {
337 /* compute touch pressure resistance using equation #2 */ 347 /* compute touch pressure resistance using equation #2 */
338 Rt = z2; 348 Rt = z2;
339 Rt -= z1; 349 Rt -= z1;
@@ -377,20 +387,10 @@ static void ads7846_rx(void *ads)
377 x, y, Rt, Rt ? "" : " UP"); 387 x, y, Rt, Rt ? "" : " UP");
378#endif 388#endif
379 389
380 /* don't retrigger while we're suspended */
381 spin_lock_irqsave(&ts->lock, flags); 390 spin_lock_irqsave(&ts->lock, flags);
382 391
383 ts->pendown = (Rt != 0); 392 ts->pendown = (Rt != 0);
384 ts->pending = 0; 393 mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
385
386 if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
387 if (ts->pendown)
388 mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
389 else if (ts->irq_disabled) {
390 ts->irq_disabled = 0;
391 enable_irq(ts->spi->irq);
392 }
393 }
394 394
395 spin_unlock_irqrestore(&ts->lock, flags); 395 spin_unlock_irqrestore(&ts->lock, flags);
396} 396}
@@ -431,10 +431,25 @@ static void ads7846_timer(unsigned long handle)
431 struct ads7846 *ts = (void *)handle; 431 struct ads7846 *ts = (void *)handle;
432 int status = 0; 432 int status = 0;
433 433
434 ts->msg_idx = 0; 434 spin_lock_irq(&ts->lock);
435 status = spi_async(ts->spi, &ts->msg[0]); 435
436 if (status) 436 if (unlikely(ts->msg_idx && !ts->pendown)) {
437 dev_err(&ts->spi->dev, "spi_async --> %d\n", status); 437 /* measurment cycle ended */
438 if (!device_suspended(&ts->spi->dev)) {
439 ts->irq_disabled = 0;
440 enable_irq(ts->spi->irq);
441 }
442 ts->pending = 0;
443 ts->msg_idx = 0;
444 } else {
445 /* pen is still down, continue with the measurement */
446 ts->msg_idx = 0;
447 status = spi_async(ts->spi, &ts->msg[0]);
448 if (status)
449 dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
450 }
451
452 spin_unlock_irq(&ts->lock);
438} 453}
439 454
440static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs) 455static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
@@ -443,7 +458,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
443 unsigned long flags; 458 unsigned long flags;
444 459
445 spin_lock_irqsave(&ts->lock, flags); 460 spin_lock_irqsave(&ts->lock, flags);
446 if (likely(!ts->irq_disabled && !ts->disabled)) { 461 if (likely(ts->get_pendown_state())) {
447 if (!ts->irq_disabled) { 462 if (!ts->irq_disabled) {
448 /* REVISIT irq logic for many ARM chips has cloned a 463 /* REVISIT irq logic for many ARM chips has cloned a
449 * bug wherein disabling an irq in its handler won't 464 * bug wherein disabling an irq in its handler won't
@@ -452,10 +467,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
452 * that state here. 467 * that state here.
453 */ 468 */
454 ts->irq_disabled = 1; 469 ts->irq_disabled = 1;
455
456 disable_irq(ts->spi->irq); 470 disable_irq(ts->spi->irq);
457 }
458 if (!ts->pending) {
459 ts->pending = 1; 471 ts->pending = 1;
460 mod_timer(&ts->timer, jiffies); 472 mod_timer(&ts->timer, jiffies);
461 } 473 }
@@ -473,20 +485,17 @@ static void ads7846_disable(struct ads7846 *ts)
473 if (ts->disabled) 485 if (ts->disabled)
474 return; 486 return;
475 487
488 ts->disabled = 1;
489
476 /* are we waiting for IRQ, or polling? */ 490 /* are we waiting for IRQ, or polling? */
477 if (!ts->pendown) { 491 if (!ts->pending) {
478 if (!ts->irq_disabled) { 492 ts->irq_disabled = 1;
479 ts->irq_disabled = 1; 493 disable_irq(ts->spi->irq);
480 disable_irq(ts->spi->irq);
481 }
482 } else { 494 } else {
483 /* polling; force a final SPI completion; 495 /* the timer will run at least once more, and
484 * that will clean things up neatly 496 * leave everything in a clean state, IRQ disabled
485 */ 497 */
486 if (!ts->pending) 498 while (ts->pending) {
487 mod_timer(&ts->timer, jiffies);
488
489 while (ts->pendown || ts->pending) {
490 spin_unlock_irq(&ts->lock); 499 spin_unlock_irq(&ts->lock);
491 msleep(1); 500 msleep(1);
492 spin_lock_irq(&ts->lock); 501 spin_lock_irq(&ts->lock);
@@ -497,7 +506,6 @@ static void ads7846_disable(struct ads7846 *ts)
497 * leave it that way after every request 506 * leave it that way after every request
498 */ 507 */
499 508
500 ts->disabled = 1;
501} 509}
502 510
503/* Must be called with ts->lock held */ 511/* Must be called with ts->lock held */
@@ -566,6 +574,11 @@ static int __devinit ads7846_probe(struct spi_device *spi)
566 return -EINVAL; 574 return -EINVAL;
567 } 575 }
568 576
577 if (pdata->get_pendown_state == NULL) {
578 dev_dbg(&spi->dev, "no get_pendown_state function?\n");
579 return -EINVAL;
580 }
581
569 /* We'd set the wordsize to 12 bits ... except that some controllers 582 /* We'd set the wordsize to 12 bits ... except that some controllers
570 * will then treat the 8 bit command words as 12 bits (and drop the 583 * will then treat the 8 bit command words as 12 bits (and drop the
571 * four MSBs of the 12 bit result). Result: inputs must be shifted 584 * four MSBs of the 12 bit result). Result: inputs must be shifted
@@ -596,6 +609,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
596 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; 609 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
597 ts->debounce_max = pdata->debounce_max ? : 1; 610 ts->debounce_max = pdata->debounce_max ? : 1;
598 ts->debounce_tol = pdata->debounce_tol ? : 10; 611 ts->debounce_tol = pdata->debounce_tol ? : 10;
612 ts->get_pendown_state = pdata->get_pendown_state;
599 613
600 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); 614 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
601 615
@@ -786,8 +800,8 @@ static int __devexit ads7846_remove(struct spi_device *spi)
786 device_remove_file(&spi->dev, &dev_attr_vaux); 800 device_remove_file(&spi->dev, &dev_attr_vaux);
787 801
788 free_irq(ts->spi->irq, ts); 802 free_irq(ts->spi->irq, ts);
789 if (ts->irq_disabled) 803 /* suspend left the IRQ disabled */
790 enable_irq(ts->spi->irq); 804 enable_irq(ts->spi->irq);
791 805
792 kfree(ts); 806 kfree(ts);
793 807