pt_mt_common.c 27 KB

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