aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kurtz <djkurtz@chromium.org>2012-06-28 09:08:17 -0400
committerHenrik Rydberg <rydberg@euromail.se>2012-06-29 09:58:05 -0400
commitfba5bc313c44acfb3561da69526cbc1a0029cdd8 (patch)
treeb0f87c1dbe7acbe68510525899ed6e227291d318
parentb19fc9ec241382c2155bf56f08f02066f2fb4826 (diff)
Input: atmel_mxt_ts - simplify event reporting
Instead of carrying around per-finger state in the driver instance, just report each finger as it arrives to the input layer, and let the input layer (evdev) hold the event state (which it does anyway). Note: this driver does not really do MT-B properly. Each input report (a group of input events followed by a SYN_REPORT) only contains data for a single contact. When multiple fingers are present on a device, each is properly reported in its own MT_SLOT. However, there is only ever one MT_SLOT per SYN_REPORT. This is fixed in a subsequent patch. This patch was tested with an mXT224E. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c89
1 files changed, 13 insertions, 76 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f2c1fbe2556e..c37584de49ca 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -239,14 +239,6 @@ struct mxt_message {
239 u8 message[7]; 239 u8 message[7];
240}; 240};
241 241
242struct mxt_finger {
243 int status;
244 int x;
245 int y;
246 int area;
247 int pressure;
248};
249
250/* Each client has this additional data */ 242/* Each client has this additional data */
251struct mxt_data { 243struct mxt_data {
252 struct i2c_client *client; 244 struct i2c_client *client;
@@ -255,7 +247,6 @@ struct mxt_data {
255 const struct mxt_platform_data *pdata; 247 const struct mxt_platform_data *pdata;
256 struct mxt_object *object_table; 248 struct mxt_object *object_table;
257 struct mxt_info info; 249 struct mxt_info info;
258 struct mxt_finger finger[MXT_MAX_FINGER];
259 unsigned int irq; 250 unsigned int irq;
260 unsigned int max_x; 251 unsigned int max_x;
261 unsigned int max_y; 252 unsigned int max_y;
@@ -519,75 +510,17 @@ static int mxt_write_object(struct mxt_data *data,
519 return mxt_write_reg(data->client, reg + offset, val); 510 return mxt_write_reg(data->client, reg + offset, val);
520} 511}
521 512
522static void mxt_input_report(struct mxt_data *data, int single_id)
523{
524 struct mxt_finger *finger = data->finger;
525 struct input_dev *input_dev = data->input_dev;
526 int status = finger[single_id].status;
527 int finger_num = 0;
528 int id;
529
530 for (id = 0; id < MXT_MAX_FINGER; id++) {
531 if (!finger[id].status)
532 continue;
533
534 input_mt_slot(input_dev, id);
535 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
536 finger[id].status != MXT_RELEASE);
537
538 if (finger[id].status != MXT_RELEASE) {
539 finger_num++;
540 input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
541 finger[id].area);
542 input_report_abs(input_dev, ABS_MT_POSITION_X,
543 finger[id].x);
544 input_report_abs(input_dev, ABS_MT_POSITION_Y,
545 finger[id].y);
546 input_report_abs(input_dev, ABS_MT_PRESSURE,
547 finger[id].pressure);
548 } else {
549 finger[id].status = 0;
550 }
551 }
552
553 input_report_key(input_dev, BTN_TOUCH, finger_num > 0);
554
555 if (status != MXT_RELEASE) {
556 input_report_abs(input_dev, ABS_X, finger[single_id].x);
557 input_report_abs(input_dev, ABS_Y, finger[single_id].y);
558 input_report_abs(input_dev,
559 ABS_PRESSURE, finger[single_id].pressure);
560 }
561
562 input_sync(input_dev);
563}
564
565static void mxt_input_touchevent(struct mxt_data *data, 513static void mxt_input_touchevent(struct mxt_data *data,
566 struct mxt_message *message, int id) 514 struct mxt_message *message, int id)
567{ 515{
568 struct mxt_finger *finger = data->finger;
569 struct device *dev = &data->client->dev; 516 struct device *dev = &data->client->dev;
570 u8 status = message->message[0]; 517 u8 status = message->message[0];
518 struct input_dev *input_dev = data->input_dev;
571 int x; 519 int x;
572 int y; 520 int y;
573 int area; 521 int area;
574 int pressure; 522 int pressure;
575 523
576 /* Check the touch is present on the screen */
577 if (!(status & MXT_DETECT)) {
578 if (status & MXT_RELEASE) {
579 dev_dbg(dev, "[%d] released\n", id);
580
581 finger[id].status = MXT_RELEASE;
582 mxt_input_report(data, id);
583 }
584 return;
585 }
586
587 /* Check only AMP detection */
588 if (!(status & (MXT_PRESS | MXT_MOVE)))
589 return;
590
591 x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf); 524 x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
592 y = (message->message[2] << 4) | ((message->message[3] & 0xf)); 525 y = (message->message[2] << 4) | ((message->message[3] & 0xf));
593 if (data->max_x < 1024) 526 if (data->max_x < 1024)
@@ -601,15 +534,19 @@ static void mxt_input_touchevent(struct mxt_data *data,
601 dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, 534 dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id,
602 status & MXT_MOVE ? "moved" : "pressed", 535 status & MXT_MOVE ? "moved" : "pressed",
603 x, y, area); 536 x, y, area);
537 input_mt_slot(input_dev, id);
538 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
539 status & MXT_DETECT);
540
541 if (status & MXT_DETECT) {
542 input_report_abs(input_dev, ABS_MT_POSITION_X, x);
543 input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
544 input_report_abs(input_dev, ABS_MT_PRESSURE, pressure);
545 input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
546 }
604 547
605 finger[id].status = status & MXT_MOVE ? 548 input_mt_report_pointer_emulation(input_dev, false);
606 MXT_MOVE : MXT_PRESS; 549 input_sync(input_dev);
607 finger[id].x = x;
608 finger[id].y = y;
609 finger[id].area = area;
610 finger[id].pressure = pressure;
611
612 mxt_input_report(data, id);
613} 550}
614 551
615static irqreturn_t mxt_interrupt(int irq, void *dev_id) 552static irqreturn_t mxt_interrupt(int irq, void *dev_id)