aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-08-08 12:29:06 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-08-13 12:16:11 -0400
commitefdbd7ae44f35cbb2b29d825640b917723319f7b (patch)
tree049280c9ff4809027e20988913b2c240d069b047 /drivers/input/touchscreen
parent6cd1ab0fb67f21e6e35eee35106d8dd2f08b544c (diff)
Input: atmel_mxt_ts - split config update a bit
Let's split config update code a bit so it is hopefully a bit easier to read. Also, the firmware update callback should be the entity releasing firmware blob, not lower layers. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c270
1 files changed, 145 insertions, 125 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index a5f943dedb20..bbaf3ff680ed 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1064,6 +1064,133 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, off_t end_off)
1064 return crc; 1064 return crc;
1065} 1065}
1066 1066
1067static int mxt_prepare_cfg_mem(struct mxt_data *data,
1068 const struct firmware *cfg,
1069 unsigned int data_pos,
1070 unsigned int cfg_start_ofs,
1071 u8 *config_mem,
1072 size_t config_mem_size)
1073{
1074 struct device *dev = &data->client->dev;
1075 struct mxt_object *object;
1076 unsigned int type, instance, size, byte_offset;
1077 int offset;
1078 int ret;
1079 int i;
1080 u16 reg;
1081 u8 val;
1082
1083 while (data_pos < cfg->size) {
1084 /* Read type, instance, length */
1085 ret = sscanf(cfg->data + data_pos, "%x %x %x%n",
1086 &type, &instance, &size, &offset);
1087 if (ret == 0) {
1088 /* EOF */
1089 break;
1090 } else if (ret != 3) {
1091 dev_err(dev, "Bad format: failed to parse object\n");
1092 return -EINVAL;
1093 }
1094 data_pos += offset;
1095
1096 object = mxt_get_object(data, type);
1097 if (!object) {
1098 /* Skip object */
1099 for (i = 0; i < size; i++) {
1100 ret = sscanf(cfg->data + data_pos, "%hhx%n",
1101 &val,
1102 &offset);
1103 data_pos += offset;
1104 }
1105 continue;
1106 }
1107
1108 if (size > mxt_obj_size(object)) {
1109 /*
1110 * Either we are in fallback mode due to wrong
1111 * config or config from a later fw version,
1112 * or the file is corrupt or hand-edited.
1113 */
1114 dev_warn(dev, "Discarding %zu byte(s) in T%u\n",
1115 size - mxt_obj_size(object), type);
1116 } else if (mxt_obj_size(object) > size) {
1117 /*
1118 * If firmware is upgraded, new bytes may be added to
1119 * end of objects. It is generally forward compatible
1120 * to zero these bytes - previous behaviour will be
1121 * retained. However this does invalidate the CRC and
1122 * will force fallback mode until the configuration is
1123 * updated. We warn here but do nothing else - the
1124 * malloc has zeroed the entire configuration.
1125 */
1126 dev_warn(dev, "Zeroing %zu byte(s) in T%d\n",
1127 mxt_obj_size(object) - size, type);
1128 }
1129
1130 if (instance >= mxt_obj_instances(object)) {
1131 dev_err(dev, "Object instances exceeded!\n");
1132 return -EINVAL;
1133 }
1134
1135 reg = object->start_address + mxt_obj_size(object) * instance;
1136
1137 for (i = 0; i < size; i++) {
1138 ret = sscanf(cfg->data + data_pos, "%hhx%n",
1139 &val,
1140 &offset);
1141 if (ret != 1) {
1142 dev_err(dev, "Bad format in T%d\n", type);
1143 return -EINVAL;
1144 }
1145 data_pos += offset;
1146
1147 if (i > mxt_obj_size(object))
1148 continue;
1149
1150 byte_offset = reg + i - cfg_start_ofs;
1151
1152 if (byte_offset >= 0 &&
1153 byte_offset <= config_mem_size) {
1154 *(config_mem + byte_offset) = val;
1155 } else {
1156 dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n",
1157 reg, object->type, byte_offset);
1158 return -EINVAL;
1159 }
1160 }
1161 }
1162
1163 return 0;
1164}
1165
1166static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start,
1167 u8 *config_mem, size_t config_mem_size)
1168{
1169 unsigned int byte_offset = 0;
1170 int error;
1171
1172 /* Write configuration as blocks */
1173 while (byte_offset < config_mem_size) {
1174 unsigned int size = config_mem_size - byte_offset;
1175
1176 if (size > MXT_MAX_BLOCK_WRITE)
1177 size = MXT_MAX_BLOCK_WRITE;
1178
1179 error = __mxt_write_reg(data->client,
1180 cfg_start + byte_offset,
1181 size, config_mem + byte_offset);
1182 if (error) {
1183 dev_err(&data->client->dev,
1184 "Config write error, ret=%d\n", error);
1185 return error;
1186 }
1187
1188 byte_offset += size;
1189 }
1190
1191 return 0;
1192}
1193
1067/* 1194/*
1068 * mxt_update_cfg - download configuration to chip 1195 * mxt_update_cfg - download configuration to chip
1069 * 1196 *
@@ -1087,26 +1214,20 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
1087{ 1214{
1088 struct device *dev = &data->client->dev; 1215 struct device *dev = &data->client->dev;
1089 struct mxt_info cfg_info; 1216 struct mxt_info cfg_info;
1090 struct mxt_object *object;
1091 int ret; 1217 int ret;
1092 int offset; 1218 int offset;
1093 int data_pos; 1219 int data_pos;
1094 int byte_offset;
1095 int i; 1220 int i;
1096 int cfg_start_ofs; 1221 int cfg_start_ofs;
1097 u32 info_crc, config_crc, calculated_crc; 1222 u32 info_crc, config_crc, calculated_crc;
1098 u8 *config_mem; 1223 u8 *config_mem;
1099 size_t config_mem_size; 1224 size_t config_mem_size;
1100 unsigned int type, instance, size;
1101 u8 val;
1102 u16 reg;
1103 1225
1104 mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); 1226 mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
1105 1227
1106 if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) { 1228 if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
1107 dev_err(dev, "Unrecognised config file\n"); 1229 dev_err(dev, "Unrecognised config file\n");
1108 ret = -EINVAL; 1230 return -EINVAL;
1109 goto release;
1110 } 1231 }
1111 1232
1112 data_pos = strlen(MXT_CFG_MAGIC); 1233 data_pos = strlen(MXT_CFG_MAGIC);
@@ -1118,8 +1239,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
1118 &offset); 1239 &offset);
1119 if (ret != 1) { 1240 if (ret != 1) {
1120 dev_err(dev, "Bad format\n");