c05564c4d8
Android 13
3932 lines
119 KiB
C
Executable file
3932 lines
119 KiB
C
Executable file
/*
|
|
* ILITEK Touch IC driver
|
|
*
|
|
* Copyright (C) 2011 ILI Technology Corporation.
|
|
*
|
|
* Author: Dicky Chiang <dicky_chiang@ilitek.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "ili9881x.h"
|
|
|
|
#define VALUE 0
|
|
#define RETRY_COUNT 3
|
|
#define INT_CHECK 0
|
|
#define POLL_CHECK 1
|
|
|
|
#define BENCHMARK 1
|
|
#define NODETYPE 1
|
|
|
|
#define TYPE_BENCHMARK 0
|
|
#define TYPE_NO_JUGE 1
|
|
#define TYPE_JUGE 2
|
|
|
|
#define NORMAL_CSV_PASS_NAME "mp_pass"
|
|
#define NORMAL_CSV_FAIL_NAME "mp_fail"
|
|
#define NORMAL_CSV_WARNING_NAME "mp_warning"
|
|
|
|
#define CSV_FILE_SIZE (1 * M)
|
|
|
|
#define PARSER_MAX_CFG_BUF (512 * 3)
|
|
#define PARSER_MAX_KEY_NUM (600 * 3)
|
|
#define PARSER_MAX_KEY_NAME_LEN 100
|
|
#define PARSER_MAX_KEY_VALUE_LEN 2000
|
|
#define MAX_SECTION_NUM 100
|
|
#define BENCHMARK_KEY_NAME "benchmark_data"
|
|
#define NODE_TYPE_KEY_NAME "node type"
|
|
#define INI_ERR_OUT_OF_LINE -1
|
|
|
|
#define CMD_MUTUAL_DAC 0x1
|
|
#define CMD_MUTUAL_BG 0x2
|
|
#define CMD_MUTUAL_SIGNAL 0x3
|
|
#define CMD_MUTUAL_NO_BK 0x5
|
|
#define CMD_MUTUAL_HAVE_BK 0x8
|
|
#define CMD_MUTUAL_BK_DAC 0x10
|
|
#define CMD_SELF_DAC 0xC
|
|
#define CMD_SELF_BG 0xF
|
|
#define CMD_SELF_SIGNAL 0xD
|
|
#define CMD_SELF_NO_BK 0xE
|
|
#define CMD_SELF_HAVE_BK 0xB
|
|
#define CMD_SELF_BK_DAC 0x11
|
|
#define CMD_KEY_DAC 0x14
|
|
#define CMD_KEY_BG 0x16
|
|
#define CMD_KEY_NO_BK 0x7
|
|
#define CMD_KEY_HAVE_BK 0x15
|
|
#define CMD_KEY_OPEN 0x12
|
|
#define CMD_KEY_SHORT 0x13
|
|
#define CMD_ST_DAC 0x1A
|
|
#define CMD_ST_BG 0x1C
|
|
#define CMD_ST_NO_BK 0x17
|
|
#define CMD_ST_HAVE_BK 0x1B
|
|
#define CMD_ST_OPEN 0x18
|
|
#define CMD_TX_SHORT 0x19
|
|
#define CMD_RX_SHORT 0x4
|
|
#define CMD_RX_OPEN 0x6
|
|
#define CMD_TX_RX_DELTA 0x1E
|
|
#define CMD_CM_DATA 0x9
|
|
#define CMD_CS_DATA 0xA
|
|
#define CMD_TRCRQ_PIN 0x20
|
|
#define CMD_RESX2_PIN 0x21
|
|
#define CMD_MUTUAL_INTEGRA_TIME 0x22
|
|
#define CMD_SELF_INTEGRA_TIME 0x23
|
|
#define CMD_KEY_INTERGRA_TIME 0x24
|
|
#define CMD_ST_INTERGRA_TIME 0x25
|
|
#define CMD_PEAK_TO_PEAK 0x1D
|
|
#define CMD_GET_TIMING_INFO 0x30
|
|
#define CMD_DOZE_P2P 0x32
|
|
#define CMD_DOZE_RAW 0x33
|
|
#define CMD_PIN_TEST 0x61
|
|
|
|
#define MP_DATA_PASS 0
|
|
#define MP_DATA_FAIL -1
|
|
|
|
#define Mathabs(x) ({ \
|
|
long ret; \
|
|
if (sizeof(x) == sizeof(long)) { \
|
|
long __x = (x); \
|
|
ret = (__x < 0) ? -__x : __x; \
|
|
} else { \
|
|
int __x = (x); \
|
|
ret = (__x < 0) ? -__x : __x; \
|
|
} \
|
|
ret; \
|
|
})
|
|
|
|
#define DUMP(fmt, arg...) \
|
|
do { \
|
|
if (debug_en) \
|
|
pr_cont(fmt, ##arg); \
|
|
} while (0)
|
|
|
|
static struct ini_file_data {
|
|
char section_name[PARSER_MAX_KEY_NAME_LEN];
|
|
char key_name[PARSER_MAX_KEY_NAME_LEN];
|
|
char key_value[PARSER_MAX_KEY_VALUE_LEN];
|
|
int section_len;
|
|
int key_name_len;
|
|
int key_val_len;
|
|
} *ini_info;
|
|
|
|
enum open_test_node_type {
|
|
NO_COMPARE = 0x00, /* Not A Area, No Compare */
|
|
AA_Area = 0x01, /* AA Area, Compare using Charge_AA */
|
|
Border_Area = 0x02, /* Border Area, Compare using Charge_Border */
|
|
Notch = 0x04, /* Notch Area, Compare using Charge_Notch */
|
|
Round_Corner = 0x08, /* Round Corner, No Compare */
|
|
Skip_Micro = 0x10 /* Skip_Micro, No Compare */
|
|
};
|
|
|
|
enum mp_test_catalog {
|
|
MUTUAL_TEST = 0,
|
|
SELF_TEST = 1,
|
|
KEY_TEST = 2,
|
|
ST_TEST = 3,
|
|
TX_RX_DELTA = 4,
|
|
UNTOUCH_P2P = 5,
|
|
PIXEL = 6,
|
|
OPEN_TEST = 7,
|
|
PEAK_TO_PEAK_TEST = 8,
|
|
SHORT_TEST = 9,
|
|
PIN_TEST = 10,
|
|
};
|
|
|
|
struct mp_test_P540_open {
|
|
s32 *tdf_700;
|
|
s32 *tdf_250;
|
|
s32 *tdf_200;
|
|
s32 *cbk_700;
|
|
s32 *cbk_250;
|
|
s32 *cbk_200;
|
|
s32 *charg_rate;
|
|
s32 *full_Open;
|
|
s32 *dac;
|
|
};
|
|
|
|
struct mp_test_open_c {
|
|
s32 *cap_dac;
|
|
s32 *cap_raw;
|
|
s32 *dcl_cap;
|
|
};
|
|
|
|
struct open_test_para {
|
|
int tvch;
|
|
int tvcl;
|
|
int gain;
|
|
int cbk_step;
|
|
int cint;
|
|
} open_para;
|
|
|
|
struct shor_test_para {
|
|
int tvch;
|
|
int tvcl;
|
|
int variation;
|
|
int rinternal;
|
|
int cint;
|
|
} short_para;
|
|
|
|
static struct core_mp_test_data {
|
|
u32 chip_pid;
|
|
u16 chip_id;
|
|
u8 chip_type;
|
|
u8 chip_ver;
|
|
u32 fw_ver;
|
|
u32 protocol_ver;
|
|
u32 core_ver;
|
|
char ini_date[128];
|
|
char ini_ver[64];
|
|
int no_bk_shift;
|
|
bool retry;
|
|
bool m_signal;
|
|
bool m_dac;
|
|
bool s_signal;
|
|
bool s_dac;
|
|
bool key_dac;
|
|
bool st_dac;
|
|
bool p_no_bk;
|
|
bool p_has_bk;
|
|
bool open_integ;
|
|
bool open_cap;
|
|
bool isLongV;
|
|
bool td_retry;
|
|
bool all_pass;
|
|
|
|
int cdc_len;
|
|
int xch_len;
|
|
int ych_len;
|
|
int stx_len;
|
|
int srx_len;
|
|
int key_len;
|
|
int st_len;
|
|
int frame_len;
|
|
int mp_items;
|
|
int final_result;
|
|
int short_varia;
|
|
|
|
u32 overlay_start_addr;
|
|
u32 overlay_end_addr;
|
|
u32 mp_flash_addr;
|
|
u32 mp_size;
|
|
u8 dma_trigger_enable;
|
|
|
|
/* Tx/Rx threshold & buffer */
|
|
int TxDeltaMax;
|
|
int TxDeltaMin;
|
|
int RxDeltaMax;
|
|
int RxDeltaMin;
|
|
s32 *tx_delta_buf;
|
|
s32 *rx_delta_buf;
|
|
s32 *tx_max_buf;
|
|
s32 *tx_min_buf;
|
|
s32 *rx_max_buf;
|
|
s32 *rx_min_buf;
|
|
|
|
int tdf;
|
|
int busy_cdc;
|
|
bool ctrl_lcm;
|
|
bool lost_benchmark;
|
|
bool lost_parameter;
|
|
} core_mp = {0};
|
|
|
|
struct mp_test_items {
|
|
/* The description must be the same as ini's section name */
|
|
char *desp;
|
|
char *result;
|
|
int catalog;
|
|
u8 cmd;
|
|
u8 spec_option;
|
|
u8 type_option;
|
|
bool run;
|
|
bool lcm;
|
|
int bch_mrk_multi;
|
|
int max;
|
|
int max_res;
|
|
int item_result;
|
|
int min;
|
|
int min_res;
|
|
int frame_count;
|
|
int trimmed_mean;
|
|
int lowest_percentage;
|
|
int highest_percentage;
|
|
int v_tdf_1;
|
|
int v_tdf_2;
|
|
int h_tdf_1;
|
|
int h_tdf_2;
|
|
int goldenmode;
|
|
int max_min_mode;
|
|
int bch_mrk_frm_num;
|
|
int retry_cnt;
|
|
u8 delay_time;
|
|
u8 test_int_pin;
|
|
u8 int_pulse_test;
|
|
s32 *result_buf;
|
|
s32 *buf;
|
|
s32 *max_buf;
|
|
s32 *min_buf;
|
|
s32 *bench_mark_max;
|
|
s32 *bench_mark_min;
|
|
s32 **bch_mrk_max;
|
|
s32 **bch_mrk_min;
|
|
s32 *node_type;
|
|
int (*do_test)(int index);
|
|
};
|
|
|
|
#define MP_TEST_ITEM 50
|
|
static struct mp_test_items tItems[MP_TEST_ITEM] = {
|
|
{.desp = "baseline data(bg)", .catalog = MUTUAL_TEST, .cmd = CMD_MUTUAL_BG, .lcm = ON},
|
|
{.desp = "untouch signal data(bg-raw-4096) - mutual",
|
|
.catalog = MUTUAL_TEST, .cmd = CMD_MUTUAL_SIGNAL, .lcm = ON},
|
|
{.desp = "manual bk data(mutual)", .catalog = MUTUAL_TEST, .cmd = CMD_MUTUAL_BK_DAC, .lcm = ON},
|
|
{.desp = "calibration data(dac) - self", .catalog = SELF_TEST, .cmd = CMD_SELF_DAC, .lcm = ON},
|
|
{.desp = "baselin data(bg,self_tx,self_r)", .catalog = SELF_TEST, .cmd = CMD_SELF_BG, .lcm = ON},
|
|
{.desp = "untouch signal data(bg-raw-4096) - self", .catalog = SELF_TEST, .cmd = CMD_SELF_SIGNAL, .lcm = ON},
|
|
{.desp = "raw data(no bk) - self", .catalog = SELF_TEST, .cmd = CMD_SELF_NO_BK, .lcm = ON},
|
|
{.desp = "raw data(have bk) - self", .catalog = SELF_TEST, .cmd = CMD_SELF_HAVE_BK, .lcm = ON},
|
|
{.desp = "manual bk dac data(self_tx,self_rx)", .catalog = SELF_TEST, .cmd = CMD_SELF_BK_DAC, .lcm = ON},
|
|
{.desp = "calibration data(dac/icon)", .catalog = KEY_TEST, .cmd = CMD_KEY_DAC, .lcm = ON},
|
|
{.desp = "key baseline data", .catalog = KEY_TEST, .cmd = CMD_KEY_BG, .lcm = ON},
|
|
{.desp = "key raw data", .catalog = KEY_TEST, .cmd = CMD_KEY_NO_BK, .lcm = ON},
|
|
{.desp = "key raw bk dac", .catalog = KEY_TEST, .cmd = CMD_KEY_HAVE_BK, .lcm = ON},
|
|
{.desp = "key raw open test", .catalog = KEY_TEST, .cmd = CMD_KEY_OPEN, .lcm = ON},
|
|
{.desp = "key raw short test", .catalog = KEY_TEST, .cmd = CMD_KEY_SHORT, .lcm = ON},
|
|
{.desp = "st calibration data(dac)", .catalog = ST_TEST, .cmd = CMD_ST_DAC, .lcm = ON},
|
|
{.desp = "st baseline data(bg)", .catalog = ST_TEST, .cmd = CMD_ST_BG, .lcm = ON},
|
|
{.desp = "st raw data(no bk)", .catalog = ST_TEST, .cmd = CMD_ST_NO_BK, .lcm = ON},
|
|
{.desp = "st raw(have bk)", .catalog = ST_TEST, .cmd = CMD_ST_HAVE_BK, .lcm = ON},
|
|
{.desp = "st open data", .catalog = ST_TEST, .cmd = CMD_ST_OPEN, .lcm = ON},
|
|
{.desp = "tx short test", .catalog = MUTUAL_TEST, .cmd = CMD_TX_SHORT, .lcm = ON},
|
|
{.desp = "rx open", .catalog = MUTUAL_TEST, .cmd = CMD_RX_OPEN, .lcm = ON},
|
|
{.desp = "untouch cm data", .catalog = MUTUAL_TEST, .cmd = CMD_CM_DATA, .lcm = ON},
|
|
{.desp = "untouch cs data", .catalog = MUTUAL_TEST, .cmd = CMD_CS_DATA, .lcm = ON},
|
|
{.desp = "tx/rx delta", .catalog = TX_RX_DELTA, .cmd = CMD_TX_RX_DELTA, .lcm = ON},
|
|
{.desp = "untouch peak to peak", .catalog = UNTOUCH_P2P, .cmd = CMD_MUTUAL_SIGNAL, .lcm = ON},
|
|
{.desp = "pixel raw (no bk)", .catalog = PIXEL, .cmd = CMD_MUTUAL_NO_BK, .lcm = ON},
|
|
{.desp = "pixel raw (have bk)", .catalog = PIXEL, .cmd = CMD_MUTUAL_HAVE_BK, .lcm = ON},
|
|
{.desp = "noise peak to peak(cut panel)", .catalog = PEAK_TO_PEAK_TEST, .lcm = ON},
|
|
{.desp = "open test(integration)", .catalog = OPEN_TEST, .cmd = CMD_RX_SHORT, .lcm = ON},
|
|
{.desp = "open test(cap)", .catalog = OPEN_TEST, .cmd = CMD_RX_SHORT, .lcm = ON},
|
|
/* Following is the new test items for protocol 5.4.0 above */
|
|
{.desp = "pin test ( int and rst )", .catalog = PIN_TEST, .cmd = CMD_PIN_TEST, .lcm = ON},
|
|
{.desp = "noise peak to peak(with panel)", .catalog = PEAK_TO_PEAK_TEST, .lcm = ON},
|
|
{.desp = "noise peak to peak(ic only)", .catalog = PEAK_TO_PEAK_TEST, .cmd = CMD_PEAK_TO_PEAK, .lcm = ON},
|
|
{.desp = "open test(integration)_sp", .catalog = OPEN_TEST, .lcm = ON},
|
|
{.desp = "raw data(no bk)", .catalog = MUTUAL_TEST, .cmd = CMD_MUTUAL_NO_BK, .lcm = ON},
|
|
{.desp = "raw data(have bk)", .catalog = MUTUAL_TEST, .cmd = CMD_MUTUAL_HAVE_BK, .lcm = ON},
|
|
{.desp = "calibration data(dac)", .catalog = MUTUAL_TEST, .cmd = CMD_MUTUAL_DAC, .lcm = ON},
|
|
{.desp = "short test -ili9881", .catalog = SHORT_TEST, .cmd = CMD_RX_SHORT, .lcm = ON},
|
|
{.desp = "short test", .catalog = SHORT_TEST, .lcm = ON},
|
|
{.desp = "doze raw data", .catalog = MUTUAL_TEST, .lcm = ON},
|
|
{.desp = "doze peak to peak", .catalog = PEAK_TO_PEAK_TEST, .lcm = ON},
|
|
{.desp = "open test_c", .catalog = OPEN_TEST, .lcm = ON},
|
|
{.desp = "touch deltac", .catalog = MUTUAL_TEST, .lcm = ON},
|
|
/* LCM OFF TEST */
|
|
{.desp = "raw data(have bk) (lcm off)", .catalog = MUTUAL_TEST, .lcm = OFF},
|
|
{.desp = "raw data(no bk) (lcm off)", .catalog = MUTUAL_TEST, .lcm = OFF},
|
|
{.desp = "noise peak to peak(with panel) (lcm off)", .catalog = PEAK_TO_PEAK_TEST, .lcm = OFF},
|
|
{.desp = "noise peak to peak(ic only) (lcm off)", .catalog = PEAK_TO_PEAK_TEST, .lcm = OFF},
|
|
{.desp = "raw data_td (lcm off)", .catalog = MUTUAL_TEST, .lcm = OFF},
|
|
{.desp = "peak to peak_td (lcm off)", .catalog = PEAK_TO_PEAK_TEST, .lcm = OFF},
|
|
};
|
|
|
|
static struct run_index {
|
|
int count;
|
|
int index[MP_TEST_ITEM];
|
|
} ri;
|
|
|
|
static s32 *frame_buf;
|
|
static s32 **frm_buf;
|
|
static s32 *key_buf;
|
|
static s32 *frame1_cbk700, *frame1_cbk250, *frame1_cbk200;
|
|
static s32 *cap_dac, *cap_raw;
|
|
static int g_ini_items = 0;
|
|
static char csv_name[128] = {0};
|
|
static char seq_item[MAX_SECTION_NUM][PARSER_MAX_KEY_NAME_LEN] = {{0} };
|
|
|
|
static int isspace_t(int x)
|
|
{
|
|
if (x == ' ' || x == '\t' || x == '\n' ||
|
|
x == '\f' || x == '\b' || x == '\r')
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
static void dump_benchmark_data(s32 *max_ptr, s32 *min_ptr)
|
|
{
|
|
ili_dump_data(max_ptr, 32, core_mp.frame_len, 0, "Dump Benchmark Max : ");
|
|
ili_dump_data(min_ptr, 32, core_mp.frame_len, 0, "Dump Benchmark Min : ");
|
|
}
|
|
|
|
static void dump_node_type_buffer(s32 *node_ptr, u8 *name)
|
|
{
|
|
ili_dump_data(node_ptr, 32, core_mp.frame_len, 0, "Dump NodeType : ");
|
|
}
|
|
|
|
static int parser_get_ini_key_value(char *section, char *key, char *value)
|
|
{
|
|
int i = 0;
|
|
int ret = -2;
|
|
|
|
for (i = 0; i < g_ini_items; i++) {
|
|
if (ipio_strcmp(section, ini_info[i].section_name) != 0)
|
|
continue;
|
|
|
|
if (ipio_strcmp(key, ini_info[i].key_name) == 0) {
|
|
ipio_memcpy(value, ini_info[i].key_value, ini_info[i].key_val_len, PARSER_MAX_KEY_VALUE_LEN);
|
|
ILI_DBG("%s (key: %s, value:%s) => (ini key: %s, val: %s)\n",
|
|
__func__, key, value, ini_info[i].key_name, ini_info[i].key_value);
|
|
ret = 0;
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void parser_ini_nodetype(s32 *type_ptr, char *desp, int frame_len)
|
|
{
|
|
int i = 0, j = 0, index1 = 0, temp, count = 0;
|
|
char str[512] = {0}, record = ',';
|
|
|
|
for (i = 0; i < g_ini_items; i++) {
|
|
if (!strstr(ini_info[i].section_name, desp) ||
|
|
ipio_strcmp(ini_info[i].key_name, NODE_TYPE_KEY_NAME) != 0) {
|
|
continue;
|
|
}
|
|
|
|
record = ',';
|
|
for (j = 0, index1 = 0; j <= ini_info[i].key_val_len; j++) {
|
|
if (ini_info[i].key_value[j] == ';' || j == ini_info[i].key_val_len) {
|
|
if (record != '.') {
|
|
memset(str, 0, sizeof(str));
|
|
ipio_memcpy(str, &ini_info[i].key_value[index1], (j - index1), sizeof(str));
|
|
temp = ili_katoi(str);
|
|
|
|
/* Over boundary, end to calculate. */
|
|
if (count >= frame_len) {
|
|
input_err(true, ilits->dev,
|
|
"%s count(%d) is larger than frame length, break\n",
|
|
__func__, count);
|
|
break;
|
|
}
|
|
type_ptr[count] = temp;
|
|
count++;
|
|
}
|
|
record = ini_info[i].key_value[j];
|
|
index1 = j + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void parser_ini_benchmark(s32 *max_ptr, s32 *min_ptr, int8_t type, char *desp, int frame_len, char *bchmrk_name)
|
|
{
|
|
int i = 0, j = 0, index1 = 0, temp, count = 0;
|
|
char str[512] = {0}, record = ',';
|
|
s32 data[4];
|
|
char benchmark_str[256] = {0};
|
|
|
|
/* format complete string from the name of section "_Benchmark_Data". */
|
|
snprintf(benchmark_str, sizeof(benchmark_str), "%s%s%s", desp, "_", bchmrk_name);
|
|
ILI_DBG("%s benchmark_str = %s\n", __func__, benchmark_str);
|
|
|
|
for (i = 0; i < g_ini_items; i++) {
|
|
if ((ipio_strcmp(ini_info[i].section_name, benchmark_str) != 0))
|
|
continue;
|
|
record = ',';
|
|
for (j = 0, index1 = 0; j <= ini_info[i].key_val_len; j++) {
|
|
if (ini_info[i].key_value[j] == ',' || ini_info[i].key_value[j] == ';' ||
|
|
ini_info[i].key_value[j] == '.' || j == ini_info[i].key_val_len) {
|
|
|
|
if (record != '.') {
|
|
memset(str, 0, sizeof(str));
|
|
ipio_memcpy(str, &ini_info[i].key_value[index1], (j - index1), sizeof(str));
|
|
temp = ili_katoi(str);
|
|
data[(count % 4)] = temp;
|
|
|
|
/* Over boundary, end to calculate. */
|
|
if ((count / 4) >= frame_len) {
|
|
input_err(true, ilits->dev,
|
|
"%s count (%d) is larger than frame length, break\n",
|
|
__func__, (count / 4));
|
|
break;
|
|
}
|
|
|
|
if ((count % 4) == 3) {
|
|
if (data[0] == 1) {
|
|
if (type == VALUE) {
|
|
max_ptr[count/4] = data[1] + data[2];
|
|
min_ptr[count/4] = data[1] - data[3];
|
|
} else {
|
|
max_ptr[count/4] = data[1] + (data[1] * data[2]) / 100;
|
|
min_ptr[count/4] = data[1] - (data[1] * data[3]) / 100;
|
|
}
|
|
} else {
|
|
max_ptr[count/4] = INT_MAX;
|
|
min_ptr[count/4] = INT_MIN;
|
|
}
|
|
}
|
|
count++;
|
|
}
|
|
record = ini_info[i].key_value[j];
|
|
index1 = j + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static int parser_get_tdf_value(char *str, int catalog)
|
|
{
|
|
u32 i, ans, index = 0, flag = 0, count = 0, size = 0;
|
|
char s[10] = {0};
|
|
|
|
if (!str) {
|
|
input_err(true, ilits->dev, "%s String is null\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
size = strlen(str);
|
|
for (i = 0, count = 0; i < size; i++) {
|
|
if (str[i] == '.') {
|
|
flag = 1;
|
|
continue;
|
|
}
|
|
s[index++] = str[i];
|
|
if (flag)
|
|
count++;
|
|
}
|
|
ans = ili_katoi(s);
|
|
|
|
/* Multiply by 100 to shift out of decimal point */
|
|
if (catalog == SHORT_TEST) {
|
|
if (count == 0)
|
|
ans = ans * 100;
|
|
else if (count == 1)
|
|
ans = ans * 10;
|
|
}
|
|
|
|
return ans;
|
|
}
|
|
|
|
static int parser_get_u8_array(char *key, u8 *buf, u16 base, int len)
|
|
{
|
|
char *s = key;
|
|
char *pToken;
|
|
int ret, conut = 0;
|
|
long s_to_long = 0;
|
|
|
|
if (strlen(s) == 0 || len <= 0) {
|
|
input_err(true, ilits->dev, "%s Can't find any characters inside buffer\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* @base: The number base to use. The maximum supported base is 16. If base is
|
|
* given as 0, then the base of the string is automatically detected with the
|
|
* conventional semantics - If it begins with 0x the number will be parsed as a
|
|
* hexadecimal (case insensitive), if it otherwise begins with 0, it will be
|
|
* parsed as an octal number. Otherwise it will be parsed as a decimal.
|
|
*/
|
|
if (isspace_t((int)(unsigned char)*s) == 0) {
|
|
while ((pToken = strsep(&s, ",")) != NULL) {
|
|
ret = kstrtol(pToken, base, &s_to_long);
|
|
if (ret == 0)
|
|
buf[conut] = s_to_long;
|
|
else
|
|
input_info(true, ilits->dev, "%s convert string too long, ret = %d\n", __func__, ret);
|
|
conut++;
|
|
|
|
if (conut >= len)
|
|
break;
|
|
}
|
|
}
|
|
|
|
return conut;
|
|
}
|
|
|
|
static int parser_get_int_data(char *section, char *keyname, char *rv, int rv_len)
|
|
{
|
|
int len = 0;
|
|
char value[512] = { 0 };
|
|
|
|
if (rv == NULL || section == NULL || keyname == NULL) {
|
|
input_err(true, ilits->dev, "%s Parameters are invalid\n", __func__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* return a white-space string if get nothing */
|
|
if (parser_get_ini_key_value(section, keyname, value) < 0) {
|
|
snprintf(rv, rv_len, "%s", value);
|
|
return 0;
|
|
}
|
|
|
|
len = snprintf(rv, rv_len, "%s", value);
|
|
return len;
|
|
}
|
|
|
|
/* Count the number of each line and assign the content to tmp buffer */
|
|
static int parser_get_ini_phy_line(char *data, char *buffer, int maxlen)
|
|
{
|
|
int i = 0;
|
|
int j = 0;
|
|
int iRetNum = -1;
|
|
char ch1 = '\0';
|
|
|
|
for (i = 0, j = 0; i < maxlen; j++) {
|
|
ch1 = data[j];
|
|
iRetNum = j + 1;
|
|
if (ch1 == '\n' || ch1 == '\r') { /* line end */
|
|
ch1 = data[j + 1];
|
|
if (ch1 == '\n' || ch1 == '\r')
|
|
iRetNum++;
|
|
break;
|
|
} else if (ch1 == 0x00) {
|
|
//iRetNum = -1;
|
|
break; /* file end */
|
|
}
|
|
|
|
buffer[i++] = ch1;
|
|
}
|
|
|
|
buffer[i] = '\0';
|
|
return iRetNum;
|
|
}
|
|
|
|
static char *parser_ini_str_trim_r(char *buf)
|
|
{
|
|
int len, i;
|
|
char *tmp = NULL;
|
|
char x[512] = {0};
|
|
char *y = NULL;
|
|
char *empty = "";
|
|
|
|
len = strlen(buf);
|
|
|
|
if (len < sizeof(x)) {
|
|
tmp = x;
|
|
goto copy;
|
|
}
|
|
|
|
y = kzalloc(len, GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(y)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate tmp buf\n", __func__);
|
|
return empty;
|
|
}
|
|
tmp = y;
|
|
|
|
copy:
|
|
for (i = 0; i < len; i++) {
|
|
if (buf[i] != ' ')
|
|
break;
|
|
}
|
|
|
|
if (i < len)
|
|
strncpy(tmp, (buf + i), (len - i));
|
|
|
|
strncpy(buf, tmp, len);
|
|
ipio_kfree((void **)&y);
|
|
return buf;
|
|
}
|
|
|
|
static int parser_get_ini_phy_data(char *data, int fsize)
|
|
{
|
|
int i, n = 0, ret = 0, banchmark_flag = 0, empty_section, nodetype_flag = 0;
|
|
int offset = 0, isEqualSign = 0, scount = 0;
|
|
char *ini_buf = NULL, *tmpSectionName = NULL;
|
|
char M_CFG_SSL = '[';
|
|
char M_CFG_SSR = ']';
|
|
/* char M_CFG_NIS = ':'; */
|
|
char M_CFG_NTS = '#';
|
|
char M_CFG_EQS = '=';
|
|
|
|
if (data == NULL) {
|
|
input_err(true, ilits->dev, "%s INI data is NULL\n", __func__);
|
|
ret = -EINVAL;
|
|
goto out;
|
|
}
|
|
|
|
ini_buf = kzalloc((PARSER_MAX_CFG_BUF + 1) * sizeof(char), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(ini_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate ini_buf memory, %ld\n", __func__, PTR_ERR(ini_buf));
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
|
|
tmpSectionName = kzalloc((PARSER_MAX_CFG_BUF + 1) * sizeof(char), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tmpSectionName)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate tmpSectionName memory, %ld\n",
|
|
__func__, PTR_ERR(tmpSectionName));
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
|
|
memset(seq_item, 0, MP_TEST_ITEM * PARSER_MAX_KEY_NAME_LEN * sizeof(char));
|
|
|
|
while (true) {
|
|
banchmark_flag = 0;
|
|
empty_section = 0;
|
|
nodetype_flag = 0;
|
|
if (g_ini_items > PARSER_MAX_KEY_NUM) {
|
|
input_err(true, ilits->dev, "%s MAX_KEY_NUM: Out of length\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
if (offset >= fsize)
|
|
goto out;/*over size*/
|
|
|
|
n = parser_get_ini_phy_line(data + offset, ini_buf, PARSER_MAX_CFG_BUF);
|
|
if (n < 0) {
|
|
input_err(true, ilits->dev, "%s End of Line\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
offset += n;
|
|
|
|
n = strlen(parser_ini_str_trim_r(ini_buf));
|
|
|
|
if (n == 0 || ini_buf[0] == M_CFG_NTS)
|
|
continue;
|
|
|
|
/* Get section names */
|
|
if (n > 2 && ((ini_buf[0] == M_CFG_SSL && ini_buf[n - 1] != M_CFG_SSR))) {
|
|
input_err(true, ilits->dev, "%s Bad Section: %s\n", __func__, ini_buf);
|
|
ret = -EINVAL;
|
|
goto out;
|
|
} else {
|
|
if (ini_buf[0] == M_CFG_SSL) {
|
|
ini_info[g_ini_items].section_len = n - 2;
|
|
if (ini_info[g_ini_items].section_len > PARSER_MAX_KEY_NAME_LEN) {
|
|
input_err(true, ilits->dev, "%s MAX_KEY_NAME_LEN: Out Of Length\n", __func__);
|
|
ret = INI_ERR_OUT_OF_LINE;
|
|
goto out;
|
|
}
|
|
|
|
if (scount > MAX_SECTION_NUM) {
|
|
input_err(true, ilits->dev,
|
|
"%s seq_item is over than its define (%d), abort\n", __func__, scount);
|
|
ret = INI_ERR_OUT_OF_LINE;
|
|
goto out;
|
|
}
|
|
|
|
ini_buf[n - 1] = 0x00;
|
|
strncpy((char *)tmpSectionName, ini_buf + 1, (PARSER_MAX_CFG_BUF + 1) * sizeof(char));
|
|
banchmark_flag = 0;
|
|
nodetype_flag = 0;
|
|
strncpy(seq_item[scount], tmpSectionName, PARSER_MAX_KEY_NAME_LEN);
|
|
scount++;
|
|
ILI_DBG("%s Section Name: %s, Len: %d, offset = %d\n",
|
|
__func__, seq_item[scount], n - 2, offset);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/* copy section's name without square brackets to its real buffer */
|
|
strncpy(ini_info[g_ini_items].section_name, tmpSectionName, (PARSER_MAX_KEY_NAME_LEN * sizeof(char)));
|
|
ini_info[g_ini_items].section_len = strlen(tmpSectionName);
|
|
|
|
isEqualSign = 0;
|
|
for (i = 0; i < n; i++) {
|
|
if (ini_buf[i] == M_CFG_EQS) {
|
|
isEqualSign = i;
|
|
break;
|
|
}
|
|
if (ini_buf[i] == M_CFG_SSL || ini_buf[i] == M_CFG_SSR) {
|
|
empty_section = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (isEqualSign == 0) {
|
|
if (empty_section)
|
|
continue;
|
|
|
|
if (strstr(ini_info[g_ini_items].section_name, BENCHMARK_KEY_NAME) != NULL) {
|
|
isEqualSign = -1;
|
|
ini_info[g_ini_items].key_name_len = strlen(ini_info[g_ini_items].section_name);
|
|
strncpy(ini_info[g_ini_items].key_name, ini_info[g_ini_items].section_name,
|
|
(PARSER_MAX_KEY_NAME_LEN * sizeof(char)));
|
|
ini_info[g_ini_items].key_val_len = n;
|
|
} else if (strstr(ini_info[g_ini_items].section_name, NODE_TYPE_KEY_NAME) != NULL) {
|
|
isEqualSign = -1;
|
|
ini_info[g_ini_items].key_name_len = strlen(NODE_TYPE_KEY_NAME);
|
|
strncpy(ini_info[g_ini_items].key_name, NODE_TYPE_KEY_NAME,
|
|
(PARSER_MAX_KEY_NAME_LEN * sizeof(char)));
|
|
ini_info[g_ini_items].key_val_len = n;
|
|
} else {
|
|
continue;
|
|
}
|
|
} else {
|
|
ini_info[g_ini_items].key_name_len = isEqualSign;
|
|
if (ini_info[g_ini_items].key_name_len > PARSER_MAX_KEY_NAME_LEN) {
|
|
/* ret = CFG_ERR_OUT_OF_LEN; */
|
|
input_err(true, ilits->dev, "%s MAX_KEY_NAME_LEN: Out Of Length\n", __func__);
|
|
ret = INI_ERR_OUT_OF_LINE;
|
|
goto out;
|
|
}
|
|
|
|
ipio_memcpy(ini_info[g_ini_items].key_name, ini_buf,
|
|
ini_info[g_ini_items].key_name_len, PARSER_MAX_KEY_NAME_LEN);
|
|
ini_info[g_ini_items].key_val_len = n - isEqualSign - 1;
|
|
}
|
|
|
|
if (ini_info[g_ini_items].key_val_len > PARSER_MAX_KEY_VALUE_LEN) {
|
|
input_err(true, ilits->dev, "%s MAX_KEY_VALUE_LEN: Out Of Length\n", __func__);
|
|
ret = INI_ERR_OUT_OF_LINE;
|
|
goto out;
|
|
}
|
|
|
|
ipio_memcpy(ini_info[g_ini_items].key_value,
|
|
ini_buf + isEqualSign + 1, ini_info[g_ini_items].key_val_len, PARSER_MAX_KEY_VALUE_LEN);
|
|
|
|
ILI_DBG("%s %s = %s\n", __func__, ini_info[g_ini_items].key_name,
|
|
ini_info[g_ini_items].key_value);
|
|
|
|
g_ini_items++;
|
|
}
|
|
out:
|
|
ipio_kfree((void **)&ini_buf);
|
|
ipio_kfree((void **)&tmpSectionName);
|
|
return ret;
|
|
}
|
|
|
|
static int ilitek_tddi_mp_ini_parser(const char *path)
|
|
{
|
|
int i, ret = 0, fsize = 0;
|
|
char *tmp = NULL;
|
|
const struct firmware *ini = NULL;
|
|
struct file *f = NULL;
|
|
mm_segment_t old_fs;
|
|
loff_t pos = 0;
|
|
|
|
input_info(true, ilits->dev, "%s ini file path = %s\n", __func__, path);
|
|
|
|
f = filp_open(path, O_RDONLY, 644);
|
|
if (ERR_ALLOC_MEM(f)) {
|
|
input_err(true, ilits->dev, "%s Failed to open ini file at %ld, try to request_firmware\n",
|
|
__func__, PTR_ERR(f));
|
|
f = NULL;
|
|
path = ilits->md_ini_rq_path;
|
|
input_info(true, ilits->dev, "%s request path = %s\n", __func__, path);
|
|
if (request_firmware(&ini, path, ilits->dev) < 0) {
|
|
input_err(true, ilits->dev, "%s Request ini file failed\n", __func__);
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
if (f != NULL) {
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
|
|
fsize = f->f_inode->i_size;
|
|
#else
|
|
struct inode *inode;
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
|
|
inode = f->f_dentry->d_inode;
|
|
#else
|
|
inode = f->f_path.dentry->d_inode;
|
|
#endif
|
|
fsize = inode->i_size;
|
|
#endif
|
|
} else {
|
|
fsize = ini->size;
|
|
}
|
|
|
|
input_info(true, ilits->dev, "%s ini file size = %d\n", __func__, fsize);
|
|
if (fsize <= 0) {
|
|
input_err(true, ilits->dev, "%s The size of file is invaild\n", __func__);
|
|
ret = -EINVAL;
|
|
goto out;
|
|
}
|
|
|
|
tmp = vmalloc(fsize+1);
|
|
if (ERR_ALLOC_MEM(tmp)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate tmp memory, %ld\n", __func__, PTR_ERR(tmp));
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
|
|
if (f != NULL) {
|
|
old_fs = get_fs();
|
|
set_fs(get_ds());
|
|
vfs_read(f, tmp, fsize, &pos);
|
|
set_fs(old_fs);
|
|
tmp[fsize] = 0x0;
|
|
} else {
|
|
memcpy(tmp, ini->data, fsize);
|
|
}
|
|
|
|
g_ini_items = 0;
|
|
|
|
/* Initialise ini strcture */
|
|
for (i = 0; i < PARSER_MAX_KEY_NUM; i++) {
|
|
memset(ini_info[i].section_name, 0, PARSER_MAX_KEY_NAME_LEN);
|
|
memset(ini_info[i].key_name, 0, PARSER_MAX_KEY_NAME_LEN);
|
|
memset(ini_info[i].key_value, 0, PARSER_MAX_KEY_VALUE_LEN);
|
|
ini_info[i].section_len = 0;
|
|
ini_info[i].key_name_len = 0;
|
|
ini_info[i].key_val_len = 0;
|
|
}
|
|
|
|
/* change all characters to lower case */
|
|
for (i = 0; i < fsize; i++)
|
|
tmp[i] = tolower(tmp[i]);
|
|
|
|
ret = parser_get_ini_phy_data(tmp, fsize);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get physical ini data, ret = %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
input_info(true, ilits->dev, "%s Parsed ini file done\n", __func__);
|
|
out:
|
|
ipio_vfree((void **)&tmp);
|
|
|
|
if (f != NULL)
|
|
filp_close(f, NULL);
|
|
else
|
|
release_firmware(ini);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void run_pixel_test(int index)
|
|
{
|
|
int i, x, y;
|
|
s32 *p_comb = frame_buf;
|
|
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
int tmp[4] = { 0 }, max = 0;
|
|
int shift = y * core_mp.xch_len;
|
|
int centre = p_comb[shift + x];
|
|
|
|
/*
|
|
* if its position is in corner, the number of point
|
|
* we have to minus is around 2 to 3.
|
|
*/
|
|
if (y == 0 && x == 0) {
|
|
tmp[0] = Mathabs(centre - p_comb[(shift + 1) + x]); /* down */
|
|
tmp[1] = Mathabs(centre - p_comb[shift + (x + 1)]); /* right */
|
|
} else if (y == (core_mp.ych_len - 1) && x == 0) {
|
|
tmp[0] = Mathabs(centre - p_comb[(shift - 1) + x]); /* up */
|
|
tmp[1] = Mathabs(centre - p_comb[shift + (x + 1)]); /* right */
|
|
} else if (y == 0 && x == (core_mp.xch_len - 1)) {
|
|
tmp[0] = Mathabs(centre - p_comb[(shift + 1) + x]); /* down */
|
|
tmp[1] = Mathabs(centre - p_comb[shift + (x - 1)]); /* left */
|
|
} else if (y == (core_mp.ych_len - 1) && x == (core_mp.xch_len - 1)) {
|
|
tmp[0] = Mathabs(centre - p_comb[(shift - 1) + x]); /* up */
|
|
tmp[1] = Mathabs(centre - p_comb[shift + (x - 1)]); /* left */
|
|
} else if (y == 0 && x != 0) {
|
|
tmp[0] = Mathabs(centre - p_comb[(shift + 1) + x]); /* down */
|
|
tmp[1] = Mathabs(centre - p_comb[shift + (x - 1)]); /* left */
|
|
tmp[2] = Mathabs(centre - p_comb[shift + (x + 1)]); /* right */
|
|
} else if (y != 0 && x == 0) {
|
|
tmp[0] = Mathabs(centre - p_comb[(shift - 1) + x]); /* up */
|
|
tmp[1] = Mathabs(centre - p_comb[shift + (x + 1)]); /* right */
|
|
tmp[2] = Mathabs(centre - p_comb[(shift + 1) + x]); /* down */
|
|
|
|
} else if (y == (core_mp.ych_len - 1) && x != 0) {
|
|
tmp[0] = Mathabs(centre - p_comb[(shift - 1) + x]); /* up */
|
|
tmp[1] = Mathabs(centre - p_comb[shift + (x - 1)]); /* left */
|
|
tmp[2] = Mathabs(centre - p_comb[shift + (x + 1)]); /* right */
|
|
} else if (y != 0 && x == (core_mp.xch_len - 1)) {
|
|
tmp[0] = Mathabs(centre - p_comb[(shift - 1) + x]); /* up */
|
|
tmp[1] = Mathabs(centre - p_comb[shift + (x - 1)]); /* left */
|
|
tmp[2] = Mathabs(centre - p_comb[(shift + 1) + x]); /* down */
|
|
} else {
|
|
/* middle minus four directions */
|
|
tmp[0] = Mathabs(centre - p_comb[(shift - 1) + x]); /* up */
|
|
tmp[1] = Mathabs(centre - p_comb[(shift + 1) + x]); /* down */
|
|
tmp[2] = Mathabs(centre - p_comb[shift + (x - 1)]); /* left */
|
|
tmp[3] = Mathabs(centre - p_comb[shift + (x + 1)]); /* right */
|
|
}
|
|
|
|
max = tmp[0];
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (tmp[i] > max)
|
|
max = tmp[i];
|
|
}
|
|
|
|
tItems[index].buf[shift + x] = max;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void run_untouch_p2p_test(int index)
|
|
{
|
|
int x, y;
|
|
s32 *p_comb = frame_buf;
|
|
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
int shift = y * core_mp.xch_len;
|
|
|
|
if (p_comb[shift + x] > tItems[index].max_buf[shift + x])
|
|
tItems[index].max_buf[shift + x] = p_comb[shift + x];
|
|
|
|
if (p_comb[shift + x] < tItems[index].min_buf[shift + x])
|
|
tItems[index].min_buf[shift + x] = p_comb[shift + x];
|
|
|
|
tItems[index].buf[shift + x] =
|
|
tItems[index].max_buf[shift + x] - tItems[index].min_buf[shift + x];
|
|
}
|
|
}
|
|
}
|
|
|
|
static int run_open_test(int index)
|
|
{
|
|
int i, x, y, k, ret = 0;
|
|
int border_x[] = {-1, 0, 1, 1, 1, 0, -1, -1};
|
|
int border_y[] = {-1, -1, -1, 0, 1, 1, 1, 0};
|
|
s32 *p_comb = frame_buf;
|
|
|
|
if (ipio_strcmp(tItems[index].desp, "open test(integration)") == 0) {
|
|
for (i = 0; i < core_mp.frame_len; i++)
|
|
tItems[index].buf[i] = p_comb[i];
|
|
} else if (ipio_strcmp(tItems[index].desp, "open test(cap)") == 0) {
|
|
/*
|
|
* Each result is getting from a 3 by 3 grid depending on where the centre location is.
|
|
* So if the centre is at corner, the number of node grabbed from a grid will be different.
|
|
*/
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
int sum = 0, avg = 0, count = 0;
|
|
int shift = y * core_mp.xch_len;
|
|
int centre = p_comb[shift + x];
|
|
|
|
for (k = 0; k < 8; k++) {
|
|
if (((y + border_y[k] >= 0) && (y + border_y[k] < core_mp.ych_len)) &&
|
|
((x + border_x[k] >= 0) && (x + border_x[k] < core_mp.xch_len))) {
|
|
count++;
|
|
sum += p_comb[(y + border_y[k]) * core_mp.xch_len + (x + border_x[k])];
|
|
}
|
|
}
|
|
|
|
avg = (sum + centre) / (count + 1); /* plus 1 because of centre */
|
|
tItems[index].buf[shift + x] = (centre * 100) / avg;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void run_tx_rx_delta_test(int index)
|
|
{
|
|
int x, y;
|
|
s32 *p_comb = frame_buf;
|
|
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
int shift = y * core_mp.xch_len;
|
|
|
|
/* Tx Delta */
|
|
if (y != (core_mp.ych_len - 1))
|
|
core_mp.tx_delta_buf[shift + x] = Mathabs(p_comb[shift + x] - p_comb[(shift + 1) + x]);
|
|
|
|
/* Rx Delta */
|
|
if (x != (core_mp.xch_len - 1))
|
|
core_mp.rx_delta_buf[shift + x] = Mathabs(p_comb[shift + x] - p_comb[shift + (x + 1)]);
|
|
}
|
|
}
|
|
}
|
|
|
|
static char *get_date_time_str(void)
|
|
{
|
|
struct timespec now_time;
|
|
struct rtc_time rtc_now_time;
|
|
static char time_data_buf[128] = { 0 };
|
|
|
|
getnstimeofday(&now_time);
|
|
rtc_time_to_tm(now_time.tv_sec, &rtc_now_time);
|
|
snprintf(time_data_buf, sizeof(time_data_buf), "%04d%02d%02d-%02d%02d%02d",
|
|
(rtc_now_time.tm_year + 1900), rtc_now_time.tm_mon + 1,
|
|
rtc_now_time.tm_mday, rtc_now_time.tm_hour, rtc_now_time.tm_min,
|
|
rtc_now_time.tm_sec);
|
|
|
|
return time_data_buf;
|
|
}
|
|
|
|
static void mp_print_csv_header(char *csv, int *csv_len, int *csv_line, int file_size)
|
|
{
|
|
int i, seq, tmp_len = *csv_len, tmp_line = *csv_line;
|
|
|
|
/* header must has 19 line*/
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len),
|
|
"==============================================================================\n");
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len),
|
|
"ILITek C-TP Utility V%s %x : Driver Sensor Test\n", DRIVER_VERSION, core_mp.chip_pid);
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "Confidentiality Notice:\n");
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len),
|
|
"Any information of this tool is confidential and privileged.\n");
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "@ ILI TECHNOLOGY CORP. All Rights Reserved.\n");
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len),
|
|
"==============================================================================\n");
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "Firmware Version ,0x%x\n", core_mp.fw_ver);
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "Panel information ,XCH=%d, YCH=%d\n",
|
|
core_mp.xch_len, core_mp.ych_len);
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "INI Release Version ,%s\n", core_mp.ini_ver);
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "INI Release Date ,%s\n", core_mp.ini_date);
|
|
tmp_line++;
|
|
tmp_line++;
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "Test Item:\n");
|
|
tmp_line++;
|
|
|
|
for (seq = 0; seq < ri.count; seq++) {
|
|
i = ri.index[seq];
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), " ---%s\n", tItems[i].desp);
|
|
tmp_line++;
|
|
}
|
|
|
|
while (tmp_line < 19) {
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "\n");
|
|
tmp_line++;
|
|
}
|
|
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len),
|
|
"==============================================================================\n");
|
|
|
|
*csv_len = tmp_len;
|
|
*csv_line = tmp_line;
|
|
}
|
|
|
|
static void mp_print_csv_tail(char *csv, int *csv_len, int file_size)
|
|
{
|
|
int i, seq, tmp_len = *csv_len;
|
|
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len),
|
|
"==============================================================================\n");
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "Result_Summary \n");
|
|
|
|
for (seq = 0; seq < ri.count; seq++) {
|
|
i = ri.index[seq];
|
|
if (tItems[i].item_result == MP_DATA_PASS) {
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), " {%s} ,OK\n",
|
|
tItems[i].desp);
|
|
} else {
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), " {%s} ,NG\n",
|
|
tItems[i].desp);
|
|
}
|
|
}
|
|
|
|
*csv_len = tmp_len;
|
|
}
|
|
|
|
static void mp_print_csv_cdc_cmd(char *csv, int *csv_len, int index, int file_size)
|
|
{
|
|
int i, slen = 0, tmp_len = *csv_len, size;
|
|
char str[128] = {0};
|
|
char *open_sp_cmd[] = {"open dac", "open raw1", "open raw2", "open raw3"};
|
|
char *open_c_cmd[] = {"open cap1 dac", "open cap1 raw"};
|
|
char *name = tItems[index].desp;
|
|
|
|
if (ipio_strcmp(name, "open test(integration)_sp") == 0) {
|
|
size = ARRAY_SIZE(open_sp_cmd);
|
|
for (i = 0; i < size; i++) {
|
|
slen = parser_get_int_data("pv5_4 command", open_sp_cmd[i], str, sizeof(str));
|
|
if (slen < 0)
|
|
input_err(true, ilits->dev, "%s Failed to get CDC command %s from ini\n",
|
|
__func__, open_sp_cmd[i]);
|
|
else
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "%s = ,%s\n",
|
|
open_sp_cmd[i], str);
|
|
}
|
|
} else if (ipio_strcmp(name, "open test_c") == 0) {
|
|
size = ARRAY_SIZE(open_c_cmd);
|
|
for (i = 0; i < size; i++) {
|
|
slen = parser_get_int_data("pv5_4 command", open_c_cmd[i], str, sizeof(str));
|
|
if (slen < 0)
|
|
input_err(true, ilits->dev, "%s Failed to get CDC command %s from ini\n",
|
|
__func__, open_sp_cmd[i]);
|
|
else
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "%s = ,%s\n",
|
|
open_c_cmd[i], str);
|
|
}
|
|
} else {
|
|
slen = parser_get_int_data("pv5_4 command", name, str, sizeof(str));
|
|
if (slen < 0)
|
|
input_err(true, ilits->dev, "%s Failed to get CDC command %s from ini\n", __func__, name);
|
|
else
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "CDC command = ,%s\n", str);
|
|
|
|
/* Print short parameters */
|
|
if (ipio_strcmp(name, "short test") == 0)
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "Variation = ,%d\n",
|
|
short_para.variation);
|
|
|
|
/* Print td second command */
|
|
if (core_mp.td_retry && (ipio_strcmp(name, "peak to peak_td (lcm off)") == 0)) {
|
|
name = "peak to peak_td (lcm off)_2";
|
|
parser_get_int_data("pv5_4 command", name, str, sizeof(str));
|
|
tmp_len += snprintf(csv + tmp_len, (file_size - tmp_len), "CDC command 2 = ,%s\n", str);
|
|
}
|
|
}
|
|
*csv_len = tmp_len;
|
|
}
|
|
|
|
static void mp_compare_cdc_show_result(int index, s32 *tmp, char *csv,
|
|
int *csv_len, int type, s32 *max_ts,
|
|
s32 *min_ts, const char *desp, int file_zise)
|
|
{
|
|
int x, y, tmp_len = *csv_len;
|
|
int mp_result = MP_DATA_PASS;
|
|
|
|
if (ERR_ALLOC_MEM(tmp)) {
|
|
input_err(true, ilits->dev, "%s The data of test item is null (%p)\n", __func__, tmp);
|
|
mp_result = -EMP_INVAL;
|
|
goto out;
|
|
}
|
|
|
|
/* print X raw only */
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
if (x == 0) {
|
|
DUMP("\n %s ", desp);
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "\n %s ,", desp);
|
|
}
|
|
DUMP(" X_%d ,", (x+1));
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), " X_%d ,", (x+1));
|
|
}
|
|
|
|
DUMP("\n");
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "\n");
|
|
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
DUMP(" Y_%d ,", (y+1));
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), " Y_%d ,", (y+1));
|
|
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
int shift = y * core_mp.xch_len + x;
|
|
|
|
/* In Short teset, we only identify if its value is low than min threshold. */
|
|
if (tItems[index].catalog == SHORT_TEST) {
|
|
if (tmp[shift] < min_ts[shift]) {
|
|
DUMP(" #%7d ", tmp[shift]);
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "#%7d,", tmp[shift]);
|
|
mp_result = MP_DATA_FAIL;
|
|
} else {
|
|
DUMP(" %7d ", tmp[shift]);
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), " %7d, ",
|
|
tmp[shift]);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if ((tmp[shift] <= max_ts[shift] && tmp[shift] >= min_ts[shift]) || (type != TYPE_JUGE)) {
|
|
if ((tmp[shift] == INT_MAX || tmp[shift] == INT_MIN) && (type == TYPE_BENCHMARK)) {
|
|
DUMP("%s", "BYPASS,");
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "BYPASS,");
|
|
} else {
|
|
DUMP(" %7d ", tmp[shift]);
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), " %7d, ",
|
|
tmp[shift]);
|
|
}
|
|
} else {
|
|
if (tmp[shift] > max_ts[shift]) {
|
|
DUMP(" *%7d ", tmp[shift]);
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "*%7d,", tmp[shift]);
|
|
} else {
|
|
DUMP(" #%7d ", tmp[shift]);
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "#%7d,", tmp[shift]);
|
|
}
|
|
mp_result = MP_DATA_FAIL;
|
|
}
|
|
}
|
|
DUMP("\n");
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "\n");
|
|
}
|
|
|
|
out:
|
|
if (type == TYPE_JUGE) {
|
|
if (mp_result == MP_DATA_PASS) {
|
|
pr_info("\n Result : PASS\n");
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "Result : PASS\n");
|
|
} else {
|
|
pr_info("\n Result : FAIL\n");
|
|
tmp_len += snprintf(csv + tmp_len, (file_zise - tmp_len), "Result : FAIL\n");
|
|
}
|
|
}
|
|
*csv_len = tmp_len;
|
|
}
|
|
|
|
#define ABS(a, b) ((a > b) ? (a - b) : (b - a))
|
|
#define ADDR(x, y) ((y * core_mp.xch_len) + (x))
|
|
|
|
static int compare_charge(s32 *charge_rate, int x, int y, s32 *inNodeType,
|
|
int Charge_AA, int Charge_Border, int Charge_Notch)
|
|
{
|
|
int OpenThreadhold, tempY, tempX, ret, k;
|
|
int sx[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
|
|
int sy[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
|
|
|
|
ret = charge_rate[ADDR(x, y)];
|
|
|
|
/*Setting Threadhold from node type */
|
|
if (charge_rate[ADDR(x, y)] == 0)
|
|
return ret;
|
|
else if ((inNodeType[ADDR(x, y)] & AA_Area) == AA_Area)
|
|
OpenThreadhold = Charge_AA;
|
|
else if ((inNodeType[ADDR(x, y)] & Border_Area) == Border_Area)
|
|
OpenThreadhold = Charge_Border;
|
|
else if ((inNodeType[ADDR(x, y)] & Notch) == Notch)
|
|
OpenThreadhold = Charge_Notch;
|
|
else
|
|
return ret;
|
|
|
|
/* compare carge rate with 3*3 node */
|
|
/* by pass => 1.no compare 2.corner 3.Skip_Micro 4.full open fail node */
|
|
for (k = 0; k < 8; k++) {
|
|
tempX = x + sx[k];
|
|
tempY = y + sy[k];
|
|
|
|
/*out of range */
|
|
if ((tempX < 0) || (tempX >= core_mp.xch_len) || (tempY < 0) || (tempY >= core_mp.ych_len))
|
|
continue;
|
|
|
|
if ((inNodeType[ADDR(tempX, tempY)] == NO_COMPARE) ||
|
|
((inNodeType[ADDR(tempX, tempY)] & Round_Corner) == Round_Corner) ||
|
|
((inNodeType[ADDR(tempX, tempY)] & Skip_Micro) == Skip_Micro) || charge_rate[ADDR(tempX, tempY)] == 0)
|
|
continue;
|
|
|
|
if ((charge_rate[ADDR(tempX, tempY)] - charge_rate[ADDR(x, y)]) > OpenThreadhold)
|
|
return OpenThreadhold;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static int full_open_rate_compare(s32 *full_open, s32 *cbk, int x, int y, s32 inNodeType, int full_open_rate)
|
|
{
|
|
int ret = true;
|
|
|
|
if ((inNodeType == NO_COMPARE) || ((inNodeType & Round_Corner) == Round_Corner))
|
|
return true;
|
|
|
|
if (full_open[ADDR(x, y)] < (cbk[ADDR(x, y)] * full_open_rate / 100))
|
|
ret = false;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static s32 open_sp_formula(int dac, int raw, int tvch, int tvcl)
|
|
{
|
|
s32 ret = 0;
|
|
u16 id = core_mp.chip_id;
|
|
|
|
if (id == ILI9881_CHIP) {
|
|
ret = ((dac * 10000 * 161 / 100) - (16384 / 2 - raw) * 20000 * 7 /
|
|
16384 * 36 / 10) / (tvch - tvcl) / 2;
|
|
} else {
|
|
ret = ((dac * 10000 * 131 / 100) - (16384 / 2 - raw) * 20000 * 7 /
|
|
16384 * 36 / 10) / (tvch - tvcl) / 2;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static s32 open_c_formula(int inCap1DAC, int inCap1Raw, int accuracy)
|
|
{
|
|
s32 inCap1Value = 0;
|
|
|
|
u16 id = core_mp.chip_id;
|
|
u8 type = core_mp.chip_type;
|
|
|
|
int inFoutRange = 16384;
|
|
int inFoutRange_half = 8192;
|
|
int inVadc_range = 36;
|
|
int inVbk = 39;
|
|
int inCbk_step = open_para.cbk_step;/* from mp.ini */
|
|
int inCint = open_para.cint;/* from mp.ini */
|
|
int inVdrv = open_para.tvch - open_para.tvcl;/* from mp.ini */
|
|
int inGain = open_para.gain;/* from mp.ini */
|
|
int inMagnification = 10;
|
|
int inPartDac = 0;
|
|
int inPartRaw = 0;
|
|
|
|
if ((inCbk_step == 0) || (inCint == 0)) {
|
|
if (id == ILI9881_CHIP) {
|
|
if ((type == ILI_N) || (type == ILI_O)) {
|
|
inCbk_step = 32;
|
|
inCint = 70;
|
|
}
|
|
} else if (id == ILI9882_CHIP) {
|
|
if (type == ILI_N) {
|
|
inCbk_step = 42;
|
|
inCint = 70;
|
|
} else if (type == ILI_H) {
|
|
inCbk_step = 42;
|
|
inCint = 69;
|
|
}
|
|
} else if (id == ILI7807_CHIP) {
|
|
if (type == ILI_Q) {
|
|
inCbk_step = 28;
|
|
inCint = 70;
|
|
} else if (type == ILI_S) {
|
|
inCbk_step = 38;
|
|
inCint = 66;
|
|
inVbk = 42;
|
|
inVdrv = inVdrv / 10;
|
|
inGain = inGain / 10;
|
|
|
|
} else if (type == ILI_V) {
|
|
inCbk_step = 28;
|
|
inCint = 70;
|
|
}
|
|
}
|
|
}
|
|
|
|
inPartDac = (inCap1DAC * inCbk_step * inVbk / 2);
|
|
inPartRaw = ((inCap1Raw - inFoutRange_half) * inVadc_range * inCint * 10 / inFoutRange);
|
|
|
|
if (accuracy)
|
|
inCap1Value = ((inPartDac + inPartRaw) * 10) / inVdrv / inMagnification / inGain;
|
|
else
|
|
inCap1Value = (inPartDac + inPartRaw) / inVdrv / inMagnification / inGain;
|
|
|
|
return inCap1Value;
|
|
}
|
|
|
|
static void allnode_open_cdc_result(int index, int *buf, int *dac, int *raw)
|
|
{
|
|
int i;
|
|
char *desp = tItems[index].desp;
|
|
char str[32] = {0};
|
|
int accuracy = 0;
|
|
|
|
if (ipio_strcmp(desp, "open test(integration)_sp") == 0) {
|
|
for (i = 0; i < core_mp.frame_len; i++)
|
|
buf[i] = open_sp_formula(dac[i], raw[i], open_para.tvch, open_para.tvcl);
|
|
} else if (ipio_strcmp(desp, "open test_c") == 0) {
|
|
|
|
if (parser_get_int_data(desp, "accuracy", str, sizeof(str)) > 0)
|
|
accuracy = ili_katoi(str);
|
|
|
|
for (i = 0; i < core_mp.frame_len; i++)
|
|
buf[i] = open_c_formula(dac[i], raw[i], accuracy);
|
|
}
|
|
}
|
|
|
|
static int codeToOhm(s32 *ohm, s32 *Code, u16 *v_tdf, u16 *h_tdf)
|
|
{
|
|
u16 id = core_mp.chip_id;
|
|
u8 type = core_mp.chip_type;
|
|
|
|
int inTVCH = short_para.tvch;
|
|
int inTVCL = short_para.tvcl;
|
|
int inVariation = short_para.variation;
|
|
int inTDF1 = 0;
|
|
int inTDF2 = 0;
|
|
int inCint = short_para.cint;
|
|
int inRinternal = short_para.rinternal;
|
|
s32 temp = 0;
|
|
int j = 0;
|
|
|
|
if (core_mp.isLongV) {
|
|
inTDF1 = *v_tdf;
|
|
inTDF2 = *(v_tdf + 1);
|
|
} else {
|
|
inTDF1 = *h_tdf;
|
|
inTDF2 = *(h_tdf + 1);
|
|
}
|
|
|
|
if (inVariation == 0)
|
|
inVariation = 100;
|
|
|
|
if ((inCint == 0) || (inRinternal == 0)) {
|
|
if (id == ILI9881_CHIP) {
|
|
if ((type == ILI_N) || (type == ILI_O)) {
|
|
inRinternal = 1915;
|
|
inCint = 70;
|
|
}
|
|
} else if (id == ILI9882_CHIP) {
|
|
if (type == ILI_N) {
|
|
inRinternal = 1354;
|
|
inCint = 70;
|
|
} else if (type == ILI_H) {
|
|
inRinternal = 1354;
|
|
inCint = 69;
|
|
}
|
|
} else if (id == ILI7807_CHIP) {
|
|
if (type == ILI_Q) {
|
|
inRinternal = 1500;
|
|
inCint = 70;
|
|
} else if (type == ILI_S) {
|
|
inRinternal = 1500;
|
|
inCint = 66;
|
|
inTVCH = inTVCH/10;
|
|
inTVCL = inTVCL/10;
|
|
} else if (type == ILI_V) {
|
|
inRinternal = 1500;
|
|
inCint = 70;
|
|
}
|
|
}
|
|
}
|
|
for (j = 0; j < core_mp.frame_len; j++) {
|
|
if (Code[j] == 0) {
|
|
input_err(true, ilits->dev, "%s code is invalid\n", __func__);
|
|
} else {
|
|
temp = ((inTVCH - inTVCL) * inVariation * (inTDF1 - inTDF2) *
|
|
(1 << 12) / (9 * Code[j] * inCint)) * 1000;
|
|
temp = (temp - inRinternal) / 1000;
|
|
}
|
|
ohm[j] = temp;
|
|
}
|
|
|
|
/* Unit = M Ohm */
|
|
return temp;
|
|
|
|
}
|
|
|
|
static int short_test(int index, int frame_index)
|
|
{
|
|
u32 pid = core_mp.chip_pid >> 8;
|
|
int j = 0, ret = 0;
|
|
u16 v_tdf[2] = {0};
|
|
u16 h_tdf[2] = {0};
|
|
char str[32] = {0};
|
|
|
|
v_tdf[0] = tItems[index].v_tdf_1;
|
|
v_tdf[1] = tItems[index].v_tdf_2;
|
|
h_tdf[0] = tItems[index].h_tdf_1;
|
|
h_tdf[1] = tItems[index].h_tdf_2;
|
|
|
|
parser_get_int_data("short test", "tvch", str, sizeof(str));
|
|
short_para.tvch = ili_katoi(str);
|
|
|
|
parser_get_int_data("short test", "tvcl", str, sizeof(str));
|
|
short_para.tvcl = ili_katoi(str);
|
|
|
|
parser_get_int_data("short test", "variation", str, sizeof(str));
|
|
short_para.variation = ili_katoi(str);
|
|
|
|
parser_get_int_data("short test", "cint", str, sizeof(str));
|
|
short_para.cint = ili_katoi(str);
|
|
|
|
parser_get_int_data("short test", "rinternal", str, sizeof(str));
|
|
short_para.rinternal = ili_katoi(str);
|
|
|
|
/* 9881N, 9881O, 7807Q, 7807S not support cbk_step and cint read from mp.ini */
|
|
if ((pid != 0x988117) && (pid != 0x988118) && (pid != 0x78071A) && (pid != 0x78071C)) {
|
|
if ((short_para.cint == 0) || (short_para.rinternal == 0)) {
|
|
input_err(true, ilits->dev, "%s Failed to get short parameter", __func__);
|
|
core_mp.lost_parameter = true;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
input_info(true, ilits->dev,
|
|
"%s TVCH = %d, TVCL = %d, Variation = %d, V_TDF1 = %d, V_TDF2 = %d, H_TDF1 = %d, H_TDF2 = %d, Cint = %d, Rinternal = %d\n",
|
|
__func__, short_para.tvch, short_para.tvcl, short_para.variation, tItems[index].v_tdf_1,
|
|
tItems[index].v_tdf_2, tItems[index].h_tdf_1, tItems[index].h_tdf_2, short_para.cint,
|
|
short_para.rinternal);
|
|
|
|
if (core_mp.protocol_ver >= PROTOCOL_VER_540) {
|
|
/* Calculate code to ohm and save to tItems[index].buf */
|
|
ili_dump_data(frame_buf, 10, core_mp.frame_len, core_mp.xch_len, "Short Raw 1");
|
|
codeToOhm(&tItems[index].buf[frame_index * core_mp.frame_len], frame_buf, v_tdf, h_tdf);
|
|
ili_dump_data(&tItems[index].buf[frame_index * core_mp.frame_len], 10,
|
|
core_mp.frame_len, core_mp.xch_len, "Short Ohm 1");
|
|
} else {
|
|
for (j = 0; j < core_mp.frame_len; j++)
|
|
tItems[index].buf[frame_index * core_mp.frame_len + j] = frame_buf[j];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int allnode_key_cdc_data(int index)
|
|
{
|
|
int i, ret = 0, len = 0;
|
|
int inDACp = 0, inDACn = 0;
|
|
u8 cmd[3] = {0};
|
|
u8 *ori = NULL;
|
|
|
|
len = core_mp.key_len * 2;
|
|
|
|
ILI_DBG("%s Read key's length = %d\n", __func__, len);
|
|
ILI_DBG("%s core_mp.key_len = %d\n", __func__, core_mp.key_len);
|
|
|
|
if (len <= 0) {
|
|
input_err(true, ilits->dev, "%s Length is invalid\n", __func__);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
/* CDC init */
|
|
cmd[0] = P5_X_SET_CDC_INIT;
|
|
cmd[1] = tItems[index].cmd;
|
|
cmd[2] = 0;
|
|
|
|
// /* Allocate a buffer for the original */
|
|
ori = kcalloc(len, sizeof(u8), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(ori)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate ori mem (%ld)\n", __func__, PTR_ERR(ori));
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
ret = ilits->wrapper(cmd, sizeof(cmd), ori, len, ON, ON);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s fail to get cdc data\n", __func__);
|
|
goto out;
|
|
}
|
|
ili_dump_data(ori, 8, len, 0, "Key CDC original");
|
|
|
|
if (key_buf == NULL) {
|
|
key_buf = kcalloc(core_mp.key_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(key_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate FrameBuffer mem (%ld)\n",
|
|
__func__, PTR_ERR(key_buf));
|
|
goto out;
|
|
}
|
|
} else {
|
|
memset(key_buf, 0x0, core_mp.key_len);
|
|
}
|
|
|
|
/* Convert original data to the physical one in each node */
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
if (tItems[index].cmd == CMD_KEY_DAC) {
|
|
/* DAC - P */
|
|
if (((ori[(2 * i) + 1] & 0x80) >> 7) == 1) {
|
|
/* Negative */
|
|
inDACp = 0 - (int)(ori[(2 * i) + 1] & 0x7F);
|
|
} else {
|
|
inDACp = ori[(2 * i) + 1] & 0x7F;
|
|
}
|
|
|
|
/* DAC - N */
|
|
if (((ori[(1 + (2 * i)) + 1] & 0x80) >> 7) == 1) {
|
|
/* Negative */
|
|
inDACn = 0 - (int)(ori[(1 + (2 * i)) + 1] & 0x7F);
|
|
} else {
|
|
inDACn = ori[(1 + (2 * i)) + 1] & 0x7F;
|
|
}
|
|
|
|
key_buf[i] = (inDACp + inDACn) / 2;
|
|
}
|
|
}
|
|
ili_dump_data(key_buf, 32, core_mp.frame_len, core_mp.xch_len, "Key CDC combined data");
|
|
|
|
out:
|
|
ipio_kfree((void **)&ori);
|
|
return ret;
|
|
}
|
|
|
|
static int mp_cdc_get_pv5_4_command(u8 *cmd, int len, int index)
|
|
{
|
|
int slen = 0;
|
|
char str[128] = {0};
|
|
char *key = tItems[index].desp;
|
|
|
|
if (core_mp.td_retry && (ipio_strcmp(key, "peak to peak_td (lcm off)") == 0))
|
|
key = "peak to peak_td (lcm off)_2";
|
|
|
|
slen = parser_get_int_data("pv5_4 command", key, str, sizeof(str));
|
|
if (slen < 0)
|
|
return -1;
|
|
|
|
if (parser_get_u8_array(str, cmd, 16, len) < 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mp_cdc_init_cmd_common(u8 *cmd, int len, int index)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (core_mp.protocol_ver >= PROTOCOL_VER_540) {
|
|
core_mp.cdc_len = 15;
|
|
return mp_cdc_get_pv5_4_command(cmd, len, index);
|
|
}
|
|
|
|
cmd[0] = P5_X_SET_CDC_INIT;
|
|
cmd[1] = tItems[index].cmd;
|
|
cmd[2] = 0;
|
|
|
|
core_mp.cdc_len = 3;
|
|
|
|
if (ipio_strcmp(tItems[index].desp, "open test(integration)") == 0)
|
|
cmd[2] = 0x2;
|
|
if (ipio_strcmp(tItems[index].desp, "open test(cap)") == 0)
|
|
cmd[2] = 0x3;
|
|
|
|
if (tItems[index].catalog == PEAK_TO_PEAK_TEST) {
|
|
cmd[2] = ((tItems[index].frame_count & 0xff00) >> 8);
|
|
cmd[3] = tItems[index].frame_count & 0xff;
|
|
cmd[4] = 0;
|
|
|
|
core_mp.cdc_len = 5;
|
|
|
|
if (ipio_strcmp(tItems[index].desp, "noise peak to peak(cut panel)") == 0)
|
|
cmd[4] = 0x1;
|
|
|
|
ILI_DBG("%s P2P CMD: %d,%d,%d,%d,%d\n",
|
|
__func__, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int allnode_open_cdc_data(int mode, int *buf)
|
|
{
|
|
int i = 0, ret = 0, len = 0;
|
|
int inDACp = 0, inDACn = 0;
|
|
u8 cmd[15] = {0};
|
|
u8 *ori = NULL;
|
|
char str[128] = {0};
|
|
char *key[] = {"open dac", "open raw1", "open raw2", "open raw3",
|
|
"open cap1 dac", "open cap1 raw"};
|
|
|
|
/* Multipling by 2 is due to the 16 bit in each node */
|
|
len = (core_mp.xch_len * core_mp.ych_len * 2) + 2;
|
|
|
|
ILI_DBG("%s Read X/Y Channel length = %d, mode = %d\n", __func__, len, mode);
|
|
|
|
if (len <= 2) {
|
|
input_err(true, ilits->dev, "%s Length is invalid\n", __func__);
|
|
ret = -EMP_INVAL;
|
|
goto out;
|
|
}
|
|
|
|
/* CDC init. Read command from ini file */
|
|
if (parser_get_int_data("pv5_4 command", key[mode], str, sizeof(str)) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to parse PV54 command, ret = %d\n", __func__, ret);
|
|
ret = -EMP_PARSE;
|
|
goto out;
|
|
}
|
|
|
|
parser_get_u8_array(str, cmd, 16, sizeof(cmd));
|
|
|
|
ili_dump_data(cmd, 8, sizeof(cmd), 0, "Open SP command");
|
|
|
|
/* Allocate a buffer for the original */
|
|
ori = kcalloc(len, sizeof(u8), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(ori)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate ori, (%ld)\n", __func__, PTR_ERR(ori));
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
/* Get original frame(cdc) data */
|
|
if (ilits->wrapper(cmd, core_mp.cdc_len, ori, len, ON, ON) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get cdc data\n", __func__);
|
|
ret = -EMP_GET_CDC;
|
|
goto out;
|
|
}
|
|
|
|
ili_dump_data(ori, 8, len, 0, "Open SP CDC original");
|
|
|
|
/* Convert original data to the physical one in each node */
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
if ((mode == 0) || (mode == 4)) {
|
|
/* DAC - P */
|
|
if (((ori[(2 * i) + 1] & 0x80) >> 7) == 1) {
|
|
/* Negative */
|
|
inDACp = 0 - (int)(ori[(2 * i) + 1] & 0x7F);
|
|
} else {
|
|
inDACp = ori[(2 * i) + 1] & 0x7F;
|
|
}
|
|
|
|
/* DAC - N */
|
|
if (((ori[(1 + (2 * i)) + 1] & 0x80) >> 7) == 1) {
|
|
/* Negative */
|
|
inDACn = 0 - (int)(ori[(1 + (2 * i)) + 1] & 0x7F);
|
|
} else {
|
|
inDACn = ori[(1 + (2 * i)) + 1] & 0x7F;
|
|
}
|
|
|
|
buf[i] = inDACp + inDACn;
|
|
} else {
|
|
/* H byte + L byte */
|
|
s32 tmp = (ori[(2 * i) + 1] << 8) + ori[(1 + (2 * i)) + 1];
|
|
|
|
if ((tmp & 0x8000) == 0x8000)
|
|
buf[i] = tmp - 65536;
|
|
else
|
|
buf[i] = tmp;
|
|
|
|
}
|
|
}
|
|
ili_dump_data(buf, 10, core_mp.frame_len, core_mp.xch_len, "Open SP CDC combined");
|
|
out:
|
|
|
|
ipio_kfree((void **)&ori);
|
|
return ret;
|
|
}
|
|
|
|
static int allnode_peak_to_peak_cdc_data(int index)
|
|
{
|
|
int i, k, ret = 0, len = 0, rd_frame_num = 1, cmd_len = 0;
|
|
u8 cmd[15] = {0};
|
|
u8 *ori = NULL;
|
|
|
|
/* Multipling by 2 is due to the 16 bit in each node */
|
|
len = (core_mp.frame_len * 2) + 2;
|
|
|
|
ILI_DBG("%s Read X/Y Channel length = %d\n", __func__, len);
|
|
|
|
if (len <= 2) {
|
|
input_err(true, ilits->dev, "%s Length is invalid\n", __func__);
|
|
ret = -EMP_INVAL;
|
|
goto out;
|
|
}
|
|
|
|
memset(cmd, 0xFF, sizeof(cmd));
|
|
|
|
/* Allocate a buffer for the original */
|
|
ori = kcalloc(len, sizeof(u8), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(ori)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate ori, (%ld)\n", __func__, PTR_ERR(ori));
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
if (tItems[index].bch_mrk_multi)
|
|
rd_frame_num = tItems[index].bch_mrk_frm_num - 1;
|
|
|
|
if (frm_buf == NULL) {
|
|
frm_buf = (s32 **)kzalloc(tItems[index].bch_mrk_frm_num * sizeof(s32 *), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(frm_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate frm_buf mem (%ld)\n",
|
|
__func__, PTR_ERR(frm_buf));
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
for (i = 0 ; i < tItems[index].bch_mrk_frm_num ; i++) {
|
|
frm_buf[i] = (s32 *)kzalloc(core_mp.frame_len * sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(frm_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate frm_buf[%d] mem (%ld)\n",
|
|
__func__, i, PTR_ERR(frm_buf));
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* CDC init */
|
|
if (mp_cdc_init_cmd_common(cmd, sizeof(cmd), index) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get cdc command\n", __func__);
|
|
ret = -EMP_CMD;
|
|
goto out;
|
|
}
|
|
|
|
ili_dump_data(cmd, 8, core_mp.cdc_len, 0, "Mutual CDC command");
|
|
|
|
for (k = 0; k < rd_frame_num; k++) {
|
|
if (k == 0)
|
|
cmd_len = core_mp.cdc_len;
|
|
else
|
|
cmd_len = 0;
|
|
memset(ori, 0, len);
|
|
/* Get original frame(cdc) data */
|
|
if (ilits->wrapper(cmd, cmd_len, ori, len, ON, ON) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get cdc data\n", __func__);
|
|
ret = -EMP_GET_CDC;
|
|
goto out;
|
|
}
|
|
|
|
ili_dump_data(ori, 8, len, 0, "Mutual CDC original");
|
|
|
|
/* Convert original data to the physical one in each node */
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
/* H byte + L byte */
|
|
s32 tmp = (ori[(2 * i) + 1] << 8) + ori[(1 + (2 * i)) + 1];
|
|
|
|
if ((tmp & 0x8000) == 0x8000)
|
|
frm_buf[k][i] = tmp - 65536;
|
|
else
|
|
frm_buf[k][i] = tmp;
|
|
|
|
// multiple case frame3 = frame1 - frame2
|
|
if (tItems[index].bch_mrk_multi && rd_frame_num == k + 1)
|
|
frm_buf[k+1][i] = frm_buf[k-1][i] - frm_buf[k][i];
|
|
}
|
|
}
|
|
|
|
if (tItems[index].bch_mrk_multi) {
|
|
ili_dump_data(frm_buf[0], 32, core_mp.frame_len, core_mp.xch_len, "Mutual CDC combined[0]/frame1");
|
|
ili_dump_data(frm_buf[1], 32, core_mp.frame_len, core_mp.xch_len, "Mutual CDC combined[1]/frame2");
|
|
ili_dump_data(frm_buf[2], 32, core_mp.frame_len, core_mp.xch_len, "Mutual CDC combined[2]/frame3");
|
|
} else {
|
|
ili_dump_data(frm_buf[0], 32, core_mp.frame_len, core_mp.xch_len, "Mutual CDC combined[0]/frame1");
|
|
}
|
|
|
|
out:
|
|
ipio_kfree((void **)&ori);
|
|
return ret;
|
|
}
|
|
|
|
static int allnode_mutual_cdc_data(int index)
|
|
{
|
|
int i, ret = 0, len = 0;
|
|
int inDACp = 0, inDACn = 0;
|
|
u8 cmd[15] = {0};
|
|
u8 *ori = NULL;
|
|
|
|
/* Multipling by 2 is due to the 16 bit in each node */
|
|
len = (core_mp.frame_len * 2) + 2;
|
|
|
|
ILI_DBG("%s Read X/Y Channel length = %d\n", __func__, len);
|
|
|
|
if (len <= 2) {
|
|
input_err(true, ilits->dev, "%s Length is invalid\n", __func__);
|
|
ret = -EMP_INVAL;
|
|
goto out;
|
|
}
|
|
|
|
memset(cmd, 0xFF, sizeof(cmd));
|
|
|
|
/* CDC init */
|
|
if (mp_cdc_init_cmd_common(cmd, sizeof(cmd), index) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get cdc command\n", __func__);
|
|
ret = -EMP_CMD;
|
|
goto out;
|
|
}
|
|
|
|
ili_dump_data(cmd, 8, core_mp.cdc_len, 0, "Mutual CDC command");
|
|
|
|
/* Allocate a buffer for the original */
|
|
ori = kcalloc(len, sizeof(u8), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(ori)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate ori, (%ld)\n", __func__, PTR_ERR(ori));
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
/* Get original frame(cdc) data */
|
|
if (ilits->wrapper(cmd, core_mp.cdc_len, ori, len, ON, ON) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get cdc data\n", __func__);
|
|
ret = -EMP_GET_CDC;
|
|
goto out;
|
|
}
|
|
|
|
ili_dump_data(ori, 8, len, 0, "Mutual CDC original");
|
|
|
|
if (frame_buf == NULL) {
|
|
frame_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(frame_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate FrameBuffer mem (%ld)\n",
|
|
__func__, PTR_ERR(frame_buf));
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
} else {
|
|
memset(frame_buf, 0x0, core_mp.frame_len);
|
|
}
|
|
|
|
/* Convert original data to the physical one in each node */
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
if (ipio_strcmp(tItems[index].desp, "calibration data(dac)") == 0) {
|
|
/* DAC - P */
|
|
if (((ori[(2 * i) + 1] & 0x80) >> 7) == 1) {
|
|
/* Negative */
|
|
inDACp = 0 - (int)(ori[(2 * i) + 1] & 0x7F);
|
|
} else {
|
|
inDACp = ori[(2 * i) + 1] & 0x7F;
|
|
}
|
|
|
|
/* DAC - N */
|
|
if (((ori[(1 + (2 * i)) + 1] & 0x80) >> 7) == 1) {
|
|
/* Negative */
|
|
inDACn = 0 - (int)(ori[(1 + (2 * i)) + 1] & 0x7F);
|
|
} else {
|
|
inDACn = ori[(1 + (2 * i)) + 1] & 0x7F;
|
|
}
|
|
|
|
frame_buf[i] = (inDACp + inDACn) / 2;
|
|
} else {
|
|
/* H byte + L byte */
|
|
s32 tmp = (ori[(2 * i) + 1] << 8) + ori[(1 + (2 * i)) + 1];
|
|
|
|
if ((tmp & 0x8000) == 0x8000)
|
|
frame_buf[i] = tmp - 65536;
|
|
else
|
|
frame_buf[i] = tmp;
|
|
|
|
if (ipio_strcmp(tItems[index].desp, "raw data(no bk)") == 0 ||
|
|
ipio_strcmp(tItems[index].desp, "raw data(no bk) (lcm off)") == 0) {
|
|
frame_buf[i] -= core_mp.no_bk_shift;
|
|
}
|
|
}
|
|
}
|
|
|
|
ili_dump_data(frame_buf, 32, core_mp.frame_len, core_mp.xch_len, "Mutual CDC combined");
|
|
|
|
out:
|
|
ipio_kfree((void **)&ori);
|
|
return ret;
|
|
}
|
|
|
|
static void compare_MaxMin_result(int index, s32 *data)
|
|
{
|
|
int x, y;
|
|
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
int shift = y * core_mp.xch_len;
|
|
|
|
if (tItems[index].catalog == UNTOUCH_P2P)
|
|
return;
|
|
else if (tItems[index].catalog == TX_RX_DELTA) {
|
|
/* Tx max/min comparison */
|
|
if (core_mp.tx_delta_buf[shift + x] < data[shift + x])
|
|
core_mp.tx_max_buf[shift + x] = data[shift + x];
|
|
|
|
if (core_mp.tx_delta_buf[shift + x] > data[shift + x])
|
|
core_mp.tx_min_buf[shift + x] = data[shift + x];
|
|
|
|
/* Rx max/min comparison */
|
|
if (core_mp.rx_delta_buf[shift + x] < data[shift + x])
|
|
core_mp.rx_max_buf[shift + x] = data[shift + x];
|
|
|
|
if (core_mp.rx_delta_buf[shift + x] > data[shift + x])
|
|
core_mp.rx_min_buf[shift + x] = data[shift + x];
|
|
} else {
|
|
if (tItems[index].max_buf[shift + x] < data[shift + x])
|
|
tItems[index].max_buf[shift + x] = data[shift + x];
|
|
|
|
if (tItems[index].min_buf[shift + x] > data[shift + x])
|
|
tItems[index].min_buf[shift + x] = data[shift + x];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static int create_mp_test_frame_buffer(int index, int frame_count)
|
|
{
|
|
int i;
|
|
|
|
ILI_DBG("%s Create MP frame buffers (index = %d), count = %d\n",
|
|
__func__, index, frame_count);
|
|
|
|
if (tItems[index].catalog == TX_RX_DELTA) {
|
|
if (core_mp.tx_delta_buf == NULL) {
|
|
core_mp.tx_delta_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(core_mp.tx_delta_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate tx_delta_buf mem\n", __func__);
|
|
ipio_kfree((void **)&core_mp.tx_delta_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (core_mp.rx_delta_buf == NULL) {
|
|
core_mp.rx_delta_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(core_mp.rx_delta_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate rx_delta_buf mem\n", __func__);
|
|
ipio_kfree((void **)&core_mp.rx_delta_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (core_mp.tx_max_buf == NULL) {
|
|
core_mp.tx_max_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(core_mp.tx_max_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate tx_max_buf mem\n", __func__);
|
|
ipio_kfree((void **)&core_mp.tx_max_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (core_mp.tx_min_buf == NULL) {
|
|
core_mp.tx_min_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(core_mp.tx_min_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate tx_min_buf mem\n", __func__);
|
|
ipio_kfree((void **)&core_mp.tx_min_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (core_mp.rx_max_buf == NULL) {
|
|
core_mp.rx_max_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(core_mp.rx_max_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate rx_max_buf mem\n", __func__);
|
|
ipio_kfree((void **)&core_mp.rx_max_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (core_mp.rx_min_buf == NULL) {
|
|
core_mp.rx_min_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(core_mp.rx_min_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate rx_min_buf mem\n", __func__);
|
|
ipio_kfree((void **)&core_mp.rx_min_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
} else {
|
|
if (tItems[index].buf == NULL) {
|
|
tItems[index].buf = vmalloc(frame_count * core_mp.frame_len * sizeof(s32));
|
|
if (ERR_ALLOC_MEM(tItems[index].buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate buf mem\n", __func__);
|
|
ipio_kfree((void **)&tItems[index].buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (tItems[index].result_buf == NULL) {
|
|
tItems[index].result_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].result_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate result_buf mem\n", __func__);
|
|
ipio_kfree((void **)&tItems[index].result_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (tItems[index].max_buf == NULL) {
|
|
tItems[index].max_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].max_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate max_buf mem\n", __func__);
|
|
ipio_kfree((void **)&tItems[index].max_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (tItems[index].min_buf == NULL) {
|
|
tItems[index].min_buf = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].min_buf)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate min_buf mem\n", __func__);
|
|
ipio_kfree((void **)&tItems[index].min_buf);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
if (tItems[index].spec_option == BENCHMARK) {
|
|
if (tItems[index].bch_mrk_max == NULL) {
|
|
tItems[index].bch_mrk_max =
|
|
(s32 **)kzalloc(tItems[index].bch_mrk_frm_num * sizeof(s32 *), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].bch_mrk_max)) {
|
|
input_err(true, ilits->dev,
|
|
"%s Failed to allocate bch_mrk_max mem\n", __func__);
|
|
ipio_kfree((void **)&tItems[index].bch_mrk_max);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
for (i = 0; i < tItems[index].bch_mrk_frm_num; i++) {
|
|
tItems[index].bch_mrk_max[i] =
|
|
(s32 *)kzalloc(core_mp.frame_len * sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].bch_mrk_max[i])) {
|
|
input_err(true, ilits->dev,
|
|
"%s Failed to allocate bch_mrk_max[%d] mem\n", __func__, i);
|
|
ipio_kfree((void **)&tItems[index].bch_mrk_max[i]);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tItems[index].bch_mrk_min == NULL) {
|
|
tItems[index].bch_mrk_min =
|
|
(s32 **)kzalloc(tItems[index].bch_mrk_frm_num * sizeof(s32 *), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].bch_mrk_min)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate bch_mrk_min mem\n",
|
|
__func__);
|
|
ipio_kfree((void **)&tItems[index].bch_mrk_min);
|
|
return -ENOMEM;
|
|
}
|
|
for (i = 0; i < tItems[index].bch_mrk_frm_num; i++) {
|
|
tItems[index].bch_mrk_min[i] =
|
|
(s32 *)kzalloc(core_mp.frame_len * sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].bch_mrk_min[i])) {
|
|
input_err(true, ilits->dev,
|
|
"%s Failed to allocate bch_mrk_min[%d] mem\n", __func__, i);
|
|
ipio_kfree((void **)&tItems[index].bch_mrk_min[i]);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tItems[index].bench_mark_max == NULL) {
|
|
tItems[index].bench_mark_max = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].bench_mark_max)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate bench_mark_max mem\n",
|
|
__func__);
|
|
ipio_kfree((void **)&tItems[index].bench_mark_max);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
if (tItems[index].bench_mark_min == NULL) {
|
|
tItems[index].bench_mark_min = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].bench_mark_min)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate bench_mark_min mem\n",
|
|
__func__);
|
|
ipio_kfree((void **)&tItems[index].bench_mark_min);
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int pin_test(int index)
|
|
{
|
|
int ret = 0;
|
|
u8 cmd[5] = {0};
|
|
|
|
input_info(true, ilits->dev, "%s PIN test start", __func__);
|
|
input_info(true, ilits->dev, "%s test_int_pin = 0x%x\n", __func__, tItems[index].test_int_pin);
|
|
input_info(true, ilits->dev, "%s int_pulse_test = 0x%x\n", __func__, tItems[index].int_pulse_test);
|
|
input_info(true, ilits->dev, "%s delay_time = 0x%x\n", __func__, tItems[index].delay_time);
|
|
|
|
if (tItems[index].test_int_pin == ENABLE) {
|
|
/* test HIGH level*/
|
|
cmd[0] = tItems[index].cmd;
|
|
cmd[1] = 0x1;
|
|
ret = ilits->wrapper(cmd, 2, NULL, 0, OFF, OFF);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Write command failed\n", __func__);
|
|
ret = -EMP_CMD;
|
|
goto out;
|
|
}
|
|
|
|
ret = ilits->detect_int_stat(false);
|
|
if (ret < 0) {
|
|
ret = -EMP_INT;
|
|
goto out;
|
|
}
|
|
|
|
/* test LOW level*/
|
|
cmd[1] = 0x0;
|
|
ret = ilits->wrapper(cmd, 2, NULL, 0, OFF, OFF);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Write command failed\n", __func__);
|
|
ret = -EMP_CMD;
|
|
goto out;
|
|
}
|
|
|
|
ret = ilits->detect_int_stat(false);
|
|
if (ret < 0) {
|
|
ret = -EMP_INT;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (tItems[index].int_pulse_test == ENABLE) {
|
|
|
|
input_info(true, ilits->dev, "%s MP IRQ Rising Trigger Test\n", __func__);
|
|
cmd[1] = 0x2;
|
|
cmd[2] = tItems[index].delay_time;
|
|
|
|
ili_irq_unregister();
|
|
ret = ili_irq_register(IRQF_TRIGGER_RISING);
|
|
if (ret < 0) {
|
|
ret = -EMP_INT;
|
|
goto out;
|
|
}
|
|
|
|
atomic_set(&ilits->cmd_int_check, ENABLE);
|
|
ret = ilits->wrapper(cmd, 3, NULL, 0, OFF, OFF);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Write command failed\n", __func__);
|
|
ret = -EMP_CMD;
|
|
goto out;
|
|
}
|
|
|
|
ret = ilits->detect_int_stat(false);
|
|
if (ret < 0) {
|
|
ret = -EMP_INT;
|
|
goto out;
|
|
}
|
|
|
|
input_info(true, ilits->dev, "%s MP IRQ Falling Trigger Test\n", __func__);
|
|
ili_irq_unregister();
|
|
ret = ili_irq_register(IRQF_TRIGGER_FALLING);
|
|
if (ret < 0) {
|
|
ret = -EMP_INT;
|
|
goto out;
|
|
}
|
|
|
|
atomic_set(&ilits->cmd_int_check, ENABLE);
|
|
|
|
ret = ilits->wrapper(cmd, 3, NULL, 0, OFF, OFF);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Write command failed\n", __func__);
|
|
ret = -EMP_CMD;
|
|
goto out;
|
|
}
|
|
|
|
ret = ilits->detect_int_stat(false);
|
|
if (ret < 0) {
|
|
ret = -EMP_INT;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
tItems[index].item_result = MP_DATA_PASS;
|
|
|
|
out:
|
|
if (ret < 0)
|
|
tItems[index].item_result = MP_DATA_FAIL;
|
|
|
|
input_info(true, ilits->dev, "%s Change to defualt IRQ trigger type\n", __func__);
|
|
ili_irq_unregister();
|
|
ili_irq_register(ilits->irq_tirgger_type);
|
|
atomic_set(&ilits->cmd_int_check, DISABLE);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int mutual_test(int index)
|
|
{
|
|
int i = 0, j = 0, x = 0, y = 0, ret = 0, get_frame_cont = 1;
|
|
|
|
ILI_DBG("%s index = %d, desp = %s, Frame Count = %d\n",
|
|
__func__, index, tItems[index].desp, tItems[index].frame_count);
|
|
|
|
/*
|
|
* We assume that users who are calling the test forget to config frame count
|
|
* as 1, so we just help them to set it up.
|
|
*/
|
|
if (tItems[index].frame_count <= 0) {
|
|
input_err(true, ilits->dev, "%s Frame count is zero, which is at least set as 1\n", __func__);
|
|
tItems[index].frame_count = 1;
|
|
}
|
|
|
|
ret = create_mp_test_frame_buffer(index, tItems[index].frame_count);
|
|
if (ret < 0) {
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
/* Init Max/Min buffer */
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
if (tItems[i].catalog == TX_RX_DELTA) {
|
|
core_mp.tx_max_buf[y * core_mp.xch_len + x] = INT_MIN;
|
|
core_mp.rx_max_buf[y * core_mp.xch_len + x] = INT_MIN;
|
|
core_mp.tx_min_buf[y * core_mp.xch_len + x] = INT_MAX;
|
|
core_mp.rx_min_buf[y * core_mp.xch_len + x] = INT_MAX;
|
|
} else {
|
|
tItems[index].max_buf[y * core_mp.xch_len + x] = INT_MIN;
|
|
tItems[index].min_buf[y * core_mp.xch_len + x] = INT_MAX;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tItems[index].catalog != PEAK_TO_PEAK_TEST)
|
|
get_frame_cont = tItems[index].frame_count;
|
|
|
|
if (tItems[index].spec_option == BENCHMARK) {
|
|
parser_ini_benchmark(tItems[index].bench_mark_max, tItems[index].bench_mark_min,
|
|
tItems[index].type_option, tItems[index].desp, core_mp.frame_len, BENCHMARK_KEY_NAME);
|
|
dump_benchmark_data(tItems[index].bench_mark_max, tItems[index].bench_mark_min);
|
|
}
|
|
|
|
for (i = 0; i < get_frame_cont; i++) {
|
|
ret = allnode_mutual_cdc_data(index);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to initialise CDC data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
switch (tItems[index].catalog) {
|
|
case PIXEL:
|
|
run_pixel_test(index);
|
|
break;
|
|
case UNTOUCH_P2P:
|
|
run_untouch_p2p_test(index);
|
|
break;
|
|
case OPEN_TEST:
|
|
run_open_test(index);
|
|
break;
|
|
case TX_RX_DELTA:
|
|
run_tx_rx_delta_test(index);
|
|
break;
|
|
case SHORT_TEST:
|
|
ret = short_test(index, i);
|
|
if (ret < 0) {
|
|
ret = -EMP_PARA_NULL;
|
|
goto out;
|
|
}
|
|
break;
|
|
default:
|
|
for (j = 0; j < core_mp.frame_len; j++)
|
|
tItems[index].buf[i * core_mp.frame_len + j] = frame_buf[j];
|
|
break;
|
|
}
|
|
compare_MaxMin_result(index, &tItems[index].buf[i * core_mp.frame_len]);
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int peak_to_peak_test(int index)
|
|
{
|
|
int i = 0, j = 0, x = 0, y = 0, ret = 0;
|
|
char benchmark_str[128] = {0};
|
|
|
|
ILI_DBG("%s index = %d, desp = %s bch_mrk_frm_num = %d\n",
|
|
__func__, index, tItems[index].desp, tItems[index].bch_mrk_frm_num);
|
|
|
|
ret = create_mp_test_frame_buffer(index, tItems[index].bch_mrk_frm_num);
|
|
if (ret < 0) {
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
if (tItems[index].spec_option == BENCHMARK) {
|
|
for (i = 0 ; i < tItems[index].bch_mrk_frm_num ; i++) {
|
|
if (tItems[index].bch_mrk_multi)
|
|
snprintf(benchmark_str, sizeof(benchmark_str), "%s%d", BENCHMARK_KEY_NAME, i+1);
|
|
else
|
|
snprintf(benchmark_str, sizeof(benchmark_str), "%s", BENCHMARK_KEY_NAME);
|
|
parser_ini_benchmark(tItems[index].bch_mrk_max[i], tItems[index].bch_mrk_min[i],
|
|
tItems[index].type_option, tItems[index].desp, core_mp.frame_len, benchmark_str);
|
|
|
|
dump_benchmark_data(tItems[index].bch_mrk_max[i], tItems[index].bch_mrk_min[i]);
|
|
}
|
|
}
|
|
|
|
/* Init Max/Min buffer */
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
tItems[index].max_buf[y * core_mp.xch_len + x] = INT_MIN;
|
|
tItems[index].min_buf[y * core_mp.xch_len + x] = INT_MAX;
|
|
}
|
|
}
|
|
|
|
ret = allnode_peak_to_peak_cdc_data(index);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to initialise CDC data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
for (i = 0; i < tItems[index].bch_mrk_frm_num; i++) {
|
|
for (j = 0; j < core_mp.frame_len; j++)
|
|
tItems[index].buf[i * core_mp.frame_len + j] = frm_buf[i][j];
|
|
|
|
compare_MaxMin_result(index, &tItems[index].buf[i * core_mp.frame_len]);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
|
|
static int open_test_sp(int index)
|
|
{
|
|
struct mp_test_P540_open *open;
|
|
int i = 0, x = 0, y = 0, ret = 0, addr = 0;
|
|
int Charge_AA = 0, Charge_Border = 0, Charge_Notch = 0, full_open_rate = 0;
|
|
char str[512] = {0};
|
|
|
|
ILI_DBG("%s index = %d, desp = %s, Frame Count = %d\n",
|
|
__func__, index, tItems[index].desp, tItems[index].frame_count);
|
|
|
|
/*
|
|
* We assume that users who are calling the test forget to config frame count
|
|
* as 1, so we just help them to set it up.
|
|
*/
|
|
if (tItems[index].frame_count <= 0) {
|
|
input_err(true, ilits->dev, "%s Frame count is zero, which is at least set as 1\n", __func__);
|
|
tItems[index].frame_count = 1;
|
|
}
|
|
|
|
open = kzalloc(tItems[index].frame_count * sizeof(struct mp_test_P540_open), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(open)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate open mem (%ld)\n", __func__, PTR_ERR(open));
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
ret = create_mp_test_frame_buffer(index, tItems[index].frame_count);
|
|
if (ret < 0) {
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
if (frame1_cbk700 == NULL) {
|
|
frame1_cbk700 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(frame1_cbk700)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate frame1_cbk700 buffer\n", __func__);
|
|
return -EMP_NOMEM;
|
|
}
|
|
} else {
|
|
memset(frame1_cbk700, 0x0, core_mp.frame_len);
|
|
}
|
|
|
|
if (frame1_cbk250 == NULL) {
|
|
frame1_cbk250 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(frame1_cbk250)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate frame1_cbk250 buffer\n", __func__);
|
|
ipio_kfree((void **)&frame1_cbk700);
|
|
return -EMP_NOMEM;
|
|
}
|
|
} else {
|
|
memset(frame1_cbk250, 0x0, core_mp.frame_len);
|
|
}
|
|
|
|
if (frame1_cbk200 == NULL) {
|
|
frame1_cbk200 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(frame1_cbk200)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate cbk buffer\n", __func__);
|
|
ipio_kfree((void **)&frame1_cbk700);
|
|
ipio_kfree((void **)&frame1_cbk250);
|
|
return -EMP_NOMEM;
|
|
}
|
|
} else {
|
|
memset(frame1_cbk200, 0x0, core_mp.frame_len);
|
|
}
|
|
|
|
tItems[index].node_type = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(tItems[index].node_type)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate node_type FRAME buffer\n", __func__);
|
|
return -EMP_NOMEM;
|
|
}
|
|
|
|
/* Init Max/Min buffer */
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
tItems[index].max_buf[y * core_mp.xch_len + x] = INT_MIN;
|
|
tItems[index].min_buf[y * core_mp.xch_len + x] = INT_MAX;
|
|
}
|
|
}
|
|
|
|
if (tItems[index].spec_option == BENCHMARK) {
|
|
parser_ini_benchmark(tItems[index].bench_mark_max, tItems[index].bench_mark_min,
|
|
tItems[index].type_option, tItems[index].desp, core_mp.frame_len, BENCHMARK_KEY_NAME);
|
|
dump_benchmark_data(tItems[index].bench_mark_max, tItems[index].bench_mark_min);
|
|
}
|
|
|
|
parser_ini_nodetype(tItems[index].node_type, NODE_TYPE_KEY_NAME, core_mp.frame_len);
|
|
dump_node_type_buffer(tItems[index].node_type, "node type");
|
|
|
|
parser_get_int_data(tItems[index].desp, "charge_aa", str, sizeof(str));
|
|
Charge_AA = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "charge_border", str, sizeof(str));
|
|
Charge_Border = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "charge_notch", str, sizeof(str));
|
|
Charge_Notch = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "full open", str, sizeof(str));
|
|
full_open_rate = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "tvch", str, sizeof(str));
|
|
open_para.tvch = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "tvcl", str, sizeof(str));
|
|
open_para.tvcl = ili_katoi(str);
|
|
|
|
ILI_DBG("%s AA = %d, Border = %d, Notch = %d, full_open_rate = %d, tvch = %d, tvcl = %d\n",
|
|
__func__, Charge_AA, Charge_Border, Charge_Notch, full_open_rate,
|
|
open_para.tvch, open_para.tvcl);
|
|
|
|
for (i = 0; i < tItems[index].frame_count; i++) {
|
|
open[i].tdf_700 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].tdf_250 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].tdf_200 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].cbk_700 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].cbk_250 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].cbk_200 = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].charg_rate = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].full_Open = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].dac = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
}
|
|
|
|
for (i = 0; i < tItems[index].frame_count; i++) {
|
|
ret = allnode_open_cdc_data(0, open[i].dac);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get Open SP DAC data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
ret = allnode_open_cdc_data(1, open[i].tdf_700);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get Open SP Raw1 data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
ret = allnode_open_cdc_data(2, open[i].tdf_250);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get Open SP Raw2 data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
ret = allnode_open_cdc_data(3, open[i].tdf_200);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get Open SP Raw3 data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
allnode_open_cdc_result(index, open[i].cbk_700, open[i].dac, open[i].tdf_700);
|
|
allnode_open_cdc_result(index, open[i].cbk_250, open[i].dac, open[i].tdf_250);
|
|
allnode_open_cdc_result(index, open[i].cbk_200, open[i].dac, open[i].tdf_200);
|
|
|
|
addr = 0;
|
|
|
|
/* record fist frame for debug */
|
|
if (i == 0) {
|
|
ipio_memcpy(frame1_cbk700, open[i].cbk_700, core_mp.frame_len * sizeof(s32),
|
|
core_mp.frame_len * sizeof(s32));
|
|
ipio_memcpy(frame1_cbk250, open[i].cbk_250, core_mp.frame_len * sizeof(s32),
|
|
core_mp.frame_len * sizeof(s32));
|
|
ipio_memcpy(frame1_cbk200, open[i].cbk_200, core_mp.frame_len * sizeof(s32),
|
|
core_mp.frame_len * sizeof(s32));
|
|
}
|
|
|
|
ili_dump_data(open[i].cbk_700, 10, core_mp.frame_len, core_mp.xch_len, "cbk 700");
|
|
ili_dump_data(open[i].cbk_250, 10, core_mp.frame_len, core_mp.xch_len, "cbk 250");
|
|
ili_dump_data(open[i].cbk_200, 10, core_mp.frame_len, core_mp.xch_len, "cbk 200");
|
|
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
open[i].charg_rate[addr] = open[i].cbk_250[addr] * 100 / open[i].cbk_700[addr];
|
|
open[i].full_Open[addr] = open[i].cbk_700[addr] - open[i].cbk_200[addr];
|
|
addr++;
|
|
}
|
|
}
|
|
|
|
ili_dump_data(open[i].charg_rate, 10, core_mp.frame_len, core_mp.xch_len, "origin charge rate");
|
|
ili_dump_data(open[i].full_Open, 10, core_mp.frame_len, core_mp.xch_len, "origin full open");
|
|
|
|
addr = 0;
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
if (full_open_rate_compare(open[i].full_Open, open[i].cbk_700, x, y,
|
|
tItems[index].node_type[addr], full_open_rate) == false) {
|
|
tItems[index].buf[(i * core_mp.frame_len) + addr] = 0;
|
|
open[i].charg_rate[addr] = 0;
|
|
}
|
|
addr++;
|
|
}
|
|
}
|
|
|
|
ili_dump_data(&tItems[index].buf[(i * core_mp.frame_len)], 10, core_mp.frame_len, core_mp.xch_len,
|
|
"after full_open_rate_compare");
|
|
|
|
addr = 0;
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
tItems[index].buf[(i * core_mp.frame_len) + addr] =
|
|
compare_charge(open[i].charg_rate, x, y, tItems[index].node_type,
|
|
Charge_AA, Charge_Border, Charge_Notch);
|
|
addr++;
|
|
}
|
|
}
|
|
|
|
ili_dump_data(&tItems[index].buf[(i * core_mp.frame_len)], 10, core_mp.frame_len, core_mp.xch_len,
|
|
"after compare charge rate");
|
|
|
|
compare_MaxMin_result(index, &tItems[index].buf[(i * core_mp.frame_len)]);
|
|
}
|
|
|
|
out:
|
|
ipio_kfree((void **)&tItems[index].node_type);
|
|
|
|
if (open != NULL) {
|
|
for (i = 0; i < tItems[index].frame_count; i++) {
|
|
ipio_kfree((void **)&open[i].tdf_700);
|
|
ipio_kfree((void **)&open[i].tdf_250);
|
|
ipio_kfree((void **)&open[i].tdf_200);
|
|
ipio_kfree((void **)&open[i].cbk_700);
|
|
ipio_kfree((void **)&open[i].cbk_250);
|
|
ipio_kfree((void **)&open[i].cbk_200);
|
|
ipio_kfree((void **)&open[i].charg_rate);
|
|
ipio_kfree((void **)&open[i].full_Open);
|
|
ipio_kfree((void **)&open[i].dac);
|
|
}
|
|
kfree(open);
|
|
open = NULL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int open_test_cap(int index)
|
|
{
|
|
u32 pid = core_mp.chip_pid >> 8;
|
|
struct mp_test_open_c *open;
|
|
int i = 0, x = 0, y = 0, ret = 0, addr = 0;
|
|
char str[512] = {0};
|
|
|
|
ILI_DBG("%s index = %d, desp = %s, Frame Count = %d\n",
|
|
__func__, index, tItems[index].desp, tItems[index].frame_count);
|
|
|
|
if (tItems[index].frame_count <= 0) {
|
|
input_err(true, ilits->dev, "%s Frame count is zero, which is at least set as 1\n", __func__);
|
|
tItems[index].frame_count = 1;
|
|
}
|
|
|
|
open = kzalloc(tItems[index].frame_count * sizeof(struct mp_test_open_c), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(open)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate open mem (%ld)\n", __func__, PTR_ERR(open));
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
if (create_mp_test_frame_buffer(index, tItems[index].frame_count) < 0) {
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
if (cap_dac == NULL) {
|
|
cap_dac = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(cap_dac)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate cap_dac buffer\n", __func__);
|
|
return -EMP_NOMEM;
|
|
}
|
|
} else {
|
|
memset(cap_dac, 0x0, core_mp.frame_len);
|
|
}
|
|
|
|
if (cap_raw == NULL) {
|
|
cap_raw = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(cap_raw)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate cap_raw buffer\n", __func__);
|
|
ipio_kfree((void **)&cap_dac);
|
|
return -EMP_NOMEM;
|
|
}
|
|
} else {
|
|
memset(cap_raw, 0x0, core_mp.frame_len);
|
|
}
|
|
|
|
/* Init Max/Min buffer */
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
tItems[index].max_buf[y * core_mp.xch_len + x] = INT_MIN;
|
|
tItems[index].min_buf[y * core_mp.xch_len + x] = INT_MAX;
|
|
}
|
|
}
|
|
|
|
if (tItems[index].spec_option == BENCHMARK) {
|
|
parser_ini_benchmark(tItems[index].bench_mark_max, tItems[index].bench_mark_min,
|
|
tItems[index].type_option, tItems[index].desp, core_mp.frame_len, BENCHMARK_KEY_NAME);
|
|
dump_benchmark_data(tItems[index].bench_mark_max, tItems[index].bench_mark_min);
|
|
}
|
|
|
|
parser_get_int_data(tItems[index].desp, "gain", str, sizeof(str));
|
|
open_para.gain = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "tvch", str, sizeof(str));
|
|
open_para.tvch = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "tvcl", str, sizeof(str));
|
|
open_para.tvcl = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "cbk_step", str, sizeof(str));
|
|
open_para.cbk_step = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[index].desp, "cint", str, sizeof(str));
|
|
open_para.cint = ili_katoi(str);
|
|
|
|
/* 9881N, 9881O, 7807Q, 7807S not support cbk_step and cint read from mp.ini */
|
|
if ((pid != 0x988117) && (pid != 0x988118) && (pid != 0x78071A) && (pid != 0x78071C)) {
|
|
if ((open_para.cbk_step == 0) || (open_para.cint == 0)) {
|
|
input_err(true, ilits->dev, "%s Failed to get open parameter", __func__);
|
|
ret = -EMP_PARA_NULL;
|
|
core_mp.lost_parameter = true;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
input_info(true, ilits->dev, "%s gain = %d, tvch = %d, tvcl = %d, cbk_step = %d, cint = %d\n",
|
|
__func__, open_para.gain, open_para.tvch, open_para.tvcl, open_para.cbk_step, open_para.cint);
|
|
for (i = 0; i < tItems[index].frame_count; i++) {
|
|
open[i].cap_dac = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].cap_raw = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
open[i].dcl_cap = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
}
|
|
|
|
for (i = 0; i < tItems[index].frame_count; i++) {
|
|
ret = allnode_open_cdc_data(4, open[i].cap_dac);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get Open CAP DAC data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
ret = allnode_open_cdc_data(5, open[i].cap_raw);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get Open CAP RAW data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
allnode_open_cdc_result(index, open[i].dcl_cap, open[i].cap_dac, open[i].cap_raw);
|
|
|
|
/* record fist frame for debug */
|
|
if (i == 0) {
|
|
ipio_memcpy(cap_dac, open[i].cap_dac, core_mp.frame_len * sizeof(s32),
|
|
core_mp.frame_len * sizeof(s32));
|
|
ipio_memcpy(cap_raw, open[i].cap_raw, core_mp.frame_len * sizeof(s32),
|
|
core_mp.frame_len * sizeof(s32));
|
|
}
|
|
|
|
ili_dump_data(open[i].dcl_cap, 10, core_mp.frame_len, core_mp.xch_len, "DCL_Cap");
|
|
|
|
addr = 0;
|
|
for (y = 0; y < core_mp.ych_len; y++) {
|
|
for (x = 0; x < core_mp.xch_len; x++) {
|
|
tItems[index].buf[(i * core_mp.frame_len) + addr] = open[i].dcl_cap[addr];
|
|
addr++;
|
|
}
|
|
}
|
|
compare_MaxMin_result(index, &tItems[index].buf[i * core_mp.frame_len]);
|
|
}
|
|
|
|
out:
|
|
if (open != NULL) {
|
|
for (i = 0; i < tItems[index].frame_count; i++) {
|
|
ipio_kfree((void **)&open[i].cap_dac);
|
|
ipio_kfree((void **)&open[i].cap_raw);
|
|
ipio_kfree((void **)&open[i].dcl_cap);
|
|
}
|
|
kfree(open);
|
|
open = NULL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int key_test(int index)
|
|
{
|
|
int i, j = 0, ret = 0;
|
|
|
|
ILI_DBG("%s Item = %s, Frame Count = %d\n",
|
|
__func__, tItems[index].desp, tItems[index].frame_count);
|
|
|
|
if (tItems[index].frame_count == 0) {
|
|
input_err(true, ilits->dev, "%s Frame count is zero, which at least sets as 1\n", __func__);
|
|
ret = -EINVAL;
|
|
goto out;
|
|
}
|
|
|
|
ret = create_mp_test_frame_buffer(index, tItems[index].frame_count);
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
for (i = 0; i < tItems[index].frame_count; i++) {
|
|
ret = allnode_key_cdc_data(index);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to initialise CDC data, %d\n", __func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
for (j = 0; j < core_mp.key_len; j++)
|
|
tItems[index].buf[j] = key_buf[j];
|
|
}
|
|
|
|
compare_MaxMin_result(index, tItems[index].buf);
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int self_test(int index)
|
|
{
|
|
input_err(true, ilits->dev, "%s TDDI has no self to be tested currently\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
static int st_test(int index)
|
|
{
|
|
input_err(true, ilits->dev, "%s ST Test is not supported by the driver\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
static int mp_get_timing_info(void)
|
|
{
|
|
int slen = 0;
|
|
char str[256] = {0};
|
|
u8 info[64] = {0};
|
|
char *key = "timing_info_raw";
|
|
|
|
core_mp.isLongV = 0;
|
|
|
|
slen = parser_get_int_data("pv5_4 command", key, str, sizeof(str));
|
|
if (slen < 0)
|
|
return -1;
|
|
|
|
if (parser_get_u8_array(str, info, 16, slen) < 0)
|
|
return -1;
|
|
|
|
core_mp.isLongV = info[6];
|
|
|
|
input_info(true, ilits->dev, "%s DDI Mode = %s\n", __func__, (core_mp.isLongV ? "Long V" : "Long H"));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mp_test_data_sort_average(s32 *oringin_data, int index, s32 *avg_result)
|
|
{
|
|
int i, j, k, x, y, len = 5, size;
|
|
s32 u32temp;
|
|
int u32up_frame, u32down_frame;
|
|
s32 *u32sum_raw_data = NULL;
|
|
s32 *u32data_buff = NULL;
|
|
int ret = 0;
|
|
|
|
if (tItems[index].frame_count <= 1) {
|
|
ret = 0;
|
|
goto out;
|
|
}
|
|
|
|
if (ERR_ALLOC_MEM(oringin_data)) {
|
|
input_err(true, ilits->dev, "%s Input wrong address\n", __func__);
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
|
|
u32data_buff = kcalloc(core_mp.frame_len * tItems[index].frame_count, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(u32data_buff)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate u32data_buff FRAME buffer\n", __func__);
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
|
|
u32sum_raw_data = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(u32data_buff)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate u32sum_raw_data FRAME buffer\n", __func__);
|
|
ret = -ENOMEM;
|
|
goto out;
|
|
}
|
|
|
|
size = core_mp.frame_len * tItems[index].frame_count;
|
|
for (i = 0; i < size; i++)
|
|
u32data_buff[i] = oringin_data[i];
|
|
|
|
u32up_frame = tItems[index].frame_count * tItems[index].highest_percentage / 100;
|
|
u32down_frame = tItems[index].frame_count * tItems[index].lowest_percentage / 100;
|
|
ILI_DBG("%s Up=%d, Down=%d -%s\n", __func__, u32up_frame, u32down_frame, tItems[index].desp);
|
|
|
|
if (debug_en) {
|
|
pr_cont("\n[Show Original frist%d and last%d node data]\n", len, len);
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
for (j = 0 ; j < tItems[index].frame_count ; j++) {
|
|
if ((i < len) || (i >= (core_mp.frame_len-len)))
|
|
pr_cont("%d,", u32data_buff[j * core_mp.frame_len + i]);
|
|
}
|
|
if ((i < len) || (i >= (core_mp.frame_len-len)))
|
|
pr_cont("\n");
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
for (j = 0; j < tItems[index].frame_count-1; j++) {
|
|
for (k = 0; k < (tItems[index].frame_count-1-j); k++) {
|
|
x = i+k*core_mp.frame_len;
|
|
y = i+(k+1)*core_mp.frame_len;
|
|
if (*(u32data_buff+x) > *(u32data_buff+y)) {
|
|
u32temp = *(u32data_buff+x);
|
|
*(u32data_buff+x) = *(u32data_buff+y);
|
|
*(u32data_buff+y) = u32temp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (debug_en) {
|
|
pr_cont("\n[After sorting frist%d and last%d node data]\n", len, len);
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
for (j = u32down_frame; j < tItems[index].frame_count - u32up_frame; j++) {
|
|
if ((i < len) || (i >= (core_mp.frame_len - len)))
|
|
pr_cont("%d,", u32data_buff[i + j * core_mp.frame_len]);
|
|
}
|
|
if ((i < len) || (i >= (core_mp.frame_len-len)))
|
|
pr_cont("\n");
|
|
}
|
|
}
|
|
|
|
for (i = 0 ; i < core_mp.frame_len ; i++) {
|
|
u32sum_raw_data[i] = 0;
|
|
for (j = u32down_frame; j < tItems[index].frame_count - u32up_frame; j++)
|
|
u32sum_raw_data[i] += u32data_buff[i + j * core_mp.frame_len];
|
|
|
|
avg_result[i] = u32sum_raw_data[i] / (tItems[index].frame_count - u32down_frame - u32up_frame);
|
|
}
|
|
|
|
if (debug_en) {
|
|
pr_cont("\n[Average result frist%d and last%d node data]\n", len, len);
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
if ((i < len) || (i >= (core_mp.frame_len-len)))
|
|
pr_cont("%d,", avg_result[i]);
|
|
}
|
|
if ((i < len) || (i >= (core_mp.frame_len-len)))
|
|
pr_cont("\n");
|
|
}
|
|
|
|
out:
|
|
ipio_kfree((void **)&u32data_buff);
|
|
ipio_kfree((void **)&u32sum_raw_data);
|
|
return ret;
|
|
}
|
|
|
|
static void mp_compare_cdc_result(int index, s32 *tmp, s32 *max_ts, s32 *min_ts, int *result)
|
|
{
|
|
int i;
|
|
|
|
if (ERR_ALLOC_MEM(tmp)) {
|
|
input_err(true, ilits->dev, "%s The data of test item is null (%p)\n", __func__, tmp);
|
|
*result = MP_DATA_FAIL;
|
|
return;
|
|
}
|
|
|
|
if (tItems[index].catalog == SHORT_TEST) {
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
if (tmp[i] < min_ts[i]) {
|
|
*result = MP_DATA_FAIL;
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
if (tmp[i] > max_ts[i] || tmp[i] < min_ts[i]) {
|
|
ILI_DBG("%s Fail No.%d: max=%d, val=%d, min=%d\n",
|
|
__func__, i, max_ts[i], tmp[i], min_ts[i]);
|
|
*result = MP_DATA_FAIL;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static int mp_compare_test_result(int index)
|
|
{
|
|
int i, test_result = MP_DATA_PASS;
|
|
s32 *max_threshold = NULL, *min_threshold = NULL;
|
|
|
|
if (tItems[index].catalog == PIN_TEST)
|
|
return tItems[index].item_result;
|
|
|
|
max_threshold = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(max_threshold)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate threshold FRAME buffer\n", __func__);
|
|
test_result = MP_DATA_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
min_threshold = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(min_threshold)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate threshold FRAME buffer\n", __func__);
|
|
test_result = MP_DATA_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
/* Show test result as below */
|
|
if (tItems[index].catalog == TX_RX_DELTA) {
|
|
if (ERR_ALLOC_MEM(core_mp.rx_delta_buf) || ERR_ALLOC_MEM(core_mp.tx_delta_buf)) {
|
|
input_err(true, ilits->dev, "%s This test item (%s) has no data inside its buffer\n",
|
|
__func__, tItems[index].desp);
|
|
test_result = MP_DATA_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
max_threshold[i] = core_mp.TxDeltaMax;
|
|
min_threshold[i] = core_mp.TxDeltaMin;
|
|
}
|
|
mp_compare_cdc_result(index, core_mp.tx_max_buf, max_threshold, min_threshold, &test_result);
|
|
mp_compare_cdc_result(index, core_mp.tx_min_buf, max_threshold, min_threshold, &test_result);
|
|
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
max_threshold[i] = core_mp.RxDeltaMax;
|
|
min_threshold[i] = core_mp.RxDeltaMin;
|
|
}
|
|
|
|
mp_compare_cdc_result(index, core_mp.rx_max_buf, max_threshold, min_threshold, &test_result);
|
|
mp_compare_cdc_result(index, core_mp.rx_min_buf, max_threshold, min_threshold, &test_result);
|
|
} else {
|
|
if (ERR_ALLOC_MEM(tItems[index].buf) || ERR_ALLOC_MEM(tItems[index].max_buf) ||
|
|
ERR_ALLOC_MEM(tItems[index].min_buf) || ERR_ALLOC_MEM(tItems[index].result_buf)) {
|
|
input_err(true, ilits->dev, "%s This test item (%s) has no data inside its buffer\n",
|
|
__func__, tItems[index].desp);
|
|
test_result = MP_DATA_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
if (tItems[index].spec_option == BENCHMARK) {
|
|
if (tItems[index].catalog == PEAK_TO_PEAK_TEST) {
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
max_threshold[i] = tItems[index].bch_mrk_max[0][i];
|
|
min_threshold[i] = tItems[index].bch_mrk_min[0][i];
|
|
}
|
|
} else {
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
max_threshold[i] = tItems[index].bench_mark_max[i];
|
|
min_threshold[i] = tItems[index].bench_mark_min[i];
|
|
}
|
|
}
|
|
} else {
|
|
for (i = 0; i < core_mp.frame_len; i++) {
|
|
max_threshold[i] = tItems[index].max;
|
|
min_threshold[i] = tItems[index].min;
|
|
}
|
|
}
|
|
|
|
/* general result */
|
|
if (tItems[index].trimmed_mean && tItems[index].catalog != PEAK_TO_PEAK_TEST) {
|
|
mp_test_data_sort_average(tItems[index].buf, index, tItems[index].result_buf);
|
|
mp_compare_cdc_result(index, tItems[index].result_buf, max_threshold, min_threshold,
|
|
&test_result);
|
|
} else {
|
|
if (tItems[index].bch_mrk_multi) {
|
|
for (i = 0; i < tItems[index].bch_mrk_frm_num; i++) {
|
|
mp_compare_cdc_result(index, frm_buf[i], tItems[index].bch_mrk_max[i],
|
|
tItems[index].bch_mrk_min[i], &test_result);
|
|
}
|
|
} else {
|
|
mp_compare_cdc_result(index, tItems[index].max_buf, max_threshold, min_threshold,
|
|
&test_result);
|
|
mp_compare_cdc_result(index, tItems[index].min_buf, max_threshold, min_threshold,
|
|
&test_result);
|
|
}
|
|
}
|
|
}
|
|
|
|
out:
|
|
ipio_kfree((void **)&max_threshold);
|
|
ipio_kfree((void **)&min_threshold);
|
|
if (frm_buf != NULL) {
|
|
for (i = 0; i < tItems[index].bch_mrk_frm_num; i++)
|
|
if (frm_buf[i] != NULL) {
|
|
kfree(frm_buf[i]);
|
|
frm_buf[i] = NULL;
|
|
}
|
|
kfree(frm_buf);
|
|
frm_buf = NULL;
|
|
}
|
|
if (core_mp.all_pass == true)
|
|
test_result = MP_DATA_PASS;
|
|
tItems[index].item_result = test_result;
|
|
return test_result;
|
|
}
|
|
|
|
static void mp_do_retry(int index, int count)
|
|
{
|
|
if (count == 0) {
|
|
input_info(true, ilits->dev, "%s Finish retry action\n", __func__);
|
|
return;
|
|
}
|
|
|
|
input_info(true, ilits->dev, "%s retry = %d, item = %s\n", __func__, count, tItems[index].desp);
|
|
|
|
tItems[index].do_test(index);
|
|
|
|
if (mp_compare_test_result(index) < 0)
|
|
return mp_do_retry(index, count - 1);
|
|
}
|
|
|
|
static int mp_show_result(bool lcm_on)
|
|
{
|
|
int ret = MP_DATA_PASS, seq;
|
|
int i, x, y, j, k = 0, csv_len = 0, pass_item_count = 0, line_count = 0, get_frame_cont = 1;
|
|
s32 *max_threshold = NULL, *min_threshold = NULL;
|
|
char *csv = NULL;
|
|
char *ret_pass_name = NULL, *ret_fail_name = NULL;
|
|
struct file *f = NULL;
|
|
mm_segment_t fs;
|
|
loff_t pos;
|
|
|
|
csv = vmalloc(CSV_FILE_SIZE);
|
|
if (ERR_ALLOC_MEM(csv)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate CSV mem\n", __func__);
|
|
ret = -EMP_NOMEM;
|
|
goto fail_open;
|
|
}
|
|
|
|
max_threshold = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
min_threshold = kcalloc(core_mp.frame_len, sizeof(s32), GFP_KERNEL);
|
|
if (ERR_ALLOC_MEM(max_threshold) || ERR_ALLOC_MEM(min_threshold)) {
|
|
input_err(true, ilits->dev, "%s Failed to allocate threshold FRAME buffer\n", __func__);
|
|
ret = -EMP_NOMEM;
|
|
goto fail_open;
|
|
}
|
|
|
|
if (parser_get_ini_key_value("pv5_4 command", "date", core_mp.ini_date) < 0)
|
|
ipio_memcpy(core_mp.ini_date, "Unknown", strlen("Unknown"), strlen("Unknown"));
|
|
if (parser_get_ini_key_value("pv5_4 command", "version", core_mp.ini_ver) < 0)
|
|
ipio_memcpy(core_mp.ini_ver, "Unknown", strlen("Unknown"), strlen("Unknown"));
|
|
|
|
mp_print_csv_header(csv, &csv_len, &line_count, CSV_FILE_SIZE);
|
|
|
|
for (seq = 0; seq < ri.count; seq++) {
|
|
i = ri.index[seq];
|
|
get_frame_cont = 1;
|
|
|
|
if (tItems[i].item_result == MP_DATA_PASS) {
|
|
pr_info("\n[%s],OK \n\n", tItems[i].desp);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "\n[%s],OK\n\n", tItems[i].desp);
|
|
} else {
|
|
pr_info("\n[%s],NG\n\n", tItems[i].desp);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "\n[%s],NG\n\n", tItems[i].desp);
|
|
}
|
|
|
|
if (tItems[i].catalog == PIN_TEST) {
|
|
pr_info("Test INT Pin = %d\n", tItems[i].test_int_pin);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "Test INT Pin = %d\n",
|
|
tItems[i].test_int_pin);
|
|
pr_info("Pulse Test = %d\n", tItems[i].int_pulse_test);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "Pulse Test = %d\n",
|
|
tItems[i].int_pulse_test);
|
|
pr_info("Delay Time = %d\n", tItems[i].delay_time);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "Delay Time = %d\n",
|
|
tItems[i].delay_time);
|
|
continue;
|
|
}
|
|
|
|
mp_print_csv_cdc_cmd(csv, &csv_len, i, CSV_FILE_SIZE);
|
|
|
|
pr_info("Frame count = %d\n", tItems[i].frame_count);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "Frame count = %d\n",
|
|
tItems[i].frame_count);
|
|
|
|
if (tItems[i].trimmed_mean && tItems[i].catalog != PEAK_TO_PEAK_TEST) {
|
|
pr_info("lowest percentage = %d\n", tItems[i].lowest_percentage);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "lowest percentage = %d\n",
|
|
tItems[i].lowest_percentage);
|
|
|
|
pr_info("highest percentage = %d\n", tItems[i].highest_percentage);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "highest percentage = %d\n",
|
|
tItems[i].highest_percentage);
|
|
}
|
|
|
|
/* Show result of benchmark max and min */
|
|
if (tItems[i].spec_option == BENCHMARK) {
|
|
if (tItems[i].catalog == PEAK_TO_PEAK_TEST) {
|
|
for (j = 0; j < core_mp.frame_len; j++) {
|
|
max_threshold[j] = tItems[i].bch_mrk_max[0][j];
|
|
min_threshold[j] = tItems[i].bch_mrk_min[0][j];
|
|
}
|
|
|
|
for (j = 0; j < tItems[i].bch_mrk_frm_num; j++) {
|
|
char bench_name[128] = {0};
|
|
|
|
snprintf(bench_name, (CSV_FILE_SIZE - csv_len), "Max_Bench%d", (j+1));
|
|
mp_compare_cdc_show_result(i, tItems[i].bch_mrk_max[j], csv, &csv_len,
|
|
TYPE_BENCHMARK, max_threshold, min_threshold,
|
|
bench_name, CSV_FILE_SIZE);
|
|
|
|
snprintf(bench_name, (CSV_FILE_SIZE - csv_len), "Min_Bench%d", (j+1));
|
|
mp_compare_cdc_show_result(i, tItems[i].bch_mrk_min[j], csv, &csv_len,
|
|
TYPE_BENCHMARK, max_threshold, min_threshold,
|
|
bench_name, CSV_FILE_SIZE);
|
|
}
|
|
} else {
|
|
for (j = 0; j < core_mp.frame_len; j++) {
|
|
max_threshold[j] = tItems[i].bench_mark_max[j];
|
|
min_threshold[j] = tItems[i].bench_mark_min[j];
|
|
}
|
|
mp_compare_cdc_show_result(i, tItems[i].bench_mark_max, csv, &csv_len, TYPE_BENCHMARK,
|
|
max_threshold, min_threshold, "Max_Bench", CSV_FILE_SIZE);
|
|
mp_compare_cdc_show_result(i, tItems[i].bench_mark_min, csv, &csv_len, TYPE_BENCHMARK,
|
|
max_threshold, min_threshold, "Min_Bench", CSV_FILE_SIZE);
|
|
}
|
|
|
|
} else {
|
|
for (j = 0; j < core_mp.frame_len; j++) {
|
|
max_threshold[j] = tItems[i].max;
|
|
min_threshold[j] = tItems[i].min;
|
|
}
|
|
|
|
pr_info("Max = %d\n", tItems[i].max);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "Max = %d\n", tItems[i].max);
|
|
|
|
pr_info("Min = %d\n", tItems[i].min);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "Min = %d\n", tItems[i].min);
|
|
}
|
|
|
|
if (ipio_strcmp(tItems[i].desp, "open test(integration)_sp") == 0) {
|
|
mp_compare_cdc_show_result(i, frame1_cbk700, csv, &csv_len, TYPE_NO_JUGE, max_threshold,
|
|
min_threshold, "frame1 cbk700", CSV_FILE_SIZE);
|
|
mp_compare_cdc_show_result(i, frame1_cbk250, csv, &csv_len, TYPE_NO_JUGE, max_threshold,
|
|
min_threshold, "frame1 cbk250", CSV_FILE_SIZE);
|
|
mp_compare_cdc_show_result(i, frame1_cbk200, csv, &csv_len, TYPE_NO_JUGE, max_threshold,
|
|
min_threshold, "frame1 cbk200", CSV_FILE_SIZE);
|
|
}
|
|
|
|
if (ipio_strcmp(tItems[i].desp, "open test_c") == 0) {
|
|
mp_compare_cdc_show_result(i, cap_dac, csv, &csv_len, TYPE_NO_JUGE, max_threshold,
|
|
min_threshold, "CAP_DAC", CSV_FILE_SIZE);
|
|
mp_compare_cdc_show_result(i, cap_raw, csv, &csv_len, TYPE_NO_JUGE, max_threshold,
|
|
min_threshold, "CAP_RAW", CSV_FILE_SIZE);
|
|
}
|
|
|
|
if (tItems[i].catalog == TX_RX_DELTA) {
|
|
if (ERR_ALLOC_MEM(core_mp.rx_delta_buf) || ERR_ALLOC_MEM(core_mp.tx_delta_buf)) {
|
|
input_err(true, ilits->dev, "%s This test item (%s) has no data inside its buffer\n",
|
|
__func__, tItems[i].desp);
|
|
continue;
|
|
}
|
|
} else {
|
|
if (ERR_ALLOC_MEM(tItems[i].buf) || ERR_ALLOC_MEM(tItems[i].max_buf) ||
|
|
ERR_ALLOC_MEM(tItems[i].min_buf)) {
|
|
input_err(true, ilits->dev, "%s This test item (%s) has no data inside its buffer\n",
|
|
__func__, tItems[i].desp);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/* Show test result as below */
|
|
if (tItems[i].catalog == KEY_TEST) {
|
|
for (x = 0; x < core_mp.key_len; x++) {
|
|
DUMP("KEY_%02d ", x);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "KEY_%02d,", x);
|
|
}
|
|
|
|
DUMP("\n");
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "\n");
|
|
|
|
for (y = 0; y < core_mp.key_len; y++) {
|
|
DUMP(" %3d ", tItems[i].buf[y]);
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), " %3d, ",
|
|
tItems[i].buf[y]);
|
|
}
|
|
|
|
DUMP("\n");
|
|
csv_len += snprintf(csv + csv_len, (CSV_FILE_SIZE - csv_len), "\n");
|
|
} else if (tItems[i].catalog == TX_RX_DELTA) {
|
|
for (j = 0; j < core_mp.frame_len; j++) {
|
|
max_threshold[j] = core_mp.TxDeltaMax;
|
|
min_threshold[j] = core_mp.TxDeltaMin;
|
|
}
|
|
mp_compare_cdc_show_result(i, core_mp.tx_max_buf, csv, &csv_len, TYPE_JUGE, max_threshold,
|
|
min_threshold, "TX Max Hold", CSV_FILE_SIZE);
|
|
mp_compare_cdc_show_result(i, core_mp.tx_min_buf, csv, &csv_len, TYPE_JUGE, max_threshold,
|
|
min_threshold, "TX Min Hold", CSV_FILE_SIZE);
|
|
|
|
for (j = 0; j < core_mp.frame_len; j++) {
|
|
max_threshold[j] = core_mp.RxDeltaMax;
|
|
min_threshold[j] = core_mp.RxDeltaMin;
|
|
}
|
|
mp_compare_cdc_show_result(i, core_mp.rx_max_buf, csv, &csv_len, TYPE_JUGE, max_threshold,
|
|
min_threshold, "RX Max Hold", CSV_FILE_SIZE);
|
|
mp_compare_cdc_show_result(i, core_mp.rx_min_buf, csv, &csv_len, TYPE_JUGE, max_threshold,
|
|
min_threshold, "RX Min Hold", CSV_FILE_SIZE);
|
|
} else {
|
|
/* general result */
|
|
if (tItems[i].trimmed_mean && tItems[i].catalog != PEAK_TO_PEAK_TEST) {
|
|
mp_compare_cdc_show_result(i, tItems[i].result_buf, csv, &csv_len, TYPE_JUGE,
|
|
max_threshold, min_threshold, "Mean result", CSV_FILE_SIZE);
|
|
} else {
|
|
if (!tItems[i].bch_mrk_multi) {
|
|
mp_compare_cdc_show_result(i, tItems[i].max_buf, csv, &csv_len, TYPE_JUGE,
|
|
max_threshold, min_threshold, "Max Hold", CSV_FILE_SIZE);
|
|
mp_compare_cdc_show_result(i, tItems[i].min_buf, csv, &csv_len, TYPE_JUGE,
|
|
max_threshold, min_threshold, "Min Hold", CSV_FILE_SIZE);
|
|
}
|
|
|
|
}
|
|
if (tItems[i].catalog != PEAK_TO_PEAK_TEST)
|
|
get_frame_cont = tItems[i].frame_count;
|
|
|
|
if (tItems[i].bch_mrk_multi)
|
|
get_frame_cont = tItems[i].bch_mrk_frm_num;
|
|
|
|
/* result of each frame */
|
|
for (j = 0; j < get_frame_cont; j++) {
|
|
char frame_name[128] = {0};
|
|
|
|
snprintf(frame_name, (CSV_FILE_SIZE - csv_len), "Frame %d", (j+1));
|
|
mp_compare_cdc_show_result(i, &tItems[i].buf[(j*core_mp.frame_len)], csv, &csv_len,
|
|
TYPE_NO_JUGE, max_threshold, min_threshold, frame_name, CSV_FILE_SIZE);
|
|
}
|
|
}
|
|
k = i;
|
|
}
|
|
|
|
memset(csv_name, 0, 128 * sizeof(char));
|
|
|
|
mp_print_csv_tail(csv, &csv_len, CSV_FILE_SIZE);
|
|
|
|
for (i = 0; i < MP_TEST_ITEM; i++) {
|
|
if (tItems[i].run) {
|
|
if (tItems[i].item_result < 0) {
|
|
pass_item_count = 0;
|
|
break;
|
|
}
|
|
pass_item_count++;
|
|
}
|
|
}
|
|
|
|
/* define csv file name */
|
|
ret_pass_name = NORMAL_CSV_PASS_NAME;
|
|
ret_fail_name = NORMAL_CSV_FAIL_NAME;
|
|
|
|
if (pass_item_count == 0) {
|
|
core_mp.final_result = MP_DATA_FAIL;
|
|
if ((ilits->sec.cmd_all_factory_state == SEC_CMD_STATUS_RUNNING) ||
|
|
(ilits->sec.cmd_state == SEC_CMD_STATUS_RUNNING))
|
|
ret = MP_DATA_PASS;//Sec using this value for check fucntion error. Not a test result.
|
|
else
|
|
ret = MP_DATA_FAIL;
|
|
|
|
if (core_mp.lost_parameter) {
|
|
ret_fail_name = NULL;
|
|
ret_fail_name = NORMAL_CSV_WARNING_NAME;
|
|
input_err(true, ilits->dev, "%s WARNING! OPEN or SHORT parameter not found in ini file!!\n",
|
|
__func__);
|
|
}
|
|
|
|
if (lcm_on) {
|
|
snprintf(csv_name, (CSV_FILE_SIZE - csv_len), "%s/%s_%s_%s.csv",
|
|
CSV_LCM_ON_PATH, get_date_time_str(), ret_fail_name, tItems[k].desp);
|
|
} else {
|
|
snprintf(csv_name, (CSV_FILE_SIZE - csv_len), "%s/%s_%s_%s.csv",
|
|
CSV_LCM_OFF_PATH, get_date_time_str(), ret_fail_name, tItems[k].desp);
|
|
}
|
|
} else {
|
|
core_mp.final_result = MP_DATA_PASS;
|
|
ret = MP_DATA_PASS;
|
|
|
|
if (core_mp.lost_benchmark) {
|
|
ret_pass_name = NULL;
|
|
ret_pass_name = NORMAL_CSV_WARNING_NAME;
|
|
input_err(true, ilits->dev, "%s WARNING! Golden and SPEC in ini file aren't matched!!\n",
|
|
__func__);
|
|
}
|
|
if (lcm_on) {
|
|
snprintf(csv_name, (CSV_FILE_SIZE - csv_len), "%s/%s_%s_%s.csv",
|
|
CSV_LCM_ON_PATH, get_date_time_str(), ret_pass_name, tItems[k].desp);
|
|
} else {
|
|
snprintf(csv_name, (CSV_FILE_SIZE - csv_len), "%s/%s_%s_%s.csv",
|
|
CSV_LCM_OFF_PATH, get_date_time_str(), ret_pass_name, tItems[k].desp);
|
|
}
|
|
}
|
|
|
|
input_info(true, ilits->dev, "%s Open CSV : %s\n", __func__, csv_name);
|
|
|
|
if (f == NULL)
|
|
f = filp_open(csv_name, O_WRONLY | O_CREAT | O_TRUNC, 644);
|
|
|
|
if (ERR_ALLOC_MEM(f)) {
|
|
input_err(true, ilits->dev, "%s Failed to open CSV file", __func__);
|
|
ret = -EMP_NOMEM;
|
|
goto fail_open;
|
|
}
|
|
|
|
input_info(true, ilits->dev, "%s Open CSV succeed, its length = %d\n ", __func__, csv_len);
|
|
|
|
if (csv_len >= CSV_FILE_SIZE) {
|
|
input_err(true, ilits->dev, "%s The length saved to CSV is too long !\n", __func__);
|
|
ret = -EMP_INVAL;
|
|
goto fail_open;
|
|
}
|
|
|
|
fs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
pos = 0;
|
|
vfs_write(f, csv, csv_len, &pos);
|
|
set_fs(fs);
|
|
filp_close(f, NULL);
|
|
|
|
input_info(true, ilits->dev, "%s Writing Data into CSV succeed\n", __func__);
|
|
|
|
fail_open:
|
|
ipio_vfree((void **)&csv);
|
|
ipio_kfree((void **)&max_threshold);
|
|
ipio_kfree((void **)&min_threshold);
|
|
return ret;
|
|
}
|
|
|
|
static void ilitek_tddi_mp_init_item(void)
|
|
{
|
|
int i = 0;
|
|
|
|
memset(&core_mp, 0, sizeof(core_mp));
|
|
memset(&open_para, 0, sizeof(open_para));
|
|
memset(&short_para, 0, sizeof(short_para));
|
|
|
|
core_mp.chip_pid = ilits->chip->pid;
|
|
core_mp.chip_id = ilits->chip->id;
|
|
core_mp.chip_type = ilits->chip->type;
|
|
core_mp.chip_ver = ilits->chip->ver;
|
|
core_mp.fw_ver = ilits->chip->fw_ver;
|
|
core_mp.protocol_ver = ilits->protocol->ver;
|
|
core_mp.core_ver = ilits->chip->core_ver;
|
|
core_mp.cdc_len = ilits->protocol->cdc_len;
|
|
core_mp.no_bk_shift = ilits->chip->no_bk_shift;
|
|
core_mp.xch_len = ilits->xch_num;
|
|
core_mp.ych_len = ilits->ych_num;
|
|
core_mp.frame_len = core_mp.xch_len * core_mp.ych_len;
|
|
core_mp.stx_len = 0;
|
|
core_mp.srx_len = 0;
|
|
core_mp.key_len = 0;
|
|
core_mp.st_len = 0;
|
|
core_mp.tdf = 240;
|
|
core_mp.busy_cdc = INT_CHECK;
|
|
core_mp.retry = ilits->mp_retry;
|
|
core_mp.td_retry = false;
|
|
core_mp.final_result = MP_DATA_FAIL;
|
|
core_mp.lost_benchmark = false;
|
|
core_mp.lost_parameter = false;
|
|
core_mp.all_pass = false;
|
|
|
|
input_info(true, ilits->dev, "%s ============== TP & Panel info ================\n", __func__);
|
|
input_info(true, ilits->dev, "Driver version = %s\n", DRIVER_VERSION);
|
|
input_info(true, ilits->dev, "TP Module = %s\n", ilits->md_name);
|
|
input_info(true, ilits->dev, "CHIP = 0x%x\n", core_mp.chip_pid);
|
|
input_info(true, ilits->dev, "Firmware version = %x\n", core_mp.fw_ver);
|
|
input_info(true, ilits->dev, "Protocol version = %x\n", core_mp.protocol_ver);
|
|
input_info(true, ilits->dev, "Core version = %x\n", core_mp.core_ver);
|
|
input_info(true, ilits->dev, "Read CDC Length = %d\n", core_mp.cdc_len);
|
|
input_info(true, ilits->dev, "X length = %d, Y length = %d\n", core_mp.xch_len, core_mp.ych_len);
|
|
input_info(true, ilits->dev, "Frame length = %d\n", core_mp.frame_len);
|
|
input_info(true, ilits->dev, "Check busy method = %s\n", (core_mp.busy_cdc ? "Polling" : "Interrupt"));
|
|
input_info(true, ilits->dev, "%s ===============================================\n", __func__);
|
|
|
|
for (i = 0; i < MP_TEST_ITEM; i++) {
|
|
tItems[i].spec_option = 0;
|
|
tItems[i].type_option = 0;
|
|
tItems[i].run = false;
|
|
tItems[i].max = 0;
|
|
tItems[i].max_res = MP_DATA_FAIL;
|
|
tItems[i].item_result = MP_DATA_PASS;
|
|
tItems[i].min = 0;
|
|
tItems[i].min_res = MP_DATA_FAIL;
|
|
tItems[i].frame_count = 0;
|
|
tItems[i].trimmed_mean = 0;
|
|
tItems[i].lowest_percentage = 0;
|
|
tItems[i].highest_percentage = 0;
|
|
tItems[i].v_tdf_1 = 0;
|
|
tItems[i].v_tdf_2 = 0;
|
|
tItems[i].h_tdf_1 = 0;
|
|
tItems[i].h_tdf_2 = 0;
|
|
tItems[i].max_min_mode = 0;
|
|
tItems[i].bch_mrk_multi = false;
|
|
tItems[i].bch_mrk_frm_num = 1;
|
|
tItems[i].goldenmode = 0;
|
|
tItems[i].retry_cnt = RETRY_COUNT;
|
|
tItems[i].result_buf = NULL;
|
|
tItems[i].buf = NULL;
|
|
tItems[i].max_buf = NULL;
|
|
tItems[i].min_buf = NULL;
|
|
tItems[i].bench_mark_max = NULL;
|
|
tItems[i].bench_mark_min = NULL;
|
|
tItems[i].bch_mrk_max = NULL;
|
|
tItems[i].bch_mrk_min = NULL;
|
|
tItems[i].node_type = NULL;
|
|
tItems[i].delay_time = 0;
|
|
tItems[i].test_int_pin = 0;
|
|
tItems[i].int_pulse_test = 0;
|
|
|
|
if (tItems[i].catalog == MUTUAL_TEST) {
|
|
tItems[i].do_test = mutual_test;
|
|
} else if (tItems[i].catalog == TX_RX_DELTA) {
|
|
tItems[i].do_test = mutual_test;
|
|
} else if (tItems[i].catalog == UNTOUCH_P2P) {
|
|
tItems[i].do_test = mutual_test;
|
|
} else if (tItems[i].catalog == PIXEL) {
|
|
tItems[i].do_test = mutual_test;
|
|
} else if (tItems[i].catalog == OPEN_TEST) {
|
|
if (ipio_strcmp(tItems[i].desp, "open test(integration)_sp") == 0)
|
|
tItems[i].do_test = open_test_sp;
|
|
else if (ipio_strcmp(tItems[i].desp, "open test_c") == 0)
|
|
tItems[i].do_test = open_test_cap;
|
|
else
|
|
tItems[i].do_test = mutual_test;
|
|
} else if (tItems[i].catalog == KEY_TEST) {
|
|
tItems[i].do_test = key_test;
|
|
} else if (tItems[i].catalog == SELF_TEST) {
|
|
tItems[i].do_test = self_test;
|
|
} else if (tItems[i].catalog == ST_TEST) {
|
|
tItems[i].do_test = st_test;
|
|
} else if (tItems[i].catalog == PEAK_TO_PEAK_TEST) {
|
|
tItems[i].do_test = peak_to_peak_test;
|
|
} else if (tItems[i].catalog == SHORT_TEST) {
|
|
tItems[i].do_test = mutual_test;
|
|
} else if (tItems[i].catalog == PIN_TEST) {
|
|
tItems[i].do_test = pin_test;
|
|
}
|
|
|
|
tItems[i].result = kmalloc(16, GFP_KERNEL);
|
|
snprintf(tItems[i].result, 16, "%s", "FAIL");
|
|
}
|
|
}
|
|
|
|
static void mp_p2p_td_retry_after_ra_fail(int p2p_td)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < MP_TEST_ITEM; i++) {
|
|
if (ipio_strcmp(tItems[i].desp, "noise peak to peak(with panel) (lcm off)") == 0)
|
|
break;
|
|
}
|
|
|
|
if (i >= MP_TEST_ITEM)
|
|
return;
|
|
|
|
ILI_DBG("%s i = %d, p2p_noise_ret = %d, p2p_noise_run = %d\n",
|
|
__func__, i, tItems[i].item_result, tItems[i].run);
|
|
|
|
if (tItems[i].item_result == MP_DATA_PASS && tItems[i].run == 1)
|
|
tItems[p2p_td].do_test(p2p_td);
|
|
}
|
|
|
|
static void mp_test_run(int index)
|
|
{
|
|
int i = index, j;
|
|
char str[512] = {0};
|
|
|
|
|
|
/* Get parameters from ini */
|
|
parser_get_int_data(tItems[i].desp, "spec option", str, sizeof(str));
|
|
tItems[i].spec_option = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "type option", str, sizeof(str));
|
|
tItems[i].type_option = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "frame count", str, sizeof(str));
|
|
tItems[i].frame_count = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "trimmed mean", str, sizeof(str));
|
|
tItems[i].trimmed_mean = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "lowest percentage", str, sizeof(str));
|
|
tItems[i].lowest_percentage = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "highest percentage", str, sizeof(str));
|
|
tItems[i].highest_percentage = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "goldenmode", str, sizeof(str));
|
|
tItems[i].goldenmode = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "max min mode", str, sizeof(str));
|
|
tItems[i].max_min_mode = ili_katoi(str);
|
|
|
|
parser_get_int_data(tItems[i].desp, "retry count", str, sizeof(str));
|
|
tItems[i].retry_cnt = ili_katoi(str);
|
|
|
|
if (tItems[i].goldenmode && (tItems[i].spec_option != tItems[i].goldenmode))
|
|
core_mp.lost_benchmark = true;
|
|
|
|
/* Get pin test delay time */
|
|
if (tItems[i].catalog == PIN_TEST) {
|
|
parser_get_int_data(tItems[i].desp, "test int pin", str, sizeof(str));
|
|
tItems[i].test_int_pin = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "int pulse test", str, sizeof(str));
|
|
tItems[i].int_pulse_test = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "delay time", str, sizeof(str));
|
|
tItems[i].delay_time = ili_katoi(str);
|
|
}
|
|
|
|
/* Get TDF value from ini */
|
|
if (tItems[i].catalog == SHORT_TEST) {
|
|
parser_get_int_data(tItems[i].desp, "v_tdf_1", str, sizeof(str));
|
|
tItems[i].v_tdf_1 = parser_get_tdf_value(str, tItems[i].catalog);
|
|
parser_get_int_data(tItems[i].desp, "v_tdf_2", str, sizeof(str));
|
|
tItems[i].v_tdf_2 = parser_get_tdf_value(str, tItems[i].catalog);
|
|
parser_get_int_data(tItems[i].desp, "h_tdf_1", str, sizeof(str));
|
|
tItems[i].h_tdf_1 = parser_get_tdf_value(str, tItems[i].catalog);
|
|
parser_get_int_data(tItems[i].desp, "h_tdf_2", str, sizeof(str));
|
|
tItems[i].h_tdf_2 = parser_get_tdf_value(str, tItems[i].catalog);
|
|
} else {
|
|
parser_get_int_data(tItems[i].desp, "v_tdf", str, sizeof(str));
|
|
tItems[i].v_tdf_1 = parser_get_tdf_value(str, tItems[i].catalog);
|
|
parser_get_int_data(tItems[i].desp, "h_tdf", str, sizeof(str));
|
|
tItems[i].h_tdf_1 = parser_get_tdf_value(str, tItems[i].catalog);
|
|
}
|
|
|
|
/* Get threshold from ini structure in parser */
|
|
if (ipio_strcmp(tItems[i].desp, "tx/rx delta") == 0) {
|
|
parser_get_int_data(tItems[i].desp, "tx max", str, sizeof(str));
|
|
core_mp.TxDeltaMax = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "tx min", str, sizeof(str));
|
|
core_mp.TxDeltaMin = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "rx max", str, sizeof(str));
|
|
core_mp.RxDeltaMax = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "rx min", str, sizeof(str));
|
|
core_mp.RxDeltaMin = ili_katoi(str);
|
|
ILI_DBG("%s %s: Tx Max = %d, Tx Min = %d, Rx Max = %d, Rx Min = %d\n",
|
|
__func__, tItems[i].desp, core_mp.TxDeltaMax, core_mp.TxDeltaMin,
|
|
core_mp.RxDeltaMax, core_mp.RxDeltaMin);
|
|
} else {
|
|
parser_get_int_data(tItems[i].desp, "max", str, sizeof(str));
|
|
tItems[i].max = ili_katoi(str);
|
|
parser_get_int_data(tItems[i].desp, "min", str, sizeof(str));
|
|
tItems[i].min = ili_katoi(str);
|
|
}
|
|
|
|
|
|
/* Get pin test delay time */
|
|
if (tItems[i].catalog == PEAK_TO_PEAK_TEST) {
|
|
if (tItems[i].max_min_mode == 1 && tItems[i].spec_option == 1) {
|
|
tItems[i].bch_mrk_multi = true;
|
|
for (j = 1; j < 11; j++) {
|
|
char tmp[8] = {0};
|
|
/* format complete string from the name of section "_Benchmark_Data". */
|
|
snprintf(str, sizeof(str), "%s%s%s%d", tItems[index].desp, "_", BENCHMARK_KEY_NAME, j);
|
|
if (parser_get_int_data(str, str, tmp, sizeof(tmp)) <= 0)
|
|
break;
|
|
|
|
tItems[i].bch_mrk_frm_num = j;
|
|
}
|
|
ILI_DBG("%s set bch_mrk_frm_num = %d\n", __func__, tItems[i].bch_mrk_frm_num);
|
|
}
|
|
}
|
|
|
|
ILI_DBG("%s %s: run = %d, max = %d, min = %d, frame_count = %d\n",
|
|
__func__, tItems[i].desp, tItems[i].run, tItems[i].max, tItems[i].min, tItems[i].frame_count);
|
|
|
|
ILI_DBG("%s v_tdf_1 = %d, v_tdf_2 = %d, h_tdf_1 = %d, h_tdf_2 = %d",
|
|
__func__, tItems[i].v_tdf_1, tItems[i].v_tdf_2, tItems[i].h_tdf_1, tItems[i].h_tdf_2);
|
|
|
|
input_info(true, ilits->dev, "%s Run MP Test Item : %s\n", __func__, tItems[i].desp);
|
|
tItems[i].do_test(i);
|
|
|
|
mp_compare_test_result(i);
|
|
|
|
/* P2P TD retry after RA sample failed. */
|
|
if (ipio_strcmp(tItems[i].desp, "peak to peak_td (lcm off)") == 0 &&
|
|
tItems[i].item_result == MP_DATA_FAIL) {
|
|
parser_get_int_data(tItems[i].desp, "recheck ptop lcm off", str, sizeof(str));
|
|
input_info(true, ilits->dev, "%s Peak to Peak TD retry = %d\n", __func__, ili_katoi(str));
|
|
core_mp.td_retry = ili_katoi(str);
|
|
if (core_mp.td_retry)
|
|
mp_p2p_td_retry_after_ra_fail(i);
|
|
}
|
|
|
|
if (core_mp.retry && tItems[i].item_result == MP_DATA_FAIL) {
|
|
input_info(true, ilits->dev, "%s MP failed, doing retry %d times\n", __func__, tItems[i].retry_cnt);
|
|
mp_do_retry(i, tItems[i].retry_cnt);
|
|
}
|
|
|
|
|
|
input_info(true, ilits->dev, "current_mp:%s, running:%s\n", ilits->current_mpitem, tItems[i].desp);
|
|
if (ipio_strcmp(tItems[i].desp, ilits->current_mpitem) == 0)
|
|
sec_factory_print_frame(tItems[i].buf);
|
|
}
|
|
|
|
static void mp_test_free(void)
|
|
{
|
|
int i, j;
|
|
|
|
input_info(true, ilits->dev, "%s Free all allocated mem for MP\n", __func__);
|
|
|
|
core_mp.final_result = MP_DATA_FAIL;
|
|
core_mp.td_retry = false;
|
|
|
|
for (i = 0; i < MP_TEST_ITEM; i++) {
|
|
tItems[i].run = false;
|
|
tItems[i].max_res = MP_DATA_FAIL;
|
|
tItems[i].min_res = MP_DATA_FAIL;
|
|
tItems[i].item_result = MP_DATA_PASS;
|
|
|
|
if (tItems[i].catalog == TX_RX_DELTA) {
|
|
ipio_kfree((void **)&core_mp.rx_delta_buf);
|
|
ipio_kfree((void **)&core_mp.tx_delta_buf);
|
|
ipio_kfree((void **)&core_mp.tx_max_buf);
|
|
ipio_kfree((void **)&core_mp.tx_min_buf);
|
|
ipio_kfree((void **)&core_mp.rx_max_buf);
|
|
ipio_kfree((void **)&core_mp.rx_min_buf);
|
|
} else {
|
|
if (tItems[i].spec_option == BENCHMARK) {
|
|
ipio_kfree((void **)&tItems[i].bench_mark_max);
|
|
ipio_kfree((void **)&tItems[i].bench_mark_min);
|
|
if (tItems[i].bch_mrk_max != NULL) {
|
|
for (j = 0; j < tItems[i].bch_mrk_frm_num; j++)
|
|
if (tItems[i].bch_mrk_max[j] != NULL) {
|
|
kfree(tItems[i].bch_mrk_max[j]);
|
|
tItems[i].bch_mrk_max[j] = NULL;
|
|
}
|
|
kfree(tItems[i].bch_mrk_max);
|
|
tItems[i].bch_mrk_max = NULL;
|
|
}
|
|
if (tItems[i].bch_mrk_min != NULL) {
|
|
for (j = 0; j < tItems[i].bch_mrk_frm_num; j++)
|
|
if (tItems[i].bch_mrk_min[j] != NULL) {
|
|
kfree(tItems[i].bch_mrk_min[j]);
|
|
tItems[i].bch_mrk_min[j] = NULL;
|
|
}
|
|
kfree(tItems[i].bch_mrk_min);
|
|
tItems[i].bch_mrk_min = NULL;
|
|
}
|
|
}
|
|
ipio_kfree((void **)&tItems[i].node_type);
|
|
ipio_kfree((void **)&tItems[i].result);
|
|
ipio_kfree((void **)&tItems[i].result_buf);
|
|
ipio_kfree((void **)&tItems[i].max_buf);
|
|
ipio_kfree((void **)&tItems[i].min_buf);
|
|
ipio_vfree((void **)&tItems[i].buf);
|
|
}
|
|
}
|
|
|
|
ipio_kfree((void **)&frame1_cbk700);
|
|
ipio_kfree((void **)&frame1_cbk250);
|
|
ipio_kfree((void **)&frame1_cbk200);
|
|
ipio_kfree((void **)&frame_buf);
|
|
ipio_kfree((void **)&key_buf);
|
|
if (frm_buf != NULL) {
|
|
for (j = 0; j < 3; j++)
|
|
if (frm_buf[j] != NULL) {
|
|
kfree(frm_buf[j]);
|
|
frm_buf[j] = NULL;
|
|
}
|
|
kfree(frm_buf);
|
|
frm_buf = NULL;
|
|
}
|
|
}
|
|
|
|
/* The method to copy results to user depends on what APK needs */
|
|
static void mp_copy_ret_to_apk(char *buf)
|
|
{
|
|
int i, seq, len = 2;
|
|
|
|
if (!buf) {
|
|
input_err(true, ilits->dev, "%s apk buffer is null\n", __func__);
|
|
return;
|
|
}
|
|
|
|
len += snprintf(buf + len, PAGE_SIZE - len, "CSV path: %s\n\n", csv_name);
|
|
for (seq = 0; seq < ri.count; seq++) {
|
|
i = ri.index[seq];
|
|
if (tItems[i].item_result == MP_DATA_FAIL) {
|
|
input_err(true, ilits->dev, "%s [%s] = FAIL\n", __func__, tItems[i].desp);
|
|
len += snprintf(buf + len, PAGE_SIZE - len, "[%s] = FAIL\n", tItems[i].desp);
|
|
} else {
|
|
input_info(true, ilits->dev, "%s [%s] = PASS\n", __func__, tItems[i].desp);
|
|
len += snprintf(buf + len, PAGE_SIZE - len, "[%s] = PASS\n", tItems[i].desp);
|
|
}
|
|
}
|
|
ilits->mp_ret_len = len;
|
|
}
|
|
|
|
static int mp_sort_item(bool lcm_on)
|
|
{
|
|
int i, j;
|
|
char str[128] = {0};
|
|
|
|
ri.count = 0;
|
|
memset(ri.index, 0x0, MP_TEST_ITEM);
|
|
|
|
for (i = 0; i < MAX_SECTION_NUM; i++) {
|
|
for (j = 0; j < MP_TEST_ITEM; j++) {
|
|
if (ipio_strcmp(seq_item[i], tItems[j].desp) != 0)
|
|
continue;
|
|
|
|
parser_get_int_data(tItems[j].desp, "enable", str, sizeof(str));
|
|
tItems[j].run = ili_katoi(str);
|
|
if (tItems[j].run != 1 || tItems[j].lcm != lcm_on)
|
|
continue;
|
|
|
|
if (ri.count > MP_TEST_ITEM) {
|
|
input_err(true, ilits->dev, "%s Test item(%d) is invaild, abort\n", __func__, ri.count);
|
|
return -EINVAL;
|
|
}
|
|
|
|
ri.index[ri.count] = j;
|
|
ri.count++;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void ilitek_tddi_mp_all_pass_check(void)
|
|
{
|
|
int ret = 0, retry = 5;
|
|
u8 cmd[1] = {0xFD};
|
|
u8 temp[3] = {0};
|
|
|
|
ilits->wait_int_timeout = 20;
|
|
do {
|
|
ret = ilits->wrapper(cmd, 1, temp, 3, ON, OFF);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Write MP All Pass command failed\n", __func__);
|
|
core_mp.all_pass = false;
|
|
} else {
|
|
if (temp[0] == 0xFD)
|
|
break;
|
|
}
|
|
} while (--retry >= 0);
|
|
ilits->wait_int_timeout = MP_INT_TIMEOUT;
|
|
if (retry <= 0) {
|
|
input_err(true, ilits->dev, "%s MP All Pass command failed, normal mode\n", __func__);
|
|
core_mp.all_pass = false;
|
|
return;
|
|
}
|
|
|
|
if (temp[2] == ili_calc_packet_checksum(temp, sizeof(temp) - 1) &&
|
|
temp[0] == 0xFD && temp[1] == 0x02) {//0xFD:back door command header, 0x02:Normal mode
|
|
core_mp.all_pass = true;
|
|
input_err(true, ilits->dev, "%s MP mode check: Back door mode, MP All Pass\n", __func__);
|
|
} else {
|
|
core_mp.all_pass = false;//0xFD:back door command header, 0x01:Normal mode
|
|
input_err(true, ilits->dev, "%s MP mode check: Normal mode\n", __func__);
|
|
}
|
|
}
|
|
|
|
int ili_mp_test_main(char *apk, bool lcm_on)
|
|
{
|
|
int i, ret = 0;
|
|
char str[128] = {0}, ver[128] = {0};
|
|
|
|
if (ilits->xch_num <= 0 || ilits->ych_num <= 0) {
|
|
input_err(true, ilits->dev, "%s Invalid frame length (%d, %d)\n",
|
|
__func__, ilits->xch_num, ilits->ych_num);
|
|
ret = -EMP_INVAL;
|
|
goto out;
|
|
}
|
|
|
|
if (ini_info == NULL) {
|
|
ini_info = (struct ini_file_data *)vmalloc(sizeof(struct ini_file_data) * PARSER_MAX_KEY_NUM);
|
|
if (ERR_ALLOC_MEM(ini_info)) {
|
|
input_err(true, ilits->dev, "%s Failed to malloc ini_info\n", __func__);
|
|
ret = -EMP_NOMEM;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
ilitek_tddi_mp_init_item();
|
|
|
|
if ((ilits->sec.cmd_all_factory_state != SEC_CMD_STATUS_RUNNING) &&
|
|
(ilits->sec.cmd_state != SEC_CMD_STATUS_RUNNING))
|
|
ilitek_tddi_mp_all_pass_check();
|
|
|
|
ret = ilitek_tddi_mp_ini_parser(ilits->md_ini_path);
|
|
if (ret < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to parsing INI file\n", __func__);
|
|
ret = -EMP_INI;
|
|
goto out;
|
|
}
|
|
|
|
/* Compare both protocol version of ini and firmware */
|
|
parser_get_ini_key_value("pv5_4 command", "protocol", str);
|
|
snprintf(ver, sizeof(ver), "0x%s", str);
|
|
if ((ili_str2hex(ver)) != (core_mp.protocol_ver >> 8)) {
|
|
input_err(true, ilits->dev, "%s ERROR! MP Protocol version is invaild, 0x%x\n",
|
|
__func__, ili_str2hex(ver));
|
|
ret = -EMP_PROTOCOL;
|
|
goto out;
|
|
}
|
|
|
|
/* Read timing info from ini file */
|
|
if (mp_get_timing_info() < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to get timing info from ini\n", __func__);
|
|
ret = -EMP_TIMING_INFO;
|
|
goto out;
|
|
}
|
|
|
|
#if MP_INT_LEVEL
|
|
if (ili_ic_int_trigger_ctrl(true) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to set INT as Level trigger", __func__);
|
|
ret = -EMP_CMD;
|
|
goto out;
|
|
}
|
|
#endif
|
|
|
|
/* Sort test item by ini file */
|
|
if (mp_sort_item(lcm_on) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to sort test item\n", __func__);
|
|
ret = -EMP_INI;
|
|
goto out;
|
|
}
|
|
|
|
for (i = 0; i < ri.count; i++)
|
|
mp_test_run(ri.index[i]);
|
|
|
|
ret = mp_show_result(lcm_on);
|
|
|
|
mp_copy_ret_to_apk(apk);
|
|
|
|
out:
|
|
mp_test_free();
|
|
|
|
#if MP_INT_LEVEL
|
|
if (ili_ic_int_trigger_ctrl(false) < 0) {
|
|
input_err(true, ilits->dev, "%s Failed to set INT back to pluse trigger", __func__);
|
|
ret = -EMP_CMD;
|
|
}
|
|
#endif
|
|
|
|
ipio_vfree((void **)&ini_info);
|
|
return ret;
|
|
};
|