drivers/input/touchscreen/st/fts_lib/ftsTest.c (4,738 lines of code) (raw):

/* * ************************************************************************** ** STMicroelectronics ** ************************************************************************** ** marco.cali@st.com ** ************************************************************************** * * * FTS API for MP test * * * ************************************************************************** ************************************************************************** * */ /*! * \file ftsTest.c * \brief Contains all the functions related to the Mass Production Test */ #include "ftsCompensation.h" #include "ftsCore.h" #include "ftsError.h" #include "ftsFrame.h" #include "ftsHardware.h" #include "ftsIO.h" #include "ftsSoftware.h" #include "ftsTest.h" #include "ftsTime.h" #include "ftsTool.h" #include "../fts.h" #include <linux/errno.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/string.h> #include <stdarg.h> #include <linux/serio.h> #include <linux/time.h> #include <linux/delay.h> #include <linux/ctype.h> #include <linux/firmware.h> #ifdef LIMITS_H_FILE #include "../fts_limits.h" #endif struct TestToDo tests; /* /< global variable that specify the tests to perform * during the Mass Production Test */ static struct LimitFile limit_file; /* /< variable which contains the limit * file during test */ /** * Initialize the testToDo variable with the default tests to perform during *the Mass Production Test * @return OK */ int initTestToDo(void) { /*** Initialize Limit File ***/ limit_file.size = 0; limit_file.data = NULL; strlcpy(limit_file.name, " ", MAX_LIMIT_FILE_NAME); tests.MutualRawAdjITO = 1; tests.MutualRaw = 1; tests.MutualRawEachNode = 0; tests.MutualRawGap = 0; tests.MutualRawAdj = 0; tests.MutualRawAdjGap = 1; tests.MutualRawAdjPeak = 0; tests.MutualRawLP = 0; tests.MutualRawGapLP = 0; tests.MutualRawAdjLP = 0; tests.MutualCx1 = 0; tests.MutualCx2 = 0; tests.MutualCx2Adj = 0; tests.MutualCxTotal = 0; tests.MutualCxTotalAdj = 0; tests.MutualCx1LP = 0; tests.MutualCx2LP = 0; tests.MutualCx2AdjLP = 0; tests.MutualCxTotalLP = 0; tests.MutualCxTotalAdjLP = 0; #ifdef PHONE_KEY tests.MutualKeyRaw = 1; #else tests.MutualKeyRaw = 0; #endif tests.MutualKeyCx1 = 0; tests.MutualKeyCx2 = 0; #ifdef PHONE_KEY tests.MutualKeyCxTotal = 0; #else tests.MutualKeyCxTotal = 0; #endif tests.SelfForceRaw = 0; tests.SelfForceRawGap = 0; tests.SelfForceRawLP = 0; tests.SelfForceRawGapLP = 0; tests.SelfForceIx1 = 0; tests.SelfForceIx2 = 0; tests.SelfForceIx2Adj = 0; tests.SelfForceIxTotal = 0; tests.SelfForceIxTotalAdj = 0; tests.SelfForceCx1 = 0; tests.SelfForceCx2 = 0; tests.SelfForceCx2Adj = 0; tests.SelfForceCxTotal = 0; tests.SelfForceCxTotalAdj = 0; tests.SelfSenseRaw = 0; tests.SelfSenseRawGap = 0; tests.SelfSenseRawLP = 1; tests.SelfSenseRawGapLP = 0; tests.SelfSenseIx1 = 0; tests.SelfSenseIx2 = 0; tests.SelfSenseIx2Adj = 0; tests.SelfSenseIxTotal = 0; tests.SelfSenseIxTotalAdj = 0; tests.SelfSenseCx1 = 0; tests.SelfSenseCx2 = 0; tests.SelfSenseCx2Adj = 0; tests.SelfSenseCxTotal = 0; tests.SelfSenseCxTotalAdj = 0; return OK; } /** * Compute the Horizontal adjacent matrix doing the abs of the difference * between the column i with the i-1 one. \n * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of signed bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which will * contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjHoriz(i8 *data, int row, int column, u8 **result) { int i, j; int size = row * (column - 1); if (column < 2) { logError(1, "%s computeAdjHoriz: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u8), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjHoriz: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 0; i < row; i++) for (j = 1; j < column; j++) *(*result + (i * (column - 1) + (j - 1))) = abs(data[i * column + j] - data[i * column + (j - 1)]); return OK; } /** * Compute the Horizontal adjacent matrix of short values doing the abs of * the difference between the column i with the i-1 one. * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of signed bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which * will contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjHorizTotal(short *data, int row, int column, u16 **result) { int i, j; int size = row * (column - 1); if (column < 2) { logError(1, "%s computeAdjHorizTotal: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u16), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjHorizTotal: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 0; i < row; i++) for (j = 1; j < column; j++) *(*result + (i * (column - 1) + (j - 1))) = abs(data[i * column + j] - data[i * column + (j - 1)]); return OK; } /** * Compute the Horizontal adjacent matrix of short values doing * the difference between the column i with the i-1 one. * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of signed bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which * will contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjHorizTotalSigned(short *data, int row, int column, u16 **result) { int i, j; int size = row * (column - 1); if (column < 2) { logError(1, "%s computeAdjHorizTotalSigned: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u16), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjHorizTotalsigned: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 0; i < row; i++) for (j = 1; j < column; j++) *(*result + (i * (column - 1) + (j - 1))) = data[i * column + j] - data[i * column + (j - 1)]; return OK; } /** * Compute the Vertical adjacent matrix doing the abs of the difference between * the row i with the i-1 one. * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other. \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of signed bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which will * contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjVert(i8 *data, int row, int column, u8 **result) { int i, j; int size = (row - 1) * (column); if (row < 2) { logError(1, "%s computeAdjVert: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u8), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjVert: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 1; i < row; i++) for (j = 0; j < column; j++) *(*result + ((i - 1) * column + j)) = abs(data[i * column + j] - data[(i - 1) * column + j]); return OK; } /** * Compute the Vertical adjacent matrix of short values doing the abs of * the difference between the row i with the i-1 one. * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other. \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of signed bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which will * contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjVertTotal(short *data, int row, int column, u16 **result) { int i, j; int size = (row - 1) * (column); if (row < 2) { logError(1, "%s computeAdjVertTotal: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u16), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjVertTotal: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 1; i < row; i++) for (j = 0; j < column; j++) *(*result + ((i - 1) * column + j)) = abs(data[i * column + j] - data[(i - 1) * column + j]); return OK; } /** * Compute the Vertical adjacent matrix of short values doing * the difference between the row i with the i-1 one. * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other. \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of signed bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which will * contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjVertTotalSigned(short *data, int row, int column, u16 **result) { int i, j; int size = (row - 1) * (column); if (row < 2) { logError(1, "%s computeAdjVertTotalSigned: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u16), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjVertTotalSigned: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 1; i < row; i++) for (j = 0; j < column; j++) *(*result + ((i - 1) * column + j)) = data[i * column + j] - data[(i - 1) * column + j]; return OK; } /** * Compute the Horizontal adjacent matrix doing the abs of the difference * between the column i with the i-1 one. \n * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of unsigned bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which will * contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjHorizFromU(u8 *data, int row, int column, u8 **result) { int i, j; int size = row * (column - 1); if (column < 2) { logError(1, "%s computeAdjHoriz: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u8), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjHoriz: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 0; i < row; i++) for (j = 1; j < column; j++) *(*result + (i * (column - 1) + (j - 1))) = abs(data[i * column + j] - data[i * column + (j - 1)]); return OK; } /** * Compute the Horizontal adjacent matrix of u16 values doing the abs of * the difference between the column i with the i-1 one. * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of unsigned bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which will * contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjHorizTotalFromU(u16 *data, int row, int column, u16 **result) { int i, j; int size = row * (column - 1); if (column < 2) { logError(1, "%s computeAdjHorizTotal: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u16), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjHorizTotal: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 0; i < row; i++) for (j = 1; j < column; j++) *(*result + (i * (column - 1) + (j - 1))) = abs(data[i * column + j] - data[i * column + (j - 1)]); return OK; } /** * Compute the Vertical adjacent matrix doing the abs of the difference between * the row i with the i-1 one. * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other. \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of unsigned bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which will * contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjVertFromU(u8 *data, int row, int column, u8 **result) { int i, j; int size = (row - 1) * (column); if (row < 2) { logError(1, "%s computeAdjVert: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u8), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjVert: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 1; i < row; i++) for (j = 0; j < column; j++) *(*result + ((i - 1) * column + j)) = abs(data[i * column + j] - data[(i - 1) * column + j]); return OK; } /** * Compute the Vertical adjacent matrix of u16 values doing the abs of * the difference between the row i with the i-1 one. * Both the original data matrix and the adj matrix are disposed as 1 dimension * array one row after the other. \n * The resulting matrix has one column less than the starting original one \n * @param data pointer to the array of unsigned bytes containing the original * data * @param row number of rows of the original data * @param column number of columns of the original data * @param result pointer of a pointer to an array of unsigned bytes which will * contain the adj matrix * @return OK if success or an error code which specify the type of error */ int computeAdjVertTotalFromU(u16 *data, int row, int column, u16 **result) { int i, j; int size = (row - 1) * (column); if (row < 2) { logError(1, "%s computeAdjVertTotal: ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } *result = kmalloc_array(size, sizeof(u16), GFP_KERNEL); if (*result == NULL) { logError(1, "%s computeAdjVertTotal: ERROR %08X\n", TAG, ERROR_ALLOC); return ERROR_ALLOC; } for (i = 1; i < row; i++) for (j = 0; j < column; j++) *(*result + ((i - 1) * column + j)) = abs(data[i * column + j] - data[(i - 1) * column + j]); return OK; } /** * Check that each value of a matrix of short doesn't exceed a min and a Max * value (these values are included in the interval). \n * The matrix is stored as 1 dimension array one row after the other. \n * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param min minimum value allowed * @param max Maximum value allowed * @return the number of elements that overcome the specified interval (0 = OK) */ int checkLimitsMinMax(short *data, int row, int column, int min, int max) { int i, j; int count = 0; for (i = 0; i < row; i++) { for (j = 0; j < column; j++) { if (data[i * column + j] < min || data[i * column + j] > max) { logError(1, "%s checkLimitsMinMax: Node[%d,%d] = %d exceed limit [%d, %d]\n", TAG, i, j, data[i * column + j], min, max); count++; } } } return count; /* if count is 0 = OK, test completed successfully */ } /** * Check that the difference between the max and min of a matrix of short is * less or equal to a threshold.\n * The matrix is stored as 1 dimension array one row after the other. * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param threshold threshold value allowed * @return OK if the difference is <= to threshold otherwise *ERROR_TEST_CHECK_FAIL */ int checkLimitsGap(short *data, int row, int column, int threshold) { int i, j; int min_node; int max_node; if (row == 0 || column == 0) { logError(1, "%s checkLimitsGap: invalid number of rows = %d or columns = %d ERROR %08X\n", TAG, row, column, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } min_node = data[0]; max_node = data[0]; for (i = 0; i < row; i++) { for (j = 0; j < column; j++) { if (data[i * column + j] < min_node) min_node = data[i * column + j]; else if (data[i * column + j] > max_node) max_node = data[i * column + j]; } } if (max_node - min_node > threshold) { logError(1, "%s checkLimitsGap: GAP = %d exceed limit %d\n", TAG, max_node - min_node, threshold); return ERROR_TEST_CHECK_FAIL; } else return OK; } /** * Check that the difference between the max and min of a matrix of short is * less or equal to a threshold.\n * The matrix is stored as 1 dimension array one row after the other. * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param threshold threshold value allowed * @param row_start index of the starting column which should be considered * @param column_start index of the starting column which should be considered * @param row_end number of index to subtract to row to identify last * valid row to check * @param column_end number of index to subtract to column to identify last * valid column to check * @return OK if the difference is <= to threshold otherwise * ERROR_TEST_CHECK_FAIL */ int checkLimitsGapOffsets(short *data, int row, int column, int threshold, int row_start, int column_start, int row_end, int column_end) { int i, j; int min_node; int max_node; if (row == 0 || column == 0) { logError(1, "%s checkLimitsGap: invalid number of rows = %d or columns = %d ERROR %08X\n", TAG, row, column, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } min_node = data[row_start*column+column_start]; max_node = data[row_start*column+column_start]; for (i = row_start; i < row-row_end; i++) { for (j = column_start; j < column-column_end; j++) { if (data[i * column + j] < min_node) min_node = data[i * column + j]; else if (data[i * column + j] > max_node) max_node = data[i * column + j]; } } if (max_node - min_node > threshold) { logError(1, "%s checkLimitsGap: GAP = %d exceed limit %d\n", TAG, max_node - min_node, threshold); return ERROR_TEST_CHECK_FAIL; } else return OK; } /** * Check that each value of a matrix of i8 doesn't exceed a specific min and *Max value set for each node (these values are included in the interval). \n * The matrixes of data, min and max values are stored as 1 dimension arrays *one row after the other. * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param min pointer to a matrix which specify the minimum value allowed for *each node * @param max pointer to a matrix which specify the Maximum value allowed for *each node * @return the number of elements that overcome the specified interval (0 = OK) */ int checkLimitsMap(i8 *data, int row, int column, int *min, int *max) { int i, j; int count = 0; for (i = 0; i < row; i++) { for (j = 0; j < column; j++) { if (data[i * column + j] < min[i * column + j] || data[i * column + j] > max[i * column + j]) { logError(1, "%s checkLimitsMap: Node[%d,%d] = %d exceed limit [%d, %d]\n", TAG, i, j, data[i * column + j], min[i * column + j], max[i * column + j]); count++; } } } return count; /* if count is 0 = OK, test completed successfully */ } /** * Check that each value of a matrix of short doesn't exceed a specific min and * Max value set for each node (these values are included in the interval). * The matrixes of data, min and max values are stored as 1 dimension arrays * one row after the other. * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param min pointer to a matrix which specify the minimum value allowed for * each node * @param max pointer to a matrix which specify the Maximum value allowed for * each node * @return the number of elements that overcome the specified interval (0 = OK) */ int checkLimitsMapTotal(short *data, int row, int column, int *min, int *max) { int i, j; int count = 0; for (i = 0; i < row; i++) { for (j = 0; j < column; j++) { if (data[i * column + j] < min[i * column + j] || data[i * column + j] > max[i * column + j]) { logError(1, "%s checkLimitsMapTotal: Node[%d,%d] = %d exceed limit [%d, %d]\n", TAG, i, j, data[i * column + j], min[i * column + j], max[i * column + j]); count++; } } } return count; /* if count is 0 = OK, test completed successfully */ } /** * Check that each value of a matrix of u8 doesn't exceed a specific min and * Max value set for each node (these values are included in the interval). \n * The matrixes of data, min and max values are stored as 1 dimension arrays * one row after the other. * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param min pointer to a matrix which specify the minimum value allowed for * each node * @param max pointer to a matrix which specify the Maximum value allowed for * each node * @return the number of elements that overcome the specified interval (0 = OK) */ int checkLimitsMapFromU(u8 *data, int row, int column, int *min, int *max) { int i, j; int count = 0; for (i = 0; i < row; i++) { for (j = 0; j < column; j++) { if (data[i * column + j] < min[i * column + j] || data[i * column + j] > max[i * column + j]) { logError(1, "%s checkLimitsMap: Node[%d,%d] = %d exceed limit [%d, %d]\n", TAG, i, j, data[i * column + j], min[i * column + j], max[i * column + j]); count++; } } } return count; /* if count is 0 = OK, test completed successfully */ } /** * Check that each value of a matrix of u16 doesn't exceed a specific min and * Max value set for each node (these values are included in the interval). * The matrixes of data, min and max values are stored as 1 dimension arrays * one row after the other. * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param min pointer to a matrix which specify the minimum value allowed for * each node * @param max pointer to a matrix which specify the Maximum value allowed for * each node * @return the number of elements that overcome the specified interval (0 = OK) */ int checkLimitsMapTotalFromU(u16 *data, int row, int column, int *min, int *max) { int i, j; int count = 0; for (i = 0; i < row; i++) { for (j = 0; j < column; j++) { if (data[i * column + j] < min[i * column + j] || data[i * column + j] > max[i * column + j]) { logError(1, "%s checkLimitsMapTotal: Node[%d,%d] = %d exceed limit [%d, %d]\n", TAG, i, j, data[i * column + j], min[i * column + j], max[i * column + j]); count++; } } } return count; /* if count is 0 = OK, test completed successfully */ } /** * Check that each value of a matrix of u8 doesn't exceed a specific Max value * set for each node (max value is included in the interval). * The matrixes of data and max values are stored as 1 dimension arrays one row * after the other. * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param max pointer to a matrix which specify the Maximum value allowed for *each node * @return the number of elements that overcome the specified interval (0 = OK) */ int checkLimitsMapAdj(u8 *data, int row, int column, int *max) { int i, j; int count = 0; for (i = 0; i < row; i++) { for (j = 0; j < column; j++) { if (data[i * column + j] > max[i * column + j]) { logError(1, "%s checkLimitsMapAdj: Node[%d,%d] = %d exceed limit > %d\n", TAG, i, j, data[i * column + j], max[i * column + j]); count++; } } } return count; /* if count is 0 = OK, test completed successfully */ } /** * Check that each value of a matrix of u16 doesn't exceed a specific Max value * set for each node (max value is included in the interval). * The matrixes of data and max values are stored as 1 dimension arrays one row * after the other. * @param data pointer to the array of short containing the data to check * @param row number of rows of data * @param column number of columns of data * @param max pointer to a matrix which specify the Maximum value allowed for * each node * @return the number of elements that overcome the specified interval (0 = OK) */ int checkLimitsMapAdjTotal(u16 *data, int row, int column, int *max) { int i, j; int count = 0; for (i = 0; i < row; i++) { for (j = 0; j < column; j++) { if (data[i * column + j] > max[i * column + j]) { logError(1, "%s checkLimitsMapAdjTotal: Node[%d,%d] = %d exceed limit > %d\n", TAG, i, j, data[i * column + j], max[i * column + j]); count++; } } } return count; /* if count is 0 = OK, test completed successfully */ } /** * Perform an ITO test setting all the possible options * (see @link ito_opt ITO Options @endlink) and checking MS Raw ADJ if enabled * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ito(char *path_limits, struct TestToDo *todo) { int res = OK; u8 sett[2] = { 0x00, 0x00 }; struct MutualSenseFrame msRawFrame; int *thresholds = NULL; u16 *adj = NULL; int trows, tcolumns; logError(0, "%s ITO Production test is starting...\n", TAG); res = fts_system_reset(); if (res < 0) { logError(1, "%s %s: ERROR %08X\n", TAG, __func__, ERROR_PROD_TEST_ITO); return res | ERROR_PROD_TEST_ITO; } sett[0] = SPECIAL_TUNING_IOFF; logError(0, "%s Trimming Ioff...\n", TAG); res = writeSysCmd(SYS_CMD_SPECIAL_TUNING, sett, 2); if (res < OK) { logError(1, "%s production_test_ito: Trimm Ioff ERROR %08X\n", TAG, (res | ERROR_PROD_TEST_ITO)); return res | ERROR_PROD_TEST_ITO; } sett[0] = 0xFF; sett[1] = 0xFF; logError(0, "%s ITO Check command sent...\n", TAG); res = writeSysCmd(SYS_CMD_ITO, sett, 2); if (res < OK) { logError(1, "%s production_test_ito: ERROR %08X\n", TAG, (res | ERROR_PROD_TEST_ITO)); return res | ERROR_PROD_TEST_ITO; } logError(0, "%s ITO Command = OK!\n", TAG); logError(0, "%s MS RAW ITO ADJ TEST:\n", TAG); if (todo->MutualRawAdjITO == 1) { logError(0, "%s Collecting MS Raw data...\n", TAG); res |= getMSFrame3(MS_RAW, &msRawFrame); if (res < OK) { logError(1, "%s %s: getMSFrame failed... ERROR %08X\n", TAG, __func__, ERROR_PROD_TEST_ITO); goto ERROR; } logError(0, "%s MS RAW ITO ADJ HORIZONTAL TEST:\n", TAG); res = computeAdjHorizTotal(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, &adj); if (res < OK) { logError(1, "%s %s: computeAdjHoriz failed... ERROR %08X\n", TAG, __func__, ERROR_PROD_TEST_ITO); goto ERROR; } res = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_ITO_ADJH, &thresholds, &trows, &tcolumns); if (res < OK || (trows != msRawFrame.header.force_node || tcolumns != msRawFrame.header.sense_node - 1)) { logError(1, "%s %s: parseProductionTestLimits MS_RAW_ITO_ADJH failed... ERROR %08X\n", TAG, __func__, ERROR_PROD_TEST_DATA); goto ERROR; } res = checkLimitsMapAdjTotal(adj, msRawFrame.header.force_node, msRawFrame.header.sense_node - 1, thresholds); if (res != OK) { logError(1, "%s production_test_data: checkLimitsAdj MS RAW ITO ADJH failed... ERROR COUNT = %d\n", TAG, res); logError(0, "%s MS RAW ITO ADJ HORIZONTAL TEST:.................FAIL\n\n", TAG); print_frame_short("MS Raw ITO frame =", array1dTo2d_short( msRawFrame.node_data, msRawFrame. node_data_size, msRawFrame.header. sense_node), msRawFrame.header.force_node, msRawFrame.header.sense_node); res = ERROR_PROD_TEST_ITO; goto ERROR; } else logError(0, "%s MS RAW ITO ADJ HORIZONTAL TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; kfree(adj); adj = NULL; logError(0, "%s MS RAW ITO ADJ VERTICAL TEST:\n", TAG); res = computeAdjVertTotal(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, &adj); if (res < OK) { logError(1, "%s %s: computeAdjVert failed... ERROR %08X\n", TAG, __func__, ERROR_PROD_TEST_ITO); goto ERROR; } res = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_ITO_ADJV, &thresholds, &trows, &tcolumns); if (res < OK || (trows != msRawFrame.header.force_node - 1 || tcolumns != msRawFrame.header.sense_node)) { logError(1, "%s %s: parseProductionTestLimits MS_RAW_ITO_ADJV failed... ERROR %08X\n", TAG, __func__, ERROR_PROD_TEST_ITO); goto ERROR; } res = checkLimitsMapAdjTotal(adj, msRawFrame.header.force_node - 1, msRawFrame.header.sense_node, thresholds); if (res != OK) { logError(1, "%s %s: checkLimitsAdj MS RAW ITO ADJV failed... ERROR COUNT = %d\n", TAG, __func__, res); logError(0, "%s MS RAW ITO ADJ VERTICAL TEST:.................FAIL\n\n", TAG); print_frame_short("MS Raw ITO frame =", array1dTo2d_short( msRawFrame.node_data, msRawFrame. node_data_size, msRawFrame.header. sense_node), msRawFrame.header.force_node, msRawFrame.header.sense_node); res = ERROR_PROD_TEST_ITO; goto ERROR; } else logError(0, "%s MS RAW ITO ADJ VERTICAL TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; kfree(adj); adj = NULL; } else logError(0, "%s MS RAW ITO ADJ TEST:.................SKIPPED\n", TAG); ERROR: if (thresholds != NULL) kfree(thresholds); if (adj != NULL) kfree(adj); if (msRawFrame.node_data != NULL) kfree(msRawFrame.node_data); freeLimitsFile(&limit_file); res |= fts_system_reset(); if (res < OK) { logError(1, "%s production_test_ito: ERROR %08X\n", TAG, ERROR_PROD_TEST_ITO); res = (res | ERROR_PROD_TEST_ITO); } return res; } /** * Perform the Initialization of the IC * @param type type of initialization to do * (see @link sys_special_opt Initialization Options (Full or Panel) @endlink) * @return OK if success or an error code which specify the type of error */ int production_test_initialization(u8 type) { int res; logError(0, "%s INITIALIZATION Production test is starting...\n", TAG); if (type != SPECIAL_PANEL_INIT && type != SPECIAL_FULL_PANEL_INIT) { logError(1, "%s production_test_initialization: Type incompatible! Type = %02X ERROR %08X\n", TAG, type, ERROR_OP_NOT_ALLOW | ERROR_PROD_TEST_INITIALIZATION); return ERROR_OP_NOT_ALLOW | ERROR_PROD_TEST_INITIALIZATION; } res = fts_system_reset(); if (res < 0) { logError(1, "%s production_test_initialization: ERROR %08X\n", TAG, ERROR_PROD_TEST_INITIALIZATION); return res | ERROR_PROD_TEST_INITIALIZATION; } logError(0, "%s INITIALIZATION command sent... %02X\n", TAG, type); res = writeSysCmd(SYS_CMD_SPECIAL, &type, 1); if (res < OK) { logError(1, "%s production_test_initialization: ERROR %08X\n", TAG, (res | ERROR_PROD_TEST_INITIALIZATION)); return res | ERROR_PROD_TEST_INITIALIZATION; } logError(0, "%s Refresh Sys Info...\n", TAG); res |= readSysInfo(1); /* need to update the chipInfo in order * to refresh several versions */ if (res < 0) { logError(1, "%s production_test_initialization: read sys info ERROR %08X\n", TAG, ERROR_PROD_TEST_INITIALIZATION); res = (res | ERROR_PROD_TEST_INITIALIZATION); } return res; } /** * Perform a FULL (ITO + INIT + DATA CHECK) Mass Production Test of the IC * @param pathThresholds name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure * otherwise it keeps going performing all the selected test * @param saveInit if >0 (possible values: NO_INIT, SPECIAL_PANEL_INIT or * SPECIAL_FULL_PANEL_INIT), * the Initialization of the IC is executed otherwise it is skipped * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_main(char *pathThresholds, int stop_on_fail, int saveInit, struct TestToDo *todo) { int res, ret; logError(0, "%s MAIN Production test is starting...\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s ITO TEST:\n", TAG); res = production_test_ito(pathThresholds, todo); if (res < 0) { logError(0, "%s Error during ITO TEST! ERROR %08X\n", TAG, res); goto END;/* in case of ITO TEST failure is no sense keep going */ } else logError(0, "%s ITO TEST OK!\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s INITIALIZATION TEST :\n", TAG); if (saveInit != NO_INIT) { res = production_test_initialization((u8)saveInit); if (res < 0) { logError(0, "%s Error during INITIALIZATION TEST! ERROR %08X\n", TAG, res); if (stop_on_fail) goto END; } else logError(0, "%s INITIALIZATION TEST OK!\n", TAG); } else logError(0, "%s INITIALIZATION TEST :................. SKIPPED\n", TAG); logError(0, "%s\n", TAG); if (saveInit != NO_INIT) { logError(0, "%s Cleaning up...\n", TAG); ret = fts_system_reset(); if (ret < 0) { logError(1, "%s production_test_main: system reset ERROR %08X\n", TAG, ret); res |= ret; if (stop_on_fail) goto END; } logError(0, "%s\n", TAG); } logError(0, "%s PRODUCTION DATA TEST:\n", TAG); ret = production_test_data(pathThresholds, stop_on_fail, todo); if (ret < 0) logError(0, "%s Error during PRODUCTION DATA TEST! ERROR %08X\n", TAG, ret); else logError(0, "%s PRODUCTION DATA TEST OK!\n", TAG); res |= ret; /* the OR is important because if the data test is OK but * the init test fail, the main production test result should = FAIL */ END: if (res < 0) { logError(0, "%s MAIN Production test finished.................FAILED\n", TAG); return res; } logError(0, "%s MAIN Production test finished.................OK\n", TAG); return OK; } /** * Perform all the test selected in a TestTodo variable related to MS raw data * (touch, keys etc..) * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure * otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ms_raw(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int ret, count_fail = 0; struct MutualSenseFrame msRawFrame; int *thresholds = NULL; int trows, tcolumns; int *thresholds_min = NULL; int *thresholds_max = NULL; u16 *adj = NULL; int maxAdjH, maxAdjV; int i, z; /************** Mutual Sense Test *************/ logError(0, "%s\n", TAG); logError(0, "%s MS RAW DATA TEST is starting...\n", TAG); if (todo->MutualRaw == 1 || todo->MutualRawGap == 1 || todo->MutualRawAdj == 1 || todo->MutualRawEachNode == 1 || todo->MutualRawAdjGap == 1 || todo->MutualRawAdjPeak == 1) { ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_ACTIVE); msleep(WAIT_FOR_FRESH_FRAMES); ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); msleep(WAIT_AFTER_SENSEOFF); ret |= getMSFrame3(MS_RAW, &msRawFrame); if (ret < OK) { logError(1, "%s production_test_data: getMSFrame failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } logError(0, "%s MS RAW MIN MAX TEST:\n", TAG); if (todo->MutualRaw == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMinMax(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, thresholds[0], thresholds[1]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax MS RAW failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW MIN MAX TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s MS RAW MIN MAX TEST:.................SKIPPED\n", TAG); logError(0, "%s MS RAW EACH NODE MIN MAX TEST:\n", TAG); if (todo->MutualRawEachNode == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_EACH_NODE_MIN, &thresholds_min, &trows, &tcolumns); if (ret < OK || (trows != msRawFrame.header.force_node || tcolumns != msRawFrame.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_EACH_NODE_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_EACH_NODE_MAX, &thresholds_max, &trows, &tcolumns); if (ret < OK || (trows != msRawFrame.header.force_node || tcolumns != msRawFrame.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_EACH_NODE_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapTotal(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, thresholds_min, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMaxEachNodeData failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS_RAW EACH NODE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS_RAW_EACH_NODE_MAX TEST:.................OK\n", TAG); if (thresholds_min != NULL) { kfree(thresholds_min); thresholds_min = NULL; } if (thresholds_max != NULL) { kfree(thresholds_max); thresholds_max = NULL; } } else { logError(0, "%s MS RAW EACH NODE MIN MAX TEST:.................SKIPPED\n", TAG); } logError(0, "%s\n", TAG); logError(0, "%s MS RAW GAP TEST:\n", TAG); if (todo->MutualRawGap == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_GAP, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_GAP failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsGap(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, thresholds[0]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsGap MS RAW failed... ERROR = %08X\n", TAG, ret); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW GAP TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s MS RAW GAP TEST:.................SKIPPED\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s MS RAW ADJ TEST:\n", TAG); if ((todo->MutualRawAdj == 1) || (todo->MutualRawAdjGap == 1) || (todo->MutualRawAdjPeak == 1)) { logError(0, "%s MS RAW ADJ HORIZONTAL TESTs:\n", TAG); ret = computeAdjHorizTotalSigned(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, &adj); if (ret < OK) { logError(1, "%s production_test_data: computeAdjHoriz failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } if (todo->MutualRawAdj) { logError(0, "%s MS RAW ADJ HORIZONTAL min/Max:\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_ADJH, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != msRawFrame.header.force_node || tcolumns != msRawFrame.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_ADJH failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(adj, msRawFrame.header. force_node, msRawFrame.header. sense_node - 1, thresholds); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsAdj MS RAW ADJH failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW ADJ HORIZONTAL min/Max:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW ADJ HORIZONTAL min/Max:.................OK\n", TAG); if (thresholds != NULL) { kfree(thresholds); thresholds = NULL; } } if (todo->MutualRawAdjGap) { logError(0, "%s MS RAW ADJ HORIZONTAL GAP:\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_ADJH_GAP, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_ADJH failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsGapOffsets(adj, msRawFrame.header. force_node, msRawFrame.header. sense_node - 1, thresholds[0], 1, 1, 1, 1); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsAdj MS RAW ADJH GAP failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW ADJ HORIZONTAL GAP:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW ADJ HORIZONTAL GAP:.................OK\n", TAG); if (thresholds != NULL) { kfree(thresholds); thresholds = NULL; } } if (todo->MutualRawAdjPeak) { logError(0, "%s MS RAW ADJ Peak: Getting max ADJH\n", TAG); maxAdjH = abs(adj[msRawFrame.header.force_node + 1]); /* skip nodes on the edges */ for (i = 1; i < msRawFrame.header .force_node - 1; i++) { for (z = 1; z < (msRawFrame.header .sense_node - 2); z++){ if (maxAdjH < abs(adj[(i * msRawFrame.header .force_node) + z])) maxAdjH = abs(adj[(i * msRawFrame.header .force_node) + z]); } } } kfree(adj); adj = NULL; logError(0, "%s MS RAW ADJ VERTICAL TESTs:\n", TAG); ret = computeAdjVertTotalSigned(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, &adj); if (ret < OK) { logError(1, "%s production_test_data: computeAdjVert failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } if (todo->MutualRawAdj) { logError(0, "%s MS RAW ADJ VERTICAL min/Max:\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_ADJV, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != msRawFrame.header.force_node - 1 || tcolumns != msRawFrame.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_ADJV failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(adj, msRawFrame.header. force_node - 1, msRawFrame.header. sense_node, thresholds); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsAdj MS RAW ADJV failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW ADJ VERTICAL min/Max:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW ADJ VERTICAL min/Max:.................OK\n", TAG); if (thresholds != NULL) { kfree(thresholds); thresholds = NULL; } } if (todo->MutualRawAdjGap) { logError(0, "%s MS RAW ADJ VERTICAL GAP:\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_ADJV_GAP, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_ADJV_GAP failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsGapOffsets(adj, msRawFrame.header. force_node - 1, msRawFrame.header. sense_node, thresholds[0], 1, 1, 1, 1); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsAdj MS RAW ADJV GAP failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW ADJ VERTICAL GAP:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW ADJ VERTICAL GAP:.................OK\n", TAG); if (thresholds != NULL) { kfree(thresholds); thresholds = NULL; } } if (todo->MutualRawAdjPeak) { logError(0, "%s MS RAW ADJ Peak: Get max ADJV\n", TAG); maxAdjV = abs(adj[(msRawFrame.header.force_node) + 1]); /* skip nodes on the edges */ for (i = 1; i < (msRawFrame.header .force_node - 2); i++) { for (z = 1; z < msRawFrame.header .sense_node - 1; z++) { if (maxAdjH < abs(adj[(i * msRawFrame.header .force_node) + z])) maxAdjH = abs(adj[(i * msRawFrame.header .force_node) + z]); } } ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_ADJ_PEAK, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_ADJV_PEAK failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(1, "%s maxAdjH = %d maxAdjV = %d threshold = %d\n", TAG, maxAdjH, maxAdjV, thresholds[0]); ret = OK; if (maxAdjH > maxAdjV) { if (maxAdjH > thresholds[0]) ret = ERROR_PROD_TEST_DATA; } else { if (maxAdjV > thresholds[0]) ret = ERROR_PROD_TEST_DATA; } if (ret != OK) { logError(1, "%s production_test_data: checkLimitsAdj MS RAW ADJV GAP failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW ADJ PEAK:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW ADJ PEAK:.................OK\n", TAG); if (thresholds != NULL) { kfree(thresholds); thresholds = NULL; } } kfree(adj); adj = NULL; } else logError(0, "%s MS RAW ADJ TEST:.................SKIPPED\n", TAG); } else logError(0, "%s MS RAW FRAME TEST:.................SKIPPED\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s MS KEY RAW TEST:\n", TAG); if (todo->MutualKeyRaw == 1) { ret = production_test_ms_key_raw(path_limits); if (ret < 0) { logError(1, "%s production_test_data: production_test_ms_key_raw failed... ERROR = %08X\n", TAG, ret); count_fail += 1; if (count_fail == 1) { logError(0, "%s MS RAW DATA TEST:.................FAIL fails_count = %d\n\n", TAG, count_fail); goto ERROR_LIMITS; } } } else logError(0, "%s MS KEY RAW TEST:.................SKIPPED\n", TAG); ret = production_test_ms_raw_lp(path_limits, stop_on_fail, todo); if (ret < 0) { logError(1, "%s production_test_data: production_test_ms_raw_lp failed... ERROR = %08X\n", TAG, ret); count_fail += 1; if (count_fail == 1) { logError(0, "%s MS RAW DATA TEST:.................FAIL fails_count = %d\n\n", TAG, count_fail); goto ERROR_LIMITS; } } ERROR: logError(0, "%s\n", TAG); if (count_fail == 0) { if (msRawFrame.node_data != NULL) { kfree(msRawFrame.node_data); msRawFrame.node_data = NULL; } logError(0, "%s MS RAW DATA TEST finished!.................OK\n", TAG); return OK; } else { print_frame_short("MS Raw frame =", array1dTo2d_short( msRawFrame.node_data, msRawFrame.node_data_size, msRawFrame.header.sense_node), msRawFrame.header.force_node, msRawFrame.header.sense_node); if (msRawFrame.node_data != NULL) kfree(msRawFrame.node_data); if (thresholds != NULL) kfree(thresholds); if (adj != NULL) kfree(adj); if (thresholds_min != NULL) { kfree(thresholds_min); thresholds_min = NULL; } if (thresholds_max != NULL) { kfree(thresholds_max); thresholds_max = NULL; } logError(0, "%s MS RAW DATA TEST:.................FAIL fails_count = %d\n\n", TAG, count_fail); return ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; } ERROR_LIMITS: if (msRawFrame.node_data != NULL) kfree(msRawFrame.node_data); if (thresholds != NULL) kfree(thresholds); return ret; } /** * Perform all the test selected in a TestTodo variable related to MS low power * raw data * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure * otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ms_raw_lp(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int ret, count_fail = 0; struct MutualSenseFrame msRawFrame; int *thresholds = NULL; int trows, tcolumns; u16 *adj = NULL; msRawFrame.node_data = NULL; /************** Mutual Sense Test **************/ logError(0, "%s\n", TAG); logError(0, "%s MS RAW LP DATA TEST:\n", TAG); if (todo->MutualRawLP == 1 || todo->MutualRawGapLP == 1 || todo->MutualRawAdjLP == 1) { ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_LP_ACTIVE); msleep(WAIT_FOR_FRESH_FRAMES); ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); msleep(WAIT_AFTER_SENSEOFF); ret |= getMSFrame3(MS_RAW, &msRawFrame); if (ret < 0) { logError(1, "%s production_test_data: getMSFrame failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } logError(0, "%s MS RAW LP MIN MAX TEST:\n", TAG); if (todo->MutualRawLP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_LP_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_LP_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMinMax(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, thresholds[0], thresholds[1]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax MS RAW LP failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW LP MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW LP MIN MAX TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s MS RAW LP MIN MAX TEST:.................SKIPPED\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s MS RAW LP GAP TEST:\n", TAG); if (todo->MutualRawGapLP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_LP_GAP, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_LP_GAP failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsGap(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, thresholds[0]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsGap MS RAW LP failed... ERROR = %08X\n", TAG, ret); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW LP GAP TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s MS RAW LP GAP TEST:.................SKIPPED\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s MS RAW LP ADJ TEST:\n", TAG); if (todo->MutualRawAdjLP == 1) { logError(0, "%s MS RAW LP ADJ HORIZONTAL TEST:\n", TAG); ret = computeAdjHorizTotal(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, &adj); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_LP_ADJH, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != msRawFrame.header.force_node || tcolumns != msRawFrame.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_LP_ADJH failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(adj, msRawFrame.header. force_node, msRawFrame.header. sense_node - 1, thresholds); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsAdj MS RAW LP ADJH failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW LP ADJ HORIZONTAL TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW LP ADJ HORIZONTAL TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; kfree(adj); adj = NULL; logError(0, "%s MS RAW LP ADJ VERTICAL TEST:\n", TAG); ret = computeAdjVertTotal(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, &adj); if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_RAW_LP_ADJV, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != msRawFrame.header.force_node - 1 || tcolumns != msRawFrame.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_RAW_ADJV failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(adj, msRawFrame.header. force_node - 1, msRawFrame.header. sense_node, thresholds); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsAdj MS RAW ADJV failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS RAW LP ADJ VERTICAL TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail == 1) goto ERROR; } else logError(0, "%s MS RAW LP ADJ VERTICAL TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; kfree(adj); adj = NULL; } else logError(0, "%s MS RAW LP ADJ TEST:.................SKIPPED\n", TAG); } else logError(0, "%s MS RAW LP FRAME TEST:.................SKIPPED\n", TAG); ERROR: logError(0, "%s\n", TAG); if (count_fail == 0) { if (msRawFrame.node_data != NULL) { kfree(msRawFrame.node_data); msRawFrame.node_data = NULL; } logError(0, "%s MS RAW DATA TEST finished!.................OK\n", TAG); return OK; } if (msRawFrame.node_data != NULL) { print_frame_short("MS Raw LP frame =", array1dTo2d_short( msRawFrame.node_data, msRawFrame. node_data_size, msRawFrame.header. sense_node), msRawFrame.header.force_node, msRawFrame.header.sense_node); kfree(msRawFrame.node_data); } if (thresholds != NULL) kfree(thresholds); if (adj != NULL) kfree(adj); logError(0, "%s MS RAW LP DATA TEST:.................FAIL fails_count = %d\n\n", TAG, count_fail); return ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; ERROR_LIMITS: if (msRawFrame.node_data != NULL) kfree(msRawFrame.node_data); if (thresholds != NULL) kfree(thresholds); return ret; } /** * Perform MS raw test for keys data * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @return OK if success or an error code which specify the type of error */ int production_test_ms_key_raw(char *path_limits) { int ret; struct MutualSenseFrame msRawFrame; int *thresholds = NULL; int trows, tcolumns; /************** Mutual Sense Test **************/ logError(0, "%s MS KEY RAW DATA TEST is starting...\n", TAG); ret = setScanMode(SCAN_MODE_ACTIVE, 0xFF); msleep(WAIT_FOR_FRESH_FRAMES); ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); msleep(WAIT_AFTER_SENSEOFF); ret |= getMSFrame3(MS_KEY_RAW, &msRawFrame); if (ret < 0) { logError(1, "%s production_test_data: getMSKeyFrame failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_KEY_RAW_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_KEY_RAW_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMinMax(msRawFrame.node_data, msRawFrame.header.force_node, msRawFrame.header.sense_node, thresholds[0], thresholds[1]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax MS KEY RAW failed... ERROR COUNT = %d\n", TAG, ret); goto ERROR; } else logError(0, "%s MS KEY RAW TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; kfree(msRawFrame.node_data); msRawFrame.node_data = NULL; return OK; ERROR: print_frame_short("MS Key Raw frame =", array1dTo2d_short( msRawFrame.node_data, msRawFrame.node_data_size, msRawFrame.header.sense_node), msRawFrame.header.force_node, msRawFrame.header.sense_node); if (msRawFrame.node_data != NULL) kfree(msRawFrame.node_data); if (thresholds != NULL) kfree(thresholds); logError(0, "%s MS KEY RAW TEST:.................FAIL\n\n", TAG); return ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; ERROR_LIMITS: if (msRawFrame.node_data != NULL) kfree(msRawFrame.node_data); if (thresholds != NULL) kfree(thresholds); return ret; } /** * Perform all the tests selected in a TestTodo variable related to MS Init * data (touch, keys etc..) * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ms_cx(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int ret; int count_fail = 0; int *thresholds = NULL; int *thresholds_min = NULL; int *thresholds_max = NULL; int trows, tcolumns; struct MutualSenseData msCompData; struct TotMutualSenseData totCompData; u8 *adjhor = NULL; u8 *adjvert = NULL; u16 container; /* u16 *total_cx = NULL; */ u16 *total_adjhor = NULL; u16 *total_adjvert = NULL; /* MS CX TEST */ logError(0, "%s\n", TAG); logError(0, "%s MS CX Testes are starting...\n", TAG); ret = readMutualSenseCompensationData(LOAD_CX_MS_TOUCH, &msCompData); /* read MS compensation data */ if (ret < 0) { logError(1, "%s production_test_data: readMutualSenseCompensationData failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } ret = readTotMutualSenseCompensationData(LOAD_PANEL_CX_TOT_MS_TOUCH, &totCompData); /* read TOT MS compensation data */ if (ret < 0) { logError(1, "%s production_test_data: readTotMutualSenseCompensationData failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); kfree(msCompData.node_data); msCompData.node_data = NULL; return ret | ERROR_PROD_TEST_DATA; } logError(0, "%s MS CX1 TEST:\n", TAG); if (todo->MutualCx1 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX1_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX1_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } container = (u16)msCompData.cx1; ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], thresholds[1]); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax MS CX1 failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS CX1 TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS CX1 TEST:.................OK\n\n", TAG); } else logError(0, "%s MS CX1 TEST:.................SKIPPED\n\n", TAG); kfree(thresholds); thresholds = NULL; logError(0, "%s MS CX2 MIN MAX TEST:\n", TAG); if (todo->MutualCx2 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX2_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load min thresholds */ if (ret < 0 || (trows != msCompData.header.force_node || tcolumns != msCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX2_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX2_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load max thresholds */ if (ret < 0 || (trows != msCompData.header.force_node || tcolumns != msCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX2_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMap(msCompData.node_data, msCompData.header.force_node, msCompData.header.sense_node, thresholds_min, thresholds_max); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap MS CX2 MIN MAX failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS CX2 MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS CX2 MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s MS CX2 MIN MAX TEST:.................SKIPPED\n\n", TAG); logError(0, "%s MS CX2 ADJ TEST:\n", TAG); if (todo->MutualCx2Adj == 1) { /* MS CX2 ADJ HORIZ */ logError(0, "%s MS CX2 ADJ HORIZ TEST:\n", TAG); ret = computeAdjHoriz(msCompData.node_data, msCompData.header.force_node, msCompData.header.sense_node, &adjhor); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s MS CX2 ADJ HORIZ computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX2_ADJH_MAP_MAX, &thresholds_max, &trows, &tcolumns); if (ret < 0 || (trows != msCompData.header.force_node || tcolumns != msCompData.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX2_ADJH_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdj(adjhor, msCompData.header.force_node, msCompData.header.sense_node - 1, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj CX2 ADJH failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS CX2 ADJ HORIZ TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS CX2 ADJ HORIZ TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(adjhor); adjhor = NULL; /* MS CX2 ADJ VERT */ logError(0, "%s MS CX2 ADJ VERT TEST:\n", TAG); ret = computeAdjVert(msCompData.node_data, msCompData.header.force_node, msCompData.header.sense_node, &adjvert); if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s MS CX2 ADJ VERT computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX2_ADJV_MAP_MAX, &thresholds_max, &trows, &tcolumns); if (ret < 0 || (trows != msCompData.header.force_node - 1 || tcolumns != msCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX2_ADJV_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdj(adjvert, msCompData.header.force_node - 1, msCompData.header.sense_node - 1, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj CX2 ADJV failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS CX2 ADJ HORIZ TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS CX2 ADJ VERT TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(adjvert); adjvert = NULL; } else logError(0, "%s MS CX2 ADJ TEST:.................SKIPPED\n\n", TAG); /* START OF TOTAL CHECK */ logError(0, "%s MS TOTAL CX TEST:\n", TAG); if (todo->MutualCxTotal == 1 || todo->MutualCxTotalAdj == 1) { logError(0, "%s MS TOTAL CX MIN MAX TEST:\n", TAG); if (todo->MutualCxTotal == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_TOTAL_CX_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load min thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_TOTAL_CX_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load max thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapTotal(totCompData.node_data, totCompData.header.force_node, totCompData.header.sense_node, thresholds_min, thresholds_max); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap MS TOTAL CX TEST failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS TOTAL CX MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS TOTAL CX MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s MS TOTAL CX MIN MAX TEST:.................SKIPPED\n\n", TAG); logError(0, "%s MS TOTAL CX ADJ TEST:\n", TAG); if (todo->MutualCxTotalAdj == 1) { /* MS TOTAL CX ADJ HORIZ */ logError(0, "%s MS TOTAL CX ADJ HORIZ TEST:\n", TAG); ret = computeAdjHorizTotal(totCompData.node_data, totCompData.header.force_node, totCompData.header.sense_node, &total_adjhor); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s MS TOTAL CX ADJ HORIZ computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_TOTAL_CX_ADJH_MAP_MAX, &thresholds_max, &trows, &tcolumns); if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != totCompData.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_ADJH_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(total_adjhor, totCompData.header. force_node, totCompData.header. sense_node - 1, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj MS TOTAL CX ADJH failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS TOTAL CX ADJ HORIZ TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS TOTAL CX ADJ HORIZ TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(total_adjhor); total_adjhor = NULL; /* MS TOTAL CX ADJ VERT */ logError(0, "%s MS TOTAL CX ADJ VERT TEST:\n", TAG); ret = computeAdjVertTotal(totCompData.node_data, totCompData.header.force_node, totCompData.header.sense_node, &total_adjvert); if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s MS TOTAL CX ADJ VERT computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_TOTAL_CX_ADJV_MAP_MAX, &thresholds_max, &trows, &tcolumns); if (ret < 0 || (trows != totCompData.header.force_node - 1 || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_ADJV_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(total_adjvert, totCompData.header. force_node - 1, totCompData.header. sense_node - 1, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj MS TOTAL CX ADJV failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS TOTAL CX ADJ HORIZ TEST:.................FAIL\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS TOTAL CX ADJ VERT TEST:.................OK\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(total_adjvert); total_adjvert = NULL; } else logError(0, "%s MS TOTAL CX ADJ TEST:.................SKIPPED\n", TAG); kfree(totCompData.node_data); totCompData.node_data = NULL; } else logError(0, "%s MS TOTAL CX TEST:.................SKIPPED\n", TAG); if ((todo->MutualCx1LP | todo->MutualCx2LP | todo->MutualCx2AdjLP | todo->MutualCxTotalLP | todo->MutualCxTotalAdjLP) == 1) { ret = production_test_ms_cx_lp(path_limits, stop_on_fail, todo); if (ret < OK) { count_fail += 1; logError(1, "%s production_test_data: production_test_cx_lp failed... ERROR = %08X\n", TAG, ret); logError(0, "%s MS CX testes finished!.................FAILED fails_count = %d\n\n", TAG, count_fail); return ret; } } else logError(0, "%s MS CX LP TEST:.................SKIPPED\n", TAG); if ((todo->MutualKeyCx1 | todo->MutualKeyCx2 | todo->MutualKeyCxTotal) == 1) { ret = production_test_ms_key_cx(path_limits, stop_on_fail, todo); if (ret < 0) { count_fail += 1; logError(1, "%s production_test_data: production_test_ms_key_cx failed... ERROR = %08X\n", TAG, ret); logError(0, "%s MS CX testes finished!.................FAILED fails_count = %d\n\n", TAG, count_fail); return ret; } } else logError(0, "%s MS KEY CX TEST:.................SKIPPED\n", TAG); ERROR: logError(0, "%s\n", TAG); if (count_fail == 0) { logError(0, "%s MS CX testes finished!.................OK\n", TAG); kfree(msCompData.node_data); msCompData.node_data = NULL; return OK; } print_frame_i8("MS Init Data (Cx2) =", array1dTo2d_i8( msCompData.node_data, msCompData.node_data_size, msCompData.header.sense_node), msCompData.header.force_node, msCompData.header.sense_node); print_frame_short(" TOT MS Init Data (Cx) =", array1dTo2d_short( totCompData.node_data, totCompData.node_data_size, totCompData.header.sense_node), totCompData.header.force_node, totCompData.header.sense_node); logError(0, "%s MS CX testes finished!.................FAILED fails_count = %d\n\n", TAG, count_fail); if (thresholds != NULL) kfree(thresholds); if (thresholds_min != NULL) kfree(thresholds_min); if (thresholds_max != NULL) kfree(thresholds_max); if (adjhor != NULL) kfree(adjhor); if (adjvert != NULL) kfree(adjvert); if (totCompData.node_data != NULL) kfree(totCompData.node_data); if (total_adjhor != NULL) kfree(total_adjhor); if (total_adjvert != NULL) kfree(total_adjvert); if (msCompData.node_data != NULL) kfree(msCompData.node_data); return ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA; ERROR_LIMITS: if (thresholds != NULL) kfree(thresholds); if (thresholds_min != NULL) kfree(thresholds_min); if (thresholds_max != NULL) kfree(thresholds_max); if (adjhor != NULL) kfree(adjhor); if (adjvert != NULL) kfree(adjvert); if (totCompData.node_data != NULL) kfree(totCompData.node_data); if (total_adjhor != NULL) kfree(total_adjhor); if (total_adjvert != NULL) kfree(total_adjvert); if (msCompData.node_data != NULL) kfree(msCompData.node_data); return ret; } /** * Perform all the tests selected in a TestTodo variable related to MS Init * data of the keys * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure * otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ms_key_cx(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int ret; int count_fail = 0; int num_keys = 0; int *thresholds = NULL; int *thresholds_min = NULL; int *thresholds_max = NULL; int trows, tcolumns; struct MutualSenseData msCompData; struct TotMutualSenseData totCompData; short container; /* MS CX TEST */ logError(0, "%s MS KEY CX Testes are starting...\n", TAG); ret = readMutualSenseCompensationData(LOAD_CX_MS_KEY, &msCompData); /* read MS compensation data */ if (ret < 0) { logError(1, "%s production_test_data: readMutualSenseCompensationData failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } if (msCompData.header.force_node > msCompData.header.sense_node) /* the meaningful data are only in the first row, * the other rows are only a copy of the first one */ num_keys = msCompData.header.force_node; else num_keys = msCompData.header.sense_node; logError(0, "%s MS KEY CX1 TEST:\n", TAG); if (todo->MutualKeyCx1 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_KEY_CX1_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_KEY_CX1_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } container = (short)msCompData.cx1; ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], thresholds[1]); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax MS CX1 failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS KEY CX1 TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS KEY CX1 TEST:.................OK\n\n", TAG); } else logError(0, "%s MS KEY CX1 TEST:.................SKIPPED\n\n", TAG); kfree(thresholds); thresholds = NULL; logError(0, "%s MS KEY CX2 TEST:\n", TAG); if (todo->MutualKeyCx2 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_KEY_CX2_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load min thresholds */ if (ret < 0 || (trows != msCompData.header.force_node || tcolumns != msCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_KEY_CX2_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_KEY_CX2_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load max thresholds */ if (ret < 0 || (trows != msCompData.header.force_node || tcolumns != msCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_KEY_CX2_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMap(msCompData.node_data, msCompData.header.force_node, msCompData.header.sense_node, thresholds_min, thresholds_max); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap MS KEY CX2 failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS KEY CX2 TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS KEY CX2 TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s MS CX2 TEST:.................SKIPPED\n\n", TAG); /* START OF TOTAL CHECK */ logError(0, "%s MS KEY TOTAL CX TEST:\n", TAG); if (todo->MutualKeyCxTotal == 1) { ret = readTotMutualSenseCompensationData( LOAD_PANEL_CX_TOT_MS_KEY, &totCompData); if (ret < 0) { logError(1, "%s production_test_data: computeTotalCx failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_KEY_TOTAL_CX_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load min thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_KEY_TOTAL_CX_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_KEY_TOTAL_CX_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load max thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_KEY_TOTAL_CX_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapTotal(totCompData.node_data, totCompData.header.force_node, totCompData.header.sense_node, thresholds_min, thresholds_max); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap MS TOTAL KEY CX TEST failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS KEY TOTAL CX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS KEY TOTAL CX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; kfree(totCompData.node_data); totCompData.node_data = NULL; } else logError(0, "%s MS KEY TOTAL CX TEST:.................SKIPPED\n", TAG); ERROR: logError(0, "%s\n", TAG); if (count_fail == 0) { logError(0, "%s MS KEY CX testes finished!.................OK\n", TAG); kfree(msCompData.node_data); msCompData.node_data = NULL; return OK; } print_frame_i8("MS Key Init Data (Cx2) =", array1dTo2d_i8( msCompData.node_data, msCompData.node_data_size, msCompData.header.sense_node), msCompData.header.force_node, msCompData.header.sense_node); logError(0, "%s MS Key CX testes finished!.................FAILED fails_count = %d\n\n", TAG, count_fail); if (thresholds != NULL) kfree(thresholds); if (thresholds_min != NULL) kfree(thresholds_min); if (thresholds_max != NULL) kfree(thresholds_max); if (msCompData.node_data != NULL) kfree(msCompData.node_data); if (totCompData.node_data != NULL) kfree(totCompData.node_data); return ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA; ERROR_LIMITS: if (thresholds != NULL) kfree(thresholds); if (thresholds_min != NULL) kfree(thresholds_min); if (thresholds_max != NULL) kfree(thresholds_max); if (msCompData.node_data != NULL) kfree(msCompData.node_data); if (totCompData.node_data != NULL) kfree(totCompData.node_data); return ret; } /** * Perform all the tests selected in a TestTodo variable related to MS LowPower * Init data (touch, keys etc..) * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ms_cx_lp(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int ret; int count_fail = 0; int *thresholds = NULL; int *thresholds_min = NULL; int *thresholds_max = NULL; int trows, tcolumns; struct MutualSenseData msCompData; struct TotMutualSenseData totCompData; u8 *adjhor = NULL; u8 *adjvert = NULL; u16 container; /* u16 *total_cx = NULL; */ u16 *total_adjhor = NULL; u16 *total_adjvert = NULL; /* MS CX TEST */ logError(0, "%s\n", TAG); logError(0, "%s MS LP CX Testes are starting...\n", TAG); ret = readMutualSenseCompensationData(LOAD_CX_MS_LOW_POWER, &msCompData); /* read MS compensation data */ if (ret < 0) { logError(1, "%s production_test_data: readMutualSenseCompensationData failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } ret = readTotMutualSenseCompensationData(LOAD_PANEL_CX_TOT_MS_LOW_POWER, &totCompData); /* read TOT MS compensation data */ if (ret < 0) { logError(1, "%s production_test_data: readTotMutualSenseCompensationData failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); kfree(msCompData.node_data); msCompData.node_data = NULL; return ret | ERROR_PROD_TEST_DATA; } logError(0, "%s MS LP CX1 TEST:\n", TAG); if (todo->MutualCx1LP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX1_LP_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX1_LP_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } container = (u16)msCompData.cx1; ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], thresholds[1]); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax MS LP CX1 failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS LP CX1 TEST:..............FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS LP CX1 TEST:.................OK\n\n", TAG); } else logError(0, "%s MS LP CX1 TEST:.................SKIPPED\n\n", TAG); kfree(thresholds); thresholds = NULL; logError(0, "%s MS LP CX2 MIN MAX TEST:\n", TAG); if (todo->MutualCx2LP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX2_LP_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load min thresholds */ if (ret < 0 || (trows != msCompData.header.force_node || tcolumns != msCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX2_LP_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX2_LP_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load max thresholds */ if (ret < 0 || (trows != msCompData.header.force_node || tcolumns != msCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX2_LP_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMap(msCompData.node_data, msCompData.header.force_node, msCompData.header.sense_node, thresholds_min, thresholds_max); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap MS LP CX2 MIN MAX failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS LP CX2 MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS LP CX2 MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s MS LP CX2 MIN MAX TEST:.................SKIPPED\n\n", TAG); logError(0, "%s MS LP CX2 ADJ TEST:\n", TAG); if (todo->MutualCx2AdjLP == 1) { /* MS CX2 ADJ HORIZ */ logError(0, "%s MS LP CX2 ADJ HORIZ TEST:\n", TAG); ret = computeAdjHoriz(msCompData.node_data, msCompData.header.force_node, msCompData.header.sense_node, &adjhor); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s MS LP CX2 ADJ HORIZ computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX2_ADJH_LP_MAP_MAX, &thresholds_max, &trows, &tcolumns); if (ret < 0 || (trows != msCompData.header.force_node || tcolumns != msCompData.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX2_ADJH_LP_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdj(adjhor, msCompData.header.force_node, msCompData.header.sense_node - 1, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj CX2 ADJH LP failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS LP CX2 ADJ HORIZ TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS LP CX2 ADJ HORIZ TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(adjhor); adjhor = NULL; /* MS CX2 ADJ VERT */ logError(0, "%s MS LP CX2 ADJ VERT TEST:\n", TAG); ret = computeAdjVert(msCompData.node_data, msCompData.header.force_node, msCompData.header.sense_node, &adjvert); if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s MS LP CX2 ADJ VERT computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_CX2_ADJV_LP_MAP_MAX, &thresholds_max, &trows, &tcolumns); if (ret < 0 || (trows != msCompData.header.force_node - 1 || tcolumns != msCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_CX2_ADJV_LP_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdj(adjvert, msCompData.header.force_node - 1, msCompData.header.sense_node - 1, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj CX2 ADJV LP failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS LP CX2 ADJ HORIZ TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS LP CX2 ADJ VERT TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(adjvert); adjvert = NULL; } else logError(0, "%s MS LP CX2 ADJ TEST:..........SKIPPED\n\n", TAG); /* START OF TOTAL CHECK */ logError(0, "%s MS TOTAL LP CX TEST:\n", TAG); if (todo->MutualCxTotalLP == 1 || todo->MutualCxTotalAdjLP == 1) { logError(0, "%s MS TOTAL LP CX MIN MAX TEST:\n", TAG); if (todo->MutualCxTotalLP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, MS_TOTAL_CX_LP_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load min thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_LP_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, MS_TOTAL_CX_LP_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load max thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_LP_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapTotal(totCompData.node_data, totCompData.header.force_node, totCompData.header.sense_node, thresholds_min, thresholds_max); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap MS TOTAL CX LP TEST failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS TOTAL CX LP MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS TOTAL CX LP MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s MS TOTAL CX LP MIN MAX TEST:.................SKIPPED\n\n", TAG); logError(0, "%s MS TOTAL CX ADJ LP TEST:\n", TAG); if (todo->MutualCxTotalAdjLP == 1) { /* MS TOTAL CX ADJ HORIZ */ logError(0, "%s MS TOTAL CX ADJ HORIZ LP TEST:\n", TAG); ret = computeAdjHorizTotal(totCompData.node_data, totCompData.header.force_node, totCompData.header.sense_node, &total_adjhor); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s MS TOTAL CX ADJ HORIZ LP computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_TOTAL_CX_ADJH_LP_MAP_MAX, &thresholds_max, &trows, &tcolumns); if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != totCompData.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_ADJH_LP_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(total_adjhor, totCompData.header. force_node, totCompData.header. sense_node - 1, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj MS TOTAL CX ADJH LP failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS TOTAL CX ADJ HORIZ LP TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS TOTAL CX ADJ HORIZ LP TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(total_adjhor); total_adjhor = NULL; /* MS TOTAL CX ADJ VERT */ logError(0, "%s MS TOTAL CX ADJ VERT LP TEST:\n", TAG); ret = computeAdjVertTotal(totCompData.node_data, totCompData.header.force_node, totCompData.header.sense_node, &total_adjvert); if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s MS TOTAL CX ADJ VERT LP computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, MS_TOTAL_CX_ADJV_LP_MAP_MAX, &thresholds_max, &trows, &tcolumns); if (ret < 0 || (trows != totCompData.header.force_node - 1 || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits MS_TOTAL_CX_ADJV_LP_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(total_adjvert, totCompData.header. force_node - 1, totCompData.header. sense_node - 1, thresholds_max); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj MS TOTAL CX ADJV failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s MS TOTAL CX ADJ HORIZ LP TEST:.................FAIL\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s MS TOTAL CX ADJ VERT LP TEST:.................OK\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(total_adjvert); total_adjvert = NULL; } else logError(0, "%s MS TOTAL CX ADJ LP TEST:.................SKIPPED\n", TAG); kfree(totCompData.node_data); totCompData.node_data = NULL; } else logError(0, "%s MS TOTAL CX LP TEST:.................SKIPPED\n", TAG); ERROR: logError(0, "%s\n", TAG); if (count_fail == 0) { logError(0, "%s MS LP CX testes finished!.................OK\n", TAG); kfree(msCompData.node_data); msCompData.node_data = NULL; return OK; } print_frame_i8("MS LP Init Data (Cx2) =", array1dTo2d_i8( msCompData.node_data, msCompData.node_data_size, msCompData.header.sense_node), msCompData.header.force_node, msCompData.header.sense_node); print_frame_short(" TOT MS LP Init Data (Cx) =", array1dTo2d_short( totCompData.node_data, totCompData.node_data_size, totCompData.header.sense_node), totCompData.header.force_node, totCompData.header.sense_node); logError(0, "%s MS LP CX testes finished!.................FAILED fails_count = %d\n\n", TAG, count_fail); if (thresholds != NULL) kfree(thresholds); if (thresholds_min != NULL) kfree(thresholds_min); if (thresholds_max != NULL) kfree(thresholds_max); if (adjhor != NULL) kfree(adjhor); if (adjvert != NULL) kfree(adjvert); if (totCompData.node_data != NULL) kfree(totCompData.node_data); if (total_adjhor != NULL) kfree(total_adjhor); if (total_adjvert != NULL) kfree(total_adjvert); if (msCompData.node_data != NULL) kfree(msCompData.node_data); return ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA; ERROR_LIMITS: if (thresholds != NULL) kfree(thresholds); if (thresholds_min != NULL) kfree(thresholds_min); if (thresholds_max != NULL) kfree(thresholds_max); if (adjhor != NULL) kfree(adjhor); if (adjvert != NULL) kfree(adjvert); if (totCompData.node_data != NULL) kfree(totCompData.node_data); if (total_adjhor != NULL) kfree(total_adjhor); if (total_adjvert != NULL) kfree(total_adjvert); if (msCompData.node_data != NULL) kfree(msCompData.node_data); return ret; } /** * Perform all the test selected in a TestTodo variable related to SS raw data * (touch, keys etc..) * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure * otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ss_raw(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int ret; int count_fail = 0; int rows, columns; struct SelfSenseFrame ssRawFrame; int *thresholds = NULL; int trows, tcolumns; /* SS TEST */ logError(0, "%s\n", TAG); logError(0, "%s SS RAW Testes are starting...\n", TAG); /************** Self Sense Test **************/ logError(0, "%s Getting SS Frame...\n", TAG); ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_ACTIVE); msleep(WAIT_FOR_FRESH_FRAMES); ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); msleep(WAIT_AFTER_SENSEOFF); ret |= getSSFrame3(SS_RAW, &ssRawFrame); if (ret < 0) { logError(1, "%s production_test_data: getSSFrame failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } /* SS RAW (PROXIMITY) FORCE TEST */ logError(0, "%s SS RAW FORCE TEST:\n", TAG); if (todo->SelfForceRaw == 1 || todo->SelfForceRawGap == 1) { columns = 1; /* there are no data for the sense channels * because is a force frame */ rows = ssRawFrame.header.force_node; logError(0, "%s SS RAW FORCE MIN MAX TEST:\n", TAG); if (todo->SelfForceRaw == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_RAW_FORCE_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_RAW_FORCE_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMinMax(ssRawFrame.force_data, rows, columns, thresholds[0], thresholds[1]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax SS RAW FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS RAW (PROXIMITY) FORCE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; print_frame_short("SS Raw force frame =", array1dTo2d_short( ssRawFrame.force_data, rows * columns, columns), rows, columns); if (stop_on_fail) { ret = ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; goto ERROR_LIMITS; } } else logError(0, "%s SS RAW FORCE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS RAW FORCE MIN MAX TEST:.................SKIPPED\n\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s SS RAW FORCE GAP TEST:\n", TAG); if (todo->SelfForceRawGap == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_RAW_FORCE_GAP, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_RAW_FORCE_GAP failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsGap(ssRawFrame.force_data, rows, columns, thresholds[0]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsGap SS RAW FORCE GAP failed... ERROR = %08X\n", TAG, ret); logError(0, "%s SS RAW FORCE GAP TEST:.................FAIL\n\n", TAG); count_fail += 1; print_frame_short("SS Raw force frame =", array1dTo2d_short( ssRawFrame.force_data, rows * columns, columns), rows, columns); if (stop_on_fail) { ret = ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; goto ERROR_LIMITS; } } else logError(0, "%s SS RAW FORCE GAP TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS RAW FORCE GAP TEST:.................SKIPPED\n\n", TAG); kfree(ssRawFrame.force_data); ssRawFrame.force_data = NULL; } else logError(0, "%s SS RAW FORCE TEST:.................SKIPPED\n\n", TAG); logError(0, "%s\n", TAG); /* SS RAW (PROXIMITY) SENSE TEST */ logError(0, "%s SS RAW SENSE TEST:\n", TAG); if (todo->SelfSenseRaw == 1 || todo->SelfSenseRawGap == 1) { columns = ssRawFrame.header.sense_node; rows = 1; /* there are no data for the force channels * because is a sense frame */ logError(0, "%s SS RAW SENSE MIN MAX TEST:\n", TAG); if (todo->SelfSenseRaw == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_RAW_SENSE_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMinMax(ssRawFrame.sense_data, rows, columns, thresholds[0], thresholds[1]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax SS RAW SENSE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS RAW SENSE MIN MAX TEST:.................FAIL\n", TAG); count_fail += 1; print_frame_short("SS Raw sense frame =", array1dTo2d_short( ssRawFrame.sense_data, rows * columns, columns), rows, columns); if (stop_on_fail) { ret = ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; goto ERROR_LIMITS; } } else logError(0, "%s SS RAW SENSE MIN MAX TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS RAW SENSE MIN MAX TEST:.................SKIPPED\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s SS RAW SENSE GAP TEST:\n", TAG); if (todo->SelfSenseRawGap == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_RAW_SENSE_GAP, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_GAP failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsGap(ssRawFrame.sense_data, rows, columns, thresholds[0]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsGap SS RAW SENSE GAP failed... ERROR = %08X\n", TAG, ret); logError(0, "%s SS RAW SENSE GAP TEST:.................FAIL\n", TAG); count_fail += 1; print_frame_short("SS Raw sense frame =", array1dTo2d_short( ssRawFrame.sense_data, rows * columns, columns), rows, columns); if (stop_on_fail) { ret = ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; goto ERROR_LIMITS; } } else logError(0, "%s SS RAW SENSE GAP TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS RAW SENSE GAP TEST:.................SKIPPED\n", TAG); kfree(ssRawFrame.sense_data); ssRawFrame.sense_data = NULL; } else logError(0, "%s SS RAW SENSE TEST:.................SKIPPED\n\n", TAG); ret = production_test_ss_raw_lp(path_limits, stop_on_fail, todo); if (ret < OK) { logError(1, "%s production_test_data: production_test_ss_raw_lp failed... ERROR = %08X\n", TAG, ret); count_fail += 1; } logError(0, "%s\n", TAG); if (count_fail == 0) { logError(0, "%s SS RAW testes finished!.................OK\n\n", TAG); return OK; } logError(0, "%s SS RAW testes finished!.................FAILED fails_count = %d\n\n", TAG, count_fail); return ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA; ERROR_LIMITS: if (ssRawFrame.force_data != NULL) kfree(ssRawFrame.force_data); if (ssRawFrame.sense_data != NULL) kfree(ssRawFrame.sense_data); if (thresholds != NULL) kfree(thresholds); return ret; } /** * Perform all the test selected in a TestTodo variable related to SS raw data * low power * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure * otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ss_raw_lp(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int ret; int count_fail = 0; int rows, columns; struct SelfSenseFrame ssRawFrame; int *thresholds = NULL; int trows, tcolumns; /* SS TEST */ logError(0, "%s\n", TAG); logError(0, "%s SS RAW LP Testes are starting...\n", TAG); /************** Self Sense Test **************/ logError(0, "%s Getting SS LP Frame...\n", TAG); ret = setScanMode(SCAN_MODE_LOCKED, LOCKED_LP_DETECT); msleep(WAIT_FOR_FRESH_FRAMES); ret |= setScanMode(SCAN_MODE_ACTIVE, 0x00); msleep(WAIT_AFTER_SENSEOFF); ret |= getSSFrame3(SS_RAW, &ssRawFrame); if (ret < 0) { logError(1, "%s production_test_data: getSSFrame failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } /* SS RAW (PROXIMITY) FORCE TEST */ logError(0, "%s SS RAW LP FORCE TEST:\n", TAG); if (todo->SelfForceRawLP == 1 || todo->SelfForceRawGapLP == 1) { columns = 1; /* there are no data for the sense channels * because is a force frame */ rows = ssRawFrame.header.force_node; logError(0, "%s SS RAW LP FORCE MIN MAX TEST:\n", TAG); if (todo->SelfForceRawLP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_RAW_LP_FORCE_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_RAW_FORCE_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMinMax(ssRawFrame.force_data, rows, columns, thresholds[0], thresholds[1]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax SS RAW FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS RAW LP FORCE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; print_frame_short("SS Raw LP force frame =", array1dTo2d_short( ssRawFrame.force_data, rows * columns, columns), rows, columns); if (stop_on_fail) { ret = ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; goto ERROR_LIMITS; } } else logError(0, "%s SS RAW LP FORCE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS RAW LP FORCE MIN MAX TEST:.................SKIPPED\n\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s SS RAW LP FORCE GAP TEST:\n", TAG); if (todo->SelfForceRawGapLP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_RAW_LP_FORCE_GAP, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_RAW_FORCE_GAP failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsGap(ssRawFrame.force_data, rows, columns, thresholds[0]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsGap SS RAW FORCE GAP failed... ERROR = %08X\n", TAG, ret); logError(0, "%s SS RAW LP FORCE GAP TEST:.................FAIL\n\n", TAG); count_fail += 1; print_frame_short("SS Raw LP force frame =", array1dTo2d_short( ssRawFrame.force_data, rows * columns, columns), rows, columns); if (stop_on_fail) { ret = ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; goto ERROR_LIMITS; } } else logError(0, "%s SS RAW LP FORCE GAP TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS RAW LP FORCE GAP TEST:.................SKIPPED\n\n", TAG); kfree(ssRawFrame.force_data); ssRawFrame.force_data = NULL; } else logError(0, "%s SS RAW LP FORCE TEST:.................SKIPPED\n\n", TAG); logError(0, "%s\n", TAG); /* SS RAW (PROXIMITY) SENSE TEST */ logError(0, "%s SS RAW LP SENSE TEST:\n", TAG); if (todo->SelfSenseRawLP == 1 || todo->SelfSenseRawGapLP == 1) { columns = ssRawFrame.header.sense_node; rows = 1; /* there are no data for the force channels * because is a sense frame */ logError(0, "%s SS RAW LP SENSE MIN MAX TEST:\n", TAG); if (todo->SelfSenseRawLP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_RAW_LP_SENSE_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMinMax(ssRawFrame.sense_data, rows, columns, thresholds[0], thresholds[1]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax SS RAW SENSE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS RAW LP SENSE MIN MAX TEST:.................FAIL\n", TAG); count_fail += 1; print_frame_short("SS Raw LP sense frame =", array1dTo2d_short( ssRawFrame.sense_data, rows * columns, columns), rows, columns); if (stop_on_fail) { ret = ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; goto ERROR_LIMITS; } } else logError(0, "%s SS RAW LP SENSE MIN MAX TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS RAW LP SENSE MIN MAX TEST:.................SKIPPED\n", TAG); logError(0, "%s\n", TAG); logError(0, "%s SS RAW LP SENSE GAP TEST:\n", TAG); if (todo->SelfSenseRawGapLP == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_RAW_LP_SENSE_GAP, &thresholds, &trows, &tcolumns); if (ret < OK || (trows != 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_RAW_SENSE_GAP failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsGap(ssRawFrame.sense_data, rows, columns, thresholds[0]); if (ret != OK) { logError(1, "%s production_test_data: checkLimitsGap SS RAW SENSE GAP failed... ERROR = %08X\n", TAG, ret); logError(0, "%s SS RAW LP SENSE GAP TEST:.................FAIL\n", TAG); count_fail += 1; print_frame_short("SS Raw LP sense frame =", array1dTo2d_short( ssRawFrame.sense_data, rows * columns, columns), rows, columns); if (stop_on_fail) { ret = ERROR_PROD_TEST_DATA | ERROR_TEST_CHECK_FAIL; goto ERROR_LIMITS; } } else logError(0, "%s SS RAW LP SENSE GAP TEST:.................OK\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS RAW LP SENSE GAP TEST:.................SKIPPED\n", TAG); kfree(ssRawFrame.sense_data); ssRawFrame.sense_data = NULL; } logError(0, "%s\n", TAG); if (count_fail == 0) { logError(0, "%s SS RAW LP testes finished!.................OK\n\n", TAG); return OK; } logError(0, "%s SS RAW LP testes finished!.................FAILED fails_count = %d\n\n", TAG, count_fail); return ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA; ERROR_LIMITS: if (ssRawFrame.force_data != NULL) kfree(ssRawFrame.force_data); if (ssRawFrame.sense_data != NULL) kfree(ssRawFrame.sense_data); if (thresholds != NULL) kfree(thresholds); return ret; } /** * Perform all the tests selected in a TestTodo variable related to SS Init * data (touch, keys etc..) * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure * otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_ss_ix_cx(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int ret; int count_fail = 0; int *thresholds = NULL; int trows, tcolumns; int *thresholds_min = NULL; int *thresholds_max = NULL; struct SelfSenseData ssCompData; struct TotSelfSenseData totCompData; u8 *adjhor = NULL; u8 *adjvert = NULL; short container; u16 *total_adjhor = NULL; u16 *total_adjvert = NULL; logError(0, "%s\n", TAG); logError(0, "%s SS IX CX testes are starting...\n", TAG); ret = readSelfSenseCompensationData(LOAD_CX_SS_TOUCH, &ssCompData); /* read the SS compensation data */ if (ret < 0) { logError(1, "%s production_test_data: readSelfSenseCompensationData failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); return ret | ERROR_PROD_TEST_DATA; } ret = readTotSelfSenseCompensationData(LOAD_PANEL_CX_TOT_SS_TOUCH, &totCompData); /* read the TOT SS compensation data */ if (ret < 0) { logError(1, "%s production_test_data: readTotSelfSenseCompensationData failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); kfree(ssCompData.ix2_fm); kfree(ssCompData.ix2_sn); kfree(ssCompData.cx2_fm); kfree(ssCompData.cx2_sn); return ret | ERROR_PROD_TEST_DATA; } /************* SS FORCE IX **************/ /* SS IX1 FORCE TEST */ logError(0, "%s SS IX1 FORCE TEST:\n", TAG); if (todo->SelfForceIx1 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_IX1_FORCE_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX1_FORCE_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } container = (short)ssCompData.f_ix1; ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], thresholds[1]); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax SS IX1 FORCE TEST failed... ERROR COUNT = %d\n", TAG, ret); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS IX1 FORCE TEST:.................OK\n\n", TAG); } else logError(0, "%s SS IX1 FORCE TEST:.................SKIPPED\n\n", TAG); kfree(thresholds); thresholds = NULL; /* SS IX2 FORCE TEST */ logError(0, "%s SS IX2 FORCE MIN MAX TEST:\n", TAG); if (todo->SelfForceIx2 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_IX2_FORCE_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load the min thresholds */ if (ret < 0 || (trows != ssCompData.header.force_node || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX2_FORCE_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, SS_IX2_FORCE_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != ssCompData.header.force_node || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX2_FORCE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapFromU(ssCompData.ix2_fm, ssCompData.header.force_node, 1, thresholds_min, thresholds_max); /* check the * values with * thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS IX2 FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS IX2 FORCE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS IX2 FORCE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s SS IX2 FORCE MIN MAX TEST:.................SKIPPED\n\n", TAG); logError(0, "%s SS IX2 FORCE ADJ TEST:\n", TAG); if (todo->SelfForceIx2Adj == 1) { /* SS IX2 FORCE ADJV TEST */ logError(0, "%s SS IX2 FORCE ADJVERT TEST:\n", TAG); ret = computeAdjVertFromU(ssCompData.ix2_fm, ssCompData.header.force_node, 1, &adjvert); if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert SS IX2 FORCE ADJV failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s SS IX2 FORCE ADJV computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, SS_IX2_FORCE_ADJV_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max * thresholds */ if (ret < 0 || (trows != ssCompData.header.force_node - 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX2_FORCE_ADJV_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdj(adjvert, ssCompData.header.force_node - 1, 1, thresholds_max); /* check the * values with * thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS IX2 FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS IX2 FORCE ADJV TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS IX2 FORCE ADJV TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(adjvert); adjvert = NULL; } else logError(0, "%s SS IX2 FORCE ADJ TEST:.................SKIPPED\n\n", TAG); /* SS TOTAL FORCE IX */ logError(0, "%s SS TOTAL IX FORCE TEST:\n", TAG); if (todo->SelfForceIxTotal == 1 || todo->SelfForceIxTotalAdj == 1) { logError(0, "%s SS TOTAL IX FORCE MIN MAX TEST:\n", TAG); if (todo->SelfForceIxTotal == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_IX_FORCE_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load the min thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_FORCE_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_IX_FORCE_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_FORCE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapTotalFromU(totCompData.ix_fm, totCompData.header. force_node, 1, thresholds_min, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS TOTAL IX FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS TOTAL IX FORCE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS TOTAL IX FORCE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s SS TOTAL IX FORCE MIN MAX TEST:.................SKIPPED\n", TAG); logError(0, "%s SS TOTAL IX FORCE ADJ TEST:\n", TAG); if (todo->SelfForceIxTotalAdj == 1) { /* SS TOTAL IX FORCE ADJV TEST */ logError(0, "%s SS TOTAL IX FORCE ADJVERT TEST:\n", TAG); ret = computeAdjVertTotalFromU(totCompData.ix_fm, totCompData.header. force_node, 1, &total_adjvert); if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert SS TOTAL IX FORCE ADJV failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s SS TOTAL IX FORCE ADJV computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_IX_FORCE_ADJV_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != totCompData.header.force_node - 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_FORCE_ADJV_MAP_MAX... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(total_adjvert, totCompData.header. force_node - 1, 1, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS TOTAL IX FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS TOTAL IX FORCE ADJV TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS TOTAL IX FORCE ADJV TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(total_adjvert); total_adjvert = NULL; } else logError(0, "%s SS TOTAL IX FORCE ADJ TEST:.................SKIPPED\n", TAG); } else logError(0, "%s SS TOTAL IX FORCE TEST:.................SKIPPED\n\n", TAG); /************** SS SENSE IX **************/ /* SS IX1 SENSE TEST */ logError(0, "%s SS IX1 SENSE TEST:\n", TAG); if (todo->SelfSenseIx1 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_IX1_SENSE_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX1_SENSE_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } container = (short)ssCompData.s_ix1; ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], thresholds[1]); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax SS IX1 SENSE TEST failed... ERROR COUNT = %d\n", TAG, ret); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS IX1 SENSE TEST:.................OK\n\n", TAG); } else logError(0, "%s SS IX1 SENSE TEST:.................SKIPPED\n\n", TAG); kfree(thresholds); thresholds = NULL; /* SS IX2 SENSE TEST */ logError(0, "%s SS IX2 SENSE MIN MAX TEST:\n", TAG); if (todo->SelfSenseIx2 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_IX2_SENSE_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load the min thresholds */ if (ret < 0 || (trows != 1 || tcolumns != ssCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX2_SENSE_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, SS_IX2_SENSE_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != 1 || tcolumns != ssCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX2_SENSE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapFromU(ssCompData.ix2_sn, 1, ssCompData.header.sense_node, thresholds_min, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS IX2 SENSE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS IX2 SENSE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS IX2 SENSE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s SS IX2 SENSE MIN MAX TEST:.................SKIPPED\n\n", TAG); logError(0, "%s SS IX2 SENSE ADJ TEST:\n", TAG); if (todo->SelfSenseIx2Adj == 1) { /* SS IX2 SENSE ADJH TEST */ logError(0, "%s SS IX2 SENSE ADJHORIZ TEST:\n", TAG); ret = computeAdjHorizFromU(ssCompData.ix2_sn, 1, ssCompData.header.sense_node, &adjhor); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz SS IX2 SENSE ADJH failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s SS IX2 SENSE ADJ HORIZ computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, SS_IX2_SENSE_ADJH_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != 1 || tcolumns != ssCompData.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX2_SENSE_ADJH_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdj(adjhor, 1, ssCompData.header.sense_node - 1, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj SS IX2 SENSE ADJH failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS IX2 SENSE ADJH TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS IX2 SENSE ADJH TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(adjhor); adjhor = NULL; } else logError(0, "%s SS IX2 SENSE ADJ TEST:.................SKIPPED\n", TAG); /* SS TOTAL IX SENSE */ logError(0, "%s SS TOTAL IX SENSE TEST:\n", TAG); if (todo->SelfSenseIxTotal == 1 || todo->SelfSenseIxTotalAdj == 1) { logError(0, "%s SS TOTAL IX SENSE MIN MAX TEST:\n", TAG); if (todo->SelfSenseIxTotal == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_IX_SENSE_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load the min thresholds */ if (ret < 0 || (trows != 1 || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_SENSE_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_IX_SENSE_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != 1 || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_SENSE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapTotalFromU(totCompData.ix_sn, 1, totCompData.header. sense_node, thresholds_min, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS TOTAL IX SENSE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS TOTAL IX SENSE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS TOTAL IX SENSE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s SS TOTAL IX SENSE MIN MAX TEST:.................SKIPPED\n", TAG); logError(0, "%s SS TOTAL IX SENSE ADJ TEST:\n", TAG); if (todo->SelfSenseIxTotalAdj == 1) { /* SS TOTAL IX SENSE ADJH TEST */ logError(0, "%s SS TOTAL IX SENSE ADJHORIZ TEST:\n", TAG); ret = computeAdjHorizTotalFromU(totCompData.ix_sn, 1, totCompData.header. sense_node, &total_adjhor); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz SS TOTAL IX SENSE ADJH failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s SS TOTAL IX SENSE ADJ HORIZ computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_IX_SENSE_ADJH_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != 1 || tcolumns != totCompData.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_IX_SENSE_ADJH_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(total_adjhor, 1, totCompData.header. sense_node - 1, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj SS TOTAL IX SENSE ADJH failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS TOTAL IX SENSE ADJH TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS TOTAL IX SENSE ADJH TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(total_adjhor); total_adjhor = NULL; } else logError(0, "%s SS TOTAL IX SENSE ADJ TEST:.................SKIPPED\n", TAG); } else logError(0, "%s SS TOTAL IX SENSE TEST:.................SKIPPED\n", TAG); /************* SS SENSE CX **************/ /* SS CX1 FORCE TEST */ logError(0, "%s SS CX1 FORCE TEST:\n", TAG); if (todo->SelfForceCx1 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_CX1_FORCE_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_CX1_FORCE_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } container = (short)ssCompData.f_cx1; ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], thresholds[1]); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax SS CX1 FORCE TEST failed... ERROR COUNT = %d\n", TAG, ret); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS CX1 FORCE TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS CX1 FORCE TEST:.................SKIPPED\n\n", TAG); /* SS CX2 FORCE TEST */ logError(0, "%s SS CX2 FORCE MIN MAX TEST:\n", TAG); if (todo->SelfForceCx2 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_CX2_FORCE_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load the min thresholds */ if (ret < 0 || (trows != ssCompData.header.force_node || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_CX2_FORCE_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, SS_CX2_FORCE_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != ssCompData.header.force_node || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_CX2_FORCE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMap(ssCompData.cx2_fm, ssCompData.header.force_node, 1, thresholds_min, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS CX2 FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS CX2 FORCE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS CX2 FORCE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s SS CX2 FORCE MIN MAX TEST:.................SKIPPED\n", TAG); logError(0, "%s SS CX2 FORCE ADJ TEST:\n", TAG); if (todo->SelfForceCx2Adj == 1) { /* SS CX2 FORCE ADJV TEST */ logError(0, "%s SS CX2 FORCE ADJVERT TEST:\n", TAG); ret = computeAdjVert(ssCompData.cx2_fm, ssCompData.header.force_node, 1, &adjvert); /* compute the ADJV for CX2 FORCE */ if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert SS CX2 FORCE ADJV failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s SS CX2 FORCE ADJV computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, SS_CX2_FORCE_ADJV_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != ssCompData.header.force_node - 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_CX2_FORCE_ADJV_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdj(adjvert, ssCompData.header.force_node - 1, 1, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS IX2 FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS CX2 FORCE ADJV TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS CX2 FORCE ADJV TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(adjvert); adjvert = NULL; } else logError(0, "%s SS CX2 FORCE ADJ TEST:.................SKIPPED\n\n", TAG); /* SS TOTAL CX FORCE */ logError(0, "%s SS TOTAL CX FORCE TEST:\n", TAG); if (todo->SelfForceCxTotal == 1 || todo->SelfForceCxTotalAdj == 1) { logError(0, "%s SS TOTAL CX FORCE MIN MAX TEST:\n", TAG); if (todo->SelfForceCxTotal == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_CX_FORCE_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load the min thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_FORCE_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_CX_FORCE_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != totCompData.header.force_node || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_FORCE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapTotal(totCompData.cx_fm, totCompData.header.force_node, 1, thresholds_min, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS TOTAL FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS TOTAL FORCE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS TOTAL FORCE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s SS TOTAL CX FORCE MIN MAX TEST:.................SKIPPED\n", TAG); /* SS TOTAL CX FORCE ADJV TEST */ logError(0, "%s SS TOTAL CX FORCE ADJ TEST:\n", TAG); if (todo->SelfForceCxTotalAdj == 1) { logError(0, "%s SS TOTAL CX FORCE ADJVERT TEST:\n", TAG); ret = computeAdjVertTotal(totCompData.cx_fm, totCompData.header.force_node, 1, &total_adjvert); /* compute the ADJV for CX2 FORCE */ if (ret < 0) { logError(1, "%s production_test_data: computeAdjVert SS TOTAL CX FORCE ADJV failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s SS TOTAL CX FORCE ADJV computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_CX_FORCE_ADJV_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != totCompData.header.force_node - 1 || tcolumns != 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_FORCE_ADJV_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(total_adjvert, totCompData.header. force_node - 1, 1, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS TOTAL CX FORCE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS TOTAL CX FORCE ADJV TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS TOTAL CX FORCE ADJV TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(total_adjvert); total_adjvert = NULL; } else logError(0, "%s SS TOTAL CX FORCE ADJ TEST:.................SKIPPED\n", TAG); } else logError(0, "%s SS TOTAL CX FORCE TEST:.................SKIPPED\n\n", TAG); /************* SS SENSE CX *************/ /* SS CX1 SENSE TEST */ logError(0, "%s SS CX1 SENSE TEST:\n", TAG); if (todo->SelfSenseCx1 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_CX1_SENSE_MIN_MAX, &thresholds, &trows, &tcolumns); if (ret < 0 || (trows != 1 || tcolumns != 2)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_CX1_SENSE_MIN_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } container = (short)ssCompData.s_cx1; ret = checkLimitsMinMax(&container, 1, 1, thresholds[0], thresholds[1]); /* check the limits */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMinMax SS CX1 SENSE TEST failed... ERROR COUNT = %d\n", TAG, ret); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS CX1 SENSE TEST:.................OK\n\n", TAG); kfree(thresholds); thresholds = NULL; } else logError(0, "%s SS CX1 SENSE TEST:.................SKIPPED\n\n", TAG); /* SS CX2 SENSE TEST */ logError(0, "%s SS CX2 SENSE MIN MAX TEST:\n", TAG); if (todo->SelfSenseCx2 == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_CX2_SENSE_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load the min thresholds */ if (ret < 0 || (trows != 1 || tcolumns != ssCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_CX2_SENSE_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, SS_CX2_SENSE_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != 1 || tcolumns != ssCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_CX2_SENSE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMap(ssCompData.cx2_sn, 1, ssCompData.header.sense_node, thresholds_min, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS CX2 SENSE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS CX2 SENSE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS CX2 SENSE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s SS CX2 SENSE MIN MAX TEST:.................SKIPPED\n", TAG); logError(0, "%s SS CX2 SENSE ADJ TEST:\n", TAG); if (todo->SelfSenseCx2Adj == 1) { /* SS CX2 SENSE ADJH TEST */ logError(0, "%s SS CX2 SENSE ADJHORIZ TEST:\n", TAG); ret = computeAdjHoriz(ssCompData.cx2_sn, 1, ssCompData.header.sense_node, &adjhor); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz SS CX2 SENSE ADJH failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s SS CX2 SENSE ADJH computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, SS_CX2_SENSE_ADJH_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != 1 || tcolumns != ssCompData.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_IX2_SENSE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdj(adjhor, 1, ssCompData.header.sense_node - 1, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj SS CX2 SENSE ADJH failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS CX2 SENSE ADJH TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS CX2 SENSE ADJH TEST:.................OK\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(adjhor); adjhor = NULL; } else logError(0, "%s SS CX2 SENSE ADJ TEST:.................SKIPPED\n\n", TAG); /* SS TOTAL CX SENSE */ logError(0, "%s SS TOTAL CX SENSE TEST:\n", TAG); if (todo->SelfSenseCxTotal == 1 || todo->SelfSenseCxTotalAdj == 1) { logError(0, "%s SS TOTAL CX SENSE MIN MAX TEST:\n", TAG); if (todo->SelfSenseCxTotal == 1) { ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_CX_SENSE_MAP_MIN, &thresholds_min, &trows, &tcolumns); /* load the min thresholds */ if (ret < 0 || (trows != 1 || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_SENSE_MAP_MIN failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_CX_SENSE_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != 1 || tcolumns != totCompData.header.sense_node)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_SENSE_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapTotal(totCompData.cx_sn, 1, totCompData.header.sense_node, thresholds_min, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMap SS TOTAL CX SENSE failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS TOTAL CX SENSE MIN MAX TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS TOTAL CX SENSE MIN MAX TEST:.................OK\n\n", TAG); kfree(thresholds_min); thresholds_min = NULL; kfree(thresholds_max); thresholds_max = NULL; } else logError(0, "%s SS TOTAL CX SENSE MIN MAX TEST:.................SKIPPED\n", TAG); /* SS TOTAL IX SENSE ADJH TEST */ logError(0, "%s SS TOTAL CX SENSE ADJ TEST:\n", TAG); if (todo->SelfSenseCxTotalAdj == 1) { logError(0, "%s SS TOTAL CX SENSE ADJHORIZ TEST:\n", TAG); ret = computeAdjHorizTotal(totCompData.cx_sn, 1, totCompData.header.sense_node, &total_adjhor); if (ret < 0) { logError(1, "%s production_test_data: computeAdjHoriz SS TOTAL CX SENSE ADJH failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } logError(0, "%s SS TOTAL CX SENSE ADJ HORIZ computed!\n", TAG); ret = parseProductionTestLimits(path_limits, &limit_file, SS_TOTAL_CX_SENSE_ADJH_MAP_MAX, &thresholds_max, &trows, &tcolumns); /* load the max thresholds */ if (ret < 0 || (trows != 1 || tcolumns != totCompData.header.sense_node - 1)) { logError(1, "%s production_test_data: parseProductionTestLimits SS_TOTAL_CX_SENSE_ADJH_MAP_MAX failed... ERROR %08X\n", TAG, ERROR_PROD_TEST_DATA); ret |= ERROR_PROD_TEST_DATA; goto ERROR_LIMITS; } ret = checkLimitsMapAdjTotal(total_adjhor, 1, totCompData.header. sense_node - 1, thresholds_max); /* check the values with thresholds */ if (ret != OK) { logError(1, "%s production_test_data: checkLimitsMapAdj SS TOTAL CX SENSE ADJH failed... ERROR COUNT = %d\n", TAG, ret); logError(0, "%s SS TOTAL CX SENSE ADJH TEST:.................FAIL\n\n", TAG); count_fail += 1; if (stop_on_fail) goto ERROR; } else logError(0, "%s SS TOTAL CX SENSE ADJH TEST:.................OK\n\n", TAG); kfree(thresholds_max); thresholds_max = NULL; kfree(total_adjhor); total_adjhor = NULL; } else logError(0, "%s SS TOTAL CX SENSE ADJ TEST:.................SKIPPED\n", TAG); } else logError(0, "%s SS TOTAL CX SENSE TEST:.................SKIPPED\n", TAG); ERROR: logError(0, "%s\n", TAG); if (count_fail == 0) { kfree(ssCompData.ix2_fm); ssCompData.ix2_fm = NULL; kfree(ssCompData.ix2_sn); ssCompData.ix2_sn = NULL; kfree(ssCompData.cx2_fm); ssCompData.cx2_fm = NULL; kfree(ssCompData.cx2_sn); ssCompData.cx2_sn = NULL; kfree(totCompData.ix_fm); totCompData.ix_fm = NULL; kfree(totCompData.ix_sn); totCompData.ix_sn = NULL; kfree(totCompData.cx_fm); totCompData.cx_fm = NULL; kfree(totCompData.cx_sn); totCompData.cx_sn = NULL; logError(0, "%s SS IX CX testes finished!.................OK\n\n", TAG); return OK; } /* print all kind of data in just one row for readability reason */ print_frame_u8("SS Init Data Ix2_fm = ", array1dTo2d_u8( ssCompData.ix2_fm, ssCompData.header.force_node, 1), ssCompData.header.force_node, 1); print_frame_i8("SS Init Data Cx2_fm = ", array1dTo2d_i8( ssCompData.cx2_fm, ssCompData.header.force_node, 1), ssCompData.header.force_node, 1); print_frame_u8("SS Init Data Ix2_sn = ", array1dTo2d_u8( ssCompData.ix2_sn, ssCompData.header.sense_node, ssCompData.header.sense_node), 1, ssCompData.header.sense_node); print_frame_i8("SS Init Data Cx2_sn = ", array1dTo2d_i8( ssCompData.cx2_sn, ssCompData.header.sense_node, ssCompData.header.sense_node), 1, ssCompData.header.sense_node); print_frame_u16("TOT SS Init Data Ix_fm = ", array1dTo2d_u16( totCompData.ix_fm, totCompData.header.force_node, 1), totCompData.header.force_node, 1); print_frame_short("TOT SS Init Data Cx_fm = ", array1dTo2d_short(totCompData.cx_fm, totCompData.header. force_node, 1), totCompData.header.force_node, 1); print_frame_u16("TOT SS Init Data Ix_sn = ", array1dTo2d_u16( totCompData.ix_sn, totCompData.header.sense_node, totCompData.header.sense_node), 1, totCompData.header.sense_node); print_frame_short("TOT SS Init Data Cx_sn = ", array1dTo2d_short(totCompData.cx_sn, totCompData.header. sense_node, totCompData.header. sense_node), 1, totCompData.header.sense_node); logError(0, "%s SS IX CX testes finished!.................FAILED fails_count = %d\n\n", TAG, count_fail); if (thresholds != NULL) kfree(thresholds); if (thresholds_min != NULL) kfree(thresholds_min); if (thresholds_max != NULL) kfree(thresholds_max); if (adjhor != NULL) kfree(adjhor); if (adjvert != NULL) kfree(adjvert); if (total_adjhor != NULL) kfree(total_adjhor); if (total_adjvert != NULL) kfree(total_adjvert); if (ssCompData.ix2_fm != NULL) kfree(ssCompData.ix2_fm); if (ssCompData.ix2_sn != NULL) kfree(ssCompData.ix2_sn); if (ssCompData.cx2_fm != NULL) kfree(ssCompData.cx2_fm); if (ssCompData.cx2_sn != NULL) kfree(ssCompData.cx2_sn); if (totCompData.ix_fm != NULL) kfree(totCompData.ix_fm); if (totCompData.ix_sn != NULL) kfree(totCompData.ix_sn); if (totCompData.cx_fm != NULL) kfree(totCompData.cx_fm); if (totCompData.cx_sn != NULL) kfree(totCompData.cx_sn); return ERROR_TEST_CHECK_FAIL | ERROR_PROD_TEST_DATA; ERROR_LIMITS: if (thresholds != NULL) kfree(thresholds); if (thresholds_min != NULL) kfree(thresholds_min); if (thresholds_max != NULL) kfree(thresholds_max); if (adjhor != NULL) kfree(adjhor); if (adjvert != NULL) kfree(adjvert); if (total_adjhor != NULL) kfree(total_adjhor); if (total_adjvert != NULL) kfree(total_adjvert); if (ssCompData.ix2_fm != NULL) kfree(ssCompData.ix2_fm); if (ssCompData.ix2_sn != NULL) kfree(ssCompData.ix2_sn); if (ssCompData.cx2_fm != NULL) kfree(ssCompData.cx2_fm); if (ssCompData.cx2_sn != NULL) kfree(ssCompData.cx2_sn); if (totCompData.ix_fm != NULL) kfree(totCompData.ix_fm); if (totCompData.ix_sn != NULL) kfree(totCompData.ix_sn); if (totCompData.cx_fm != NULL) kfree(totCompData.cx_fm); if (totCompData.cx_sn != NULL) kfree(totCompData.cx_sn); return ret; } /** * Perform a complete Data Test check of the IC * @param path_limits name of Production Limit file to load or * "NULL" if the limits data should be loaded by a .h file * @param stop_on_fail if 1, the test flow stops at the first data check * failure otherwise it keeps going performing all the selected test * @param todo pointer to a TestToDo variable which select the test to do * @return OK if success or an error code which specify the type of error */ int production_test_data(char *path_limits, int stop_on_fail, struct TestToDo *todo) { int res = OK, ret; if (todo == NULL) { logError(1, "%s production_test_data: No TestToDo specified!! ERROR = %08X\n", TAG, (ERROR_OP_NOT_ALLOW | ERROR_PROD_TEST_DATA)); return ERROR_OP_NOT_ALLOW | ERROR_PROD_TEST_DATA; } logError(0, "%s DATA Production test is starting...\n", TAG); ret = production_test_ms_raw(path_limits, stop_on_fail, todo); res |= ret; if (ret < 0) { logError(1, "%s production_test_data: production_test_ms_raw failed... ERROR = %08X\n", TAG, ret); if (stop_on_fail == 1) goto END; } ret = production_test_ms_cx(path_limits, stop_on_fail, todo); res |= ret; if (ret < 0) { logError(1, "%s production_test_data: production_test_ms_cx failed... ERROR = %08X\n", TAG, ret); if (stop_on_fail == 1) goto END; } ret = production_test_ss_raw(path_limits, stop_on_fail, todo); res |= ret; if (ret < 0) { logError(1, "%s production_test_data: production_test_ss_raw failed... ERROR = %08X\n", TAG, ret); if (stop_on_fail == 1) goto END; } ret = production_test_ss_ix_cx(path_limits, stop_on_fail, todo); res |= ret; if (ret < 0) { logError(1, "%s production_test_data: production_test_ss_ix_cx failed... ERROR = %08X\n", TAG, ret); if (stop_on_fail == 1) goto END; } END: freeLimitsFile(&limit_file); /* /< release the limit file loaded * during the test */ if (res < OK) logError(0, "%s DATA Production test failed!\n", TAG); else logError(0, "%s DATA Production test finished!\n", TAG); return res; } /** * Retrieve the actual Test Limit data from the system (bin file or header *file) * @param path name of Production Test Limit file to load or "NULL" if the *limits data should be loaded by a .h file * @param file pointer to the LimitFile struct which will contains the limits *data * @return OK if success or an error code which specify the type of error *encountered */ int getLimitsFile(char *path, struct LimitFile *file) { const struct firmware *fw = NULL; struct device *dev = NULL; int fd = -1; logError(0, "%s Get Limits File starting... %s\n", TAG, path); if (file->data != NULL) {/* to avoid memory leak on consecutive call of * the function with the same pointer */ logError(0, "%s Pointer to Limits Data already contains something... freeing its content!\n", TAG); kfree(file->data); file->data = NULL; file->size = 0; } strlcpy(file->name, path, MAX_LIMIT_FILE_NAME); if (strncmp(path, "NULL", 4) == 0) { #ifdef LIMITS_H_FILE logError(0, "%s Loading Limits File from .h!\n", TAG); file->size = LIMITS_SIZE_NAME; file->data = kmalloc((file->size) * sizeof(char), GFP_KERNEL); if (file->data != NULL) { memcpy(file->data, (char *)(LIMITS_ARRAY_NAME), file->size); return OK; } logError(1, "%s Error while allocating data... ERROR %08X\n", TAG, path, ERROR_ALLOC); return ERROR_ALLOC; #else logError(1, "%s limit file path NULL... ERROR %08X\n", TAG, ERROR_FILE_NOT_FOUND); return ERROR_FILE_NOT_FOUND; #endif } else { dev = getDev(); if (dev != NULL) { logError(0, "%s Loading Limits File from .csv!\n", TAG); fd = request_firmware(&fw, path, dev); if (fd == 0) { logError(0, "%s Start to copy %s...\n", TAG, path); file->size = fw->size; file->data = kmalloc((file->size) * sizeof(char), GFP_KERNEL); if (file->data != NULL) { memcpy(file->data, (char *)fw->data, file->size); logError(0, "%s Limit file Size = %d\n", TAG, file->size); release_firmware(fw); return OK; } logError(1, "%s Error while allocating data... ERROR %08X\n", TAG, ERROR_ALLOC); release_firmware(fw); return ERROR_ALLOC; } logError(1, "%s Request the file %s failed... ERROR %08X\n", TAG, path, ERROR_FILE_NOT_FOUND); return ERROR_FILE_NOT_FOUND; } logError(1, "%s Error while getting the device ERROR %08X\n", TAG, ERROR_FILE_READ); return ERROR_FILE_READ; } } /** * Reset and release the memory which store a Production Limit File previously *loaded * @param file pointer to the LimitFile struct to free * @return OK if success or an error code which specify the type of error *encountered */ int freeLimitsFile(struct LimitFile *file) { logError(0, "%s Freeing Limit File ...\n", TAG); if (file != NULL) { if (file->data != NULL) { kfree(file->data); file->data = NULL; } else logError(0, "%s Limit File was already freed!\n", TAG); file->size = 0; strlcpy(file->name, " ", MAX_LIMIT_FILE_NAME); return OK; } logError(1, "%s Passed a NULL argument! ERROR %08X\n", TAG, ERROR_OP_NOT_ALLOW); return ERROR_OP_NOT_ALLOW; } /** * Reset and release the memory which store the current Limit File previously *loaded * @return OK if success or an error code which specify the type of error *encountered */ int freeCurrentLimitsFile(void) { return freeLimitsFile(&limit_file); } /** * Parse the raw data read from a Production test limit file in order to find *the specified information * If no limits file data are passed, the function loads and stores the limit *file from the system * @param path name of Production Test Limit file to load or "NULL" if the *limits data should be loaded by a .h file * @param file pointer to LimitFile struct that should be parsed or NULL if the *limit file in the system should be loaded and then parsed * @param label string which identify a particular set of data in the file that *want to be loaded * @param data pointer to the pointer which will contains the specified limits *data as 1 dimension matrix with data arranged row after row * @param row pointer to a int variable which will contain the number of row of *data * @param column pointer to a int variable which will contain the number of *column of data * @return OK if success or an error code which specify the type of error */ int parseProductionTestLimits(char *path, struct LimitFile *file, char *label, int **data, int *row, int *column) { int find = 0; char *token = NULL; int i = 0; int j = 0; int z = 0; char *line2 = NULL; char line[800]; char *buf = NULL; int n, size, pointer = 0, ret = OK; char *data_file = NULL; if (file == NULL || strcmp(path, file->name) != 0 || file->size == 0) { logError(0, "%s No limit File data passed... try to get them from the system!\n", TAG); ret = getLimitsFile(LIMITS_FILE, &limit_file); if (ret < OK) { logError(1, "%s parseProductionTestLimits: ERROR %08X\n", TAG, ERROR_FILE_NOT_FOUND); return ERROR_FILE_NOT_FOUND; } size = limit_file.size; data_file = limit_file.data; } else { logError(0, "%s Limit File data passed as arguments!\n", TAG); size = file->size; data_file = file->data; } logError(0, "%s The size of the limits file is %d bytes...\n", TAG, size); while (find == 0) { /* start to look for the wanted label */ if (readLine(&data_file[pointer], line, size - pointer, &n) < 0) { find = -1; break; } pointer += n; if (line[0] == '*') { /* each header row start with * ex. * *label,n_row,n_colum */ line2 = kstrdup(line, GFP_KERNEL); if (line2 == NULL) { logError(1, "%s parseProductionTestLimits: kstrdup ERROR %08X\n", TAG, ERROR_ALLOC); ret = ERROR_ALLOC; goto END; } buf = line2; line2 += 1; token = strsep(&line2, ","); if (strcmp(token, label) == 0) {/* if the row is the * wanted one i retrieve * rows and columns info */ find = 1; token = strsep(&line2, ","); if (token != NULL) { ret = kstrtoint(token, 0, row); if (ret == 0) logError(0, "%s Row = %d\n", TAG, *row); else { logError(0, "%s ERROR while reading the row value! ERROR %08X\n", TAG, ERROR_FILE_PARSE); ret = ERROR_FILE_PARSE; goto END; } } else { logError(1, "%s parseProductionTestLimits 1: ERROR %08X\n", TAG, ERROR_FILE_PARSE); ret = ERROR_FILE_PARSE; goto END; } token = strsep(&line2, ","); if (token != NULL) { ret = kstrtoint(token, 0, column); if (ret == 0) logError(0, "%s Column = %d\n", TAG, *column); else { logError(0, "%s ERROR while reading the column value! ERROR %08X\n", TAG, ERROR_FILE_PARSE); ret = ERROR_FILE_PARSE; goto END; } } else { logError(1, "%s parseProductionTestLimits 2: ERROR %08X\n", TAG, ERROR_FILE_PARSE); ret = ERROR_FILE_PARSE; goto END; } kfree(buf); buf = NULL; *data = kmalloc(((*row) * (*column)) * sizeof(int), GFP_KERNEL); /* allocate the memory for containing the data */ j = 0; if (*data == NULL) { logError(1, "%s parseProductionTestLimits: ERROR %08X\n", TAG, ERROR_ALLOC); ret = ERROR_ALLOC; goto END; } /* start to read the data */ for (i = 0; i < *row; i++) { if (readLine(&data_file[pointer], line, size - pointer, &n) < 0) { logError(1, "%s parseProductionTestLimits : ERROR %08X\n", TAG, ERROR_FILE_READ); ret = ERROR_FILE_READ; goto END; } pointer += n; line2 = kstrdup(line, GFP_KERNEL); if (line2 == NULL) { logError(1, "%s parseProductionTestLimits: kstrdup ERROR %08X\n", TAG, ERROR_ALLOC); ret = ERROR_ALLOC; goto END; } buf = line2; token = strsep(&line2, ","); for (z = 0; (z < *column) && (token != NULL); z++) { ret = kstrtoint(token, 0, ((*data) + j)); if (ret == 0) { j++; token = strsep(&line2, ","); } } kfree(buf); buf = NULL; } if (j == ((*row) * (*column))) {/* check that * all the data * are read */ logError(0, "%s READ DONE!\n", TAG); ret = OK; goto END; } logError(1, "%s parseProductionTestLimits 3: ERROR %08X\n", TAG, ERROR_FILE_PARSE); ret = ERROR_FILE_PARSE; goto END; } kfree(buf); buf = NULL; } } logError(1, "%s parseProductionTestLimits: ERROR %08X\n", TAG, ERROR_LABEL_NOT_FOUND); ret = ERROR_LABEL_NOT_FOUND; END: if (buf != NULL) kfree(buf); return ret; } /** * Read one line of a text file passed as array of byte and terminate it with a *termination character '\0' * @param data text file as array of bytes * @param line pointer to an array of char that will contain the line read * @param size size of data * @param n pointer to a int variable which will contain the number of *characters of the line * @return OK if success or an error code which specify the type of error */ int readLine(char *data, char *line, int size, int *n) { int i = 0; if (size < 1) return ERROR_OP_NOT_ALLOW; while (data[i] != '\n' && i < size) { line[i] = data[i]; i++; } *n = i + 1; line[i] = '\0'; return OK; }