blob: 72df84c2d076fa4984e60739b65f7aab17e9e45d [file] [log] [blame]
masonwangcdc58ea2021-07-27 09:54:47 +08001// SPDX-License-Identifier: GPL-2.0
2/* Himax Android Driver Sample Code for debug nodes
3 *
4 * Copyright (C) 2019 Himax Corporation.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include "himax_debug.h"
17#include "himax_ic_core.h"
18
19#if defined(HX_TP_PROC_2T2R)
20 bool Is_2T2R;
21EXPORT_SYMBOL(Is_2T2R);
22 int HX_RX_NUM_2;
23 int HX_TX_NUM_2;
24#endif
25
26uint8_t g_diag_arr_num;
masonwang533a4032021-08-05 09:57:24 +080027bool g_test_result;
masonwangcdc58ea2021-07-27 09:54:47 +080028
29int g_max_mutual;
30int g_min_mutual = 0xFFFF;
31int g_max_self;
32int g_min_self = 0xFFFF;
33
34/* moved from debug.h */
35
36static char g_file_path[256];
37
38uint8_t proc_reg_addr[4];
39uint8_t proc_reg_addr_type;
40uint8_t *proc_reg_buf;
41uint8_t proc_reg_85xx_flag;
42
43struct proc_dir_entry *himax_proc_stack_file;
44struct proc_dir_entry *himax_proc_delta_file;
45struct proc_dir_entry *himax_proc_dc_file;
46struct proc_dir_entry *himax_proc_baseline_file;
47bool dsram_flag;
48
49#if defined(HX_TP_PROC_2T2R)
50uint32_t *diag_mutual_2;
51#endif
52int32_t *diag_mutual;
53int32_t *diag_mutual_new;
54int32_t *diag_mutual_old;
55uint8_t hx_state_info[2];
56uint8_t diag_coor[128];
57int32_t *diag_self;
58int32_t *diag_self_new;
59int32_t *diag_self_old;
60
61struct proc_dir_entry *himax_proc_debug_file;
62bool fw_update_complete;
63bool fw_update_going;
64int handshaking_result;
65unsigned char debug_level_cmd;
66uint8_t cmd_set[8];
67uint8_t mutual_set_flag;
68
69struct proc_dir_entry *himax_proc_flash_dump_file;
70uint8_t *g_dump_buffer;
71uint8_t g_dump_cmd;
72uint8_t g_dump_show;
73uint32_t g_dump_addr;
74uint32_t g_dump_size;
75uint8_t g_flash_progress;
76bool g_flash_dump_rst; /*Fail = 0, Pass = 1*/
77
78uint32_t **raw_data_array;
79uint8_t X_NUM;
80uint8_t Y_NUM;
81uint8_t sel_type = 0x0D;
82
83/* Moved from debug.h End */
84char buf_tmp[BUF_SIZE] = {0};
85
86struct proc_dir_entry *himax_proc_pen_pos_file;
87
88#if defined(KERNEL_VER_ABOVE_5_10)
89struct timespec64 timeStart, timeEnd, timeDelta;
90#else
91struct timespec timeStart, timeEnd, timeDelta;
92#endif
93int g_switch_mode;
94/*
95 * Segment : Himax PROC Debug Function
96 */
97
98/****** useful functions ******/
99int count_char(char *input)
100{
101 int count = 0;
102 int i = 0;
103
104 for (i = 0; input[i] != '\0'; i++)
105 count++;
106 return count;
107}
108
109#define SIOS_DBG_STR "i = %d, j =%d, idx_find_str=%d, sts_find[%d]=%d\n"
110static int str_idx_of_str(char *base, char *find)
111{
112 int i = 0, j = 0;
113 int idx_find_str = 0;
114 int len_find_str = strlen(find);
115 int len_base_str = strlen(base);
116 int ret = -1;
117 int sts_find[256];
118 if (len_find_str > 256)
119 len_find_str = 256;
120
121 for (i = 0; i < len_base_str; i++) {
122 if (i + len_find_str > len_base_str) {
123 I("Command Check End!\n");
124 sts_find[0] = -1;
125 goto END;
126 }
127 for (j = 0; j < len_find_str; j++) {
128 if (*(base + i + j) == *(find + idx_find_str)) {
129 sts_find[idx_find_str] = i + j;
130 I(SIOS_DBG_STR,
131 i, j, idx_find_str,
132 idx_find_str, sts_find[idx_find_str]);
133 if (idx_find_str++ == (len_find_str - 1)) {
134 I("all check finish!\n");
135 goto END;
136 }
137 } else {
138 idx_find_str = 0;
139 sts_find[0] = -1;
140 break;
141 }
142 }
143 }
144END:
145 ret = sts_find[0];
146 return ret;
147}
148static void _str_to_arr_in_char(char **arr, int arr_size, char *str, char c)
149{
150 int i = 0;
151 int _arr_str_idx = 0;
152 int _arr_idx = 0;
153 int _arr_max_idx = arr_size;
154
155 for (i = 0; str[i] != '\0'; i++) {
156 if (_arr_max_idx <= _arr_idx) {
157 I("%s: Oversize!\n", __func__);
158 goto END;
159 }
160 if (str[i] == c || str[i] == '\0') {
161 I("%s: String parse compelete!\n", __func__);
162 _arr_idx++;
163 _arr_str_idx = 0;
164 } else {
165 arr[_arr_idx][_arr_str_idx] = str[i];
166 _arr_str_idx++;
167 continue;
168 }
169 }
170END:
171 return;
172}
173
174bool chk_normal_str(char *str)
175{
176 int i = 0;
177 bool result = false;
178 int str_len = strlen(str);
179
180 I("%s, str_len=%d\n", __func__, str_len);
181 for (i = 0; i < str_len; i++) {
182 if (str[i] >= '0' && str[i] <= '9') {
183 result = true;
184 continue;
185 } else if (str[i] >= 'A' && str[i] <= 'Z') {
186 result = true;
187 continue;
188 } else if (str[i] >= 'a' && str[i] <= 'z') {
189 result = true;
190 continue;
191 } else {
192 result = false;
193 break;
194 }
195 }
196 return result;
197}
198bool chk_normal_char(char c)
199{
200 bool result = false;
201
202 if (c >= '0' && c <= '9')
203 result = true;
204 else if (c >= 'A' && c <= 'Z')
205 result = true;
206 else if (c >= 'a' && c <= 'z')
207 result = true;
208 else
209 result = false;
210
211 return result;
212}
213/* claculate 10's power function */
214static int himax_power_cal(int pow, int number, int base)
215{
216 int i = 0;
217 int result = 1;
218
219 for (i = 0; i < pow; i++)
220 result *= base;
221 result = result * number;
222
223 return result;
224
225}
226
227/* String to int */
228static int hiamx_parse_str2int(char *str)
229{
230 int i = 0;
231 int temp_cal = 0;
232 int result = -948794;
233 unsigned int str_len = strlen(str);
234 int negtive_flag = 0;
235
236 for (i = 0; i < str_len; i++) {
237 if (i == 0)
238 result = 0;
239 if (str[i] != '-' && str[i] > '9' && str[i] < '0') {
240 E("%s: Parsing fail!\n", __func__);
241 result = -9487;
242 negtive_flag = 0;
243 break;
244 }
245 if (str[i] == '-') {
246 negtive_flag = 1;
247 continue;
248 }
249 temp_cal = str[i] - '0';
250 result += himax_power_cal(str_len-i-1, temp_cal, 10);
251 /* str's the lowest char is the number's the highest number
252 * So we should reverse this number before using the power
253 * function
254 * -1: starting number is from 0 ex:10^0 = 1,10^1=10
255 */
256 }
257
258 if (negtive_flag == 1)
259 result = 0 - result;
260
261 return result;
262}
263
264/* String in Hex to int */
265static int hx_parse_hexstr2int(char *str)
266{
267 int i = 0;
268 int temp_cal = 0;
269 int result = -948794;
270 unsigned int str_len = strlen(str);
271 int negtive_flag = 0;
272
273 for (i = 0; i < str_len; i++) {
274 if (i == 0)
275 result = 0;
276 if (str[i] == '-' && i == 0) {
277 negtive_flag = 1;
278 continue;
279 } else if (str[i] <= '9' && str[i] >= '0') {
280 temp_cal = str[i] - '0';
281 result += himax_power_cal(str_len-i-1, temp_cal, 16);
282 } else if (str[i] <= 'f' && str[i] >= 'a') {
283 temp_cal = str[i] - 'a' + 10;
284 result += himax_power_cal(str_len-i-1, temp_cal, 16);
285 } else if (str[i] <= 'F' && str[i] >= 'A') {
286 temp_cal = str[i] - 'A' + 10;
287 result += himax_power_cal(str_len-i-1, temp_cal, 16);
288 } else {
289 E("%s: Parsing fail!\n", __func__);
290 result = -9487;
291 negtive_flag = 0;
292 break;
293 }
294 }
295
296 if (negtive_flag == 1)
297 result = 0 - result;
298
299 return result;
300}
301
302/****** end ******/
303static int himax_crc_test_read(struct seq_file *m)
304{
305 int ret = 0;
306 uint8_t result = 0;
307 uint32_t size = 0;
308
309 g_core_fp.fp_sense_off(true);
310 msleep(20);
311 if (g_core_fp._diff_overlay_flash() == 1)
312 size = FW_SIZE_128k;
313 else
314 size = FW_SIZE_64k;
315 result = g_core_fp.fp_calculateChecksum(false, size);
316 g_core_fp.fp_sense_on(0x01);
317
318 if (result)
319 seq_printf(m,
320 "CRC test is Pass!\n");
321 else
322 seq_printf(m,
323 "CRC test is Fail!\n");
324
325
326 return ret;
327}
328
masonwang533a4032021-08-05 09:57:24 +0800329static int himax_proc_fw_debug_read(struct seq_file *m)
masonwangcdc58ea2021-07-27 09:54:47 +0800330{
331 int ret = 0;
332 uint8_t i = 0;
333 uint8_t addr[4] = {0};
334 uint8_t data[4] = {0};
335 int len = 0;
336
337 len = (size_t)(sizeof(dbg_reg_ary)/sizeof(uint32_t));
338
339 for (i = 0; i < len; i++) {
340 himax_parse_assign_cmd(dbg_reg_ary[i], addr, 4);
341 g_core_fp.fp_register_read(addr, data, DATA_LEN_4);
342
343 seq_printf(m,
344 "reg[0-3] : 0x%08X = 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
345 dbg_reg_ary[i], data[0], data[1], data[2], data[3]);
346 I("reg[0-3] : 0x%08X = 0x%02X, 0x%02X, 0x%02X, 0x%02X\n",
347 dbg_reg_ary[i], data[0], data[1], data[2], data[3]);
348 }
349
350 return ret;
351}
352
353static int himax_attn_read(struct seq_file *m)
354{
355 int ret = 0;
356 struct himax_ts_data *ts_data;
357
358 ts_data = private_ts;
359
360 seq_printf(m, "attn = %x\n",
361 himax_int_gpio_read(ts_data->pdata->gpio_irq));
362
363 return ret;
364}
365
366static int himax_layout_read(struct seq_file *m)
367{
368 struct himax_ts_data *ts = private_ts;
369 size_t ret = 0;
370
371 if (debug_data->is_call_help) {
372 seq_printf(m, HELP_LAYOUT);
373 debug_data->is_call_help = false;
374 } else {
375 seq_printf(m, "%d ",
376 ts->pdata->abs_x_min);
377 seq_printf(m, "%d ",
378 ts->pdata->abs_x_max);
379 seq_printf(m, "%d ",
380 ts->pdata->abs_y_min);
381 seq_printf(m, "%d ",
382 ts->pdata->abs_y_max);
383 seq_puts(m, "\n");
384 }
385
386 return ret;
387}
388
389static ssize_t himax_layout_write(char *buf, size_t len)
390{
391 struct himax_ts_data *ts = private_ts;
392 char buf_tmp[5] = {0};
393 int i = 0, j = 0, k = 0, ret;
394 unsigned long value;
395 int layout[4] = {0};
396
397 if (len >= 80) {
398 I("%s: no command exceeds 80 chars.\n", __func__);
399 return -EFAULT;
400 }
401
402 if (str_idx_of_str(buf, "help") >= 0) {
403 debug_data->is_call_help = true;
404 goto END;
405 } else {
406
407 for (i = 0; i < 20; i++) {
408 if (buf[i] == ',' || buf[i] == '\n') {
409 memset(buf_tmp, 0x0, sizeof(buf_tmp));
410
411 if (i - j <= 5) {
412 memcpy(buf_tmp, buf + j, i - j);
413 } else {
414 I("buffer size is over 5 char\n");
415 return len;
416 }
417
418 j = i + 1;
419
420 if (k < 4) {
421 ret = kstrtoul(buf_tmp, 10, &value);
422 layout[k++] = value;
423 }
424 }
425 }
426
427 if (k == 4) {
428 ts->pdata->abs_x_min = layout[0];
429 ts->pdata->abs_x_max = (layout[1] - 1);
430 ts->pdata->abs_y_min = layout[2];
431 ts->pdata->abs_y_max = (layout[3] - 1);
432 I("%d, %d, %d, %d\n",
433 ts->pdata->abs_x_min, ts->pdata->abs_x_max,
434 ts->pdata->abs_y_min, ts->pdata->abs_y_max);
435 input_unregister_device(ts->input_dev);
436 himax_input_register(ts);
437 } else {
438 I("ERR@%d, %d, %d, %d\n",
439 ts->pdata->abs_x_min, ts->pdata->abs_x_max,
440 ts->pdata->abs_y_min, ts->pdata->abs_y_max);
441 }
442 }
443END:
444 return len;
445}
446
447#if defined(HX_EXCP_RECOVERY)
448#if defined(HW_ED_EXCP_EVENT)
449static int himax_excp_cnt_read(struct seq_file *m)
450{
451 int ret = 0;
452
453 I("%s: enter, %d\n", __func__, __LINE__);
454
455 if (debug_data->is_call_help) {
456 seq_printf(m, HELP_EXCPT);
457 debug_data->is_call_help = false;
458 } else {
459 seq_printf(m,
460 "EB_cnt = %d, EC_cnt = %d, EE_cnt = %d\n",
461 hx_EB_event_flag,
462 hx_EC_event_flag,
463 hx_EE_event_flag);
464 }
465 return ret;
466}
467
468static ssize_t himax_excp_cnt_write(char *buf, size_t len)
469{
470 int i = 0;
471
472 if (len >= 12) {
473 I("%s: no command exceeds 80 chars.\n", __func__);
474 return -EFAULT;
475 }
476
477 if (str_idx_of_str(buf, "help") >= 0) {
478 debug_data->is_call_help = true;
479 } else {
480 if (buf[i] == '0') {
481 I("Clear EXCEPTION Flag\n");
482 hx_EB_event_flag = 0;
483 hx_EC_event_flag = 0;
484 hx_EE_event_flag = 0;
485 }
486 }
487
488 return len;
489}
490#else
491static int himax_excp_cnt_read(struct seq_file *m)
492{
493 int ret = 0;
494
495 I("%s: enter, %d\n", __func__, __LINE__);
496 if (debug_data->is_call_help) {
497 seq_printf(m, HELP_EXCPT);
498 debug_data->is_call_help = false;
499 } else {
500 seq_printf(m,
501 "EB_cnt = %d, EC_cnt = %d, ED_cnt = %d\n",
502 hx_EB_event_flag,
503 hx_EC_event_flag,
504 hx_ED_event_flag);
505 }
506 return ret;
507}
508
509static ssize_t himax_excp_cnt_write(char *buf, size_t len)
510{
511 int i = 0;
512
513 if (len >= 12) {
514 I("%s: no command exceeds 80 chars.\n", __func__);
515 return -EFAULT;
516 }
517 if (str_idx_of_str(buf, "help") >= 0) {
518 debug_data->is_call_help = true;
519 } else {
520 I("Clear EXCEPTION Flag\n");
521
522 if (buf[i] == '0') {
523 hx_EB_event_flag = 0;
524 hx_EC_event_flag = 0;
525 hx_ED_event_flag = 0;
526 }
527 }
528 return len;
529}
530#endif
531#endif
532
masonwang533a4032021-08-05 09:57:24 +0800533static int himax_sense_on_off_read(struct seq_file *m)
534{
535 int ret = 0;
536 I("%s: enter, %d\n", __func__, __LINE__);
537
538 if (debug_data->is_call_help) {
539 seq_printf(m, HELP_SNS);
540 debug_data->is_call_help = false;
541 } else {
542 if (g_test_result) {
543 seq_printf(m,"Result: Pass\n");
544 } else {
545 seq_printf(m,"Result: Fail\n");
546 }
547 }
548 return ret;
549}
550
masonwangcdc58ea2021-07-27 09:54:47 +0800551static ssize_t himax_sense_on_off_write(char *buf, size_t len)
552{
masonwang533a4032021-08-05 09:57:24 +0800553 int ret;
554 g_test_result = false;
masonwangcdc58ea2021-07-27 09:54:47 +0800555 if (len >= 80) {
556 I("%s: no command exceeds 80 chars.\n", __func__);
557 return -EFAULT;
558 }
559
masonwang533a4032021-08-05 09:57:24 +0800560 if (str_idx_of_str(buf, "help") >= 0) {
561 debug_data->is_call_help = true;
masonwangcdc58ea2021-07-27 09:54:47 +0800562 } else {
masonwang533a4032021-08-05 09:57:24 +0800563 if (buf[0] == '0') {
564 ret = g_core_fp.fp_sense_off(true);
565 if (ret) {
566 g_test_result = true;
567 }
568 I("Sense off\n");
569 } else if (buf[0] == '1') {
570 if (buf[1] == 's') {
571 ret = g_core_fp.fp_sense_on(0x00);
572 I("Sense on re-map on, run sram\n");
573 } else {
574 ret = g_core_fp.fp_sense_on(0x01);
575 I("Sense on re-map off, run flash\n");
576 }
577 if (ret) {
578 g_test_result = true;
579 }
580 } else {
581 I("Do nothing\n");
582 }
masonwangcdc58ea2021-07-27 09:54:47 +0800583 }
584
585 return len;
586}
587
588static int test_irq_pin(void)
589{
590 struct himax_ts_data *ts = private_ts;
591 int result = NO_ERR;
592 int irq_sts = -1;
593 uint8_t tmp_addr[DATA_LEN_4] = {0};
594 uint8_t tmp_data[DATA_LEN_4] = {0};
595 uint8_t tmp_read[DATA_LEN_4] = {0};
596
597 g_core_fp.fp_sense_off(true);
598
599 I("check IRQ LOW\n");
600 usleep_range(20000, 20001);
601 himax_parse_assign_cmd(0x90028060, tmp_addr, DATA_LEN_4);
602 himax_parse_assign_cmd(0x00000002, tmp_data, DATA_LEN_4);
603 g_core_fp.fp_register_write(tmp_addr, tmp_data, DATA_LEN_4);
604 usleep_range(20000, 20001);
605 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
606 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
607 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
608 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
609
610 usleep_range(20000, 20001);
611 himax_parse_assign_cmd(0x90028064, tmp_addr, DATA_LEN_4);
612 himax_parse_assign_cmd(0x00000001, tmp_data, DATA_LEN_4);
613 g_core_fp.fp_register_write(tmp_addr, tmp_data, DATA_LEN_4);
614 usleep_range(20000, 20001);
615 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
616 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
617 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
618 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
619
620 usleep_range(20000, 20001);
621 himax_parse_assign_cmd(0x90028068, tmp_addr, DATA_LEN_4);
622 himax_parse_assign_cmd(0x00000000, tmp_data, DATA_LEN_4);
623 g_core_fp.fp_register_write(tmp_addr, tmp_data, DATA_LEN_4);
624 usleep_range(20000, 20001);
625 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
626 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
627 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
628 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
629
630 usleep_range(20000, 20001);
631 irq_sts = himax_int_gpio_read(ts->pdata->gpio_irq);
632 if (irq_sts == 0) {
633 I("[LOW]Now IRQ is LOW!\n");
634 result += NO_ERR;
635 } else {
636 I("[LOW]Now IRQ is High!\n");
637 result += 1;
638 }
639
640 I("check IRQ High\n");
641 usleep_range(20000, 20001);
642 himax_parse_assign_cmd(0x90028060, tmp_addr, DATA_LEN_4);
643 himax_parse_assign_cmd(0x00000002, tmp_data, DATA_LEN_4);
644 g_core_fp.fp_register_write(tmp_addr, tmp_data, DATA_LEN_4);
645 usleep_range(20000, 20001);
646 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
647 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
648 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
649 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
650
651 usleep_range(20000, 20001);
652 himax_parse_assign_cmd(0x90028064, tmp_addr, DATA_LEN_4);
653 himax_parse_assign_cmd(0x00000001, tmp_data, DATA_LEN_4);
654 g_core_fp.fp_register_write(tmp_addr, tmp_data, DATA_LEN_4);
655 usleep_range(20000, 20001);
656 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
657 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
658 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
659 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
660
661 usleep_range(20000, 20001);
662 himax_parse_assign_cmd(0x90028068, tmp_addr, DATA_LEN_4);
663 himax_parse_assign_cmd(0x00000001, tmp_data, DATA_LEN_4);
664 g_core_fp.fp_register_write(tmp_addr, tmp_data, DATA_LEN_4);
665 usleep_range(20000, 20001);
666 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
667 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
668 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
669 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
670
671 usleep_range(20000, 20001);
672 irq_sts = himax_int_gpio_read(ts->pdata->gpio_irq);
673 if (irq_sts == 0) {
674 I("[High]Now IRQ is LOW!\n");
675 result += 1;
676 } else {
677 I("[High]Now IRQ is High!\n");
678 result += NO_ERR;
679 }
680 debug_data->is_checking_irq = false;
681
682 g_core_fp.fp_sense_on(0x00);
683
684 return result;
685}
686static int himax_int_en_read(struct seq_file *m)
687{
688 struct himax_ts_data *ts = private_ts;
689 int ret = 0;
690 int check_rslt = -1;
691
692
693 if (debug_data->is_checking_irq) {
694 check_rslt = test_irq_pin();
695 if (check_rslt == NO_ERR) {
696 seq_printf(m,
697 "IRQ check OK!\n");
698 } else {
699 seq_printf(m,
700 "IRQ check Fail!\n");
701 }
702 } else {
703 seq_printf(m, "irq_status:%d\n",
704 ts->irq_enabled);
705 }
706 return ret;
707}
708
709static ssize_t himax_int_en_write(char *buf, size_t len)
710{
711 struct himax_ts_data *ts = private_ts;
712 int ret = 0;
713
714 if (len >= 12) {
715 I("%s: no command exceeds 12 chars.\n", __func__);
716 return -EFAULT;
717 }
718
719 if (buf[0] == '0') {
720 himax_int_enable(0);
721 } else if (buf[0] == '1') {
722 himax_int_enable(1);
723 } else if (buf[0] == '2') {
724 himax_int_enable(0);
725 free_irq(ts->hx_irq, ts);
726 ts->irq_enabled = 0;
727 } else if (buf[0] == '3') {
728 ret = himax_int_en_set();
729
730 if (ret == 0) {
731 ts->irq_enabled = 1;
732 atomic_set(&ts->irq_state, 1);
733 }
734 } else if (str_idx_of_str(buf, "test") >= 0) {
735 debug_data->is_checking_irq = true;
736 I("Checking IRQ start!\n");
737 } else
738 return -EINVAL;
739
740 return len;
741}
742
743static int himax_irq_info_read(struct seq_file *m)
744{
745 // struct himax_ts_data *ts = private_ts;
746 int ret = 0;
747
748 if (g_core_fp.fp_read_ic_trigger_type() == 1)
749 seq_printf(m,
750 "IC Interrupt type is edge trigger.\n");
751 else if (g_core_fp.fp_read_ic_trigger_type() == 0)
752 seq_printf(m,
753 "IC Interrupt type is level trigger.\n");
754 else
755 seq_printf(m,
756 "Unkown IC trigger type.\n");
757
758 if (ic_data->HX_INT_IS_EDGE)
759 seq_printf(m,
760 "Driver register Interrupt : EDGE TIRGGER\n");
761 else
762 seq_printf(m,
763 "Driver register Interrupt : LEVEL TRIGGER\n");
764
765 return ret;
766}
767
768static ssize_t himax_irq_info_write(char *buf, size_t len)
769{
770 // struct himax_ts_data *ts = private_ts;
771 // int ret = 0;
772
773 if (len >= 12) {
774 I("%s: no command exceeds 12 chars.\n", __func__);
775 return -EFAULT;
776 }
777
778
779 return len;
780}
781
782static int himax_debug_level_read(struct seq_file *m)
783{
784 struct himax_ts_data *ts_data;
785 int ret = 0;
786
787 ts_data = private_ts;
788 seq_printf(m, "tsdbg: %d\n",
789 g_ts_dbg);
790 seq_printf(m, "level: %X\n",
791 ts_data->debug_log_level);
792
793
794 return ret;
795}
796
797static ssize_t himax_debug_level_write(char *buf, size_t len)
798{
799 struct himax_ts_data *ts;
800 int i;
801
802 int cmp_rslt = -1;
803
804 ts = private_ts;
805
806 if (len >= 12) {
807 I("%s: no command exceeds 12 chars.\n", __func__);
808 return -EFAULT;
809 }
810
811 cmp_rslt = str_idx_of_str(buf, "tsdbg");
812 if (cmp_rslt >= 0) {
813 if (buf[5] == '1') {
814 I("Open Ts Debug!\n");
815 g_ts_dbg = 1;
816 } else if (buf[5] == '0') {
817 I("Close Ts Debug!\n");
818 g_ts_dbg = 0;
819 } else {
820 E("Parameter fault for ts debug\n");
821 }
822 } else {
823
824 ts->debug_log_level = 0;
825
826 for (i = 0; i < len; i++) {
827 if (buf[i] >= '0' && buf[i] <= '9')
828 ts->debug_log_level |= (buf[i] - '0');
829 else if (buf[i] >= 'A' && buf[i] <= 'F')
830 ts->debug_log_level |= (buf[i] - 'A' + 10);
831 else if (buf[i] >= 'a' && buf[i] <= 'f')
832 ts->debug_log_level |= (buf[i] - 'a' + 10);
833
834 if (i != len - 1)
835 ts->debug_log_level <<= 4;
836 }
837 I("Now debug level value=%d\n", ts->debug_log_level);
838
839 if (ts->debug_log_level & BIT(4)) {
840 I("Turn on/Enable Debug Mode for Inspection!\n");
841 goto END_FUNC;
842 }
843
844 if (ts->debug_log_level & BIT(3)) {
845 if (ts->pdata->screenWidth > 0
846 && ts->pdata->screenHeight > 0
847 && (ts->pdata->abs_x_max - ts->pdata->abs_x_min) > 0
848 && (ts->pdata->abs_y_max - ts->pdata->abs_y_min) > 0) {
849 ts->widthFactor =
850 (ts->pdata->screenWidth << SHIFTBITS)
851 / (ts->pdata->abs_x_max
852 - ts->pdata->abs_x_min);
853 ts->heightFactor =
854 (ts->pdata->screenHeight << SHIFTBITS)
855 / (ts->pdata->abs_y_max
856 - ts->pdata->abs_y_min);
857
858 if (ts->widthFactor > 0 &&
859 ts->heightFactor > 0) {
860 ts->useScreenRes = 1;
861 } else {
862 ts->heightFactor = 0;
863 ts->widthFactor = 0;
864 ts->useScreenRes = 0;
865 }
866 } else
867 I("En-finger-dbg with raw position mode!\n");
868 } else {
869 ts->useScreenRes = 0;
870 ts->widthFactor = 0;
871 ts->heightFactor = 0;
872 }
873 }
874END_FUNC:
875 return len;
876}
877
878static int himax_proc_register_read(struct seq_file *m)
879{
880 int ret = 0;
881 uint16_t i;
882
883 if (debug_data->is_call_help) {
884 seq_printf(m, HELP_REGISTER);
885 debug_data->is_call_help = false;
886 } else {
887
888 memset(proc_reg_buf, 0x00, 128 * sizeof(uint8_t));
889
890 I("himax_register_show: %02X,%02X,%02X,%02X\n",
891 proc_reg_addr[3], proc_reg_addr[2], proc_reg_addr[1],
892 proc_reg_addr[0]);
893
894 if (proc_reg_addr_type == 1) {
895 ret = himax_bus_read(proc_reg_addr[0], proc_reg_buf,
896 128);
897 if (ret < 0) {
898 E("%s: bus access fail!\n", __func__);
899 return BUS_FAIL;
900 }
901 } else {
902 if (proc_reg_85xx_flag)
903 g_core_fp.fp_idle_mode(1);
904
905 g_core_fp.fp_register_read(proc_reg_addr, proc_reg_buf,
906 128);
907
908 /* don't enable idle mode ??
909 *if (proc_reg_85xx_flag)
910 * g_core_fp.fp_idle_mode(0);
911 */
912 }
913
914 seq_printf(m, "command: %02X,%02X,%02X,%02X\n",
915 proc_reg_addr[3], proc_reg_addr[2], proc_reg_addr[1],
916 proc_reg_addr[0]);
917
918 for (i = 0; i < 128; i++) {
919 seq_printf(m, "0x%2.2X ", proc_reg_buf[i]);
920 if ((i % 16) == 15)
921 seq_puts(m, "\n");
922
923 }
924
925 seq_puts(m, "\n");
926 }
927
928 return ret;
929}
930
931static ssize_t himax_proc_register_write(char *buf, size_t len)
932{
933 char buff_tmp[16] = {0};
934 uint8_t length = 0;
935 uint8_t byte_length = 0;
936 unsigned long result = 0;
937 uint8_t i = 0;
938 char *data_str = NULL;
939 uint8_t w_data[20] = {0};
940 uint8_t x_pos[20] = {0};
941 uint8_t count = 0;
942 int ret = 0;
943
944 if (len >= 80) {
945 I("%s: no command exceeds 80 chars.\n", __func__);
946 return -EFAULT;
947 }
948
949 I("himax %s\n", buf);
950
951 if (str_idx_of_str(buf, "help") >= 0) {
952 debug_data->is_call_help = true;
953 goto END;
954 }
955
956 memset(proc_reg_addr, 0x0, sizeof(proc_reg_addr));
957 proc_reg_85xx_flag = 0;
958
959 if ((buf[0] == 'r' || buf[0] == 'w')
960 && buf[1] == ':' && buf[2] == 'x') {
961 length = strlen(buf);
962
963 /* I("%s: length = %d.\n", __func__,length); */
964 for (i = 0; i < length; i++) {
965 /* find postion of 'x' */
966 if (buf[i] == 'x') {
967 x_pos[count] = i;
968 count++;
969 }
970 }
971
972 data_str = strrchr(buf, 'x');
973 I("%s: %s.\n", __func__, data_str);
974 length = strlen(data_str + 1);
975
976 switch (buf[0]) {
977 case 'r':
978 if (buf[3] == 'F' && buf[4] == 'E' && length == 4) {
979 length = length - 2;
980 proc_reg_addr_type = 1;
981 memcpy(buff_tmp, data_str + 3, length);
982 } else {
983 proc_reg_addr_type = 0;
984 memcpy(buff_tmp, data_str + 1, length);
985 }
986 byte_length = length / 2;
987 if (!kstrtoul(buff_tmp, 16, &result)) {
988 for (i = 0; i < byte_length; i++)
989 proc_reg_addr[i] = (uint8_t)(result >> (i * 8));
990 }
991
992 if (strcmp(HX_85XX_H_SERIES_PWON, private_ts->chip_name) == 0)
993 proc_reg_85xx_flag = 1;
994
995 break;
996
997 case 'w':
998 if (buf[3] == 'F' && buf[4] == 'E') {
999 proc_reg_addr_type = 1;
1000 memcpy(buff_tmp, buf + 5, length);
1001 } else {
1002 proc_reg_addr_type = 0;
1003 memcpy(buff_tmp, buf + 3, length);
1004 }
1005
1006 if (count < 3) {
1007 byte_length = length / 2;
1008
1009 if (!kstrtoul(buff_tmp, 16, &result)) {
1010 /* command */
1011 for (i = 0; i < byte_length; i++)
1012 proc_reg_addr[i] =
1013 (uint8_t)(result >> (i * 8));
1014 }
1015
1016 if (!kstrtoul(data_str + 1, 16, &result)) {
1017 /* data */
1018 for (i = 0; i < byte_length; i++)
1019 w_data[i] = (uint8_t)(result >> i * 8);
1020 }
1021 } else {
1022 for (i = 0; i < count; i++) {
1023 /* parsing addr after 'x' */
1024 memset(buff_tmp, 0x0, sizeof(buff_tmp));
1025 if (proc_reg_addr_type != 0 && i != 0)
1026 byte_length = 2;
1027 else
1028 byte_length = x_pos[1] - x_pos[0] - 2;
1029 /* original */
1030
1031 memcpy(buff_tmp, buf+x_pos[i]+1, byte_length);
1032
1033 if (!kstrtoul(buff_tmp, 16, &result)) {
1034 if (i == 0)
1035 proc_reg_addr[i] =
1036 (uint8_t)(result);
1037 else
1038 w_data[i - 1] =
1039 (uint8_t)(result);
1040 }
1041 }
1042
1043 byte_length = count - 1;
1044
1045 if (strcmp(HX_85XX_H_SERIES_PWON, private_ts->chip_name)
1046 == 0)
1047 proc_reg_85xx_flag = 1;
1048 }
1049
1050 if (proc_reg_addr_type == 1) {
1051 ret = himax_bus_write(proc_reg_addr[0], w_data,
1052 byte_length);
1053 if (ret < 0) {
1054 E("%s: bus access fail!\n", __func__);
1055 return BUS_FAIL;
1056 }
1057 } else {
1058 if (proc_reg_85xx_flag)
1059 g_core_fp.fp_idle_mode(1);
1060
1061 g_core_fp.fp_register_write(proc_reg_addr, w_data,
1062 byte_length);
1063
1064 if (proc_reg_85xx_flag)
1065 g_core_fp.fp_idle_mode(0);
1066 }
1067
1068 break;
1069 };
1070 }
1071END:
1072 return len;
1073}
1074
1075int32_t *getMutualBuffer(void)
1076{
1077 return diag_mutual;
1078}
1079int32_t *getMutualNewBuffer(void)
1080{
1081 return diag_mutual_new;
1082}
1083int32_t *getMutualOldBuffer(void)
1084{
1085 return diag_mutual_old;
1086}
1087int32_t *getSelfBuffer(void)
1088{
1089 return diag_self;
1090}
1091int32_t *getSelfNewBuffer(void)
1092{
1093 return diag_self_new;
1094}
1095int32_t *getSelfOldBuffer(void)
1096{
1097 return diag_self_old;
1098}
1099void setMutualBuffer(uint8_t x_num, uint8_t y_num)
1100{
1101 diag_mutual = kzalloc(x_num * y_num * sizeof(int32_t), GFP_KERNEL);
1102}
1103void setMutualNewBuffer(uint8_t x_num, uint8_t y_num)
1104{
1105 diag_mutual_new = kzalloc(x_num * y_num * sizeof(int32_t), GFP_KERNEL);
1106}
1107void setMutualOldBuffer(uint8_t x_num, uint8_t y_num)
1108{
1109 diag_mutual_old = kzalloc(x_num * y_num * sizeof(int32_t), GFP_KERNEL);
1110}
1111void setSelfBuffer(uint8_t x_num, uint8_t y_num)
1112{
1113 diag_self = kzalloc((x_num + y_num) * sizeof(int32_t), GFP_KERNEL);
1114}
1115void setSelfNewBuffer(uint8_t x_num, uint8_t y_num)
1116{
1117 diag_self_new = kzalloc((x_num + y_num) * sizeof(int32_t), GFP_KERNEL);
1118}
1119void setSelfOldBuffer(uint8_t x_num, uint8_t y_num)
1120{
1121 diag_self_old = kzalloc((x_num + y_num) * sizeof(int32_t), GFP_KERNEL);
1122}
1123
1124#if defined(HX_TP_PROC_2T2R)
1125int32_t *getMutualBuffer_2(void)
1126{
1127 return diag_mutual_2;
1128}
1129void setMutualBuffer_2(uint8_t x_num_2, uint8_t y_num_2)
1130{
1131 diag_mutual_2 =
1132 kzalloc(x_num_2 * y_num_2 * sizeof(int32_t), GFP_KERNEL);
1133}
1134#endif
1135
1136int himax_set_diag_cmd(struct himax_ic_data *ic_data,
1137 struct himax_report_data *hx_touch_data)
1138{
1139 struct himax_ts_data *ts = private_ts;
1140 int32_t *mutual_data;
1141 int32_t *self_data;
1142 int mul_num;
1143 int self_num;
1144 /* int RawDataLen = 0; */
1145 hx_touch_data->diag_cmd = ts->diag_cmd;
1146
1147 if (hx_touch_data->diag_cmd >= 1 && hx_touch_data->diag_cmd <= 7) {
1148 /* Check event stack CRC */
1149 if (!g_core_fp.fp_diag_check_sum(hx_touch_data))
1150 goto bypass_checksum_failed_packet;
1151
1152#if defined(HX_TP_PROC_2T2R)
1153 if (Is_2T2R && (hx_touch_data->diag_cmd >= 4 &&
1154 hx_touch_data->diag_cmd <= 6)) {
1155 mutual_data = getMutualBuffer_2();
1156 self_data = getSelfBuffer();
1157 /* initiallize the block number of mutual and self */
1158 mul_num = ic_data->HX_RX_NUM_2 * ic_data->HX_TX_NUM_2;
1159 self_num = ic_data->HX_RX_NUM_2 + ic_data->HX_TX_NUM_2;
1160 } else
1161#endif
1162 {
1163 mutual_data = getMutualBuffer();
1164 self_data = getSelfBuffer();
1165 /* initiallize the block number of mutual and self */
1166 mul_num = ic_data->HX_RX_NUM * ic_data->HX_TX_NUM;
1167 self_num = ic_data->HX_RX_NUM + ic_data->HX_TX_NUM;
1168 }
1169 g_core_fp.fp_diag_parse_raw_data(hx_touch_data, mul_num,
1170 self_num, hx_touch_data->diag_cmd, mutual_data,
1171 self_data);
1172 } else if (hx_touch_data->diag_cmd == 8) {
1173 memset(diag_coor, 0x00, sizeof(diag_coor));
1174 memcpy(&(diag_coor[0]), &hx_touch_data->hx_coord_buf[0],
1175 hx_touch_data->touch_info_size);
1176 }
1177
1178 /* assign state info data */
1179 memcpy(&(hx_state_info[0]), &hx_touch_data->hx_state_info[0], 2);
1180 return NO_ERR;
1181bypass_checksum_failed_packet:
1182 return 1;
1183}
1184
1185/* #if defined(HX_DEBUG_LEVEL) */
1186void himax_log_touch_data(int start)
1187{
1188 int i = 0;
1189 int print_size = 0;
1190 uint8_t *buf = NULL;
1191
1192 if (start == 1)
1193 return; /* report data when end of ts_work*/
1194
1195 if (hx_touch_data->diag_cmd > 0) {
1196 print_size = hx_touch_data->touch_all_size;
1197 buf = kcalloc(print_size, sizeof(uint8_t), GFP_KERNEL);
1198 if (buf == NULL) {
1199 E("%s, Failed to allocate memory\n", __func__);
1200 return;
1201 }
1202
1203 memcpy(buf, hx_touch_data->hx_coord_buf,
1204 hx_touch_data->touch_info_size);
1205 memcpy(&buf[hx_touch_data->touch_info_size],
1206 hx_touch_data->hx_rawdata_buf,
1207 print_size - hx_touch_data->touch_info_size);
1208 }
1209#if defined(HX_SMART_WAKEUP)
1210 else if (private_ts->SMWP_enable > 0 && private_ts->suspended) {
1211 print_size = hx_touch_data->event_size;
1212 buf = kcalloc(print_size, sizeof(uint8_t), GFP_KERNEL);
1213 if (buf == NULL) {
1214 E("%s, Failed to allocate memory\n", __func__);
1215 return;
1216 }
1217
1218 memcpy(buf, hx_touch_data->hx_event_buf, print_size);
1219 }
1220#endif
1221 else if (hx_touch_data->diag_cmd == 0) {
1222 print_size = hx_touch_data->touch_info_size;
1223 buf = kcalloc(print_size, sizeof(uint8_t), GFP_KERNEL);
1224 if (buf == NULL) {
1225 E("%s, Failed to allocate memory\n", __func__);
1226 return;
1227 }
1228
1229 memcpy(buf, hx_touch_data->hx_coord_buf, print_size);
1230 } else {
1231 E("%s:cmd fault\n", __func__);
1232 return;
1233 }
1234
1235 for (i = 0; i < print_size; i += 8) {
1236 if ((i + 7) >= print_size) {
1237 I("P %2d = 0x%2.2X P %2d = 0x%2.2X ",
1238 i,
1239 buf[i],
1240 i + 1,
1241 buf[i + 1]);
1242 I("P %2d = 0x%2.2X P %2d = 0x%2.2X\n",
1243 i + 2,
1244 buf[i + 2],
1245 i + 3,
1246 buf[i + 3]);
1247 break;
1248 }
1249
1250 I("P %2d = 0x%2.2X P %2d = 0x%2.2X ",
1251 i, buf[i], i + 1, buf[i + 1]);
1252 I("P %2d = 0x%2.2X P %2d = 0x%2.2X ",
1253 i + 2, buf[i + 2], i + 3, buf[i + 3]);
1254 I("P %2d = 0x%2.2X P %2d = 0x%2.2X ",
1255 i + 4, buf[i + 4], i + 5, buf[i + 5]);
1256 I("P %2d = 0x%2.2X P %2d = 0x%2.2X ",
1257 i + 6, buf[i + 6], i + 7, buf[i + 7]);
1258 I("\n");
1259 }
1260 kfree(buf);
1261}
1262
1263void himax_log_touch_event(struct himax_ts_data *ts, int start)
1264{
1265 int i = 0;
1266
1267 if (start == 1)
1268 return; /*report data when end of ts_work*/
1269
1270 if (g_target_report_data->finger_on > 0 &&
1271 g_target_report_data->finger_num > 0) {
1272 for (i = 0; i < ts->nFinger_support; i++) {
1273 if (g_target_report_data->p[i].x >= 0
1274 && g_target_report_data->p[i].x
1275 <= ts->pdata->abs_x_max
1276 && g_target_report_data->p[i].y >= 0
1277 && g_target_report_data->p[i].y
1278 <= ts->pdata->abs_y_max) {
1279 I(PRT_LOG,
1280 i + 1,
1281 g_target_report_data->p[i].x,
1282 g_target_report_data->p[i].y,
1283 g_target_report_data->p[i].w,
1284 g_target_report_data->p[i].w,
1285 i + 1,
1286 g_target_report_data->ig_count);
1287 }
1288 }
1289 } else if (g_target_report_data->finger_on == 0
1290 && g_target_report_data->finger_num == 0) {
1291 I("All Finger leave\n");
1292 } else {
1293 I("%s : wrong input!\n", __func__);
1294 }
1295}
1296void himax_log_touch_int_devation(int touched)
1297{
1298 if (touched == HX_FINGER_ON) {
1299#if defined(KERNEL_VER_ABOVE_5_10)
1300 ktime_get_ts64(&timeStart);
1301#else
1302 getnstimeofday(&timeStart);
1303#endif
1304 /* I(" Irq start time = %ld.%06ld s\n",
1305 * timeStart.tv_sec, timeStart.tv_nsec/1000);
1306 */
1307 } else if (touched == HX_FINGER_LEAVE) {
1308#if defined(KERNEL_VER_ABOVE_5_10)
1309 ktime_get_ts64(&timeEnd);
1310#else
1311 getnstimeofday(&timeEnd);
1312#endif
1313 timeDelta.tv_nsec =
1314 (timeEnd.tv_sec * 1000000000 + timeEnd.tv_nsec) -
1315 (timeStart.tv_sec * 1000000000 + timeStart.tv_nsec);
1316 /* I("Irq finish time = %ld.%06ld s\n",
1317 * timeEnd.tv_sec, timeEnd.tv_nsec/1000);
1318 */
1319 I("Touch latency = %ld us\n", timeDelta.tv_nsec / 1000);
1320 I("bus_speed = %d kHz\n", private_ts->bus_speed);
1321 if (g_target_report_data->finger_on == 0
1322 && g_target_report_data->finger_num == 0)
1323 I("All Finger leave\n");
1324 } else {
1325 I("%s : wrong input!\n", __func__);
1326 }
1327}
1328
1329void himax_log_touch_event_detail(struct himax_ts_data *ts, int start)
1330{
1331 int i = 0;
1332
1333 if (start == HX_FINGER_LEAVE) {
1334 for (i = 0; i < ts->nFinger_support; i++) {
1335 if (((ts->old_finger >> i & 1) == 0)
1336 && ((ts->pre_finger_mask >> i & 1) == 1)) {
1337 if (g_target_report_data->p[i].x >= 0
1338 && g_target_report_data->p[i].x
1339 <= ts->pdata->abs_x_max
1340 && g_target_report_data->p[i].y >= 0
1341 && g_target_report_data->p[i].y
1342 <= ts->pdata->abs_y_max) {
1343 I(RAW_DOWN_STATUS, i + 1,
1344 g_target_report_data->p[i].x,
1345 g_target_report_data->p[i].y,
1346 g_target_report_data->p[i].w);
1347 }
1348 } else if ((((ts->old_finger >> i & 1) == 1)
1349 && ((ts->pre_finger_mask >> i & 1) == 0))) {
1350 I(RAW_UP_STATUS, i + 1,
1351 ts->pre_finger_data[i][0],
1352 ts->pre_finger_data[i][1]);
1353 } else {
1354 /* I("dbg hx_point_num=%d, old_finger=0x%02X,"
1355 * " pre_finger_mask=0x%02X\n",
1356 * ts->hx_point_num, ts->old_finger,
1357 * ts->pre_finger_mask);
1358 */
1359 }
1360 }
1361 }
1362}
1363
1364void himax_ts_dbg_func(struct himax_ts_data *ts, int start)
1365{
1366 if (ts->debug_log_level & BIT(0)) {
1367 /* I("debug level 1\n"); */
1368 himax_log_touch_data(start);
1369 }
1370 if (ts->debug_log_level & BIT(1)) {
1371 /* I("debug level 2\n"); */
1372 himax_log_touch_event(ts, start);
1373 }
1374 if (ts->debug_log_level & BIT(2)) {
1375 /* I("debug level 4\n"); */
1376 himax_log_touch_int_devation(start);
1377 }
1378 if (ts->debug_log_level & BIT(3)) {
1379 /* I("debug level 8\n"); */
1380 himax_log_touch_event_detail(ts, start);
1381 }
1382}
1383
1384static int himax_change_mode(uint8_t str_pw, uint8_t end_pw)
1385{
1386 uint8_t data[4] = {0};
1387 int count = 0;
1388
1389 /*sense off*/
1390 g_core_fp.fp_sense_off(true);
1391 /*mode change*/
1392 data[1] = str_pw; data[0] = str_pw;
1393 if (g_core_fp.fp_assign_sorting_mode != NULL)
1394 g_core_fp.fp_assign_sorting_mode(data);
1395
1396 /*sense on*/
1397 g_core_fp.fp_sense_on(1);
1398 /*wait mode change*/
1399 do {
1400 if (g_core_fp.fp_check_sorting_mode != NULL)
1401 g_core_fp.fp_check_sorting_mode(data);
1402 if ((data[0] == end_pw) && (data[1] == end_pw))
1403 return 0;
1404
1405 I("Now retry %d times!\n", count);
1406 count++;
1407 msleep(50);
1408 } while (count < 50);
1409
1410 return ERR_WORK_OUT;
1411}
1412
1413static ssize_t himax_irq_dbg_cmd_write(char *buf, size_t len)
1414{
1415 // struct himax_ts_data *ts = private_ts;
1416 int cmd = 0;
1417
1418 if (!kstrtoint(buf, 16, &cmd)) {
1419 I("%s, now irq_dbg status=%d!\n", __func__, cmd);
1420 g_ts_dbg = cmd;
1421 } else {
1422 E("%s: command not int!\n", __func__);
1423 }
1424 return len;
1425}
1426
1427static ssize_t himax_diag_cmd_write(char *buf, size_t len)
1428{
1429 struct himax_ts_data *ts = private_ts;
1430 char *dbg_map_str = "mode:";
1431 char *str_ptr = NULL;
1432 int str_len = 0;
1433 int rst = 0;
1434 uint8_t str_pw = 0;
1435 uint8_t end_pw = 0;
1436
1437 if (str_idx_of_str(buf, "help") >= 0) {
1438 debug_data->is_call_help = true;
1439 goto END;
1440 }
1441
1442 switch (len) {
1443 case 1:/*raw out select - diag,X*/
1444 if (!kstrtoint(buf, 16, &rst)) {
1445 ts->diag_cmd = rst;
1446 I("%s: dsram_flag = %d\n", __func__, dsram_flag);
1447 if (dsram_flag) {
1448 /*Cancal work queue and return to stack*/
1449 process_type = 0;
1450 while (dsram_flag == true)
1451 usleep_range(10000, 11000);
1452 cancel_delayed_work(&ts->himax_diag_delay_work);
1453 himax_int_enable(1);
1454 g_core_fp.fp_return_event_stack();
1455 }
1456 g_core_fp.fp_diag_register_set(ts->diag_cmd, 0, false);
1457 I("%s: Set raw out select 0x%X.\n",
1458 __func__, ts->diag_cmd);
1459 }
1460 if (!ts->diag_cmd) {
1461 if (mode_flag) /*back to normal mode*/
1462 himax_change_mode(0x00, 0x99);
1463 }
1464 break;
1465 case 2:/*data processing + rawout select - diag,XY*/
1466 if (!kstrtoint(buf, 16, &rst)) {
1467 process_type = (rst >> 4) & 0xF;
1468 ts->diag_cmd = rst & 0xF;
1469 }
1470 if (ts->diag_cmd == 0)
1471 break;
1472 else if (process_type > 0 && process_type <= 3) {
1473 if (!dsram_flag) {
1474 /*Start wrok queue*/
1475 himax_int_enable(0);
1476 g_core_fp.fp_diag_register_set(ts->diag_cmd,
1477 process_type, false);
1478
1479 queue_delayed_work(ts->himax_diag_wq,
1480 &ts->himax_diag_delay_work, 2 * HZ / 100);
1481 dsram_flag = true;
1482
1483 I("%s: Start get raw data in DSRAM\n",
1484 __func__);
1485 } else {
1486 g_core_fp.fp_diag_register_set(ts->diag_cmd,
1487 process_type, false);
1488 }
1489 }
1490 break;
1491 case 4:/*data processing + rawout select - diag,XXYY*/
1492 /*ex:XXYY=010A=dsram rawdata*/
1493 I("%s, now case 4\n", __func__);
1494 if (!kstrtoint(buf, 16, &rst)) {
1495 process_type = (rst >> 8) & 0xFF;
1496 ts->diag_cmd = rst & 0xFF;
1497 I("%s:process_type=0x%02X, diag_cmd=0x%02X\n",
1498 __func__, process_type, ts->diag_cmd);
1499 }
1500 if (process_type <= 0 || ts->diag_cmd <= 0)
1501 break;
1502 else if (process_type > 0 && process_type <= 3) {
1503 if (!dsram_flag) {
1504 /*Start wrok queue*/
1505 himax_int_enable(0);
1506 g_core_fp.fp_diag_register_set(ts->diag_cmd,
1507 process_type, true);
1508
1509 queue_delayed_work(ts->himax_diag_wq,
1510 &ts->himax_diag_delay_work, 2 * HZ / 100);
1511 dsram_flag = true;
1512
1513 I("%s: Start get raw data in DSRAM\n",
1514 __func__);
1515 } else {
1516 g_core_fp.fp_diag_register_set(ts->diag_cmd,
1517 process_type, true);
1518 }
1519 }
1520 break;
1521 case 9:/*change mode - mode:XXYY(start PW,end PW)*/
1522 str_ptr = strnstr(buf, dbg_map_str, len);
1523 if (str_ptr) {
1524 str_len = strlen(dbg_map_str);
1525 if (!kstrtoint(buf + str_len, 16, &rst)) {
1526 str_pw = (rst >> 8) & 0xFF;
1527 end_pw = rst & 0xFF;
1528 if (!himax_change_mode(str_pw, end_pw)) {
1529 mode_flag = 1;
1530 I(PRT_OK_LOG, __func__,
1531 rst, str_pw, end_pw);
1532 } else
1533 I(PRT_FAIL_LOG, __func__,
1534 str_pw, end_pw);
1535 }
1536 } else {
1537 I("%s: Can't find string [%s].\n",
1538 __func__, dbg_map_str);
1539 }
1540 break;
1541 default:
1542 I("%s: Length is not correct.\n", __func__);
1543 }
1544END:
1545 return len;
1546}
1547
1548static int himax_diag_arrange_read(struct seq_file *m)
1549{
1550 int ret = NO_ERR;
1551
1552 if (debug_data->is_call_help) {
1553 seq_printf(m, HELP_DIAG_ARR);
1554 debug_data->is_call_help = false;
1555 } else {
1556 seq_printf(m, "diag value=%d\n", g_diag_arr_num);
1557 }
1558 return ret;
1559}
1560
1561static ssize_t himax_diag_arrange_write(char *buf, size_t len)
1562{
1563 if (len >= 80) {
1564 I("%s: no command exceeds 80 chars.\n", __func__);
1565 return -EFAULT;
1566 }
1567
1568 if (str_idx_of_str(buf, "help") >= 0) {
1569 debug_data->is_call_help = true;
1570 } else {
1571 g_diag_arr_num = buf[0] - '0';
1572 I("%s: g_diag_arr_num = %d\n", __func__, g_diag_arr_num);
1573 }
1574 return len;
1575}
1576
1577void himax_get_mutual_edge(void)
1578{
1579 int i = 0;
1580
1581 for (i = 0; i < (ic_data->HX_RX_NUM * ic_data->HX_TX_NUM); i++) {
1582 if (diag_mutual[i] > g_max_mutual)
1583 g_max_mutual = diag_mutual[i];
1584
1585 if (diag_mutual[i] < g_min_mutual)
1586 g_min_mutual = diag_mutual[i];
1587 }
1588}
1589
1590void himax_get_self_edge(void)
1591{
1592 int i = 0;
1593
1594 for (i = 0; i < (ic_data->HX_RX_NUM + ic_data->HX_TX_NUM); i++) {
1595 if (diag_self[i] > g_max_self)
1596 g_max_self = diag_self[i];
1597
1598 if (diag_self[i] < g_min_self)
1599 g_min_self = diag_self[i];
1600 }
1601}
1602
1603static void print_state_info(struct seq_file *s)
1604{
1605 /* seq_printf(s, "State_info_2bytes:%3d, %3d\n",
1606 * _state_info[0],hx_state_info[1]);
1607 */
1608
1609#if defined(HX_NEW_EVENT_STACK_FORMAT)
1610 seq_printf(s, "ReCal = %d\t", hx_state_info[0] & 0x03);
1611 seq_printf(s, "Base Line = %d\t", hx_state_info[0] >> 2 & 0x01);
1612 seq_printf(s, "Palm = %d\t", hx_state_info[0] >> 3 & 0x01);
1613 seq_printf(s, "Idle mode = %d\t", hx_state_info[0] >> 4 & 0x01);
1614 seq_printf(s, "Water = %d\n", hx_state_info[0] >> 5 & 0x01);
1615 seq_printf(s, "TX Hop = %d\t", hx_state_info[0] >> 6 & 0x01);
1616 seq_printf(s, "AC mode = %d\t", hx_state_info[0] >> 7 & 0x01);
1617 seq_printf(s, "Glove = %d\t", hx_state_info[1] & 0x01);
1618 seq_printf(s, "Stylus = %d\t", hx_state_info[1] >> 1 & 0x01);
1619 seq_printf(s, "Hovering = %d\t", hx_state_info[1] >> 2 & 0x01);
1620 seq_printf(s, "Proximity = %d\t", hx_state_info[1] >> 3 & 0x01);
1621 seq_printf(s, "KEY = %d\n", hx_state_info[1] >> 4 & 0x0F);
1622#else
1623 seq_printf(s, "ReCal = %d\t", hx_state_info[0] & 0x01);
1624 seq_printf(s, "Palm = %d\t", hx_state_info[0] >> 1 & 0x01);
1625 seq_printf(s, "AC mode = %d\t", hx_state_info[0] >> 2 & 0x01);
1626 seq_printf(s, "Water = %d\n", hx_state_info[0] >> 3 & 0x01);
1627 seq_printf(s, "Glove = %d\t", hx_state_info[0] >> 4 & 0x01);
1628 seq_printf(s, "TX Hop = %d\t", hx_state_info[0] >> 5 & 0x01);
1629 seq_printf(s, "Base Line = %d\t", hx_state_info[0] >> 6 & 0x01);
1630 seq_printf(s, "OSR Hop = %d\t", hx_state_info[1] >> 3 & 0x01);
1631 seq_printf(s, "KEY = %d\n", hx_state_info[1] >> 4 & 0x0F);
1632#endif
1633}
1634
1635static void himax_diag_arrange_print(struct seq_file *s, int i, int j,
1636 int transpose)
1637{
1638 if (transpose)
1639 seq_printf(s, "%6d", diag_mutual[j + i * ic_data->HX_RX_NUM]);
1640 else
1641 seq_printf(s, "%6d", diag_mutual[i + j * ic_data->HX_RX_NUM]);
1642}
1643
1644/* ready to print second step which is column*/
1645static void himax_diag_arrange_inloop(struct seq_file *s, int in_init,
1646 int out_init, bool transpose, int j)
1647{
1648 int x_channel = ic_data->HX_RX_NUM;
1649 int y_channel = ic_data->HX_TX_NUM;
1650 int i;
1651 int in_max = 0;
1652
1653 if (transpose)
1654 in_max = y_channel;
1655 else
1656 in_max = x_channel;
1657
1658 if (in_init > 0) { /* bit0 = 1 */
1659 for (i = in_init - 1; i >= 0; i--)
1660 himax_diag_arrange_print(s, i, j, transpose);
1661
1662 if (transpose) {
1663 if (out_init > 0)
1664 seq_printf(s, " %5d\n", diag_self[j]);
1665 else
1666 seq_printf(s, " %5d\n",
1667 diag_self[x_channel - j - 1]);
1668 }
1669 } else { /* bit0 = 0 */
1670 for (i = 0; i < in_max; i++)
1671 himax_diag_arrange_print(s, i, j, transpose);
1672
1673 if (transpose) {
1674 if (out_init > 0)
1675 seq_printf(s, " %5d\n",
1676 diag_self[x_channel - j - 1]);
1677 else
1678 seq_printf(s, " %5d\n", diag_self[j]);
1679 }
1680 }
1681}
1682
1683/* print first step which is row */
1684static void himax_diag_arrange_outloop(struct seq_file *s, int transpose,
1685 int out_init, int in_init)
1686{
1687 int j;
1688 int x_channel = ic_data->HX_RX_NUM;
1689 int y_channel = ic_data->HX_TX_NUM;
1690 int out_max = 0;
1691 int self_cnt = 0;
1692
1693 if (transpose)
1694 out_max = x_channel;
1695 else
1696 out_max = y_channel;
1697
1698 if (out_init > 0) { /* bit1 = 1 */
1699 self_cnt = 1;
1700
1701 for (j = out_init - 1; j >= 0; j--) {
1702 seq_printf(s, "%3c%02d%c", '[', j + 1, ']');
1703 himax_diag_arrange_inloop(s, in_init, out_init,
1704 transpose, j);
1705
1706 if (!transpose) {
1707 seq_printf(s, " %5d\n",
1708 diag_self[y_channel + x_channel - self_cnt]);
1709 self_cnt++;
1710 }
1711 }
1712 } else { /* bit1 = 0 */
1713 /* self_cnt = x_channel; */
1714 for (j = 0; j < out_max; j++) {
1715 seq_printf(s, "%3c%02d%c", '[', j + 1, ']');
1716 himax_diag_arrange_inloop(s, in_init, out_init,
1717 transpose, j);
1718
1719 if (!transpose) {
1720 seq_printf(s, " %5d\n",
1721 diag_self[j + x_channel]);
1722 }
1723 }
1724 }
1725}
1726
1727/* determin the output format of diag */
1728static void himax_diag_arrange(struct seq_file *s)
1729{
1730 int x_channel = ic_data->HX_RX_NUM;
1731 int y_channel = ic_data->HX_TX_NUM;
1732 int bit2, bit1, bit0;
1733 int i;
1734 /* rotate bit */
1735 bit2 = g_diag_arr_num >> 2;
1736 /* reverse Y */
1737 bit1 = g_diag_arr_num >> 1 & 0x1;
1738 /* reverse X */
1739 bit0 = g_diag_arr_num & 0x1;
1740
1741 if (g_diag_arr_num < 4) {
1742 for (i = 0 ; i <= x_channel; i++)
1743 seq_printf(s, "%3c%02d%c", '[', i, ']');
1744
1745 seq_puts(s, "\n");
1746 himax_diag_arrange_outloop(s, bit2, bit1 * y_channel,
1747 bit0 * x_channel);
1748 seq_printf(s, "%6c", ' ');
1749
1750 if (bit0 == 1) {
1751 for (i = x_channel - 1; i >= 0; i--)
1752 seq_printf(s, "%6d", diag_self[i]);
1753 } else {
1754 for (i = 0; i < x_channel; i++)
1755 seq_printf(s, "%6d", diag_self[i]);
1756 }
1757 } else {
1758 for (i = 0 ; i <= y_channel; i++)
1759 seq_printf(s, "%3c%02d%c", '[', i, ']');
1760
1761 seq_puts(s, "\n");
1762 himax_diag_arrange_outloop(s, bit2, bit1 * x_channel,
1763 bit0 * y_channel);
1764 seq_printf(s, "%6c", ' ');
1765
1766 if (bit1 == 1) {
1767 for (i = x_channel + y_channel - 1; i >= x_channel;
1768 i--)
1769 seq_printf(s, "%6d", diag_self[i]);
1770 } else {
1771 for (i = x_channel; i < x_channel + y_channel; i++)
1772 seq_printf(s, "%6d", diag_self[i]);
1773 }
1774 }
1775}
1776
1777/* DSRAM thread */
1778bool himax_ts_diag_func(int dsram_type)
1779{
1780 int i = 0, j = 0;
1781 unsigned int index = 0;
1782 int x_channel = ic_data->HX_RX_NUM;
1783 int y_channel = ic_data->HX_TX_NUM;
1784 int total_size = (y_channel * x_channel + y_channel + x_channel) * 2;
1785 uint8_t *info_data = NULL;
1786 int32_t *mutual_data = NULL;
1787 int32_t *mutual_data_new = NULL;
1788 int32_t *mutual_data_old = NULL;
1789 int32_t *self_data = NULL;
1790 int32_t *self_data_new = NULL;
1791 int32_t *self_data_old = NULL;
1792 int32_t new_data;
1793 /* 1:common dsram,2:100 frame Max,3:N-(N-1)frame */
1794 if (dsram_type < 1 || dsram_type > 3) {
1795 E("%s: type %d is out of range\n", __func__, dsram_type);
1796 return false;
1797 }
1798
1799 info_data = kcalloc(total_size, sizeof(uint8_t), GFP_KERNEL);
1800 if (info_data == NULL) {
1801 E("%s: Failed to allocate memory\n", __func__);
1802 return false;
1803 }
1804
1805 memset(info_data, 0, total_size * sizeof(uint8_t));
1806
1807 g_core_fp.fp_burst_enable(1);
1808
1809 if (dsram_type == 1 || dsram_type == 2) {
1810 mutual_data = getMutualBuffer();
1811 self_data = getSelfBuffer();
1812 } else if (dsram_type == 3) {
1813 mutual_data = getMutualBuffer();
1814 mutual_data_new = getMutualNewBuffer();
1815 mutual_data_old = getMutualOldBuffer();
1816 self_data = getSelfBuffer();
1817 self_data_new = getSelfNewBuffer();
1818 self_data_old = getSelfOldBuffer();
1819 }
1820
1821 if (!g_core_fp.fp_get_DSRAM_data(info_data, dsram_flag)) {
1822 E("%s: Get DSRAM data failed\n", __func__);
1823 kfree(info_data);
1824 return false;
1825 }
1826
1827 index = 0;
1828
1829 for (i = 0; i < y_channel; i++) { /*mutual data*/
1830 for (j = 0; j < x_channel; j++) {
1831 new_data = (((int8_t)info_data[index + 1] << 8) |
1832 info_data[index]);
1833
1834 if (dsram_type <= 1) {
1835 mutual_data[i * x_channel + j] = new_data;
1836 } else if (dsram_type == 2) { /* Keep max data */
1837 if (mutual_data[i * x_channel + j] < new_data)
1838 mutual_data[i * x_channel + j] =
1839 new_data;
1840 } else if (dsram_type == 3) {
1841 /* Cal data for [N]-[N-1] frame */
1842 mutual_data_new[i * x_channel + j] = new_data;
1843 mutual_data[i * x_channel + j] =
1844 mutual_data_new[i * x_channel + j]
1845 - mutual_data_old[i * x_channel + j];
1846 }
1847 index += 2;
1848 }
1849 }
1850
1851 for (i = 0; i < x_channel + y_channel; i++) { /*self data*/
1852 new_data = (((int8_t)info_data[index + 1] << 8) |
1853 info_data[index]);
1854 if (dsram_type <= 1) {
1855 self_data[i] = new_data;
1856 } else if (dsram_type == 2) { /* Keep max data */
1857 if (self_data[i] < new_data)
1858 self_data[i] = new_data;
1859 } else if (dsram_type == 3) { /* Cal data for [N]-[N-1] frame */
1860 self_data_new[i] = new_data;
1861 self_data[i] = self_data_new[i] - self_data_old[i];
1862 }
1863 index += 2;
1864 }
1865
1866 kfree(info_data);
1867
1868 if (dsram_type == 3) {
1869 memcpy(mutual_data_old, mutual_data_new,
1870 x_channel * y_channel * sizeof(int32_t));
1871 /* copy N data to N-1 array */
1872 memcpy(self_data_old, self_data_new,
1873 (x_channel + y_channel) * sizeof(int32_t));
1874 /* copy N data to N-1 array */
1875 }
1876
1877
1878 return true;
1879}
1880
1881static int himax_diag_print(struct seq_file *s, void *v)
1882{
1883 int x_num = ic_data->HX_RX_NUM;
1884 int y_num = ic_data->HX_TX_NUM;
1885 size_t ret = 0;
1886 uint16_t mutual_num, self_num, width;
1887
1888 mutual_num = x_num * y_num;
1889 self_num = x_num + y_num;
1890 /* don't add KEY_COUNT */
1891 width = x_num;
1892 seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_num, y_num);
1893
1894 /* start to show out the raw data in adb shell */
1895 himax_diag_arrange(s);
1896 seq_puts(s, "\n");
1897 seq_puts(s, "ChannelEnd");
1898 seq_puts(s, "\n");
1899
1900 /* print Mutual/Slef Maximum and Minimum */
1901 himax_get_mutual_edge();
1902 himax_get_self_edge();
1903 seq_printf(s, "Mutual Max:%3d, Min:%3d\n", g_max_mutual,
1904 g_min_mutual);
1905 seq_printf(s, "Self Max:%3d, Min:%3d\n", g_max_self,
1906 g_min_self);
1907 /* recovery status after print*/
1908 g_max_mutual = 0;
1909 g_min_mutual = 0xFFFF;
1910 g_max_self = 0;
1911 g_min_self = 0xFFFF;
1912
1913 /*pring state info*/
1914 print_state_info(s);
1915
1916 if (s->count >= s->size)
1917 overflow++;
1918
1919 return ret;
1920}
1921
1922static int himax_stack_show(struct seq_file *s, void *v)
1923{
1924 struct himax_ts_data *ts = private_ts;
1925
1926 if (debug_data->is_call_help) {
1927 seq_puts(s, HELP_DIAG);
1928 debug_data->is_call_help = false;
1929 } else {
1930 if (ts->diag_cmd)
1931 himax_diag_print(s, v);
1932 else
1933 seq_puts(s, "Please set raw out select 'echo diag,X > debug'\n\n");
1934 }
1935 return 0;
1936}
1937__CREATE_OREAD_NODE_HX(stack);
1938
1939static int himax_sram_read(struct seq_file *s, void *v, uint8_t rs)
1940{
1941 struct himax_ts_data *ts = private_ts;
1942 int d_type = 0;
1943 int current_size =
1944 ((ic_data->HX_TX_NUM + 1) * (ic_data->HX_RX_NUM + 1)
1945 + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) * 6 + 256;
1946 if (debug_data->is_call_help) {
1947 seq_puts(s, HELP_DIAG);
1948 debug_data->is_call_help = false;
1949 } else {
1950 d_type = (!ts->diag_cmd)?rs:ts->diag_cmd;
1951
1952 I("%s, s->size = %d\n", __func__, (int)s->size);
1953 I("%s, sizeof(s->buf) = %d\n", __func__, (int)sizeof(s->buf));
1954
1955 s->size = current_size;
1956 s->buf = kcalloc(s->size, sizeof(char), GFP_KERNEL);
1957 if (s->buf == NULL) {
1958 E("%s,%d: Memory allocation falied!\n",
1959 __func__, __LINE__);
1960 return -ENOMEM;
1961 }
1962
1963 memset(s->buf, 0, s->size * sizeof(char));
1964
1965 if (!overflow) {
1966 if (!process_type) {
1967 himax_int_enable(0);
1968 g_core_fp.fp_diag_register_set(d_type,
1969 0, false);
1970
1971 /* use process type 1 for default */
1972 if (!himax_ts_diag_func(1))
1973 seq_puts(s, "Get sram data failed.");
1974 else
1975 himax_diag_print(s, v);
1976
1977 ts->diag_cmd = 0;
1978 g_core_fp.fp_diag_register_set(0, 0, false);
1979 himax_int_enable(1);
1980 }
1981 }
1982
1983 if ((process_type <= 3
1984 && ts->diag_cmd
1985 && dsram_flag)
1986 || overflow) {
1987 himax_diag_print(s, v);
1988 overflow = 0;
1989 }
1990 }
1991 return 0;
1992}
1993
1994static int himax_delta_show(struct seq_file *s, void *v)
1995{
1996 return himax_sram_read(s, v, 0x09);
1997}
1998__CREATE_OREAD_NODE_HX(delta);
1999
2000static int himax_dc_show(struct seq_file *s, void *v)
2001{
2002 return himax_sram_read(s, v, 0x0A);
2003}
2004__CREATE_OREAD_NODE_HX(dc);
2005
2006static int himax_baseline_show(struct seq_file *s, void *v)
2007{
2008 return himax_sram_read(s, v, 0x0B);
2009}
2010__CREATE_OREAD_NODE_HX(baseline);
2011
2012#if defined(HX_RST_PIN_FUNC)
2013static void test_rst_pin(void)
2014{
2015 int rst_sts1 = -1;
2016 int rst_sts2 = -1;
2017 int cnt = 0;
2018 uint8_t tmp_addr[DATA_LEN_4] = {0};
2019 uint8_t tmp_data[DATA_LEN_4] = {0};
2020 uint8_t tmp_read[DATA_LEN_4] = {0};
2021
2022 himax_int_enable(0);
2023 g_core_fp.fp_sense_off(true);
2024
2025
2026 usleep_range(20000, 20001);
2027 himax_parse_assign_cmd(0x900000F0, tmp_addr, DATA_LEN_4);
2028 himax_parse_assign_cmd(0x00000001, tmp_data, DATA_LEN_4);
2029 g_core_fp.fp_register_write(tmp_addr, tmp_data, DATA_LEN_4);
2030 usleep_range(20000, 20001);
2031 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
2032 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
2033 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
2034 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
2035 I("trigger Reset Pin\n");
2036 g_core_fp.fp_ic_reset(false, false);
2037
2038 usleep_range(20000, 20001);
2039 do {
2040 himax_parse_assign_cmd(0x900000A8, tmp_addr, DATA_LEN_4);
2041 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
2042 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
2043 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
2044 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
2045 rst_sts1 = tmp_read[0];
2046 cnt++;
2047 if (rst_sts1 == 0x05)
2048 break;
2049 if (rst_sts1 == 0x00)
2050 cnt += 5;
2051 if (cnt > 20)
2052 goto END_FUNC;
2053 } while (rst_sts1 == 0x04);
2054
2055 himax_parse_assign_cmd(0x900000F0, tmp_addr, DATA_LEN_4);
2056 g_core_fp.fp_register_read(tmp_addr, tmp_read, DATA_LEN_4);
2057 I("R%02X%02X%02X%02XH = 0x%02X%02X%02X%02X\n",
2058 tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0],
2059 tmp_read[3], tmp_read[2], tmp_read[1], tmp_read[0]);
2060 rst_sts2 = tmp_read[0];
2061
2062END_FUNC:
2063 if (rst_sts1 == 0x05 && rst_sts2 == 0x00)
2064 I("%s: TP Reset test OK!\n", __func__);
2065 else if (rst_sts1 == 0xFF || rst_sts2 == 0x01)
2066 I("%s: TP Reset test Fail!\n", __func__);
2067 else
2068 I("%s, Unknown Fail state1=0x%02X, state2=0x%02X!\n",
2069 __func__, rst_sts1, rst_sts2);
2070
2071 g_core_fp.fp_sense_on(0x00);
2072 himax_int_enable(1);
2073}
2074#endif
2075
2076static int himax_reset_read(struct seq_file *m)
2077{
masonwang533a4032021-08-05 09:57:24 +08002078 int ret = 0;
2079 I("%s: enter, %d\n", __func__, __LINE__);
masonwangcdc58ea2021-07-27 09:54:47 +08002080
2081 if (debug_data->is_call_help) {
2082 seq_printf(m, HELP_RST);
2083 debug_data->is_call_help = false;
2084 } else {
masonwang533a4032021-08-05 09:57:24 +08002085 if (g_test_result) {
2086 seq_printf(m,"Result: Pass\n");
2087 } else {
2088 seq_printf(m,"Result: Fail\n");
2089 }
masonwangcdc58ea2021-07-27 09:54:47 +08002090 }
2091 return ret;
2092}
masonwang533a4032021-08-05 09:57:24 +08002093
masonwangcdc58ea2021-07-27 09:54:47 +08002094static ssize_t himax_reset_write(char *buf, size_t len)
2095{
masonwang533a4032021-08-05 09:57:24 +08002096 int ret = 0;
2097 g_test_result = false;
masonwangcdc58ea2021-07-27 09:54:47 +08002098 if (len >= 12) {
2099 I("%s: no command exceeds 12 chars.\n", __func__);
2100 return -EFAULT;
2101 }
2102
2103 if (str_idx_of_str(buf, "help") >= 0) {
2104 debug_data->is_call_help = true;
2105 } else {
2106#if defined(HX_RST_PIN_FUNC)
2107 if (buf[0] == '1')
masonwang533a4032021-08-05 09:57:24 +08002108 ret = g_core_fp.fp_ic_reset(false, false);
masonwangcdc58ea2021-07-27 09:54:47 +08002109 else if (buf[0] == '2')
masonwang533a4032021-08-05 09:57:24 +08002110 ret = g_core_fp.fp_ic_reset(false, true);
masonwangcdc58ea2021-07-27 09:54:47 +08002111 /* else if (buf[0] == '5') */
2112 /* ESD_HW_REST(); */
2113 else if (str_idx_of_str(buf, "test") >= 0)
2114 test_rst_pin();
2115#endif
2116#if defined(HX_ZERO_FLASH)
2117 if (g_core_fp.fp_0f_reload_to_active)
2118 g_core_fp.fp_0f_reload_to_active();
2119#endif
masonwang533a4032021-08-05 09:57:24 +08002120 if (ret) {
2121 g_test_result = true;
2122 }
masonwangcdc58ea2021-07-27 09:54:47 +08002123 }
2124 return len;
2125}
2126
masonwangcdc58ea2021-07-27 09:54:47 +08002127void hx_dump_prog_set(uint8_t prog)
2128{
2129 g_flash_progress = prog;
2130 if (prog == ONGOING)
2131 debug_data->flash_dump_going = ONGOING;
2132 else
2133 debug_data->flash_dump_going = START;
2134}
2135
2136static int himax_flash_dump_show(struct seq_file *s, void *v)
2137{
2138 ssize_t ret = 0;
2139 int i;
2140 uint8_t flash_progress = g_flash_progress;
2141 // uint8_t flash_cmd = g_dump_show;
2142 bool flash_rst = g_flash_dump_rst;
masonwangcdc58ea2021-07-27 09:54:47 +08002143
2144 I("dump_progress = %d\n", flash_progress);
2145
2146 if (!flash_rst) {
2147 seq_puts(s, "DumpStart:Fail\n");
2148 seq_puts(s, "DumpEnd\n");
2149 goto END;
2150 }
2151
2152 if (flash_progress == START)
2153 seq_puts(s, "Dump - Start\n");
2154 else if (flash_progress == ONGOING)
2155 seq_puts(s, "Dump - On-going\n");
2156 else if (flash_progress == FINISHED)
2157 seq_puts(s, "Dump - Finished\n");
2158
2159 /*print flash dump data*/
2160 if (g_dump_show == 2 && flash_progress == FINISHED) {
2161 seq_puts(s, "Start to print dump data\n");
2162 for (i = 0; i < ic_data->flash_size; i++) {
2163 seq_printf(s, "0x%02X,", g_dump_buffer[i]);
2164 if (i % 16 == 15)
2165 seq_puts(s, "\n");
2166 }
masonwangcdc58ea2021-07-27 09:54:47 +08002167 }
2168
2169 seq_puts(s, "DumpEnd\n");
2170END:
2171 return ret;
2172}
2173#define FDS_DBG1 "%s, input cmd:is_flash=%d, is_file=%d, dump_size=%d, addr=0x%08X\n"
2174#define FDS_DBG2 "%s, assigned:is_flash=%d, is_file=%d, dump_size=%d, addr=0x%08X\n"
2175static ssize_t himax_flash_dump_store(struct file *filp,
2176 const char __user *buff, size_t len, loff_t *data)
2177{
2178 char buf[80] = {0};
2179 char *input_str[4];
2180 int i = 0;
2181 int is_flash = -1;
2182 int is_file = -1;
2183 int dump_size = -1;
2184 uint32_t addr = 0x000000;
2185
2186 g_dump_cmd = 0;
2187 g_dump_size = 0;
2188 g_dump_show = 0;
2189 g_dump_addr = 0;
2190
2191 if (len >= 80) {
2192 I("%s: no command exceeds 80 chars.\n", __func__);
2193 return -EFAULT;
2194 }
2195
2196 if (copy_from_user(buf, buff, len))
2197 return -EFAULT;
2198
2199 I("%s: buf = %s\n", __func__, buf);
2200
2201 if (g_flash_progress == ONGOING) {
2202 E("%s: process is busy , return!\n", __func__);
2203 return len;
2204 }
2205
2206 buf[len - 1] = '\0';
2207
2208 for (i = 0; i < 4; i++)
2209 input_str[i] = kzalloc(sizeof(char) * 128, GFP_KERNEL);
2210
2211 _str_to_arr_in_char(input_str, 4, buf, ',');
2212
2213 for (i = 0; i < 4; i++) {
2214 if (input_str[i] == NULL) {
2215 continue;
2216 } else {
2217 I("%d:%s\n", i, input_str[i]);
2218 switch (i) {
2219 case 0:
2220 if (str_idx_of_str(input_str[i],
2221 "help") >= 0) {
2222 is_flash = 0;
2223 goto CON_WORK;
2224 } else if (str_idx_of_str(input_str[i],
2225 "flash") >= 0) {
2226 is_flash = 1;
2227 } else if (str_idx_of_str(input_str[i],
2228 "ram") >= 0) {
2229 is_flash = 2;
2230 } else {
2231 is_flash = -1;
2232 goto CON_WORK;
2233 }
2234 break;
2235 case 1:
2236 if (str_idx_of_str(input_str[i],
2237 "print") >= 0) {
2238 is_file = 2;
2239 } else if (str_idx_of_str(input_str[i],
2240 "file") >= 0) {
2241 is_file = 1;
2242 } else {
2243 is_file = -1;
2244 goto CON_WORK;
2245 }
2246 break;
2247 case 2:
2248 dump_size = hiamx_parse_str2int(
2249 input_str[i]);
2250 break;
2251 case 3:
2252 if (input_str[i] == NULL)
2253 addr = 0x00;
2254 else
2255 addr = hx_parse_hexstr2int(
2256 input_str[i]);
2257 I("addr=%d\n", addr);
2258 break;
2259 default:
2260 break;
2261 }
2262 }
2263 }
2264CON_WORK:
2265 I(FDS_DBG1,
2266 __func__, is_flash, is_file, dump_size, addr);
2267/*
2268 *
2269 * if ((buf[1] == '_') && (buf[2] == '3') && (buf[3] == '2'))
2270 * g_dump_size = FW_SIZE_32k;
2271 * else if ((buf[1] == '_') && (buf[2] == '6')) {
2272 * if (buf[3] == '0')
2273 * g_dump_size = FW_SIZE_60k;
2274 * else if (buf[3] == '4')
2275 * g_dump_size = FW_SIZE_64k;
2276
2277 *} else if ((buf[1] == '_') && (buf[2] == '2')) {
2278 * if (buf[3] == '4')
2279 * g_dump_size = FW_SIZE_124k;
2280 * else if (buf[3] == '8')
2281 * g_dump_size = FW_SIZE_128k;
2282 *}
2283 *
2284 * //1 : print flash to window, 2 : dump to sdcard
2285 *if (buf[0] == '1') {
2286 * //1_32,1_60,1_64,1_24,1_28 for flash size:
2287 * // 32k,60k,64k,124k,128k
2288 *
2289 * g_dump_cmd = 1;
2290 * hx_dump_prog_set(START);
2291 * g_flash_dump_rst = true;
2292 * queue_work(private_ts->dump_wq, &private_ts->dump_work);
2293 *} else if (buf[0] == '2') {
2294 * // 2_32,2_60,2_64,2_24,2_28 for dump size:
2295 * // 32k,60k,64k,124k,128k
2296 *
2297 * g_dump_cmd = 2;
2298 * hx_dump_prog_set(START);
2299 * g_flash_dump_rst = true;
2300 * queue_work(private_ts->dump_wq, &private_ts->dump_work);
2301 *}
2302 **/
2303
2304 g_dump_cmd = is_flash;
2305 g_dump_size = dump_size;
2306 g_dump_show = is_file;
2307 g_dump_addr = addr;
2308 I(FDS_DBG2,
2309 __func__, g_dump_cmd, g_dump_show, g_dump_size, g_dump_addr);
2310 hx_dump_prog_set(START);
2311 g_flash_dump_rst = true;
2312 queue_work(private_ts->dump_wq, &private_ts->dump_work);
2313
2314 for (i = 0; i < 4; i++)
2315 kfree(input_str[i]);
2316 return len;
2317}
2318__CREATE_RW_NODE_HX(flash_dump);
2319
2320void himax_ts_dump_func(void)
2321{
2322 uint8_t tmp_addr[DATA_LEN_4] = {0};
2323 int ret = NO_ERR;
2324
2325 hx_dump_prog_set(ONGOING);
2326
2327 /*msleep(100);*/
2328 // I("%s: flash_command = %d enter.\n", __func__, flash_command);
2329 I("%s: entering, is_flash=%d, is_file=%d, size=%d, add=0x%08X\n",
2330 __func__, g_dump_cmd, g_dump_show, g_dump_size, g_dump_addr);
2331
2332 if (g_dump_cmd == 1) {
2333 himax_int_enable(0);
2334 g_core_fp.fp_flash_dump_func(g_dump_cmd, g_dump_size,
2335 g_dump_buffer);
2336 g_flash_dump_rst = true;
2337 himax_int_enable(1);
2338 } else if (g_dump_cmd == 2) {
2339 I("dump ram start\n");
2340 if (g_dump_addr != -948794) {
2341 tmp_addr[0] = g_dump_addr % 0x100;
2342 tmp_addr[1] = (g_dump_addr >> 8) % 0x100;
2343 tmp_addr[2] = (g_dump_addr >> 16) % 0x100;
2344 tmp_addr[3] = g_dump_addr / 0x1000000;
2345 ret = g_core_fp.fp_register_read(tmp_addr,
2346 g_dump_buffer, g_dump_size);
2347 g_flash_dump_rst = true;
2348 } else {
2349 E("addr is wrong!\n");
2350 g_flash_dump_rst = false;
2351 goto END;
2352 }
2353 if (ret) {
2354 E("read ram fail, please check cmd !\n");
2355 g_flash_dump_rst = false;
2356 goto END;
2357 }
2358 }
2359
2360 I("Dump Complete\n");
2361
2362
2363END:
2364 hx_dump_prog_set(FINISHED);
2365}
2366
2367#if defined(HX_TP_PROC_GUEST_INFO)
2368static int printMat(struct seq_file *m, int max_size,
2369 uint8_t *guest_str, int loc)
2370{
2371 int ret = loc;
2372 int i;
2373
2374 for (i = 0; i < max_size; i++) {
2375 if ((i % 16) == 0 && i > 0)
2376 seq_puts(m, "\n");
2377
2378 seq_printf(m, "0x%02X\t",
2379 guest_str[i]);
2380 }
2381 return ret;
2382}
2383
2384static int printUnit(struct seq_file *m, int max_size,
2385 char *info_item, uint8_t *guest_str, int loc)
2386{
2387 int ret = loc;
2388
2389 seq_printf(m, "%s:\n", info_item);
2390 ret = printMat(m, max_size, guest_str, ret);
2391 seq_puts(m, "\n");
2392 return ret;
2393}
2394
2395static int himax_proc_guest_info_read(struct seq_file *m)
2396{
2397 int ret = 0;
2398 int j = 0;
2399 int max_size = 128;
2400 struct hx_guest_info *info = g_guest_info_data;
2401
2402
2403 if (debug_data->is_call_help) {
2404 seq_printf(m, HELP_GUEST_INFO);
2405 debug_data->is_call_help = false;
2406 } else {
2407 I("guest info progress\n");
2408
2409 if (g_core_fp.guest_info_get_status()) {
2410 seq_printf(m,
2411 "Not Ready\n");
2412 goto END_FUNCTION;
2413 } else {
2414 if (info->g_guest_info_type == 1) {
2415 for (j = 0; j < 3; j++) {
2416 ret = printUnit(m, max_size,
2417 g_guest_info_item[j],
2418 info->g_guest_str[j], ret);
2419 I("str[%d] %s\n", j,
2420 info->g_guest_str[j]);
2421 }
2422 ret = printUnit(m, max_size,
2423 g_guest_info_item[8],
2424 info->g_guest_str[8],
2425 ret);
2426
2427 I("str[8] %s\n",
2428 info->g_guest_str[8]);
2429
2430 ret = printUnit(m, max_size,
2431 g_guest_info_item[9],
2432 info->g_guest_str[9],
2433 ret);
2434
2435 I("str[9] %s\n", info->g_guest_str[9]);
2436 } else if (info->g_guest_info_type == 0) {
2437 for (j = 0; j < 10; j++) {
2438 if (j == 3)
2439 j = 8;
2440
2441 seq_printf(m, "%s:\n",
2442 g_guest_info_item[j]);
2443
2444 if (info->g_guest_data_type[j] == 0) {
2445 seq_printf(m, "%s",
2446 info->g_guest_str_in_format[j]);
2447 } else {
2448 ret = printMat(m,
2449 info->g_guest_data_len[j],
2450 info->g_guest_str_in_format[j],
2451 ret);
2452 }
2453 seq_puts(m, "\n");
2454 }
2455 }
2456 }
2457 }
2458END_FUNCTION:
2459 return ret;
2460}
2461
2462static ssize_t himax_proc_guest_info_write(char *buf, size_t len)
2463{
2464 if (len >= 80) {
2465 I("%s: no command exceeds 80 chars.\n", __func__);
2466 return -EFAULT;
2467 }
2468
2469 I("%s: buf = %s\n", __func__, buf);
2470
2471 if (str_idx_of_str(buf, "help") >= 0) {
2472 debug_data->is_call_help = true;
2473 } else {
2474 if (buf[0] == 'r') {
2475 I("%s,Test to get", __func__);
2476 queue_work(private_ts->guest_info_wq,
2477 &private_ts->guest_info_work);
2478 }
2479 }
2480 return len;
2481}
2482
2483#endif
2484
2485static int himax_test_bus_read(struct seq_file *m)
2486{
2487 int ret = NO_ERR;
2488
2489 if (g_core_fp.fp_read_i2c_status())
2490 seq_printf(m,
2491 "Bus communication is bad.\n");
2492 else
2493 seq_printf(m,
2494 "Bus communication is good.\n");
2495 return ret;
2496}
2497
2498static int himax_info_read(struct seq_file *m)
2499{
2500 int ret = NO_ERR;
2501
2502 seq_printf(m,
2503 "Himax Touch IC Information :\n");
2504 seq_printf(m,
2505 "%s\n", private_ts->chip_name);
2506
2507 switch (IC_CHECKSUM) {
2508 case HX_TP_BIN_CHECKSUM_SW:
2509 seq_printf(m,
2510 "IC Checksum : SW\n");
2511 break;
2512
2513 case HX_TP_BIN_CHECKSUM_HW:
2514 seq_printf(m,
2515 "IC Checksum : HW\n");
2516 break;
2517
2518 case HX_TP_BIN_CHECKSUM_CRC:
2519 seq_printf(m,
2520 "IC Checksum : CRC\n");
2521 break;
2522
2523 default:
2524 seq_printf(m,
2525 "IC Checksum error.\n");
2526 }
2527
2528 if (ic_data->HX_INT_IS_EDGE)
2529 seq_printf(m,
2530 "Driver register Interrupt : EDGE TIRGGER\n");
2531 else
2532 seq_printf(m,
2533 "Driver register Interrupt : LEVEL TRIGGER\n");
2534
2535 if (private_ts->protocol_type == PROTOCOL_TYPE_A)
2536 seq_printf(m,
2537 "Protocol : TYPE_A\n");
2538 else
2539 seq_printf(m,
2540 "Protocol : TYPE_B\n");
2541
2542 seq_printf(m,
2543 "RX Num : %d\n", ic_data->HX_RX_NUM);
2544 seq_printf(m,
2545 "TX Num : %d\n", ic_data->HX_TX_NUM);
2546 seq_printf(m,
2547 "BT Num : %d\n", ic_data->HX_BT_NUM);
2548 seq_printf(m,
2549 "X Resolution : %d\n", ic_data->HX_X_RES);
2550 seq_printf(m,
2551 "Y Resolution : %d\n", ic_data->HX_Y_RES);
2552 seq_printf(m,
2553 "Max Point : %d\n", ic_data->HX_MAX_PT);
2554#if defined(HX_TP_PROC_2T2R)
2555 if (Is_2T2R) {
2556 seq_printf(m,
2557 "2T2R panel\n");
2558 seq_printf(m,
2559 "RX Num_2 : %d\n", HX_RX_NUM_2);
2560 seq_printf(m,
2561 "TX Num_2 : %d\n", HX_TX_NUM_2);
2562 }
2563#endif
2564
2565 return ret;
2566}
2567
2568static int hx_node_update(char *buf, size_t is_len)
2569{
2570 int result;
2571 char fileName[128];
2572 int fw_type = 0;
2573
2574 const struct firmware *fw = NULL;
2575
2576 fw_update_complete = false;
2577 fw_update_going = true;
2578 memset(fileName, 0, 128);
2579 /* parse the file name */
2580 if (!is_len)
2581 memcpy(fileName, buf, strlen(buf) * sizeof(char));
2582 else
2583 snprintf(fileName, is_len - 2, "%s", &buf[2]);
2584
2585 I("%s: upgrade from file(%s) start!\n", __func__, fileName);
2586 /* manual upgrade will not use embedded firmware */
2587 result = request_firmware(&fw, fileName, private_ts->dev);
2588 if (result < 0) {
2589 E("request FW %s failed(%d)\n", fileName, result);
2590 return result;
2591 }
2592
2593 I("%s: FW image: %02X, %02X, %02X, %02X\n", __func__,
2594 fw->data[0], fw->data[1],
2595 fw->data[2], fw->data[3]);
2596
2597 himax_int_enable(0);
2598
2599#if defined(HX_ZERO_FLASH)
2600 I("NOW Running Zero flash update!\n");
2601
2602 /* FW type: 0, normal; 1, MPFW */
2603 if (strcmp(fileName, MPAP_FWNAME) == 0)
2604 fw_type = 1;
2605
2606 CFG_TABLE_FLASH_ADDR = CFG_TABLE_FLASH_ADDR_T;
2607 g_core_fp.fp_bin_desc_get((unsigned char *)fw->data, HX1K);
2608
2609 result = g_core_fp.fp_firmware_update_0f(fw, fw_type);
2610 if (result) {
2611 fw_update_complete = false;
2612 I("Zero flash update fail!\n");
2613 } else {
2614 fw_update_complete = true;
2615 I("Zero flash update complete!\n");
2616 }
2617#else
2618 I("NOW Running common flow update!\n");
2619
2620 fw_type = (fw->size) / 1024;
2621 I("Now FW size is : %dk\n", fw_type);
2622
2623 switch (fw_type) {
2624 case 32:
2625 if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_32k(
2626 (unsigned char *)fw->data, fw->size, false) == 0) {
2627 E("%s: TP upgrade error, line: %d\n",
2628 __func__, __LINE__);
2629 fw_update_complete = false;
2630 } else {
2631 I("%s: TP upgrade OK, line: %d\n",
2632 __func__, __LINE__);
2633 fw_update_complete = true;
2634 }
2635 break;
2636
2637 case 60:
2638 if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_60k(
2639 (unsigned char *)fw->data, fw->size, false) == 0) {
2640 E("%s: TP upgrade error, line: %d\n",
2641 __func__, __LINE__);
2642 fw_update_complete = false;
2643 } else {
2644 I("%s: TP upgrade OK, line: %d\n",
2645 __func__, __LINE__);
2646 fw_update_complete = true;
2647 }
2648 break;
2649
2650 case 64:
2651 if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_64k(
2652 (unsigned char *)fw->data, fw->size, false) == 0) {
2653 E("%s: TP upgrade error, line: %d\n",
2654 __func__, __LINE__);
2655 fw_update_complete = false;
2656 } else {
2657 I("%s: TP upgrade OK, line: %d\n",
2658 __func__, __LINE__);
2659 fw_update_complete = true;
2660 }
2661 break;
2662
2663 case 124:
2664 if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_124k(
2665 (unsigned char *)fw->data, fw->size, false) == 0) {
2666 E("%s: TP upgrade error, line: %d\n",
2667 __func__, __LINE__);
2668 fw_update_complete = false;
2669 } else {
2670 I("%s: TP upgrade OK, line: %d\n",
2671 __func__, __LINE__);
2672 fw_update_complete = true;
2673 }
2674 break;
2675
2676 case 128:
2677 if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_128k(
2678 (unsigned char *)fw->data, fw->size, false) == 0) {
2679 E("%s: TP upgrade error, line: %d\n",
2680 __func__, __LINE__);
2681 fw_update_complete = false;
2682 } else {
2683 I("%s: TP upgrade OK, line: %d\n",
2684 __func__, __LINE__);
2685 fw_update_complete = true;
2686 }
2687 break;
2688
2689 case 255:
2690 if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_255k(
2691 (unsigned char *)fw->data, fw->size, false) == 0) {
2692 E("%s: TP upgrade error, line: %d\n",
2693 __func__, __LINE__);
2694 fw_update_complete = false;
2695 } else {
2696 I("%s: TP upgrade OK, line: %d\n",
2697 __func__, __LINE__);
2698 fw_update_complete = true;
2699 }
2700 break;
2701
2702 default:
2703 E("%s: Flash command fail: %d\n", __func__, __LINE__);
2704 fw_update_complete = false;
2705 break;
2706 }
2707#endif
2708 release_firmware(fw);
2709 goto firmware_upgrade_done;
2710firmware_upgrade_done:
2711 fw_update_going = false;
2712 g_core_fp.fp_reload_disable(0);
2713 g_core_fp.fp_power_on_init();
2714 g_core_fp.fp_read_FW_ver();
2715
2716 g_core_fp.fp_tp_info_check();
2717
2718 himax_int_enable(1);
2719 return result;
2720}
2721
2722static int himax_update_read(struct seq_file *m)
2723{
2724 int ret = NO_ERR;
2725
2726 if (debug_data->is_call_help) {
2727 seq_printf(m, HELP_UPDATE);
2728 debug_data->is_call_help = false;
2729 } else {
2730 if (!fw_update_going) {
2731 if (fw_update_complete)
2732 seq_printf(m,
2733 "FW Update Complete\n");
2734 else
2735 seq_printf(m,
2736 "FW Update Fail\n");
2737 } else {
2738 seq_printf(m,
2739 "FW Update Ongoing\n");
2740 }
2741 }
2742
2743 return ret;
2744}
2745static ssize_t himax_update_write(char *buf, size_t len)
2746{
2747
2748 I("Now cmd=%s", buf);
2749 if (str_idx_of_str(buf, "help") >= 0)
2750 debug_data->is_call_help = true;
2751 else
2752 hx_node_update(buf, 0);
2753 return len;
2754}
2755
2756static int himax_version_read(struct seq_file *m)
2757{
2758 int ret = NO_ERR;
masonwang533a4032021-08-05 09:57:24 +08002759 I("%s: enter, %d\n", __func__, __LINE__);
masonwangcdc58ea2021-07-27 09:54:47 +08002760 if (debug_data->is_call_help) {
2761 seq_printf(m, HELP_VER);
2762 debug_data->is_call_help = false;
2763 } else {
2764 seq_printf(m,
2765 "FW_VER = 0x%2.2X\n",
2766 ic_data->vendor_fw_ver);
2767 if (private_ts->chip_cell_type == CHIP_IS_ON_CELL)
2768 seq_printf(m,
2769 "CONFIG_VER = 0x%2.2X\n",
2770 ic_data->vendor_config_ver);
2771 else {
2772 seq_printf(m,
2773 "TOUCH_VER = 0x%2.2X\n",
2774 ic_data->vendor_touch_cfg_ver);
2775 seq_printf(m,
2776 "DISPLAY_VER = 0x%2.2X\n",
2777 ic_data->vendor_display_cfg_ver);
2778 }
2779 if (ic_data->vendor_cid_maj_ver < 0
2780 && ic_data->vendor_cid_min_ver < 0)
2781 seq_printf(m,
2782 "CID_VER = NULL\n");
2783 else
2784 seq_printf(m,
2785 "CID_VER = 0x%2.2X\n",
2786 (ic_data->vendor_cid_maj_ver << 8 |
2787 ic_data->vendor_cid_min_ver));
2788
2789 if (ic_data->vendor_panel_ver < 0)
2790 seq_printf(m,
2791 "PANEL_VER = NULL\n");
2792 else
2793 seq_printf(m,
2794 "PANEL_VER = 0x%2.2X\n",
2795 ic_data->vendor_panel_ver);
2796 if (private_ts->chip_cell_type == CHIP_IS_IN_CELL) {
2797 seq_printf(m,
2798 "Cusomer = %s\n",
2799 ic_data->vendor_cus_info);
2800
2801 seq_printf(m,
2802 "Project = %s\n",
2803 ic_data->vendor_proj_info);
2804 }
2805 seq_puts(m, "\n");
2806 seq_printf(m,
2807 "Himax Touch Driver Version:\n");
2808 seq_printf(m,
2809 "%s\n", HIMAX_DRIVER_VER);
2810 }
2811 return ret;
2812}
2813static ssize_t himax_version_write(char *buf, size_t len)
2814{
2815 if (len >= 80) {
2816 I("%s: no command exceeds 80 chars.\n", __func__);
2817 return -EFAULT;
2818 }
2819 I("Now cmd=%s", buf);
2820 if (str_idx_of_str(buf, "help") >= 0)
2821 debug_data->is_call_help = true;
2822 else
2823 g_core_fp.fp_read_FW_ver();
2824
2825 return len;
2826}
2827
2828static int himax_list_cmd_read(struct seq_file *m)
2829{
2830 int ret = NO_ERR;
2831 int i = 0, j = 0;
2832
2833 for (i = CMD_START_IDX; dbg_cmd_str[i] != NULL; i++) {
2834 for (j = 0; dbg_cmd_str[i][j] != NULL ; j++) {
2835 if (j != 0)
2836 seq_puts(m, ", ");
2837 seq_printf(m, dbg_cmd_str[i][j]);
2838 }
2839 seq_puts(m, "\n");
2840 }
2841 return ret;
2842}
2843
2844static int himax_help_read(struct seq_file *m)
2845{
2846 int ret = NO_ERR;
2847
2848 seq_printf(m, HELP_ALL_DEBUG);
2849 return ret;
2850}
2851static ssize_t himax_help_write(char *buf, size_t len)
2852{
2853 if (len >= 80) {
2854 I("%s: no command exceeds 80 chars.\n", __func__);
2855 return -EFAULT;
2856 }
2857 I("Now cmd=%s", buf);
2858
2859 return len;
2860}
2861
2862static int himax_debug_show(struct seq_file *m, void *v)
2863{
2864 int ret = 0;
2865
2866 if (dbg_cmd_flag) {
2867 if (dbg_func_ptr_r[dbg_cmd_flag]) {
2868 dbg_func_ptr_r[dbg_cmd_flag](m);
2869 goto END_FUNC_R;
2870 }
2871 }
2872
2873 if (debug_level_cmd == 't') {
2874 if (!fw_update_going) {
2875 if (fw_update_complete)
2876 seq_printf(m,
2877 "FW Update Complete ");
2878 else
2879 seq_printf(m,
2880 "FW Update Fail ");
2881 } else {
2882 seq_printf(m,
2883 "FW Update Ongoing ");
2884 }
2885 } else if (debug_level_cmd == 'h') {
2886 if (handshaking_result == 0)
2887 seq_printf(m,
2888 "Handshaking Result = %d (MCU Running)\n",
2889 handshaking_result);
2890 else if (handshaking_result == 1)
2891 seq_printf(m,
2892 "Handshaking Result = %d (MCU Stop)\n",
2893 handshaking_result);
2894 else if (handshaking_result == 2)
2895 seq_printf(m,
2896 "Handshaking Result = %d (I2C Error)\n",
2897 handshaking_result);
2898 else
2899 seq_printf(m,
2900 "Handshaking Result = error\n");
2901
2902 } else {
2903 himax_list_cmd_read(m);
2904 }
2905
2906END_FUNC_R:
2907
2908 return ret;
2909}
2910
2911static ssize_t himax_debug_store(struct file *file, const char __user *ubuf,
2912 size_t len, loff_t *data)
2913{
2914
2915 char buf[80] = "\0";
2916 char *str_ptr = NULL;
2917 int str_len = 0;
2918 int input_cmd_len = 0;
2919 int i = 0, j = 0;
2920
2921 if (len >= 80) {
2922 I("%s: no command exceeds 80 chars.\n", __func__);
2923 return -EFAULT;
2924 }
2925
2926 if (copy_from_user(buf, ubuf, len))
2927 return -EFAULT;
2928
2929 str_len = len;
2930 buf[str_len - 1] = '\0';/*remove \n*/
2931 input_cmd_len = (int)strcspn(buf, ",");
2932 if (input_cmd_len == -1)
2933 input_cmd_len = str_len;
2934
2935 i = CMD_START_IDX; /* start from 1*/
2936 while (dbg_cmd_str[i] != NULL) {
2937 while (dbg_cmd_str[i][j] != NULL) {
2938 str_ptr = strnstr(buf, dbg_cmd_str[i][j], len);
2939 str_len = strlen(dbg_cmd_str[i][j]);
2940 if (str_len != input_cmd_len) {
2941 str_ptr = NULL;
2942 j++;
2943 continue;
2944 }
2945 if (str_ptr) {
2946 dbg_cmd_flag = i;
2947 debug_level_cmd = 0;
2948 I("Cmd is correct :%s, dbg_cmd = %d\n",
2949 str_ptr, dbg_cmd_flag);
2950 goto CHECK;
2951 }
2952 j++;
2953 }
2954 j = 0;
2955 i++;
2956 }
2957CHECK:
2958 if (!str_ptr) {
2959 I("Cmd is in old fromat or incorrect\n");
2960 dbg_cmd_flag = 0;
2961 goto CONTI;
2962 }
2963
2964 if (buf[str_len] == ',') {
2965 dbg_cmd_par = buf + str_len + 1;
2966 if (dbg_func_ptr_w[dbg_cmd_flag])
2967 /* 2 => '/n' + ','*/
2968 dbg_func_ptr_w[dbg_cmd_flag](dbg_cmd_par,
2969 len - str_len - 2);
2970
2971 I("string of paremeter is %s; dbg_cmd_par = %s, size = %d\n",
2972 buf + str_len + 1,
2973 dbg_cmd_par, (int)(len - str_len - 2));
2974 } else {
2975 I("Write cmd=%s, without parameter\n",
2976 dbg_cmd_str[dbg_cmd_flag][0]);
2977 }
2978CONTI:
2979 if (dbg_cmd_flag)
2980 return len;
2981
2982 if (buf[0] == 't') {
masonwangc4f998d2021-07-27 18:15:04 +08002983 /* Update firmware */
masonwangcdc58ea2021-07-27 09:54:47 +08002984 debug_level_cmd = buf[0];
2985 hx_node_update(buf, len);
masonwangc4f998d2021-07-27 18:15:04 +08002986 } else if (buf[0] == 'c' && buf[1] == 't' && buf[2] == 'i') {
masonwangcdc58ea2021-07-27 09:54:47 +08002987 /* Compare Touch Information */
2988 g_core_fp.fp_tp_info_check();
2989 goto ENDFUCTION;
masonwangc4f998d2021-07-27 18:15:04 +08002990 } else if (buf[0] == 'e' && buf[1] == 'c') {
2991 /* Erase firmware */
2992 g_core_fp.fp_sense_off(true);
2993 g_core_fp.fp_chip_erase();
masonwangcdc58ea2021-07-27 09:54:47 +08002994 } else {
masonwangc4f998d2021-07-27 18:15:04 +08002995 /* others, do nothing */
masonwangcdc58ea2021-07-27 09:54:47 +08002996 debug_level_cmd = 0;
2997 }
2998
2999ENDFUCTION:
3000 return len;
3001}
3002__CREATE_RW_NODE_HX(debug);
3003
3004static int himax_vendor_show(struct seq_file *m, void *v)
3005{
3006 int ret = 0;
3007
3008 seq_printf(m,
3009 "IC = %s\n", private_ts->chip_name);
3010
3011 seq_printf(m,
3012 "FW_VER = 0x%2.2X\n", ic_data->vendor_fw_ver);
3013
3014 if (private_ts->chip_cell_type == CHIP_IS_ON_CELL) {
3015 seq_printf(m,
3016 "CONFIG_VER = 0x%2.2X\n",
3017 ic_data->vendor_config_ver);
3018 } else {
3019 seq_printf(m,
3020 "TOUCH_VER = 0x%2.2X\n",
3021 ic_data->vendor_touch_cfg_ver);
3022 seq_printf(m,
3023 "DISPLAY_VER = 0x%2.2X\n",
3024 ic_data->vendor_display_cfg_ver);
3025 }
3026
3027 if (ic_data->vendor_cid_maj_ver < 0
3028 && ic_data->vendor_cid_min_ver < 0) {
3029 seq_printf(m,
3030 "CID_VER = NULL\n");
3031 } else {
3032 seq_printf(m,
3033 "CID_VER = 0x%2.2X\n",
3034 (ic_data->vendor_cid_maj_ver << 8 |
3035 ic_data->vendor_cid_min_ver));
3036 }
3037
3038 if (ic_data->vendor_panel_ver < 0) {
3039 seq_printf(m,
3040 "PANEL_VER = NULL\n");
3041 } else {
3042 seq_printf(m,
3043 "PANEL_VER = 0x%2.2X\n",
3044 ic_data->vendor_panel_ver);
3045 }
3046 if (private_ts->chip_cell_type == CHIP_IS_IN_CELL) {
3047 seq_printf(m,
3048 "Cusomer = %s\n",
3049 ic_data->vendor_cus_info);
3050 seq_printf(m,
3051 "Project = %s\n",
3052 ic_data->vendor_proj_info);
3053 }
3054 seq_puts(m, "\n");
3055 seq_printf(m,
3056 "Himax Touch Driver Version:\n");
3057 seq_printf(m, "%s\n",
3058 HIMAX_DRIVER_VER);
3059
3060 return ret;
3061}
3062__CREATE_OREAD_NODE_HX(vendor);
3063
3064static void himax_himax_data_init(void)
3065{
3066 debug_data->fp_ts_dbg_func = himax_ts_dbg_func;
3067 debug_data->fp_set_diag_cmd = himax_set_diag_cmd;
3068 debug_data->flash_dump_going = false;
3069 debug_data->is_checking_irq = false;
3070 debug_data->is_call_help = false;
3071}
3072
3073static void himax_ts_dump_work_func(struct work_struct *work)
3074{
3075 himax_ts_dump_func();
3076}
3077#if defined(HX_TP_PROC_GUEST_INFO)
3078static void himax_ts_guest_info_work_func(struct work_struct *work)
3079{
3080 g_core_fp.read_guest_info();
3081}
3082#endif
3083
3084static void himax_ts_diag_work_func(struct work_struct *work)
3085{
3086 himax_ts_diag_func(process_type);
3087
3088 if (process_type != 0) {
3089 queue_delayed_work(private_ts->himax_diag_wq,
3090 &private_ts->himax_diag_delay_work, 1 / 10 * HZ);
3091 } else {
3092 dsram_flag = false;
3093 }
3094}
3095
3096void dbg_func_ptr_init(void)
3097{
3098 /*debug function ptr init*/
masonwang533a4032021-08-05 09:57:24 +08003099 dbg_func_ptr_r[CMD_CRC_TEST] = himax_crc_test_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003100
masonwang533a4032021-08-05 09:57:24 +08003101 dbg_func_ptr_r[CND_FW_DBG] = himax_proc_fw_debug_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003102
masonwang533a4032021-08-05 09:57:24 +08003103 dbg_func_ptr_r[CMD_ATTN] = himax_attn_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003104
masonwang533a4032021-08-05 09:57:24 +08003105 dbg_func_ptr_w[CMD_LAYOUT] = himax_layout_write;
3106 dbg_func_ptr_r[CMD_LAYOUT] = himax_layout_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003107
3108#if defined(HX_EXCP_RECOVERY)
masonwang533a4032021-08-05 09:57:24 +08003109 dbg_func_ptr_w[CMD_EXCEPT] = himax_excp_cnt_write;
3110 dbg_func_ptr_r[CMD_EXCEPT] = himax_excp_cnt_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003111#endif
masonwangcdc58ea2021-07-27 09:54:47 +08003112
masonwang533a4032021-08-05 09:57:24 +08003113 dbg_func_ptr_w[CMD_SENSE_ON_OFF] = himax_sense_on_off_write;
3114 dbg_func_ptr_r[CMD_SENSE_ON_OFF] = himax_sense_on_off_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003115
masonwang533a4032021-08-05 09:57:24 +08003116 dbg_func_ptr_w[CMD_DBG_LEVEL] = himax_debug_level_write;
3117 dbg_func_ptr_r[CMD_DBG_LEVEL] = himax_debug_level_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003118
3119#if defined(HX_TP_PROC_GUEST_INFO)
masonwang533a4032021-08-05 09:57:24 +08003120 dbg_func_ptr_w[CMD_GUEST_INFO] = himax_proc_guest_info_write;
3121 dbg_func_ptr_r[CMD_GUEST_INFO] = himax_proc_guest_info_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003122#endif
masonwangcdc58ea2021-07-27 09:54:47 +08003123
masonwang533a4032021-08-05 09:57:24 +08003124 dbg_func_ptr_w[CMD_INTERRUPT] = himax_int_en_write;
3125 dbg_func_ptr_r[CMD_INTERRUPT] = himax_int_en_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003126
masonwang533a4032021-08-05 09:57:24 +08003127 dbg_func_ptr_w[CND_IRQ_INFO] = himax_irq_info_write;
3128 dbg_func_ptr_r[CND_IRQ_INFO] = himax_irq_info_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003129
masonwang533a4032021-08-05 09:57:24 +08003130 dbg_func_ptr_w[CMD_REGISTER] = himax_proc_register_write;
3131 dbg_func_ptr_r[CMD_REGISTER] = himax_proc_register_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003132
masonwang533a4032021-08-05 09:57:24 +08003133 dbg_func_ptr_w[CMD_RESET] = himax_reset_write;
3134 dbg_func_ptr_r[CMD_RESET] = himax_reset_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003135
masonwang533a4032021-08-05 09:57:24 +08003136 dbg_func_ptr_w[CMD_DIAG_ARRANGE] = himax_diag_arrange_write;
3137 dbg_func_ptr_r[CMD_DIAG_ARRANGE] = himax_diag_arrange_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003138
masonwang533a4032021-08-05 09:57:24 +08003139 dbg_func_ptr_w[CMD_DIAG_CMD] = himax_diag_cmd_write;
masonwangcdc58ea2021-07-27 09:54:47 +08003140
masonwang533a4032021-08-05 09:57:24 +08003141 dbg_func_ptr_w[CMD_IRQ_DBG_CMD] = himax_irq_dbg_cmd_write;
masonwangcdc58ea2021-07-27 09:54:47 +08003142
masonwang533a4032021-08-05 09:57:24 +08003143 dbg_func_ptr_r[CMD_TEST_BUS] = himax_test_bus_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003144
masonwang533a4032021-08-05 09:57:24 +08003145 dbg_func_ptr_w[CMD_FW_UPDATE] = himax_update_write;
3146 dbg_func_ptr_r[CMD_FW_UPDATE] = himax_update_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003147
masonwang533a4032021-08-05 09:57:24 +08003148 dbg_func_ptr_w[CMD_VERSION] = himax_version_write;
3149 dbg_func_ptr_r[CMD_VERSION] = himax_version_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003150
masonwang533a4032021-08-05 09:57:24 +08003151 dbg_func_ptr_r[CND_INFO] = himax_info_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003152
masonwang533a4032021-08-05 09:57:24 +08003153 dbg_func_ptr_r[CMD_LIST] = himax_list_cmd_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003154
masonwang533a4032021-08-05 09:57:24 +08003155 dbg_func_ptr_w[CMD_HELP] = himax_help_write;
3156 dbg_func_ptr_r[CMD_HELP] = himax_help_read;
masonwangcdc58ea2021-07-27 09:54:47 +08003157}
3158
3159int himax_touch_proc_init(void)
3160{
3161 himax_proc_diag_dir = proc_mkdir(HIMAX_PROC_DIAG_FOLDER,
3162 himax_touch_proc_dir);
3163
3164 if (himax_proc_diag_dir == NULL) {
3165 E(" %s: himax_proc_diag_dir file create failed!\n", __func__);
3166 return -ENOMEM;
3167 }
3168
3169 himax_proc_stack_file = proc_create(HIMAX_PROC_STACK_FILE, 0444,
3170 himax_proc_diag_dir, &himax_stack_ops);
3171 if (himax_proc_stack_file == NULL) {
3172 E(" %s: proc stack file create failed!\n", __func__);
3173 goto fail_2_1;
3174 }
3175
3176 himax_proc_delta_file = proc_create(HIMAX_PROC_DELTA_FILE, 0444,
3177 himax_proc_diag_dir, &himax_delta_ops);
3178 if (himax_proc_delta_file == NULL) {
3179 E(" %s: proc delta file create failed!\n", __func__);
3180 goto fail_2_2;
3181 }
3182
3183 himax_proc_dc_file = proc_create(HIMAX_PROC_DC_FILE, 0444,
3184 himax_proc_diag_dir, &himax_dc_ops);
3185 if (himax_proc_dc_file == NULL) {
3186 E(" %s: proc dc file create failed!\n", __func__);
3187 goto fail_2_3;
3188 }
3189
3190 himax_proc_baseline_file = proc_create(HIMAX_PROC_BASELINE_FILE, 0444,
3191 himax_proc_diag_dir, &himax_baseline_ops);
3192 if (himax_proc_baseline_file == NULL) {
3193 E(" %s: proc baseline file create failed!\n", __func__);
3194 goto fail_2_4;
3195 }
3196
3197 himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE,
3198 0644, himax_touch_proc_dir,
3199 &himax_debug_ops);
3200 if (himax_proc_debug_file == NULL) {
3201 E(" %s: proc debug file create failed!\n", __func__);
3202 goto fail_3;
3203 }
3204 dbg_func_ptr_init();
3205
3206 himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE,
3207 0644, himax_touch_proc_dir,
3208 &himax_flash_dump_ops);
3209 if (himax_proc_flash_dump_file == NULL) {
3210 E(" %s: proc flash dump file create failed!\n", __func__);
3211 goto fail_4;
3212 }
3213
3214 return 0;
3215
3216fail_4: remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir);
3217fail_3: remove_proc_entry(HIMAX_PROC_BASELINE_FILE, himax_proc_diag_dir);
3218fail_2_4: remove_proc_entry(HIMAX_PROC_DC_FILE, himax_proc_diag_dir);
3219fail_2_3: remove_proc_entry(HIMAX_PROC_DELTA_FILE, himax_proc_diag_dir);
3220fail_2_2: remove_proc_entry(HIMAX_PROC_STACK_FILE, himax_proc_diag_dir);
3221fail_2_1:
3222 return -ENOMEM;
3223}
3224
3225void himax_touch_proc_deinit(void)
3226{
3227
3228 remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir);
3229 remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir);
3230 remove_proc_entry(HIMAX_PROC_BASELINE_FILE, himax_proc_diag_dir);
3231 remove_proc_entry(HIMAX_PROC_DC_FILE, himax_proc_diag_dir);
3232 remove_proc_entry(HIMAX_PROC_DELTA_FILE, himax_proc_diag_dir);
3233 remove_proc_entry(HIMAX_PROC_STACK_FILE, himax_proc_diag_dir);
3234}
3235
3236int himax_debug_init(void)
3237{
3238 struct himax_ts_data *ts = private_ts;
3239
3240 I("%s:Enter\n", __func__);
3241
3242 if (ts == NULL) {
3243 E("%s: ts struct is NULL\n", __func__);
3244 return -EPROBE_DEFER;
3245 }
3246
3247 proc_reg_buf = kzalloc(128 * sizeof(uint8_t), GFP_KERNEL);
3248 if (proc_reg_buf == NULL) {
3249 E("%s: reg_read_data allocate failed\n", __func__);
3250 goto err_alloc_reg_read_data_fail;
3251 }
3252
3253 debug_data = kzalloc(sizeof(struct himax_debug), GFP_KERNEL);
3254 if (debug_data == NULL) { /*Allocate debug data space*/
3255 E("%s: debug_data allocate failed\n", __func__);
3256 goto err_alloc_debug_data_fail;
3257 }
3258
3259 himax_himax_data_init();
3260
3261 g_dump_buffer = kcalloc(ic_data->flash_size,
3262 sizeof(uint8_t),
3263 GFP_KERNEL);
3264 if (g_dump_buffer == NULL) {
3265 E("%s: dump buffer allocate fail failed\n", __func__);
3266 goto err_dump_buf_alloc_failed;
3267 }
3268
3269 ts->dump_wq = create_singlethread_workqueue("himax_dump_wq");
3270 if (!ts->dump_wq) {
3271 E("%s: create flash workqueue failed\n", __func__);
3272 goto err_create_flash_dump_wq_failed;
3273 }
3274 INIT_WORK(&ts->dump_work, himax_ts_dump_work_func);
3275 g_flash_progress = START;
3276
3277#if defined(HX_TP_PROC_GUEST_INFO)
3278 if (g_guest_info_data == NULL) {
3279 g_guest_info_data = kzalloc(sizeof(struct hx_guest_info),
3280 GFP_KERNEL);
3281 if (g_guest_info_data == NULL) {
3282 E("%s: flash buffer allocate fail failed\n", __func__);
3283 goto err_guest_info_alloc_failed;
3284 }
3285 g_guest_info_data->g_guest_info_ongoing = 0;
3286 g_guest_info_data->g_guest_info_type = 0;
3287 }
3288
3289 ts->guest_info_wq =
3290 create_singlethread_workqueue("himax_guest_info_wq");
3291 if (!ts->guest_info_wq) {
3292 E("%s: create guest info workqueue failed\n", __func__);
3293 goto err_create_guest_info_wq_failed;
3294 }
3295 INIT_WORK(&ts->guest_info_work, himax_ts_guest_info_work_func);
3296#endif
3297
3298 setSelfBuffer(ic_data->HX_RX_NUM, ic_data->HX_TX_NUM);
3299 if (getSelfBuffer() == NULL) {
3300 E("%s: self buffer allocate failed\n", __func__);
3301 goto err_self_buf_alloc_failed;
3302 }
3303
3304 setSelfNewBuffer(ic_data->HX_RX_NUM, ic_data->HX_TX_NUM);
3305 if (getSelfNewBuffer() == NULL) {
3306 E("%s: self new buffer allocate failed\n", __func__);
3307 goto err_self_new_alloc_failed;
3308 }
3309
3310 setSelfOldBuffer(ic_data->HX_RX_NUM, ic_data->HX_TX_NUM);
3311 if (getSelfOldBuffer() == NULL) {
3312 E("%s: self old buffer allocate failed\n", __func__);
3313 goto err_self_old_alloc_failed;
3314 }
3315
3316 setMutualBuffer(ic_data->HX_RX_NUM, ic_data->HX_TX_NUM);
3317 if (getMutualBuffer() == NULL) {
3318 E("%s: mutual buffer allocate failed\n", __func__);
3319 goto err_mut_buf_alloc_failed;
3320 }
3321
3322 setMutualNewBuffer(ic_data->HX_RX_NUM, ic_data->HX_TX_NUM);
3323 if (getMutualNewBuffer() == NULL) {
3324 E("%s: mutual new buffer allocate failed\n", __func__);
3325 goto err_mut_new_alloc_failed;
3326 }
3327
3328 setMutualOldBuffer(ic_data->HX_RX_NUM, ic_data->HX_TX_NUM);
3329 if (getMutualOldBuffer() == NULL) {
3330 E("%s: mutual old buffer allocate failed\n", __func__);
3331 goto err_mut_old_alloc_failed;
3332 }
3333
3334#if defined(HX_TP_PROC_2T2R)
3335 if (Is_2T2R) {
3336 setMutualBuffer_2(ic_data->HX_RX_NUM_2, ic_data->HX_TX_NUM_2);
3337 if (getMutualBuffer_2() == NULL) {
3338 E("%s: mutual buffer 2 allocate failed\n", __func__);
3339 goto err_mut_buf2_alloc_failed;
3340 }
3341 }
3342#endif
3343
3344 ts->himax_diag_wq = create_singlethread_workqueue("himax_diag");
3345 if (!ts->himax_diag_wq) {
3346 E("%s: create diag workqueue failed\n", __func__);
3347 goto err_create_diag_wq_failed;
3348 }
3349 INIT_DELAYED_WORK(&ts->himax_diag_delay_work, himax_ts_diag_work_func);
3350
3351 if (himax_touch_proc_init())
3352 goto err_proc_init_failed;
3353
3354
3355 snprintf(g_file_path, (int)(strlen(HX_RSLT_OUT_PATH)
3356 + strlen(HX_RSLT_OUT_FILE)+1),
3357 "%s%s", HX_RSLT_OUT_PATH, HX_RSLT_OUT_FILE);
3358
3359 return 0;
3360
3361err_proc_init_failed:
3362 cancel_delayed_work_sync(&ts->himax_diag_delay_work);
3363 destroy_workqueue(ts->himax_diag_wq);
3364err_create_diag_wq_failed:
3365#if defined(HX_TP_PROC_2T2R)
3366 kfree(diag_mutual_2);
3367 diag_mutual_2 = NULL;
3368err_mut_buf2_alloc_failed:
3369#endif
3370 kfree(diag_mutual_old);
3371 diag_mutual_old = NULL;
3372err_mut_old_alloc_failed:
3373 kfree(diag_mutual_new);
3374 diag_mutual_new = NULL;
3375err_mut_new_alloc_failed:
3376 kfree(diag_mutual);
3377 diag_mutual = NULL;
3378err_mut_buf_alloc_failed:
3379 kfree(diag_self_old);
3380 diag_self_old = NULL;
3381err_self_old_alloc_failed:
3382 kfree(diag_self_new);
3383 diag_self_new = NULL;
3384err_self_new_alloc_failed:
3385 kfree(diag_self);
3386 diag_self = NULL;
3387err_self_buf_alloc_failed:
3388#if defined(HX_TP_PROC_GUEST_INFO)
3389 cancel_work_sync(&ts->guest_info_work);
3390 destroy_workqueue(ts->guest_info_wq);
3391err_create_guest_info_wq_failed:
3392 if (g_guest_info_data != NULL) {
3393 kfree(g_guest_info_data);
3394 g_guest_info_data = NULL;
3395 }
3396err_guest_info_alloc_failed:
3397#endif
3398 cancel_work_sync(&ts->dump_work);
3399 destroy_workqueue(ts->dump_wq);
3400err_create_flash_dump_wq_failed:
3401 kfree(g_dump_buffer);
3402 g_dump_buffer = NULL;
3403err_dump_buf_alloc_failed:
3404 kfree(debug_data);
3405 debug_data = NULL;
3406err_alloc_debug_data_fail:
3407 kfree(proc_reg_buf);
3408 proc_reg_buf = NULL;
3409err_alloc_reg_read_data_fail:
3410
3411 return -ENOMEM;
3412}
3413EXPORT_SYMBOL(himax_debug_init);
3414
3415int himax_debug_remove(void)
3416{
3417 struct himax_ts_data *ts = private_ts;
3418
3419 himax_touch_proc_deinit();
3420
3421 cancel_delayed_work_sync(&ts->himax_diag_delay_work);
3422 destroy_workqueue(ts->himax_diag_wq);
3423
3424 kfree(diag_mutual_2);
3425 diag_mutual_2 = NULL;
3426
3427 kfree(diag_mutual_old);
3428 diag_mutual_old = NULL;
3429
3430 kfree(diag_mutual_new);
3431 diag_mutual_new = NULL;
3432
3433 kfree(diag_mutual);
3434 diag_mutual = NULL;
3435
3436 kfree(diag_self_old);
3437 diag_self_old = NULL;
3438
3439 kfree(diag_self_new);
3440 diag_self_new = NULL;
3441
3442 kfree(diag_self);
3443 diag_self = NULL;
3444
3445#if defined(HX_TP_PROC_GUEST_INFO)
3446 cancel_work_sync(&ts->guest_info_work);
3447 destroy_workqueue(ts->guest_info_wq);
3448 if (g_guest_info_data != NULL) {
3449 kfree(g_guest_info_data);
3450 g_guest_info_data = NULL;
3451 }
3452#endif
3453
3454 cancel_work_sync(&ts->dump_work);
3455 destroy_workqueue(ts->dump_wq);
3456
3457 kfree(g_dump_buffer);
3458 g_dump_buffer = NULL;
3459
3460 kfree(debug_data);
3461 debug_data = NULL;
3462
3463 kfree(proc_reg_buf);
3464 proc_reg_buf = NULL;
3465
3466 return 0;
3467}
3468EXPORT_SYMBOL(himax_debug_remove);
3469