aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDaniel Kurtz <djkurtz@chromium.org>2012-06-28 09:08:20 -0400
committerHenrik Rydberg <rydberg@euromail.se>2012-06-29 09:58:06 -0400
commit333e5a9a99b8bba14f1a8631218d2d1e55fd58b1 (patch)
tree5ef107a17e2bcba86dfc8f7238a50d854be7f5f9 /drivers/input
parent7d4fa100b0cc069b2d788e1d9fe086e9e057958e (diff)
Input: atmel_mxt_ts - cache T9 reportid range when reading object table
Streamline interrupt processing by caching the T9 reportid range when first reading the object table. In the process, refactor reading the object descriptor table. First, since the object_table entries are now exactly the same layout in device memory and in the driver, allocate an appropriately sized array and fetch the entire table directly into it in a single i2c transaction. Since a 6 byte table object requires 10 bytes to read, doing this dramatically reduces overhead. Note: The cached T9 reportid's are initialized to 0, which is an invalid reportid. Thus, the checks in the interrupt handler will always fail for devices that do not support the T9 object. Therefore, after doing a firmware update, the old object table is destroyed and all cached object values are reset to 0, before reading the new object table, in case the new firmware does not have the old objects. This patch tested on an MXT224E. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c76
1 files changed, 41 insertions, 35 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 488e3e88c3fc..48f3637aecaa 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -227,13 +227,10 @@ struct mxt_info {
227struct mxt_object { 227struct mxt_object {
228 u8 type; 228 u8 type;
229 u16 start_address; 229 u16 start_address;
230 u8 size; 230 u8 size; /* Size of each instance - 1 */
231 u8 instances; 231 u8 instances; /* Number of instances - 1 */
232 u8 num_report_ids; 232 u8 num_report_ids;
233 233} __packed;
234 /* to map object and message */
235 u8 max_reportid;
236};
237 234
238struct mxt_message { 235struct mxt_message {
239 u8 reportid; 236 u8 reportid;
@@ -251,6 +248,10 @@ struct mxt_data {
251 unsigned int irq; 248 unsigned int irq;
252 unsigned int max_x; 249 unsigned int max_x;
253 unsigned int max_y; 250 unsigned int max_y;
251
252 /* Cached parameters from object table */
253 u8 T9_reportid_min;
254 u8 T9_reportid_max;
254}; 255};
255 256
256static bool mxt_object_readable(unsigned int type) 257static bool mxt_object_readable(unsigned int type)
@@ -459,13 +460,6 @@ static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
459 return __mxt_write_reg(client, reg, 1, &val); 460 return __mxt_write_reg(client, reg, 1, &val);
460} 461}
461 462
462static int mxt_read_object_table(struct i2c_client *client,
463 u16 reg, u8 *object_buf)
464{
465 return __mxt_read_reg(client, reg, MXT_OBJECT_SIZE,
466 object_buf);
467}
468
469static struct mxt_object * 463static struct mxt_object *
470mxt_get_object(struct mxt_data *data, u8 type) 464mxt_get_object(struct mxt_data *data, u8 type)
471{ 465{
@@ -564,7 +558,6 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
564{ 558{
565 struct mxt_data *data = dev_id; 559 struct mxt_data *data = dev_id;
566 struct mxt_message message; 560 struct mxt_message message;
567 struct mxt_object *object;
568 struct device *dev = &data->client->dev; 561 struct device *dev = &data->client->dev;
569 int id; 562 int id;
570 u8 reportid; 563 u8 reportid;
@@ -579,13 +572,8 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
579 572
580 reportid = message.reportid; 573 reportid = message.reportid;
581 574
582 /* whether reportid is thing of MXT_TOUCH_MULTI_T9 */ 575 max_reportid = data->T9_reportid_max;
583 object = mxt_get_object(data, MXT_TOUCH_MULTI_T9); 576 min_reportid = data->T9_reportid_min;
584 if (!object)
585 goto end;
586
587 max_reportid = object->max_reportid;
588 min_reportid = max_reportid - object->num_report_ids + 1;
589 id = reportid - min_reportid; 577 id = reportid - min_reportid;
590 578
591 if (reportid >= min_reportid && reportid <= max_reportid) 579 if (reportid >= min_reportid && reportid <= max_reportid)
@@ -720,30 +708,46 @@ static int mxt_get_info(struct mxt_data *data)
720 708
721static int mxt_get_object_table(struct mxt_data *data) 709static int mxt_get_object_table(struct mxt_data *data)
722{ 710{
711 struct i2c_client *client = data->client;
712 size_t table_size;
723 int error; 713 int error;
724 int i; 714 int i;
725 u16 reg; 715 u8 reportid;
726 u8 reportid = 0; 716
727 u8 buf[MXT_OBJECT_SIZE]; 717 table_size = data->info.object_num * sizeof(struct mxt_object);
718 error = __mxt_read_reg(client, MXT_OBJECT_START, table_size,
719 data->object_table);
720 if (error)
721 return error;
728 722
723 /* Valid Report IDs start counting from 1 */
724 reportid = 1;
729 for (i = 0; i < data->info.object_num; i++) { 725 for (i = 0; i < data->info.object_num; i++) {
730 struct mxt_object *object = data->object_table + i; 726 struct mxt_object *object = data->object_table + i;
727 u8 min_id, max_id;
731 728
732 reg = MXT_OBJECT_START + MXT_OBJECT_SIZE * i; 729 le16_to_cpus(&object->start_address);
733 error = mxt_read_object_table(data->client, reg, buf);
734 if (error)
735 return error;
736
737 object->type = buf[0];
738 object->start_address = (buf[2] << 8) | buf[1];
739 object->size = buf[3];
740 object->instances = buf[4];
741 object->num_report_ids = buf[5];
742 730
743 if (object->num_report_ids) { 731 if (object->num_report_ids) {
732 min_id = reportid;
744 reportid += object->num_report_ids * 733 reportid += object->num_report_ids *
745 (object->instances + 1); 734 (object->instances + 1);
746 object->max_reportid = reportid; 735 max_id = reportid - 1;
736 } else {
737 min_id = 0;
738 max_id = 0;
739 }
740
741 dev_dbg(&data->client->dev,
742 "Type %2d Start %3d Size %3d Instances %2d ReportIDs %3u : %3u\n",
743 object->type, object->start_address, object->size + 1,
744 object->instances + 1, min_id, max_id);
745
746 switch (object->type) {
747 case MXT_TOUCH_MULTI_T9:
748 data->T9_reportid_min = min_id;
749 data->T9_reportid_max = max_id;
750 break;
747 } 751 }
748 } 752 }
749 753
@@ -754,6 +758,8 @@ static void mxt_free_object_table(struct mxt_data *data)
754{ 758{
755 kfree(data->object_table); 759 kfree(data->object_table);
756 data->object_table = NULL; 760 data->object_table = NULL;
761 data->T9_reportid_min = 0;
762 data->T9_reportid_max = 0;
757} 763}
758 764
759static int mxt_initialize(struct mxt_data *data) 765static int mxt_initialize(struct mxt_data *data)