pt_mt_common.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. /*
  2. * pt_mt_common.c
  3. * Parade TrueTouch(TM) Standard Product Multi-Touch Reports Module.
  4. * For use with Parade touchscreen controllers.
  5. * Supported parts include:
  6. * TMA5XX
  7. * TMA448
  8. * TMA445A
  9. * TT21XXX
  10. * TT31XXX
  11. * TT4XXXX
  12. * TT7XXX
  13. * TC3XXX
  14. *
  15. * Copyright (C) 2015-2020 Parade Technologies
  16. *
  17. * This program is free software; you can redistribute it and/or
  18. * modify it under the terms of the GNU General Public License
  19. * version 2, and only version 2, as published by the
  20. * Free Software Foundation.
  21. *
  22. * This program is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU General Public License for more details.
  26. *
  27. * Contact Parade Technologies at www.paradetech.com <[email protected]>
  28. */
  29. #include "pt_regs.h"
  30. #define MT_PARAM_SIGNAL(md, sig_ost) PARAM_SIGNAL(md->pdata->frmwrk, sig_ost)
  31. #define MT_PARAM_MIN(md, sig_ost) PARAM_MIN(md->pdata->frmwrk, sig_ost)
  32. #define MT_PARAM_MAX(md, sig_ost) PARAM_MAX(md->pdata->frmwrk, sig_ost)
  33. #define MT_PARAM_FUZZ(md, sig_ost) PARAM_FUZZ(md->pdata->frmwrk, sig_ost)
  34. #define MT_PARAM_FLAT(md, sig_ost) PARAM_FLAT(md->pdata->frmwrk, sig_ost)
  35. /*******************************************************************************
  36. * FUNCTION: pt_mt_lift_all
  37. *
  38. * SUMMARY: Reports touch liftoff action
  39. *
  40. * PARAMETERS:
  41. * *md - pointer to touch data structure
  42. ******************************************************************************/
  43. static void pt_mt_lift_all(struct pt_mt_data *md)
  44. {
  45. int max = md->si->tch_abs[PT_TCH_T].max;
  46. if (md->num_prv_rec != 0) {
  47. if (md->mt_function.report_slot_liftoff)
  48. md->mt_function.report_slot_liftoff(md, max);
  49. input_sync(md->input);
  50. md->num_prv_rec = 0;
  51. }
  52. }
  53. /*******************************************************************************
  54. * FUNCTION: pt_get_touch_axis
  55. *
  56. * SUMMARY: Calculates touch axis
  57. *
  58. * PARAMETERS:
  59. * *md - pointer to touch data structure
  60. * *axis - pointer to axis calculation result
  61. * size - size in byte
  62. * max - max value of result
  63. * *xy_data - pointer to input data to be parsed
  64. * bofs - bit offset
  65. ******************************************************************************/
  66. static void pt_get_touch_axis(struct pt_mt_data *md,
  67. int *axis, int size, int max, u8 *xy_data, int bofs)
  68. {
  69. int nbyte;
  70. int next;
  71. for (nbyte = 0, *axis = 0, next = 0; nbyte < size; nbyte++) {
  72. pt_debug(md->dev, DL_DEBUG,
  73. "%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p xy_data[%d]=%02X(%d) bofs=%d\n",
  74. __func__, *axis, *axis, size, max, xy_data, next,
  75. xy_data[next], xy_data[next], bofs);
  76. *axis = *axis + ((xy_data[next] >> bofs) << (nbyte * 8));
  77. next++;
  78. }
  79. *axis &= max - 1;
  80. pt_debug(md->dev, DL_DEBUG,
  81. "%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p xy_data[%d]=%02X(%d)\n",
  82. __func__, *axis, *axis, size, max, xy_data, next,
  83. xy_data[next], xy_data[next]);
  84. }
  85. /*******************************************************************************
  86. * FUNCTION: pt_get_touch_hdr
  87. *
  88. * SUMMARY: Get the header of touch report
  89. *
  90. * PARAMETERS:
  91. * *md - pointer to touch data structure
  92. * *touch - pointer to pt_touch structure
  93. * *xy_mode - pointer to touch mode data
  94. ******************************************************************************/
  95. static void pt_get_touch_hdr(struct pt_mt_data *md,
  96. struct pt_touch *touch, u8 *xy_mode)
  97. {
  98. struct device *dev = md->dev;
  99. struct pt_sysinfo *si = md->si;
  100. enum pt_tch_hdr hdr;
  101. for (hdr = PT_TCH_TIME; hdr < PT_TCH_NUM_HDR; hdr++) {
  102. if (!si->tch_hdr[hdr].report)
  103. continue;
  104. pt_get_touch_axis(md, &touch->hdr[hdr],
  105. si->tch_hdr[hdr].size,
  106. si->tch_hdr[hdr].max,
  107. xy_mode + si->tch_hdr[hdr].ofs,
  108. si->tch_hdr[hdr].bofs);
  109. pt_debug(dev, DL_DEBUG, "%s: get %s=%04X(%d)\n",
  110. __func__, pt_tch_hdr_string[hdr],
  111. touch->hdr[hdr], touch->hdr[hdr]);
  112. }
  113. pt_debug(dev, DL_INFO,
  114. "%s: time=%X tch_num=%d lo=%d noise=%d counter=%d\n",
  115. __func__,
  116. touch->hdr[PT_TCH_TIME],
  117. touch->hdr[PT_TCH_NUM],
  118. touch->hdr[PT_TCH_LO],
  119. touch->hdr[PT_TCH_NOISE],
  120. touch->hdr[PT_TCH_COUNTER]);
  121. }
  122. /*******************************************************************************
  123. * FUNCTION: pt_get_touch_record
  124. *
  125. * SUMMARY: Gets axis of touch report
  126. *
  127. * PARAMETERS:
  128. * *md - pointer to touch data structure
  129. * *touch - pointer to pt_touch structure
  130. * *xy_data - pointer to touch data
  131. ******************************************************************************/
  132. static void pt_get_touch_record(struct pt_mt_data *md,
  133. struct pt_touch *touch, u8 *xy_data)
  134. {
  135. struct device *dev = md->dev;
  136. struct pt_sysinfo *si = md->si;
  137. enum pt_tch_abs abs;
  138. for (abs = PT_TCH_X; abs < PT_TCH_NUM_ABS; abs++) {
  139. if (!si->tch_abs[abs].report)
  140. continue;
  141. pt_get_touch_axis(md, &touch->abs[abs],
  142. si->tch_abs[abs].size,
  143. si->tch_abs[abs].max,
  144. xy_data + si->tch_abs[abs].ofs,
  145. si->tch_abs[abs].bofs);
  146. pt_debug(dev, DL_DEBUG, "%s: get %s=%04X(%d)\n",
  147. __func__, pt_tch_abs_string[abs],
  148. touch->abs[abs], touch->abs[abs]);
  149. }
  150. }
  151. /*******************************************************************************
  152. * FUNCTION: pt_mt_process_touch
  153. *
  154. * SUMMARY: Process touch includes oritation,axis invert and
  155. * convert MAJOR/MINOR from mm to resolution
  156. *
  157. * PARAMETERS:
  158. * *md - pointer to touch data structure
  159. * *touch - pointer to pt_touch structure
  160. ******************************************************************************/
  161. static void pt_mt_process_touch(struct pt_mt_data *md,
  162. struct pt_touch *touch)
  163. {
  164. struct device *dev = md->dev;
  165. struct pt_sysinfo *si = md->si;
  166. int tmp;
  167. bool flipped;
  168. /* Orientation is signed */
  169. touch->abs[PT_TCH_OR] = (int8_t)touch->abs[PT_TCH_OR];
  170. if (md->pdata->flags & PT_MT_FLAG_FLIP) {
  171. tmp = touch->abs[PT_TCH_X];
  172. touch->abs[PT_TCH_X] = touch->abs[PT_TCH_Y];
  173. touch->abs[PT_TCH_Y] = tmp;
  174. if (touch->abs[PT_TCH_OR] > 0)
  175. touch->abs[PT_TCH_OR] =
  176. md->or_max - touch->abs[PT_TCH_OR];
  177. else
  178. touch->abs[PT_TCH_OR] =
  179. md->or_min - touch->abs[PT_TCH_OR];
  180. flipped = true;
  181. } else
  182. flipped = false;
  183. /*
  184. * 1 is subtracted from each touch location to make the location
  185. * 0 based. e.g. If the resolution of touch panel is 1200x1600,
  186. * the FW touch report must be (0~1199,0~1599). The driver
  187. * should register the (min,max) value to Linux input system as
  188. * (0~1199,0~1599). When the host needs to invert the
  189. * coordinates, the driver would incorrectly use the resolution
  190. * to subtract the reported point directly, such as
  191. * 1200-(0~1199). The input system will lose the 0 point report
  192. * and the 1200 point will be ignored.
  193. */
  194. if (md->pdata->flags & PT_MT_FLAG_INV_X) {
  195. if (flipped)
  196. touch->abs[PT_TCH_X] = si->sensing_conf_data.res_y -
  197. touch->abs[PT_TCH_X] - 1;
  198. else
  199. touch->abs[PT_TCH_X] = si->sensing_conf_data.res_x -
  200. touch->abs[PT_TCH_X] - 1;
  201. touch->abs[PT_TCH_OR] *= -1;
  202. }
  203. if (md->pdata->flags & PT_MT_FLAG_INV_Y) {
  204. if (flipped)
  205. touch->abs[PT_TCH_Y] = si->sensing_conf_data.res_x -
  206. touch->abs[PT_TCH_Y] - 1;
  207. else
  208. touch->abs[PT_TCH_Y] = si->sensing_conf_data.res_y -
  209. touch->abs[PT_TCH_Y] - 1;
  210. touch->abs[PT_TCH_OR] *= -1;
  211. }
  212. /* Convert MAJOR/MINOR from mm to resolution */
  213. tmp = touch->abs[PT_TCH_MAJ] * 100 * si->sensing_conf_data.res_x;
  214. touch->abs[PT_TCH_MAJ] = tmp / si->sensing_conf_data.len_x;
  215. tmp = touch->abs[PT_TCH_MIN] * 100 * si->sensing_conf_data.res_x;
  216. touch->abs[PT_TCH_MIN] = tmp / si->sensing_conf_data.len_x;
  217. pt_debug(dev, DL_INFO,
  218. "%s: flip=%s inv-x=%s inv-y=%s x=%04X(%d) y=%04X(%d)\n",
  219. __func__, flipped ? "true" : "false",
  220. md->pdata->flags & PT_MT_FLAG_INV_X ? "true" : "false",
  221. md->pdata->flags & PT_MT_FLAG_INV_Y ? "true" : "false",
  222. touch->abs[PT_TCH_X], touch->abs[PT_TCH_X],
  223. touch->abs[PT_TCH_Y], touch->abs[PT_TCH_Y]);
  224. }
  225. /*******************************************************************************
  226. * FUNCTION: pt_report_event
  227. *
  228. * SUMMARY: Reports touch event
  229. *
  230. * PARAMETERS:
  231. * *md - pointer to touch data structure
  232. * event - type of touch event
  233. * value - value of report event
  234. ******************************************************************************/
  235. static void pt_report_event(struct pt_mt_data *md, int event,
  236. int value)
  237. {
  238. int sig = MT_PARAM_SIGNAL(md, event);
  239. if (sig != PT_IGNORE_VALUE)
  240. input_report_abs(md->input, sig, value);
  241. }
  242. /*******************************************************************************
  243. * FUNCTION: pt_get_mt_touches
  244. *
  245. * SUMMARY: Parse and report touch event
  246. *
  247. * PARAMETERS:
  248. * *md - pointer to touch data structure
  249. * *tch - pointer to touch structure
  250. * num_cur_tch - number of current touch
  251. ******************************************************************************/
  252. static void pt_get_mt_touches(struct pt_mt_data *md,
  253. struct pt_touch *tch, int num_cur_tch)
  254. {
  255. struct device *dev = md->dev;
  256. struct pt_sysinfo *si = md->si;
  257. int sig;
  258. int i, j, t = 0;
  259. DECLARE_BITMAP(ids, PT_TOUCH_ID_MAX);
  260. int mt_sync_count = 0;
  261. u8 *tch_addr;
  262. if (PT_TOUCH_ID_MAX < si->tch_abs[PT_TCH_T].max) {
  263. pt_debug(dev, DL_ERROR,
  264. "%s: Touch ID num %d is allocated less than needed %d\n",
  265. __func__, PT_TOUCH_ID_MAX, si->tch_abs[PT_TCH_T].max);
  266. return;
  267. }
  268. bitmap_zero(ids, PT_TOUCH_ID_MAX);
  269. memset(tch->abs, 0, sizeof(tch->abs));
  270. for (i = 0; i < num_cur_tch; i++) {
  271. tch_addr = si->xy_data + (i * si->desc.tch_record_size);
  272. pt_get_touch_record(md, tch, tch_addr);
  273. /* Discard proximity event */
  274. if (tch->abs[PT_TCH_O] == PT_OBJ_PROXIMITY) {
  275. pt_debug(dev, DL_INFO,
  276. "%s: Discarding proximity event\n",
  277. __func__);
  278. continue;
  279. }
  280. /* Validate track_id */
  281. t = tch->abs[PT_TCH_T];
  282. if (t < md->t_min || t > md->t_max) {
  283. pt_debug(dev, DL_INFO,
  284. "%s: tch=%d -> bad trk_id=%d max_id=%d\n",
  285. __func__, i, t, md->t_max);
  286. if (md->mt_function.input_sync)
  287. md->mt_function.input_sync(md->input);
  288. mt_sync_count++;
  289. continue;
  290. }
  291. /* Lift-off */
  292. if (tch->abs[PT_TCH_E] == PT_EV_LIFTOFF) {
  293. pt_debug(dev, DL_INFO, "%s: t=%d e=%d lift-off\n",
  294. __func__, t, tch->abs[PT_TCH_E]);
  295. goto pt_get_mt_touches_pr_tch;
  296. }
  297. /* Process touch */
  298. pt_mt_process_touch(md, tch);
  299. /* use 0 based track id's */
  300. t -= md->t_min;
  301. sig = MT_PARAM_SIGNAL(md, PT_ABS_ID_OST);
  302. if (sig != PT_IGNORE_VALUE) {
  303. if (md->mt_function.input_report)
  304. md->mt_function.input_report(md->input, sig,
  305. t, tch->abs[PT_TCH_O]);
  306. __set_bit(t, ids);
  307. }
  308. pt_report_event(md, PT_ABS_D_OST, 0);
  309. /* all devices: position and pressure fields */
  310. for (j = 0; j <= PT_ABS_W_OST; j++) {
  311. if (!si->tch_abs[j].report)
  312. continue;
  313. pt_report_event(md, PT_ABS_X_OST + j,
  314. tch->abs[PT_TCH_X + j]);
  315. }
  316. /* Get the extended touch fields */
  317. for (j = 0; j < PT_NUM_EXT_TCH_FIELDS; j++) {
  318. if (!si->tch_abs[PT_ABS_MAJ_OST + j].report)
  319. continue;
  320. pt_report_event(md, PT_ABS_MAJ_OST + j,
  321. tch->abs[PT_TCH_MAJ + j]);
  322. }
  323. if (md->mt_function.input_sync)
  324. md->mt_function.input_sync(md->input);
  325. mt_sync_count++;
  326. pt_get_mt_touches_pr_tch:
  327. pt_debug(dev, DL_INFO,
  328. "%s: t=%d x=%d y=%d z=%d M=%d m=%d o=%d e=%d obj=%d tip=%d\n",
  329. __func__, t,
  330. tch->abs[PT_TCH_X],
  331. tch->abs[PT_TCH_Y],
  332. tch->abs[PT_TCH_P],
  333. tch->abs[PT_TCH_MAJ],
  334. tch->abs[PT_TCH_MIN],
  335. tch->abs[PT_TCH_OR],
  336. tch->abs[PT_TCH_E],
  337. tch->abs[PT_TCH_O],
  338. tch->abs[PT_TCH_TIP]);
  339. }
  340. if (md->mt_function.final_sync)
  341. md->mt_function.final_sync(md->input,
  342. si->tch_abs[PT_TCH_T].max, mt_sync_count, ids);
  343. md->num_prv_rec = num_cur_tch;
  344. }
  345. /*******************************************************************************
  346. * FUNCTION: pt_xy_worker
  347. *
  348. * SUMMARY: Read xy_data for all current touches
  349. *
  350. * RETURN:
  351. * 0 = success
  352. * !0 = failure
  353. *
  354. * PARAMETERS:
  355. * *md - pointer to touch data structure
  356. ******************************************************************************/
  357. static int pt_xy_worker(struct pt_mt_data *md)
  358. {
  359. struct device *dev = md->dev;
  360. struct pt_sysinfo *si = md->si;
  361. int max_tch = si->sensing_conf_data.max_tch;
  362. struct pt_touch tch;
  363. u8 num_cur_tch;
  364. int rc = 0;
  365. pt_get_touch_hdr(md, &tch, si->xy_mode + 3);
  366. num_cur_tch = tch.hdr[PT_TCH_NUM];
  367. if (num_cur_tch > max_tch) {
  368. pt_debug(dev, DL_ERROR, "%s: Num touch err detected (n=%d)\n",
  369. __func__, num_cur_tch);
  370. num_cur_tch = max_tch;
  371. }
  372. if (tch.hdr[PT_TCH_LO]) {
  373. pt_debug(dev, DL_INFO, "%s: Large area detected\n",
  374. __func__);
  375. if (md->pdata->flags & PT_MT_FLAG_NO_TOUCH_ON_LO)
  376. num_cur_tch = 0;
  377. }
  378. if (num_cur_tch == 0 && md->num_prv_rec == 0)
  379. goto pt_xy_worker_exit;
  380. /* extract xy_data for all currently reported touches */
  381. pt_debug(dev, DL_DEBUG, "%s: extract data num_cur_tch=%d\n",
  382. __func__, num_cur_tch);
  383. if (num_cur_tch)
  384. pt_get_mt_touches(md, &tch, num_cur_tch);
  385. else
  386. pt_mt_lift_all(md);
  387. rc = 0;
  388. pt_xy_worker_exit:
  389. return rc;
  390. }
  391. /*******************************************************************************
  392. * FUNCTION: pt_mt_send_dummy_event
  393. *
  394. * SUMMARY: Send dummy/key event to wakeup upper layer of system
  395. *
  396. * PARAMETERS:
  397. * *cd - pointer to core data structure
  398. * *md - pointer to touch data structure
  399. ******************************************************************************/
  400. static void pt_mt_send_dummy_event(struct pt_core_data *cd,
  401. struct pt_mt_data *md)
  402. {
  403. #ifndef EASYWAKE_TSG6
  404. /* TSG5 EasyWake */
  405. unsigned long ids = 0;
  406. /* for easy wakeup */
  407. if (md->mt_function.input_report)
  408. md->mt_function.input_report(md->input, ABS_MT_TRACKING_ID,
  409. 0, PT_OBJ_STANDARD_FINGER);
  410. if (md->mt_function.input_sync)
  411. md->mt_function.input_sync(md->input);
  412. if (md->mt_function.final_sync)
  413. md->mt_function.final_sync(md->input, 0, 1, &ids);
  414. if (md->mt_function.report_slot_liftoff)
  415. md->mt_function.report_slot_liftoff(md, 1);
  416. if (md->mt_function.final_sync)
  417. md->mt_function.final_sync(md->input, 1, 1, &ids);
  418. #else
  419. /* TSG6 FW1.3 and above only. TSG6 FW1.0 - 1.2 does not */
  420. /* support EasyWake, and this function will not be called */
  421. u8 key_value = 0;
  422. switch (cd->gesture_id) {
  423. case GESTURE_DOUBLE_TAP:
  424. key_value = KEY_WAKEUP;
  425. break;
  426. case GESTURE_TWO_FINGERS_SLIDE:
  427. key_value = KEY_WAKEUP;
  428. break;
  429. case GESTURE_TOUCH_DETECTED:
  430. key_value = KEY_WAKEUP;
  431. break;
  432. case GESTURE_PUSH_BUTTON:
  433. key_value = KEY_F4;
  434. break;
  435. case GESTURE_SINGLE_SLIDE_DE_TX:
  436. key_value = KEY_F5;
  437. break;
  438. case GESTURE_SINGLE_SLIDE_IN_TX:
  439. key_value = KEY_F6;
  440. break;
  441. case GESTURE_SINGLE_SLIDE_DE_RX:
  442. key_value = KEY_F7;
  443. break;
  444. case GESTURE_SINGLE_SLIDE_IN_RX:
  445. key_value = KEY_F8;
  446. break;
  447. default:
  448. break;
  449. }
  450. if (key_value > 0) {
  451. input_report_key(md->input, key_value, 1);
  452. input_sync(md->input);
  453. input_report_key(md->input, key_value, 0);
  454. input_sync(md->input);
  455. }
  456. /*
  457. * Caution - this debug print is needed by the TTDL automated
  458. * regression test suite
  459. */
  460. pt_debug(md->dev, DL_INFO, "%s: report key: %d\n",
  461. __func__, key_value);
  462. #endif
  463. }
  464. /*******************************************************************************
  465. * FUNCTION: pt_mt_attention
  466. *
  467. * SUMMARY: Wrapper function for pt_xy_worker() that subscribe into the TTDL
  468. * attention list.
  469. *
  470. * RETURN:
  471. * 0 = success
  472. * !0 = failure
  473. *
  474. * PARAMETERS:
  475. * *dev - pointer to device structure
  476. ******************************************************************************/
  477. static int pt_mt_attention(struct device *dev)
  478. {
  479. struct pt_core_data *cd = dev_get_drvdata(dev);
  480. struct pt_mt_data *md = &cd->md;
  481. int rc;
  482. if (md->si->xy_mode[2] != md->si->desc.tch_report_id)
  483. return 0;
  484. /* core handles handshake */
  485. mutex_lock(&md->mt_lock);
  486. rc = pt_xy_worker(md);
  487. mutex_unlock(&md->mt_lock);
  488. if (rc < 0)
  489. pt_debug(dev, DL_ERROR,
  490. "%s: xy_worker error r=%d\n", __func__, rc);
  491. return rc;
  492. }
  493. /*******************************************************************************
  494. * FUNCTION: pt_mt_wake_attention
  495. *
  496. * SUMMARY: Wrapper function for pt_mt_send_dummy_event() that register to
  497. * attention list.
  498. *
  499. * RETURN:
  500. * 0 = success
  501. *
  502. * PARAMETERS:
  503. * *dev - pointer to device structure
  504. ******************************************************************************/
  505. static int pt_mt_wake_attention(struct device *dev)
  506. {
  507. struct pt_core_data *cd = dev_get_drvdata(dev);
  508. struct pt_mt_data *md = &cd->md;
  509. mutex_lock(&md->mt_lock);
  510. pt_mt_send_dummy_event(cd, md);
  511. mutex_unlock(&md->mt_lock);
  512. return 0;
  513. }
  514. /*******************************************************************************
  515. * FUNCTION: pt_startup_attention
  516. *
  517. * SUMMARY: Wrapper function for pt_mt_lift_all() that subcribe into the TTDL
  518. * attention list.
  519. *
  520. * RETURN:
  521. * 0 = success
  522. *
  523. * PARAMETERS:
  524. * *dev - pointer to device structure
  525. ******************************************************************************/
  526. static int pt_startup_attention(struct device *dev)
  527. {
  528. struct pt_core_data *cd = dev_get_drvdata(dev);
  529. struct pt_mt_data *md = &cd->md;
  530. mutex_lock(&md->mt_lock);
  531. pt_mt_lift_all(md);
  532. mutex_unlock(&md->mt_lock);
  533. return 0;
  534. }
  535. /*******************************************************************************
  536. * FUNCTION: pt_mt_suspend_attention
  537. *
  538. * SUMMARY: Function for touch to enter suspend state that as following steps:
  539. * 1) Lift all touch
  540. * 2) Set flag with suspend state
  541. * 3) Decrese pm system count
  542. *
  543. * RETURN:
  544. * 0 = success
  545. *
  546. * PARAMETERS:
  547. * *dev - pointer to device structure
  548. ******************************************************************************/
  549. static int pt_mt_suspend_attention(struct device *dev)
  550. {
  551. struct pt_core_data *cd = dev_get_drvdata(dev);
  552. struct pt_mt_data *md = &cd->md;
  553. mutex_lock(&md->mt_lock);
  554. pt_mt_lift_all(md);
  555. md->is_suspended = true;
  556. mutex_unlock(&md->mt_lock);
  557. pm_runtime_put(dev);
  558. return 0;
  559. }
  560. /*******************************************************************************
  561. * FUNCTION: pt_mt_resume_attention
  562. *
  563. * SUMMARY: Function for touch to leave suspend state that as following steps:
  564. * 1) Increse pm system count
  565. * 2) Clear suspend state flag
  566. *
  567. * RETURN:
  568. * 0 = success
  569. *
  570. * PARAMETERS:
  571. * *dev - pointer to device structure
  572. ******************************************************************************/
  573. static int pt_mt_resume_attention(struct device *dev)
  574. {
  575. struct pt_core_data *cd = dev_get_drvdata(dev);
  576. struct pt_mt_data *md = &cd->md;
  577. pm_runtime_get(dev);
  578. mutex_lock(&md->mt_lock);
  579. md->is_suspended = false;
  580. mutex_unlock(&md->mt_lock);
  581. return 0;
  582. }
  583. /*******************************************************************************
  584. * FUNCTION: pt_mt_open
  585. *
  586. * SUMMARY: Open method for input device(touch) that sets up call back
  587. * functions to TTDL attention list
  588. *
  589. * RETURN:
  590. * 0 = success
  591. *
  592. * PARAMETERS:
  593. * *input - pointer to input_dev structure
  594. ******************************************************************************/
  595. static int pt_mt_open(struct input_dev *input)
  596. {
  597. struct device *dev = input->dev.parent;
  598. struct pt_core_data *cd = dev_get_drvdata(dev);
  599. struct pt_mt_data *md = &cd->md;
  600. pm_runtime_get_sync(dev);
  601. mutex_lock(&md->mt_lock);
  602. md->is_suspended = false;
  603. mutex_unlock(&md->mt_lock);
  604. pt_debug(dev, DL_INFO, "%s: setup subscriptions\n", __func__);
  605. /* set up touch call back */
  606. _pt_subscribe_attention(dev, PT_ATTEN_IRQ, PT_MT_NAME,
  607. pt_mt_attention, PT_MODE_OPERATIONAL);
  608. /* set up startup call back */
  609. _pt_subscribe_attention(dev, PT_ATTEN_STARTUP, PT_MT_NAME,
  610. pt_startup_attention, 0);
  611. /* set up wakeup call back */
  612. _pt_subscribe_attention(dev, PT_ATTEN_WAKE, PT_MT_NAME,
  613. pt_mt_wake_attention, 0);
  614. /* set up suspend call back */
  615. _pt_subscribe_attention(dev, PT_ATTEN_SUSPEND, PT_MT_NAME,
  616. pt_mt_suspend_attention, 0);
  617. /* set up resume call back */
  618. _pt_subscribe_attention(dev, PT_ATTEN_RESUME, PT_MT_NAME,
  619. pt_mt_resume_attention, 0);
  620. return 0;
  621. }
  622. /*******************************************************************************
  623. * FUNCTION: pt_mt_close
  624. *
  625. * SUMMARY: Close method for input device(touch) that clears call back
  626. * functions from TTDL attention list.
  627. *
  628. * PARAMETERS:
  629. * *input - pointer to input_dev structure
  630. ******************************************************************************/
  631. static void pt_mt_close(struct input_dev *input)
  632. {
  633. struct device *dev = input->dev.parent;
  634. struct pt_core_data *cd = dev_get_drvdata(dev);
  635. struct pt_mt_data *md = &cd->md;
  636. _pt_unsubscribe_attention(dev, PT_ATTEN_IRQ, PT_MT_NAME,
  637. pt_mt_attention, PT_MODE_OPERATIONAL);
  638. _pt_unsubscribe_attention(dev, PT_ATTEN_STARTUP, PT_MT_NAME,
  639. pt_startup_attention, 0);
  640. _pt_unsubscribe_attention(dev, PT_ATTEN_WAKE, PT_MT_NAME,
  641. pt_mt_wake_attention, 0);
  642. _pt_unsubscribe_attention(dev, PT_ATTEN_SUSPEND, PT_MT_NAME,
  643. pt_mt_suspend_attention, 0);
  644. _pt_unsubscribe_attention(dev, PT_ATTEN_RESUME, PT_MT_NAME,
  645. pt_mt_resume_attention, 0);
  646. mutex_lock(&md->mt_lock);
  647. if (!md->is_suspended) {
  648. pm_runtime_put(dev);
  649. md->is_suspended = true;
  650. }
  651. mutex_unlock(&md->mt_lock);
  652. }
  653. /*******************************************************************************
  654. * FUNCTION: pt_setup_input_device
  655. *
  656. * SUMMARY: Set up resolution, event signal capabilities and
  657. * register input device for touch.
  658. *
  659. * RETURN:
  660. * 0 = success
  661. * !0 = failure
  662. *
  663. * PARAMETERS:
  664. * *dev - pointer to device structure
  665. ******************************************************************************/
  666. static int pt_setup_input_device(struct device *dev)
  667. {
  668. struct pt_core_data *cd = dev_get_drvdata(dev);
  669. struct pt_mt_data *md = &cd->md;
  670. int signal = PT_IGNORE_VALUE;
  671. int max_x, max_y, max_p, min, max;
  672. int max_x_tmp, max_y_tmp;
  673. int i;
  674. int rc;
  675. pt_debug(dev, DL_INFO, "%s: Initialize event signals\n",
  676. __func__);
  677. __set_bit(EV_ABS, md->input->evbit);
  678. __set_bit(EV_REL, md->input->evbit);
  679. __set_bit(EV_KEY, md->input->evbit);
  680. #ifdef INPUT_PROP_DIRECT
  681. __set_bit(INPUT_PROP_DIRECT, md->input->propbit);
  682. #endif
  683. /* If virtualkeys enabled, don't use all screen */
  684. if (md->pdata->flags & PT_MT_FLAG_VKEYS) {
  685. max_x_tmp = md->pdata->vkeys_x;
  686. max_y_tmp = md->pdata->vkeys_y;
  687. } else {
  688. max_x_tmp = md->si->sensing_conf_data.res_x;
  689. max_y_tmp = md->si->sensing_conf_data.res_y;
  690. }
  691. /* get maximum values from the sysinfo data */
  692. if (md->pdata->flags & PT_MT_FLAG_FLIP) {
  693. max_x = max_y_tmp - 1;
  694. max_y = max_x_tmp - 1;
  695. } else {
  696. max_x = max_x_tmp - 1;
  697. max_y = max_y_tmp - 1;
  698. }
  699. max_p = md->si->sensing_conf_data.max_z;
  700. /* set event signal capabilities */
  701. for (i = 0; i < NUM_SIGNALS(md->pdata->frmwrk); i++) {
  702. signal = MT_PARAM_SIGNAL(md, i);
  703. if (signal != PT_IGNORE_VALUE) {
  704. __set_bit(signal, md->input->absbit);
  705. min = MT_PARAM_MIN(md, i);
  706. max = MT_PARAM_MAX(md, i);
  707. if (i == PT_ABS_ID_OST) {
  708. /* shift track ids down to start at 0 */
  709. max = max - min;
  710. min = min - min;
  711. } else if (i == PT_ABS_X_OST)
  712. max = max_x;
  713. else if (i == PT_ABS_Y_OST)
  714. max = max_y;
  715. else if (i == PT_ABS_P_OST)
  716. max = max_p;
  717. input_set_abs_params(md->input, signal, min, max,
  718. MT_PARAM_FUZZ(md, i), MT_PARAM_FLAT(md, i));
  719. pt_debug(dev, DL_INFO,
  720. "%s: register signal=%02X min=%d max=%d\n",
  721. __func__, signal, min, max);
  722. }
  723. }
  724. md->or_min = MT_PARAM_MIN(md, PT_ABS_OR_OST);
  725. md->or_max = MT_PARAM_MAX(md, PT_ABS_OR_OST);
  726. md->t_min = MT_PARAM_MIN(md, PT_ABS_ID_OST);
  727. md->t_max = MT_PARAM_MAX(md, PT_ABS_ID_OST);
  728. rc = md->mt_function.input_register_device(md->input,
  729. md->si->tch_abs[PT_TCH_T].max);
  730. if (rc < 0)
  731. pt_debug(dev, DL_ERROR, "%s: Error, failed register input device r=%d\n",
  732. __func__, rc);
  733. else
  734. md->input_device_registered = true;
  735. #ifdef EASYWAKE_TSG6
  736. input_set_capability(md->input, EV_KEY, KEY_F1);
  737. input_set_capability(md->input, EV_KEY, KEY_F2);
  738. input_set_capability(md->input, EV_KEY, KEY_F3);
  739. input_set_capability(md->input, EV_KEY, KEY_F4);
  740. input_set_capability(md->input, EV_KEY, KEY_F5);
  741. input_set_capability(md->input, EV_KEY, KEY_F6);
  742. input_set_capability(md->input, EV_KEY, KEY_F7);
  743. input_set_capability(md->input, EV_KEY, KEY_F8);
  744. input_set_capability(md->input, EV_KEY, KEY_WAKEUP);
  745. #endif
  746. return rc;
  747. }
  748. /*******************************************************************************
  749. * FUNCTION: pt_setup_input_attention
  750. *
  751. * SUMMARY: Wrapper function for pt_setup_input_device() register to TTDL
  752. * attention list.
  753. *
  754. * RETURN:
  755. * 0 = success
  756. * !0 = failure
  757. *
  758. * PARAMETERS:
  759. * *dev - pointer to device structure
  760. ******************************************************************************/
  761. static int pt_setup_input_attention(struct device *dev)
  762. {
  763. struct pt_core_data *cd = dev_get_drvdata(dev);
  764. struct pt_mt_data *md = &cd->md;
  765. int rc;
  766. md->si = _pt_request_sysinfo(dev);
  767. if (!md->si)
  768. return -EINVAL;
  769. rc = pt_setup_input_device(dev);
  770. _pt_unsubscribe_attention(dev, PT_ATTEN_STARTUP, PT_MT_NAME,
  771. pt_setup_input_attention, 0);
  772. return rc;
  773. }
  774. /*******************************************************************************
  775. * FUNCTION: pt_mt_probe
  776. *
  777. * SUMMARY: The probe function for touch input device
  778. *
  779. * RETURN:
  780. * 0 = success
  781. * !0 = failure
  782. *
  783. * PARAMETERS:
  784. * *dev - pointer to device structure
  785. ******************************************************************************/
  786. int pt_mt_probe(struct device *dev)
  787. {
  788. struct pt_core_data *cd = dev_get_drvdata(dev);
  789. struct pt_mt_data *md = &cd->md;
  790. struct pt_platform_data *pdata = dev_get_platdata(dev);
  791. struct pt_mt_platform_data *mt_pdata;
  792. int rc = 0;
  793. pt_debug(dev, DL_INFO,
  794. "%s: >>>>>> Register MT <<<<<<\n", __func__);
  795. if (!pdata || !pdata->mt_pdata) {
  796. pt_debug(dev, DL_ERROR,
  797. "%s: Missing platform data\n", __func__);
  798. rc = -ENODEV;
  799. goto error_no_pdata;
  800. }
  801. mt_pdata = pdata->mt_pdata;
  802. pt_init_function_ptrs(md);
  803. mutex_init(&md->mt_lock);
  804. md->dev = dev;
  805. md->pdata = mt_pdata;
  806. /* Create the input device and register it. */
  807. pt_debug(dev, DL_INFO,
  808. "%s: Create the input device and register it\n", __func__);
  809. md->input = input_allocate_device();
  810. if (!md->input) {
  811. pt_debug(dev, DL_ERROR, "%s: Error, failed to allocate input device\n",
  812. __func__);
  813. rc = -ENODEV;
  814. goto error_alloc_failed;
  815. } else
  816. md->input_device_allocated = true;
  817. if (md->pdata->inp_dev_name)
  818. md->input->name = md->pdata->inp_dev_name;
  819. else
  820. md->input->name = PT_MT_NAME;
  821. scnprintf(md->phys, sizeof(md->phys), "%s/input%d", dev_name(dev),
  822. cd->phys_num++);
  823. md->input->phys = md->phys;
  824. md->input->dev.parent = md->dev;
  825. md->input->open = pt_mt_open;
  826. md->input->close = pt_mt_close;
  827. input_set_drvdata(md->input, md);
  828. /* get sysinfo */
  829. md->si = _pt_request_sysinfo(dev);
  830. if (md->si) {
  831. rc = pt_setup_input_device(dev);
  832. if (rc)
  833. goto error_init_input;
  834. } else {
  835. pt_debug(dev, DL_ERROR, "%s: Fail get sysinfo pointer from core p=%p\n",
  836. __func__, md->si);
  837. _pt_subscribe_attention(dev, PT_ATTEN_STARTUP,
  838. PT_MT_NAME, pt_setup_input_attention, 0);
  839. }
  840. return 0;
  841. error_init_input:
  842. input_free_device(md->input);
  843. md->input_device_allocated = false;
  844. error_alloc_failed:
  845. error_no_pdata:
  846. pt_debug(dev, DL_ERROR, "%s failed.\n", __func__);
  847. return rc;
  848. }
  849. /*******************************************************************************
  850. * FUNCTION: pt_mt_release
  851. *
  852. * SUMMARY: The release function for touch input device
  853. *
  854. * RETURN:
  855. * 0 = success
  856. *
  857. * PARAMETERS:
  858. * *dev - pointer to device structure
  859. ******************************************************************************/
  860. int pt_mt_release(struct device *dev)
  861. {
  862. struct pt_core_data *cd;
  863. struct pt_mt_data *md;
  864. /* Ensure valid pointers before de-referencing them */
  865. if (dev) {
  866. cd = dev_get_drvdata(dev);
  867. if (cd)
  868. md = &cd->md;
  869. else
  870. return 0;
  871. } else {
  872. return 0;
  873. }
  874. /*
  875. * Second call this function may cause kernel panic if probe fail.
  876. * Use input_device_registered & input_device_allocated variable to
  877. * avoid unregister or free unavailable devive.
  878. */
  879. if (md && md->input_device_registered) {
  880. md->input_device_registered = false;
  881. input_unregister_device(md->input);
  882. /* Unregistering device will free the device too */
  883. md->input_device_allocated = false;
  884. } else if (md && md->input_device_allocated) {
  885. md->input_device_allocated = false;
  886. input_free_device(md->input);
  887. _pt_unsubscribe_attention(dev, PT_ATTEN_STARTUP,
  888. PT_MT_NAME, pt_setup_input_attention, 0);
  889. }
  890. return 0;
  891. }