diff options
author | Daniel Kurtz <djkurtz@chromium.org> | 2012-06-28 09:08:17 -0400 |
---|---|---|
committer | Henrik Rydberg <rydberg@euromail.se> | 2012-06-29 09:58:05 -0400 |
commit | fba5bc313c44acfb3561da69526cbc1a0029cdd8 (patch) | |
tree | b0f87c1dbe7acbe68510525899ed6e227291d318 | |
parent | b19fc9ec241382c2155bf56f08f02066f2fb4826 (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.c | 89 |
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 | ||
242 | struct 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 */ |
251 | struct mxt_data { | 243 | struct 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 | ||
522 | static 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 | |||
565 | static void mxt_input_touchevent(struct mxt_data *data, | 513 | static 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 | ||
615 | static irqreturn_t mxt_interrupt(int irq, void *dev_id) | 552 | static irqreturn_t mxt_interrupt(int irq, void *dev_id) |