ftsFlash.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * FTS Capacitive touch screen controller (FingerTipS)
  4. *
  5. * Copyright (C) 2016-2019, STMicroelectronics Limited.
  6. * Authors: AMG(Analog Mems Group) <[email protected]>
  7. *
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License version 2 as published by
  11. * the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful, but WITHOUT
  14. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  16. * more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along with
  19. * this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. *
  23. **************************************************************************
  24. ** STMicroelectronics **
  25. **************************************************************************
  26. ** [email protected] **
  27. **************************************************************************
  28. * *
  29. * FTS API for Flashing the IC *
  30. * *
  31. **************************************************************************
  32. **************************************************************************
  33. *
  34. */
  35. #include <linux/init.h>
  36. #include <linux/errno.h>
  37. #include <linux/platform_device.h>
  38. #include <linux/kernel.h>
  39. #include <linux/module.h>
  40. #include <linux/slab.h>
  41. #include <linux/string.h>
  42. #include <stdarg.h>
  43. #include <linux/input.h>
  44. #include <linux/interrupt.h>
  45. #include <linux/serio.h>
  46. #include <linux/time.h>
  47. #include <linux/pm.h>
  48. #include <linux/delay.h>
  49. #include <linux/ctype.h>
  50. #include <linux/gpio.h>
  51. #include <linux/i2c.h>
  52. #include <linux/i2c-dev.h>
  53. #include <linux/fs.h>
  54. #include <linux/uaccess.h>
  55. #include <linux/power_supply.h>
  56. #include <linux/firmware.h>
  57. #include <linux/regulator/consumer.h>
  58. #include <linux/of_gpio.h>
  59. #include "ftsCrossCompile.h"
  60. #include "ftsCompensation.h"
  61. #include "ftsError.h"
  62. #include "ftsFlash.h"
  63. #include "ftsFrame.h"
  64. #include "ftsIO.h"
  65. #include "ftsSoftware.h"
  66. #include "ftsTest.h"
  67. #include "ftsTime.h"
  68. #include "ftsTool.h"
  69. #include "../fts.h"//needed for including the define FW_H_FILE
  70. #ifdef FW_H_FILE
  71. #include <../fts_fw.h>
  72. #define LOAD_FW_FROM 1
  73. #else
  74. #define LOAD_FW_FROM 0
  75. #endif
  76. #define FTS_LATEST_VERSION 0x1101
  77. static char tag[8] = "[ FTS ]\0";
  78. int getFirmwareVersion(u16 *fw_vers, u16 *config_id)
  79. {
  80. u8 fwvers[DCHIP_FW_VER_BYTE];
  81. u8 confid[CONFIG_ID_BYTE];
  82. int res;
  83. res = readCmdU16(FTS_CMD_HW_REG_R, DCHIP_FW_VER_ADDR,
  84. fwvers, DCHIP_FW_VER_BYTE, DUMMY_HW_REG);
  85. if (res < OK) {
  86. logError(1,
  87. "%s %s:unable to read fw_version ERROR %02X\n",
  88. tag, __func__, ERROR_FW_VER_READ);
  89. return (res | ERROR_FW_VER_READ);
  90. }
  91. u8ToU16(fwvers, fw_vers); //fw version use big endian
  92. if (*fw_vers != 0) {
  93. // if fw_version is 00 00 means that there is
  94. //no firmware running in the chip therefore will be
  95. //impossible find the config_id
  96. res = readB2(CONFIG_ID_ADDR, confid, CONFIG_ID_BYTE);
  97. if (res < OK) {
  98. logError(1, "%s %s:unable to read config_id ",
  99. tag, __func__);
  100. logError(1, "ERROR %02X\n", ERROR_FW_VER_READ);
  101. return (res | ERROR_FW_VER_READ);
  102. }
  103. u8ToU16(confid, config_id); //config id use little endian
  104. } else {
  105. *config_id = 0x0000;
  106. }
  107. logError(0, "%s FW VERS = %04X\n", tag, *fw_vers);
  108. logError(0, "%s CONFIG ID = %04X\n", tag, *config_id);
  109. return OK;
  110. }
  111. int getFWdata_nocheck(const char *pathToFile, u8 **data, int *size, int from)
  112. {
  113. const struct firmware *fw = NULL;
  114. struct device *dev = getDev();
  115. int res;
  116. if (dev == NULL)
  117. return ERROR_OP_NOT_ALLOW;
  118. logError(0, "%s Read FW from BIN file!\n", tag);
  119. res = firmware_request_nowarn(&fw, pathToFile, dev);
  120. if (res) {
  121. logError(1, "%s %s:No File found! ERROR %08X\n",
  122. tag, __func__, ERROR_FILE_NOT_FOUND);
  123. return ERROR_FILE_NOT_FOUND;
  124. }
  125. *size = fw->size;
  126. *data = (u8 *)kmalloc_array((*size), sizeof(u8), GFP_KERNEL);
  127. if (*data == NULL) {
  128. logError(1, "%s %s:Impossible to allocate! %08X\n", __func__);
  129. release_firmware(fw);
  130. return ERROR_ALLOC;
  131. }
  132. memcpy(*data, (u8 *)fw->data, (*size));
  133. release_firmware(fw);
  134. logError(0, "%s %s:Finshed!\n", tag, __func__);
  135. return OK;
  136. }
  137. int getFWdata(const char *pathToFile, u8 **data, int *size, int from)
  138. {
  139. const struct firmware *fw = NULL;
  140. struct device *dev = NULL;
  141. int res;
  142. logError(0, "%s %s starting...\n", tag, __func__);
  143. switch (from) {
  144. #ifdef FW_H_FILE
  145. case 1:
  146. logError(1, "%s Read FW from .h file!\n", tag);
  147. *size = FW_SIZE_NAME;
  148. *data = (u8 *)kmalloc_array((*size), sizeof(u8), GFP_KERNEL);
  149. if (*data == NULL) {
  150. logError(1, "%s %s:Impossible to allocate memory! ",
  151. tag, __func__);
  152. logError(1, "ERROR %08X\n", ERROR_ALLOC);
  153. return ERROR_ALLOC;
  154. }
  155. memcpy(*data, (u8 *)FW_ARRAY_NAME, (*size));
  156. break;
  157. #endif
  158. default:
  159. logError(0, "%s Read FW from BIN file!\n", tag);
  160. if (ftsInfo.u16_fwVer >= FTS_LATEST_VERSION)
  161. return ERROR_FW_NO_UPDATE;
  162. dev = getDev();
  163. if (dev != NULL) {
  164. res = firmware_request_nowarn(&fw, pathToFile, dev);
  165. if (res == 0) {
  166. *size = fw->size;
  167. *data = (u8 *)kmalloc_array((*size), sizeof(u8),
  168. GFP_KERNEL);
  169. if (*data == NULL) {
  170. logError(1, "%s %s:Impossible to ",
  171. tag, __func__);
  172. logError(1, "%allocate! %08X\n",
  173. ERROR_ALLOC);
  174. release_firmware(fw);
  175. return ERROR_ALLOC;
  176. }
  177. memcpy(*data, (u8 *)fw->data, (*size));
  178. release_firmware(fw);
  179. } else {
  180. logError(0, "%s %s:No File found! ERROR %08X\n",
  181. tag, __func__, ERROR_FILE_NOT_FOUND);
  182. return ERROR_FILE_NOT_FOUND;
  183. }
  184. } else {
  185. logError(1, "%s %s:No device found! ERROR %08X\n",
  186. tag, __func__, ERROR_OP_NOT_ALLOW);
  187. return ERROR_OP_NOT_ALLOW;
  188. }
  189. /* break; */
  190. }
  191. logError(0, "%s %s:Finshed!\n", tag, __func__);
  192. return OK;
  193. }
  194. int readFwFile(const char *path, struct Firmware *fw, int keep_cx)
  195. {
  196. int res;
  197. int orig_size;
  198. u8 *orig_data = NULL;
  199. res = getFWdata(path, &orig_data, &orig_size, LOAD_FW_FROM);
  200. if (res < OK) {
  201. logError(0, "%s %s:impossible retrieve FW... ERROR %08X\n",
  202. tag, __func__, ERROR_MEMH_READ);
  203. return (res | ERROR_MEMH_READ);
  204. }
  205. res = parseBinFile(orig_data, orig_size, fw, keep_cx);
  206. if (res < OK) {
  207. logError(1, "%s %s:impossible parse ERROR %08X\n",
  208. tag, __func__, ERROR_MEMH_READ);
  209. return (res | ERROR_MEMH_READ);
  210. }
  211. return OK;
  212. }
  213. int flashProcedure(const char *path, int force, int keep_cx)
  214. {
  215. struct Firmware fw;
  216. int res;
  217. fw.data = NULL;
  218. logError(0, "%s Reading Fw file...\n", tag);
  219. res = readFwFile(path, &fw, keep_cx);
  220. if (res < OK) {
  221. logError(0, "%s %s: ERROR %02X\n",
  222. tag, __func__, (res | ERROR_FLASH_PROCEDURE));
  223. kfree(fw.data);
  224. return (res | ERROR_FLASH_PROCEDURE);
  225. }
  226. logError(0, "%s Fw file read COMPLETED!\n", tag);
  227. logError(0, "%s Starting flashing procedure...\n", tag);
  228. res = flash_burn(&fw, force, keep_cx);
  229. if (res < OK && res != (ERROR_FW_NO_UPDATE | ERROR_FLASH_BURN_FAILED)) {
  230. logError(1, "%s %s: ERROR %02X\n",
  231. tag, __func__, ERROR_FLASH_PROCEDURE);
  232. kfree(fw.data);
  233. return (res | ERROR_FLASH_PROCEDURE);
  234. }
  235. logError(0, "%s flashing procedure Finished!\n", tag);
  236. kfree(fw.data);
  237. return res;
  238. }
  239. #ifdef FTM3_CHIP
  240. int flash_status(void)
  241. {
  242. u8 cmd[2] = {FLASH_CMD_READSTATUS, 0x00};
  243. u8 readData = 0;
  244. logError(0, "%s %s:Reading ...\n", tag, __func__);
  245. if (fts_readCmd(cmd, 2, &readData, FLASH_STATUS_BYTES) < 0) {
  246. logError(1, "%s %s: ERROR % 02X\n", tag, __func__, ERROR_I2C_R);
  247. return ERROR_I2C_R;
  248. }
  249. readData &= 0x01;
  250. logError(0, "%s %s = %d\n", tag, __func__, readData);
  251. return (int) readData;
  252. }
  253. int flash_status_ready(void)
  254. {
  255. int status = flash_status();
  256. if (status == ERROR_I2C_R) {
  257. logError(1, "%s %s: ERROR % 02X\n", tag, __func__, ERROR_I2C_R);
  258. return ERROR_I2C_R;
  259. }
  260. if (status != FLASH_READY) {
  261. //logError(1,
  262. //"%s %s:flash busy or unknown STATUS = % 02X\n",
  263. //tag, status);
  264. return ERROR_FLASH_UNKNOWN;
  265. }
  266. return FLASH_READY;
  267. }
  268. int wait_for_flash_ready(void)
  269. {
  270. int status;
  271. int (*code)(void);
  272. code = flash_status_ready;
  273. logError(0, "%s Waiting for flash ready...\n", tag);
  274. status = attempt_function(code, FLASH_WAIT_BEFORE_RETRY,
  275. FLASH_RETRY_COUNT);
  276. if (status != FLASH_READY) {
  277. logError(1, "%s %s: ERROR % 02X\n",
  278. tag, __func__, ERROR_FLASH_NOT_READY);
  279. return (status | ERROR_FLASH_NOT_READY);
  280. }
  281. logError(0, "%s Flash ready!\n", tag);
  282. return OK;
  283. }
  284. int flash_unlock(void)
  285. {
  286. int status;
  287. //write the command to perform the unlock
  288. u8 cmd[3] = {FLASH_CMD_UNLOCK, FLASH_UNLOCK_CODE0,
  289. FLASH_UNLOCK_CODE1};
  290. logError(0, "%s Try to unlock flash...\n", tag);
  291. status = wait_for_flash_ready();
  292. if (status != OK) {
  293. logError(1, "%s %s: ERROR % 02X\n",
  294. tag, __func__, ERROR_FLASH_NOT_READY);
  295. //Flash not ready within the chosen time, better exit!
  296. return (status | ERROR_FLASH_NOT_READY);
  297. }
  298. logError(0, "%s Command unlock ...\n", tag);
  299. if (fts_writeCmd(cmd, sizeof(cmd)) < 0) {
  300. logError(1, "%s %s: ERROR % 02X\n",
  301. tag, __func__, ERROR_I2C_W);
  302. return ERROR_I2C_W;
  303. }
  304. status = wait_for_flash_ready();
  305. if (status != OK) {
  306. logError(1, "%s %s: ERROR % 02X\n",
  307. tag, __func__, ERROR_FLASH_NOT_READY);
  308. //Flash not ready within the chosen time,
  309. //better exit!
  310. return (status | ERROR_FLASH_NOT_READY);
  311. }
  312. logError(0, "%s Unlock flash DONE!\n", tag);
  313. return OK;
  314. }
  315. int parseBinFile(u8 *fw_data, int fw_size, Firmware *fwData, int keep_cx)
  316. {
  317. int dimension;
  318. if (keep_cx) {
  319. dimension = FW_SIZE - FW_CX_SIZE;
  320. logError(1, "%s %s: Selected 124k Configuration!\n",
  321. tag, __func__);
  322. } else {
  323. dimension = FW_SIZE;
  324. logError(1, "%s %s: Selected 128k Configuration!\n",
  325. tag, __func__);
  326. }
  327. if (fw_size - FW_HEADER_SIZE != FW_SIZE || fw_data == NULL) {
  328. logError(1, "%s %s:Read only %d instead of %d... ERROR %02X\n",
  329. tag, __func__,
  330. fw_size - FW_HEADER_SIZE,
  331. FW_SIZE, ERROR_FILE_PARSE);
  332. kfree(fw_data);
  333. return ERROR_FILE_PARSE;
  334. }
  335. fwData->data = (u8 *)kmalloc_array(dimension, sizeof(u8), GFP_KERNEL);
  336. if (fwData->data == NULL) {
  337. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_ALLOC);
  338. kfree(fw_data);
  339. return ERROR_ALLOC;
  340. }
  341. memcpy(fwData->data, ((u8 *)(fw_data) + FW_HEADER_SIZE),
  342. dimension);
  343. fwData->data_size = dimension;
  344. fwData->fw_ver = (u16)(((fwData->data[FW_VER_MEMH_BYTE1] & 0x00FF) << 8)
  345. + (fwData->data[FW_VER_MEMH_BYTE0] & 0x00FF));
  346. fwData->config_id = (u16)(((fwData->data[(FW_CODE_SIZE)
  347. + FW_OFF_CONFID_MEMH_BYTE1] & 0x00FF) << 8)
  348. + (fwData->data[(FW_CODE_SIZE) +
  349. FW_OFF_CONFID_MEMH_BYTE0] & 0x00FF));
  350. logError(0, "%s %s: FW VERS File = %04X\n",
  351. tag, __func__, fwData->fw_ver);
  352. logError(0, "%s %s: CONFIG ID File = %04X\n",
  353. tag, __func__, fwData->config_id);
  354. logError(0, "%s READ FW DONE %d bytes!\n", tag, fwData->data_size);
  355. kfree(fw_data);
  356. return OK;
  357. }
  358. int fillMemory(u32 address, u8 *data, int size)
  359. {
  360. int remaining = size;
  361. int toWrite = 0;
  362. int delta;
  363. u8 *buff = (u8 *)kmalloc_array((MEMORY_CHUNK + 3), sizeof(u8),
  364. GFP_KERNEL);
  365. if (buff == NULL) {
  366. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_ALLOC);
  367. return ERROR_ALLOC;
  368. }
  369. while (remaining > 0) {
  370. if (remaining >= MEMORY_CHUNK) {
  371. if ((address + MEMORY_CHUNK) < FLASH_ADDR_SWITCH_CMD) {
  372. buff[0] = FLASH_CMD_WRITE_LOWER_64;
  373. toWrite = MEMORY_CHUNK;
  374. remaining -= MEMORY_CHUNK;
  375. } else {
  376. if (address < FLASH_ADDR_SWITCH_CMD) {
  377. delta = FLASH_ADDR_SWITCH_CMD - address;
  378. buff[0] = FLASH_CMD_WRITE_LOWER_64;
  379. toWrite = delta;
  380. remaining -= delta;
  381. } else {
  382. buff[0] = FLASH_CMD_WRITE_UPPER_64;
  383. toWrite = MEMORY_CHUNK;
  384. remaining -= MEMORY_CHUNK;
  385. }
  386. }
  387. } else {
  388. if ((address + remaining) < FLASH_ADDR_SWITCH_CMD) {
  389. buff[0] = FLASH_CMD_WRITE_LOWER_64;
  390. toWrite = remaining;
  391. remaining = 0;
  392. } else {
  393. if (address < FLASH_ADDR_SWITCH_CMD) {
  394. delta = FLASH_ADDR_SWITCH_CMD - address;
  395. buff[0] = FLASH_CMD_WRITE_LOWER_64;
  396. toWrite = delta;
  397. remaining -= delta;
  398. } else {
  399. buff[0] = FLASH_CMD_WRITE_UPPER_64;
  400. toWrite = remaining;
  401. remaining = 0;
  402. }
  403. }
  404. }
  405. buff[1] = (u8) ((address & 0x0000FF00) >> 8);
  406. buff[2] = (u8) (address & 0x000000FF);
  407. memcpy(buff + 3, data, toWrite);
  408. //logError(0,
  409. //"%s Command = %02X , address = %02X %02X, bytes = %d\n",
  410. //tag, buff[0], buff[1], buff[2], toWrite);
  411. if (fts_writeCmd(buff, 3 + toWrite) < 0) {
  412. logError(1, "%s %s: ERROR %02X\n",
  413. tag, __func__, ERROR_I2C_W);
  414. kfree(buff);
  415. return ERROR_I2C_W;
  416. }
  417. address += toWrite;
  418. data += toWrite;
  419. }
  420. kfree(buff);
  421. return OK;
  422. }
  423. int flash_burn(Firmware *fw, int force_burn, int keep_cx)
  424. {
  425. u8 cmd;
  426. int res;
  427. if (!force_burn && (ftsInfo.u16_fwVer >= fw->fw_ver)
  428. && (ftsInfo.u16_cfgId >= fw->config_id)) {
  429. logError(0, "Firmware in the chip newer");
  430. logError(0, " or equal to the one to burn! ");
  431. logError(0, "%s %s:NO UPDATE ERROR %02X\n",
  432. tag, __func__, ERROR_FW_NO_UPDATE);
  433. return (ERROR_FW_NO_UPDATE | ERROR_FLASH_BURN_FAILED);
  434. }
  435. //programming procedure start
  436. logError(0, "%s Programming Procedure for flashing started:\n", tag);
  437. logError(0, "%s 1) SYSTEM RESET:\n", tag);
  438. res = fts_system_reset();
  439. if (res < 0) {
  440. logError(1, "%s system reset FAILED!\n", tag);
  441. //if there is no firmware i will not
  442. //get the controller ready event and
  443. //there will be a timeout but i can
  444. //keep going, but if there is
  445. //an I2C error i have to exit
  446. if (res != (ERROR_SYSTEM_RESET_FAIL | ERROR_TIMEOUT))
  447. return (res | ERROR_FLASH_BURN_FAILED);
  448. } else
  449. logError(0, "%s system reset COMPLETED!\n\n", tag);
  450. logError(0, "%s 2) FLASH UNLOCK:\n", tag);
  451. res = flash_unlock();
  452. if (res < 0) {
  453. logError(1, "%s flash unlock FAILED! ERROR %02X\n",
  454. tag, ERROR_FLASH_BURN_FAILED);
  455. return (res | ERROR_FLASH_BURN_FAILED);
  456. }
  457. logError(0, "%s flash unlock COMPLETED!\n\n", tag);
  458. //Write the lower part of the Program RAM
  459. logError(0, "%s 3) PREPARING DATA FOR FLASH BURN:\n", tag);
  460. res = fillMemory(FLASH_ADDR_CODE, fw->data, fw->data_size);
  461. if (res < 0) {
  462. logError(1, "%s Error During filling the memory!%02X\n",
  463. tag, ERROR_FLASH_BURN_FAILED);
  464. return (res | ERROR_FLASH_BURN_FAILED);
  465. }
  466. logError(0, "%s Data copy COMPLETED!\n\n", tag);
  467. logError(0, "%s 4) ERASE FLASH:\n", tag);
  468. res = wait_for_flash_ready();
  469. if (res < 0) {
  470. logError(1, "%s Flash not ready! ERROR %02X\n",
  471. tag, ERROR_FLASH_BURN_FAILED);
  472. return (res | ERROR_FLASH_BURN_FAILED);
  473. }
  474. logError(0, "%s Command erase ...\n", tag);
  475. cmd = FLASH_CMD_ERASE;
  476. if (fts_writeCmd(&cmd, 1) < 0) {
  477. logError(1, "%s Error during erasing flash! ERROR %02X\n",
  478. tag, ERROR_FLASH_BURN_FAILED);
  479. return (ERROR_I2C_W | ERROR_FLASH_BURN_FAILED);
  480. }
  481. res = wait_for_flash_ready();
  482. if (res < 0) {
  483. logError(1, "%s Flash not ready 2! ERROR %02X\n",
  484. tag, ERROR_FLASH_BURN_FAILED);
  485. return (res | ERROR_FLASH_BURN_FAILED);
  486. }
  487. logError(0, "%s Flash erase COMPLETED!\n\n", tag);
  488. logError(0, "%s 5) BURN FLASH:\n", tag);
  489. logError(0, "%s Command burn ...\n", tag);
  490. cmd = FLASH_CMD_BURN;
  491. if (fts_writeCmd(&cmd, 1) < 0) {
  492. logError(1, "%s Error during burning data! ERROR %02X\n",
  493. tag, ERROR_FLASH_BURN_FAILED);
  494. return (ERROR_I2C_W | ERROR_FLASH_BURN_FAILED);
  495. }
  496. res = wait_for_flash_ready();
  497. if (res < 0) {
  498. logError(1, "%s Flash not ready! ERROR %02X\n",
  499. tag, ERROR_FLASH_BURN_FAILED);
  500. return (res | ERROR_FLASH_BURN_FAILED);
  501. }
  502. logError(0, "%s Flash burn COMPLETED!\n\n", tag);
  503. logError(0, "%s 6) SYSTEM RESET:\n", tag);
  504. res = fts_system_reset();
  505. if (res < 0) {
  506. logError(1, "%s system reset FAILED! ERROR %02X\n",
  507. tag, ERROR_FLASH_BURN_FAILED);
  508. return (res | ERROR_FLASH_BURN_FAILED);
  509. }
  510. logError(0, "%s system reset COMPLETED!\n\n", tag);
  511. logError(0, "%s 7) FINAL CHECK:\n", tag);
  512. res = readChipInfo(0);
  513. if (res < 0) {
  514. logError(1, "%s %s:Unable to retrieve Chip INFO!%02X\n",
  515. tag, ERROR_FLASH_BURN_FAILED);
  516. return (res | ERROR_FLASH_BURN_FAILED);
  517. }
  518. if ((ftsInfo.u16_fwVer != fw->fw_ver)
  519. && (ftsInfo.u16_cfgId != fw->config_id)) {
  520. logError(1, "Firmware in the chip different");
  521. logError(1, " from the one that was burn!");
  522. logError(1, "%s fw: %x != %x , conf: %x != %x\n",
  523. tag, ftsInfo.u16_fwVer,
  524. fw->fw_ver,
  525. ftsInfo.u16_cfgId,
  526. fw->config_id);
  527. return ERROR_FLASH_BURN_FAILED;
  528. }
  529. logError(0, "%s Final check OK! fw: %02X, conf: %02X\n",
  530. tag, ftsInfo.u16_fwVer, ftsInfo.u16_cfgId);
  531. return OK;
  532. }
  533. #else
  534. int wait_for_flash_ready(u8 type)
  535. {
  536. u8 cmd[2] = {FLASH_CMD_READ_REGISTER, type};
  537. u8 readData = 0;
  538. int i, res = -1;
  539. logError(0, "%s Waiting for flash ready ...\n", tag);
  540. for (i = 0; i < FLASH_RETRY_COUNT && res != 0; i++) {
  541. if (fts_readCmd(cmd, sizeof(cmd), &readData, 1) < 0) {
  542. logError(1, "%s %s: ERROR % 02X\n",
  543. tag, __func__, ERROR_I2C_R);
  544. } else {
  545. res = readData & 0x80;
  546. //logError(0, "%s flash status = %d\n", tag, res);
  547. }
  548. msleep(FLASH_WAIT_BEFORE_RETRY);
  549. }
  550. if (i == FLASH_RETRY_COUNT && res != 0) {
  551. logError(1, "%s Wait for flash TIMEOUT! ERROR %02X\n",
  552. tag, ERROR_TIMEOUT);
  553. return ERROR_TIMEOUT;
  554. }
  555. logError(0, "%s Flash READY!\n", tag);
  556. return OK;
  557. }
  558. int fts_warm_boot(void)
  559. {
  560. //write the command to perform the warm boot
  561. u8 cmd[4] = {FTS_CMD_HW_REG_W, 0x00, 0x00, WARM_BOOT_VALUE};
  562. u16ToU8_be(ADDR_WARM_BOOT, &cmd[1]);
  563. logError(0, "%s Command warm boot ...\n", tag);
  564. if (fts_writeCmd(cmd, sizeof(cmd)) < 0) {
  565. logError(1, "%s flash_unlock: ERROR % 02X\n", tag, ERROR_I2C_W);
  566. return ERROR_I2C_W;
  567. }
  568. logError(0, "%s Warm boot DONE!\n", tag);
  569. return OK;
  570. }
  571. int parseBinFile(u8 *data, int fw_size,
  572. struct Firmware *fwData, int keep_cx)
  573. {
  574. int dimension, index = 0;
  575. u32 temp;
  576. int res, i;
  577. //the file should contain at least the header plus the content_crc
  578. if (fw_size < FW_HEADER_SIZE+FW_BYTES_ALIGN || data == NULL) {
  579. logError(1, "%s %s:Read only %d instead of %d...ERROR %02X\n",
  580. tag, __func__, fw_size,
  581. FW_HEADER_SIZE + FW_BYTES_ALIGN,
  582. ERROR_FILE_PARSE);
  583. res = ERROR_FILE_PARSE;
  584. goto END;
  585. } else {
  586. //start parsing of bytes
  587. u8ToU32(&data[index], &temp);
  588. if (temp != FW_HEADER_SIGNATURE) {
  589. logError(1, "%s %s:Wrong Signature %08X...ERROR %02X\n",
  590. tag, __func__, temp, ERROR_FILE_PARSE);
  591. res = ERROR_FILE_PARSE;
  592. goto END;
  593. }
  594. logError(0, "%s %s: Fw Signature OK!\n", tag, __func__);
  595. index += FW_BYTES_ALIGN;
  596. u8ToU32(&data[index], &temp);
  597. if (temp != FW_FTB_VER) {
  598. logError(1, "%s %s:Wrong ftb_version %08X.ERROR %02X\n",
  599. tag, __func__, temp, ERROR_FILE_PARSE);
  600. res = ERROR_FILE_PARSE;
  601. goto END;
  602. }
  603. logError(0, "%s %s:ftb_version OK!\n", __func__, tag);
  604. index += FW_BYTES_ALIGN;
  605. if (data[index] != DCHIP_ID_0 || data[index+1] != DCHIP_ID_1) {
  606. logError(1, "%s %s:Wrong target %02X != %02X ",
  607. tag, __func__, data[index]);
  608. logError(1, "%%02X != %02X:%08X\n",
  609. DCHIP_ID_0, data[index+1],
  610. DCHIP_ID_1, ERROR_FILE_PARSE);
  611. res = ERROR_FILE_PARSE;
  612. goto END;
  613. }
  614. index += FW_BYTES_ALIGN;
  615. u8ToU32(&data[index], &temp);
  616. logError(0, "%s %s: Fw ID = %08X\n", tag, __func__, temp);
  617. index += FW_BYTES_ALIGN;
  618. u8ToU32(&data[index], &temp);
  619. fwData->fw_ver = temp;
  620. logError(0, "%s %s:FILE Fw Version = %04X\n",
  621. tag, __func__, fwData->fw_ver);
  622. index += FW_BYTES_ALIGN;
  623. u8ToU32(&data[index], &temp);
  624. fwData->config_id = temp;
  625. logError(0, "%s %s:FILE Config ID = %04X\n",
  626. tag, __func__, fwData->config_id);
  627. index += FW_BYTES_ALIGN;
  628. u8ToU32(&data[index], &temp);
  629. logError(0, "%s %s:Config Version = %08X\n",
  630. tag, __func__, temp);
  631. //skip reserved data
  632. index += FW_BYTES_ALIGN * 2;
  633. index += FW_BYTES_ALIGN;
  634. logError(0, "%s %s:File External Release = ",
  635. tag, __func__);
  636. for (i = 0; i < EXTERNAL_RELEASE_INFO_SIZE; i++) {
  637. fwData->externalRelease[i] = data[index++];
  638. logError(0, "%02X", fwData->externalRelease[i]);
  639. }
  640. logError(0, "\n");
  641. //index += FW_BYTES_ALIGN;
  642. u8ToU32(&data[index], &temp);
  643. fwData->sec0_size = temp;
  644. logError(0, "%s %s:sec0_size = %08X (%d bytes)\n",
  645. tag, __func__, fwData->sec0_size, fwData->sec0_size);
  646. index += FW_BYTES_ALIGN;
  647. u8ToU32(&data[index], &temp);
  648. fwData->sec1_size = temp;
  649. logError(0, "%s %s:sec1_size = %08X (%d bytes)\n",
  650. tag, __func__, fwData->sec1_size, fwData->sec1_size);
  651. index += FW_BYTES_ALIGN;
  652. u8ToU32(&data[index], &temp);
  653. fwData->sec2_size = temp;
  654. logError(0, "%s %s:sec2_size = %08X (%d bytes)\n",
  655. tag, __func__, fwData->sec2_size, fwData->sec2_size);
  656. index += FW_BYTES_ALIGN;
  657. u8ToU32(&data[index], &temp);
  658. fwData->sec3_size = temp;
  659. logError(0, "%s %s:sec3_size = %08X (%d bytes)\n",
  660. tag, __func__, fwData->sec3_size, fwData->sec3_size);
  661. //skip header crc
  662. index += FW_BYTES_ALIGN;
  663. if (!keep_cx) {
  664. dimension = fwData->sec0_size + fwData->sec1_size
  665. + fwData->sec2_size + fwData->sec3_size;
  666. temp = fw_size;
  667. } else {
  668. //sec2 may contain cx data (future implementation)
  669. //sec3 atm not used
  670. dimension = fwData->sec0_size + fwData->sec1_size;
  671. temp = fw_size - fwData->sec2_size - fwData->sec3_size;
  672. fwData->sec2_size = 0;
  673. fwData->sec3_size = 0;
  674. }
  675. if (dimension + FW_HEADER_SIZE + FW_BYTES_ALIGN != temp) {
  676. logError(1, "%s %s:Read only %d instead of %d...",
  677. tag, __func__, fw_size,
  678. dimension + FW_HEADER_SIZE + FW_BYTES_ALIGN);
  679. logError(1, "ERROR %02X\n", ERROR_FILE_PARSE);
  680. res = ERROR_FILE_PARSE;
  681. goto END;
  682. }
  683. fwData->data = (u8 *)kmalloc_array(dimension, sizeof(u8),
  684. GFP_KERNEL);
  685. if (fwData->data == NULL) {
  686. logError(1, "%s %s: ERROR %02X\n",
  687. tag, __func__, ERROR_ALLOC);
  688. res = ERROR_ALLOC;
  689. goto END;
  690. }
  691. index += FW_BYTES_ALIGN;
  692. memcpy(fwData->data, &data[index], dimension);
  693. fwData->data_size = dimension;
  694. logError(0, "%s READ FW DONE %d bytes!\n",
  695. tag, fwData->data_size);
  696. res = OK;
  697. goto END;
  698. }
  699. END:
  700. kfree(data);
  701. return res;
  702. }
  703. int flash_unlock(void)
  704. {
  705. //write the command to perform the unlock
  706. u8 cmd[3] = {FLASH_CMD_UNLOCK,
  707. FLASH_UNLOCK_CODE0, FLASH_UNLOCK_CODE1};
  708. logError(0, "%s Command unlock ...\n", tag);
  709. if (fts_writeCmd(cmd, sizeof(cmd)) < 0) {
  710. logError(1, "%s %s: ERROR % 02X\n", tag, __func__, ERROR_I2C_W);
  711. return ERROR_I2C_W;
  712. }
  713. //mdelay(FLASH_WAIT_TIME);
  714. logError(0, "%s Unlock flash DONE!\n", tag);
  715. return OK;
  716. }
  717. int flash_erase_unlock(void)
  718. {
  719. //write the command to perform
  720. //the unlock for erasing the flash
  721. u8 cmd[3] = {FLASH_CMD_WRITE_REGISTER, FLASH_ERASE_UNLOCK_CODE0,
  722. FLASH_ERASE_UNLOCK_CODE1};
  723. logError(0, "%s Try to erase unlock flash...\n", tag);
  724. logError(0, "%s Command erase unlock ...\n", tag);
  725. if (fts_writeCmd(cmd, sizeof(cmd)) < 0) {
  726. logError(1, "%s %s:ERROR % 02X\n", tag, __func__, ERROR_I2C_W);
  727. return ERROR_I2C_W;
  728. }
  729. logError(0, "%s Erase Unlock flash DONE!\n", tag);
  730. return OK;
  731. }
  732. int flash_full_erase(void)
  733. {
  734. int status;
  735. //write the command to erase the flash
  736. u8 cmd[3] = {FLASH_CMD_WRITE_REGISTER, FLASH_ERASE_CODE0,
  737. FLASH_ERASE_CODE1};
  738. logError(0, "%s Command full erase sent...\n",
  739. tag);
  740. if (fts_writeCmd(cmd, sizeof(cmd)) < 0) {
  741. logError(1, "%s %s:ERROR % 02X\n", tag, __func__, ERROR_I2C_W);
  742. return ERROR_I2C_W;
  743. }
  744. status = wait_for_flash_ready(FLASH_ERASE_CODE0);
  745. if (status != OK) {
  746. logError(1, "%s %s:ERROR % 02X\n",
  747. tag, __func__, ERROR_FLASH_NOT_READY);
  748. //Flash not ready within the chosen time,
  749. //better exit!
  750. return (status | ERROR_FLASH_NOT_READY);
  751. }
  752. logError(0, "%s Full Erase flash DONE!\n", tag);
  753. return OK;
  754. }
  755. int flash_erase_page_by_page(int keep_cx)
  756. {
  757. u8 status, i = 0;
  758. //write the command to erase the flash
  759. u8 cmd[4] = {FLASH_CMD_WRITE_REGISTER, FLASH_ERASE_CODE0, 0x00, 0x00};
  760. for (i = 0; i < FLASH_NUM_PAGE; i++) {
  761. if (i >= FLASH_CX_PAGE_START && i <= FLASH_CX_PAGE_END
  762. && keep_cx == 1) {
  763. logError(0, "%s Skipping erase page %d!\n", tag, i);
  764. continue;
  765. }
  766. cmd[2] = (0x3F & i) | FLASH_ERASE_START;
  767. logError(0, "Command erase page %d sent", i);
  768. logError(0, "%s:%02X %02X %02X %02X\n",
  769. tag, i, cmd[0], cmd[1], cmd[2], cmd[3]);
  770. if (fts_writeCmd(cmd, sizeof(cmd)) < 0) {
  771. logError(1,
  772. "%s %s:ERROR % 08X\n",
  773. tag, __func__, ERROR_I2C_W);
  774. return ERROR_I2C_W;
  775. }
  776. status = wait_for_flash_ready(FLASH_ERASE_CODE0);
  777. if (status != OK) {
  778. logError(1, "%s %s:ERROR % 08X\n",
  779. tag, __func__, ERROR_FLASH_NOT_READY);
  780. //Flash not ready within the chosen time,
  781. //better exit!
  782. return (status | ERROR_FLASH_NOT_READY);
  783. }
  784. }
  785. logError(0, "%s Erase flash page by page DONE!\n", tag);
  786. return OK;
  787. }
  788. int start_flash_dma(void)
  789. {
  790. int status;
  791. //write the command to erase the flash
  792. u8 cmd[3] = {FLASH_CMD_WRITE_REGISTER, FLASH_DMA_CODE0,
  793. FLASH_DMA_CODE1};
  794. logError(0, "%s Command flash DMA ...\n", tag);
  795. if (fts_writeCmd(cmd, sizeof(cmd)) < 0) {
  796. logError(1, "%s %s: ERROR % 02X\n",
  797. tag, __func__, ERROR_I2C_W);
  798. return ERROR_I2C_W;
  799. }
  800. status = wait_for_flash_ready(FLASH_DMA_CODE0);
  801. if (status != OK) {
  802. logError(1, "%s %s: ERROR % 02X\n",
  803. tag, __func__, ERROR_FLASH_NOT_READY);
  804. //Flash not ready within the chosen time, better exit!
  805. return (status | ERROR_FLASH_NOT_READY);
  806. }
  807. logError(0, "%s flash DMA DONE!\n", tag);
  808. return OK;
  809. }
  810. int fillFlash(u32 address, u8 *data, int size)
  811. {
  812. int remaining = size;
  813. int toWrite = 0;
  814. int byteBlock = 0;
  815. int wheel = 0;
  816. u32 addr = 0;
  817. int res;
  818. int delta;
  819. u8 *buff = NULL;
  820. u8 buff2[9] = {0};
  821. buff = (u8 *)kmalloc_array((DMA_CHUNK + 3), sizeof(u8), GFP_KERNEL);
  822. if (buff == NULL) {
  823. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_ALLOC);
  824. return ERROR_ALLOC;
  825. }
  826. while (remaining > 0) {
  827. byteBlock = 0;
  828. addr = 0;
  829. while (byteBlock < FLASH_CHUNK && remaining > 0) {
  830. buff[0] = FLASH_CMD_WRITE_64K;
  831. if (remaining >= DMA_CHUNK) {
  832. if ((byteBlock + DMA_CHUNK) <= FLASH_CHUNK) {
  833. //logError(1, "%s fillFlash:1\n", tag);
  834. toWrite = DMA_CHUNK;
  835. remaining -= DMA_CHUNK;
  836. byteBlock += DMA_CHUNK;
  837. } else {
  838. //logError(1, "%s fillFlash:2\n", tag);
  839. delta = FLASH_CHUNK - byteBlock;
  840. toWrite = delta;
  841. remaining -= delta;
  842. byteBlock += delta;
  843. }
  844. } else {
  845. if ((byteBlock + remaining) <= FLASH_CHUNK) {
  846. //logError(1, "%s fillFlash:3\n", tag);
  847. toWrite = remaining;
  848. byteBlock += remaining;
  849. remaining = 0;
  850. } else {
  851. //logError(1, "%s fillFlash:4\n", tag);
  852. delta = FLASH_CHUNK - byteBlock;
  853. toWrite = delta;
  854. remaining -= delta;
  855. byteBlock += delta;
  856. }
  857. }
  858. buff[1] = (u8) ((addr & 0x0000FF00) >> 8);
  859. buff[2] = (u8) (addr & 0x000000FF);
  860. memcpy(&buff[3], data, toWrite);
  861. //logError(0,
  862. //"%s Command = %02X, address = %02X %02X,
  863. //bytes = %d, data = %02X %02X, %02X %02X\n",
  864. //tag, buff[0], buff[1], buff[2], toWrite,
  865. //buff[3], buff[4], buff[3 + toWrite-2],
  866. //buff[3 + toWrite-1]);
  867. if (fts_writeCmd(buff, 3 + toWrite) < 0) {
  868. logError(1, "%s %s: ERROR %02X\n",
  869. tag, __func__, ERROR_I2C_W);
  870. kfree(buff);
  871. return ERROR_I2C_W;
  872. }
  873. addr += toWrite;
  874. data += toWrite;
  875. }
  876. //configuring the DMA
  877. byteBlock = byteBlock / 4 - 1;
  878. buff2[0] = FLASH_CMD_WRITE_REGISTER;
  879. buff2[1] = FLASH_DMA_CONFIG;
  880. buff2[2] = 0x00;
  881. buff2[3] = 0x00;
  882. addr = address + ((wheel * FLASH_CHUNK)/4);
  883. buff2[4] = (u8) ((addr & 0x000000FF));
  884. buff2[5] = (u8) ((addr & 0x0000FF00) >> 8);
  885. buff2[6] = (u8) (byteBlock & 0x000000FF);
  886. buff2[7] = (u8) ((byteBlock & 0x0000FF00) >> 8);
  887. buff2[8] = 0x00;
  888. logError(0, "%s:Command:%02X, address:%02X %02X, ",
  889. tag, buff2[0], buff2[5], buff2[4]);
  890. logError(0, "words:%02X %02X\n", buff2[7], buff2[6]);
  891. if (fts_writeCmd(buff2, 9) < OK) {
  892. logError(1, "%s Error during filling Flash!:%02X\n",
  893. tag, ERROR_I2C_W);
  894. kfree(buff);
  895. return ERROR_I2C_W;
  896. }
  897. //mdelay(FLASH_WAIT_TIME);
  898. res = start_flash_dma();
  899. if (res < OK) {
  900. logError(1, "%s Error during flashing DMA!:%02X\n",
  901. tag, res);
  902. kfree(buff);
  903. return res;
  904. }
  905. wheel++;
  906. }
  907. kfree(buff);
  908. return OK;
  909. }
  910. int flash_burn(struct Firmware *fw, int force_burn, int keep_cx)
  911. {
  912. int res;
  913. if (!force_burn && (ftsInfo.u16_fwVer >= fw->fw_ver)
  914. && (ftsInfo.u16_cfgId >= fw->config_id)) {
  915. for (res = EXTERNAL_RELEASE_INFO_SIZE-1; res >= 0; res--) {
  916. if (fw->externalRelease[res] >
  917. ftsInfo.u8_extReleaseInfo[res])
  918. goto start;
  919. }
  920. logError(0, "Firmware in the chip newer or ");
  921. logError(0, "equal to the one to burn!");
  922. logError(0, "%s %s:NO UPDATE ERROR %02X\n",
  923. tag, __func__, ERROR_FW_NO_UPDATE);
  924. return (ERROR_FW_NO_UPDATE | ERROR_FLASH_BURN_FAILED);
  925. }
  926. //programming procedure start
  927. start:
  928. logError(0, "%s Programming Procedure for flashing started:\n\n", tag);
  929. logError(0, "%s 1) SYSTEM RESET:\n", tag);
  930. logError(0, "%s 2) WARM BOOT:\n", tag);
  931. res = fts_warm_boot();
  932. if (res < OK) {
  933. logError(1, "%s warm boot FAILED!\n", tag);
  934. return (res | ERROR_FLASH_BURN_FAILED);
  935. }
  936. logError(0, "%s warm boot COMPLETED!\n\n", tag);
  937. //mdelay(FLASH_WAIT_TIME);
  938. logError(0, "%s 3) FLASH UNLOCK:\n", tag);
  939. res = flash_unlock();
  940. if (res < OK) {
  941. logError(1, "%s flash unlock FAILED! ERROR %02X\n",
  942. tag, ERROR_FLASH_BURN_FAILED);
  943. return (res | ERROR_FLASH_BURN_FAILED);
  944. }
  945. logError(0, "%s flash unlock COMPLETED!\n\n", tag);
  946. //mdelay(200);
  947. logError(0, "%s 4) FLASH ERASE UNLOCK:\n", tag);
  948. res = flash_erase_unlock();
  949. if (res < 0) {
  950. logError(1, "%s flash unlock FAILED! ERROR %02X\n",
  951. tag, ERROR_FLASH_BURN_FAILED);
  952. return (res | ERROR_FLASH_BURN_FAILED);
  953. }
  954. logError(0, "%s flash unlock COMPLETED!\n\n", tag);
  955. //mdelay(FLASH_WAIT_TIME);
  956. logError(0, "%s 5) FLASH ERASE:\n", tag);
  957. if (keep_cx == 1)
  958. res = flash_erase_page_by_page(keep_cx);
  959. else
  960. res = flash_full_erase();
  961. if (res < 0) {
  962. logError(1, "%s flash erase FAILED! ERROR %02X\n",
  963. tag, ERROR_FLASH_BURN_FAILED);
  964. return (res | ERROR_FLASH_BURN_FAILED);
  965. }
  966. logError(0, "%s flash erase COMPLETED!\n\n", tag);
  967. //mdelay(FLASH_WAIT_TIME);
  968. logError(0, "%s 6) LOAD PROGRAM:\n", tag);
  969. res = fillFlash(FLASH_ADDR_CODE, (u8 *)(&fw->data[0]),
  970. fw->sec0_size);
  971. if (res < OK) {
  972. logError(1, "%s load program ERROR %02X\n",
  973. tag, ERROR_FLASH_BURN_FAILED);
  974. return (res | ERROR_FLASH_BURN_FAILED);
  975. }
  976. logError(0, "%s load program DONE!\n", tag);
  977. logError(0, "%s 7) LOAD CONFIG:\n", tag);
  978. res = fillFlash(FLASH_ADDR_CONFIG,
  979. &(fw->data[fw->sec0_size]), fw->sec1_size);
  980. if (res < OK) {
  981. logError(1, "%s load config ERROR %02X\n",
  982. tag, ERROR_FLASH_BURN_FAILED);
  983. return (res | ERROR_FLASH_BURN_FAILED);
  984. }
  985. logError(0, "%s load config DONE!\n", tag);
  986. logError(0, "%s Flash burn COMPLETED!\n\n", tag);
  987. logError(0, "%s 8) SYSTEM RESET:\n", tag);
  988. res = fts_system_reset();
  989. if (res < 0) {
  990. logError(1, "%s system reset FAILED! ERROR %02X\n",
  991. tag, ERROR_FLASH_BURN_FAILED);
  992. return (res | ERROR_FLASH_BURN_FAILED);
  993. }
  994. logError(0, "%s system reset COMPLETED!\n\n", tag);
  995. logError(0, "%s 9) FINAL CHECK:\n", tag);
  996. res = readChipInfo(0);
  997. if (res < 0) {
  998. logError(1, "%s %s:Unable to retrieve Chip INFO!:%02X\n",
  999. tag, __func__, ERROR_FLASH_BURN_FAILED);
  1000. return (res | ERROR_FLASH_BURN_FAILED);
  1001. }
  1002. if ((ftsInfo.u16_fwVer != fw->fw_ver)
  1003. && (ftsInfo.u16_cfgId != fw->config_id)) {
  1004. pr_err("Firmware is different from the old!\n");
  1005. logError(1, "%s fw: %x != %x, conf: %x != %x\n",
  1006. tag, ftsInfo.u16_fwVer, fw->fw_ver,
  1007. ftsInfo.u16_cfgId, fw->config_id);
  1008. return ERROR_FLASH_BURN_FAILED;
  1009. }
  1010. logError(0, "%s Final check OK! fw: %02X , conf: %02X\n",
  1011. tag, ftsInfo.u16_fwVer, ftsInfo.u16_cfgId);
  1012. return OK;
  1013. }
  1014. #endif