aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorNick Dyer <nick.dyer@itdev.co.uk>2014-07-23 15:38:48 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-23 17:42:07 -0400
commit50a77c658b80e7e3303e3bcec195b30e2b62d513 (patch)
tree51681b9187e29a1f616b4a3dcb5ca5496d4f31f0 /drivers/input
parent78188be3e5dd59cc2f67bf4cf573e579da186d39 (diff)
Input: atmel_mxt_ts - download device config using firmware loader
The existing implementation which encodes the configuration as a binary blob in platform data is unsatisfactory since it requires a kernel recompile for the configuration to be changed, and it doesn't deal well with firmware changes that move values around on the chip. Atmel define an ASCII format for the configuration which can be exported from their tools. This patch implements a parser for that format which loads the configuration via the firmware loader and sends it to the MXT chip. 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>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c278
1 files changed, 204 insertions, 74 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4317273c2138..c6b5e7dbd942 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2,6 +2,7 @@
2 * Atmel maXTouch Touchscreen driver 2 * Atmel maXTouch Touchscreen driver
3 * 3 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd 4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Copyright (C) 2011-2014 Atmel Corporation
5 * Copyright (C) 2012 Google, Inc. 6 * Copyright (C) 2012 Google, Inc.
6 * 7 *
7 * Author: Joonyoung Shim <jy0922.shim@samsung.com> 8 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
@@ -30,8 +31,10 @@
30#define MXT_VER_21 21 31#define MXT_VER_21 21
31#define MXT_VER_22 22 32#define MXT_VER_22 22
32 33
33/* Firmware */ 34/* Firmware files */
34#define MXT_FW_NAME "maxtouch.fw" 35#define MXT_FW_NAME "maxtouch.fw"
36#define MXT_CFG_NAME "maxtouch.cfg"
37#define MXT_CFG_MAGIC "OBP_RAW V1"
35 38
36/* Registers */ 39/* Registers */
37#define MXT_INFO 0x00 40#define MXT_INFO 0x00
@@ -298,37 +301,6 @@ static bool mxt_object_readable(unsigned int type)
298 } 301 }
299} 302}
300 303
301static bool mxt_object_writable(unsigned int type)
302{
303 switch (type) {
304 case MXT_GEN_COMMAND_T6:
305 case MXT_GEN_POWER_T7:
306 case MXT_GEN_ACQUIRE_T8:
307 case MXT_TOUCH_MULTI_T9:
308 case MXT_TOUCH_KEYARRAY_T15:
309 case MXT_TOUCH_PROXIMITY_T23:
310 case MXT_TOUCH_PROXKEY_T52:
311 case MXT_PROCI_GRIPFACE_T20:
312 case MXT_PROCG_NOISE_T22:
313 case MXT_PROCI_ONETOUCH_T24:
314 case MXT_PROCI_TWOTOUCH_T27:
315 case MXT_PROCI_GRIP_T40:
316 case MXT_PROCI_PALM_T41:
317 case MXT_PROCI_TOUCHSUPPRESSION_T42:
318 case MXT_PROCI_STYLUS_T47:
319 case MXT_PROCG_NOISESUPPRESSION_T48:
320 case MXT_SPT_COMMSCONFIG_T18:
321 case MXT_SPT_GPIOPWM_T19:
322 case MXT_SPT_SELFTEST_T25:
323 case MXT_SPT_CTECONFIG_T28:
324 case MXT_SPT_DIGITIZER_T43:
325 case MXT_SPT_CTECONFIG_T46:
326 return true;
327 default:
328 return false;
329 }
330}
331
332static void mxt_dump_message(struct device *dev, 304static void mxt_dump_message(struct device *dev,
333 struct mxt_message *message) 305 struct mxt_message *message)
334{ 306{
@@ -606,7 +578,7 @@ mxt_get_object(struct mxt_data *data, u8 type)
606 return object; 578 return object;
607 } 579 }
608 580
609 dev_err(&data->client->dev, "Invalid object type T%u\n", type); 581 dev_warn(&data->client->dev, "Invalid object type T%u\n", type);
610 return NULL; 582 return NULL;
611} 583}
612 584
@@ -877,58 +849,197 @@ static void mxt_update_crc(struct mxt_data *data, u8 cmd, u8 value)
877 mxt_wait_for_completion(data, &data->crc_completion, MXT_CRC_TIMEOUT); 849 mxt_wait_for_completion(data, &data->crc_completion, MXT_CRC_TIMEOUT);
878} 850}
879 851
880static int mxt_check_reg_init(struct mxt_data *data) 852/*
853 * mxt_update_cfg - download configuration to chip
854 *
855 * Atmel Raw Config File Format
856 *
857 * The first four lines of the raw config file contain:
858 * 1) Version
859 * 2) Chip ID Information (first 7 bytes of device memory)
860 * 3) Chip Information Block 24-bit CRC Checksum
861 * 4) Chip Configuration 24-bit CRC Checksum
862 *
863 * The rest of the file consists of one line per object instance:
864 * <TYPE> <INSTANCE> <SIZE> <CONTENTS>
865 *
866 * <TYPE> - 2-byte object type as hex
867 * <INSTANCE> - 2-byte object instance number as hex
868 * <SIZE> - 2-byte object size as hex
869 * <CONTENTS> - array of <SIZE> 1-byte hex values
870 */
871static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
881{ 872{
882 const struct mxt_platform_data *pdata = data->pdata;
883 struct mxt_object *object;
884 struct device *dev = &data->client->dev; 873 struct device *dev = &data->client->dev;
885 int index = 0; 874 struct mxt_info cfg_info;
886 int i, size; 875 struct mxt_object *object;
887 int ret; 876 int ret;
877 int offset;
878 int pos;
879 int i;
880 u32 info_crc, config_crc;
881 unsigned int type, instance, size;
882 u8 val;
883 u16 reg;
888 884
889 if (!pdata->config) { 885 mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
890 dev_dbg(dev, "No cfg data defined, skipping reg init\n"); 886
891 return 0; 887 if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
888 dev_err(dev, "Unrecognised config file\n");
889 ret = -EINVAL;
890 goto release;
892 } 891 }
893 892
894 mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); 893 pos = strlen(MXT_CFG_MAGIC);
894
895 /* Load information block and check */
896 for (i = 0; i < sizeof(struct mxt_info); i++) {
897 ret = sscanf(cfg->data + pos, "%hhx%n",
898 (unsigned char *)&cfg_info + i,
899 &offset);
900 if (ret != 1) {
901 dev_err(dev, "Bad format\n");
902 ret = -EINVAL;
903 goto release;
904 }
895 905
896 if (data->config_crc == pdata->config_crc) { 906 pos += offset;
897 dev_info(dev, "Config CRC 0x%06X: OK\n", data->config_crc); 907 }
898 return 0; 908
909 if (cfg_info.family_id != data->info.family_id) {
910 dev_err(dev, "Family ID mismatch!\n");
911 ret = -EINVAL;
912 goto release;
899 } 913 }
900 914
901 dev_info(dev, "Config CRC 0x%06X: does not match 0x%06X\n", 915 if (cfg_info.variant_id != data->info.variant_id) {
902 data->config_crc, pdata->config_crc); 916 dev_err(dev, "Variant ID mismatch!\n");
917 ret = -EINVAL;
918 goto release;
919 }
903 920
904 for (i = 0; i < data->info.object_num; i++) { 921 if (cfg_info.version != data->info.version)
905 object = data->object_table + i; 922 dev_err(dev, "Warning: version mismatch!\n");
906 923
907 if (!mxt_object_writable(object->type)) 924 if (cfg_info.build != data->info.build)
925 dev_err(dev, "Warning: build num mismatch!\n");
926
927 ret = sscanf(cfg->data + pos, "%x%n", &info_crc, &offset);
928 if (ret != 1) {
929 dev_err(dev, "Bad format: failed to parse Info CRC\n");
930 ret = -EINVAL;
931 goto release;
932 }
933 pos += offset;
934
935 /* Check config CRC */
936 ret = sscanf(cfg->data + pos, "%x%n", &config_crc, &offset);
937 if (ret != 1) {
938 dev_err(dev, "Bad format: failed to parse Config CRC\n");
939 ret = -EINVAL;
940 goto release;
941 }
942 pos += offset;
943
944 if (data->config_crc == config_crc) {
945 dev_dbg(dev, "Config CRC 0x%06X: OK\n", config_crc);
946 ret = 0;
947 goto release;
948 }
949
950 dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
951 data->config_crc, config_crc);
952
953 while (pos < cfg->size) {
954 /* Read type, instance, length */
955 ret = sscanf(cfg->data + pos, "%x %x %x%n",
956 &type, &instance, &size, &offset);
957 if (ret == 0) {
958 /* EOF */
959 ret = 1;
960 goto release;
961 } else if (ret != 3) {
962 dev_err(dev, "Bad format: failed to parse object\n");
963 ret = -EINVAL;
964 goto release;
965 }
966 pos += offset;
967
968 object = mxt_get_object(data, type);
969 if (!object) {
970 /* Skip object */
971 for (i = 0; i < size; i++) {
972 ret = sscanf(cfg->data + pos, "%hhx%n",
973 &val,
974 &offset);
975 pos += offset;
976 }
908 continue; 977 continue;
978 }
909 979
910 size = mxt_obj_size(object) * mxt_obj_instances(object); 980 if (size > mxt_obj_size(object)) {
911 if (index + size > pdata->config_length) { 981 dev_err(dev, "Discarding %zu byte(s) in T%u\n",
912 dev_err(dev, "Not enough config data!\n"); 982 size - mxt_obj_size(object), type);
913 return -EINVAL;
914 } 983 }
915 984
916 ret = __mxt_write_reg(data->client, object->start_address, 985 if (instance >= mxt_obj_instances(object)) {
917 size, &pdata->config[index]); 986 dev_err(dev, "Object instances exceeded!\n");
918 if (ret) 987 ret = -EINVAL;
919 return ret; 988 goto release;
920 index += size; 989 }
990
991 reg = object->start_address + mxt_obj_size(object) * instance;
992
993 for (i = 0; i < size; i++) {
994 ret = sscanf(cfg->data + pos, "%hhx%n",
995 &val,
996 &offset);
997 if (ret != 1) {
998 dev_err(dev, "Bad format in T%d\n", type);
999 ret = -EINVAL;
1000 goto release;
1001 }
1002 pos += offset;
1003
1004 if (i > mxt_obj_size(object))
1005 continue;
1006
1007 ret = mxt_write_reg(data->client, reg + i, val);
1008 if (ret)
1009 goto release;
1010
1011 }
1012
1013 /*
1014 * If firmware is upgraded, new bytes may be added to end of
1015 * objects. It is generally forward compatible to zero these
1016 * bytes - previous behaviour will be retained. However
1017 * this does invalidate the CRC and will force a config
1018 * download every time until the configuration is updated.
1019 */
1020 if (size < mxt_obj_size(object)) {
1021 dev_info(dev, "Zeroing %zu byte(s) in T%d\n",
1022 mxt_obj_size(object) - size, type);
1023
1024 for (i = size + 1; i < mxt_obj_size(object); i++) {
1025 ret = mxt_write_reg(data->client, reg + i, 0);
1026 if (ret)
1027 goto release;
1028 }
1029 }
921 } 1030 }
922 1031
923 mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); 1032 mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
924 1033
925 ret = mxt_soft_reset(data); 1034 ret = mxt_soft_reset(data);
926 if (ret) 1035 if (ret)
927 return ret; 1036 goto release;
928 1037
929 dev_info(dev, "Config successfully updated\n"); 1038 dev_info(dev, "Config successfully updated\n");
930 1039
931 return 0; 1040release:
1041 release_firmware(cfg);
1042 return ret;
932} 1043}
933 1044
934static int mxt_make_highchg(struct mxt_data *data) 1045static int mxt_make_highchg(struct mxt_data *data)
@@ -1204,10 +1315,17 @@ err_free_mem:
1204 return error; 1315 return error;
1205} 1316}
1206 1317
1318static int mxt_configure_objects(struct mxt_data *data,
1319 const struct firmware *cfg);
1320
1321static void mxt_config_cb(const struct firmware *cfg, void *ctx)
1322{
1323 mxt_configure_objects(ctx, cfg);
1324}
1325
1207static int mxt_initialize(struct mxt_data *data) 1326static int mxt_initialize(struct mxt_data *data)
1208{ 1327{
1209 struct i2c_client *client = data->client; 1328 struct i2c_client *client = data->client;
1210 struct mxt_info *info = &data->info;
1211 int error; 1329 int error;
1212 1330
1213 error = mxt_get_info(data); 1331 error = mxt_get_info(data);
@@ -1225,28 +1343,40 @@ static int mxt_initialize(struct mxt_data *data)
1225 if (error) 1343 if (error)
1226 goto err_free_object_table; 1344 goto err_free_object_table;
1227 1345
1228 /* Check register init values */ 1346 request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
1229 error = mxt_check_reg_init(data); 1347 &data->client->dev, GFP_KERNEL, data,
1230 if (error) { 1348 mxt_config_cb);
1231 dev_err(&client->dev, "Error %d initializing configuration\n", 1349
1232 error); 1350 return 0;
1233 goto err_free_object_table; 1351
1352err_free_object_table:
1353 mxt_free_object_table(data);
1354 return error;
1355}
1356
1357static int mxt_configure_objects(struct mxt_data *data,
1358 const struct firmware *cfg)
1359{
1360 struct device *dev = &data->client->dev;
1361 struct mxt_info *info = &data->info;
1362 int error;
1363
1364 if (cfg) {
1365 error = mxt_update_cfg(data, cfg);
1366 if (error)
1367 dev_warn(dev, "Error %d updating config\n", error);
1234 } 1368 }
1235 1369
1236 error = mxt_initialize_t9_input_device(data); 1370 error = mxt_initialize_t9_input_device(data);
1237 if (error) 1371 if (error)
1238 goto err_free_object_table; 1372 return error;
1239 1373
1240 dev_info(&client->dev, 1374 dev_info(dev,
1241 "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", 1375 "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
1242 info->family_id, info->variant_id, info->version >> 4, 1376 info->family_id, info->variant_id, info->version >> 4,
1243 info->version & 0xf, info->build, info->object_num); 1377 info->version & 0xf, info->build, info->object_num);
1244 1378
1245 return 0; 1379 return 0;
1246
1247err_free_object_table:
1248 mxt_free_object_table(data);
1249 return error;
1250} 1380}
1251 1381
1252/* Firmware Version is returned as Major.Minor.Build */ 1382/* Firmware Version is returned as Major.Minor.Build */