diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/touchscreen/ads7846.c | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 11979be33589..b18c63a3f2ab 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -378,11 +378,8 @@ static struct attribute_group ads7845_attr_group = { | |||
378 | static void ads7846_rx(void *ads) | 378 | static void ads7846_rx(void *ads) |
379 | { | 379 | { |
380 | struct ads7846 *ts = ads; | 380 | struct ads7846 *ts = ads; |
381 | struct input_dev *input_dev = ts->input; | ||
382 | unsigned Rt; | 381 | unsigned Rt; |
383 | unsigned sync = 0; | ||
384 | u16 x, y, z1, z2; | 382 | u16 x, y, z1, z2; |
385 | unsigned long flags; | ||
386 | 383 | ||
387 | /* ads7846_rx_val() did in-place conversion (including byteswap) from | 384 | /* ads7846_rx_val() did in-place conversion (including byteswap) from |
388 | * on-the-wire format as part of debouncing to get stable readings. | 385 | * on-the-wire format as part of debouncing to get stable readings. |
@@ -396,7 +393,7 @@ static void ads7846_rx(void *ads) | |||
396 | if (x == MAX_12BIT) | 393 | if (x == MAX_12BIT) |
397 | x = 0; | 394 | x = 0; |
398 | 395 | ||
399 | if (likely(x && z1 && !device_suspended(&ts->spi->dev))) { | 396 | if (likely(x && z1)) { |
400 | /* compute touch pressure resistance using equation #2 */ | 397 | /* compute touch pressure resistance using equation #2 */ |
401 | Rt = z2; | 398 | Rt = z2; |
402 | Rt -= z1; | 399 | Rt -= z1; |
@@ -412,52 +409,44 @@ static void ads7846_rx(void *ads) | |||
412 | * once more the measurement | 409 | * once more the measurement |
413 | */ | 410 | */ |
414 | if (ts->tc.ignore || Rt > ts->pressure_max) { | 411 | if (ts->tc.ignore || Rt > ts->pressure_max) { |
412 | #ifdef VERBOSE | ||
413 | pr_debug("%s: ignored %d pressure %d\n", | ||
414 | ts->spi->dev.bus_id, ts->tc.ignore, Rt); | ||
415 | #endif | ||
415 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | 416 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), |
416 | HRTIMER_REL); | 417 | HRTIMER_REL); |
417 | return; | 418 | return; |
418 | } | 419 | } |
419 | 420 | ||
420 | /* NOTE: "pendown" is inferred from pressure; we don't rely on | 421 | /* NOTE: We can't rely on the pressure to determine the pen down |
421 | * being able to check nPENIRQ status, or "friendly" trigger modes | 422 | * state, even this controller has a pressure sensor. The pressure |
422 | * (both-edges is much better than just-falling or low-level). | 423 | * value can fluctuate for quite a while after lifting the pen and |
423 | * | 424 | * in some cases may not even settle at the expected value. |
424 | * REVISIT: some boards may require reading nPENIRQ; it's | ||
425 | * needed on 7843. and 7845 reads pressure differently... | ||
426 | * | 425 | * |
427 | * REVISIT: the touchscreen might not be connected; this code | 426 | * The only safe way to check for the pen up condition is in the |
428 | * won't notice that, even if nPENIRQ never fires ... | 427 | * timer by reading the pen signal state (it's a GPIO _and_ IRQ). |
429 | */ | 428 | */ |
430 | if (!ts->pendown && Rt != 0) { | ||
431 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
432 | sync = 1; | ||
433 | } else if (ts->pendown && Rt == 0) { | ||
434 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
435 | sync = 1; | ||
436 | } | ||
437 | |||
438 | if (Rt) { | 429 | if (Rt) { |
439 | input_report_abs(input_dev, ABS_X, x); | 430 | struct input_dev *input = ts->input; |
440 | input_report_abs(input_dev, ABS_Y, y); | ||
441 | sync = 1; | ||
442 | } | ||
443 | 431 | ||
444 | if (sync) { | 432 | if (!ts->pendown) { |
445 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | 433 | input_report_key(input, BTN_TOUCH, 1); |
446 | input_sync(input_dev); | 434 | ts->pendown = 1; |
447 | } | 435 | #ifdef VERBOSE |
448 | 436 | dev_dbg(&ts->spi->dev, "DOWN\n"); | |
449 | #ifdef VERBOSE | ||
450 | if (Rt || ts->pendown) | ||
451 | pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id, | ||
452 | x, y, Rt, Rt ? "" : " UP"); | ||
453 | #endif | 437 | #endif |
438 | } | ||
439 | input_report_abs(input, ABS_X, x); | ||
440 | input_report_abs(input, ABS_Y, y); | ||
441 | input_report_abs(input, ABS_PRESSURE, Rt); | ||
454 | 442 | ||
455 | spin_lock_irqsave(&ts->lock, flags); | 443 | input_sync(input); |
444 | #ifdef VERBOSE | ||
445 | dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); | ||
446 | #endif | ||
447 | } | ||
456 | 448 | ||
457 | ts->pendown = (Rt != 0); | ||
458 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_REL); | 449 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_REL); |
459 | |||
460 | spin_unlock_irqrestore(&ts->lock, flags); | ||
461 | } | 450 | } |
462 | 451 | ||
463 | static int ads7846_debounce(void *ads, int data_idx, int *val) | 452 | static int ads7846_debounce(void *ads, int data_idx, int *val) |
@@ -553,14 +542,27 @@ static int ads7846_timer(struct hrtimer *handle) | |||
553 | 542 | ||
554 | spin_lock_irq(&ts->lock); | 543 | spin_lock_irq(&ts->lock); |
555 | 544 | ||
556 | if (unlikely(ts->msg_idx && !ts->pendown)) { | 545 | if (unlikely(!ts->get_pendown_state() || |
546 | device_suspended(&ts->spi->dev))) { | ||
547 | if (ts->pendown) { | ||
548 | struct input_dev *input = ts->input; | ||
549 | |||
550 | input_report_key(input, BTN_TOUCH, 0); | ||
551 | input_report_abs(input, ABS_PRESSURE, 0); | ||
552 | input_sync(input); | ||
553 | |||
554 | ts->pendown = 0; | ||
555 | #ifdef VERBOSE | ||
556 | dev_dbg(&ts->spi->dev, "UP\n"); | ||
557 | #endif | ||
558 | } | ||
559 | |||
557 | /* measurement cycle ended */ | 560 | /* measurement cycle ended */ |
558 | if (!device_suspended(&ts->spi->dev)) { | 561 | if (!device_suspended(&ts->spi->dev)) { |
559 | ts->irq_disabled = 0; | 562 | ts->irq_disabled = 0; |
560 | enable_irq(ts->spi->irq); | 563 | enable_irq(ts->spi->irq); |
561 | } | 564 | } |
562 | ts->pending = 0; | 565 | ts->pending = 0; |
563 | ts->msg_idx = 0; | ||
564 | } else { | 566 | } else { |
565 | /* pen is still down, continue with the measurement */ | 567 | /* pen is still down, continue with the measurement */ |
566 | ts->msg_idx = 0; | 568 | ts->msg_idx = 0; |