|
@@ -378,11 +378,8 @@ static struct attribute_group ads7845_attr_group = {
|
|
|
static void ads7846_rx(void *ads)
|
|
|
{
|
|
|
struct ads7846 *ts = ads;
|
|
|
- struct input_dev *input_dev = ts->input;
|
|
|
unsigned Rt;
|
|
|
- unsigned sync = 0;
|
|
|
u16 x, y, z1, z2;
|
|
|
- unsigned long flags;
|
|
|
|
|
|
/* ads7846_rx_val() did in-place conversion (including byteswap) from
|
|
|
* on-the-wire format as part of debouncing to get stable readings.
|
|
@@ -396,7 +393,7 @@ static void ads7846_rx(void *ads)
|
|
|
if (x == MAX_12BIT)
|
|
|
x = 0;
|
|
|
|
|
|
- if (likely(x && z1 && !device_suspended(&ts->spi->dev))) {
|
|
|
+ if (likely(x && z1)) {
|
|
|
/* compute touch pressure resistance using equation #2 */
|
|
|
Rt = z2;
|
|
|
Rt -= z1;
|
|
@@ -412,52 +409,44 @@ static void ads7846_rx(void *ads)
|
|
|
* once more the measurement
|
|
|
*/
|
|
|
if (ts->tc.ignore || Rt > ts->pressure_max) {
|
|
|
+#ifdef VERBOSE
|
|
|
+ pr_debug("%s: ignored %d pressure %d\n",
|
|
|
+ ts->spi->dev.bus_id, ts->tc.ignore, Rt);
|
|
|
+#endif
|
|
|
hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
|
|
|
HRTIMER_REL);
|
|
|
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).
|
|
|
- *
|
|
|
- * REVISIT: some boards may require reading nPENIRQ; it's
|
|
|
- * needed on 7843. and 7845 reads pressure differently...
|
|
|
+ /* NOTE: We can't rely on the pressure to determine the pen down
|
|
|
+ * state, even this controller has a pressure sensor. The pressure
|
|
|
+ * value can fluctuate for quite a while after lifting the pen and
|
|
|
+ * in some cases may not even settle at the expected value.
|
|
|
*
|
|
|
- * REVISIT: the touchscreen might not be connected; this code
|
|
|
- * won't notice that, even if nPENIRQ never fires ...
|
|
|
+ * The only safe way to check for the pen up condition is in the
|
|
|
+ * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
|
|
|
*/
|
|
|
- if (!ts->pendown && Rt != 0) {
|
|
|
- input_report_key(input_dev, BTN_TOUCH, 1);
|
|
|
- sync = 1;
|
|
|
- } else if (ts->pendown && Rt == 0) {
|
|
|
- input_report_key(input_dev, BTN_TOUCH, 0);
|
|
|
- sync = 1;
|
|
|
- }
|
|
|
-
|
|
|
if (Rt) {
|
|
|
- input_report_abs(input_dev, ABS_X, x);
|
|
|
- input_report_abs(input_dev, ABS_Y, y);
|
|
|
- sync = 1;
|
|
|
- }
|
|
|
+ struct input_dev *input = ts->input;
|
|
|
|
|
|
- if (sync) {
|
|
|
- input_report_abs(input_dev, ABS_PRESSURE, Rt);
|
|
|
- input_sync(input_dev);
|
|
|
- }
|
|
|
-
|
|
|
-#ifdef VERBOSE
|
|
|
- if (Rt || ts->pendown)
|
|
|
- pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id,
|
|
|
- x, y, Rt, Rt ? "" : " UP");
|
|
|
+ if (!ts->pendown) {
|
|
|
+ input_report_key(input, BTN_TOUCH, 1);
|
|
|
+ ts->pendown = 1;
|
|
|
+#ifdef VERBOSE
|
|
|
+ dev_dbg(&ts->spi->dev, "DOWN\n");
|
|
|
#endif
|
|
|
+ }
|
|
|
+ input_report_abs(input, ABS_X, x);
|
|
|
+ input_report_abs(input, ABS_Y, y);
|
|
|
+ input_report_abs(input, ABS_PRESSURE, Rt);
|
|
|
|
|
|
- spin_lock_irqsave(&ts->lock, flags);
|
|
|
+ input_sync(input);
|
|
|
+#ifdef VERBOSE
|
|
|
+ dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
|
|
|
+#endif
|
|
|
+ }
|
|
|
|
|
|
- ts->pendown = (Rt != 0);
|
|
|
hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_REL);
|
|
|
-
|
|
|
- spin_unlock_irqrestore(&ts->lock, flags);
|
|
|
}
|
|
|
|
|
|
static int ads7846_debounce(void *ads, int data_idx, int *val)
|
|
@@ -553,14 +542,27 @@ static int ads7846_timer(struct hrtimer *handle)
|
|
|
|
|
|
spin_lock_irq(&ts->lock);
|
|
|
|
|
|
- if (unlikely(ts->msg_idx && !ts->pendown)) {
|
|
|
+ if (unlikely(!ts->get_pendown_state() ||
|
|
|
+ device_suspended(&ts->spi->dev))) {
|
|
|
+ if (ts->pendown) {
|
|
|
+ struct input_dev *input = ts->input;
|
|
|
+
|
|
|
+ input_report_key(input, BTN_TOUCH, 0);
|
|
|
+ input_report_abs(input, ABS_PRESSURE, 0);
|
|
|
+ input_sync(input);
|
|
|
+
|
|
|
+ ts->pendown = 0;
|
|
|
+#ifdef VERBOSE
|
|
|
+ dev_dbg(&ts->spi->dev, "UP\n");
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
/* measurement 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;
|