Skip to content

Commit 9d8dc3e

Browse files
ndyerdtor
authored andcommitted
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 <[email protected]> Acked-by: Benson Leung <[email protected]> Acked-by: Yufeng Shen <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent b9b05a8 commit 9d8dc3e

File tree

1 file changed

+159
-32
lines changed

1 file changed

+159
-32
lines changed

drivers/input/touchscreen/atmel_mxt_ts.c

Lines changed: 159 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,15 @@ struct mxt_data {
244244
unsigned int max_y;
245245
bool in_bootloader;
246246
u16 mem_size;
247+
u8 max_reportid;
247248
u32 config_crc;
248249
u32 info_crc;
249250
u8 bootloader_addr;
250251
u8 *msg_buf;
251252
u8 t6_status;
252253
bool update_input;
254+
u8 last_message_count;
255+
u8 num_touchids;
253256

254257
/* Cached parameters from object table */
255258
u16 T5_address;
@@ -260,6 +263,7 @@ struct mxt_data {
260263
u8 T9_reportid_min;
261264
u8 T9_reportid_max;
262265
u8 T19_reportid;
266+
u16 T44_address;
263267

264268
/* for fw update in bootloader */
265269
struct completion bl_completion;
@@ -795,30 +799,142 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)
795799
return 1;
796800
}
797801

798-
static int mxt_read_and_process_message(struct mxt_data *data)
802+
static int mxt_read_and_process_messages(struct mxt_data *data, u8 count)
799803
{
800804
struct device *dev = &data->client->dev;
801805
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;
802812

813+
/* Process remaining messages if necessary */
803814
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);
805816
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);
807818
return ret;
808819
}
809820

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;
811831
}
812832

813-
static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)
833+
static irqreturn_t mxt_process_messages_t44(struct mxt_data *data)
814834
{
835+
struct device *dev = &data->client->dev;
815836
int ret;
837+
u8 count, num_left;
816838

817-
do {
818-
ret = mxt_read_and_process_message(data);
839+
/* Read T44 and T5 together */
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);
819869
if (ret < 0)
870+
goto end;
871+
else if (ret != num_left)
872+
dev_warn(dev, "Unexpected invalid message\n");
873+
}
874+
875+
end:
876+
if (data->update_input) {
877+
mxt_input_sync(data);
878+
data->update_input = false;
879+
}
880+
881+
return IRQ_HANDLED;
882+
}
883+
884+
static 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+
908+
static 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)
820928
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+
936+
update_count:
937+
data->last_message_count = total_handled;
822938

823939
if (data->update_input) {
824940
mxt_input_sync(data);
@@ -841,7 +957,11 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
841957
if (!data->object_table)
842958
return IRQ_HANDLED;
843959

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+
}
845965
}
846966

847967
static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset,
@@ -1214,32 +1334,13 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
12141334
return ret;
12151335
}
12161336

1217-
static 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-
12361337
static int mxt_acquire_irq(struct mxt_data *data)
12371338
{
12381339
int error;
12391340

12401341
enable_irq(data->irq);
12411342

1242-
error = mxt_make_highchg(data);
1343+
error = mxt_process_messages_until_invalid(data);
12431344
if (error)
12441345
return error;
12451346

@@ -1276,6 +1377,8 @@ static void mxt_free_object_table(struct mxt_data *data)
12761377
data->T9_reportid_min = 0;
12771378
data->T9_reportid_max = 0;
12781379
data->T19_reportid = 0;
1380+
data->T44_address = 0;
1381+
data->max_reportid = 0;
12791382
}
12801383

12811384
static int mxt_get_object_table(struct mxt_data *data)
@@ -1329,8 +1432,16 @@ static int mxt_get_object_table(struct mxt_data *data)
13291432

13301433
switch (object->type) {
13311434
case MXT_GEN_MESSAGE_T5:
1332-
/* CRC not enabled, therefore don't read last byte */
1333-
data->T5_msg_size = mxt_obj_size(object) - 1;
1435+
if (data->info.family_id == 0x80) {
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+
}
13341445
data->T5_address = object->start_address;
13351446
case MXT_GEN_COMMAND_T6:
13361447
data->T6_reportid = min_id;
@@ -1342,6 +1453,11 @@ static int mxt_get_object_table(struct mxt_data *data)
13421453
case MXT_TOUCH_MULTI_T9:
13431454
data->T9_reportid_min = min_id;
13441455
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;
13451461
break;
13461462
case MXT_SPT_GPIOPWM_T19:
13471463
data->T19_reportid = min_id;
@@ -1355,7 +1471,18 @@ static int mxt_get_object_table(struct mxt_data *data)
13551471
data->mem_size = end_address + 1;
13561472
}
13571473

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);
13591486
if (!data->msg_buf) {
13601487
dev_err(&client->dev, "Failed to allocate message buffer\n");
13611488
error = -ENOMEM;

0 commit comments

Comments
 (0)