tpd_debug.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2019 MediaTek Inc.
  4. */
  5. #include <linux/vmalloc.h>
  6. #include <linux/uaccess.h>
  7. #include <linux/major.h>
  8. #include <linux/miscdevice.h>
  9. #include <linux/i2c.h>
  10. #include <linux/delay.h>
  11. #include "tpd.h"
  12. #include "met_ftrace_touch.h"
  13. #ifdef TPD_DEBUG_CODE
  14. int tpd_fail_count;
  15. int tpd_trial_count;
  16. int tpd_debug_nr;
  17. module_param(tpd_debug_nr, int, 0644);
  18. module_param(tpd_fail_count, int, 0644);
  19. module_param(tpd_trial_count, int, 0644);
  20. int tpd_debug_time;
  21. long tpd_last_2_int_time[2] = { 0 };
  22. long tpd_last_down_time;
  23. int tpd_start_profiling;
  24. int tpd_down_status;
  25. module_param(tpd_debug_time, int, 0644);
  26. void tpd_debug_set_time(void)
  27. {
  28. struct timeval t;
  29. if (!tpd_debug_time && !tpd_em_log)
  30. return;
  31. do_gettimeofday(&t);
  32. tpd_last_2_int_time[0] = tpd_last_2_int_time[1];
  33. tpd_last_2_int_time[1] = (t.tv_sec & 0xFFF) * 1000000 + t.tv_usec;
  34. /* */
  35. /* Start profiling while receive touch DOWN event */
  36. /* Stop profiling while the first frame is upadted */
  37. /* */
  38. if (!tpd_down_status) {
  39. tpd_start_profiling = 1;
  40. tpd_last_down_time = tpd_last_2_int_time[1];
  41. }
  42. }
  43. #ifdef TPD_DEBUG_TRACK
  44. int tpd_debug_track;
  45. int tpd_debug_track_color;
  46. int tpd_debug_touch_up;
  47. module_param(tpd_debug_track, int, 0644);
  48. void tpd_draw(int x, int y)
  49. {
  50. UINT16 *buf = (UINT16 *) dal_fb_addr;
  51. buf = buf + (x + y * TPD_RES_X);
  52. tpd_debug_track_color += (tpd_debug_track_color >= 31 ? 0 : 1);
  53. *buf = (0xffe0 + tpd_debug_track_color);
  54. }
  55. void tpd_down_debug_track(int x, int y)
  56. {
  57. if (tpd_debug_touch_up == 1) {
  58. DAL_Clean();
  59. tpd_debug_touch_up = 0;
  60. }
  61. LCD_LayerEnable(5, TRUE);
  62. tpd_draw(x - 1, y - 1);
  63. tpd_draw(x, y - 1);
  64. tpd_draw(x + 1, y - 1);
  65. tpd_draw(x - 1, y);
  66. tpd_draw(x + 1, y);
  67. tpd_draw(x - 1, y + 1);
  68. tpd_draw(x, y + 1);
  69. tpd_draw(x + 1, y + 1);
  70. }
  71. void tpd_up_debug_track(int x, int y)
  72. {
  73. if (x == 0 && y == 0) {
  74. tpd_debug_track_color = 0;
  75. DAL_Clean();
  76. }
  77. tpd_debug_touch_up = 1;
  78. }
  79. #endif /* TPD_DEBUG_TRACK */
  80. #define BUFFER_SIZE 128
  81. int tpd_em_log;
  82. module_param(tpd_em_log, int, 0664);
  83. void tpd_enable_em_log(int enable)
  84. {
  85. if (enable)
  86. tpd_em_log = 1;
  87. else
  88. tpd_em_log = 0;
  89. }
  90. EXPORT_SYMBOL(tpd_enable_em_log);
  91. int tpd_em_log_to_fs;
  92. module_param(tpd_em_log_to_fs, int, 0664);
  93. int tpd_em_log_first = 1;
  94. struct tpd_em_log_struct {
  95. struct list_head list;
  96. char data[BUFFER_SIZE];
  97. };
  98. static LIST_HEAD(tpd_em_log_list);
  99. int tpd_log_line_buffer = 128; /* per line 128 bytes */
  100. int tpd_log_line_cnt = 1024 * 10;
  101. module_param(tpd_log_line_buffer, int, 0664);
  102. module_param(tpd_log_line_cnt, int, 0664);
  103. struct tpd_debug_log_buf {
  104. unsigned int head;
  105. unsigned int tail;
  106. spinlock_t buffer_lock;
  107. unsigned int cnt;
  108. unsigned char *buffer;
  109. };
  110. struct tpd_debug_log_buf tpd_buf;
  111. static int tpd_debug_log_open(struct inode *inode, struct file *file)
  112. {
  113. if (tpd_buf.buffer == NULL)
  114. tpd_buf.buffer =
  115. vmalloc(tpd_log_line_cnt * tpd_log_line_buffer);
  116. if (tpd_buf.buffer == NULL) {
  117. pr_info("tpd_log: nomem for tpd_buf->buffer\n");
  118. return -ENOMEM;
  119. }
  120. spin_lock(&tpd_buf.buffer_lock);
  121. tpd_buf.head = tpd_buf.tail = 0;
  122. tpd_buf.cnt = 0;
  123. spin_unlock(&tpd_buf.buffer_lock);
  124. file->private_data = &tpd_buf;
  125. pr_debug("[tpd_em_log]: open log file\n");
  126. return 0;
  127. }
  128. static int tpd_debug_log_release(struct inode *inode, struct file *file)
  129. {
  130. unsigned char *tmp_buffer = NULL;
  131. pr_debug("[tpd_em_log]: close log file\n");
  132. spin_lock(&tpd_buf.buffer_lock);
  133. tmp_buffer = tpd_buf.buffer;
  134. tpd_buf.buffer = NULL;
  135. spin_unlock(&tpd_buf.buffer_lock);
  136. if (tmp_buffer)
  137. vfree(tmp_buffer);
  138. /* free(tpd_buf); */
  139. return 0;
  140. }
  141. static ssize_t tpd_debug_log_write(struct file *file, const char __user *buffer,
  142. size_t count, loff_t *ppos)
  143. {
  144. return 0;
  145. }
  146. static ssize_t tpd_debug_log_read(struct file *file, char __user *buffer,
  147. size_t count, loff_t *ppos)
  148. {
  149. struct tpd_debug_log_buf *tpd_buf =
  150. (struct tpd_debug_log_buf *)file->private_data;
  151. unsigned int retval = 0, unit = tpd_log_line_buffer;
  152. unsigned char *tmp_buf = NULL;
  153. if (tpd_buf == NULL)
  154. return -ENOMEM;
  155. if (tpd_buf->head == tpd_buf->tail && (file->f_flags & O_NONBLOCK))
  156. return -EAGAIN;
  157. while ((count - retval) >= unit) {
  158. spin_lock_irq(&tpd_buf->buffer_lock);
  159. if (tpd_buf->head != tpd_buf->tail) {
  160. tmp_buf = &tpd_buf->buffer[tpd_buf->tail++ * unit];
  161. tpd_buf->tail &= tpd_log_line_cnt - 1;
  162. } else {
  163. spin_unlock_irq(&tpd_buf->buffer_lock);
  164. break;
  165. }
  166. spin_unlock_irq(&tpd_buf->buffer_lock);
  167. if (copy_to_user(buffer + retval, tmp_buf, unit))
  168. return -EFAULT;
  169. retval += unit;
  170. }
  171. return retval;
  172. }
  173. static unsigned char *tpd_log_find_buffer(void)
  174. {
  175. unsigned char *buffer = NULL;
  176. unsigned int unit = tpd_log_line_buffer;
  177. if (tpd_buf.buffer == NULL) {
  178. pr_info("[tpd_em_log] :tpd_buf.buffer is NULL\n");
  179. return NULL;
  180. }
  181. spin_lock(&tpd_buf.buffer_lock);
  182. buffer = &tpd_buf.buffer[tpd_buf.head++ * unit];
  183. tpd_buf.head &= tpd_log_line_cnt - 1;
  184. spin_unlock(&tpd_buf.buffer_lock);
  185. if (tpd_buf.head == tpd_buf.tail) {
  186. snprintf(buffer, unit, "[tpd_em_log] overlay !!!!!\n");
  187. return NULL;
  188. }
  189. memset(buffer, 0, unit);
  190. return buffer;
  191. }
  192. static const struct file_operations tpd_debug_log_fops = {
  193. .owner = THIS_MODULE,
  194. .read = tpd_debug_log_read,
  195. .write = tpd_debug_log_write,
  196. .open = tpd_debug_log_open,
  197. .release = tpd_debug_log_release,
  198. };
  199. static struct miscdevice tpd_debug_log_dev = {
  200. .minor = MISC_DYNAMIC_MINOR,
  201. .name = "tpd_em_log",
  202. .fops = &tpd_debug_log_fops,
  203. };
  204. #ifndef CREATE_TRACE_POINTS
  205. #define CREATE_TRACE_POINTS
  206. #endif
  207. noinline void MET_touch(int raw_x, int raw_y,
  208. int cal_x, int cal_y, int p, int down)
  209. {
  210. struct timeval t;
  211. do_gettimeofday(&t);
  212. if ((tpd_down_status == 0 && down == 1) ||
  213. (tpd_down_status == 1 && down == 0)) {
  214. trace_MET_touch("EV_KEY",
  215. t.tv_sec, t.tv_usec, "BTN_TOUCH", down);
  216. tpd_down_status = !tpd_down_status;
  217. }
  218. if (tpd_down_status) {
  219. trace_MET_touch("EV_ABS", t.tv_sec, t.tv_usec, "X", raw_x);
  220. trace_MET_touch("EV_ABS", t.tv_sec, t.tv_usec, "Y", raw_y);
  221. }
  222. }
  223. void tpd_em_log_output(int raw_x, int raw_y,
  224. int cal_x, int cal_y, int p, int down)
  225. {
  226. if (down == TPD_TYPE_INT_DOWN) {
  227. pr_debug("[tpd_em_log] int trigger down\n");
  228. } else if (down == TPD_TYPE_INT_UP) {
  229. pr_debug("[tpd_em_log] int trigger up\n");
  230. } else if (down == TPD_TYPE_TIMER) {
  231. pr_debug("[tpd_em_log] timer trigger\n");
  232. } else if (down == TPD_TYPE_RAW_DATA) {
  233. if (tpd_em_log == TPD_TYPE_RAW_DATA) {
  234. pr_debug("[tpd_em_log] rx=%d,ry=%d,rz1=%d"
  235. SPLIT "rz2=%d,p=%d,r\n",
  236. raw_x, raw_y, cal_x, cal_y, p);
  237. }
  238. } else if (down == TPD_TYPE_REJECT1) {
  239. pr_debug("[tpd_em_log] the first or last point is rejected\n");
  240. } else if (down == TPD_TYPE_REJECT2) {
  241. pr_debug
  242. ("[tpd_em_log] pressure(%d) > NICE_PRESSURE(%d)"
  243. SPLIT "debounce debt0:%d ms, debt1:%d ms, spl_num:%d\n",
  244. raw_x, raw_y, cal_x, cal_y, p);
  245. } else if (down == TPD_TYPE_FIST_LATENCY) {
  246. pr_debug("[tpd_em_log] The first touch latency is %d ms\n",
  247. raw_x / 1000);
  248. } else if (down && tpd_down_status == 0) {
  249. pr_debug("[tpd_em_log] rx=%d,ry=%d,cx=%d"
  250. SPLIT "cy=%d,p=%d,d(+%ld ms)\n",
  251. raw_x, raw_y, cal_x, cal_y, p,
  252. (tpd_last_2_int_time[1] -
  253. tpd_last_2_int_time[0]) / 1000);
  254. } else if (down && tpd_down_status != 0) {
  255. pr_debug("[tpd_em_log] rx=%d,ry=%d,cx=%d"
  256. SPLIT "cy=%d,p=%d,m(+%ld ms)\n",
  257. raw_x, raw_y, cal_x, cal_y, p,
  258. (tpd_last_2_int_time[1] -
  259. tpd_last_2_int_time[0]) / 1000);
  260. } else {
  261. pr_debug("[tpd_em_log] rx=%d,ry=%d,cx=%d"
  262. SPLIT "cy=%d,p=%d,u(+%ld ms)\n",
  263. raw_x, raw_y, cal_x, cal_y, p,
  264. (tpd_last_2_int_time[1] -
  265. tpd_last_2_int_time[0]) / 1000);
  266. }
  267. }
  268. void tpd_em_log_store(int raw_x, int raw_y,
  269. int cal_x, int cal_y, int p, int down)
  270. {
  271. /* static struct proc_dir_entry *entry = NULL; */
  272. /* struct tpd_em_log_struct *tpd_em_log_struct_new; */
  273. struct timeval t;
  274. unsigned char *buffer = NULL;
  275. /* unsigned int unit = tpd_log_line_buffer; */
  276. buffer = tpd_log_find_buffer();
  277. if (buffer == NULL) {
  278. pr_info("not buffer\n");
  279. return;
  280. }
  281. do_gettimeofday(&t);
  282. if (down == TPD_TYPE_INT_DOWN) {
  283. snprintf(buffer, tpd_log_line_buffer,
  284. "[%5lu.%06lu][tpd_em_log] int trigger down\n",
  285. (t.tv_sec & 0xFFF), t.tv_usec);
  286. } else if (down == TPD_TYPE_INT_UP) {
  287. snprintf(buffer, tpd_log_line_buffer,
  288. "[%5lu.%06lu][tpd_em_log] int trigger up\n",
  289. (t.tv_sec & 0xFFF), t.tv_usec);
  290. } else if (down == TPD_TYPE_TIMER) {
  291. snprintf(buffer, tpd_log_line_buffer,
  292. "[%5lu.%06lu][tpd_em_log] timer trigger\n",
  293. (t.tv_sec & 0xFFF), t.tv_usec);
  294. } else if (down == TPD_TYPE_RAW_DATA) {
  295. if (tpd_em_log == TPD_TYPE_RAW_DATA) {
  296. snprintf(buffer, tpd_log_line_buffer,
  297. "[%5lu.%06lu][tpd_em_log]"
  298. SPLIT "rx=%d,ry=%d,rz1=%d,rz2=%d,p=%d,r\n",
  299. (t.tv_sec & 0xFFF), t.tv_usec,
  300. raw_x, raw_y, cal_x, cal_y, p);
  301. }
  302. } else if (down == TPD_TYPE_REJECT1) {
  303. snprintf(buffer, tpd_log_line_buffer,
  304. "[%5lu.%06lu][tpd_em_log]"
  305. SPLIT "the first or last point is rejected\n",
  306. (t.tv_sec & 0xFFF), t.tv_usec);
  307. } else if (down == TPD_TYPE_REJECT2) {
  308. snprintf(buffer, tpd_log_line_buffer,
  309. "[%5lu.%06lu][tpd_em_log]"
  310. SPLIT "pressure(%d) > NICE_PRESSURE(%d), "
  311. SPLIT "debounce debt0:%d, debt1:%d, spl_num:%d\n",
  312. (t.tv_sec & 0xFFF), t.tv_usec,
  313. raw_x, raw_y, cal_x, cal_y, p);
  314. } else if (down == TPD_TYPE_FIST_LATENCY) {
  315. snprintf(buffer, tpd_log_line_buffer,
  316. "[%5lu.%06lu][tpd_em_log]"
  317. SPLIT "The first touch latency is %d ms\n",
  318. (t.tv_sec & 0xFFF), t.tv_usec, raw_x / 1000);
  319. } else if (down && tpd_down_status == 0) {
  320. snprintf(buffer, tpd_log_line_buffer,
  321. "[%5lu.%06lu][tpd_em_log]"
  322. SPLIT "rx=%d,ry=%d,cx=%d,cy=%d,p=%d,d(+%ld ms)\n",
  323. (t.tv_sec & 0xFFF), t.tv_usec,
  324. raw_x, raw_y, cal_x, cal_y, p,
  325. (tpd_last_2_int_time[1] -
  326. tpd_last_2_int_time[0]) / 1000);
  327. } else if (down && tpd_down_status != 0) {
  328. snprintf(buffer, tpd_log_line_buffer,
  329. "[%5lu.%06lu][tpd_em_log]"
  330. SPLIT "rx=%d,ry=%d,cx=%d,cy=%d,p=%d,d(+%ld ms)\n",
  331. (t.tv_sec & 0xFFF), t.tv_usec,
  332. raw_x, raw_y, cal_x, cal_y, p,
  333. (tpd_last_2_int_time[1] -
  334. tpd_last_2_int_time[0]) / 1000);
  335. } else {
  336. snprintf(buffer, tpd_log_line_buffer,
  337. "[%5lu.%06lu][tpd_em_log]"
  338. SPLIT "rx=%d,ry=%d,cx=%d,cy=%d,p=%d,u(+%ld ms)\n",
  339. (t.tv_sec & 0xFFF), t.tv_usec,
  340. raw_x, raw_y, cal_x, cal_y, p,
  341. (tpd_last_2_int_time[1] -
  342. tpd_last_2_int_time[0]) / 1000);
  343. }
  344. /* list_add_tail(&tpd_em_log_struct_new->list, &tpd_em_log_list); */
  345. }
  346. void tpd_em_log_release(void)
  347. {
  348. struct tpd_em_log_struct *p, *p_tmp;
  349. if (!tpd_em_log_first) {
  350. remove_proc_entry("tpd_em_log", NULL);
  351. list_for_each_entry_safe(p, p_tmp, &tpd_em_log_list, list) {
  352. list_del(&p->list);
  353. kfree(p);
  354. }
  355. tpd_em_log_first = 1;
  356. tpd_em_log_to_fs = 0;
  357. }
  358. }
  359. int tpd_log_init(void)
  360. {
  361. if (misc_register(&tpd_debug_log_dev) < 0) {
  362. pr_info("[tpd_em_log] :register device failed\n");
  363. return -1;
  364. }
  365. pr_info("[tpd_em_log] :register device successfully\n");
  366. spin_lock_init(&tpd_buf.buffer_lock);
  367. return 0;
  368. }
  369. EXPORT_SYMBOL_GPL(tpd_log_init);
  370. void tpd_log_exit(void)
  371. {
  372. misc_deregister(&tpd_debug_log_dev);
  373. }
  374. EXPORT_SYMBOL_GPL(tpd_log_exit);
  375. int tpd_debuglog;
  376. module_param(tpd_debuglog, int, 0664);
  377. #endif /* TPD_DEBUG_CODE */