1 /*
2  *
3  * FocalTech TouchScreen driver.
4  *
5  * Copyright (c) 2012-2018, FocalTech Systems, Ltd., all rights reserved.
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 
18 #include "focaltech_test.h"
19 
20 /*****************************************************************************
21 * Private constant and macro definitions using #define
22 *****************************************************************************/
23 struct ini_ic_type ic_types[] = {
24     {"FT5X46",  0x54000002},
25     {"FT5X46i", 0x54010002},
26     {"FT5526",  0x54020002},
27     {"FT3X17",  0x54030002},
28     {"FT5436",  0x54040002},
29     {"FT3X27",  0x54050002},
30     {"FT5526i", 0x54060002},
31     {"FT5416",  0x54070002},
32     {"FT5426",  0x54080002},
33     {"FT5435",  0x54090002},
34     {"FT7681",  0x540A0002},
35     {"FT7661",  0x540B0002},
36     {"FT7511",  0x540C0002},
37     {"FT7421",  0x540D0002},
38     {"FT7311",  0x54100002},
39     {"FT3327DQQ-001", 0x41000082},
40     {"FT5446DQS-W01", 0x40000082},
41 
42     {"FT5452",  0x55000081},
43     {"FT3518",  0x55010081},
44     {"FT3558",  0x55020081},
45     {"FT3528",  0x55030081},
46     {"FT5536",  0x55040081},
47 
48     {"FT5472",  0x8F000083},
49     {"FT5446U", 0x8F010083},
50     {"FT5456U", 0x8F020083},
51     {"FT3417U", 0x8F030083},
52     {"FT5426U", 0x8F040083},
53     {"FT3428",  0x8F050083},
54     {"FT3437U", 0x8F060083},
55 
56     {"FT5822",  0x58000001},
57     {"FT5626",  0x58010001},
58     {"FT5726",  0x58020001},
59     {"FT5826B", 0x58030001},
60     {"FT3617",  0x58040001},
61     {"FT3717",  0x58050001},
62     {"FT7811",  0x58060001},
63     {"FT5826S", 0x58070001},
64     {"FT3517U", 0x58090001},
65     {"FT3557",  0x580A0001},
66 
67     {"FT6X36",  0x63000003},
68     {"FT3X07",  0x63010003},
69     {"FT6416",  0x63020003},
70     {"FT6336G/U", 0x63030003},
71     {"FT7401",  0x63040003},
72     {"FT3407U", 0x63050003},
73     {"FT6236U", 0x63060003},
74     {"FT6436U", 0x63070003},
75 
76     {"FT3267",  0x63080004},
77     {"FT3367",  0x63090004},
78 
79 
80     {"FT8607",  0x81000009},
81     {"FT8716",  0x82000005},
82     {"FT8716U", 0x44000005},
83     {"FT8716F", 0x8A000005},
84     {"FT8613",  0x4500000C},
85 
86     {"FT8736",  0x83000006},
87 
88     {"FT8006M", 0x87000007},
89     {"FT8201",  0x87010010},
90     {"FT7250",  0x87020007},
91 
92     {"FT8006U", 0x8900000B},
93     {"FT8006S", 0x8901000B},
94 
95     {"FT8719",  0x9000000D},
96     {"FT8615",  0x9100000F},
97 
98     {"FT8739",  0x8D00000E},
99 
100     {"FT8006P", 0x93000011},
101 };
102 
103 /*****************************************************************************
104 * Global variable or extern global variabls/functions
105 *****************************************************************************/
106 
107 /*****************************************************************************
108 * Static function prototypes
109 *****************************************************************************/
110 /* Works only for digits and letters, but small and fast */
111 #define TOLOWER(x) ((x) | 0x20)
fts_strncmp(const char * cs,const char * ct,int count)112 static int fts_strncmp(const char *cs, const char *ct, int count)
113 {
114     u8 c1 = 0, c2 = 0;
115 
116     while (count) {
117         if  ((*cs == '\0') || (*ct == '\0'))
118             return -1;
119         c1 = TOLOWER(*cs++);
120         c2 = TOLOWER(*ct++);
121         if (c1 != c2)
122             return c1 < c2 ? -1 : 1;
123         if (!c1)
124             break;
125         count--;
126     }
127 
128     return 0;
129 }
130 
fts_atol(char * nptr)131 static long fts_atol(char *nptr)
132 {
133     int c; /* current char */
134     long total; /* current total */
135     int sign; /* if ''-'', then negative, otherwise positive */
136     /* skip whitespace */
137     while ( isspace((int)(unsigned char)*nptr) )
138         ++nptr;
139     c = (int)(unsigned char) * nptr++;
140     sign = c; /* save sign indication */
141     if (c == '-' || c == '+')
142         c = (int)(unsigned char) * nptr++; /* skip sign */
143     total = 0;
144     while (isdigit(c)) {
145         total = 10 * total + (c - '0'); /* accumulate digit */
146         c = (int)(unsigned char) * nptr++; /* get next char */
147     }
148     if (sign == '-')
149         return -total;
150     else
151         return total; /* return result, negated if necessary */
152 }
153 
fts_atoi(char * nptr)154 static int fts_atoi(char *nptr)
155 {
156     return (int)fts_atol(nptr);
157 }
158 
fts_test_get_ini_size(char * config_name)159 static int fts_test_get_ini_size(char *config_name)
160 {
161     struct file *pfile = NULL;
162     struct inode *inode = NULL;
163     off_t fsize = 0;
164     char filepath[128];
165 
166     FTS_TEST_FUNC_ENTER();
167 
168     memset(filepath, 0, sizeof(filepath));
169     sprintf(filepath, "%s%s", FTS_INI_FILE_PATH, config_name);
170 
171     if (NULL == pfile)
172         pfile = filp_open(filepath, O_RDONLY, 0);
173     if (IS_ERR(pfile)) {
174         FTS_TEST_ERROR("error occured while opening file %s.",  filepath);
175         return -EIO;
176     }
177 
178 #if 1
179     inode = pfile->f_inode;
180 #else
181     /* reserved for linux earlier verion */
182     inode = pfile->f_dentry->d_inode;
183 #endif
184     fsize = inode->i_size;
185     filp_close(pfile, NULL);
186 
187     FTS_TEST_FUNC_ENTER();
188 
189     return fsize;
190 }
191 
fts_test_read_ini_data(char * config_name,char * config_buf)192 static int fts_test_read_ini_data(char *config_name, char *config_buf)
193 {
194     struct file *pfile = NULL;
195     struct inode *inode = NULL;
196     off_t fsize = 0;
197     char filepath[128];
198     loff_t pos = 0;
199     mm_segment_t old_fs;
200 
201     FTS_TEST_FUNC_ENTER();
202 
203     memset(filepath, 0, sizeof(filepath));
204     sprintf(filepath, "%s%s", FTS_INI_FILE_PATH, config_name);
205     if (NULL == pfile) {
206         pfile = filp_open(filepath, O_RDONLY, 0);
207     }
208     if (IS_ERR(pfile)) {
209         FTS_TEST_ERROR("error occured while opening file %s.",  filepath);
210         return -EIO;
211     }
212 
213 #if 1
214     inode = pfile->f_inode;
215 #else
216     /* reserved for linux earlier verion */
217     inode = pfile->f_dentry->d_inode;
218 #endif
219     fsize = inode->i_size;
220     old_fs = get_fs();
221     set_fs(KERNEL_DS);
222     pos = 0;
223     vfs_read(pfile, config_buf, fsize, &pos);
224     filp_close(pfile, NULL);
225     set_fs(old_fs);
226 
227     FTS_TEST_FUNC_EXIT();
228     return 0;
229 }
230 
str_space_remove(char * str)231 static void str_space_remove(char *str)
232 {
233     char *t = str;
234     char *s = str;
235 
236     while (*t != '\0') {
237         if (*t != ' ') {
238             *s = *t;
239             s++;
240         }
241         t++;
242     }
243 
244     *s = '\0';
245 }
246 
247 #ifdef INI_PRINT
print_ini_data(struct ini_data * ini)248 static void print_ini_data(struct ini_data *ini)
249 {
250     int i = 0;
251     int j = 0;
252     struct ini_section *section;
253     struct ini_keyword *keyword;
254 
255     if (!ini || !ini->tmp) {
256         FTS_TEST_DBG("ini is null");
257         return;
258     }
259 
260     FTS_TEST_DBG("section num:%d, keyword num total:%d\n",
261                  ini->section_num, ini->keyword_num_total);
262     for (i = 0; i < ini->section_num; i++) {
263         section = &ini->section[i];
264         FTS_TEST_DBG("section name:[%s] keyword num:%d\n",
265                      section->name, section->keyword_num);
266         for (j = 0; j < section->keyword_num; j++) {
267             keyword = &section->keyword[j];
268             FTS_TEST_DBG("%s=%s\n", keyword->name, keyword->value);
269         }
270     }
271 }
272 #endif
273 
ini_get_line(char * filedata,char * line_data,int * line_len)274 static int ini_get_line(char *filedata, char *line_data, int *line_len)
275 {
276     int i = 0;
277     int line_length = 0;
278     int type;
279 
280     /* get a line data */
281     for (i = 0; i < MAX_INI_LINE_LEN; i++) {
282         if (('\n' == filedata[i]) || ('\r' == filedata[i])) {
283             line_data[line_length++] = '\0';
284             if (('\n' == filedata[i + 1]) || ('\r' == filedata[i + 1])) {
285                 line_length++;
286             }
287             break;
288         } else {
289             line_data[line_length++] = filedata[i];
290         }
291     }
292 
293     if (i >= MAX_INI_LINE_LEN) {
294         FTS_TEST_ERROR("line length(%d)>max(%d)", line_length, MAX_INI_LINE_LEN);
295         return -ENODATA;
296     }
297 
298     /* remove space */
299     str_space_remove(line_data);
300 
301     /* confirm line type */
302     if (('\0' == line_data[0]) || ('#' == line_data[0])) {
303         type = LINE_OTHER;
304     } else if ('[' == line_data[0]) {
305         type = LINE_SECTION;
306     } else {
307         type = LINE_KEYWORD; /* key word */
308     }
309 
310     *line_len = line_length;
311     return type;
312 }
313 
ini_parse_keyword(struct ini_data * ini,char * line_buffer)314 static int ini_parse_keyword(struct ini_data *ini, char *line_buffer)
315 {
316     int i = 0;
317     int offset = 0;
318     int length = strlen(line_buffer);
319     struct ini_section *section = NULL;
320 
321     for (i = 0; i < length; i++) {
322         if (line_buffer[i] == '=')
323             break;
324     }
325 
326     if ((i == 0) || (i >= length)) {
327         FTS_TEST_ERROR("mark(=)in keyword line fail");
328         return -ENODATA;
329     }
330 
331     if ((ini->section_num > 0) && (ini->section_num < MAX_INI_SECTION_NUM)) {
332         section = &ini->section[ini->section_num - 1];
333     }
334 
335     if (NULL == section) {
336         FTS_TEST_ERROR("section is null");
337         return -ENODATA;
338     }
339 
340     offset = ini->keyword_num_total;
341     if (offset > MAX_KEYWORD_NUM) {
342         FTS_TEST_ERROR("keyword num(%d)>max(%d),please check MAX_KEYWORD_NUM",
343                        ini->keyword_num_total, MAX_KEYWORD_NUM);
344         return -ENODATA;
345     }
346     memcpy(ini->tmp[offset].name, &line_buffer[0], i);
347     ini->tmp[offset].name[i] = '\0';
348     memcpy(ini->tmp[offset].value, &line_buffer[i + 1], length - i - 1);
349     ini->tmp[offset].value[length - i - 1] = '\0';
350     section->keyword_num++;
351     ini->keyword_num_total++;
352 
353     return 0;
354 }
355 
ini_parse_section(struct ini_data * ini,char * line_buffer)356 static int ini_parse_section(struct ini_data *ini, char *line_buffer)
357 {
358     int length = strlen(line_buffer);
359     struct ini_section *section = NULL;
360 
361     if ((length <= 2) || (length > MAX_KEYWORD_NAME_LEN)) {
362         FTS_TEST_ERROR("section line length fail");
363         return -EINVAL;
364     }
365 
366     if ((ini->section_num < 0) || (ini->section_num > MAX_INI_SECTION_NUM)) {
367         FTS_TEST_ERROR("section_num(%d) fail", ini->section_num);
368         return -EINVAL;
369     }
370     section = &ini->section[ini->section_num];
371     memcpy(section->name, line_buffer + 1, length - 2);
372     section->name[length - 2] = '\0';
373     FTS_TEST_INFO("section:%s, keyword offset:%d",
374                   section->name, ini->keyword_num_total);
375     section->keyword = (struct ini_keyword *)&ini->tmp[ini->keyword_num_total];
376     section->keyword_num = 0;
377     ini->section_num++;
378     if (ini->section_num > MAX_INI_SECTION_NUM) {
379         FTS_TEST_ERROR("section num(%d)>max(%d), please check MAX_INI_SECTION_NUM",
380                        ini->section_num, MAX_INI_SECTION_NUM);
381         return -ENOMEM;
382     }
383 
384     return 0;
385 }
386 
ini_init_inidata(struct ini_data * ini)387 static int ini_init_inidata(struct ini_data *ini)
388 {
389     int pos = 0;
390     int ret = 0;
391     char line_buffer[MAX_INI_LINE_LEN] = { 0 };
392     int line_len = 0;
393 
394     if (!ini || !ini->data || !ini->tmp) {
395         FTS_TEST_DBG("ini/data/tmp is null");
396         return -EINVAL;
397     }
398 
399     while (pos < ini->length) {
400         ret = ini_get_line(ini->data + pos, line_buffer, &line_len);
401         if (ret < 0) {
402             FTS_TEST_ERROR("ini_get_line fail");
403             return ret;
404         } else if (ret == LINE_KEYWORD) {
405             ret = ini_parse_keyword(ini, line_buffer);
406             if (ret < 0) {
407                 FTS_TEST_ERROR("ini_parse_keyword fail");
408                 return ret;
409             }
410         } else if (ret == LINE_SECTION) {
411             ret = ini_parse_section(ini, line_buffer);
412             if (ret < 0) {
413                 FTS_TEST_ERROR("ini_parse_section fail");
414                 return ret;
415             }
416         }
417 
418         pos += line_len;
419     }
420 
421     return 0;
422 }
423 
ini_get_key(char * section_name,char * key_name,char * value)424 static int ini_get_key(char *section_name, char *key_name, char *value)
425 {
426     int i = 0;
427     int j = 0;
428     struct ini_data *ini = &fts_ftest->ini;
429     struct ini_section *section;
430     struct ini_keyword *keyword;
431     int key_len = 0;
432 
433 #ifdef INI_PRINT
434     FTS_TEST_DBG("section name:%s, key name:%s\n", section_name, key_name);
435     FTS_TEST_DBG("section num:%d\n", ini->section_num);
436 #endif
437     for (i = 0; i < ini->section_num; i++) {
438         section = &ini->section[i];
439         key_len = strlen(section_name);
440         if (key_len != strlen(section->name))
441             continue;
442         if (fts_strncmp(section->name, section_name, key_len) != 0)
443             continue;
444 #ifdef INI_PRINT
445         FTS_TEST_DBG("section name:%s keyword num:%d\n",
446                      section->name, section->keyword_num);
447 #endif
448         for (j = 0; j < section->keyword_num; j++) {
449             keyword = &section->keyword[j];
450             key_len = strlen(key_name);
451             if (key_len == strlen(keyword->name)) {
452                 if (0 == fts_strncmp(keyword->name, key_name, key_len)) {
453                     key_len = strlen(keyword->value);
454                     memcpy(value, keyword->value, key_len);
455                     FTS_TEST_DBG("section:%s,%s=%s\n", section_name, key_name, value);
456                     return key_len;
457                 }
458             }
459         }
460     }
461 
462     return -ENODATA;
463 }
464 
465 /* return keyword's value length if success */
ini_get_string_value(char * section_name,char * key_name,char * rval)466 static int ini_get_string_value(char *section_name, char *key_name, char *rval)
467 {
468     if (!section_name || !key_name || !rval) {
469         FTS_TEST_ERROR("section_name/key_name/rval is null");
470         return -EINVAL;
471     }
472 
473     return ini_get_key(section_name, key_name, rval);
474 }
475 
get_keyword_value(char * section,char * name,int * value)476 int get_keyword_value(char *section, char *name, int *value)
477 {
478     int ret = 0;
479     char str[MAX_KEYWORD_VALUE_LEN] = { 0 };
480 
481     ret = ini_get_string_value(section, name, str);
482     if (ret > 0) {
483         /* search successfully, so change value, otherwise keep default */
484         *value = fts_atoi(str);
485     }
486 
487     return ret;
488 }
489 
fts_init_buffer(int * buffer,int value,int len)490 static void fts_init_buffer(int *buffer, int value, int len)
491 {
492     int i = 0;
493 
494     if (NULL == buffer) {
495         FTS_TEST_ERROR("buffer is null\n");
496         return;
497     }
498 
499     for (i = 0; i < len; i++) {
500         buffer[i] = value;
501     }
502 }
503 
get_test_item(char name[][MAX_KEYWORD_NAME_LEN],int length,int * val)504 static int get_test_item(char name[][MAX_KEYWORD_NAME_LEN], int length, int *val)
505 {
506     int i = 0;
507     int ret = 0;
508     int tmpval = 0;
509 
510     if (length > TEST_ITEM_COUNT_MAX) {
511         FTS_TEST_SAVE_ERR("test item count(%d) > max(%d)\n",
512                           length, TEST_ITEM_COUNT_MAX);
513         return -EINVAL;
514     }
515 
516     FTS_TEST_INFO("test items in total of driver:%d", length);
517     *val = 0;
518     for (i = 0; i < length; i++) {
519         tmpval = 0;
520         ret = get_value_testitem(name[i], &tmpval);
521         if (ret < 0) {
522             FTS_TEST_DBG("test item:%s not found", name[i]);
523         } else {
524             FTS_TEST_DBG("test item:%s=%d", name[i], tmpval);
525             *val |= (tmpval << i);
526         }
527     }
528 
529     return 0;
530 }
531 
get_basic_threshold(char name[][MAX_KEYWORD_NAME_LEN],int length,int * val)532 static int get_basic_threshold(char name[][MAX_KEYWORD_NAME_LEN], int length, int *val)
533 {
534     int i = 0;
535     int ret = 0;
536     struct fts_test *tdata = fts_ftest;
537 
538     FTS_TEST_INFO("basic_thr string length(%d), count(%d)\n", length, tdata->basic_thr_count);
539     if (length > fts_ftest->basic_thr_count) {
540         FTS_TEST_SAVE_ERR("basic_thr string length > count\n");
541         return -EINVAL;
542     }
543 
544     for (i = 0; i < length; i++) {
545         ret = get_value_basic(name[i], &val[i]);
546         if (ret < 0) {
547             FTS_TEST_DBG("basic thr:%s not found", name[i]);
548         } else {
549             FTS_TEST_DBG("basic thr:%s=%d", name[i], val[i]);
550         }
551     }
552 
553     return 0;
554 }
555 
get_detail_threshold(char * key_name,bool is_prex,int * thr)556 static void get_detail_threshold(char *key_name, bool is_prex, int *thr)
557 {
558     char str[MAX_KEYWORD_VALUE_LEN] = { 0 };
559     char str_temp[MAX_KEYWORD_NAME_LEN] = { 0 };
560     char str_tmp[MAX_KEYWORD_VALUE_ONE_LEN] = { 0 };
561     struct fts_test *tdata = fts_ftest;
562     int divider_pos = 0;
563     int index = 0;
564     int i = 0;
565     int j = 0;
566     int k = 0;
567     int tx_num = 0;
568     int rx_num = 0;
569 
570     if (!key_name || !thr) {
571         FTS_TEST_ERROR("key_name/thr is null");
572         return;
573     }
574 
575     if (is_prex) {
576         tx_num = tdata->node.tx_num;
577         rx_num = tdata->node.rx_num;
578     }
579     for (i = 0; i < tx_num + 1; i++) {
580         if (is_prex) {
581             snprintf(str_temp, MAX_KEYWORD_NAME_LEN, "%s%d", key_name, (i + 1));
582         } else {
583             snprintf(str_temp, MAX_KEYWORD_NAME_LEN, "%s", key_name);
584         }
585         divider_pos = ini_get_string_value("SpecialSet", str_temp, str);
586         if (divider_pos <= 0)
587             continue;
588         index = 0;
589         k = 0;
590         memset(str_tmp, 0, sizeof(str_tmp));
591         for (j = 0; j < divider_pos; j++) {
592             if (',' == str[j]) {
593                 thr[i * rx_num + k] = (short)(fts_atoi(str_tmp));
594                 index = 0;
595                 memset(str_tmp, 0x00, sizeof(str_tmp));
596                 k++;
597             } else {
598                 if (' ' == str[j])
599                     continue;
600                 str_tmp[index] = str[j];
601                 index++;
602             }
603         }
604     }
605 }
606 
init_node_valid(void)607 static int init_node_valid(void)
608 {
609     char str[MAX_KEYWORD_NAME_LEN] = {0};
610     int i = 0;
611     int j = 0;
612     int chy = 0;
613     int node_num = 0;
614     int cnt = 0;
615     struct fts_test *tdata = fts_ftest;
616 
617     if (!tdata || !tdata->node_valid || !tdata->node_valid_sc) {
618         FTS_TEST_ERROR("tdata/node_valid/node_valid_sc is null");
619         return -EINVAL;
620     }
621 
622     chy = tdata->node.rx_num;
623     node_num = tdata->node.node_num;
624     fts_init_buffer(tdata->node_valid, 1 , node_num);
625     if ((tdata->func->hwtype == IC_HW_INCELL) || (tdata->func->hwtype == IC_HW_MC_SC)) {
626         for (cnt = 0; cnt < node_num; cnt++) {
627             i = cnt / chy + 1;
628             j = cnt % chy + 1;
629             snprintf(str, MAX_KEYWORD_NAME_LEN, "InvalidNode[%d][%d]", i, j);
630             get_keyword_value("INVALID_NODE", str, &tdata->node_valid[cnt]);
631         }
632     }
633 
634     if (tdata->func->hwtype == IC_HW_MC_SC) {
635         chy = tdata->sc_node.rx_num;
636         node_num = tdata->sc_node.node_num;
637         fts_init_buffer(tdata->node_valid_sc, 1, node_num);
638 
639         for (cnt = 0; cnt < node_num; cnt++) {
640             i = (cnt >= chy) ? 2 : 1;
641             j = (cnt >= chy) ? (cnt - chy + 1) : (cnt + 1);
642             snprintf(str, MAX_KEYWORD_NAME_LEN, "InvalidNodeS[%d][%d]", i, j);
643             get_keyword_value("INVALID_NODES", str, &tdata->node_valid_sc[cnt]);
644         }
645     }
646 
647     print_buffer(tdata->node_valid, tdata->node.node_num, tdata->node.rx_num);
648     print_buffer(tdata->node_valid_sc, tdata->sc_node.node_num, tdata->sc_node.rx_num);
649     return 0;
650 }
651 
652 /* incell */
get_test_item_incell(void)653 static int get_test_item_incell(void)
654 {
655     int ret = 0;
656     char item_name[][MAX_KEYWORD_NAME_LEN] = TEST_ITEM_INCELL;
657     int length = sizeof(item_name) / MAX_KEYWORD_NAME_LEN;
658     int item_val = 0;
659 
660     ret = get_test_item(item_name, length, &item_val);
661     if (ret < 0) {
662         FTS_TEST_SAVE_ERR("get test item fail\n");
663         return ret;
664     }
665 
666     fts_ftest->ic.incell.u.tmp = item_val;
667     return 0;
668 }
669 
670 static char bthr_name_incell[][MAX_KEYWORD_NAME_LEN] = BASIC_THRESHOLD_INCELL;
get_test_threshold_incell(void)671 static int get_test_threshold_incell(void)
672 {
673     int ret = 0;
674     int length = sizeof(bthr_name_incell) / MAX_KEYWORD_NAME_LEN;
675     struct fts_test *tdata = fts_ftest;
676     struct incell_threshold *thr = &tdata->ic.incell.thr;
677     int node_num = tdata->node.node_num;
678 
679     tdata->basic_thr_count = sizeof(struct incell_threshold_b) / sizeof(int);
680     /* get standard basic threshold */
681     ret = get_basic_threshold(bthr_name_incell, length, (int *)&thr->basic);
682     if (ret < 0) {
683         FTS_TEST_SAVE_ERR("get basic thr fail\n");
684         return ret;
685     }
686 
687     /* basic special set by ic */
688     if (tdata->func->param_init) {
689         ret = tdata->func->param_init();
690         if (ret < 0) {
691             FTS_TEST_SAVE_ERR("special basic thr init fail\n");
692             return ret;
693         }
694     }
695 
696     /* init buffer */
697     fts_init_buffer(thr->rawdata_max, thr->basic.rawdata_max, node_num);
698     fts_init_buffer(thr->rawdata_min, thr->basic.rawdata_min, node_num);
699     if (tdata->func->rawdata2_support) {
700         fts_init_buffer(thr->rawdata2_max, thr->basic.rawdata2_max, node_num);
701         fts_init_buffer(thr->rawdata2_min, thr->basic.rawdata2_min, node_num);
702     }
703     fts_init_buffer(thr->cb_max, thr->basic.cb_max, node_num);
704     fts_init_buffer(thr->cb_min, thr->basic.cb_min, node_num);
705 
706     /* detail threshold */
707     get_detail_threshold("RawData_Max_Tx", true, thr->rawdata_max);
708     get_detail_threshold("RawData_Min_Tx", true, thr->rawdata_min);
709     get_detail_threshold("CB_Max_Tx", true, thr->cb_max);
710     get_detail_threshold("CB_Min_Tx", true, thr->cb_min);
711 
712     return 0;
713 }
714 
print_thr_incell(void)715 static void print_thr_incell(void)
716 {
717     struct fts_test *tdata = fts_ftest;
718     struct incell_threshold *thr = &tdata->ic.incell.thr;
719 
720     FTS_TEST_DBG("short_res_min:%d", thr->basic.short_res_min);
721     FTS_TEST_DBG("short_res_vk_min:%d", thr->basic.short_res_vk_min);
722     FTS_TEST_DBG("open_cb_min:%d", thr->basic.open_cb_min);
723     FTS_TEST_DBG("open_k1_check:%d", thr->basic.open_k1_check);
724     FTS_TEST_DBG("open_k1_value:%d", thr->basic.open_k1_value);
725     FTS_TEST_DBG("open_k2_check:%d", thr->basic.open_k2_check);
726     FTS_TEST_DBG("open_k2_value:%d", thr->basic.open_k2_value);
727     FTS_TEST_DBG("cb_min:%d", thr->basic.cb_min);
728     FTS_TEST_DBG("cb_max:%d", thr->basic.cb_max);
729     FTS_TEST_DBG("cb_vkey_check:%d", thr->basic.cb_vkey_check);
730     FTS_TEST_DBG("cb_min_vk:%d", thr->basic.cb_min_vk);
731     FTS_TEST_DBG("cb_max_vk:%d", thr->basic.cb_max_vk);
732     FTS_TEST_DBG("rawdata_min:%d", thr->basic.rawdata_min);
733     FTS_TEST_DBG("rawdata_max:%d", thr->basic.rawdata_max);
734     FTS_TEST_DBG("rawdata_vkey_check:%d", thr->basic.rawdata_vkey_check);
735     FTS_TEST_DBG("rawdata_min_vk:%d", thr->basic.rawdata_min_vk);
736     FTS_TEST_DBG("rawdata_max_vk:%d", thr->basic.rawdata_max_vk);
737     FTS_TEST_DBG("lcdnoise_frame:%d", thr->basic.lcdnoise_frame);
738     FTS_TEST_DBG("lcdnoise_coefficient:%d", thr->basic.lcdnoise_coefficient);
739     FTS_TEST_DBG("lcdnoise_coefficient_vkey:%d", thr->basic.lcdnoise_coefficient_vkey);
740 
741     FTS_TEST_DBG("open_nmos:%d", thr->basic.open_nmos);
742     FTS_TEST_DBG("keyshort_k1:%d", thr->basic.keyshort_k1);
743     FTS_TEST_DBG("keyshort_cb_max:%d", thr->basic.keyshort_cb_max);
744     FTS_TEST_DBG("rawdata2_min:%d", thr->basic.rawdata2_min);
745     FTS_TEST_DBG("rawdata2_max:%d", thr->basic.rawdata2_max);
746 
747 
748     print_buffer(thr->rawdata_min, tdata->node.node_num, tdata->node.rx_num);
749     print_buffer(thr->rawdata_max, tdata->node.node_num, tdata->node.rx_num);
750     print_buffer(thr->cb_min, tdata->node.node_num, tdata->node.rx_num);
751     print_buffer(thr->cb_max, tdata->node.node_num, tdata->node.rx_num);
752     print_buffer(thr->rawdata2_min, tdata->node.node_num, tdata->node.rx_num);
753     print_buffer(thr->rawdata2_max, tdata->node.node_num, tdata->node.rx_num);
754 }
755 
ini_init_test_incell(void)756 static int ini_init_test_incell(void)
757 {
758     int ret = 0;
759 
760     ret = get_test_item_incell();
761     if (ret < 0) {
762         FTS_TEST_SAVE_ERR("get incell test item fail\n");
763         return ret;
764     }
765 
766 
767     ret = get_test_threshold_incell();
768     if (ret < 0) {
769         FTS_TEST_SAVE_ERR("get incell threshold fail\n");
770         return ret;
771     }
772 
773     print_thr_incell();
774     return 0;
775 }
776 
777 /* mc_sc */
get_test_item_mc_sc(void)778 static int get_test_item_mc_sc(void)
779 {
780     int ret = 0;
781     char item_name[][MAX_KEYWORD_NAME_LEN] = TEST_ITEM_MC_SC;
782     int length = sizeof(item_name) / MAX_KEYWORD_NAME_LEN;
783     int item_val = 0;
784 
785     ret = get_test_item(item_name, length, &item_val);
786     if (ret < 0) {
787         FTS_TEST_SAVE_ERR("get test item fail\n");
788         return ret;
789     }
790 
791     fts_ftest->ic.mc_sc.u.tmp = item_val;
792     FTS_TEST_INFO("test item:0x%x in ini", fts_ftest->ic.mc_sc.u.tmp);
793     return 0;
794 }
795 
796 static char bthr_name_mc_sc[][MAX_KEYWORD_NAME_LEN] = BASIC_THRESHOLD_MC_SC;
get_test_threshold_mc_sc(void)797 static int get_test_threshold_mc_sc(void)
798 {
799     int ret = 0;
800     int length = sizeof(bthr_name_mc_sc) / MAX_KEYWORD_NAME_LEN;
801     struct fts_test *tdata = fts_ftest;
802     struct mc_sc_threshold *thr = &tdata->ic.mc_sc.thr;
803     int node_num = tdata->node.node_num;
804     int sc_num = tdata->sc_node.node_num;
805 
806     tdata->basic_thr_count = sizeof(struct mc_sc_threshold_b) / sizeof(int);
807     /* get standard basic threshold */
808     ret = get_basic_threshold(bthr_name_mc_sc, length, (int *)&thr->basic);
809     if (ret < 0) {
810         FTS_TEST_SAVE_ERR("get basic thr fail\n");
811         return ret;
812     }
813 
814     /* basic special set by ic */
815     if (tdata->func->param_init) {
816         ret = tdata->func->param_init();
817         if (ret < 0) {
818             FTS_TEST_SAVE_ERR("special basic thr init fail\n");
819             return ret;
820         }
821     }
822 
823     /* init buffer */
824     fts_init_buffer(thr->rawdata_h_min, thr->basic.rawdata_h_min, node_num);
825     fts_init_buffer(thr->rawdata_h_max, thr->basic.rawdata_h_max, node_num);
826     if (tdata->func->rawdata2_support) {
827         fts_init_buffer(thr->rawdata_l_min, thr->basic.rawdata_l_min, node_num);
828         fts_init_buffer(thr->rawdata_l_max, thr->basic.rawdata_l_max, node_num);
829     }
830     fts_init_buffer(thr->tx_linearity_max, thr->basic.uniformity_tx_hole, node_num);
831     fts_init_buffer(thr->tx_linearity_min, 0, node_num);
832     fts_init_buffer(thr->rx_linearity_max, thr->basic.uniformity_rx_hole, node_num);
833     fts_init_buffer(thr->rx_linearity_min, 0, node_num);
834     fts_init_buffer(thr->scap_cb_off_min, thr->basic.scap_cb_off_min, sc_num);
835     fts_init_buffer(thr->scap_cb_off_max, thr->basic.scap_cb_off_max, sc_num);
836     fts_init_buffer(thr->scap_cb_on_min, thr->basic.scap_cb_on_min, sc_num);
837     fts_init_buffer(thr->scap_cb_on_max, thr->basic.scap_cb_on_max, sc_num);
838     fts_init_buffer(thr->scap_rawdata_off_min, thr->basic.scap_rawdata_off_min, sc_num);
839     fts_init_buffer(thr->scap_rawdata_off_max, thr->basic.scap_rawdata_off_max, sc_num);
840     fts_init_buffer(thr->scap_rawdata_on_min, thr->basic.scap_rawdata_on_min, sc_num);
841     fts_init_buffer(thr->scap_rawdata_on_max, thr->basic.scap_rawdata_on_max, sc_num);
842     fts_init_buffer(thr->panel_differ_min, thr->basic.panel_differ_min, node_num);
843     fts_init_buffer(thr->panel_differ_max, thr->basic.panel_differ_max, node_num);
844 
845     /* detail threshold */
846     get_detail_threshold("RawData_Min_High_Tx", true, thr->rawdata_h_min);
847     get_detail_threshold("RawData_Max_High_Tx", true, thr->rawdata_h_max);
848     if (tdata->func->rawdata2_support) {
849         get_detail_threshold("RawData_Min_Low_Tx", true, thr->rawdata_l_min);
850         get_detail_threshold("RawData_Max_Low_Tx", true, thr->rawdata_l_max);
851     }
852     get_detail_threshold("Tx_Linearity_Max_Tx", true, thr->tx_linearity_max);
853     get_detail_threshold("Rx_Linearity_Max_Tx", true, thr->rx_linearity_max);
854     get_detail_threshold("ScapCB_OFF_Min_", true, thr->scap_cb_off_min);
855     get_detail_threshold("ScapCB_OFF_Max_", true, thr->scap_cb_off_max);
856     get_detail_threshold("ScapCB_ON_Min_", true, thr->scap_cb_on_min);
857     get_detail_threshold("ScapCB_ON_Max_", true, thr->scap_cb_on_max);
858     get_detail_threshold("ScapRawData_OFF_Min_", true, thr->scap_rawdata_off_min);
859     get_detail_threshold("ScapRawData_OFF_Max_", true, thr->scap_rawdata_off_max);
860     get_detail_threshold("ScapRawData_ON_Min_", true, thr->scap_rawdata_on_min);
861     get_detail_threshold("ScapRawData_ON_Max_", true, thr->scap_rawdata_on_max);
862     get_detail_threshold("Panel_Differ_Min_Tx", true, thr->panel_differ_min);
863     get_detail_threshold("Panel_Differ_Max_Tx", true, thr->panel_differ_max);
864 
865     return 0;
866 }
867 
print_thr_mc_sc(void)868 static void print_thr_mc_sc(void)
869 {
870     struct fts_test *tdata = fts_ftest;
871     struct mc_sc_threshold *thr = &tdata->ic.mc_sc.thr;
872 
873     FTS_TEST_DBG("rawdata_h_min:%d", thr->basic.rawdata_h_min);
874     FTS_TEST_DBG("rawdata_h_max:%d", thr->basic.rawdata_h_max);
875     FTS_TEST_DBG("rawdata_set_hfreq:%d", thr->basic.rawdata_set_hfreq);
876     FTS_TEST_DBG("rawdata_l_min:%d", thr->basic.rawdata_l_min);
877     FTS_TEST_DBG("rawdata_l_max:%d", thr->basic.rawdata_l_max);
878     FTS_TEST_DBG("rawdata_set_lfreq:%d", thr->basic.rawdata_set_lfreq);
879     FTS_TEST_DBG("uniformity_check_tx:%d", thr->basic.uniformity_check_tx);
880     FTS_TEST_DBG("uniformity_check_rx:%d", thr->basic.uniformity_check_rx);
881     FTS_TEST_DBG("uniformity_check_min_max:%d", thr->basic.uniformity_check_min_max);
882     FTS_TEST_DBG("uniformity_tx_hole:%d", thr->basic.uniformity_tx_hole);
883     FTS_TEST_DBG("uniformity_rx_hole:%d", thr->basic.uniformity_rx_hole);
884     FTS_TEST_DBG("uniformity_min_max_hole:%d", thr->basic.uniformity_min_max_hole);
885     FTS_TEST_DBG("scap_cb_off_min:%d", thr->basic.scap_cb_off_min);
886     FTS_TEST_DBG("scap_cb_off_max:%d", thr->basic.scap_cb_off_max);
887     FTS_TEST_DBG("scap_cb_wp_off_check:%d", thr->basic.scap_cb_wp_off_check);
888     FTS_TEST_DBG("scap_cb_on_min:%d", thr->basic.scap_cb_on_min);
889     FTS_TEST_DBG("scap_cb_on_max:%d", thr->basic.scap_cb_on_max);
890     FTS_TEST_DBG("scap_cb_wp_on_check:%d", thr->basic.scap_cb_wp_on_check);
891     FTS_TEST_DBG("scap_rawdata_off_min:%d", thr->basic.scap_rawdata_off_min);
892     FTS_TEST_DBG("scap_rawdata_off_max:%d", thr->basic.scap_rawdata_off_max);
893     FTS_TEST_DBG("scap_rawdata_wp_off_check:%d", thr->basic.scap_rawdata_wp_off_check);
894     FTS_TEST_DBG("scap_rawdata_on_min:%d", thr->basic.scap_rawdata_on_min);
895     FTS_TEST_DBG("scap_rawdata_on_max:%d", thr->basic.scap_rawdata_on_max);
896     FTS_TEST_DBG("scap_rawdata_wp_on_check:%d", thr->basic.scap_rawdata_wp_on_check);
897     FTS_TEST_DBG("short_cg:%d", thr->basic.short_cg);
898     FTS_TEST_DBG("short_cc:%d", thr->basic.short_cc);
899     FTS_TEST_DBG("panel_differ_min:%d", thr->basic.panel_differ_min);
900     FTS_TEST_DBG("panel_differ_max:%d", thr->basic.panel_differ_max);
901 
902     print_buffer(thr->rawdata_h_min, tdata->node.node_num, tdata->node.rx_num);
903     print_buffer(thr->rawdata_h_max, tdata->node.node_num, tdata->node.rx_num);
904     print_buffer(thr->rawdata_l_min, tdata->node.node_num, tdata->node.rx_num);
905     print_buffer(thr->rawdata_l_max, tdata->node.node_num, tdata->node.rx_num);
906     print_buffer(thr->scap_cb_off_min, tdata->sc_node.node_num, tdata->sc_node.rx_num);
907     print_buffer(thr->scap_cb_off_max, tdata->sc_node.node_num, tdata->sc_node.rx_num);
908     print_buffer(thr->scap_cb_on_min, tdata->sc_node.node_num, tdata->sc_node.rx_num);
909     print_buffer(thr->scap_cb_on_max, tdata->sc_node.node_num, tdata->sc_node.rx_num);
910     print_buffer(thr->scap_rawdata_off_min, tdata->sc_node.node_num, tdata->sc_node.rx_num);
911     print_buffer(thr->scap_rawdata_off_max, tdata->sc_node.node_num, tdata->sc_node.rx_num);
912     print_buffer(thr->scap_rawdata_on_min, tdata->sc_node.node_num, tdata->sc_node.rx_num);
913     print_buffer(thr->scap_rawdata_on_max, tdata->sc_node.node_num, tdata->sc_node.rx_num);
914     print_buffer(thr->panel_differ_min, tdata->node.node_num, tdata->node.rx_num);
915     print_buffer(thr->panel_differ_max, tdata->node.node_num, tdata->node.rx_num);
916 }
917 
ini_init_test_mc_sc(void)918 static int ini_init_test_mc_sc(void)
919 {
920     int ret = 0;
921 
922     ret = get_test_item_mc_sc();
923     if (ret < 0) {
924         FTS_TEST_SAVE_ERR("get mc_sc test item fail\n");
925         return ret;
926     }
927 
928     ret = get_test_threshold_mc_sc();
929     if (ret < 0) {
930         FTS_TEST_SAVE_ERR("get mc_sc threshold fail\n");
931         return ret;
932     }
933 
934     print_thr_mc_sc();
935     return 0;
936 }
937 
938 /* sc */
get_test_item_sc(void)939 static int get_test_item_sc(void)
940 {
941     int ret = 0;
942     char item_name[][MAX_KEYWORD_NAME_LEN] = TEST_ITEM_SC;
943     int length = sizeof(item_name) / MAX_KEYWORD_NAME_LEN;
944     int item_val = 0;
945 
946     ret = get_test_item(item_name, length, &item_val);
947     if (ret < 0) {
948         FTS_TEST_SAVE_ERR("get test item fail\n");
949         return ret;
950     }
951 
952     fts_ftest->ic.sc.u.tmp = item_val;
953     return 0;
954 }
955 
956 static char bthr_name_sc[][MAX_KEYWORD_NAME_LEN] = BASIC_THRESHOLD_SC;
get_test_threshold_sc(void)957 static int get_test_threshold_sc(void)
958 {
959     int ret = 0;
960     int length = sizeof(bthr_name_sc) / MAX_KEYWORD_NAME_LEN;
961     struct fts_test *tdata = fts_ftest;
962     struct sc_threshold *thr = &tdata->ic.sc.thr;
963     int node_num = tdata->node.node_num;
964 
965     tdata->basic_thr_count = sizeof(struct sc_threshold_b) / sizeof(int);
966     /* get standard basic threshold */
967     ret = get_basic_threshold(bthr_name_sc, length, (int *)&thr->basic);
968     if (ret < 0) {
969         FTS_TEST_SAVE_ERR("get basic thr fail\n");
970         return ret;
971     }
972 
973     /* basic special set by ic */
974     if (tdata->func->param_init) {
975         ret = tdata->func->param_init();
976         if (ret < 0) {
977             FTS_TEST_SAVE_ERR("special basic thr init fail\n");
978             return ret;
979         }
980     }
981 
982     /* init buffer */
983     fts_init_buffer(thr->rawdata_min, thr->basic.rawdata_min, node_num);
984     fts_init_buffer(thr->rawdata_max, thr->basic.rawdata_max, node_num);
985     fts_init_buffer(thr->cb_min, thr->basic.cb_min, node_num);
986     fts_init_buffer(thr->cb_max, thr->basic.cb_max, node_num);
987     fts_init_buffer(thr->dcb_sort, 0, node_num);
988     fts_init_buffer(thr->dcb_base, thr->basic.dcb_base, node_num);
989 
990     /* detail threshold */
991     get_detail_threshold("RawDataTest_Min", false, thr->rawdata_min);
992     get_detail_threshold("RawDataTest_Max", false, thr->rawdata_max);
993     get_detail_threshold("CbTest_Min", false, thr->cb_min);
994     get_detail_threshold("CbTest_Max", false, thr->cb_max);
995     get_detail_threshold("DeltaCxTest_Sort", false, thr->dcb_sort);
996     get_detail_threshold("DeltaCbTest_Base", false, thr->dcb_base);
997 
998     return 0;
999 }
1000 
print_thr_sc(void)1001 static void print_thr_sc(void)
1002 {
1003     struct fts_test *tdata = fts_ftest;
1004     struct sc_threshold *thr = &tdata->ic.sc.thr;
1005 
1006     FTS_TEST_DBG("rawdata_min:%d", thr->basic.rawdata_min);
1007     FTS_TEST_DBG("rawdata_max:%d", thr->basic.rawdata_max);
1008     FTS_TEST_DBG("cb_min:%d", thr->basic.cb_min);
1009     FTS_TEST_DBG("cb_max:%d", thr->basic.cb_max);
1010     FTS_TEST_DBG("dcb_differ_max:%d", thr->basic.dcb_differ_max);
1011     FTS_TEST_DBG("dcb_key_check:%d", thr->basic.dcb_key_check);
1012     FTS_TEST_DBG("dcb_key_differ_max:%d", thr->basic.dcb_key_differ_max);
1013     FTS_TEST_DBG("dcb_ds1:%d", thr->basic.dcb_ds1);
1014     FTS_TEST_DBG("dcb_ds2:%d", thr->basic.dcb_ds2);
1015     FTS_TEST_DBG("dcb_ds3:%d", thr->basic.dcb_ds3);
1016     FTS_TEST_DBG("dcb_ds4:%d", thr->basic.dcb_ds4);
1017     FTS_TEST_DBG("dcb_ds5:%d", thr->basic.dcb_ds5);
1018     FTS_TEST_DBG("dcb_ds6:%d", thr->basic.dcb_ds6);
1019     FTS_TEST_DBG("dcb_critical_check:%d", thr->basic.dcb_critical_check);
1020     FTS_TEST_DBG("dcb_cs1:%d", thr->basic.dcb_cs1);
1021     FTS_TEST_DBG("dcb_cs2:%d", thr->basic.dcb_cs2);
1022     FTS_TEST_DBG("dcb_cs3:%d", thr->basic.dcb_cs3);
1023     FTS_TEST_DBG("dcb_cs4:%d", thr->basic.dcb_cs4);
1024     FTS_TEST_DBG("dcb_cs5:%d", thr->basic.dcb_cs5);
1025     FTS_TEST_DBG("dcb_cs6:%d", thr->basic.dcb_cs6);
1026 
1027     print_buffer(thr->rawdata_min, tdata->node.node_num, tdata->node.rx_num);
1028     print_buffer(thr->rawdata_max, tdata->node.node_num, tdata->node.rx_num);
1029     print_buffer(thr->cb_min, tdata->node.node_num, tdata->node.rx_num);
1030     print_buffer(thr->cb_max, tdata->node.node_num, tdata->node.rx_num);
1031     print_buffer(thr->dcb_sort, tdata->node.node_num, tdata->node.rx_num);
1032     print_buffer(thr->dcb_base, tdata->node.node_num, tdata->node.rx_num);
1033 }
1034 
ini_init_test_sc(void)1035 static int ini_init_test_sc(void)
1036 {
1037     int ret = 0;
1038 
1039     ret = get_test_item_sc();
1040     if (ret < 0) {
1041         FTS_TEST_SAVE_ERR("get sc test item fail\n");
1042         return ret;
1043     }
1044 
1045     ret = get_test_threshold_sc();
1046     if (ret < 0) {
1047         FTS_TEST_SAVE_ERR("get sc threshold fail\n");
1048         return ret;
1049     }
1050 
1051     print_thr_sc();
1052     return 0;
1053 }
1054 
ini_get_ic_code(char * ic_name)1055 static u32 ini_get_ic_code(char *ic_name)
1056 {
1057     int i = 0;
1058     int type_size = 0;
1059     int ini_icname_len = 0;
1060     int ic_types_len = 0;
1061 
1062     ini_icname_len = strlen(ic_name);
1063     type_size = sizeof(ic_types) / sizeof(ic_types[0]);
1064     for (i = 0; i < type_size; i++) {
1065         ic_types_len = strlen(ic_name);
1066         if (ini_icname_len == ic_types_len) {
1067             if (0 == strncmp(ic_name, ic_types[i].ic_name, ic_types_len))
1068                 return ic_types[i].ic_type;
1069         }
1070     }
1071 
1072     FTS_TEST_ERROR("no IC type match");
1073     return 0;
1074 }
1075 
1076 
ini_init_interface(struct ini_data * ini)1077 static void ini_init_interface(struct ini_data *ini)
1078 {
1079     char str[MAX_KEYWORD_VALUE_LEN] = { 0 };
1080     u32 value = 0;
1081     struct fts_test *tdata = fts_ftest;
1082 
1083     /* IC type */
1084     ini_get_string_value("Interface", "IC_Type", str);
1085     memcpy(ini->ic_name, str, sizeof(str));
1086 
1087     value = ini_get_ic_code(str);
1088     ini->ic_code = value;
1089     FTS_TEST_INFO("ic name:%s, ic code:%x", ini->ic_name, ini->ic_code);
1090 
1091     if (IC_HW_MC_SC == tdata->func->hwtype) {
1092         get_value_interface("Normalize_Type", &value);
1093         tdata->normalize = (u8)value;
1094         FTS_TEST_DBG("normalize:%d", tdata->normalize);
1095     }
1096 }
1097 
ini_init_test(struct ini_data * ini)1098 static int ini_init_test(struct ini_data *ini)
1099 {
1100     int ret = 0;
1101     struct fts_test *tdata = fts_ftest;
1102 
1103     /* interface init */
1104     ini_init_interface(ini);
1105 
1106     /* node valid */
1107     ret = init_node_valid();
1108     if (ret < 0) {
1109         FTS_TEST_ERROR("init node valid fail");
1110         return ret;
1111     }
1112 
1113     switch (tdata->func->hwtype) {
1114     case IC_HW_INCELL:
1115         ret = ini_init_test_incell();
1116         break;
1117     case IC_HW_MC_SC:
1118         ret = ini_init_test_mc_sc();
1119         break;
1120     case IC_HW_SC:
1121         ret = ini_init_test_sc();
1122         break;
1123     default:
1124         FTS_TEST_SAVE_ERR("test ic type(%d) fail\n", tdata->func->hwtype);
1125         ret = -EINVAL;
1126         break;
1127     }
1128 
1129     return ret;
1130 }
1131 
1132 /*
1133  * fts_test_get_testparam_from_ini - get test parameters from ini
1134  *
1135  * read, parse the configuration file, initialize the test variable
1136  *
1137  * return 0 if succuss, else errro code
1138  */
fts_test_get_testparam_from_ini(char * config_name)1139 int fts_test_get_testparam_from_ini(char *config_name)
1140 {
1141     int ret = 0;
1142     int inisize = 0;
1143     struct ini_data *ini = &fts_ftest->ini;
1144 
1145     inisize = fts_test_get_ini_size(config_name);
1146     FTS_TEST_DBG("ini file size:%d", inisize);
1147     if (inisize <= 0) {
1148         FTS_TEST_ERROR("get ini file size fail");
1149         return -ENODATA;
1150     }
1151 
1152     ini->data = vmalloc(inisize + 1);
1153     if (NULL == ini->data) {
1154         FTS_TEST_ERROR("malloc memory for ini data fail");
1155         return -ENOMEM;
1156     }
1157     memset(ini->data, 0, inisize + 1);
1158     ini->length = inisize + 1;
1159     ini->keyword_num_total = 0;
1160     ini->section_num = 0;
1161 
1162     ini->tmp = vmalloc(sizeof(struct ini_keyword) * MAX_KEYWORD_NUM);
1163     if (NULL == ini->tmp) {
1164         FTS_TEST_ERROR("malloc memory for ini tmp fail");
1165         ret = -ENOMEM;
1166         goto ini_tmp_err;
1167     }
1168     memset(ini->tmp, 0, sizeof(struct ini_keyword) * MAX_KEYWORD_NUM);
1169 
1170     ret = fts_test_read_ini_data(config_name, ini->data);
1171     if (ret) {
1172         FTS_TEST_ERROR("read ini file fail");
1173         goto get_inidata_err;
1174     }
1175     ini->data[inisize] = '\n';  /* last line is null line */
1176 
1177     /* parse ini data to get keyword name&value */
1178     ret = ini_init_inidata(ini);
1179     if (ret < 0) {
1180         FTS_TEST_ERROR("ini_init_inidata fail");
1181         goto get_inidata_err;
1182     }
1183 
1184     /* parse threshold & test item */
1185     ret = ini_init_test(ini);
1186     if (ret < 0) {
1187         FTS_TEST_ERROR("ini init fail");
1188         goto get_inidata_err;
1189     }
1190 
1191     ret = 0;
1192 get_inidata_err:
1193     if (ini->tmp) {
1194         vfree(ini->tmp);
1195         ini->tmp = NULL;
1196     }
1197 ini_tmp_err:
1198     if (ini->data) {
1199         vfree(ini->data);
1200         ini->data = NULL;
1201     }
1202 
1203     return ret;
1204 }
1205