aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Dyer <nick.dyer@itdev.co.uk>2014-07-23 15:49:04 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-23 17:42:14 -0400
commit9d8dc3e529a19e427fd379118acd132520935c5d (patch)
tree30fe040eede1891d31b2274b877ebe77c29d565e
parentb9b05a89721f05e2db227283ec9f7af804830b01 (diff)
Input: atmel_mxt_ts - implement T44 message handling
maXTouch chips allow the reading of multiple messages in a single I2C transaction, which reduces bus overhead and improves performance/latency. The number of messages available to be read is given by the value in the T44 object which is located directly before the T5 object. Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk> Acked-by: Benson Leung <bleung@chromium.org> Acked-by: Yufeng Shen <miletus@chromium.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c191
1 files changed, 159 insertions, 32 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 699de552a6d8..c6dfd0af6365 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -244,12 +244,15 @@ struct mxt_data {
244 unsigned int max_y; 244 unsigned int max_y;
245 bool in_bootloader; 245 bool in_bootloader;
246 u16 mem_size; 246 u16 mem_size;
247 u8 max_reportid;
247 u32 config_crc; 248 u32 config_crc;
248 u32 info_crc; 249 u32 info_crc;
249 u8 bootloader_addr; 250 u8 bootloader_addr;
250 u8 *msg_buf; 251 u8 *msg_buf;
251 u8 t6_status; 252 u8 t6_status;
252 bool update_input; 253 bool update_input;
254 u8 last_message_count;
255 u8 num_touchids;
253 256
254 /* Cached parameters from object table */ 257 /* Cached parameters from object table */
255 u16 T5_address; 258 u16 T5_address;
@@ -260,6 +263,7 @@ struct mxt_data {
260 u8 T9_reportid_min; 263 u8 T9_reportid_min;
261 u8 T9_reportid_max; 264 u8 T9_reportid_max;
262 u8 T19_reportid; 265 u8 T19_reportid;
266 u16 T44_address;
263 267
264 /* for fw update in bootloader */ 268 /* for fw update in bootloader */
265 struct completion bl_completion; 269 struct completion bl_completion;
@@ -795,30 +799,142 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)
795 return 1; 799 return 1;
796} 800}
797 801
798static int mxt_read_and_process_message(struct mxt_data *data) 802static int mxt_read_and_process_messages(struct mxt_data *data, u8 count)
799{ 803{
800 struct device *dev = &data->client->dev; 804 struct device *dev = &data->client->dev;
801 int ret; 805 int ret;
806 int i;
807 u8 num_valid = 0;
808
809 /* Safety check for msg_buf */
810 if (count > data->max_reportid)
811 return -EINVAL;
802 812
813 /* Process remaining messages if necessary */
803 ret = __mxt_read_reg(data->client, data->T5_address, 814 ret = __mxt_read_reg(data->client, data->T5_address,
804 data->T5_msg_size, data->msg_buf); 815 data->T5_msg_size * count, data->msg_buf);
805 if (ret) { 816 if (ret) {
806 dev_err(dev, "Error %d reading message\n", ret); 817 dev_err(dev, "Failed to read %u messages (%d)\n", count, ret);
807 return ret; 818 return ret;
808 } 819 }
809 820
810 return mxt_proc_message(data, data->msg_buf); 821 for (i = 0; i < count; i++) {
822 ret = mxt_proc_message(data,
823 data->msg_buf + data->T5_msg_size * i);
824
825 if (ret == 1)
826 num_valid++;
827 }
828
829 /* return number of messages read */
830 return num_valid;
811} 831}
812 832
813static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data) 833static irqreturn_t mxt_process_messages_t44(struct mxt_data *data)
814{ 834{
835 struct device *dev = &data->client->dev;
815 int ret; 836 int ret;
837 u8 count, num_left;
816 838
817 do { 839 /* Read T44 and T5 together */
818 ret = mxt_read_and_process_message(data); 840 ret = __mxt_read_reg(data->client, data->T44_address,
841 data->T5_msg_size + 1, data->msg_buf);
842 if (ret) {
843 dev_err(dev, "Failed to read T44 and T5 (%d)\n", ret);
844 return IRQ_NONE;
845 }
846
847 count = data->msg_buf[0];
848
849 if (count == 0) {
850 dev_warn(dev, "Interrupt triggered but zero messages\n");
851 return IRQ_NONE;
852 } else if (count > data->max_reportid) {
853 dev_err(dev, "T44 count %d exceeded max report id\n", count);
854 count = data->max_reportid;
855 }
856
857 /* Process first message */
858 ret = mxt_proc_message(data, data->msg_buf + 1);
859 if (ret < 0) {
860 dev_warn(dev, "Unexpected invalid message\n");
861 return IRQ_NONE;
862 }
863
864 num_left = count - 1;
865
866 /* Process remaining messages if necessary */
867 if (num_left) {
868 ret = mxt_read_and_process_messages(data, num_left);
819 if (ret < 0) 869 if (ret < 0)
870 goto end;
871 else if (ret != num_left)
872 dev_warn(dev, "Unexpected invalid message\n");
873 }
874
875end:
876 if (data->update_input) {
877 mxt_input_sync(data);
878 data->update_input = false;
879 }
880
881 return IRQ_HANDLED;
882}
883
884static int mxt_process_messages_until_invalid(struct mxt_data *data)
885{
886 struct device *dev = &data->client->dev;
887 int count, read;
888 u8 tries = 2;
889
890 count = data->max_reportid;
891
892 /* Read messages until we force an invalid */
893 do {
894 read = mxt_read_and_process_messages(data, count);
895 if (read < count)
896 return 0;
897 } while (--tries);
898
899 if (data->update_input) {
900 mxt_input_sync(data);
901 data->update_input = false;
902 }
903
904 dev_err(dev, "CHG pin isn't cleared\n");
905 return -EBUSY;
906}
907
908static irqreturn_t mxt_process_messages(struct mxt_data *data)
909{
910 int total_handled, num_handled;
911 u8 count = data->last_message_count;
912
913 if (count < 1 || count > data->max_reportid)
914 count = 1;
915
916 /* include final invalid message */
917 total_handled = mxt_read_and_process_messages(data, count + 1);
918 if (total_handled < 0)
919 return IRQ_NONE;
920 /* if there were invalid messages, then we are done */
921 else if (total_handled <= count)
922 goto update_count;
923
924 /* keep reading two msgs until one is invalid or reportid limit */
925 do {
926 num_handled = mxt_read_and_process_messages(data, 2);
927 if (num_handled < 0)
820 return IRQ_NONE; 928 return IRQ_NONE;
821 } while (ret > 0); 929
930 total_handled += num_handled;
931
932 if (num_handled < 2)
933 break;
934 } while (total_handled < data->num_touchids);
935
936update_count:
937 data->last_message_count = total_handled;
822 938
823 if (data->update_input) { 939 if (data->update_input) {
824 mxt_input_sync(data); 940 mxt_input_sync(data);
@@ -841,7 +957,11 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
841 if (!data->object_table) 957 if (!data->object_table)
842 return IRQ_HANDLED; 958 return IRQ_HANDLED;
843 959
844 return mxt_process_messages_until_invalid(data); 960 if (data->T44_address) {
961 return mxt_process_messages_t44(data);
962 } else {
963 return mxt_process_messages(data);
964 }
845} 965}
846 966
847static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset, 967static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset,
@@ -1214,32 +1334,13 @@ release:
1214 return ret; 1334 return ret;
1215} 1335}
1216 1336
1217static int mxt_make_highchg(struct mxt_data *data)
1218{
1219 struct device *dev = &data->client->dev;
1220 int count = 10;
1221 int ret;
1222
1223 /* Read messages until we force an invalid */
1224 do {
1225 ret = mxt_read_and_process_message(data);
1226 if (ret == 0)
1227 return 0;
1228 else if (ret < 0)
1229 return ret;
1230 } while (--count);
1231
1232 dev_err(dev, "CHG pin isn't cleared\n");
1233 return -EBUSY;
1234}
1235
1236static int mxt_acquire_irq(struct mxt_data *data) 1337static int mxt_acquire_irq(struct mxt_data *data)
1237{ 1338{
1238 int error; 1339 int error;
1239 1340
1240 enable_irq(data->irq); 1341 enable_irq(data->irq);
1241 1342
1242 error = mxt_make_highchg(data); 1343 error = mxt_process_messages_until_invalid(data);
1243 if (error) 1344 if (error)
1244 return error; 1345 return error;
1245 1346
@@ -1276,6 +1377,8 @@ static void mxt_free_object_table(struct mxt_data *data)
1276 data->T9_reportid_min = 0; 1377 data->T9_reportid_min = 0;
1277 data->T9_reportid_max = 0; 1378 data->T9_reportid_max = 0;
1278 data->T19_reportid = 0; 1379 data->T19_reportid = 0;
1380 data->T44_address = 0;
1381 data->max_reportid = 0;
1279} 1382}
1280 1383
1281static int mxt_get_object_table(struct mxt_data *data) 1384static int mxt_get_object_table(struct mxt_data *data)
@@ -1329,8 +1432,16 @@ static int mxt_get_object_table(struct mxt_data *data)
1329 1432
1330 switch (object->type) { 1433 switch (object->type) {
1331 case MXT_GEN_MESSAGE_T5: 1434 case MXT_GEN_MESSAGE_T5:
1332 /* CRC not enabled, therefore don't read last byte */ 1435 if (data->info.family_id == 0x80) {
1333 data->T5_msg_size = mxt_obj_size(object) - 1; 1436 /*
1437 * On mXT224 read and discard unused CRC byte
1438 * otherwise DMA reads are misaligned
1439 */
1440 data->T5_msg_size = mxt_obj_size(object);
1441 } else {
1442 /* CRC not enabled, so skip last byte */
1443 data->T5_msg_size = mxt_obj_size(object) - 1;
1444 }
1334 data->T5_address = object->start_address; 1445 data->T5_address = object->start_address;
1335 case MXT_GEN_COMMAND_T6: 1446 case MXT_GEN_COMMAND_T6:
1336 data->T6_reportid = min_id; 1447 data->T6_reportid = min_id;
@@ -1342,6 +1453,11 @@ static int mxt_get_object_table(struct mxt_data *data)
1342 case MXT_TOUCH_MULTI_T9: 1453 case MXT_TOUCH_MULTI_T9:
1343 data->T9_reportid_min = min_id; 1454 data->T9_reportid_min = min_id;
1344 data->T9_reportid_max = max_id; 1455 data->T9_reportid_max = max_id;
1456 data->num_touchids = object->num_report_ids
1457 * mxt_obj_instances(object);
1458 break;
1459 case MXT_SPT_MESSAGECOUNT_T44:
1460 data->T44_address = object->start_address;
1345 break; 1461 break;
1346 case MXT_SPT_GPIOPWM_T19: 1462 case MXT_SPT_GPIOPWM_T19:
1347 data->T19_reportid = min_id; 1463 data->T19_reportid = min_id;
@@ -1355,7 +1471,18 @@ static int mxt_get_object_table(struct mxt_data *data)
1355 data->mem_size = end_address + 1; 1471 data->mem_size = end_address + 1;
1356 } 1472 }
1357 1473
1358 data->msg_buf = kzalloc(data->T5_msg_size, GFP_KERNEL); 1474 /* Store maximum reportid */
1475 data->max_reportid = reportid;
1476
1477 /* If T44 exists, T5 position has to be directly after */
1478 if (data->T44_address && (data->T5_address != data->T44_address + 1)) {
1479 dev_err(&client->dev, "Invalid T44 position\n");
1480 error = -EINVAL;
1481 goto free_object_table;
1482 }
1483
1484 data->msg_buf = kcalloc(data->max_reportid,
1485 data->T5_msg_size, GFP_KERNEL);
1359 if (!data->msg_buf) { 1486 if (!data->msg_buf) {
1360 dev_err(&client->dev, "Failed to allocate message buffer\n"); 1487 dev_err(&client->dev, "Failed to allocate message buffer\n");
1361 error = -ENOMEM; 1488 error = -ENOMEM;