fpc1020_capture.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. /* FPC1020 Touch sensor driver
  2. *
  3. * Copyright (c) 2013,2014 Fingerprint Cards AB <tech@fingerprints.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License Version 2
  7. * as published by the Free Software Foundation.
  8. */
  9. #define DEBUG
  10. #include <linux/input.h>
  11. #include <linux/delay.h>
  12. #include <linux/time.h>
  13. #ifndef CONFIG_OF
  14. #include <linux/spi/fpc1020_common.h>
  15. #include <linux/spi/fpc1020_capture.h>
  16. #else
  17. #include "fpc1020_common.h"
  18. #include "fpc1020_capture.h"
  19. #endif
  20. /* -------------------------------------------------------------------- */
  21. /* function prototypes */
  22. /* -------------------------------------------------------------------- */
  23. static size_t fpc1020_calc_image_size(fpc1020_data_t *fpc1020);
  24. /* -------------------------------------------------------------------- */
  25. /* function definitions */
  26. /* -------------------------------------------------------------------- */
  27. int fpc1020_init_capture(fpc1020_data_t *fpc1020)
  28. {
  29. fpc1020->capture.state = FPC1020_CAPTURE_STATE_IDLE;
  30. fpc1020->capture.current_mode = FPC1020_MODE_IDLE;
  31. fpc1020->capture.available_bytes = 0;
  32. fpc1020->capture.deferred_finger_up = false;
  33. init_waitqueue_head(&fpc1020->capture.wq_data_avail);
  34. return 0;
  35. }
  36. /* -------------------------------------------------------------------- */
  37. int fpc1020_write_capture_setup(fpc1020_data_t *fpc1020)
  38. {
  39. return fpc1020_write_sensor_setup(fpc1020);
  40. }
  41. /* -------------------------------------------------------------------- */
  42. int fpc1020_write_test_setup(fpc1020_data_t *fpc1020, u16 pattern)
  43. {
  44. int error = 0;
  45. u8 config = 0x04;
  46. fpc1020_reg_access_t reg;
  47. dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, pattern);
  48. error = fpc1020_write_sensor_setup(fpc1020);
  49. if (error)
  50. goto out;
  51. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &pattern);
  52. error = fpc1020_reg_access(fpc1020, &reg);
  53. if (error)
  54. goto out;
  55. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &config);
  56. error = fpc1020_reg_access(fpc1020, &reg);
  57. if (error)
  58. goto out;
  59. error = fpc1020_capture_settings(fpc1020, 0);
  60. if (error)
  61. goto out;
  62. out:
  63. return error;
  64. }
  65. /* -------------------------------------------------------------------- */
  66. int fpc1020_write_cb_test_setup_102x(fpc1020_data_t *fpc1020, bool invert)
  67. {
  68. int error = 0;
  69. u8 temp_u8;
  70. u16 temp_u16;
  71. u64 temp_u64;
  72. fpc1020_reg_access_t reg;
  73. temp_u16 = (invert) ? 0x55aa : 0xaa55;
  74. dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, temp_u16);
  75. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16);
  76. error = fpc1020_reg_access(fpc1020, &reg);
  77. if (error)
  78. goto out;
  79. temp_u8 = 0x04;
  80. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8);
  81. error = fpc1020_reg_access(fpc1020, &reg);
  82. if (error)
  83. goto out;
  84. temp_u16 = (invert) ? 0x0f1b : 0x0f0f;
  85. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16);
  86. error = fpc1020_reg_access(fpc1020, &reg);
  87. if (error)
  88. goto out;
  89. temp_u16 = (invert) ? 0x0800 : 0x00;
  90. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16);
  91. error = fpc1020_reg_access(fpc1020, &reg);
  92. if (error)
  93. goto out;
  94. temp_u8 = 0x14;
  95. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8);
  96. error = fpc1020_reg_access(fpc1020, &reg);
  97. if (error)
  98. goto out;
  99. temp_u8 = 0x20;
  100. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8);
  101. error = fpc1020_reg_access(fpc1020, &reg);
  102. if (error)
  103. goto out;
  104. temp_u64 = 0x1e1e1e1e2d2d2d2d;
  105. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64);
  106. error = fpc1020_reg_access(fpc1020, &reg);
  107. if (error)
  108. goto out;
  109. out:
  110. return error;
  111. }
  112. /* -------------------------------------------------------------------- */
  113. int fpc1020_write_cb_test_setup_1155(fpc1020_data_t *fpc1020, bool invert)
  114. {
  115. int error = 0;
  116. u8 temp_u8;
  117. u16 temp_u16;
  118. u64 temp_u64;
  119. fpc1020_reg_access_t reg;
  120. temp_u16 = (invert) ? 0x55aa : 0xaa55;
  121. dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, temp_u16);
  122. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16);
  123. error = fpc1020_reg_access(fpc1020, &reg);
  124. if (error)
  125. goto out;
  126. temp_u8 = 0x14;
  127. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8);
  128. error = fpc1020_reg_access(fpc1020, &reg);
  129. if (error)
  130. goto out;
  131. temp_u16 = (invert) ? 0x0f1a : 0x0f0e;
  132. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16);
  133. error = fpc1020_reg_access(fpc1020, &reg);
  134. if (error)
  135. goto out;
  136. temp_u16 = (invert) ? 0x0800 : 0x0000;
  137. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16);
  138. error = fpc1020_reg_access(fpc1020, &reg);
  139. if (error)
  140. goto out;
  141. temp_u8 = 0x2f;
  142. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8);
  143. error = fpc1020_reg_access(fpc1020, &reg);
  144. if (error)
  145. goto out;
  146. temp_u8 = 0x38;
  147. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8);
  148. error = fpc1020_reg_access(fpc1020, &reg);
  149. if (error)
  150. goto out;
  151. temp_u64 = 0x373737373f3f3f3f;
  152. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64);
  153. error = fpc1020_reg_access(fpc1020, &reg);
  154. if (error)
  155. goto out;
  156. temp_u64 = 0x5540002d24;
  157. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SETUP, &temp_u64);
  158. error = fpc1020_reg_access(fpc1020, &reg);
  159. if (error)
  160. goto out;
  161. out:
  162. return error;
  163. }
  164. /* -------------------------------------------------------------------- */
  165. int fpc1020_write_cb_test_setup_1022(fpc1020_data_t *fpc1020, bool invert)
  166. {
  167. int error = 0;
  168. u8 temp_u8;
  169. u16 temp_u16;
  170. /*u64 temp_u64;*/
  171. fpc1020_reg_access_t reg;
  172. temp_u16 = (invert) ? 0x55aa : 0xaa55;
  173. dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, temp_u16);
  174. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16);
  175. error = fpc1020_reg_access(fpc1020, &reg);
  176. if (error)
  177. goto out;
  178. temp_u8 = 0x04;
  179. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8);
  180. error = fpc1020_reg_access(fpc1020, &reg);
  181. if (error)
  182. goto out;
  183. temp_u16 = (invert) ? 0x0f1b : 0x0f0f;
  184. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16);
  185. error = fpc1020_reg_access(fpc1020, &reg);
  186. if (error)
  187. goto out;
  188. temp_u16 = (invert) ? 0x0800 : 0x00;
  189. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16);
  190. error = fpc1020_reg_access(fpc1020, &reg);
  191. if (error)
  192. goto out;
  193. out:
  194. return error;
  195. }
  196. /* -------------------------------------------------------------------- */
  197. int fpc1020_write_cb_test_setup_1145(fpc1020_data_t *fpc1020, bool invert)
  198. {
  199. return fpc1020_write_cb_test_setup_1155(fpc1020, invert);
  200. }
  201. /* -------------------------------------------------------------------- */
  202. int fpc1020_write_cb_test_setup(fpc1020_data_t *fpc1020, bool invert)
  203. {
  204. int error = 0;
  205. switch (fpc1020->chip.type) {
  206. case FPC1020_CHIP_1035X:
  207. case FPC1020_CHIP_1022X:
  208. error = fpc1020_write_cb_test_setup_1022(fpc1020, invert);
  209. break;
  210. case FPC1020_CHIP_1155X:
  211. error = fpc1020_write_cb_test_setup_1155(fpc1020, invert);
  212. break;
  213. case FPC1020_CHIP_1145X:
  214. error = fpc1020_write_cb_test_setup_1145(fpc1020, invert);
  215. break;
  216. default:
  217. error = fpc1020_write_cb_test_setup_102x(fpc1020, invert);
  218. break;
  219. }
  220. return error;
  221. }
  222. /* -------------------------------------------------------------------- */
  223. bool fpc1020_capture_check_ready(fpc1020_data_t *fpc1020)
  224. {
  225. fpc1020_capture_state_t state = fpc1020->capture.state;
  226. return (state == FPC1020_CAPTURE_STATE_IDLE) ||
  227. (state == FPC1020_CAPTURE_STATE_COMPLETED) ||
  228. (state == FPC1020_CAPTURE_STATE_FAILED);
  229. }
  230. /* -------------------------------------------------------------------- */
  231. int fpc1020_capture_task(fpc1020_data_t *fpc1020)
  232. {
  233. struct timespec ts_t1, ts_t2, ts_t3, ts_delta;
  234. int time_settings_us[FPC1020_BUFFER_MAX_IMAGES];
  235. int time_capture_us[FPC1020_BUFFER_MAX_IMAGES];
  236. int time_capture_sum_us;
  237. int error = 0;
  238. bool wait_finger_down = false;
  239. bool wait_finger_up = false;
  240. bool adjust_settings;
  241. fpc1020_capture_mode_t mode = fpc1020->capture.current_mode;
  242. int current_capture, capture_count;
  243. int image_offset;
  244. size_t image_byte_size;
  245. fpc1020->capture.state = FPC1020_CAPTURE_STATE_WRITE_SETTINGS;
  246. error = fpc1020_wake_up(fpc1020);
  247. if (error < 0)
  248. goto out_error;
  249. switch (mode) {
  250. case FPC1020_MODE_CAPTURE_AND_WAIT_FINGER_UP:
  251. wait_finger_up = true;
  252. capture_count = fpc1020->setup.capture_count;
  253. adjust_settings = true;
  254. error = fpc1020_write_capture_setup(fpc1020);
  255. break;
  256. case FPC1020_MODE_WAIT_AND_CAPTURE:
  257. wait_finger_down =
  258. wait_finger_up = true;
  259. case FPC1020_MODE_SINGLE_CAPTURE:
  260. case FPC1020_MODE_SINGLE_CAPTURE_CAL:
  261. capture_count = fpc1020->setup.capture_count;
  262. adjust_settings = true;
  263. error = fpc1020_write_capture_setup(fpc1020);
  264. break;
  265. case FPC1020_MODE_CHECKERBOARD_TEST_NORM:
  266. capture_count = 1;
  267. adjust_settings = false;
  268. error = fpc1020_write_cb_test_setup(fpc1020, false);
  269. break;
  270. case FPC1020_MODE_CHECKERBOARD_TEST_INV:
  271. capture_count = 1;
  272. adjust_settings = false;
  273. error = fpc1020_write_cb_test_setup(fpc1020, true);
  274. break;
  275. case FPC1020_MODE_BOARD_TEST_ONE:
  276. capture_count = 1;
  277. adjust_settings = false;
  278. error = fpc1020_write_test_setup(fpc1020, 0xffff);
  279. break;
  280. case FPC1020_MODE_BOARD_TEST_ZERO:
  281. capture_count = 1;
  282. adjust_settings = false;
  283. error = fpc1020_write_test_setup(fpc1020, 0x0000);
  284. break;
  285. case FPC1020_MODE_WAIT_FINGER_DOWN:
  286. wait_finger_down = true;
  287. capture_count = 0;
  288. adjust_settings = false;
  289. error = fpc1020_write_capture_setup(fpc1020);
  290. break;
  291. case FPC1020_MODE_WAIT_FINGER_UP:
  292. wait_finger_up = true;
  293. capture_count = 0;
  294. adjust_settings = false;
  295. error = fpc1020_write_capture_setup(fpc1020);
  296. break;
  297. case FPC1020_MODE_IDLE:
  298. default:
  299. capture_count = 0;
  300. adjust_settings = false;
  301. error = -EINVAL;
  302. break;
  303. }
  304. if (error < 0)
  305. goto out_error;
  306. error = fpc1020_capture_set_crop(fpc1020,
  307. fpc1020->setup.capture_col_start,
  308. fpc1020->setup.capture_col_groups,
  309. fpc1020->setup.capture_row_start,
  310. fpc1020->setup.capture_row_count);
  311. if (error < 0)
  312. goto out_error;
  313. image_byte_size = fpc1020_calc_image_size(fpc1020);
  314. dev_dbg(&fpc1020->spi->dev,
  315. "Start capture, mode %d, (%d frames)\n",
  316. mode,
  317. capture_count);
  318. if (!wait_finger_down)
  319. fpc1020->capture.deferred_finger_up = false;
  320. if (wait_finger_down) {
  321. error = fpc1020_capture_finger_detect_settings(fpc1020);
  322. if (error < 0)
  323. goto out_error;
  324. }
  325. if (wait_finger_down && fpc1020->capture.deferred_finger_up) {
  326. fpc1020->capture.state =
  327. FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP;
  328. dev_dbg(&fpc1020->spi->dev, "Waiting for (deferred) finger up\n");
  329. error = fpc1020_capture_wait_finger_up(fpc1020);
  330. if (error < 0)
  331. goto out_error;
  332. dev_dbg(&fpc1020->spi->dev, "Finger up\n");
  333. fpc1020->capture.deferred_finger_up = false;
  334. }
  335. if (wait_finger_down) {
  336. fpc1020->capture.state =
  337. FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN;
  338. error = fpc1020_capture_wait_finger_down(fpc1020);
  339. if (error < 0)
  340. goto out_error;
  341. dev_dbg(&fpc1020->spi->dev, "Finger down\n");
  342. if (mode == FPC1020_MODE_WAIT_FINGER_DOWN) {
  343. fpc1020->capture.available_bytes = 4;
  344. fpc1020->huge_buffer[0] = 'F';
  345. fpc1020->huge_buffer[1] = ':';
  346. fpc1020->huge_buffer[2] = 'D';
  347. fpc1020->huge_buffer[3] = 'N';
  348. }
  349. }
  350. current_capture = 0;
  351. image_offset = 0;
  352. fpc1020->diag.last_capture_time = 0;
  353. if (mode == FPC1020_MODE_SINGLE_CAPTURE_CAL) {
  354. error = fpc1020_capture_set_sample_mode(fpc1020, true);
  355. if (error)
  356. goto out_error;
  357. }
  358. while (capture_count && (error >= 0)) {
  359. getnstimeofday(&ts_t1);
  360. fpc1020->capture.state = FPC1020_CAPTURE_STATE_ACQUIRE;
  361. dev_dbg(&fpc1020->spi->dev,
  362. "Capture, frame #%d\n",
  363. current_capture + 1);
  364. error = (!adjust_settings) ? 0 :
  365. fpc1020_capture_settings(fpc1020, current_capture);
  366. if (error < 0)
  367. goto out_error;
  368. getnstimeofday(&ts_t2);
  369. error = fpc1020_cmd(fpc1020,
  370. FPC1020_CMD_CAPTURE_IMAGE,
  371. FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA);
  372. if (error < 0)
  373. goto out_error;
  374. fpc1020->capture.state = FPC1020_CAPTURE_STATE_FETCH;
  375. error = fpc1020_fetch_image(fpc1020,
  376. fpc1020->huge_buffer,
  377. image_offset,
  378. image_byte_size,
  379. (size_t)fpc1020->huge_buffer_size);
  380. if (error < 0)
  381. goto out_error;
  382. fpc1020->capture.available_bytes += (error >= 0) ?
  383. (int)image_byte_size : 0;
  384. fpc1020->capture.last_error = error;
  385. getnstimeofday(&ts_t3);
  386. ts_delta = timespec_sub(ts_t2, ts_t1);
  387. time_settings_us[current_capture] =
  388. ts_delta.tv_sec * USEC_PER_SEC +
  389. (ts_delta.tv_nsec / NSEC_PER_USEC);
  390. ts_delta = timespec_sub(ts_t3, ts_t2);
  391. time_capture_us[current_capture] =
  392. ts_delta.tv_sec * USEC_PER_SEC +
  393. (ts_delta.tv_nsec / NSEC_PER_USEC);
  394. capture_count--;
  395. current_capture++;
  396. image_offset += (int)image_byte_size;
  397. }
  398. error = fpc1020_capture_set_sample_mode(fpc1020, false);
  399. if (error)
  400. goto out_error;
  401. /* Update finger_present_status after image capture */
  402. fpc1020_check_finger_present_raw(fpc1020);
  403. if (mode != FPC1020_MODE_WAIT_FINGER_UP)
  404. wake_up_interruptible(&fpc1020->capture.wq_data_avail);
  405. if (wait_finger_up) {
  406. fpc1020->capture.state =
  407. FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP;
  408. error = fpc1020_capture_finger_detect_settings(fpc1020);
  409. if (error < 0)
  410. goto out_error;
  411. error = fpc1020_capture_wait_finger_up(fpc1020);
  412. if (error == -EINTR) {
  413. dev_dbg(&fpc1020->spi->dev, "Finger up check interrupted\n");
  414. fpc1020->capture.deferred_finger_up = true;
  415. goto out_interrupted;
  416. } else if (error < 0)
  417. goto out_error;
  418. if (mode == FPC1020_MODE_WAIT_FINGER_UP) {
  419. fpc1020->capture.available_bytes = 4;
  420. fpc1020->huge_buffer[0] = 'F';
  421. fpc1020->huge_buffer[1] = ':';
  422. fpc1020->huge_buffer[2] = 'U';
  423. fpc1020->huge_buffer[3] = 'P';
  424. wake_up_interruptible(&fpc1020->capture.wq_data_avail);
  425. }
  426. dev_dbg(&fpc1020->spi->dev, "Finger up\n");
  427. }
  428. out_interrupted:
  429. capture_count = 0;
  430. time_capture_sum_us = 0;
  431. while (current_capture) {
  432. current_capture--;
  433. dev_dbg(&fpc1020->spi->dev,
  434. "Frame #%d acq. time %d+%d=%d (us)\n",
  435. capture_count + 1,
  436. time_settings_us[capture_count],
  437. time_capture_us[capture_count],
  438. time_settings_us[capture_count] +
  439. time_capture_us[capture_count]);
  440. time_capture_sum_us += time_settings_us[capture_count];
  441. time_capture_sum_us += time_capture_us[capture_count];
  442. capture_count++;
  443. }
  444. fpc1020->diag.last_capture_time = time_capture_sum_us / 1000;
  445. dev_dbg(&fpc1020->spi->dev,
  446. "Total acq. time %d (us)\n", time_capture_sum_us);
  447. out_error:
  448. fpc1020->capture.last_error = error;
  449. if (error) {
  450. fpc1020->capture.state = FPC1020_CAPTURE_STATE_FAILED;
  451. dev_err(&fpc1020->spi->dev, "%s %s %d\n", __func__,
  452. (error == -EINTR) ? "TERMINATED" : "FAILED", error);
  453. } else {
  454. fpc1020->capture.state = FPC1020_CAPTURE_STATE_COMPLETED;
  455. dev_err(&fpc1020->spi->dev, "%s OK\n", __func__);
  456. }
  457. return error;
  458. }
  459. /* -------------------------------------------------------------------- */
  460. int fpc1020_capture_wait_finger_down(fpc1020_data_t *fpc1020)
  461. {
  462. int error;
  463. bool finger_down = false;
  464. error = fpc1020_wait_finger_present(fpc1020);
  465. while (!finger_down && (error >= 0)) {
  466. if (fpc1020->worker.stop_request)
  467. error = -EINTR;
  468. else
  469. error = fpc1020_check_finger_present_sum(fpc1020);
  470. if (error > fpc1020->setup.capture_finger_down_threshold)
  471. finger_down = true;
  472. else
  473. msleep(FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS);
  474. }
  475. fpc1020_read_irq(fpc1020, true);
  476. return (finger_down) ? 0 : error;
  477. }
  478. /* -------------------------------------------------------------------- */
  479. int fpc1020_capture_wait_finger_up(fpc1020_data_t *fpc1020)
  480. {
  481. int error = 0;
  482. bool finger_up = false;
  483. while (!finger_up && (error >= 0)) {
  484. if (fpc1020->worker.stop_request)
  485. error = -EINTR;
  486. else
  487. error = fpc1020_check_finger_present_sum(fpc1020);
  488. if ((error >= 0) && (error < fpc1020->setup.capture_finger_up_threshold + 1))
  489. finger_up = true;
  490. else
  491. msleep(FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS);
  492. }
  493. fpc1020_read_irq(fpc1020, true);
  494. return (finger_up) ? 0 : error;
  495. }
  496. /* -------------------------------------------------------------------- */
  497. int fpc1020_capture_settings(fpc1020_data_t *fpc1020, int select)
  498. {
  499. int error = 0;
  500. fpc1020_reg_access_t reg;
  501. u16 pxlCtrl;
  502. u16 adc_shift_gain;
  503. dev_dbg(&fpc1020->spi->dev, "%s #%d\n", __func__, select);
  504. if (select >= FPC1020_MAX_ADC_SETTINGS) {
  505. error = -EINVAL;
  506. goto out_err;
  507. }
  508. pxlCtrl = fpc1020->setup.pxl_ctrl[select];
  509. pxlCtrl |= FPC1020_PXL_BIAS_CTRL;
  510. adc_shift_gain = fpc1020->setup.adc_shift[select];
  511. adc_shift_gain <<= 8;
  512. adc_shift_gain |= fpc1020->setup.adc_gain[select];
  513. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &pxlCtrl);
  514. error = fpc1020_reg_access(fpc1020, &reg);
  515. if (error)
  516. goto out_err;
  517. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &adc_shift_gain);
  518. error = fpc1020_reg_access(fpc1020, &reg);
  519. if (error)
  520. goto out_err;
  521. out_err:
  522. if (error)
  523. dev_err(&fpc1020->spi->dev, "%s Error %d\n", __func__, error);
  524. return error;
  525. }
  526. int fpc1020_capture_set_sample_mode(fpc1020_data_t *fpc1020, bool single)
  527. {
  528. int error = 0;
  529. fpc1020_reg_access_t reg;
  530. u8 image_setup;
  531. u8 image_rd;
  532. dev_dbg(&fpc1020->spi->dev, "%s single %s\n", __func__, single ?
  533. "true" : "false");
  534. if (single) {
  535. image_setup = 0x0A;
  536. image_rd = 0x0C;
  537. } else {
  538. image_setup = 0x03 | 0x08;
  539. image_rd = 0x0E;
  540. }
  541. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMAGE_SETUP, &image_setup);
  542. error = fpc1020_reg_access(fpc1020, &reg);
  543. if (error)
  544. goto out_err;
  545. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMG_RD, &image_rd);
  546. error = fpc1020_reg_access(fpc1020, &reg);
  547. if (error)
  548. goto out_err;
  549. out_err:
  550. if (error)
  551. dev_err(&fpc1020->spi->dev, "%s Error %d\n", __func__, error);
  552. return error;
  553. }
  554. /* -------------------------------------------------------------------- */
  555. int fpc1020_capture_finger_detect_settings(fpc1020_data_t *fpc1020)
  556. {
  557. dev_dbg(&fpc1020->spi->dev, "%s\n", __func__);
  558. return fpc1020_capture_settings(fpc1020, FPC1020_MAX_ADC_SETTINGS - 1);
  559. }
  560. /* -------------------------------------------------------------------- */
  561. static size_t fpc1020_calc_image_size(fpc1020_data_t *fpc1020)
  562. {
  563. int image_byte_size = fpc1020->setup.capture_row_count *
  564. fpc1020->setup.capture_col_groups *
  565. fpc1020->chip.adc_group_size;
  566. dev_dbg(&fpc1020->spi->dev, "%s Rows %d->%d,Cols %d->%d (%d bytes)\n",
  567. __func__,
  568. fpc1020->setup.capture_row_start,
  569. fpc1020->setup.capture_row_start
  570. + fpc1020->setup.capture_row_count - 1,
  571. fpc1020->setup.capture_col_start
  572. * fpc1020->chip.adc_group_size,
  573. (fpc1020->setup.capture_col_start
  574. * fpc1020->chip.adc_group_size)
  575. + (fpc1020->setup.capture_col_groups *
  576. fpc1020->chip.adc_group_size) - 1,
  577. image_byte_size
  578. );
  579. return image_byte_size;
  580. }
  581. /* -------------------------------------------------------------------- */
  582. int fpc1020_capture_set_crop(fpc1020_data_t *fpc1020,
  583. int first_column,
  584. int num_columns,
  585. int first_row,
  586. int num_rows)
  587. {
  588. fpc1020_reg_access_t reg;
  589. u32 temp_u32;
  590. temp_u32 = first_row;
  591. temp_u32 <<= 8;
  592. temp_u32 |= num_rows;
  593. temp_u32 <<= 8;
  594. temp_u32 |= (first_column * fpc1020->chip.adc_group_size);
  595. temp_u32 <<= 8;
  596. temp_u32 |= (num_columns * fpc1020->chip.adc_group_size);
  597. FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMG_CAPT_SIZE, &temp_u32);
  598. return fpc1020_reg_access(fpc1020, &reg);
  599. }
  600. /* -------------------------------------------------------------------- */
  601. int fpc1020_capture_buffer(fpc1020_data_t *fpc1020,
  602. u8 *data,
  603. size_t offset,
  604. size_t image_size_bytes)
  605. {
  606. int error = 0;
  607. dev_dbg(&fpc1020->spi->dev, "%s\n", __func__);
  608. error = fpc1020_cmd(fpc1020,
  609. FPC1020_CMD_CAPTURE_IMAGE,
  610. FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA);
  611. if (error < 0)
  612. goto out_error;
  613. error = fpc1020_fetch_image(fpc1020,
  614. data,
  615. offset,
  616. image_size_bytes,
  617. (size_t)fpc1020->huge_buffer_size);
  618. if (error < 0)
  619. goto out_error;
  620. return 0;
  621. out_error:
  622. dev_dbg(&fpc1020->spi->dev, "%s FAILED %d\n", __func__, error);
  623. return error;
  624. }
  625. /* -------------------------------------------------------------------- */
  626. extern int fpc1020_capture_deferred_task(fpc1020_data_t *fpc1020)
  627. {
  628. int error = 0;
  629. dev_dbg(&fpc1020->spi->dev, "%s\n", __func__);
  630. error = (fpc1020->capture.deferred_finger_up) ?
  631. fpc1020_capture_wait_finger_up(fpc1020) : 0;
  632. if (error >= 0)
  633. fpc1020->capture.deferred_finger_up = false;
  634. return error;
  635. }
  636. /* -------------------------------------------------------------------- */