ftsTool.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * FTS Capacitive touch screen controller (FingerTipS)
  4. *
  5. * Copyright (C) 2016-2018, 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 Utility Functions *
  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/init.h>
  47. #include <linux/pm.h>
  48. #include <linux/delay.h>
  49. #include <linux/ctype.h>
  50. #include <linux/fs.h>
  51. #include <linux/uaccess.h>
  52. #include <linux/power_supply.h>
  53. #include <linux/firmware.h>
  54. #include <linux/gpio.h>
  55. #include "ftsCompensation.h"
  56. #include "ftsCrossCompile.h"
  57. #include "ftsError.h"
  58. #include "ftsHardware.h"
  59. #include "ftsIO.h"
  60. #include "ftsSoftware.h"
  61. #include "ftsTime.h"
  62. #include "ftsFlash.h"
  63. #include "ftsTool.h"
  64. #include "../fts.h"
  65. static char tag[8] = "[ FTS ]\0";
  66. static int reset_gpio = GPIO_NOT_DEFINED;
  67. static int system_resetted_up;
  68. static int system_resetted_down;
  69. int readB2(u16 address, u8 *outBuf, int len)
  70. {
  71. int remaining = len;
  72. int toRead = 0;
  73. int retry = 0;
  74. int ret;
  75. int event_to_search[3];
  76. char *temp = NULL;
  77. u8 *init_outBuf = outBuf;
  78. u16 init_addr = address;
  79. u8 readEvent[FIFO_EVENT_SIZE] = {0};
  80. u8 cmd[4] = { FTS_CMD_REQU_FW_CONF, 0x00, 0x00, (u8)len };
  81. u16ToU8_be(address, &cmd[1]);
  82. temp = printHex("Command B2 = ", cmd, 4);
  83. if (temp != NULL)
  84. logError(0, "%s %s", tag, temp);
  85. kfree(temp);
  86. do {
  87. remaining = len;
  88. ret = fts_writeFwCmd(cmd, 4);
  89. if (ret < 0) {
  90. logError(1, "%s %s: ERROR %02X\n",
  91. tag, __func__, ERROR_I2C_W);
  92. return ret;
  93. }
  94. //ask to the FW the data
  95. logError(0, "%s Command to FW sent!\n", tag);
  96. event_to_search[0] = (int)EVENTID_FW_CONFIGURATION;
  97. while (remaining > OK) {
  98. event_to_search[1] = (int)((address & 0xFF00) >> 8);
  99. event_to_search[2] = (int)(address & 0x00FF);
  100. if (remaining > B2_DATA_BYTES) {
  101. toRead = B2_DATA_BYTES;
  102. remaining -= B2_DATA_BYTES;
  103. } else {
  104. toRead = remaining;
  105. remaining = 0;
  106. }
  107. ret = pollForEvent(event_to_search, 3,
  108. readEvent, GENERAL_TIMEOUT);
  109. if (ret >= OK) {
  110. //start the polling for reading the reply
  111. memcpy(outBuf, &readEvent[3], toRead);
  112. retry = 0;
  113. outBuf += toRead;
  114. } else {
  115. retry += 1;
  116. break;
  117. }
  118. address += B2_DATA_BYTES;
  119. }
  120. logError(0, "%s %s:B2 failed...attempt = %d\n",
  121. tag, __func__, retry);
  122. outBuf = init_outBuf;
  123. address = init_addr;
  124. } while (retry < B2_RETRY && retry != 0);
  125. if (retry == B2_RETRY) {
  126. logError(1, "%s %s:ERROR %02X\n", tag, __func__, ERROR_TIMEOUT);
  127. return ERROR_TIMEOUT;
  128. }
  129. logError(0, "%s B2 read %d bytes\n", tag, len);
  130. return OK;
  131. }
  132. int readB2U16(u16 address, u8 *outBuf, int byteToRead)
  133. {
  134. int remaining = byteToRead;
  135. int toRead = 0;
  136. int ret;
  137. u8 *buff = (u8 *)kmalloc_array((B2_CHUNK + 1), sizeof(u8), GFP_KERNEL);
  138. if (buff == NULL) {
  139. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_ALLOC);
  140. return ERROR_ALLOC;
  141. }
  142. while (remaining > 0) {
  143. if (remaining >= B2_CHUNK) {
  144. toRead = B2_CHUNK;
  145. remaining -= B2_CHUNK;
  146. } else {
  147. toRead = remaining;
  148. remaining = 0;
  149. }
  150. ret = readB2(address, buff, toRead);
  151. if (ret < 0) {
  152. kfree(buff);
  153. return ret;
  154. }
  155. memcpy(outBuf, buff, toRead);
  156. address += toRead;
  157. outBuf += toRead;
  158. }
  159. kfree(buff);
  160. return OK;
  161. }
  162. int releaseInformation(void)
  163. {
  164. int ret;
  165. u8 cmd[1] = { FTS_CMD_RELEASE_INFO };
  166. int event_to_search[1];
  167. u8 readEvent[FIFO_EVENT_SIZE];
  168. event_to_search[0] = (int)EVENTID_RELEASE_INFO;
  169. logError(0, "%s %s: started... Chip INFO:\n", tag, __func__);
  170. ret = fts_writeFwCmd(cmd, 1);
  171. if (ret < OK) {
  172. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ret);
  173. return ret;
  174. }
  175. ret = pollForEvent(event_to_search, 1, &readEvent[0],
  176. RELEASE_INFO_TIMEOUT);
  177. //start the polling for reading the reply
  178. if (ret < OK) {
  179. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ret);
  180. return ret;
  181. }
  182. logError(0, "%s %s: Finished! %d\n", tag, __func__, ret);
  183. return OK;
  184. }
  185. int lockDownInfo(u8 *data, int len)
  186. {
  187. int ret;
  188. int i = 0, num_event;
  189. u8 cmd[1] = { FTS_CMD_LOCKDOWN_CMD };
  190. int event_to_search[3] = {EVENTID_LOCKDOWN_INFO,
  191. EVENT_TYPE_LOCKDOWN, 0x00};
  192. u8 readEvent[FIFO_EVENT_SIZE];
  193. logError(0, "%s %s:started...\n", tag, __func__);
  194. if (len <= 0)
  195. return ERROR_OP_NOT_ALLOW;
  196. ret = fts_writeFwCmd(cmd, 1);
  197. if (ret < OK) {
  198. logError(1, "%s %s:ERROR %02X\n", tag, __func__, ret);
  199. return ret;
  200. }
  201. num_event = (len + 3) / 4;
  202. logError(0, "%s %s:num_event = %d\n", tag, __func__, num_event);
  203. for (i = 0; i < num_event; i++) {
  204. ret = pollForEvent(event_to_search, 3,
  205. &readEvent[0], GENERAL_TIMEOUT);
  206. //start the polling for reading the reply
  207. if (ret < OK) {
  208. logError(1, "%s %s:ERROR %02X\n", tag, __func__, ret);
  209. return ret;
  210. }
  211. data[i * 4] = readEvent[3];
  212. data[i * 4 + 1] = readEvent[4];
  213. data[i * 4 + 2] = readEvent[5];
  214. data[i * 4 + 3] = readEvent[6];
  215. event_to_search[2] += 4;
  216. //logError(0, "%02X %02X %02X %02X ", readEvent[3],
  217. //readEvent[4], readEvent[5], readEvent[6]);
  218. }
  219. logError(0, "%s %s:Finished! %d\n", tag, __func__, ret);
  220. return OK;
  221. }
  222. int calculateCRC8(u8 *u8_srcBuff, int size, u8 *crc)
  223. {
  224. u8 u8_remainder;
  225. u8 bit;
  226. int i = 0;
  227. u8_remainder = 0x00;
  228. logError(0, "%s %s: Start CRC computing...\n", tag, __func__);
  229. if (size == 0 || u8_srcBuff == NULL) {
  230. logError(1, "Arguments passed not valid!");
  231. logError(1, "%s %s:Data pointer = NULL ", tag, __func__);
  232. logError(1, "or size = 0 (%d) ERROR %08X\n",
  233. size, ERROR_OP_NOT_ALLOW);
  234. return ERROR_OP_NOT_ALLOW;
  235. }
  236. // Perform modulo-2 division, a byte at a time.
  237. //Bring the next byte into the remainder.
  238. for (i = 0; i < size; i++) {
  239. //Perform modulo-2 division, a bit at a time.
  240. u8_remainder ^= u8_srcBuff[i];
  241. //Try to divide the current data bit.
  242. for (bit = 8; bit > 0; --bit) {
  243. if (u8_remainder & (0x1 << 7))
  244. u8_remainder = (u8_remainder << 1) ^ 0x9B;
  245. else
  246. u8_remainder = (u8_remainder << 1);
  247. }
  248. } //The final remainder is the CRC result.
  249. *crc = u8_remainder;
  250. logError(0, "%s %s: CRC value = %02X\n", tag, __func__, *crc);
  251. return OK;
  252. }
  253. int writeLockDownInfo(u8 *data, int size)
  254. {
  255. int ret, i, toWrite, retry = 0, offset = size;
  256. u8 cmd[2 + LOCKDOWN_CODE_WRITE_CHUNK] = {FTS_CMD_LOCKDOWN_FILL, 0x00};
  257. u8 crc = 0;
  258. int event_to_search[2] = {EVENTID_STATUS_UPDATE,
  259. EVENT_TYPE_LOCKDOWN_WRITE};
  260. u8 readEvent[FIFO_EVENT_SIZE];
  261. char *temp = NULL;
  262. logError(0, "%s %s: Writing Lockdown code into the IC...\n",
  263. tag, __func__);
  264. ret = fts_disableInterrupt();
  265. if (ret < OK) {
  266. logError(1, "%s %s: ERROR %08X\n", tag, __func__, ret);
  267. ret = (ret | ERROR_LOCKDOWN_CODE);
  268. goto ERROR;
  269. }
  270. if (size > LOCKDOWN_CODE_MAX_SIZE) {
  271. logError(1, "%s %s: Lockdown data to write too big! ",
  272. tag, __func__);
  273. logError(1, "%d>%d ERROR %08X\n",
  274. size, LOCKDOWN_CODE_MAX_SIZE, ret);
  275. ret = (ERROR_OP_NOT_ALLOW | ERROR_LOCKDOWN_CODE);
  276. goto ERROR;
  277. }
  278. temp = printHex("Lockdown Code = ", data, size);
  279. if (temp != NULL) {
  280. logError(0, "%s %s: %s", tag, __func__, temp);
  281. kfree(temp);
  282. }
  283. for (retry = 0; retry < LOCKDOWN_CODE_RETRY; retry++) {
  284. logError(0, "%s %s: Filling FW buffer...\n", tag, __func__);
  285. i = 0;
  286. offset = size;
  287. cmd[0] = FTS_CMD_LOCKDOWN_FILL;
  288. while (offset > 0) {
  289. if (offset > LOCKDOWN_CODE_WRITE_CHUNK)
  290. toWrite = LOCKDOWN_CODE_WRITE_CHUNK;
  291. else
  292. toWrite = offset;
  293. memcpy(&cmd[2], &data[i], toWrite);
  294. cmd[1] = i;
  295. temp = printHex("Commmand = ", cmd, 2 + toWrite);
  296. if (temp != NULL) {
  297. logError(0, "%s %s: %s", tag, __func__, temp);
  298. kfree(temp);
  299. }
  300. ret = fts_writeFwCmd(cmd, 2 + toWrite);
  301. if (ret < OK) {
  302. logError(1, "Unable to write Lockdown data ");
  303. logError(1, "%s %s:Lockdown data at %d ",
  304. tag, __func__, i);
  305. logError(1, "iteration.%08X\n", ret);
  306. ret = (ret | ERROR_LOCKDOWN_CODE);
  307. continue;
  308. }
  309. i += toWrite;//update the offset
  310. offset -= toWrite;
  311. }
  312. logError(0, "%s %s: Compute 8bit CRC...\n", tag, __func__);
  313. ret = calculateCRC8(data, size, &crc);
  314. if (ret < OK) {
  315. logError(1, "%s %s:Unable to compute CRC..ERROR %08X\n",
  316. tag, __func__, ret);
  317. ret = (ret | ERROR_LOCKDOWN_CODE);
  318. continue;
  319. }
  320. cmd[0] = FTS_CMD_LOCKDOWN_WRITE;
  321. cmd[1] = 0x00;
  322. cmd[2] = (u8)size;
  323. cmd[3] = crc;
  324. logError(0, "%s %s: Write Lockdown data...\n",
  325. tag, __func__);
  326. temp = printHex("Commmand = ", cmd, 4);
  327. if (temp != NULL) {
  328. logError(0, "%s %s: %s", tag, __func__, temp);
  329. kfree(temp);
  330. }
  331. ret = fts_writeFwCmd(cmd, 4);
  332. if (ret < OK) {
  333. logError(1, "%s%s:Unable to send Lockdown data ",
  334. tag, __func__);
  335. logError(1, "write command%08X\n", ret);
  336. ret = (ret | ERROR_LOCKDOWN_CODE);
  337. continue;
  338. }
  339. ret = pollForEvent(event_to_search,
  340. 2,
  341. &readEvent[0],
  342. GENERAL_TIMEOUT);
  343. //start the polling for reading the reply
  344. if (ret < OK) {
  345. logError(1, "%s%s:Cann't find lockdown code ",
  346. tag, __func__);
  347. logError(1, "%write reply %08X\n", ret);
  348. continue;
  349. }
  350. if (readEvent[2] != 0x00) {
  351. logError(1, "%s %s:Event check FAIL!%02X != 0x00 ",
  352. tag, __func__, readEvent[2]);
  353. logError(1, "%ERR%08X\n", ERROR_LOCKDOWN_CODE);
  354. ret = ERROR_LOCKDOWN_CODE;
  355. continue;
  356. } else {
  357. logError(0, "%s %s:Lockdown Code write DONE!\n",
  358. tag, __func__);
  359. ret = OK;
  360. break;
  361. }
  362. }
  363. ERROR:
  364. //ret = fts_enableInterrupt();
  365. //ensure that the interrupt are always renabled when exit from funct
  366. if (fts_enableInterrupt() < OK) {
  367. logError(1, "%s %s: Error while re-enabling the interrupt!\n",
  368. tag, __func__);
  369. }
  370. return ret;
  371. }
  372. int rewriteLockDownInfo(u8 *data, int size)
  373. {
  374. int ret, i, toWrite, retry = 0, offset = size;
  375. u8 cmd[2 + LOCKDOWN_CODE_WRITE_CHUNK] = {FTS_CMD_LOCKDOWN_FILL, 0x00};
  376. u8 crc = 0;
  377. int event_to_search[2] = {EVENTID_STATUS_UPDATE,
  378. EVENT_TYPE_LOCKDOWN_WRITE};
  379. u8 readEvent[FIFO_EVENT_SIZE];
  380. char *temp = NULL;
  381. logError(0, "%s %s: ReWriting Lockdown code into the IC start ...\n",
  382. tag, __func__);
  383. ret = fts_disableInterrupt();
  384. if (ret < OK) {
  385. logError(1, "%s %s: ERROR %08X\n", tag, __func__, ret);
  386. ret = (ret | ERROR_LOCKDOWN_CODE);
  387. goto ERROR;
  388. }
  389. if (size > LOCKDOWN_CODE_MAX_SIZE) {
  390. logError(1, "%s %s: Lockdown data to write too big! ",
  391. tag, __func__);
  392. logError(1, "%d>%d ERROR %08X\n",
  393. size, LOCKDOWN_CODE_MAX_SIZE, ret);
  394. ret = (ERROR_OP_NOT_ALLOW | ERROR_LOCKDOWN_CODE);
  395. goto ERROR;
  396. }
  397. temp = printHex("Lockdown Code = ", data, size);
  398. if (temp != NULL) {
  399. logError(0, "%s %s: %s", tag, __func__, temp);
  400. kfree(temp);
  401. }
  402. for (retry = 0; retry < LOCKDOWN_CODE_RETRY; retry++) {
  403. logError(0, "%s %s: Filling FW buffer ...\n", tag, __func__);
  404. i = 0;
  405. offset = size;
  406. cmd[0] = FTS_CMD_LOCKDOWN_FILL;
  407. while (offset > 0) {
  408. if (offset > LOCKDOWN_CODE_WRITE_CHUNK)
  409. toWrite = LOCKDOWN_CODE_WRITE_CHUNK;
  410. else
  411. toWrite = offset;
  412. memcpy(&cmd[2], &data[i], toWrite);
  413. cmd[1] = i;
  414. temp = printHex("Commmand = ", cmd, 2 + toWrite);
  415. if (temp != NULL) {
  416. logError(0, "%s %s: %s", tag, __func__, temp);
  417. kfree(temp);
  418. }
  419. ret = fts_writeFwCmd(cmd, 2 + toWrite);
  420. if (ret < OK) {
  421. logError(1, "Unable to rewrite Lockdown data");
  422. logError(1, "%s %s: at %d iteration ",
  423. tag, __func__, i);
  424. logError(1, "ERROR %08X\n", ret);
  425. ret = (ret | ERROR_LOCKDOWN_CODE);
  426. continue;
  427. }
  428. i += toWrite;//update the offset
  429. offset -= toWrite;
  430. }
  431. logError(0, "%s %s: Compute 8bit CRC...\n", tag, __func__);
  432. ret = calculateCRC8(data, size, &crc);
  433. if (ret < OK) {
  434. logError(1, "%s %s:Unable to compute CRC.. ",
  435. tag, __func__);
  436. logError(1, "ERROR %08X\n", ret);
  437. ret = (ret | ERROR_LOCKDOWN_CODE);
  438. continue;
  439. }
  440. cmd[0] = FTS_CMD_LOCKDOWN_WRITE;
  441. cmd[1] = 0x01;
  442. cmd[2] = (u8)size;
  443. cmd[3] = crc;
  444. temp = printHex("Commmand = ", cmd, 4);
  445. if (temp != NULL) {
  446. logError(0, "%s %s: %s", tag, __func__, temp);
  447. kfree(temp);
  448. }
  449. logError(0, "%s %s: ReWrite Lockdown data...\n", tag, __func__);
  450. ret = fts_writeFwCmd(cmd, 4);
  451. if (ret < OK) {
  452. logError(1, "Unable to send Lockdown data");
  453. logError(1, "%s %s:rewrite command... ERROR %08X\n",
  454. tag, __func__, ret);
  455. ret = (ret | ERROR_LOCKDOWN_CODE);
  456. continue;
  457. }
  458. //start the polling for reading the reply
  459. ret = pollForEvent(event_to_search, 2,
  460. &readEvent[0], GENERAL_TIMEOUT);
  461. if (ret >= OK) {
  462. if (readEvent[2] < 0x00) {
  463. logError(1, "%s %s:Event check FAIL! ",
  464. tag, __func__);
  465. logError(1, "%02X != 0x00 %08X\n",
  466. readEvent[2], ERROR_LOCKDOWN_CODE);
  467. ret = ERROR_LOCKDOWN_CODE;
  468. continue;
  469. } else {
  470. logError(0, "%s %s: Lockdown Code ",
  471. tag, __func__);
  472. logError(0, "rewrite DONE!\n");
  473. ret = OK;
  474. break;
  475. }
  476. } else {
  477. logError(1, "Can not find lockdown code write ");
  478. logError(1, "reply event!%s %s: ERROR %08X\n",
  479. tag, __func__, ret);
  480. }
  481. }
  482. ERROR:
  483. //ret = fts_enableInterrupt();
  484. //ensure that the interrupt are always renabled when exit from funct
  485. if (fts_enableInterrupt() < OK) {
  486. logError(1, "%s %s: Error while re-enabling the interrupt!\n",
  487. tag, __func__);
  488. }
  489. return ret;
  490. }
  491. int readLockDownInfo(u8 *lockData, int *size)
  492. {
  493. int ret, retry = 0, toRead = 0, byteToRead;
  494. u8 cmd = FTS_CMD_LOCKDOWN_READ;
  495. int event_to_search[3] = {EVENTID_LOCKDOWN_INFO_READ, -1, 0x00};
  496. u8 readEvent[FIFO_EVENT_SIZE];
  497. char *temp = NULL;
  498. lockData = NULL;
  499. logError(0, "%s %s: Reading Lockdown code from the IC...\n",
  500. tag, __func__);
  501. ret = fts_disableInterrupt();
  502. if (ret < OK) {
  503. logError(1, "%s %s: ERROR %08X\n", tag, __func__, ret);
  504. ret = (ret | ERROR_LOCKDOWN_CODE);
  505. goto ERROR;
  506. }
  507. for (retry = 0; retry < LOCKDOWN_CODE_RETRY; retry++) {
  508. event_to_search[2] = 0x00;
  509. logError(0, "%s %s: Read Lockdown data.(%d attempt)\n",
  510. tag, __func__, retry + 1);
  511. ret = fts_writeFwCmd(&cmd, 1);
  512. if (ret < OK) {
  513. logError(1, "%s%s:Unable to send Lockdown data ",
  514. tag, __func__);
  515. logError(1, "write CMD %08X\n", ret);
  516. ret = (ret | ERROR_LOCKDOWN_CODE);
  517. continue;
  518. }
  519. //start the polling for reading the reply
  520. ret = pollForEvent(event_to_search, 3,
  521. &readEvent[0], GENERAL_TIMEOUT);
  522. if (ret < OK) {
  523. logError(1, "Cann't find first lockdown code read");
  524. logError(1, "%s %s:reply event! ERROR %08X\n",
  525. tag, __func__, ret);
  526. continue;
  527. }
  528. byteToRead = readEvent[1];
  529. *size = byteToRead;
  530. logError(0, "%s %s:Lockdown Code size = %d\n",
  531. tag, __func__, *size);
  532. lockData = (u8 *)kmalloc_array((byteToRead),
  533. sizeof(u8), GFP_KERNEL);
  534. if (lockData == NULL) {
  535. logError(1, "%s %s:Unable to allocate lockData %08X\n",
  536. tag, __func__, ERROR_ALLOC);
  537. ret = (ERROR_ALLOC | ERROR_LOCKDOWN_CODE);
  538. continue;
  539. }
  540. while (byteToRead > 0) {
  541. if ((readEvent[1] - readEvent[2])
  542. > LOCKDOWN_CODE_READ_CHUNK) {
  543. toRead = LOCKDOWN_CODE_READ_CHUNK;
  544. } else {
  545. toRead = readEvent[1] - readEvent[2];
  546. }
  547. byteToRead -= toRead;
  548. memcpy(&lockData[readEvent[2]],
  549. &readEvent[3], toRead);
  550. event_to_search[2] += toRead;
  551. if (byteToRead <= 0)
  552. continue;
  553. ret = pollForEvent(event_to_search,
  554. 3,
  555. &readEvent[0],
  556. GENERAL_TIMEOUT);
  557. //start polling for reading reply
  558. if (ret < OK) {
  559. logError(1, "Can not find lockdow");
  560. logError(1, "code read reply event ");
  561. logError(1, "%s%s:offset%02X%08X\n",
  562. tag, __func__, event_to_search[2], ret);
  563. ret = (ERROR_ALLOC | ERROR_LOCKDOWN_CODE);
  564. break;
  565. }
  566. }
  567. if (byteToRead != 0) {
  568. logError(1, "%s %s:Read Lockdown code FAIL! ",
  569. tag, __func__);
  570. logError(1, "ERROR %08X\n", ret);
  571. continue;
  572. } else {
  573. logError(0, "%s %s: Lockdown Code read DONE!\n",
  574. tag, __func__);
  575. ret = OK;
  576. temp = printHex("Lockdown Code = ", lockData, *size);
  577. if (temp != NULL) {
  578. logError(0, "%s %s: %s", tag, __func__, temp);
  579. kfree(temp);
  580. }
  581. break;
  582. }
  583. }
  584. ERROR:
  585. //ret = fts_enableInterrupt();
  586. //ensure that the interrupt are always
  587. //renabled when exit from funct
  588. if (fts_enableInterrupt() < OK) {
  589. logError(1, "%s %s:Error while re-enabling the interrupt!\n",
  590. tag, __func__);
  591. }
  592. return ret;
  593. }
  594. char *printHex(char *label, u8 *buff, int count)
  595. {
  596. int i, offset;
  597. char *result = NULL;
  598. size_t len = 0;
  599. offset = strlen(label);
  600. len = (offset + 3 * count) + 2;
  601. result = (char *)kmalloc_array(len, sizeof(char), GFP_KERNEL);
  602. if (result != NULL) {
  603. strlcpy(result, label, len);
  604. for (i = 0; i < count; i++)
  605. snprintf(&result[offset + i * 3], 4, "%02X ", buff[i]);
  606. strlcat(result, "\n", len);
  607. }
  608. return result;
  609. }
  610. int pollForEvent(int *event_to_search, int event_bytes,
  611. u8 *readData, int time_to_wait)
  612. {
  613. int i, find, retry, count_err;
  614. int time_to_count;
  615. int err_handling = OK;
  616. struct StopWatch clock;
  617. u8 cmd[1] = { FIFO_CMD_READONE };
  618. char *temp = NULL;
  619. find = 0;
  620. retry = 0;
  621. count_err = 0;
  622. time_to_count = time_to_wait / TIMEOUT_RESOLUTION;
  623. startStopWatch(&clock);
  624. while (find != 1 && retry < time_to_count
  625. && fts_readCmd(cmd, 1, readData, FIFO_EVENT_SIZE) >= 0) {
  626. if (readData[0] == EVENTID_ERROR_EVENT) {
  627. temp = printHex("ERROR EVENT = ",
  628. readData, FIFO_EVENT_SIZE);
  629. if (temp != NULL)
  630. logError(0, "%s %s", tag, temp);
  631. kfree(temp);
  632. count_err++;
  633. err_handling = errorHandler(readData, FIFO_EVENT_SIZE);
  634. if ((err_handling & 0xF0FF0000)
  635. == ERROR_HANDLER_STOP_PROC) {
  636. logError(1, "%s %s: forced to be stopped! ",
  637. tag, __func__);
  638. logError(1, "ERROR %08X\n", err_handling);
  639. return err_handling;
  640. }
  641. } else {
  642. if (readData[0] != EVENTID_NO_EVENT) {
  643. temp = printHex("READ EVENT = ",
  644. readData, FIFO_EVENT_SIZE);
  645. if (temp != NULL)
  646. logError(0, "%s %s", tag, temp);
  647. kfree(temp);
  648. }
  649. if (readData[0] == EVENTID_CONTROL_READY &&
  650. event_to_search[0] != EVENTID_CONTROL_READY) {
  651. logError(0, "Unmanned Controller Ready Event!");
  652. logError(0, "%s %s:Setting reset flags...\n",
  653. tag, __func__);
  654. setSystemResettedUp(1);
  655. setSystemResettedDown(1);
  656. }
  657. }
  658. find = 1;
  659. for (i = 0; i < event_bytes; i++) {
  660. if (event_to_search[i] != -1
  661. && (int)readData[i] != event_to_search[i]) {
  662. find = 0;
  663. break;
  664. }
  665. }
  666. retry++;
  667. msleep(TIMEOUT_RESOLUTION);
  668. }
  669. stopStopWatch(&clock);
  670. if ((retry >= time_to_count) && find != 1) {
  671. logError(0, "%s %s: ERROR %02X\n",
  672. tag, __func__, ERROR_TIMEOUT);
  673. return ERROR_TIMEOUT;
  674. }
  675. if (find == 1) {
  676. temp = printHex("FOUND EVENT = ", readData, FIFO_EVENT_SIZE);
  677. if (temp != NULL)
  678. logError(0, "%s %s", tag, temp);
  679. kfree(temp);
  680. logError(0, "%s Event found in %d ms (%d iterations)!\n",
  681. tag, elapsedMillisecond(&clock), retry);
  682. logError(0, "Number of errors found = %d\n", count_err);
  683. return count_err;
  684. }
  685. logError(0, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_R);
  686. return ERROR_I2C_R;
  687. }
  688. int flushFIFO(void)
  689. {
  690. u8 cmd = FIFO_CMD_FLUSH;
  691. if (fts_writeCmd(&cmd, 1) < 0) {
  692. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_W);
  693. return ERROR_I2C_W;
  694. }
  695. logError(0, "%s FIFO flushed!\n", tag);
  696. return OK;
  697. }
  698. int fts_disableInterrupt(void)
  699. {
  700. //disable interrupt
  701. u8 cmd[4] = { FTS_CMD_HW_REG_W, 0x00, 0x00, IER_DISABLE };
  702. u16ToU8_be(IER_ADDR, &cmd[1]);
  703. if (fts_writeCmd(cmd, 4) < OK) {
  704. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_W);
  705. return ERROR_I2C_W;
  706. }
  707. logError(0, "%s Interrupt Disabled!\n", tag);
  708. return OK;
  709. }
  710. int fts_enableInterrupt(void)
  711. {
  712. u8 cmd[4] = { FTS_CMD_HW_REG_W, 0x00, 0x00, IER_ENABLE };
  713. u16ToU8_be(IER_ADDR, &cmd[1]);
  714. if (fts_writeCmd(cmd, 4) < 0) {
  715. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_W);
  716. return ERROR_I2C_W;
  717. }
  718. logError(0, "%s Interrupt Enabled!\n", tag);
  719. return OK;
  720. }
  721. int u8ToU16n(u8 *src, int src_length, u16 *dst)
  722. {
  723. int i, j;
  724. u16 *buf;
  725. if (src_length % 2 != 0)
  726. return -EINVAL;
  727. j = 0;
  728. buf = (u16 *)kmalloc_array((src_length / 2), sizeof(u16), GFP_KERNEL);
  729. if (!buf) {
  730. dst = NULL;
  731. return -EINVAL;
  732. }
  733. dst = buf;
  734. for (i = 0; i < src_length; i += 2) {
  735. dst[j] = ((src[i+1] & 0x00FF) << 8) + (src[i] & 0x00FF);
  736. j++;
  737. }
  738. return (src_length / 2);
  739. }
  740. int u8ToU16(u8 *src, u16 *dst)
  741. {
  742. *dst = (u16)(((src[1] & 0x00FF) << 8) + (src[0] & 0x00FF));
  743. return 0;
  744. }
  745. int u8ToU16_le(u8 *src, u16 *dst)
  746. {
  747. *dst = (u16)(((src[0] & 0x00FF) << 8) + (src[1] & 0x00FF));
  748. return 0;
  749. }
  750. int u16ToU8n(u16 *src, int src_length, u8 *dst)
  751. {
  752. int i, j;
  753. u8 *buf = (u8 *)kmalloc_array(2 * src_length, sizeof(u8), GFP_KERNEL);
  754. if (!buf) {
  755. dst = NULL;
  756. return -EINVAL;
  757. }
  758. dst = buf;
  759. j = 0;
  760. for (i = 0; i < src_length; i++) {
  761. dst[j] = (u8) (src[i] & 0xFF00) >> 8;
  762. dst[j+1] = (u8) (src[i] & 0x00FF);
  763. j += 2;
  764. }
  765. return src_length * 2;
  766. }
  767. int u16ToU8(u16 src, u8 *dst)
  768. {
  769. dst[0] = (u8)((src & 0xFF00) >> 8);
  770. dst[1] = (u8)(src & 0x00FF);
  771. return 0;
  772. }
  773. int u16ToU8_be(u16 src, u8 *dst)
  774. {
  775. dst[0] = (u8)((src & 0xFF00) >> 8);
  776. dst[1] = (u8)(src & 0x00FF);
  777. return 0;
  778. }
  779. int u16ToU8_le(u16 src, u8 *dst)
  780. {
  781. dst[1] = (u8)((src & 0xFF00) >> 8);
  782. dst[0] = (u8)(src & 0x00FF);
  783. return 0;
  784. }
  785. int u8ToU32(u8 *src, u32 *dst)
  786. {
  787. *dst = (u32)(((src[3] & 0xFF) << 24) + ((src[2] & 0xFF) << 16)
  788. + ((src[1] & 0xFF) << 8) + (src[0] & 0xFF));
  789. return 0;
  790. }
  791. int u32ToU8(u32 src, u8 *dst)
  792. {
  793. dst[3] = (u8)((src & 0xFF000000) >> 24);
  794. dst[2] = (u8)((src & 0x00FF0000) >> 16);
  795. dst[1] = (u8)((src & 0x0000FF00) >> 8);
  796. dst[0] = (u8)(src & 0x000000FF);
  797. return 0;
  798. }
  799. int attempt_function(int(*code)(void), unsigned long wait_before_retry,
  800. int retry_count)
  801. {
  802. int result;
  803. int count = 0;
  804. do {
  805. result = code();
  806. count++;
  807. msleep(wait_before_retry);
  808. } while (count < retry_count && result < 0);
  809. if (count == retry_count)
  810. result |= ERROR_TIMEOUT;
  811. return result;
  812. }
  813. void setResetGpio(int gpio)
  814. {
  815. reset_gpio = gpio;
  816. logError(0, "%s %s: reset_gpio = %d\n", tag, __func__, reset_gpio);
  817. }
  818. int fts_system_reset(void)
  819. {
  820. u8 readData[FIFO_EVENT_SIZE];
  821. int event_to_search;
  822. int res = -1;
  823. int i;
  824. u8 cmd[4] = { FTS_CMD_HW_REG_W, 0x00, 0x00, SYSTEM_RESET_VALUE };
  825. event_to_search = (int)EVENTID_CONTROL_READY;
  826. u16ToU8_be(SYSTEM_RESET_ADDRESS, &cmd[1]);
  827. logError(0, "%s System resetting...\n", tag);
  828. for (i = 0; i < SYSTEM_RESET_RETRY && res < 0; i++) {
  829. if (reset_gpio == GPIO_NOT_DEFINED) {
  830. #ifndef FTM3_CHIP
  831. res |= fts_warm_boot();
  832. #endif
  833. res = fts_writeCmd(cmd, 4);
  834. } else {
  835. gpio_set_value(reset_gpio, 0);
  836. msleep(20);
  837. gpio_set_value(reset_gpio, 1);
  838. res = OK;
  839. }
  840. if (res < OK) {
  841. logError(1, "%s %s:ERROR %02X\n",
  842. tag, __func__, ERROR_I2C_W);
  843. } else {
  844. res = pollForEvent(&event_to_search, 1,
  845. readData, GENERAL_TIMEOUT);
  846. if (res < OK) {
  847. logError(0, "%s %s: ERROR %02X\n",
  848. tag, __func__, res);
  849. }
  850. }
  851. }
  852. if (res < OK) {
  853. logError(1, "%s %s:failed after 3 attempts: ERROR %02X\n",
  854. tag, __func__, (res | ERROR_SYSTEM_RESET_FAIL));
  855. res = (res | ERROR_SYSTEM_RESET_FAIL);
  856. } else {
  857. logError(0, "%s System reset DONE!\n", tag);
  858. system_resetted_down = 1;
  859. system_resetted_up = 1;
  860. res = OK;
  861. }
  862. return res;
  863. }
  864. int isSystemResettedDown(void)
  865. {
  866. return system_resetted_down;
  867. }
  868. int isSystemResettedUp(void)
  869. {
  870. return system_resetted_up;
  871. }
  872. void setSystemResettedDown(int val)
  873. {
  874. system_resetted_down = val;
  875. }
  876. void setSystemResettedUp(int val)
  877. {
  878. system_resetted_up = val;
  879. }
  880. int senseOn(void)
  881. {
  882. int ret;
  883. u8 cmd[1] = { FTS_CMD_MS_MT_SENSE_ON };
  884. ret = fts_writeFwCmd(cmd, 1);
  885. if (ret < OK) {
  886. logError(1, "%s %s:ERROR %02X\n",
  887. tag, __func__, ERROR_SENSE_ON_FAIL);
  888. return (ret|ERROR_SENSE_ON_FAIL);
  889. }
  890. logError(0, "%s %s: SENSE ON\n", tag, __func__);
  891. return OK;
  892. }
  893. int senseOff(void)
  894. {
  895. int ret;
  896. u8 cmd[1] = { FTS_CMD_MS_MT_SENSE_OFF };
  897. ret = fts_writeFwCmd(cmd, 1);
  898. if (ret < OK) {
  899. logError(1, "%s %s:ERROR %02X\n",
  900. tag, __func__, ERROR_SENSE_OFF_FAIL);
  901. return (ret | ERROR_SENSE_OFF_FAIL);
  902. }
  903. logError(0, "%s %s: SENSE OFF\n", tag, __func__);
  904. return OK;
  905. }
  906. int keyOn(void)
  907. {
  908. int ret;
  909. u8 cmd[1] = { FTS_CMD_MS_KEY_ON };
  910. ret = fts_writeFwCmd(cmd, 1);
  911. if (ret < OK) {
  912. logError(1, "%s %s:ERROR %02X\n",
  913. tag, __func__, ERROR_SENSE_ON_FAIL);
  914. return (ret | ERROR_SENSE_ON_FAIL);
  915. }
  916. logError(0, "%s %s: KEY ON\n", tag, __func__);
  917. return OK;
  918. }
  919. int keyOff(void)
  920. {
  921. int ret;
  922. u8 cmd[1] = { FTS_CMD_MS_KEY_OFF };
  923. ret = fts_writeFwCmd(cmd, 1);
  924. if (ret < OK) {
  925. logError(1, "%s %s:ERROR %02X\n",
  926. tag, __func__, ERROR_SENSE_OFF_FAIL);
  927. return (ret | ERROR_SENSE_OFF_FAIL);
  928. }
  929. logError(0, "%s %s: KEY OFF\n", tag, __func__);
  930. return OK;
  931. }
  932. int cleanUp(int enableTouch)
  933. {
  934. int res;
  935. logError(0, "%s %s: system reset...\n", tag, __func__);
  936. res = fts_system_reset();
  937. if (res < OK)
  938. return res;
  939. if (enableTouch) {
  940. logError(0, "%s %s:enabling touches...\n", tag, __func__);
  941. res = senseOn();
  942. if (res < OK)
  943. return res;
  944. #ifdef PHONE_KEY
  945. res = keyOn();
  946. if (res < OK)
  947. return res;
  948. #endif
  949. logError(0, "%s %s:enabling interrupts...\n", tag, __func__);
  950. res = fts_enableInterrupt();
  951. if (res < OK)
  952. return res;
  953. }
  954. return OK;
  955. }
  956. int checkEcho(u8 *cmd, int size)
  957. {
  958. int ret, i;
  959. int event_to_search[FIFO_EVENT_SIZE + 1];
  960. u8 readData[FIFO_EVENT_SIZE];
  961. if ((ftsInfo.u32_echoEn & 0x00000001) != ECHO_ENABLED) {
  962. logError(0, "%s ECHO Not Enabled!\n", tag);
  963. return OK;
  964. }
  965. if (size < 1) {
  966. logError(1, "%s:Error Size = %d not valid!", tag, size);
  967. logError(1, " or ECHO not Enabled!%08X\n", ERROR_OP_NOT_ALLOW);
  968. return ERROR_OP_NOT_ALLOW;
  969. }
  970. if ((size + 2) > FIFO_EVENT_SIZE)
  971. size = FIFO_EVENT_SIZE - 2;
  972. //Echo event EC xx xx xx xx xx xx
  973. //fifo_status therefore for command
  974. //with more than 6 bytes will echo only the first 6
  975. event_to_search[0] = EVENTID_ECHO;
  976. for (i = 1; i <= size; i++)
  977. event_to_search[i] = cmd[i - 1];
  978. ret = pollForEvent(event_to_search, size + 1,
  979. readData, GENERAL_TIMEOUT);
  980. if (ret < OK) {
  981. logError(1, "%s %s:Echo Event not found! ERROR %02X\n",
  982. tag, __func__, ret);
  983. return (ret | ERROR_CHECK_ECHO_FAIL);
  984. }
  985. logError(0, "%s ECHO OK!\n", tag);
  986. ret = OK;
  987. return ret;
  988. }
  989. int featureEnableDisable(int on_off, u32 feature)
  990. {
  991. int ret;
  992. u8 cmd[5];
  993. if (on_off == FEAT_ENABLE) {
  994. cmd[0] = FTS_CMD_FEATURE_ENABLE;
  995. logError(0, "%s %s: Enabling feature %08X ...\n",
  996. tag, __func__, feature);
  997. } else {
  998. cmd[0] = FTS_CMD_FEATURE_DISABLE;
  999. logError(0, "%s %s: Disabling feature %08X ...\n",
  1000. tag, __func__, feature);
  1001. }
  1002. u32ToU8(feature, &cmd[1]);
  1003. //not use writeFwCmd because this function can be
  1004. //called also during interrupt enable and should be fast
  1005. ret = fts_writeCmd(cmd, 5);
  1006. if (ret < OK) {
  1007. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ret);
  1008. return (ret | ERROR_FEATURE_ENABLE_DISABLE);
  1009. }
  1010. logError(0, "%s %s: DONE!\n", tag, __func__);
  1011. return OK;
  1012. }
  1013. int writeNoiseParameters(u8 *noise)
  1014. {
  1015. int ret, i;
  1016. u8 cmd[2+NOISE_PARAMETERS_SIZE];
  1017. u8 readData[FIFO_EVENT_SIZE];
  1018. int event_to_search[2] = {EVENTID_NOISE_WRITE, NOISE_PARAMETERS};
  1019. logError(0, "%s %s: Writing noise parameters to the IC ...\n",
  1020. tag, __func__);
  1021. ret = fts_disableInterrupt();
  1022. if (ret < OK) {
  1023. logError(1, "%s %s: ERROR %08X\n", tag, __func__, ret);
  1024. ret = (ret | ERROR_NOISE_PARAMETERS);
  1025. goto ERROR;
  1026. }
  1027. cmd[0] = FTS_CMD_NOISE_WRITE;
  1028. cmd[1] = NOISE_PARAMETERS;
  1029. logError(0, "%s %s: Noise parameters = ", tag, __func__);
  1030. for (i = 0; i < NOISE_PARAMETERS_SIZE; i++) {
  1031. cmd[2 + i] = noise[i];
  1032. logError(0, "%02X", cmd[2 + i]);
  1033. }
  1034. logError(0, "\n");
  1035. ret = fts_writeCmd(cmd, NOISE_PARAMETERS_SIZE + 2);
  1036. //not use writeFwCmd because this function should be fast
  1037. if (ret < OK) {
  1038. logError(0, "%s %s:impossible write command... ERROR %02X\n",
  1039. tag, __func__, ret);
  1040. ret = (ret | ERROR_NOISE_PARAMETERS);
  1041. goto ERROR;
  1042. }
  1043. ret = pollForEvent(event_to_search, 2, readData, GENERAL_TIMEOUT);
  1044. if (ret < OK) {
  1045. logError(0, "%s %s: polling FIFO ERROR %02X\n",
  1046. tag, __func__, ret);
  1047. ret = (ret | ERROR_NOISE_PARAMETERS);
  1048. goto ERROR;
  1049. }
  1050. if (readData[2] != 0x00) {
  1051. logError(1, "%s %s:Event check FAIL! %02X != 0x00 ERROR%02X\n",
  1052. tag, __func__, readData[2], ERROR_NOISE_PARAMETERS);
  1053. ret = ERROR_NOISE_PARAMETERS;
  1054. goto ERROR;
  1055. }
  1056. logError(0, "%s %s:DONE!\n", tag, __func__);
  1057. ret = OK;
  1058. ERROR:
  1059. ret = fts_enableInterrupt();
  1060. //ensure that the interrupt are always renabled when exit from funct
  1061. if (ret < OK) {
  1062. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ret);
  1063. return (ret | ERROR_NOISE_PARAMETERS);
  1064. }
  1065. return ret;
  1066. }
  1067. int readNoiseParameters(u8 *noise)
  1068. {
  1069. int ret, i;
  1070. u8 cmd[2];
  1071. u8 readData[FIFO_EVENT_SIZE];
  1072. int event_to_search[2] = {EVENTID_NOISE_READ, NOISE_PARAMETERS};
  1073. logError(0, "%s %s:Reading noise parameters from the IC ...\n",
  1074. tag, __func__);
  1075. ret = fts_disableInterrupt();
  1076. if (ret < OK) {
  1077. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ret);
  1078. ret = (ret | ERROR_NOISE_PARAMETERS);
  1079. goto ERROR;
  1080. }
  1081. cmd[0] = FTS_CMD_NOISE_READ;
  1082. cmd[1] = NOISE_PARAMETERS;
  1083. ret = fts_writeCmd(cmd, 2);//not use writeFwCmd should be fast
  1084. if (ret < OK) {
  1085. logError(0, "%s %s:impossible write command... ERROR %02X\n",
  1086. tag, __func__, ret);
  1087. ret = (ret | ERROR_NOISE_PARAMETERS);
  1088. goto ERROR;
  1089. }
  1090. ret = pollForEvent(event_to_search, 2, readData, GENERAL_TIMEOUT);
  1091. if (ret < OK) {
  1092. logError(0, "%s %s: polling FIFO ERROR %02X\n",
  1093. tag, __func__, ret);
  1094. ret = (ret | ERROR_NOISE_PARAMETERS);
  1095. goto ERROR;
  1096. }
  1097. logError(0, "%s %s: Noise parameters = ", tag, __func__);
  1098. for (i = 0; i < NOISE_PARAMETERS_SIZE; i++) {
  1099. noise[i] = readData[2 + i];
  1100. logError(0, "%02X ", noise[i]);
  1101. }
  1102. logError(0, "\n");
  1103. logError(0, "%s %s: DONE!\n", tag, __func__);
  1104. ret = OK;
  1105. ERROR:
  1106. ret = fts_enableInterrupt();
  1107. //ensure that the interrupt are always renabled when exit from funct
  1108. if (ret < OK) {
  1109. logError(1, "%s %s: ERROR %02X\n", tag, __func__, ret);
  1110. return (ret | ERROR_NOISE_PARAMETERS);
  1111. }
  1112. return ret;
  1113. }
  1114. short **array1dTo2d_short(short *data, int size, int columns)
  1115. {
  1116. int i;
  1117. int count = size / columns;
  1118. short **matrix = (short **)kmalloc_array(count,
  1119. sizeof(short *), GFP_KERNEL);
  1120. if (matrix != NULL) {
  1121. for (i = 0; i < count; i++) {
  1122. matrix[i] = (short *)kmalloc_array(columns,
  1123. sizeof(short), GFP_KERNEL);
  1124. }
  1125. for (i = 0; i < size; i++)
  1126. matrix[i / columns][i % columns] = data[i];
  1127. }
  1128. return matrix;
  1129. }
  1130. u8 **array1dTo2d_u8(u8 *data, int size, int columns)
  1131. {
  1132. int i;
  1133. int count = size / columns;
  1134. u8 **matrix = (u8 **)kmalloc_array(count,
  1135. sizeof(u8 *), GFP_KERNEL);
  1136. if (matrix != NULL) {
  1137. for (i = 0; i < count; i++) {
  1138. matrix[i] = (u8 *)kmalloc_array(columns,
  1139. sizeof(u8), GFP_KERNEL);
  1140. }
  1141. for (i = 0; i < size; i++)
  1142. matrix[i / columns][i % columns] = data[i];
  1143. }
  1144. return matrix;
  1145. }
  1146. void print_frame_short(char *label, short **matrix, int row, int column)
  1147. {
  1148. int i, j;
  1149. logError(0, "%s %s\n", tag, label);
  1150. for (i = 0; i < row; i++) {
  1151. logError(0, "%s ", tag);
  1152. for (j = 0; j < column; j++)
  1153. logError(0, "%d", matrix[i][j]);
  1154. logError(0, "\n");
  1155. kfree(matrix[i]);
  1156. }
  1157. kfree(matrix);
  1158. }
  1159. void print_frame_u8(char *label, u8 **matrix, int row, int column)
  1160. {
  1161. int i, j;
  1162. logError(0, "%s %s\n", tag, label);
  1163. for (i = 0; i < row; i++) {
  1164. logError(0, "%s ", tag);
  1165. for (j = 0; j < column; j++)
  1166. logError(0, "%d ", matrix[i][j]);
  1167. logError(0, "\n");
  1168. kfree(matrix[i]);
  1169. }
  1170. kfree(matrix);
  1171. }
  1172. void print_frame_u32(char *label, u32 **matrix, int row, int column)
  1173. {
  1174. int i, j;
  1175. logError(0, "%s %s\n", tag, label);
  1176. for (i = 0; i < row; i++) {
  1177. logError(0, "%s ", tag);
  1178. for (j = 0; j < column; j++)
  1179. logError(0, "%d ", matrix[i][j]);
  1180. logError(0, "\n");
  1181. kfree(matrix[i]);
  1182. }
  1183. kfree(matrix);
  1184. }
  1185. void print_frame_int(char *label, int **matrix, int row, int column)
  1186. {
  1187. int i, j;
  1188. logError(0, "%s %s\n", tag, label);
  1189. for (i = 0; i < row; i++) {
  1190. logError(0, "%s ", tag);
  1191. for (j = 0; j < column; j++)
  1192. logError(0, "%d ", matrix[i][j]);
  1193. logError(0, "\n");
  1194. kfree(matrix[i]);
  1195. }
  1196. kfree(matrix);
  1197. }