pt_pen.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. #ifndef TTDL_KERNEL_SUBMISSION
  2. /*
  3. * pt_pen.c
  4. * Parade TrueTouch(TM) Standard Product CapSense Reports Module.
  5. * For use with Parade touchscreen controllers.
  6. * Supported parts include:
  7. * TMA5XX
  8. * TMA448
  9. * TMA445A
  10. * TT21XXX
  11. * TT31XXX
  12. * TT4XXXX
  13. * TT7XXX
  14. * TC3XXX
  15. *
  16. * Copyright (C) 2015-2021 Parade Technologies
  17. *
  18. * This program is free software; you can redistribute it and/or
  19. * modify it under the terms of the GNU General Public License
  20. * version 2, and only version 2, as published by the
  21. * Free Software Foundation.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU General Public License for more details.
  27. *
  28. * Contact Parade Technologies at www.paradetech.com <[email protected]>
  29. */
  30. #include "pt_regs.h"
  31. /*******************************************************************************
  32. * FUNCTION: pt_pen_lift_all
  33. *
  34. * SUMMARY: Reports pen liftoff action
  35. *
  36. * PARAMETERS:
  37. * *pend - pointer to pen data structure
  38. ******************************************************************************/
  39. static void pt_pen_lift_all(struct pt_pen_data *pend)
  40. {
  41. input_report_key(pend->input, BTN_STYLUS, 0);
  42. input_report_key(pend->input, BTN_STYLUS2, 0);
  43. input_report_key(pend->input, BTN_TOUCH, 0);
  44. input_report_key(pend->input, BTN_TOOL_PEN, 0);
  45. input_sync(pend->input);
  46. }
  47. /*******************************************************************************
  48. * FUNCTION: pt_get_pen_data
  49. *
  50. * SUMMARY: Gets axis of pen report
  51. *
  52. * PARAMETERS:
  53. * *pend - pointer to pen data structure
  54. * *xy_data - pointer to touch data
  55. ******************************************************************************/
  56. static void pt_get_pen(struct pt_pen_data *pend,
  57. struct pt_pen *pen, u8 *xy_data)
  58. {
  59. struct device *dev = pend->dev;
  60. struct pt_sysinfo *si = pend->si;
  61. enum pt_pen_abs abs;
  62. for (abs = PT_PEN_X; abs < PT_PEN_NUM_ABS; abs++) {
  63. if (!si->pen_abs[abs].report)
  64. continue;
  65. pt_get_touch_field(dev, &pen->abs[abs],
  66. si->pen_abs[abs].size,
  67. si->pen_abs[abs].max,
  68. xy_data + si->tch_abs[abs].ofs,
  69. si->pen_abs[abs].bofs);
  70. pt_debug(dev, DL_DEBUG, "%s: get %s=%04X(%d)\n",
  71. __func__, pt_pen_abs_string[abs],
  72. pen->abs[abs], pen->abs[abs]);
  73. }
  74. }
  75. /*******************************************************************************
  76. * FUNCTION: pt_xy_worker
  77. *
  78. * SUMMARY: Read xy_data for current pen touch
  79. *
  80. * RETURN:
  81. * 0 = success
  82. *
  83. * PARAMETERS:
  84. * *pend - pointer to pen data structure
  85. ******************************************************************************/
  86. static int pt_xy_worker(struct pt_pen_data *pend)
  87. {
  88. struct pt_sysinfo *si = pend->si;
  89. struct pt_pen pen;
  90. bool tool;
  91. pt_get_pen(pend, &pen, si->xy_data + 3);
  92. tool = pen.abs[PT_PEN_IV] ?
  93. BTN_TOOL_RUBBER : BTN_TOOL_PEN;
  94. input_report_abs(pend->input, ABS_X, pen.abs[PT_PEN_X]);
  95. input_report_abs(pend->input, ABS_Y, pen.abs[PT_PEN_Y]);
  96. input_report_abs(pend->input, ABS_PRESSURE, pen.abs[PT_PEN_P]);
  97. input_report_key(pend->input, BTN_STYLUS, pen.abs[PT_PEN_BS]);
  98. if (si->pen_abs[PT_PEN_2ND_BS].report)
  99. input_report_key(pend->input, BTN_STYLUS2,
  100. pen.abs[PT_PEN_2ND_BS]);
  101. input_report_key(pend->input, BTN_TOUCH, pen.abs[PT_PEN_TS]);
  102. input_report_key(pend->input, tool, pen.abs[PT_PEN_IR]);
  103. if (si->pen_abs[PT_PEN_X_TILT].report)
  104. input_report_abs(pend->input, ABS_TILT_X,
  105. pen.abs[PT_PEN_X_TILT]);
  106. if (si->pen_abs[PT_PEN_Y_TILT].report)
  107. input_report_abs(pend->input, ABS_TILT_Y,
  108. pen.abs[PT_PEN_Y_TILT]);
  109. input_sync(pend->input);
  110. return 0;
  111. }
  112. /*******************************************************************************
  113. * FUNCTION: pt_pen_attention
  114. *
  115. * SUMMARY: Wrapper function for pt_xy_worker() that register to TTDL attention
  116. * list.
  117. *
  118. * RETURN:
  119. * 0 = success
  120. * !0 = failure
  121. *
  122. * PARAMETERS:
  123. * *dev - pointer to device structure
  124. ******************************************************************************/
  125. static int pt_pen_attention(struct device *dev)
  126. {
  127. struct pt_core_data *cd = dev_get_drvdata(dev);
  128. struct pt_pen_data *pend = &cd->pend;
  129. int rc;
  130. if (pend->si->xy_mode[2] != pend->si->desc.pen_report_id)
  131. return 0;
  132. /* core handles handshake */
  133. mutex_lock(&pend->pen_lock);
  134. rc = pt_xy_worker(pend);
  135. mutex_unlock(&pend->pen_lock);
  136. if (rc < 0)
  137. pt_debug(dev, DL_ERROR,
  138. "%s: xy_worker error r=%d\n", __func__, rc);
  139. return rc;
  140. }
  141. /*******************************************************************************
  142. * FUNCTION: pt_startup_attention
  143. *
  144. * SUMMARY: Wrapper function for pt_pen_lift_all() that register to TTDL
  145. * attention list.
  146. *
  147. * RETURN:
  148. * 0 = success
  149. *
  150. * PARAMETERS:
  151. * *dev - pointer to device structure
  152. ******************************************************************************/
  153. static int pt_startup_attention(struct device *dev)
  154. {
  155. struct pt_core_data *cd = dev_get_drvdata(dev);
  156. struct pt_pen_data *pend = &cd->pend;
  157. mutex_lock(&pend->pen_lock);
  158. pt_pen_lift_all(pend);
  159. mutex_unlock(&pend->pen_lock);
  160. return 0;
  161. }
  162. /*******************************************************************************
  163. * FUNCTION: pt_pen_suspend_attention
  164. *
  165. * SUMMARY: Function for pen to enter suspend state that as following steps:
  166. * 1) Lift pen touch
  167. * 2) Set flag with suspend state
  168. * 3) Decrese pm system count
  169. *
  170. * RETURN:
  171. * 0 = success
  172. *
  173. * PARAMETERS:
  174. * *dev - pointer to device structure
  175. ******************************************************************************/
  176. static int pt_pen_suspend_attention(struct device *dev)
  177. {
  178. struct pt_core_data *cd = dev_get_drvdata(dev);
  179. struct pt_pen_data *pend = &cd->pend;
  180. mutex_lock(&pend->pen_lock);
  181. pt_pen_lift_all(pend);
  182. pend->is_suspended = true;
  183. mutex_unlock(&pend->pen_lock);
  184. pm_runtime_put(dev);
  185. return 0;
  186. }
  187. /*******************************************************************************
  188. * FUNCTION: pt_pen_resume_attention
  189. *
  190. * SUMMARY: Function for pen to leave suspend state that as following steps:
  191. * 1) Increse pm system count
  192. * 2) Clear suspend state flag
  193. *
  194. * RETURN:
  195. * 0 = success
  196. *
  197. * PARAMETERS:
  198. * *dev - pointer to device structure
  199. ******************************************************************************/
  200. static int pt_pen_resume_attention(struct device *dev)
  201. {
  202. struct pt_core_data *cd = dev_get_drvdata(dev);
  203. struct pt_pen_data *pend = &cd->pend;
  204. pm_runtime_get(dev);
  205. mutex_lock(&pend->pen_lock);
  206. pend->is_suspended = false;
  207. mutex_unlock(&pend->pen_lock);
  208. return 0;
  209. }
  210. /*******************************************************************************
  211. * FUNCTION: pt_pen_open
  212. *
  213. * SUMMARY: Open method for input device(pen) that sets up call back
  214. * functions to TTDL attention list
  215. *
  216. * RETURN:
  217. * 0 = success
  218. *
  219. * PARAMETERS:
  220. * *input - pointer to input_dev structure
  221. ******************************************************************************/
  222. static int pt_pen_open(struct input_dev *input)
  223. {
  224. struct device *dev = input->dev.parent;
  225. struct pt_core_data *cd = dev_get_drvdata(dev);
  226. struct pt_pen_data *pend = &cd->pend;
  227. pm_runtime_get_sync(dev);
  228. mutex_lock(&pend->pen_lock);
  229. pend->is_suspended = false;
  230. mutex_unlock(&pend->pen_lock);
  231. pt_debug(dev, DL_INFO, "%s: setup subscriptions\n", __func__);
  232. /* set up touch call back */
  233. _pt_subscribe_attention(dev, PT_ATTEN_IRQ, PT_PEN_NAME,
  234. pt_pen_attention, PT_MODE_OPERATIONAL);
  235. /* set up startup call back */
  236. _pt_subscribe_attention(dev, PT_ATTEN_STARTUP, PT_PEN_NAME,
  237. pt_startup_attention, 0);
  238. /* set up suspend call back */
  239. _pt_subscribe_attention(dev, PT_ATTEN_SUSPEND, PT_PEN_NAME,
  240. pt_pen_suspend_attention, 0);
  241. /* set up resume call back */
  242. _pt_subscribe_attention(dev, PT_ATTEN_RESUME, PT_PEN_NAME,
  243. pt_pen_resume_attention, 0);
  244. return 0;
  245. }
  246. /*******************************************************************************
  247. * FUNCTION: pt_pen_close
  248. *
  249. * SUMMARY: Close method for input device(pen) that clears call back
  250. * functions from TTDL attention list.
  251. *
  252. * PARAMETERS:
  253. * *input - pointer to input_dev structure
  254. ******************************************************************************/
  255. static void pt_pen_close(struct input_dev *input)
  256. {
  257. struct device *dev = input->dev.parent;
  258. struct pt_core_data *cd = dev_get_drvdata(dev);
  259. struct pt_pen_data *pend = &cd->pend;
  260. _pt_unsubscribe_attention(dev, PT_ATTEN_IRQ, PT_PEN_NAME,
  261. pt_pen_attention, PT_MODE_OPERATIONAL);
  262. _pt_unsubscribe_attention(dev, PT_ATTEN_STARTUP, PT_PEN_NAME,
  263. pt_startup_attention, 0);
  264. _pt_unsubscribe_attention(dev, PT_ATTEN_SUSPEND, PT_PEN_NAME,
  265. pt_pen_suspend_attention, 0);
  266. _pt_unsubscribe_attention(dev, PT_ATTEN_RESUME, PT_PEN_NAME,
  267. pt_pen_resume_attention, 0);
  268. mutex_lock(&pend->pen_lock);
  269. if (!pend->is_suspended) {
  270. pm_runtime_put(dev);
  271. pend->is_suspended = true;
  272. }
  273. mutex_unlock(&pend->pen_lock);
  274. }
  275. /*******************************************************************************
  276. * FUNCTION: pt_setup_input_device
  277. *
  278. * SUMMARY: Set up resolution, event signal capabilities and register input
  279. * device for pen.
  280. *
  281. * RETURN:
  282. * 0 = success
  283. * !0 = failure
  284. *
  285. * PARAMETERS:
  286. * *dev - pointer to device structure
  287. ******************************************************************************/
  288. static int pt_setup_input_device(struct device *dev)
  289. {
  290. struct pt_core_data *cd = dev_get_drvdata(dev);
  291. struct pt_pen_data *pend = &cd->pend;
  292. int i;
  293. int rc;
  294. u32 usage;
  295. int max_x, max_y, max_p;
  296. pt_debug(dev, DL_INFO, "%s: Initialize event signals\n",
  297. __func__);
  298. __set_bit(EV_ABS, pend->input->evbit);
  299. __set_bit(EV_KEY, pend->input->evbit);
  300. for (i = PT_PEN_X; i < PT_PEN_NUM_ABS; i++) {
  301. usage = pt_pen_abs_field_map[i];
  302. switch (usage) {
  303. case HID_GD_X:
  304. max_x = pend->si->sensing_conf_data.res_x;
  305. input_set_abs_params(pend->input,
  306. ABS_X, 0, max_x, 0, 0);
  307. break;
  308. case HID_GD_Y:
  309. max_y = pend->si->sensing_conf_data.res_y;
  310. input_set_abs_params(pend->input,
  311. ABS_Y, 0, max_y, 0, 0);
  312. break;
  313. case HID_DG_TIPPRESSURE:
  314. max_p = pend->si->sensing_conf_data.max_z;
  315. input_set_abs_params(pend->input,
  316. ABS_PRESSURE, 0, max_p, 0, 0);
  317. break;
  318. case HID_DG_INRANGE:
  319. input_set_capability(pend->input,
  320. EV_KEY, BTN_TOOL_PEN);
  321. break;
  322. case HID_DG_INVERT:
  323. input_set_capability(pend->input,
  324. EV_KEY, BTN_TOOL_RUBBER);
  325. break;
  326. case HID_DG_TILT_X:
  327. max_x = pend->si->pen_abs[i].max;
  328. input_set_abs_params(pend->input,
  329. ABS_TILT_X, 0, max_x, 0, 0);
  330. break;
  331. case HID_DG_TILT_Y:
  332. max_x = pend->si->pen_abs[i].max;
  333. input_set_abs_params(pend->input,
  334. ABS_TILT_Y, 0, max_x, 0, 0);
  335. break;
  336. case HID_DG_ERASER:
  337. case HID_DG_TIPSWITCH:
  338. input_set_capability(pend->input,
  339. EV_KEY, BTN_TOUCH);
  340. break;
  341. case HID_DG_BARRELSWITCH:
  342. input_set_capability(pend->input,
  343. EV_KEY, BTN_STYLUS);
  344. break;
  345. case HID_DG_BARRELSWITCH2:
  346. input_set_capability(pend->input,
  347. EV_KEY, BTN_STYLUS2);
  348. break;
  349. }
  350. }
  351. rc = input_register_device(pend->input);
  352. if (rc < 0)
  353. pt_debug(dev, DL_ERROR,
  354. "%s: Error, failed register input device r=%d\n",
  355. __func__, rc);
  356. else
  357. pend->input_device_registered = true;
  358. return rc;
  359. }
  360. /*******************************************************************************
  361. * FUNCTION: pt_setup_input_attention
  362. *
  363. * SUMMARY: Wrapper function for pt_setup_input_device() register to TTDL
  364. * attention list.
  365. *
  366. * RETURN:
  367. * 0 = success
  368. * !0 = failure
  369. *
  370. * PARAMETERS:
  371. * *dev - pointer to device structure
  372. ******************************************************************************/
  373. static int pt_setup_input_attention(struct device *dev)
  374. {
  375. struct pt_core_data *cd = dev_get_drvdata(dev);
  376. struct pt_pen_data *pend = &cd->pend;
  377. int rc;
  378. pend->si = _pt_request_sysinfo(dev);
  379. if (!pend->si)
  380. return -1;
  381. rc = pt_setup_input_device(dev);
  382. _pt_unsubscribe_attention(dev, PT_ATTEN_STARTUP, PT_PEN_NAME,
  383. pt_setup_input_attention, 0);
  384. return rc;
  385. }
  386. /*******************************************************************************
  387. * FUNCTION: pt_pen_probe
  388. *
  389. * SUMMARY: The probe function for pen input device
  390. *
  391. * RETURN:
  392. * 0 = success
  393. * !0 = failure
  394. *
  395. * PARAMETERS:
  396. * *dev - pointer to device structure
  397. ******************************************************************************/
  398. int pt_pen_probe(struct device *dev)
  399. {
  400. struct pt_core_data *cd = dev_get_drvdata(dev);
  401. struct pt_pen_data *pend = &cd->pend;
  402. struct pt_platform_data *pdata = dev_get_platdata(dev);
  403. struct pt_pen_platform_data *pen_pdata;
  404. int rc = 0;
  405. if (!pdata || !pdata->pen_pdata) {
  406. pt_debug(dev, DL_ERROR,
  407. "%s: Missing platform data\n", __func__);
  408. rc = -ENODEV;
  409. goto error_no_pdata;
  410. }
  411. pen_pdata = pdata->pen_pdata;
  412. mutex_init(&pend->pen_lock);
  413. pend->dev = dev;
  414. pend->pdata = pen_pdata;
  415. /* Create the input device and register it. */
  416. pt_debug(dev, DL_INFO,
  417. "%s: Create the input device and register it\n", __func__);
  418. pend->input = input_allocate_device();
  419. if (!pend->input) {
  420. pt_debug(dev, DL_ERROR,
  421. "%s: Error, failed to allocate input device\n",
  422. __func__);
  423. rc = -ENODEV;
  424. goto error_alloc_failed;
  425. } else
  426. pend->input_device_allocated = true;
  427. if (pend->pdata->inp_dev_name)
  428. pend->input->name = pend->pdata->inp_dev_name;
  429. else
  430. pend->input->name = PT_PEN_NAME;
  431. scnprintf(pend->phys, sizeof(pend->phys), "%s/input%d", dev_name(dev),
  432. cd->phys_num++);
  433. pend->input->phys = pend->phys;
  434. pend->input->dev.parent = pend->dev;
  435. pend->input->open = pt_pen_open;
  436. pend->input->close = pt_pen_close;
  437. input_set_drvdata(pend->input, pend);
  438. /* get sysinfo */
  439. pend->si = _pt_request_sysinfo(dev);
  440. if (pend->si) {
  441. rc = pt_setup_input_device(dev);
  442. if (rc)
  443. goto error_init_input;
  444. } else {
  445. pt_debug(dev, DL_ERROR,
  446. "%s: Fail get sysinfo pointer from core p=%p\n",
  447. __func__, pend->si);
  448. _pt_subscribe_attention(dev, PT_ATTEN_STARTUP,
  449. PT_PEN_NAME, pt_setup_input_attention, 0);
  450. }
  451. return 0;
  452. error_init_input:
  453. input_free_device(pend->input);
  454. pend->input_device_allocated = false;
  455. error_alloc_failed:
  456. error_no_pdata:
  457. pt_debug(dev, DL_ERROR, "%s failed.\n", __func__);
  458. return rc;
  459. }
  460. /*******************************************************************************
  461. * FUNCTION: pt_pen_release
  462. *
  463. * SUMMARY: The release function for pen input device
  464. *
  465. * RETURN:
  466. * 0 = success
  467. *
  468. * PARAMETERS:
  469. * *dev - pointer to device structure
  470. ******************************************************************************/
  471. int pt_pen_release(struct device *dev)
  472. {
  473. struct pt_core_data *cd;
  474. struct pt_pen_data *pend;
  475. /* Ensure valid pointers before de-referencing them */
  476. if (dev) {
  477. cd = dev_get_drvdata(dev);
  478. if (cd)
  479. pend = &cd->pend;
  480. else
  481. return 0;
  482. } else {
  483. return 0;
  484. }
  485. /*
  486. * Second call this function may cause kernel panic if probe fail.
  487. * Use input_device_registered & input_device_allocated variable to
  488. * avoid unregister or free unavailable devive.
  489. */
  490. if (pend && pend->input_device_registered) {
  491. pend->input_device_registered = false;
  492. input_unregister_device(pend->input);
  493. /* Unregistering device will free the device too */
  494. pend->input_device_allocated = false;
  495. } else if (pend && pend->input_device_allocated) {
  496. pend->input_device_allocated = false;
  497. input_free_device(pend->input);
  498. _pt_unsubscribe_attention(dev, PT_ATTEN_STARTUP,
  499. PT_PEN_NAME, pt_setup_input_attention, 0);
  500. }
  501. return 0;
  502. }
  503. #endif /*!TTDL_KERNEL_SUBMISSION */