ftsGesture.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * FTS Capacitive touch screen controller (FingerTipS)
  4. *
  5. * Copyright (C) 2016-2019, STMicroelectronics Limited.
  6. * Authors: AMG(Analog Mems Group) <[email protected]>
  7. *
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License version 2 as published by
  11. * the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful, but WITHOUT
  14. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  16. * more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along with
  19. * this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. *
  23. **************************************************************************
  24. ** STMicroelectronics **
  25. **************************************************************************
  26. ** [email protected] **
  27. **************************************************************************
  28. * *
  29. * FTS Gesture Utilities *
  30. * *
  31. **************************************************************************
  32. **************************************************************************
  33. */
  34. #include "ftsSoftware.h"
  35. #include "ftsError.h"
  36. #include "ftsGesture.h"
  37. #include "ftsIO.h"
  38. #include "ftsTool.h"
  39. static char tag[8] = "[ FTS ]\0";
  40. static u8 gesture_mask[GESTURE_MASK_SIZE] = { 0 };
  41. static u8 custom_gestures[GESTURE_CUSTOM_NUMBER][GESTURE_CUSTOM_POINTS];
  42. static u8 custom_gesture_index[GESTURE_CUSTOM_NUMBER] = { 0 };
  43. static int refreshGestureMask;
  44. u16 gesture_coordinates_x[GESTURE_COORDS_REPORT_MAX] = {0};
  45. u16 gesture_coordinates_y[GESTURE_COORDS_REPORT_MAX] = {0};
  46. int gesture_coords_reported = ERROR_OP_NOT_ALLOW;
  47. struct mutex gestureMask_mutex;
  48. int updateGestureMask(u8 *mask, int size, int en)
  49. {
  50. u8 temp;
  51. int i;
  52. if (mask == NULL) {
  53. logError(1, "%s %s: Mask NULL! ERROR %08X\n",
  54. tag, __func__, ERROR_OP_NOT_ALLOW);
  55. return ERROR_OP_NOT_ALLOW;
  56. }
  57. if (size > GESTURE_MASK_SIZE) {
  58. logError(1, "%s %s:Size not valid! %d > %d ERROR %08X\n",
  59. tag, __func__, size, GESTURE_MASK_SIZE);
  60. return ERROR_OP_NOT_ALLOW;
  61. }
  62. if (en == FEAT_ENABLE) {
  63. mutex_lock(&gestureMask_mutex);
  64. logError(0, "%s %s:setting gesture mask to enable..\n",
  65. tag, __func__);
  66. if (mask != NULL) {
  67. for (i = 0; i < size; i++) {
  68. //back up the gesture enabled
  69. gesture_mask[i] = gesture_mask[i] | mask[i];
  70. }
  71. }
  72. refreshGestureMask = 1;
  73. logError(0, "%s %s:gesture mask to enable SET!\n",
  74. tag, __func__);
  75. mutex_unlock(&gestureMask_mutex);
  76. return OK;
  77. }
  78. if (en == FEAT_DISABLE) {
  79. mutex_lock(&gestureMask_mutex);
  80. logError(0, "%s %s:setting gesture ", tag, __func__);
  81. logError(0, "mask to disable...\n");
  82. for (i = 0; i < size; i++) {
  83. // enabled XOR disabled
  84. temp = gesture_mask[i] ^ mask[i];
  85. gesture_mask[i] = temp & gesture_mask[i];
  86. }
  87. logError(0, "%s %s:gesture mask to disable SET!\n",
  88. tag, __func__);
  89. refreshGestureMask = 1;
  90. mutex_unlock(&gestureMask_mutex);
  91. return OK;
  92. }
  93. logError(1, "%s%s:Enable parameter Invalid%d!=%d or%d%:08X",
  94. tag, __func__, FEAT_DISABLE,
  95. FEAT_ENABLE, ERROR_OP_NOT_ALLOW);
  96. return ERROR_OP_NOT_ALLOW;
  97. }
  98. int enableGesture(u8 *mask, int size)
  99. {
  100. u8 cmd[GESTURE_MASK_SIZE + 2];
  101. u8 readData[FIFO_EVENT_SIZE] = {0};
  102. int i, res;
  103. int event_to_search[4] = { EVENTID_GESTURE,
  104. EVENT_TYPE_ENB, 0x00, GESTURE_ENABLE };
  105. logError(0, "%s Trying to enable gesture...\n", tag);
  106. cmd[0] = FTS_CMD_GESTURE_CMD;
  107. cmd[1] = GESTURE_ENABLE;
  108. if (size > GESTURE_MASK_SIZE) {
  109. logError(1, "%s %s: Size not valid! %d > %d ERROR %08X\n",
  110. tag, __func__, size, GESTURE_MASK_SIZE);
  111. return ERROR_OP_NOT_ALLOW;
  112. }
  113. mutex_lock(&gestureMask_mutex);
  114. if (mask != NULL) {
  115. for (i = 0; i < size; i++) {
  116. cmd[i + 2] = mask[i];
  117. //back up of the gesture enabled
  118. gesture_mask[i] = gesture_mask[i] | mask[i];
  119. }
  120. while (i < GESTURE_MASK_SIZE) {
  121. cmd[i + 2] = gesture_mask[i];
  122. i++;
  123. }
  124. } else {
  125. for (i = 0; i < GESTURE_MASK_SIZE; i++)
  126. cmd[i + 2] = gesture_mask[i];
  127. }
  128. res = fts_writeFwCmd(cmd, GESTURE_MASK_SIZE + 2);
  129. if (res < OK) {
  130. logError(1, "%s %s: ERROR %08X\n", tag, __func__, res);
  131. goto END;
  132. }
  133. res = pollForEvent(event_to_search, 4,
  134. readData, GENERAL_TIMEOUT);
  135. if (res < OK) {
  136. logError(1, "%s %s: pollForEvent ERROR %08X\n",
  137. tag, __func__, res);
  138. goto END;
  139. }
  140. if (readData[4] != 0x00) {
  141. logError(1, "%s %s: ERROR %08X\n",
  142. tag, __func__, ERROR_GESTURE_ENABLE_FAIL);
  143. res = ERROR_GESTURE_ENABLE_FAIL;
  144. goto END;
  145. }
  146. logError(0, "%s %s: DONE!\n", tag, __func__);
  147. res = OK;
  148. END:
  149. mutex_unlock(&gestureMask_mutex);
  150. return res;
  151. }
  152. int disableGesture(u8 *mask, int size)
  153. {
  154. u8 cmd[2 + GESTURE_MASK_SIZE];
  155. u8 readData[FIFO_EVENT_SIZE] = {0};
  156. u8 temp;
  157. int i, res;
  158. int event_to_search[4] = { EVENTID_GESTURE,
  159. EVENT_TYPE_ENB, 0x00, GESTURE_DISABLE };
  160. logError(0, "%s Trying to disable gesture...\n", tag);
  161. cmd[0] = FTS_CMD_GESTURE_CMD;
  162. cmd[1] = GESTURE_DISABLE;
  163. if (size > GESTURE_MASK_SIZE) {
  164. logError(1, "%s %s: Size not valid! %d > %d ERROR %08X\n",
  165. tag, __func__, size, GESTURE_MASK_SIZE);
  166. return ERROR_OP_NOT_ALLOW;
  167. }
  168. mutex_lock(&gestureMask_mutex);
  169. if (mask != NULL) {
  170. for (i = 0; i < size; i++) {
  171. cmd[i + 2] = mask[i];
  172. // enabled XOR disabled
  173. temp = gesture_mask[i] ^ mask[i];
  174. gesture_mask[i] = temp & gesture_mask[i];
  175. }
  176. while (i < GESTURE_MASK_SIZE) {
  177. //cmd[i + 2] = gesture_mask[i];
  178. //gesture_mask[i] = 0x00;
  179. cmd[i + 2] = 0x00;
  180. //leave untouched the gestures not specified
  181. i++;
  182. }
  183. } else {
  184. for (i = 0; i < GESTURE_MASK_SIZE; i++) {
  185. //cmd[i + 2] = gesture_mask[i];
  186. cmd[i + 2] = 0xFF;
  187. }
  188. }
  189. res = fts_writeFwCmd(cmd, 2 + GESTURE_MASK_SIZE);
  190. if (res < OK) {
  191. logError(1, "%s %s:ERROR %08X\n", tag, __func__, res);
  192. goto END;
  193. }
  194. res = pollForEvent(event_to_search, 4, readData, GENERAL_TIMEOUT);
  195. if (res < OK) {
  196. logError(1, "%s %s: pollForEvent ERROR %08X\n",
  197. tag, __func__, res);
  198. goto END;
  199. }
  200. if (readData[4] != 0x00) {
  201. logError(1, "%s %s:ERROR %08X\n",
  202. tag, __func__, ERROR_GESTURE_ENABLE_FAIL);
  203. res = ERROR_GESTURE_ENABLE_FAIL;
  204. goto END;
  205. }
  206. logError(0, "%s %s: DONE!\n", tag, __func__);
  207. res = OK;
  208. END:
  209. mutex_unlock(&gestureMask_mutex);
  210. return res;
  211. }
  212. int startAddCustomGesture(u8 gestureID)
  213. {
  214. u8 cmd[3] = { FTS_CMD_GESTURE_CMD, GESTURE_START_ADD, gestureID };
  215. int res;
  216. u8 readData[FIFO_EVENT_SIZE] = {0};
  217. int event_to_search[4] = { EVENTID_GESTURE, EVENT_TYPE_ENB,
  218. gestureID, GESTURE_START_ADD };
  219. res = fts_writeFwCmd(cmd, 3);
  220. if (res < OK) {
  221. logError(1,
  222. "%s%s:Impossible to start adding custom gesture ID:%02X %08X\n",
  223. tag, __func__, gestureID, res);
  224. return res;
  225. }
  226. res = pollForEvent(event_to_search, 4, readData, GENERAL_TIMEOUT);
  227. if (res < OK) {
  228. logError(1, "%s %s:start add event not found! ERROR %08X\n",
  229. tag, __func__, res);
  230. return res;
  231. }
  232. //check of gestureID is redundant
  233. if (readData[2] != gestureID || readData[4] != 0x00) {
  234. logError(1, "%s %s:start add event status not OK! ERROR %08X\n",
  235. tag, __func__, readData[4]);
  236. return ERROR_GESTURE_START_ADD;
  237. }
  238. return OK;
  239. }
  240. int finishAddCustomGesture(u8 gestureID)
  241. {
  242. u8 cmd[3] = { FTS_CMD_GESTURE_CMD,
  243. GESTURE_FINISH_ADD, gestureID };
  244. int res;
  245. u8 readData[FIFO_EVENT_SIZE] = {0};
  246. int event_to_search[4] = { EVENTID_GESTURE, EVENT_TYPE_ENB,
  247. gestureID, GESTURE_FINISH_ADD };
  248. res = fts_writeFwCmd(cmd, 3);
  249. if (res < OK) {
  250. logError(1,
  251. "%s%s:Impossible to finish adding custom gestureID:%02X %08X\n",
  252. tag, __func__, gestureID, res);
  253. return res;
  254. }
  255. res = pollForEvent(event_to_search, 4, readData, GENERAL_TIMEOUT);
  256. if (res < OK) {
  257. logError(1, "%s %s: finish add event not found! ERROR %08X\n",
  258. tag, __func__, res);
  259. return res;
  260. }
  261. //check of gestureID is redundant
  262. if (readData[2] != gestureID || readData[4] != 0x00) {
  263. logError(1,
  264. "%s %s:finish add event status not OK! ERROR %08X\n",
  265. tag, __func__, readData[4]);
  266. return ERROR_GESTURE_FINISH_ADD;
  267. }
  268. return OK;
  269. }
  270. int loadCustomGesture(u8 *template, u8 gestureID)
  271. {
  272. int res, i, wheel;
  273. int remaining = GESTURE_CUSTOM_POINTS;
  274. int toWrite, offset = 0;
  275. u8 cmd[TEMPLATE_CHUNK + 5];
  276. int event_to_search[4] = { EVENTID_GESTURE, EVENT_TYPE_ENB,
  277. gestureID, GESTURE_DATA_ADD };
  278. u8 readData[FIFO_EVENT_SIZE] = {0};
  279. logError(0, "%s Starting adding custom gesture procedure...\n", tag);
  280. res = startAddCustomGesture(gestureID);
  281. if (res < OK) {
  282. logError(1, "%s %s:unable to start adding procedure %08X\n",
  283. tag, __func__, res);
  284. return res;
  285. }
  286. cmd[0] = FTS_CMD_GESTURE_CMD;
  287. cmd[1] = GESTURE_DATA_ADD;
  288. cmd[2] = gestureID;
  289. wheel = 0;
  290. while (remaining > 0) {
  291. if (remaining > TEMPLATE_CHUNK)
  292. toWrite = TEMPLATE_CHUNK;
  293. else
  294. toWrite = remaining;
  295. cmd[3] = toWrite;
  296. cmd[4] = offset;
  297. for (i = 0; i < toWrite; i++)
  298. cmd[i + 5] = template[wheel++];
  299. res = fts_writeFwCmd(cmd, toWrite + 5);
  300. if (res < OK) {
  301. logError(1, "%s %s:unable to start ", tag, __func__);
  302. logError(1, "adding procedure %08X\n", res);
  303. return res;
  304. }
  305. res = pollForEvent(event_to_search,
  306. 4,
  307. readData,
  308. GENERAL_TIMEOUT);
  309. if (res < OK) {
  310. logError(1, "%s %s: add event not found! ERROR %08X\n",
  311. tag, __func__, res);
  312. return res;
  313. }
  314. //check of gestureID is redundant
  315. if (readData[2] != gestureID || readData[4] != 0x00) {
  316. logError(1, "%s %s:add event status not OK! ",
  317. tag, __func__);
  318. logError(1, "ERROR %08X\n", readData[4]);
  319. return ERROR_GESTURE_DATA_ADD;
  320. }
  321. remaining -= toWrite;
  322. offset += toWrite / 2;
  323. }
  324. res = finishAddCustomGesture(gestureID);
  325. if (res < OK) {
  326. logError(1, "%s %s:unable to finish adding procedure! ",
  327. tag, __func__);
  328. logError(1, "ERROR %08X\n", res);
  329. return res;
  330. }
  331. logError(0, "%s Adding custom gesture procedure DONE!\n", tag);
  332. return OK;
  333. }
  334. int reloadCustomGesture(void)
  335. {
  336. int res, i;
  337. logError(0, "%s Starting reload Gesture Template...\n", tag);
  338. for (i = 0; i < GESTURE_CUSTOM_NUMBER; i++) {
  339. if (custom_gesture_index[i] == 1) {
  340. res = loadCustomGesture(custom_gestures[i],
  341. GESTURE_CUSTOM_OFFSET + i);
  342. if (res < OK) {
  343. logError(1, "%s %s:Impossible load gesture ",
  344. tag, __func__);
  345. logError(1, "D:%02X %08X\n",
  346. GESTURE_CUSTOM_OFFSET + i, res);
  347. return res;
  348. }
  349. }
  350. }
  351. logError(0, "%s Reload Gesture Template DONE!\n", tag);
  352. return OK;
  353. }
  354. int enterGestureMode(int reload)
  355. {
  356. u8 cmd = FTS_CMD_GESTURE_MODE;
  357. int res, ret;
  358. res = fts_disableInterrupt();
  359. if (res < OK) {
  360. logError(1, "%s %s: ERROR %08X\n",
  361. tag, __func__, res | ERROR_DISABLE_INTER);
  362. return res | ERROR_DISABLE_INTER;
  363. }
  364. if (reload == 1 || refreshGestureMask == 1) {
  365. if (reload == 1) {
  366. res = reloadCustomGesture();
  367. if (res < OK) {
  368. logError(1, "%s %s:impossible reload ",
  369. tag, __func__);
  370. logError(1, "custom gesture %08X\n", res);
  371. goto END;
  372. }
  373. }
  374. /**
  375. * mandatory steps to set the correct gesture
  376. * mask defined by the user
  377. */
  378. res = disableGesture(NULL, 0);
  379. if (res < OK) {
  380. logError(1, "%s %s:disableGesture ERROR %08X\n",
  381. tag, res);
  382. goto END;
  383. }
  384. res = enableGesture(NULL, 0);
  385. if (res < OK) {
  386. logError(1, "%s %s:enableGesture ERROR %08X\n",
  387. tag, __func__, res);
  388. goto END;
  389. }
  390. refreshGestureMask = 0;
  391. /**************************************************/
  392. }
  393. res = fts_writeFwCmd(&cmd, 1);
  394. if (res < OK) {
  395. logError(1, "%s %s:enter gesture mode ERROR %08X\n",
  396. tag, __func__, res);
  397. goto END;
  398. }
  399. res = OK;
  400. END:
  401. ret = fts_enableInterrupt();
  402. if (ret < OK) {
  403. logError(1, "%s %s:fts_enableInterrupt ERROR %08X\n",
  404. tag, __func__, res | ERROR_ENABLE_INTER);
  405. res |= ret | ERROR_ENABLE_INTER;
  406. }
  407. return res;
  408. }
  409. int addCustomGesture(u8 *data, int size, u8 gestureID)
  410. {
  411. int index, res, i;
  412. index = gestureID - GESTURE_CUSTOM_OFFSET;
  413. logError(0, "%s Starting Custom Gesture Adding procedure...\n", tag);
  414. if (size != GESTURE_CUSTOM_POINTS || (gestureID != GES_ID_CUST1
  415. && gestureID != GES_ID_CUST2 && gestureID != GES_ID_CUST3
  416. && gestureID != GES_ID_CUST4 && gestureID != GES_ID_CUST5)) {
  417. logError(1, "%s %s:Invalid size(%d) or Custom GestureID ",
  418. tag, __func__, size);
  419. logError(1, "(%02X)!ERROR%08X\n",
  420. size, gestureID, ERROR_OP_NOT_ALLOW);
  421. return ERROR_OP_NOT_ALLOW;
  422. }
  423. for (i = 0; i < GESTURE_CUSTOM_POINTS; i++)
  424. custom_gestures[index][i] = data[i];
  425. res = loadCustomGesture(custom_gestures[index], gestureID);
  426. if (res < OK) {
  427. logError(1, "%s %s:impossible to load the custom gesture! ",
  428. tag, __func__);
  429. logError(1, "ERROR %08X\n", res);
  430. return res;
  431. }
  432. custom_gesture_index[index] = 1;
  433. logError(0, "%s Custom Gesture Adding procedure DONE!\n", tag);
  434. return OK;
  435. }
  436. int removeCustomGesture(u8 gestureID)
  437. {
  438. int res, index;
  439. u8 cmd[3] = { FTS_CMD_GESTURE_CMD, GETURE_REMOVE_CUSTOM, gestureID };
  440. int event_to_search[4] = { EVENTID_GESTURE, EVENT_TYPE_ENB,
  441. gestureID, GETURE_REMOVE_CUSTOM };
  442. u8 readData[FIFO_EVENT_SIZE] = {0};
  443. index = gestureID - GESTURE_CUSTOM_OFFSET;
  444. logError(0, "%s Starting Custom Gesture Removing procedure...\n", tag);
  445. if (gestureID != GES_ID_CUST1 && gestureID != GES_ID_CUST2 &&
  446. gestureID != GES_ID_CUST3 && gestureID !=
  447. GES_ID_CUST4 && gestureID != GES_ID_CUST5) {
  448. logError(1, "%s %s:Invalid Custom GestureID (%02X)! ",
  449. tag, __func__, gestureID);
  450. logError(1, "ERROR %08X\n", ERROR_OP_NOT_ALLOW);
  451. return ERROR_OP_NOT_ALLOW;
  452. }
  453. //when a gesture is removed, it is also disabled automatically
  454. res = fts_writeFwCmd(cmd, 3);
  455. if (res < OK) {
  456. logError(1, "%s %s:Impossible to remove custom ",
  457. tag, __func__);
  458. logError(1, "%gesture ID:%02X %08X\n", gestureID, res);
  459. return res;
  460. }
  461. res = pollForEvent(event_to_search, 4, readData, GENERAL_TIMEOUT);
  462. if (res < OK) {
  463. logError(1, "%s %s:remove event not found! ERROR %08X\n",
  464. tag, __func__, res);
  465. return res;
  466. }
  467. //check of gestureID is redundant
  468. if (readData[2] != gestureID || readData[4] != 0x00) {
  469. logError(1, "%s %s:remove event status not OK! ERROR %08X\n",
  470. tag, __func__, readData[4]);
  471. return ERROR_GESTURE_REMOVE;
  472. }
  473. custom_gesture_index[index] = 0;
  474. logError(0, "%s Custom Gesture Remove procedure DONE!\n", tag);
  475. return OK;
  476. }
  477. int isAnyGestureActive(void)
  478. {
  479. int res = 0;
  480. /*-1 because in any case the last gesture mask byte will*/
  481. /*be evaluated with the following if*/
  482. while (res < (GESTURE_MASK_SIZE - 1) && gesture_mask[res] == 0)
  483. res++;
  484. if (gesture_mask[res] == 0) {
  485. logError(0, "%s %s: All Gestures Disabled!\n", tag, __func__);
  486. return FEAT_DISABLE;
  487. }
  488. logError(0, "%s %s:Active Gestures Found! gesture_mask[%d] = %02X!\n",
  489. tag, __func__, res, gesture_mask[res]);
  490. return FEAT_ENABLE;
  491. }
  492. int gestureIDtoGestureMask(u8 id, u8 *mask)
  493. {
  494. logError(0, "%s %s: Index = %d Position = %d!\n",
  495. tag, __func__, ((int)((id) / 8)), (id % 8));
  496. mask[((int)((id) / 8))] |= 0x01 << (id % 8);
  497. return OK;
  498. }
  499. int readGestureCoords(u8 *event)
  500. {
  501. int i = 0;
  502. u8 rCmd[3] = {FTS_CMD_FRAMEBUFFER_R, 0x00, 0x00 };
  503. int res;
  504. unsigned char val[GESTURE_COORDS_REPORT_MAX * 4 + 1];
  505. //the max coordinates to read are GESTURE_COORDS_REPORT_MAX*4
  506. //(because each coordinate is a short(*2) and we have x and y)
  507. //+ dummy byte
  508. if (event[0] != EVENTID_GESTURE
  509. || event[1] != EVENT_TYPE_GESTURE_DTC2) {
  510. logError(1, "%s %s:The event passsed as argument is invalid! ",
  511. tag, __func__);
  512. logError(1, "ERROR %08X\n", ERROR_OP_NOT_ALLOW);
  513. return ERROR_OP_NOT_ALLOW;
  514. }
  515. rCmd[1] = event[4]; // Offset address L
  516. rCmd[2] = event[3]; // Offset address H
  517. //number of coords reported L
  518. gesture_coords_reported = event[6];
  519. //number of coords reported H
  520. gesture_coords_reported = (gesture_coords_reported << 8) | event[5];
  521. if (gesture_coords_reported > GESTURE_COORDS_REPORT_MAX) {
  522. logError(1, "%s%s:FW reported more than:%d points ",
  523. tag, __func__, gesture_coords_reported);
  524. logError(1, "for gestures!\n");
  525. logError(1, " Decreasing to %d\n", GESTURE_COORDS_REPORT_MAX);
  526. gesture_coords_reported = GESTURE_COORDS_REPORT_MAX;
  527. }
  528. logError(1, "%s %s: Offset: %02X %02X points = %d\n", tag,
  529. __func__, rCmd[1], rCmd[2], gesture_coords_reported);
  530. res = fts_readCmd(rCmd, 3, (unsigned char *)val,
  531. 1 + (gesture_coords_reported * 2));
  532. if (res < OK) {
  533. logError(1, "%s %s: Cannot read the coordinates! ERROR %08X\n",
  534. tag, __func__, res);
  535. gesture_coords_reported = ERROR_OP_NOT_ALLOW;
  536. return res;
  537. }
  538. //all the points of the gesture are stored in val
  539. for (i = 0; i < gesture_coords_reported; i++) {
  540. //ignore first byte data because it is a dummy byte
  541. gesture_coordinates_x[i] = (((u16) val[i * 2 + 1 + 1])
  542. & 0x0F) << 8 | (((u16) val[i * 2 + 1]) & 0xFF);
  543. gesture_coordinates_y[i] =
  544. (((u16)val[gesture_coords_reported * 2
  545. + i * 2 + 1 + 1]) & 0x0F) << 8
  546. | (((u16)val[gesture_coords_reported * 2
  547. + i * 2 + 1]) & 0xFF);
  548. }
  549. logError(1, "%s %s: Reading Gesture Coordinates DONE!\n",
  550. tag, __func__);
  551. return OK;
  552. }
  553. int getGestureCoords(u16 *x, u16 *y)
  554. {
  555. x = gesture_coordinates_x;
  556. y = gesture_coordinates_y;
  557. logError(1, "%s %s:Number of gesture coordinates returned = %d\n",
  558. tag, __func__, gesture_coords_reported);
  559. return gesture_coords_reported;
  560. }