Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+170 -150
+170 -150
drivers/input/touchscreen/atmel_mxt_ts.c
··· 1064 1064 return crc; 1065 1065 } 1066 1066 1067 - /* 1068 - * mxt_update_cfg - download configuration to chip 1069 - * 1070 - * Atmel Raw Config File Format 1071 - * 1072 - * The first four lines of the raw config file contain: 1073 - * 1) Version 1074 - * 2) Chip ID Information (first 7 bytes of device memory) 1075 - * 3) Chip Information Block 24-bit CRC Checksum 1076 - * 4) Chip Configuration 24-bit CRC Checksum 1077 - * 1078 - * The rest of the file consists of one line per object instance: 1079 - * <TYPE> <INSTANCE> <SIZE> <CONTENTS> 1080 - * 1081 - * <TYPE> - 2-byte object type as hex 1082 - * <INSTANCE> - 2-byte object instance number as hex 1083 - * <SIZE> - 2-byte object size as hex 1084 - * <CONTENTS> - array of <SIZE> 1-byte hex values 1085 - */ 1086 - static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) 1067 + static 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) 1087 1073 { 1088 1074 struct device *dev = &data->client->dev; 1089 - struct mxt_info cfg_info; 1090 1075 struct mxt_object *object; 1091 - int ret; 1076 + unsigned int type, instance, size, byte_offset; 1092 1077 int offset; 1093 - int data_pos; 1094 - int byte_offset; 1078 + int ret; 1095 1079 int i; 1096 - int cfg_start_ofs; 1097 - u32 info_crc, config_crc, calculated_crc; 1098 - u8 *config_mem; 1099 - size_t config_mem_size; 1100 - unsigned int type, instance, size; 1101 - u8 val; 1102 1080 u16 reg; 1103 - 1104 - mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); 1105 - 1106 - if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) { 1107 - dev_err(dev, "Unrecognised config file\n"); 1108 - ret = -EINVAL; 1109 - goto release; 1110 - } 1111 - 1112 - data_pos = strlen(MXT_CFG_MAGIC); 1113 - 1114 - /* Load information block and check */ 1115 - for (i = 0; i < sizeof(struct mxt_info); i++) { 1116 - ret = sscanf(cfg->data + data_pos, "%hhx%n", 1117 - (unsigned char *)&cfg_info + i, 1118 - &offset); 1119 - if (ret != 1) { 1120 - dev_err(dev, "Bad format\n"); 1121 - ret = -EINVAL; 1122 - goto release; 1123 - } 1124 - 1125 - data_pos += offset; 1126 - } 1127 - 1128 - if (cfg_info.family_id != data->info.family_id) { 1129 - dev_err(dev, "Family ID mismatch!\n"); 1130 - ret = -EINVAL; 1131 - goto release; 1132 - } 1133 - 1134 - if (cfg_info.variant_id != data->info.variant_id) { 1135 - dev_err(dev, "Variant ID mismatch!\n"); 1136 - ret = -EINVAL; 1137 - goto release; 1138 - } 1139 - 1140 - /* Read CRCs */ 1141 - ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset); 1142 - if (ret != 1) { 1143 - dev_err(dev, "Bad format: failed to parse Info CRC\n"); 1144 - ret = -EINVAL; 1145 - goto release; 1146 - } 1147 - data_pos += offset; 1148 - 1149 - ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset); 1150 - if (ret != 1) { 1151 - dev_err(dev, "Bad format: failed to parse Config CRC\n"); 1152 - ret = -EINVAL; 1153 - goto release; 1154 - } 1155 - data_pos += offset; 1156 - 1157 - /* 1158 - * The Info Block CRC is calculated over mxt_info and the object 1159 - * table. If it does not match then we are trying to load the 1160 - * configuration from a different chip or firmware version, so 1161 - * the configuration CRC is invalid anyway. 1162 - */ 1163 - if (info_crc == data->info_crc) { 1164 - if (config_crc == 0 || data->config_crc == 0) { 1165 - dev_info(dev, "CRC zero, attempting to apply config\n"); 1166 - } else if (config_crc == data->config_crc) { 1167 - dev_dbg(dev, "Config CRC 0x%06X: OK\n", 1168 - data->config_crc); 1169 - ret = 0; 1170 - goto release; 1171 - } else { 1172 - dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n", 1173 - data->config_crc, config_crc); 1174 - } 1175 - } else { 1176 - dev_warn(dev, 1177 - "Warning: Info CRC error - device=0x%06X file=0x%06X\n", 1178 - data->info_crc, info_crc); 1179 - } 1180 - 1181 - /* Malloc memory to store configuration */ 1182 - cfg_start_ofs = MXT_OBJECT_START + 1183 - data->info.object_num * sizeof(struct mxt_object) + 1184 - MXT_INFO_CHECKSUM_SIZE; 1185 - config_mem_size = data->mem_size - cfg_start_ofs; 1186 - config_mem = kzalloc(config_mem_size, GFP_KERNEL); 1187 - if (!config_mem) { 1188 - dev_err(dev, "Failed to allocate memory\n"); 1189 - ret = -ENOMEM; 1190 - goto release; 1191 - } 1081 + u8 val; 1192 1082 1193 1083 while (data_pos < cfg->size) { 1194 1084 /* Read type, instance, length */ ··· 1089 1199 break; 1090 1200 } else if (ret != 3) { 1091 1201 dev_err(dev, "Bad format: failed to parse object\n"); 1092 - ret = -EINVAL; 1093 - goto release_mem; 1202 + return -EINVAL; 1094 1203 } 1095 1204 data_pos += offset; 1096 1205 ··· 1129 1240 1130 1241 if (instance >= mxt_obj_instances(object)) { 1131 1242 dev_err(dev, "Object instances exceeded!\n"); 1132 - ret = -EINVAL; 1133 - goto release_mem; 1243 + return -EINVAL; 1134 1244 } 1135 1245 1136 1246 reg = object->start_address + mxt_obj_size(object) * instance; ··· 1140 1252 &offset); 1141 1253 if (ret != 1) { 1142 1254 dev_err(dev, "Bad format in T%d\n", type); 1143 - ret = -EINVAL; 1144 - goto release_mem; 1255 + return -EINVAL; 1145 1256 } 1146 1257 data_pos += offset; 1147 1258 ··· 1149 1262 1150 1263 byte_offset = reg + i - cfg_start_ofs; 1151 1264 1152 - if ((byte_offset >= 0) 1153 - && (byte_offset <= config_mem_size)) { 1265 + if (byte_offset >= 0 && 1266 + byte_offset <= config_mem_size) { 1154 1267 *(config_mem + byte_offset) = val; 1155 1268 } else { 1156 1269 dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n", 1157 1270 reg, object->type, byte_offset); 1158 - ret = -EINVAL; 1159 - goto release_mem; 1271 + return -EINVAL; 1160 1272 } 1161 1273 } 1162 1274 } 1275 + 1276 + return 0; 1277 + } 1278 + 1279 + static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start, 1280 + u8 *config_mem, size_t config_mem_size) 1281 + { 1282 + unsigned int byte_offset = 0; 1283 + int error; 1284 + 1285 + /* Write configuration as blocks */ 1286 + while (byte_offset < config_mem_size) { 1287 + unsigned int size = config_mem_size - byte_offset; 1288 + 1289 + if (size > MXT_MAX_BLOCK_WRITE) 1290 + size = MXT_MAX_BLOCK_WRITE; 1291 + 1292 + error = __mxt_write_reg(data->client, 1293 + cfg_start + byte_offset, 1294 + size, config_mem + byte_offset); 1295 + if (error) { 1296 + dev_err(&data->client->dev, 1297 + "Config write error, ret=%d\n", error); 1298 + return error; 1299 + } 1300 + 1301 + byte_offset += size; 1302 + } 1303 + 1304 + return 0; 1305 + } 1306 + 1307 + /* 1308 + * mxt_update_cfg - download configuration to chip 1309 + * 1310 + * Atmel Raw Config File Format 1311 + * 1312 + * The first four lines of the raw config file contain: 1313 + * 1) Version 1314 + * 2) Chip ID Information (first 7 bytes of device memory) 1315 + * 3) Chip Information Block 24-bit CRC Checksum 1316 + * 4) Chip Configuration 24-bit CRC Checksum 1317 + * 1318 + * The rest of the file consists of one line per object instance: 1319 + * <TYPE> <INSTANCE> <SIZE> <CONTENTS> 1320 + * 1321 + * <TYPE> - 2-byte object type as hex 1322 + * <INSTANCE> - 2-byte object instance number as hex 1323 + * <SIZE> - 2-byte object size as hex 1324 + * <CONTENTS> - array of <SIZE> 1-byte hex values 1325 + */ 1326 + static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) 1327 + { 1328 + struct device *dev = &data->client->dev; 1329 + struct mxt_info cfg_info; 1330 + int ret; 1331 + int offset; 1332 + int data_pos; 1333 + int i; 1334 + int cfg_start_ofs; 1335 + u32 info_crc, config_crc, calculated_crc; 1336 + u8 *config_mem; 1337 + size_t config_mem_size; 1338 + 1339 + mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); 1340 + 1341 + if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) { 1342 + dev_err(dev, "Unrecognised config file\n"); 1343 + return -EINVAL; 1344 + } 1345 + 1346 + data_pos = strlen(MXT_CFG_MAGIC); 1347 + 1348 + /* Load information block and check */ 1349 + for (i = 0; i < sizeof(struct mxt_info); i++) { 1350 + ret = sscanf(cfg->data + data_pos, "%hhx%n", 1351 + (unsigned char *)&cfg_info + i, 1352 + &offset); 1353 + if (ret != 1) { 1354 + dev_err(dev, "Bad format\n"); 1355 + return -EINVAL; 1356 + } 1357 + 1358 + data_pos += offset; 1359 + } 1360 + 1361 + if (cfg_info.family_id != data->info.family_id) { 1362 + dev_err(dev, "Family ID mismatch!\n"); 1363 + return -EINVAL; 1364 + } 1365 + 1366 + if (cfg_info.variant_id != data->info.variant_id) { 1367 + dev_err(dev, "Variant ID mismatch!\n"); 1368 + return -EINVAL; 1369 + } 1370 + 1371 + /* Read CRCs */ 1372 + ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset); 1373 + if (ret != 1) { 1374 + dev_err(dev, "Bad format: failed to parse Info CRC\n"); 1375 + return -EINVAL; 1376 + } 1377 + data_pos += offset; 1378 + 1379 + ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset); 1380 + if (ret != 1) { 1381 + dev_err(dev, "Bad format: failed to parse Config CRC\n"); 1382 + return -EINVAL; 1383 + } 1384 + data_pos += offset; 1385 + 1386 + /* 1387 + * The Info Block CRC is calculated over mxt_info and the object 1388 + * table. If it does not match then we are trying to load the 1389 + * configuration from a different chip or firmware version, so 1390 + * the configuration CRC is invalid anyway. 1391 + */ 1392 + if (info_crc == data->info_crc) { 1393 + if (config_crc == 0 || data->config_crc == 0) { 1394 + dev_info(dev, "CRC zero, attempting to apply config\n"); 1395 + } else if (config_crc == data->config_crc) { 1396 + dev_dbg(dev, "Config CRC 0x%06X: OK\n", 1397 + data->config_crc); 1398 + return 0; 1399 + } else { 1400 + dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n", 1401 + data->config_crc, config_crc); 1402 + } 1403 + } else { 1404 + dev_warn(dev, 1405 + "Warning: Info CRC error - device=0x%06X file=0x%06X\n", 1406 + data->info_crc, info_crc); 1407 + } 1408 + 1409 + /* Malloc memory to store configuration */ 1410 + cfg_start_ofs = MXT_OBJECT_START + 1411 + data->info.object_num * sizeof(struct mxt_object) + 1412 + MXT_INFO_CHECKSUM_SIZE; 1413 + config_mem_size = data->mem_size - cfg_start_ofs; 1414 + config_mem = kzalloc(config_mem_size, GFP_KERNEL); 1415 + if (!config_mem) { 1416 + dev_err(dev, "Failed to allocate memory\n"); 1417 + return -ENOMEM; 1418 + } 1419 + 1420 + ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs, 1421 + config_mem, config_mem_size); 1422 + if (ret) 1423 + goto release_mem; 1163 1424 1164 1425 /* Calculate crc of the received configs (not the raw config file) */ 1165 1426 if (data->T7_address < cfg_start_ofs) { ··· 1321 1286 data->T7_address - cfg_start_ofs, 1322 1287 config_mem_size); 1323 1288 1324 - if (config_crc > 0 && (config_crc != calculated_crc)) 1289 + if (config_crc > 0 && config_crc != calculated_crc) 1325 1290 dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n", 1326 1291 calculated_crc, config_crc); 1327 1292 1328 - /* Write configuration as blocks */ 1329 - byte_offset = 0; 1330 - while (byte_offset < config_mem_size) { 1331 - size = config_mem_size - byte_offset; 1332 - 1333 - if (size > MXT_MAX_BLOCK_WRITE) 1334 - size = MXT_MAX_BLOCK_WRITE; 1335 - 1336 - ret = __mxt_write_reg(data->client, 1337 - cfg_start_ofs + byte_offset, 1338 - size, config_mem + byte_offset); 1339 - if (ret != 0) { 1340 - dev_err(dev, "Config write error, ret=%d\n", ret); 1341 - goto release_mem; 1342 - } 1343 - 1344 - byte_offset += size; 1345 - } 1293 + ret = mxt_upload_cfg_mem(data, cfg_start_ofs, 1294 + config_mem, config_mem_size); 1295 + if (ret) 1296 + goto release_mem; 1346 1297 1347 1298 mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); 1348 1299 ··· 1340 1319 1341 1320 release_mem: 1342 1321 kfree(config_mem); 1343 - release: 1344 - release_firmware(cfg); 1345 1322 return ret; 1346 1323 } 1347 1324 ··· 1659 1640 static void mxt_config_cb(const struct firmware *cfg, void *ctx) 1660 1641 { 1661 1642 mxt_configure_objects(ctx, cfg); 1643 + release_firmware(cfg); 1662 1644 } 1663 1645 1664 1646 static int mxt_initialize(struct mxt_data *data)