nt36xxx_fw_update.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2010 - 2018 Novatek, Inc.
  4. *
  5. * $Revision: 47247 $
  6. * $Date: 2019-07-10 10:41:36 +0800 (Wed, 10 Jul 2019) $
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  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. */
  19. #if !defined(NVT_NT36XXX_SPI) /* NT36XXX I2C */
  20. #include <linux/firmware.h>
  21. #include "nt36xxx.h"
  22. #if BOOT_UPDATE_FIRMWARE
  23. #define SIZE_4KB 4096
  24. #define FLASH_SECTOR_SIZE SIZE_4KB
  25. #define SIZE_64KB 65536
  26. #define BLOCK_64KB_NUM 4
  27. #define FW_BIN_VER_OFFSET (fw_need_write_size - SIZE_4KB)
  28. #define FW_BIN_VER_BAR_OFFSET (FW_BIN_VER_OFFSET + 1)
  29. #define NVT_FLASH_END_FLAG_LEN 3
  30. #define NVT_FLASH_END_FLAG_ADDR (fw_need_write_size - NVT_FLASH_END_FLAG_LEN)
  31. const struct firmware *fw_entry = NULL;
  32. static size_t fw_need_write_size = 0;
  33. static int32_t nvt_get_fw_need_write_size(const struct firmware *fw_entry)
  34. {
  35. int32_t i = 0;
  36. int32_t total_sectors_to_check = 0;
  37. total_sectors_to_check = fw_entry->size / FLASH_SECTOR_SIZE;
  38. /* printk("total_sectors_to_check = %d\n", total_sectors_to_check); */
  39. for (i = total_sectors_to_check; i > 0; i--) {
  40. /* printk("current end flag address checked = 0x%X\n", i * FLASH_SECTOR_SIZE - NVT_FLASH_END_FLAG_LEN); */
  41. /* check if there is end flag "NVT" at the end of this sector */
  42. if ((memcmp((const char *)&fw_entry->data[i * FLASH_SECTOR_SIZE -
  43. NVT_FLASH_END_FLAG_LEN], "NVT", NVT_FLASH_END_FLAG_LEN) == 0) ||
  44. (memcmp((const char *)&fw_entry->data[i * FLASH_SECTOR_SIZE -
  45. NVT_FLASH_END_FLAG_LEN], "MOD", NVT_FLASH_END_FLAG_LEN) == 0)) {
  46. fw_need_write_size = i * FLASH_SECTOR_SIZE;
  47. NVT_LOG("fw_need_write_size = %zu(0x%zx)\n", fw_need_write_size, fw_need_write_size);
  48. return 0;
  49. }
  50. }
  51. NVT_ERR("end flag \"NVT\" not found!\n");
  52. return -1;
  53. }
  54. /*******************************************************
  55. Description:
  56. Novatek touchscreen request update firmware function.
  57. return:
  58. Executive outcomes. 0---succeed. -1,-22---failed.
  59. *******************************************************/
  60. int32_t update_firmware_request(char *filename)
  61. {
  62. int32_t ret = 0;
  63. if (NULL == filename) {
  64. return -1;
  65. }
  66. NVT_LOG("filename is %s\n", filename);
  67. ret = request_firmware(&fw_entry, filename, &ts->client->dev);
  68. if (ret) {
  69. NVT_ERR("firmware load failed, ret=%d\n", ret);
  70. return ret;
  71. }
  72. // check FW need to write size
  73. if (nvt_get_fw_need_write_size(fw_entry)) {
  74. NVT_ERR("get fw need to write size fail!\n");
  75. return -EINVAL;
  76. }
  77. // check if FW version add FW version bar equals 0xFF
  78. if (*(fw_entry->data + FW_BIN_VER_OFFSET) + *(fw_entry->data + FW_BIN_VER_BAR_OFFSET) != 0xFF) {
  79. NVT_ERR("bin file FW_VER + FW_VER_BAR should be 0xFF!\n");
  80. NVT_ERR("FW_VER=0x%02X, FW_VER_BAR=0x%02X\n", *(fw_entry->data+FW_BIN_VER_OFFSET), *(fw_entry->data+FW_BIN_VER_BAR_OFFSET));
  81. return -EINVAL;
  82. }
  83. return 0;
  84. }
  85. /*******************************************************
  86. Description:
  87. Novatek touchscreen release update firmware function.
  88. return:
  89. n.a.
  90. *******************************************************/
  91. void update_firmware_release(void)
  92. {
  93. if (fw_entry) {
  94. release_firmware(fw_entry);
  95. }
  96. fw_entry=NULL;
  97. }
  98. /*******************************************************
  99. Description:
  100. Novatek touchscreen check firmware version function.
  101. return:
  102. Executive outcomes. 0---need update. 1---need not
  103. update.
  104. *******************************************************/
  105. int32_t Check_FW_Ver(void)
  106. {
  107. uint8_t buf[16] = {0};
  108. int32_t ret = 0;
  109. //write i2c index to EVENT BUF ADDR
  110. ret = nvt_set_page(I2C_BLDR_Address, ts->mmap->EVENT_BUF_ADDR | EVENT_MAP_FWINFO);
  111. if (ret < 0) {
  112. NVT_ERR("i2c write error!(%d)\n", ret);
  113. return ret;
  114. }
  115. //read Firmware Version
  116. buf[0] = EVENT_MAP_FWINFO;
  117. buf[1] = 0x00;
  118. buf[2] = 0x00;
  119. ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
  120. if (ret < 0) {
  121. NVT_ERR("i2c read error!(%d)\n", ret);
  122. return ret;
  123. }
  124. NVT_LOG("IC FW Ver = 0x%02X, FW Ver Bar = 0x%02X\n", buf[1], buf[2]);
  125. NVT_LOG("Bin FW Ver = 0x%02X, FW ver Bar = 0x%02X\n",
  126. fw_entry->data[FW_BIN_VER_OFFSET], fw_entry->data[FW_BIN_VER_BAR_OFFSET]);
  127. // check IC FW_VER + FW_VER_BAR equals 0xFF or not, need to update if not
  128. if ((buf[1] + buf[2]) != 0xFF) {
  129. NVT_ERR("IC FW_VER + FW_VER_BAR not equals to 0xFF!\n");
  130. return 0;
  131. }
  132. // compare IC and binary FW version
  133. if (buf[1] > fw_entry->data[FW_BIN_VER_OFFSET])
  134. return 1;
  135. else
  136. return 0;
  137. }
  138. /*******************************************************
  139. Description:
  140. Novatek touchscreen resume from deep power down function.
  141. return:
  142. Executive outcomes. 0---succeed. negative---failed.
  143. *******************************************************/
  144. int32_t Resume_PD(void)
  145. {
  146. uint8_t buf[8] = {0};
  147. int32_t ret = 0;
  148. int32_t retry = 0;
  149. // Resume Command
  150. buf[0] = 0x00;
  151. buf[1] = 0xAB;
  152. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
  153. if (ret < 0) {
  154. NVT_ERR("Write Enable error!!(%d)\n", ret);
  155. return ret;
  156. }
  157. // Check 0xAA (Resume Command)
  158. retry = 0;
  159. while(1) {
  160. msleep(1);
  161. buf[0] = 0x00;
  162. buf[1] = 0x00;
  163. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  164. if (ret < 0) {
  165. NVT_ERR("Check 0xAA (Resume Command) error!!(%d)\n", ret);
  166. return ret;
  167. }
  168. if (buf[1] == 0xAA) {
  169. break;
  170. }
  171. retry++;
  172. if (unlikely(retry > 20)) {
  173. NVT_ERR("Check 0xAA (Resume Command) error!! status=0x%02X\n", buf[1]);
  174. return -1;
  175. }
  176. }
  177. msleep(10);
  178. NVT_LOG("Resume PD OK\n");
  179. return 0;
  180. }
  181. /*******************************************************
  182. Description:
  183. Novatek touchscreen check firmware checksum function.
  184. return:
  185. Executive outcomes. 0---checksum not match.
  186. 1---checksum match. -1--- checksum read failed.
  187. *******************************************************/
  188. int32_t Check_CheckSum(void)
  189. {
  190. uint8_t buf[64] = {0};
  191. uint32_t XDATA_Addr = ts->mmap->READ_FLASH_CHECKSUM_ADDR;
  192. int32_t ret = 0;
  193. int32_t i = 0;
  194. int32_t k = 0;
  195. uint16_t WR_Filechksum[BLOCK_64KB_NUM] = {0};
  196. uint16_t RD_Filechksum[BLOCK_64KB_NUM] = {0};
  197. size_t len_in_blk = 0;
  198. int32_t retry = 0;
  199. if (Resume_PD()) {
  200. NVT_ERR("Resume PD error!!\n");
  201. return -1;
  202. }
  203. for (i = 0; i < BLOCK_64KB_NUM; i++) {
  204. if (fw_need_write_size > (i * SIZE_64KB)) {
  205. // Calculate WR_Filechksum of each 64KB block
  206. len_in_blk = min(fw_need_write_size - i * SIZE_64KB, (size_t)SIZE_64KB);
  207. WR_Filechksum[i] = i + 0x00 + 0x00 + (((len_in_blk - 1) >> 8) & 0xFF) + ((len_in_blk - 1) & 0xFF);
  208. for (k = 0; k < len_in_blk; k++) {
  209. WR_Filechksum[i] += fw_entry->data[k + i * SIZE_64KB];
  210. }
  211. WR_Filechksum[i] = 65535 - WR_Filechksum[i] + 1;
  212. // Fast Read Command
  213. buf[0] = 0x00;
  214. buf[1] = 0x07;
  215. buf[2] = i;
  216. buf[3] = 0x00;
  217. buf[4] = 0x00;
  218. buf[5] = ((len_in_blk - 1) >> 8) & 0xFF;
  219. buf[6] = (len_in_blk - 1) & 0xFF;
  220. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
  221. if (ret < 0) {
  222. NVT_ERR("Fast Read Command error!!(%d)\n", ret);
  223. return ret;
  224. }
  225. // Check 0xAA (Fast Read Command)
  226. retry = 0;
  227. while (1) {
  228. msleep(80);
  229. buf[0] = 0x00;
  230. buf[1] = 0x00;
  231. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  232. if (ret < 0) {
  233. NVT_ERR("Check 0xAA (Fast Read Command) error!!(%d)\n", ret);
  234. return ret;
  235. }
  236. if (buf[1] == 0xAA) {
  237. break;
  238. }
  239. retry++;
  240. if (unlikely(retry > 5)) {
  241. NVT_ERR("Check 0xAA (Fast Read Command) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
  242. return -1;
  243. }
  244. }
  245. // Read Checksum (write addr high byte & middle byte)
  246. ret = nvt_set_page(I2C_BLDR_Address, XDATA_Addr);
  247. if (ret < 0) {
  248. NVT_ERR("Read Checksum (write addr high byte & middle byte) error!!(%d)\n", ret);
  249. return ret;
  250. }
  251. // Read Checksum
  252. buf[0] = (XDATA_Addr) & 0xFF;
  253. buf[1] = 0x00;
  254. buf[2] = 0x00;
  255. ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
  256. if (ret < 0) {
  257. NVT_ERR("Read Checksum error!!(%d)\n", ret);
  258. return ret;
  259. }
  260. RD_Filechksum[i] = (uint16_t)((buf[2] << 8) | buf[1]);
  261. if (WR_Filechksum[i] != RD_Filechksum[i]) {
  262. NVT_ERR("RD_Filechksum[%d]=0x%04X, WR_Filechksum[%d]=0x%04X\n", i, RD_Filechksum[i], i, WR_Filechksum[i]);
  263. NVT_ERR("firmware checksum not match!!\n");
  264. return 0;
  265. }
  266. }
  267. }
  268. NVT_LOG("firmware checksum match\n");
  269. return 1;
  270. }
  271. /*******************************************************
  272. Description:
  273. Novatek touchscreen initial bootloader and flash
  274. block function.
  275. return:
  276. Executive outcomes. 0---succeed. negative---failed.
  277. *******************************************************/
  278. int32_t Init_BootLoader(void)
  279. {
  280. uint8_t buf[64] = {0};
  281. int32_t ret = 0;
  282. int32_t retry = 0;
  283. // SW Reset & Idle
  284. nvt_sw_reset_idle();
  285. // Initiate Flash Block
  286. buf[0] = 0x00;
  287. buf[1] = 0x00;
  288. buf[2] = I2C_FW_Address;
  289. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 3);
  290. if (ret < 0) {
  291. NVT_ERR("Inittial Flash Block error!!(%d)\n", ret);
  292. return ret;
  293. }
  294. // Check 0xAA (Initiate Flash Block)
  295. retry = 0;
  296. while(1) {
  297. msleep(1);
  298. buf[0] = 0x00;
  299. buf[1] = 0x00;
  300. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  301. if (ret < 0) {
  302. NVT_ERR("Check 0xAA (Inittial Flash Block) error!!(%d)\n", ret);
  303. return ret;
  304. }
  305. if (buf[1] == 0xAA) {
  306. break;
  307. }
  308. retry++;
  309. if (unlikely(retry > 20)) {
  310. NVT_ERR("Check 0xAA (Inittial Flash Block) error!! status=0x%02X\n", buf[1]);
  311. return -1;
  312. }
  313. }
  314. NVT_LOG("Init OK \n");
  315. msleep(20);
  316. return 0;
  317. }
  318. /*******************************************************
  319. Description:
  320. Novatek touchscreen erase flash sectors function.
  321. return:
  322. Executive outcomes. 0---succeed. negative---failed.
  323. *******************************************************/
  324. int32_t Erase_Flash(void)
  325. {
  326. uint8_t buf[64] = {0};
  327. int32_t ret = 0;
  328. int32_t count = 0;
  329. int32_t i = 0;
  330. int32_t Flash_Address = 0;
  331. int32_t retry = 0;
  332. // Write Enable
  333. buf[0] = 0x00;
  334. buf[1] = 0x06;
  335. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
  336. if (ret < 0) {
  337. NVT_ERR("Write Enable (for Write Status Register) error!!(%d)\n", ret);
  338. return ret;
  339. }
  340. // Check 0xAA (Write Enable)
  341. retry = 0;
  342. while (1) {
  343. msleep(1);
  344. buf[0] = 0x00;
  345. buf[1] = 0x00;
  346. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  347. if (ret < 0) {
  348. NVT_ERR("Check 0xAA (Write Enable for Write Status Register) error!!(%d)\n", ret);
  349. return ret;
  350. }
  351. if (buf[1] == 0xAA) {
  352. break;
  353. }
  354. retry++;
  355. if (unlikely(retry > 20)) {
  356. NVT_ERR("Check 0xAA (Write Enable for Write Status Register) error!! status=0x%02X\n", buf[1]);
  357. return -1;
  358. }
  359. }
  360. // Write Status Register
  361. buf[0] = 0x00;
  362. buf[1] = 0x01;
  363. buf[2] = 0x00;
  364. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 3);
  365. if (ret < 0) {
  366. NVT_ERR("Write Status Register error!!(%d)\n", ret);
  367. return ret;
  368. }
  369. // Check 0xAA (Write Status Register)
  370. retry = 0;
  371. while (1) {
  372. msleep(1);
  373. buf[0] = 0x00;
  374. buf[1] = 0x00;
  375. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  376. if (ret < 0) {
  377. NVT_ERR("Check 0xAA (Write Status Register) error!!(%d)\n", ret);
  378. return ret;
  379. }
  380. if (buf[1] == 0xAA) {
  381. break;
  382. }
  383. retry++;
  384. if (unlikely(retry > 20)) {
  385. NVT_ERR("Check 0xAA (Write Status Register) error!! status=0x%02X\n", buf[1]);
  386. return -1;
  387. }
  388. }
  389. // Read Status
  390. retry = 0;
  391. while (1) {
  392. msleep(5);
  393. buf[0] = 0x00;
  394. buf[1] = 0x05;
  395. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
  396. if (ret < 0) {
  397. NVT_ERR("Read Status (for Write Status Register) error!!(%d)\n", ret);
  398. return ret;
  399. }
  400. // Check 0xAA (Read Status)
  401. buf[0] = 0x00;
  402. buf[1] = 0x00;
  403. buf[2] = 0x00;
  404. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
  405. if (ret < 0) {
  406. NVT_ERR("Check 0xAA (Read Status for Write Status Register) error!!(%d)\n", ret);
  407. return ret;
  408. }
  409. if ((buf[1] == 0xAA) && (buf[2] == 0x00)) {
  410. break;
  411. }
  412. retry++;
  413. if (unlikely(retry > 100)) {
  414. NVT_ERR("Check 0xAA (Read Status for Write Status Register) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
  415. return -1;
  416. }
  417. }
  418. if (fw_need_write_size % FLASH_SECTOR_SIZE)
  419. count = fw_need_write_size / FLASH_SECTOR_SIZE + 1;
  420. else
  421. count = fw_need_write_size / FLASH_SECTOR_SIZE;
  422. for(i = 0; i < count; i++) {
  423. // Write Enable
  424. buf[0] = 0x00;
  425. buf[1] = 0x06;
  426. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
  427. if (ret < 0) {
  428. NVT_ERR("Write Enable error!!(%d,%d)\n", ret, i);
  429. return ret;
  430. }
  431. // Check 0xAA (Write Enable)
  432. retry = 0;
  433. while (1) {
  434. msleep(1);
  435. buf[0] = 0x00;
  436. buf[1] = 0x00;
  437. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  438. if (ret < 0) {
  439. NVT_ERR("Check 0xAA (Write Enable) error!!(%d,%d)\n", ret, i);
  440. return ret;
  441. }
  442. if (buf[1] == 0xAA) {
  443. break;
  444. }
  445. retry++;
  446. if (unlikely(retry > 20)) {
  447. NVT_ERR("Check 0xAA (Write Enable) error!! status=0x%02X\n", buf[1]);
  448. return -1;
  449. }
  450. }
  451. Flash_Address = i * FLASH_SECTOR_SIZE;
  452. // Sector Erase
  453. buf[0] = 0x00;
  454. buf[1] = 0x20; // Command : Sector Erase
  455. buf[2] = ((Flash_Address >> 16) & 0xFF);
  456. buf[3] = ((Flash_Address >> 8) & 0xFF);
  457. buf[4] = (Flash_Address & 0xFF);
  458. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 5);
  459. if (ret < 0) {
  460. NVT_ERR("Sector Erase error!!(%d,%d)\n", ret, i);
  461. return ret;
  462. }
  463. // Check 0xAA (Sector Erase)
  464. retry = 0;
  465. while (1) {
  466. msleep(1);
  467. buf[0] = 0x00;
  468. buf[1] = 0x00;
  469. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  470. if (ret < 0) {
  471. NVT_ERR("Check 0xAA (Sector Erase) error!!(%d,%d)\n", ret, i);
  472. return ret;
  473. }
  474. if (buf[1] == 0xAA) {
  475. break;
  476. }
  477. retry++;
  478. if (unlikely(retry > 20)) {
  479. NVT_ERR("Check 0xAA (Sector Erase) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
  480. return -1;
  481. }
  482. }
  483. // Read Status
  484. retry = 0;
  485. while (1) {
  486. msleep(5);
  487. buf[0] = 0x00;
  488. buf[1] = 0x05;
  489. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
  490. if (ret < 0) {
  491. NVT_ERR("Read Status error!!(%d,%d)\n", ret, i);
  492. return ret;
  493. }
  494. // Check 0xAA (Read Status)
  495. buf[0] = 0x00;
  496. buf[1] = 0x00;
  497. buf[2] = 0x00;
  498. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
  499. if (ret < 0) {
  500. NVT_ERR("Check 0xAA (Read Status) error!!(%d,%d)\n", ret, i);
  501. return ret;
  502. }
  503. if ((buf[1] == 0xAA) && (buf[2] == 0x00)) {
  504. break;
  505. }
  506. retry++;
  507. if (unlikely(retry > 100)) {
  508. NVT_ERR("Check 0xAA (Read Status) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
  509. return -1;
  510. }
  511. }
  512. }
  513. NVT_LOG("Erase OK \n");
  514. return 0;
  515. }
  516. /*******************************************************
  517. Description:
  518. Novatek touchscreen write flash sectors function.
  519. return:
  520. Executive outcomes. 0---succeed. negative---failed.
  521. *******************************************************/
  522. int32_t Write_Flash(void)
  523. {
  524. uint8_t buf[64] = {0};
  525. uint32_t XDATA_Addr = ts->mmap->RW_FLASH_DATA_ADDR;
  526. uint32_t Flash_Address = 0;
  527. int32_t i = 0, j = 0, k = 0;
  528. uint8_t tmpvalue = 0;
  529. int32_t count = 0;
  530. int32_t ret = 0;
  531. int32_t retry = 0;
  532. int32_t percent = 0;
  533. int32_t previous_percent = -1;
  534. // change I2C buffer index
  535. ret = nvt_set_page(I2C_BLDR_Address, XDATA_Addr);
  536. if (ret < 0) {
  537. NVT_ERR("change I2C buffer index error!!(%d)\n", ret);
  538. return ret;
  539. }
  540. if (fw_need_write_size % 256)
  541. count = fw_need_write_size / 256 + 1;
  542. else
  543. count = fw_need_write_size / 256;
  544. for (i = 0; i < count; i++) {
  545. Flash_Address = i * 256;
  546. // Write Enable
  547. buf[0] = 0x00;
  548. buf[1] = 0x06;
  549. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
  550. if (ret < 0) {
  551. NVT_ERR("Write Enable error!!(%d)\n", ret);
  552. return ret;
  553. }
  554. // Check 0xAA (Write Enable)
  555. retry = 0;
  556. while (1) {
  557. udelay(100);
  558. buf[0] = 0x00;
  559. buf[1] = 0x00;
  560. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  561. if (ret < 0) {
  562. NVT_ERR("Check 0xAA (Write Enable) error!!(%d,%d)\n", ret, i);
  563. return ret;
  564. }
  565. if (buf[1] == 0xAA) {
  566. break;
  567. }
  568. retry++;
  569. if (unlikely(retry > 20)) {
  570. NVT_ERR("Check 0xAA (Write Enable) error!! status=0x%02X\n", buf[1]);
  571. return -1;
  572. }
  573. }
  574. // Write Page : 256 bytes
  575. for (j = 0; j < min(fw_need_write_size - i * 256, (size_t)256); j += 32) {
  576. buf[0] = (XDATA_Addr + j) & 0xFF;
  577. for (k = 0; k < 32; k++) {
  578. buf[1 + k] = fw_entry->data[Flash_Address + j + k];
  579. }
  580. ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 33);
  581. if (ret < 0) {
  582. NVT_ERR("Write Page error!!(%d), j=%d\n", ret, j);
  583. return ret;
  584. }
  585. }
  586. if (fw_need_write_size - Flash_Address >= 256)
  587. tmpvalue=(Flash_Address >> 16) + ((Flash_Address >> 8) & 0xFF) + (Flash_Address & 0xFF) + 0x00 + (255);
  588. else
  589. tmpvalue=(Flash_Address >> 16) + ((Flash_Address >> 8) & 0xFF) + (Flash_Address & 0xFF) + 0x00 + (fw_need_write_size - Flash_Address - 1);
  590. for (k = 0; k < min(fw_need_write_size - Flash_Address, (size_t)256); k++)
  591. tmpvalue += fw_entry->data[Flash_Address + k];
  592. tmpvalue = 255 - tmpvalue + 1;
  593. // Page Program
  594. buf[0] = 0x00;
  595. buf[1] = 0x02;
  596. buf[2] = ((Flash_Address >> 16) & 0xFF);
  597. buf[3] = ((Flash_Address >> 8) & 0xFF);
  598. buf[4] = (Flash_Address & 0xFF);
  599. buf[5] = 0x00;
  600. buf[6] = min(fw_need_write_size - Flash_Address, (size_t)256) - 1;
  601. buf[7] = tmpvalue;
  602. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 8);
  603. if (ret < 0) {
  604. NVT_ERR("Page Program error!!(%d), i=%d\n", ret, i);
  605. return ret;
  606. }
  607. // Check 0xAA (Page Program)
  608. retry = 0;
  609. while (1) {
  610. msleep(1);
  611. buf[0] = 0x00;
  612. buf[1] = 0x00;
  613. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  614. if (ret < 0) {
  615. NVT_ERR("Page Program error!!(%d)\n", ret);
  616. return ret;
  617. }
  618. if (buf[1] == 0xAA || buf[1] == 0xEA) {
  619. break;
  620. }
  621. retry++;
  622. if (unlikely(retry > 20)) {
  623. NVT_ERR("Check 0xAA (Page Program) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
  624. return -1;
  625. }
  626. }
  627. if (buf[1] == 0xEA) {
  628. NVT_ERR("Page Program error!! i=%d\n", i);
  629. return -3;
  630. }
  631. // Read Status
  632. retry = 0;
  633. while (1) {
  634. msleep(5);
  635. buf[0] = 0x00;
  636. buf[1] = 0x05;
  637. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
  638. if (ret < 0) {
  639. NVT_ERR("Read Status error!!(%d)\n", ret);
  640. return ret;
  641. }
  642. // Check 0xAA (Read Status)
  643. buf[0] = 0x00;
  644. buf[1] = 0x00;
  645. buf[2] = 0x00;
  646. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
  647. if (ret < 0) {
  648. NVT_ERR("Check 0xAA (Read Status) error!!(%d)\n", ret);
  649. return ret;
  650. }
  651. if (((buf[1] == 0xAA) && (buf[2] == 0x00)) || (buf[1] == 0xEA)) {
  652. break;
  653. }
  654. retry++;
  655. if (unlikely(retry > 100)) {
  656. NVT_ERR("Check 0xAA (Read Status) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
  657. return -1;
  658. }
  659. }
  660. if (buf[1] == 0xEA) {
  661. NVT_ERR("Page Program error!! i=%d\n", i);
  662. return -4;
  663. }
  664. percent = ((i + 1) * 100) / count;
  665. if (((percent % 10) == 0) && (percent != previous_percent)) {
  666. NVT_LOG("Programming...%2d%%\n", percent);
  667. previous_percent = percent;
  668. }
  669. }
  670. NVT_LOG("Program OK \n");
  671. return 0;
  672. }
  673. /*******************************************************
  674. Description:
  675. Novatek touchscreen verify checksum of written
  676. flash function.
  677. return:
  678. Executive outcomes. 0---succeed. negative---failed.
  679. *******************************************************/
  680. int32_t Verify_Flash(void)
  681. {
  682. uint8_t buf[64] = {0};
  683. uint32_t XDATA_Addr = ts->mmap->READ_FLASH_CHECKSUM_ADDR;
  684. int32_t ret = 0;
  685. int32_t i = 0;
  686. int32_t k = 0;
  687. uint16_t WR_Filechksum[BLOCK_64KB_NUM] = {0};
  688. uint16_t RD_Filechksum[BLOCK_64KB_NUM] = {0};
  689. size_t len_in_blk = 0;
  690. int32_t retry = 0;
  691. for (i = 0; i < BLOCK_64KB_NUM; i++) {
  692. if (fw_need_write_size > (i * SIZE_64KB)) {
  693. // Calculate WR_Filechksum of each 64KB block
  694. len_in_blk = min(fw_need_write_size - i * SIZE_64KB, (size_t)SIZE_64KB);
  695. WR_Filechksum[i] = i + 0x00 + 0x00 + (((len_in_blk - 1) >> 8) & 0xFF) + ((len_in_blk - 1) & 0xFF);
  696. for (k = 0; k < len_in_blk; k++) {
  697. WR_Filechksum[i] += fw_entry->data[k + i * SIZE_64KB];
  698. }
  699. WR_Filechksum[i] = 65535 - WR_Filechksum[i] + 1;
  700. // Fast Read Command
  701. buf[0] = 0x00;
  702. buf[1] = 0x07;
  703. buf[2] = i;
  704. buf[3] = 0x00;
  705. buf[4] = 0x00;
  706. buf[5] = ((len_in_blk - 1) >> 8) & 0xFF;
  707. buf[6] = (len_in_blk - 1) & 0xFF;
  708. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
  709. if (ret < 0) {
  710. NVT_ERR("Fast Read Command error!!(%d)\n", ret);
  711. return ret;
  712. }
  713. // Check 0xAA (Fast Read Command)
  714. retry = 0;
  715. while (1) {
  716. msleep(80);
  717. buf[0] = 0x00;
  718. buf[1] = 0x00;
  719. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  720. if (ret < 0) {
  721. NVT_ERR("Check 0xAA (Fast Read Command) error!!(%d)\n", ret);
  722. return ret;
  723. }
  724. if (buf[1] == 0xAA) {
  725. break;
  726. }
  727. retry++;
  728. if (unlikely(retry > 5)) {
  729. NVT_ERR("Check 0xAA (Fast Read Command) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
  730. return -1;
  731. }
  732. }
  733. // Read Checksum (write addr high byte & middle byte)
  734. ret = nvt_set_page(I2C_BLDR_Address, XDATA_Addr);
  735. if (ret < 0) {
  736. NVT_ERR("Read Checksum (write addr high byte & middle byte) error!!(%d)\n", ret);
  737. return ret;
  738. }
  739. // Read Checksum
  740. buf[0] = (XDATA_Addr) & 0xFF;
  741. buf[1] = 0x00;
  742. buf[2] = 0x00;
  743. ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
  744. if (ret < 0) {
  745. NVT_ERR("Read Checksum error!!(%d)\n", ret);
  746. return ret;
  747. }
  748. RD_Filechksum[i] = (uint16_t)((buf[2] << 8) | buf[1]);
  749. if (WR_Filechksum[i] != RD_Filechksum[i]) {
  750. NVT_ERR("Verify Fail%d!!\n", i);
  751. NVT_ERR("RD_Filechksum[%d]=0x%04X, WR_Filechksum[%d]=0x%04X\n", i, RD_Filechksum[i], i, WR_Filechksum[i]);
  752. return -1;
  753. }
  754. }
  755. }
  756. NVT_LOG("Verify OK \n");
  757. return 0;
  758. }
  759. /*******************************************************
  760. Description:
  761. Novatek touchscreen update firmware function.
  762. return:
  763. Executive outcomes. 0---succeed. negative---failed.
  764. *******************************************************/
  765. int32_t Update_Firmware(void)
  766. {
  767. int32_t ret = 0;
  768. //---Stop CRC check to prevent IC auto reboot---
  769. nvt_stop_crc_reboot();
  770. // Step 1 : initial bootloader
  771. ret = Init_BootLoader();
  772. if (ret) {
  773. return ret;
  774. }
  775. // Step 2 : Resume PD
  776. ret = Resume_PD();
  777. if (ret) {
  778. return ret;
  779. }
  780. // Step 3 : Erase
  781. ret = Erase_Flash();
  782. if (ret) {
  783. return ret;
  784. }
  785. // Step 4 : Program
  786. ret = Write_Flash();
  787. if (ret) {
  788. return ret;
  789. }
  790. // Step 5 : Verify
  791. ret = Verify_Flash();
  792. if (ret) {
  793. return ret;
  794. }
  795. //Step 6 : Bootloader Reset
  796. nvt_bootloader_reset();
  797. nvt_check_fw_reset_state(RESET_STATE_INIT);
  798. nvt_get_fw_info();
  799. return ret;
  800. }
  801. /*******************************************************
  802. Description:
  803. Novatek touchscreen check flash end flag function.
  804. return:
  805. Executive outcomes. 0---succeed. 1,negative---failed.
  806. *******************************************************/
  807. int32_t nvt_check_flash_end_flag(void)
  808. {
  809. uint8_t buf[8] = {0};
  810. uint8_t nvt_end_flag[NVT_FLASH_END_FLAG_LEN + 1] = {0};
  811. int32_t ret = 0;
  812. // Step 1 : initial bootloader
  813. ret = Init_BootLoader();
  814. if (ret) {
  815. return ret;
  816. }
  817. // Step 2 : Resume PD
  818. ret = Resume_PD();
  819. if (ret) {
  820. return ret;
  821. }
  822. // Step 3 : unlock
  823. buf[0] = 0x00;
  824. buf[1] = 0x35;
  825. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
  826. if (ret < 0) {
  827. NVT_ERR("write unlock error!!(%d)\n", ret);
  828. return ret;
  829. }
  830. msleep(10);
  831. //Step 4 : Flash Read Command
  832. buf[0] = 0x00;
  833. buf[1] = 0x03;
  834. buf[2] = (NVT_FLASH_END_FLAG_ADDR >> 16) & 0xFF; //Addr_H
  835. buf[3] = (NVT_FLASH_END_FLAG_ADDR >> 8) & 0xFF; //Addr_M
  836. buf[4] = NVT_FLASH_END_FLAG_ADDR & 0xFF; //Addr_L
  837. buf[5] = (NVT_FLASH_END_FLAG_LEN >> 8) & 0xFF; //Len_H
  838. buf[6] = NVT_FLASH_END_FLAG_LEN & 0xFF; //Len_L
  839. ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
  840. if (ret < 0) {
  841. NVT_ERR("write Read Command error!!(%d)\n", ret);
  842. return ret;
  843. }
  844. msleep(10);
  845. // Check 0xAA (Read Command)
  846. buf[0] = 0x00;
  847. buf[1] = 0x00;
  848. ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
  849. if (ret < 0) {
  850. NVT_ERR("Check 0xAA (Read Command) error!!(%d)\n", ret);
  851. return ret;
  852. }
  853. if (buf[1] != 0xAA) {
  854. NVT_ERR("Check 0xAA (Read Command) error!! status=0x%02X\n", buf[1]);
  855. return -1;
  856. }
  857. msleep(10);
  858. //Step 5 : Read Flash Data
  859. ret = nvt_set_page(I2C_BLDR_Address, ts->mmap->READ_FLASH_CHECKSUM_ADDR);
  860. if (ret < 0) {
  861. NVT_ERR("change index error!! (%d)\n", ret);
  862. return ret;
  863. }
  864. msleep(10);
  865. // Read Back
  866. buf[0] = ts->mmap->READ_FLASH_CHECKSUM_ADDR & 0xFF;
  867. ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 6);
  868. if (ret < 0) {
  869. NVT_ERR("Read Back error!! (%d)\n", ret);
  870. return ret;
  871. }
  872. //buf[3:5] => NVT End Flag
  873. strlcpy(nvt_end_flag, &buf[3], sizeof(nvt_end_flag));
  874. NVT_LOG("nvt_end_flag=%s (%02X %02X %02X)\n", nvt_end_flag, buf[3], buf[4], buf[5]);
  875. if ((memcmp(nvt_end_flag, "NVT", NVT_FLASH_END_FLAG_LEN) == 0) ||
  876. (memcmp(nvt_end_flag, "MOD", NVT_FLASH_END_FLAG_LEN) == 0)) {
  877. return 0;
  878. } else {
  879. NVT_ERR("\"NVT\" end flag not found!\n");
  880. return 1;
  881. }
  882. }
  883. /*******************************************************
  884. Description:
  885. Novatek touchscreen update firmware when booting
  886. function.
  887. return:
  888. n.a.
  889. *******************************************************/
  890. void Boot_Update_Firmware(struct work_struct *work)
  891. {
  892. int32_t ret = 0;
  893. char firmware_name[256] = "";
  894. snprintf(firmware_name, sizeof(firmware_name),
  895. BOOT_UPDATE_FIRMWARE_NAME);
  896. // request bin file in "/etc/firmware"
  897. ret = update_firmware_request(firmware_name);
  898. if (ret) {
  899. NVT_ERR("update_firmware_request failed. (%d)\n", ret);
  900. return;
  901. }
  902. mutex_lock(&ts->lock);
  903. #if NVT_TOUCH_ESD_PROTECT
  904. nvt_esd_check_enable(false);
  905. #endif /* #if NVT_TOUCH_ESD_PROTECT */
  906. nvt_sw_reset_idle();
  907. ret = Check_CheckSum();
  908. if (ret < 0) { // read firmware checksum failed
  909. NVT_ERR("read firmware checksum failed\n");
  910. Update_Firmware();
  911. } else if ((ret == 0) && (Check_FW_Ver() == 0)) { // (fw checksum not match) && (bin fw version >= ic fw version)
  912. NVT_LOG("firmware version not match\n");
  913. Update_Firmware();
  914. } else if (nvt_check_flash_end_flag()) {
  915. NVT_LOG("check flash end flag failed\n");
  916. Update_Firmware();
  917. } else {
  918. // Bootloader Reset
  919. nvt_bootloader_reset();
  920. ret = nvt_check_fw_reset_state(RESET_STATE_INIT);
  921. if (ret) {
  922. NVT_LOG("check fw reset state failed\n");
  923. Update_Firmware();
  924. }
  925. }
  926. mutex_unlock(&ts->lock);
  927. update_firmware_release();
  928. }
  929. #endif /* BOOT_UPDATE_FIRMWARE */
  930. #else /* NT36XXX_SPI */
  931. #include <linux/firmware.h>
  932. #include <linux/gpio.h>
  933. #include "nt36xxx.h"
  934. #if NVT_SPI_BOOT_UPDATE_FIRMWARE
  935. #define SIZE_4KB 4096
  936. #define FLASH_SECTOR_SIZE SIZE_4KB
  937. #define FW_BIN_VER_OFFSET (nvt_spi_fw_need_write_size - SIZE_4KB)
  938. #define FW_BIN_VER_BAR_OFFSET (FW_BIN_VER_OFFSET + 1)
  939. #define NVT_FLASH_END_FLAG_LEN 3
  940. #define NVT_FLASH_END_FLAG_ADDR (nvt_spi_fw_need_write_size - NVT_FLASH_END_FLAG_LEN)
  941. #define NVT_DUMP_PARTITION (0)
  942. #define NVT_DUMP_PARTITION_LEN (1024)
  943. #define NVT_DUMP_PARTITION_PATH "/data/local/tmp"
  944. static ktime_t nvt_spi_start, nvt_spi_end;
  945. static const struct firmware *nvt_spi_fw_entry;
  946. static size_t nvt_spi_fw_need_write_size;
  947. static uint8_t *nvt_spi_fwbuf;
  948. struct nvt_spi_bin_map_t {
  949. char name[12];
  950. uint32_t BIN_addr;
  951. uint32_t SRAM_addr;
  952. uint32_t size;
  953. uint32_t crc;
  954. };
  955. static struct nvt_spi_bin_map_t *nvt_spi_bin_map;
  956. static int32_t nvt_spi_get_fw_need_write_size(const struct firmware *fw_entry)
  957. {
  958. int32_t i = 0;
  959. int32_t total_sectors_to_check = 0;
  960. total_sectors_to_check = fw_entry->size / FLASH_SECTOR_SIZE;
  961. /* printk("total_sectors_to_check = %d\n", total_sectors_to_check); */
  962. for (i = total_sectors_to_check; i > 0; i--) {
  963. // printk("current end flag address checked = 0x%X\n",
  964. // i * FLASH_SECTOR_SIZE - NVT_FLASH_END_FLAG_LEN);
  965. /* check if there is end flag "NVT" at the end of this sector */
  966. if (memcmp(&fw_entry->data[i * FLASH_SECTOR_SIZE - NVT_FLASH_END_FLAG_LEN],
  967. "NVT", NVT_FLASH_END_FLAG_LEN) == 0) {
  968. nvt_spi_fw_need_write_size = i * FLASH_SECTOR_SIZE;
  969. NVT_LOG("fw_need_write_size = %zu(0x%zx), NVT end flag\n",
  970. nvt_spi_fw_need_write_size, nvt_spi_fw_need_write_size);
  971. return 0;
  972. }
  973. /* check if there is end flag "MOD" at the end of this sector */
  974. if (memcmp(&fw_entry->data[i * FLASH_SECTOR_SIZE - NVT_FLASH_END_FLAG_LEN],
  975. "MOD", NVT_FLASH_END_FLAG_LEN) == 0) {
  976. nvt_spi_fw_need_write_size = i * FLASH_SECTOR_SIZE;
  977. NVT_LOG("fw_need_write_size = %zu(0x%zx), MOD end flag\n",
  978. nvt_spi_fw_need_write_size, nvt_spi_fw_need_write_size);
  979. return 0;
  980. }
  981. }
  982. NVT_ERR("end flag \"NVT\" \"MOD\" not found!\n");
  983. return -EINVAL;
  984. }
  985. /*
  986. *******************************************************
  987. * Description:
  988. * Novatek touchscreen init variable and allocate buffer
  989. * for download firmware function.
  990. *
  991. * return:
  992. * n.a.
  993. ******************************************************
  994. */
  995. static int32_t nvt_spi_download_init(void)
  996. {
  997. uint8_t *buf;
  998. /* allocate buffer for transfer firmware */
  999. //NVT_LOG("NVT_TRANSFER_LEN = 0x%06X\n", NVT_SPI_TRANSFER_LEN);
  1000. if (nvt_spi_fwbuf == NULL) {
  1001. buf = kzalloc((NVT_SPI_TRANSFER_LEN + 1 + NVT_SPI_DUMMY_BYTES), GFP_KERNEL);
  1002. if (buf == NULL) {
  1003. NVT_ERR("kzalloc for fwbuf failed!\n");
  1004. return -ENOMEM;
  1005. }
  1006. nvt_spi_fwbuf = buf;
  1007. }
  1008. return 0;
  1009. }
  1010. /*
  1011. ******************************************************
  1012. * Description:
  1013. * Novatek touchscreen checksum function. Calculate bin
  1014. * file checksum for comparison.
  1015. *
  1016. * return:
  1017. * n.a.
  1018. ******************************************************
  1019. */
  1020. static uint32_t CheckSum(const u8 *data, size_t len)
  1021. {
  1022. uint32_t i = 0;
  1023. uint32_t checksum = 0;
  1024. for (i = 0 ; i < len + 1; i++)
  1025. checksum += data[i];
  1026. checksum += len;
  1027. checksum = ~checksum + 1;
  1028. return checksum;
  1029. }
  1030. static uint32_t byte_to_word(const uint8_t *data)
  1031. {
  1032. return data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24);
  1033. }
  1034. /*
  1035. ******************************************************
  1036. * Description:
  1037. * Novatek touchscreen parsing bin header function.
  1038. *
  1039. * return:
  1040. * n.a.
  1041. ******************************************************
  1042. */
  1043. static uint32_t nvt_spi_partition;
  1044. static uint8_t nvt_spi_ilm_dlm_num = 2;
  1045. static uint8_t nvt_spi_cascade_2nd_header_info;
  1046. static int32_t nvt_spi_bin_header_parser(const u8 *fwdata, size_t fwsize)
  1047. {
  1048. uint32_t list = 0;
  1049. uint32_t pos = 0x00;
  1050. uint32_t end = 0x00;
  1051. uint8_t info_sec_num = 0;
  1052. uint8_t ovly_sec_num = 0;
  1053. uint8_t ovly_info = 0;
  1054. uint8_t find_bin_header = 0;
  1055. struct nvt_spi_bin_map_t *bin_map = NULL;
  1056. struct nvt_spi_data_t *ts = nvt_spi_data;
  1057. /* Find the header size */
  1058. end = fwdata[0] + (fwdata[1] << 8) + (fwdata[2] << 16) + (fwdata[3] << 24);
  1059. /* check cascade next header */
  1060. nvt_spi_cascade_2nd_header_info = (fwdata[0x20] & 0x02) >> 1;
  1061. NVT_LOG("cascade_2nd_header_info = %d\n", nvt_spi_cascade_2nd_header_info);
  1062. if (nvt_spi_cascade_2nd_header_info) {
  1063. pos = 0x30; // info section start at 0x30 offset
  1064. while (pos < (end / 2)) {
  1065. info_sec_num++;
  1066. pos += 0x10; /* each header info is 16 bytes */
  1067. }
  1068. info_sec_num = info_sec_num + 1; //next header section
  1069. } else {
  1070. pos = 0x30; // info section start at 0x30 offset
  1071. while (pos < end) {
  1072. info_sec_num++;
  1073. pos += 0x10; /* each header info is 16 bytes */
  1074. }
  1075. }
  1076. /*
  1077. * Find the DLM OVLY section
  1078. * [0:3] Overlay Section Number
  1079. * [4] Overlay Info
  1080. */
  1081. ovly_info = (fwdata[0x28] & 0x10) >> 4;
  1082. ovly_sec_num = (ovly_info) ? (fwdata[0x28] & 0x0F) : 0;
  1083. /*
  1084. * calculate all partition number
  1085. * ilm_dlm_num (ILM & DLM) + ovly_sec_num + info_sec_num
  1086. */
  1087. nvt_spi_partition = nvt_spi_ilm_dlm_num + ovly_sec_num + info_sec_num;
  1088. NVT_LOG("ovly_info=%d, ilm_dlm_num=%d, ovly_sec_num=%d, info_sec_num=%d, partition=%d\n",
  1089. ovly_info, nvt_spi_ilm_dlm_num, ovly_sec_num, info_sec_num, nvt_spi_partition);
  1090. /* allocated memory for header info */
  1091. bin_map = kzalloc((nvt_spi_partition+1) * sizeof(struct nvt_spi_bin_map_t), GFP_KERNEL);
  1092. if (bin_map == NULL) {
  1093. NVT_ERR("kzalloc for bin_map failed!\n");
  1094. return -ENOMEM;
  1095. }
  1096. nvt_spi_bin_map = bin_map;
  1097. for (list = 0; list < nvt_spi_partition; list++) {
  1098. /*
  1099. * [1] parsing ILM & DLM header info
  1100. * BIN_addr : SRAM_addr : size (12-bytes)
  1101. * crc located at 0x18 & 0x1C
  1102. */
  1103. if (list < nvt_spi_ilm_dlm_num) {
  1104. bin_map[list].BIN_addr = byte_to_word(&fwdata[0 + list * 12]);
  1105. bin_map[list].SRAM_addr = byte_to_word(&fwdata[4 + list * 12]);
  1106. bin_map[list].size = byte_to_word(&fwdata[8 + list * 12]);
  1107. if (ts->hw_crc)
  1108. bin_map[list].crc = byte_to_word(&fwdata[0x18 + list * 4]);
  1109. else { //ts->hw_crc
  1110. if ((bin_map[list].BIN_addr + bin_map[list].size) < fwsize)
  1111. bin_map[list].crc = CheckSum(
  1112. &fwdata[bin_map[list].BIN_addr],
  1113. bin_map[list].size);
  1114. else {
  1115. NVT_ERR("access range (0x%08X to 0x%08X) is too large!\n",
  1116. bin_map[list].BIN_addr,
  1117. bin_map[list].BIN_addr + bin_map[list].size);
  1118. return -EINVAL;
  1119. }
  1120. } //ts->hw_crc
  1121. if (list == 0)
  1122. snprintf(bin_map[list].name, sizeof(bin_map[list].name), "ILM");
  1123. else if (list == 1)
  1124. snprintf(bin_map[list].name, sizeof(bin_map[list].name), "DLM");
  1125. }
  1126. /*
  1127. * [2] parsing others header info
  1128. * SRAM_addr : size : BIN_addr : crc (16-bytes)
  1129. */
  1130. if ((list >= nvt_spi_ilm_dlm_num)
  1131. && (list < (nvt_spi_ilm_dlm_num + info_sec_num))) {
  1132. if (find_bin_header == 0) {
  1133. /* others partition located at 0x30 offset */
  1134. pos = 0x30 + (0x10 * (list - nvt_spi_ilm_dlm_num));
  1135. } else if (find_bin_header && nvt_spi_cascade_2nd_header_info) {
  1136. /* cascade 2nd header info */
  1137. pos = end - 0x10;
  1138. }
  1139. bin_map[list].SRAM_addr = byte_to_word(&fwdata[pos]);
  1140. bin_map[list].size = byte_to_word(&fwdata[pos + 4]);
  1141. bin_map[list].BIN_addr = byte_to_word(&fwdata[pos + 8]);
  1142. if (ts->hw_crc)
  1143. bin_map[list].crc = byte_to_word(&fwdata[pos + 12]);
  1144. else { //ts->hw_crc
  1145. if ((bin_map[list].BIN_addr + bin_map[list].size) < fwsize)
  1146. bin_map[list].crc = CheckSum(
  1147. &fwdata[bin_map[list].BIN_addr],
  1148. bin_map[list].size);
  1149. else {
  1150. NVT_ERR("access range (0x%08X to 0x%08X) is too large!\n",
  1151. bin_map[list].BIN_addr,
  1152. bin_map[list].BIN_addr + bin_map[list].size);
  1153. return -EINVAL;
  1154. }
  1155. } //ts->hw_crc
  1156. /* detect header end to protect parser function */
  1157. if ((bin_map[list].BIN_addr < end) && (bin_map[list].size != 0)) {
  1158. snprintf(bin_map[list].name, sizeof(bin_map[list].name),
  1159. "Header");
  1160. find_bin_header = 1;
  1161. } else
  1162. snprintf(bin_map[list].name, sizeof(bin_map[list].name),
  1163. "Info-%d", (list - nvt_spi_ilm_dlm_num));
  1164. }
  1165. /*
  1166. * [3] parsing overlay section header info
  1167. * SRAM_addr : size : BIN_addr : crc (16-bytes)
  1168. */
  1169. if (list >= (nvt_spi_ilm_dlm_num + info_sec_num)) {
  1170. /* overlay info located at DLM (list = 1) start addr */
  1171. pos = bin_map[1].BIN_addr;
  1172. pos += (0x10 * (list - nvt_spi_ilm_dlm_num - info_sec_num));
  1173. bin_map[list].SRAM_addr = byte_to_word(&fwdata[pos]);
  1174. bin_map[list].size = byte_to_word(&fwdata[pos + 4]);
  1175. bin_map[list].BIN_addr = byte_to_word(&fwdata[pos + 8]);
  1176. if (ts->hw_crc)
  1177. bin_map[list].crc = byte_to_word(&fwdata[pos + 12]);
  1178. else { //ts->hw_crc
  1179. if ((bin_map[list].BIN_addr + bin_map[list].size) < fwsize)
  1180. bin_map[list].crc = CheckSum(
  1181. &fwdata[bin_map[list].BIN_addr],
  1182. bin_map[list].size);
  1183. else {
  1184. NVT_ERR("access range (0x%08X to 0x%08X) is too large!\n",
  1185. bin_map[list].BIN_addr,
  1186. bin_map[list].BIN_addr + bin_map[list].size);
  1187. return -EINVAL;
  1188. }
  1189. } //ts->hw_crc
  1190. snprintf(bin_map[list].name, sizeof(bin_map[list].name),
  1191. "Overlay-%d",
  1192. (list - nvt_spi_ilm_dlm_num - info_sec_num));
  1193. }
  1194. /* BIN size error detect */
  1195. if ((bin_map[list].BIN_addr + bin_map[list].size) > fwsize) {
  1196. NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n",
  1197. bin_map[list].BIN_addr,
  1198. bin_map[list].BIN_addr + bin_map[list].size);
  1199. return -EINVAL;
  1200. }
  1201. // NVT_LOG("[%d][%s] SRAM (0x%08X), SIZE (0x%08X), BIN (0x%08X), CRC (0x%08X)\n",
  1202. // list, bin_map[list].name,
  1203. // bin_map[list].SRAM_addr, bin_map[list].size,
  1204. // bin_map[list].BIN_addr, bin_map[list].crc);
  1205. }
  1206. return 0;
  1207. }
  1208. /*
  1209. *******************************************************
  1210. * Description:
  1211. * Novatek touchscreen release update firmware function.
  1212. *
  1213. * return:
  1214. * n.a.
  1215. ******************************************************
  1216. */
  1217. static void nvt_spi_update_firmware_release(void)
  1218. {
  1219. if (nvt_spi_fw_entry)
  1220. release_firmware(nvt_spi_fw_entry);
  1221. nvt_spi_fw_entry = NULL;
  1222. }
  1223. /*
  1224. ******************************************************
  1225. * Description:
  1226. * Novatek touchscreen request update firmware function.
  1227. *
  1228. * return:
  1229. * Executive outcomes. 0---succeed. -1,-22---failed.
  1230. ******************************************************
  1231. */
  1232. static int32_t nvt_spi_update_firmware_request(char *filename)
  1233. {
  1234. uint8_t retry = 0;
  1235. int32_t ret = 0;
  1236. struct nvt_spi_data_t *ts = nvt_spi_data;
  1237. uint8_t ver;
  1238. if (filename == NULL)
  1239. return -ENOENT;
  1240. while (1) {
  1241. NVT_LOG("filename is %s\n", filename);
  1242. ret = request_firmware(&nvt_spi_fw_entry, filename, &ts->client->dev);
  1243. if (ret) {
  1244. NVT_ERR("firmware load failed, ret=%d\n", ret);
  1245. goto request_fail;
  1246. }
  1247. // check FW need to write size
  1248. if (nvt_spi_get_fw_need_write_size(nvt_spi_fw_entry)) {
  1249. NVT_ERR("get fw need to write size fail!\n");
  1250. ret = -EINVAL;
  1251. goto invalid;
  1252. }
  1253. // check if FW version add FW version bar equals 0xFF
  1254. ver = *(nvt_spi_fw_entry->data + FW_BIN_VER_OFFSET);
  1255. if (ver + *(nvt_spi_fw_entry->data + FW_BIN_VER_BAR_OFFSET) != 0xFF) {
  1256. NVT_ERR("bin file FW_VER + FW_VER_BAR should be 0xFF!\n");
  1257. NVT_ERR("FW_VER=0x%02X, FW_VER_BAR=0x%02X\n",
  1258. *(nvt_spi_fw_entry->data+FW_BIN_VER_OFFSET),
  1259. *(nvt_spi_fw_entry->data+FW_BIN_VER_BAR_OFFSET));
  1260. ret = -ENOEXEC;
  1261. goto invalid;
  1262. }
  1263. /* BIN Header Parser */
  1264. ret = nvt_spi_bin_header_parser(nvt_spi_fw_entry->data, nvt_spi_fw_entry->size);
  1265. if (ret) {
  1266. NVT_ERR("bin header parser failed\n");
  1267. goto invalid;
  1268. } else
  1269. break;
  1270. invalid:
  1271. nvt_spi_update_firmware_release();
  1272. if (!IS_ERR_OR_NULL(nvt_spi_bin_map)) {
  1273. kfree(nvt_spi_bin_map);
  1274. nvt_spi_bin_map = NULL;
  1275. }
  1276. request_fail:
  1277. retry++;
  1278. if (unlikely(retry > 2)) {
  1279. NVT_ERR("error, retry=%d\n", retry);
  1280. break;
  1281. }
  1282. }
  1283. return ret;
  1284. }
  1285. /*
  1286. *******************************************************
  1287. * Description:
  1288. * Novatek touchscreen write data to sram function.
  1289. *
  1290. * - fwdata : The buffer is written
  1291. * - SRAM_addr: The sram destination address
  1292. * - size : Number of data bytes in @fwdata being written
  1293. * - BIN_addr : The transferred data offset of @fwdata
  1294. *
  1295. * return:
  1296. * Executive outcomes. 0---succeed. else---fail.
  1297. *******************************************************
  1298. */
  1299. static int32_t nvt_spi_write_sram(const u8 *fwdata,
  1300. uint32_t SRAM_addr, uint32_t size, uint32_t BIN_addr)
  1301. {
  1302. int32_t ret = 0;
  1303. uint32_t i = 0;
  1304. uint16_t len = 0;
  1305. int32_t count = 0;
  1306. if (size % NVT_SPI_TRANSFER_LEN)
  1307. count = (size / NVT_SPI_TRANSFER_LEN) + 1;
  1308. else
  1309. count = (size / NVT_SPI_TRANSFER_LEN);
  1310. for (i = 0 ; i < count ; i++) {
  1311. len = (size < NVT_SPI_TRANSFER_LEN) ? size : NVT_SPI_TRANSFER_LEN;
  1312. //---set xdata index to start address of SRAM---
  1313. ret = nvt_spi_set_page(SRAM_addr);
  1314. if (ret) {
  1315. NVT_ERR("set page failed, ret = %d\n", ret);
  1316. return ret;
  1317. }
  1318. //---write data into SRAM---
  1319. nvt_spi_fwbuf[0] = SRAM_addr & 0x7F; //offset
  1320. memcpy(nvt_spi_fwbuf+1, &fwdata[BIN_addr], len); //payload
  1321. ret = nvt_spi_write(nvt_spi_fwbuf, len+1);
  1322. if (ret) {
  1323. NVT_ERR("write to sram failed, ret = %d\n", ret);
  1324. return ret;
  1325. }
  1326. SRAM_addr += NVT_SPI_TRANSFER_LEN;
  1327. BIN_addr += NVT_SPI_TRANSFER_LEN;
  1328. size -= NVT_SPI_TRANSFER_LEN;
  1329. }
  1330. return ret;
  1331. }
  1332. /*
  1333. *******************************************************
  1334. * Description:
  1335. * Novatek touchscreen nvt_spi_write_firmware function to write
  1336. * firmware into each partition.
  1337. *
  1338. * return:
  1339. * n.a.
  1340. ******************************************************
  1341. */
  1342. static int32_t nvt_spi_write_firmware(const u8 *fwdata, size_t fwsize)
  1343. {
  1344. uint32_t list = 0;
  1345. char *name;
  1346. uint32_t BIN_addr, SRAM_addr, size;
  1347. int32_t ret = 0;
  1348. memset(nvt_spi_fwbuf, 0, (NVT_SPI_TRANSFER_LEN+1));
  1349. for (list = 0; list < nvt_spi_partition; list++) {
  1350. /* initialize variable */
  1351. SRAM_addr = nvt_spi_bin_map[list].SRAM_addr;
  1352. size = nvt_spi_bin_map[list].size;
  1353. BIN_addr = nvt_spi_bin_map[list].BIN_addr;
  1354. name = nvt_spi_bin_map[list].name;
  1355. // NVT_LOG("[%d][%s] SRAM (0x%08X), SIZE (0x%08X), BIN (0x%08X)\n",
  1356. // list, name, SRAM_addr, size, BIN_addr);
  1357. /* Check data size */
  1358. if ((BIN_addr + size) > fwsize) {
  1359. NVT_ERR("access range (0x%08X to 0x%08X) is larger than bin size!\n",
  1360. BIN_addr, BIN_addr + size);
  1361. ret = -EINVAL;
  1362. goto out;
  1363. }
  1364. /* ignore reserved partition (Reserved Partition size is zero) */
  1365. if (!size)
  1366. continue;
  1367. else
  1368. size = size + 1;
  1369. /* write data to SRAM */
  1370. ret = nvt_spi_write_sram(fwdata, SRAM_addr, size, BIN_addr);
  1371. if (ret) {
  1372. NVT_ERR("sram program failed, ret = %d\n", ret);
  1373. goto out;
  1374. }
  1375. }
  1376. out:
  1377. return ret;
  1378. }
  1379. /*
  1380. *******************************************************
  1381. * Description:
  1382. * Novatek touchscreen check checksum function.
  1383. * This function will compare file checksum and fw checksum.
  1384. *
  1385. * return:
  1386. * n.a.
  1387. *******************************************************
  1388. */
  1389. static int32_t nvt_spi_check_fw_checksum(void)
  1390. {
  1391. uint32_t fw_checksum = 0;
  1392. uint32_t len = nvt_spi_partition * 4;
  1393. uint32_t list = 0;
  1394. int32_t ret = 0;
  1395. struct nvt_spi_data_t *ts = nvt_spi_data;
  1396. memset(nvt_spi_fwbuf, 0, (len+1));
  1397. //---set xdata index to checksum---
  1398. nvt_spi_set_page(ts->mmap->R_ILM_CHECKSUM_ADDR);
  1399. /* read checksum */
  1400. nvt_spi_fwbuf[0] = (ts->mmap->R_ILM_CHECKSUM_ADDR) & 0x7F;
  1401. ret = nvt_spi_read(nvt_spi_fwbuf, len+1);
  1402. if (ret) {
  1403. NVT_ERR("Read fw checksum failed\n");
  1404. return ret;
  1405. }
  1406. /*
  1407. * Compare each checksum from fw
  1408. * ILM + DLM + Overlay + Info
  1409. * nvt_spi_ilm_dlm_num (ILM & DLM) + ovly_sec_num + info_sec_num
  1410. */
  1411. for (list = 0; list < nvt_spi_partition; list++) {
  1412. fw_checksum = byte_to_word(&nvt_spi_fwbuf[1+list*4]);
  1413. /* ignore reserved partition (Reserved Partition size is zero) */
  1414. if (!nvt_spi_bin_map[list].size)
  1415. continue;
  1416. if (nvt_spi_bin_map[list].crc != fw_checksum) {
  1417. NVT_ERR("[%d] BIN_checksum=0x%08X, FW_checksum=0x%08X\n",
  1418. list, nvt_spi_bin_map[list].crc, fw_checksum);
  1419. ret = -EIO;
  1420. }
  1421. }
  1422. return ret;
  1423. }
  1424. /*
  1425. *******************************************************
  1426. * Description:
  1427. * Novatek touchscreen set bootload crc reg bank function.
  1428. * This function will set hw crc reg before enable crc function.
  1429. *
  1430. * return:
  1431. * n.a.
  1432. ******************************************************
  1433. */
  1434. static void nvt_spi_set_bld_crc_bank(uint32_t DES_ADDR, uint32_t SRAM_ADDR,
  1435. uint32_t LENGTH_ADDR, uint32_t size,
  1436. uint32_t G_CHECKSUM_ADDR, uint32_t crc)
  1437. {
  1438. struct nvt_spi_data_t *ts = nvt_spi_data;
  1439. /* write destination address */
  1440. nvt_spi_set_page(DES_ADDR);
  1441. nvt_spi_fwbuf[0] = DES_ADDR & 0x7F;
  1442. nvt_spi_fwbuf[1] = (SRAM_ADDR) & 0xFF;
  1443. nvt_spi_fwbuf[2] = (SRAM_ADDR >> 8) & 0xFF;
  1444. nvt_spi_fwbuf[3] = (SRAM_ADDR >> 16) & 0xFF;
  1445. nvt_spi_write(nvt_spi_fwbuf, 4);
  1446. /* write length */
  1447. //nvt_spi_set_page(LENGTH_ADDR);
  1448. nvt_spi_fwbuf[0] = LENGTH_ADDR & 0x7F;
  1449. nvt_spi_fwbuf[1] = (size) & 0xFF;
  1450. nvt_spi_fwbuf[2] = (size >> 8) & 0xFF;
  1451. nvt_spi_fwbuf[3] = (size >> 16) & 0x01;
  1452. if (ts->hw_crc == 1)
  1453. nvt_spi_write(nvt_spi_fwbuf, 3);
  1454. else if (ts->hw_crc > 1)
  1455. nvt_spi_write(nvt_spi_fwbuf, 4);
  1456. /* write golden dlm checksum */
  1457. //nvt_spi_set_page(G_CHECKSUM_ADDR);
  1458. nvt_spi_fwbuf[0] = G_CHECKSUM_ADDR & 0x7F;
  1459. nvt_spi_fwbuf[1] = (crc) & 0xFF;
  1460. nvt_spi_fwbuf[2] = (crc >> 8) & 0xFF;
  1461. nvt_spi_fwbuf[3] = (crc >> 16) & 0xFF;
  1462. nvt_spi_fwbuf[4] = (crc >> 24) & 0xFF;
  1463. nvt_spi_write(nvt_spi_fwbuf, 5);
  1464. }
  1465. /*
  1466. *********************************************************
  1467. * Description:
  1468. * Novatek touchscreen set BLD hw crc function.
  1469. * This function will set ILM and DLM crc information to register.
  1470. *
  1471. * return:
  1472. * n.a.
  1473. *********************************************************
  1474. */
  1475. static void nvt_spi_set_bld_hw_crc(void)
  1476. {
  1477. struct nvt_spi_data_t *ts = nvt_spi_data;
  1478. /* [0] ILM */
  1479. /* write register bank */
  1480. nvt_spi_set_bld_crc_bank(ts->mmap->ILM_DES_ADDR, nvt_spi_bin_map[0].SRAM_addr,
  1481. ts->mmap->ILM_LENGTH_ADDR, nvt_spi_bin_map[0].size,
  1482. ts->mmap->G_ILM_CHECKSUM_ADDR, nvt_spi_bin_map[0].crc);
  1483. /* [1] DLM */
  1484. /* write register bank */
  1485. nvt_spi_set_bld_crc_bank(ts->mmap->DLM_DES_ADDR, nvt_spi_bin_map[1].SRAM_addr,
  1486. ts->mmap->DLM_LENGTH_ADDR, nvt_spi_bin_map[1].size,
  1487. ts->mmap->G_DLM_CHECKSUM_ADDR, nvt_spi_bin_map[1].crc);
  1488. }
  1489. /*
  1490. *******************************************************
  1491. * Description:
  1492. * Novatek touchscreen read BLD hw crc info function.
  1493. * This function will check crc results from register.
  1494. *
  1495. * return:
  1496. * n.a.
  1497. ******************************************************
  1498. */
  1499. static void nvt_spi_read_bld_hw_crc(void)
  1500. {
  1501. uint8_t buf[8] = {0};
  1502. uint32_t g_crc = 0, r_crc = 0;
  1503. struct nvt_spi_data_t *ts = nvt_spi_data;
  1504. /* CRC Flag */
  1505. nvt_spi_set_page(ts->mmap->BLD_ILM_DLM_CRC_ADDR);
  1506. buf[0] = ts->mmap->BLD_ILM_DLM_CRC_ADDR & 0x7F;
  1507. buf[1] = 0x00;
  1508. nvt_spi_read(buf, 2);
  1509. NVT_ERR("crc_done = %d, ilm_crc_flag = %d, dlm_crc_flag = %d\n",
  1510. (buf[1] >> 2) & 0x01, (buf[1] >> 0) & 0x01, (buf[1] >> 1) & 0x01);
  1511. /* ILM CRC */
  1512. nvt_spi_set_page(ts->mmap->G_ILM_CHECKSUM_ADDR);
  1513. buf[0] = ts->mmap->G_ILM_CHECKSUM_ADDR & 0x7F;
  1514. buf[1] = 0x00;
  1515. buf[2] = 0x00;
  1516. buf[3] = 0x00;
  1517. buf[4] = 0x00;
  1518. nvt_spi_read(buf, 5);
  1519. g_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24);
  1520. nvt_spi_set_page(ts->mmap->R_ILM_CHECKSUM_ADDR);
  1521. buf[0] = ts->mmap->R_ILM_CHECKSUM_ADDR & 0x7F;
  1522. buf[1] = 0x00;
  1523. buf[2] = 0x00;
  1524. buf[3] = 0x00;
  1525. buf[4] = 0x00;
  1526. nvt_spi_read(buf, 5);
  1527. r_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24);
  1528. NVT_ERR("ilm: bin crc = 0x%08X, golden = 0x%08X, result = 0x%08X\n",
  1529. nvt_spi_bin_map[0].crc, g_crc, r_crc);
  1530. /* DLM CRC */
  1531. nvt_spi_set_page(ts->mmap->G_DLM_CHECKSUM_ADDR);
  1532. buf[0] = ts->mmap->G_DLM_CHECKSUM_ADDR & 0x7F;
  1533. buf[1] = 0x00;
  1534. buf[2] = 0x00;
  1535. buf[3] = 0x00;
  1536. buf[4] = 0x00;
  1537. nvt_spi_read(buf, 5);
  1538. g_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24);
  1539. nvt_spi_set_page(ts->mmap->R_DLM_CHECKSUM_ADDR);
  1540. buf[0] = ts->mmap->R_DLM_CHECKSUM_ADDR & 0x7F;
  1541. buf[1] = 0x00;
  1542. buf[2] = 0x00;
  1543. buf[3] = 0x00;
  1544. buf[4] = 0x00;
  1545. nvt_spi_read(buf, 5);
  1546. r_crc = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24);
  1547. NVT_ERR("dlm: bin crc = 0x%08X, golden = 0x%08X, result = 0x%08X\n",
  1548. nvt_spi_bin_map[1].crc, g_crc, r_crc);
  1549. }
  1550. /*
  1551. ******************************************************
  1552. * Description:
  1553. * Novatek touchscreen Download_Firmware with HW CRC
  1554. * function. It's complete download firmware flow.
  1555. *
  1556. * return:
  1557. * Executive outcomes. 0---succeed. else---fail.
  1558. ******************************************************
  1559. */
  1560. static int32_t nvt_spi_download_firmware_hw_crc(void)
  1561. {
  1562. uint8_t retry = 0;
  1563. int32_t ret = 0;
  1564. const struct firmware *fw = nvt_spi_fw_entry;
  1565. nvt_spi_start = ktime_get();
  1566. while (1) {
  1567. /* bootloader reset to reset MCU */
  1568. nvt_spi_bootloader_reset();
  1569. /* set ilm & dlm reg bank */
  1570. nvt_spi_set_bld_hw_crc();
  1571. /* Start to write firmware process */
  1572. if (nvt_spi_cascade_2nd_header_info) {
  1573. /* for cascade */
  1574. nvt_spi_tx_auto_copy_mode();
  1575. ret = nvt_spi_write_firmware(fw->data, fw->size);
  1576. if (ret) {
  1577. NVT_ERR("Write_Firmware failed. (%d)\n", ret);
  1578. goto fail;
  1579. }
  1580. ret = nvt_spi_check_spi_dma_tx_info();
  1581. if (ret) {
  1582. NVT_ERR("spi dma tx info failed. (%d)\n", ret);
  1583. goto fail;
  1584. }
  1585. } else {
  1586. ret = nvt_spi_write_firmware(fw->data, fw->size);
  1587. if (ret) {
  1588. NVT_ERR("Write_Firmware failed. (%d)\n", ret);
  1589. goto fail;
  1590. }
  1591. }
  1592. #if NVT_DUMP_PARTITION
  1593. ret = nvt_dump_partition();
  1594. if (ret)
  1595. NVT_ERR("nvt_dump_partition failed, ret = %d\n", ret);
  1596. #endif
  1597. /* enable hw bld crc function */
  1598. nvt_spi_bld_crc_enable();
  1599. /* clear fw reset status & enable fw crc check */
  1600. nvt_spi_fw_crc_enable();
  1601. /* Set Boot Ready Bit */
  1602. nvt_spi_boot_ready();
  1603. ret = nvt_spi_check_fw_reset_state(NVT_SPI_RESET_STATE_INIT);
  1604. if (ret) {
  1605. NVT_ERR("nvt_check_fw_reset_state failed. (%d)\n", ret);
  1606. goto fail;
  1607. } else {
  1608. break;
  1609. }
  1610. fail:
  1611. retry++;
  1612. if (unlikely(retry > 2)) {
  1613. NVT_ERR("error, retry=%d\n", retry);
  1614. nvt_spi_read_bld_hw_crc();
  1615. break;
  1616. }
  1617. }
  1618. nvt_spi_end = ktime_get();
  1619. return ret;
  1620. }
  1621. /*
  1622. ********************************************************
  1623. * Description:
  1624. * Novatek touchscreen Download_Firmware function. It's
  1625. * complete download firmware flow.
  1626. *
  1627. * return:
  1628. * n.a.
  1629. ******************************************************
  1630. */
  1631. static int32_t nvt_spi_download_firmware(void)
  1632. {
  1633. uint32_t addr;
  1634. uint8_t retry = 0;
  1635. int32_t ret = 0;
  1636. struct nvt_spi_data_t *ts = nvt_spi_data;
  1637. nvt_spi_start = ktime_get();
  1638. while (1) {
  1639. /*
  1640. * Send eng reset cmd before download FW
  1641. * Keep TP_RESX low when send eng reset cmd
  1642. */
  1643. #if NVT_SPI_TOUCH_SUPPORT_HW_RST
  1644. gpio_set_value(ts->reset_gpio, 0);
  1645. mdelay(1); //wait 1ms
  1646. #endif
  1647. nvt_spi_eng_reset();
  1648. #if NVT_SPI_TOUCH_SUPPORT_HW_RST
  1649. gpio_set_value(ts->reset_gpio, 1);
  1650. mdelay(10); //wait tRT2BRST after TP_RST
  1651. #endif
  1652. nvt_spi_bootloader_reset();
  1653. addr = ts->mmap->EVENT_BUF_ADDR;
  1654. /* clear fw reset status */
  1655. nvt_spi_write_addr(addr | NVT_SPI_EVENT_MAP_RESET_COMPLETE, 0x00);
  1656. /* Start to write firmware process */
  1657. ret = nvt_spi_write_firmware(nvt_spi_fw_entry->data, nvt_spi_fw_entry->size);
  1658. if (ret) {
  1659. NVT_ERR("Write_Firmware failed. (%d)\n", ret);
  1660. goto fail;
  1661. }
  1662. #if NVT_DUMP_PARTITION
  1663. ret = nvt_dump_partition();
  1664. if (ret)
  1665. NVT_ERR("nvt_dump_partition failed, ret = %d\n", ret);
  1666. #endif
  1667. /* Set Boot Ready Bit */
  1668. nvt_spi_boot_ready();
  1669. ret = nvt_spi_check_fw_reset_state(NVT_SPI_RESET_STATE_INIT);
  1670. if (ret) {
  1671. NVT_ERR("nvt_check_fw_reset_state failed. (%d)\n", ret);
  1672. goto fail;
  1673. }
  1674. /* check fw checksum result */
  1675. ret = nvt_spi_check_fw_checksum();
  1676. if (ret) {
  1677. NVT_ERR("firmware checksum not match, retry=%d\n", retry);
  1678. goto fail;
  1679. } else
  1680. break;
  1681. fail:
  1682. retry++;
  1683. if (unlikely(retry > 2)) {
  1684. NVT_ERR("error, retry=%d\n", retry);
  1685. break;
  1686. }
  1687. }
  1688. nvt_spi_end = ktime_get();
  1689. return ret;
  1690. }
  1691. /*
  1692. ******************************************************
  1693. * Description:
  1694. * Novatek touchscreen update firmware main function.
  1695. *
  1696. * return:
  1697. * n.a.
  1698. ******************************************************
  1699. */
  1700. int32_t nvt_spi_update_firmware(char *firmware_name)
  1701. {
  1702. int32_t ret = 0;
  1703. struct nvt_spi_data_t *ts = nvt_spi_data;
  1704. // request bin file in "/etc/firmware"
  1705. ret = nvt_spi_update_firmware_request(firmware_name);
  1706. if (ret) {
  1707. NVT_ERR("update_firmware_request failed. (%d)\n", ret);
  1708. goto request_firmware_fail;
  1709. }
  1710. /* initial buffer and variable */
  1711. ret = nvt_spi_download_init();
  1712. if (ret) {
  1713. NVT_ERR("Download Init failed. (%d)\n", ret);
  1714. goto download_fail;
  1715. }
  1716. /* download firmware process */
  1717. if (ts->hw_crc)
  1718. ret = nvt_spi_download_firmware_hw_crc();
  1719. else
  1720. ret = nvt_spi_download_firmware();
  1721. if (ret) {
  1722. NVT_ERR("Download Firmware failed. (%d)\n", ret);
  1723. goto download_fail;
  1724. }
  1725. NVT_LOG("Update firmware success! <%ld us>\n",
  1726. (long) ktime_us_delta(nvt_spi_end, nvt_spi_start));
  1727. /* Get FW Info */
  1728. ret = nvt_spi_get_fw_info();
  1729. if (ret)
  1730. NVT_ERR("nvt_get_fw_info failed. (%d)\n", ret);
  1731. download_fail:
  1732. if (!IS_ERR_OR_NULL(nvt_spi_bin_map)) {
  1733. kfree(nvt_spi_bin_map);
  1734. nvt_spi_bin_map = NULL;
  1735. }
  1736. nvt_spi_update_firmware_release();
  1737. request_firmware_fail:
  1738. return ret;
  1739. }
  1740. /*
  1741. *******************************************************
  1742. * Description:
  1743. * Novatek touchscreen update firmware when booting
  1744. * function.
  1745. *
  1746. * return:
  1747. * n.a.
  1748. ******************************************************
  1749. */
  1750. void nvt_spi_update_firmware_work(struct work_struct *work)
  1751. {
  1752. struct nvt_spi_data_t *ts = nvt_spi_data;
  1753. mutex_lock(&ts->lock);
  1754. nvt_spi_update_firmware(NVT_SPI_BOOT_UPDATE_FIRMWARE_NAME);
  1755. mutex_unlock(&ts->lock);
  1756. }
  1757. #endif
  1758. #endif