2128 lines
72 KiB
C
2128 lines
72 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#define LOG_TAG "Oem"
|
|
|
|
#include "cts_config.h"
|
|
#include "cts_platform.h"
|
|
#include "cts_core.h"
|
|
#include "cts_oem.h"
|
|
#include "cts_test.h"
|
|
#include "cts_tcs.h"
|
|
#include "cts_firmware.h"
|
|
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/slab.h>
|
|
|
|
/* Following options override device tree settings */
|
|
#define OEM_OF_DEF_PROPVAL_TEST_RESET_PIN true
|
|
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
|
|
#define OEM_OF_DEF_PROPVAL_TEST_INT_PIN false
|
|
#else
|
|
#define OEM_OF_DEF_PROPVAL_TEST_INT_PIN true
|
|
#endif
|
|
#define OEM_OF_DEF_PROPVAL_TEST_RAWDATA true
|
|
#define OEM_OF_DEF_PROPVAL_TEST_NOISE true
|
|
#define OEM_OF_DEF_PROPVAL_TEST_OPEN true
|
|
#define OEM_OF_DEF_PROPVAL_TEST_SHORT true
|
|
#define OEM_OF_DEF_PROPVAL_TEST_COMP_CAP true
|
|
|
|
/* Default settings if device tree NOT exist */
|
|
#define OEM_OF_DEF_PROPVAL_RAWDATA_FRAMES 1
|
|
#define OEM_OF_DEF_PROPVAL_RAWDATA_MIN 1000
|
|
#define OEM_OF_DEF_PROPVAL_RAWDATA_MAX 2000
|
|
#define OEM_OF_DEF_PROPVAL_NOISE_FRAMES 50
|
|
#define OEM_OF_DEF_PROPVAL_NOISE_MAX 80
|
|
#define OEM_OF_DEF_PROPVAL_OPEN_MIN 1000
|
|
#define OEM_OF_DEF_PROPVAL_SHORT_MIN 500
|
|
#define OEM_OF_DEF_PROPVAL_COMP_CAP_MIN 1
|
|
#define OEM_OF_DEF_PROPVAL_COMP_CAP_MAX 126
|
|
|
|
#define OEM_OF_PROPNAME_PREFIX "chipone," //modify
|
|
|
|
#define OEM_OF_PROPNAME_TEST_RESET_PIN OEM_OF_PROPNAME_PREFIX"test-reset-pin"
|
|
#define OEM_OF_PROPNAME_TEST_INT_PIN OEM_OF_PROPNAME_PREFIX"test-int-pin"
|
|
#define OEM_OF_PROPNAME_TEST_RAWDATA OEM_OF_PROPNAME_PREFIX"test-rawdata"
|
|
#define OEM_OF_PROPNAME_RAWDATA_FRAMES OEM_OF_PROPNAME_PREFIX"test-rawdata-frames"
|
|
#define OEM_OF_PROPNAME_RAWDATA_MIN OEM_OF_PROPNAME_PREFIX"rawdata-min"
|
|
#define OEM_OF_PROPNAME_RAWDATA_MAX OEM_OF_PROPNAME_PREFIX"rawdata-max"
|
|
#define OEM_OF_PROPNAME_TEST_NOISE OEM_OF_PROPNAME_PREFIX"test-noise"
|
|
#define OEM_OF_PROPNAME_NOISE_FRAMES OEM_OF_PROPNAME_PREFIX"test-noise-frames"
|
|
#define OEM_OF_PROPNAME_NOISE_MAX OEM_OF_PROPNAME_PREFIX"noise-max"
|
|
#define OEM_OF_PROPNAME_TEST_OPEN OEM_OF_PROPNAME_PREFIX"test-open"
|
|
#define OEM_OF_PROPNAME_OPEN_MIN OEM_OF_PROPNAME_PREFIX"open-min"
|
|
#define OEM_OF_PROPNAME_TEST_SHORT OEM_OF_PROPNAME_PREFIX"test-short"
|
|
#define OEM_OF_PROPNAME_SHORT_MIN OEM_OF_PROPNAME_PREFIX"short-min"
|
|
#define OEM_OF_PROPNAME_TEST_COMP_CAP OEM_OF_PROPNAME_PREFIX"test-compensate-cap"
|
|
#define OEM_OF_PROPNAME_COMP_CAP_MIN OEM_OF_PROPNAME_PREFIX"compensate-cap-min"
|
|
#define OEM_OF_PROPNAME_COMP_CAP_MAX OEM_OF_PROPNAME_PREFIX"compensate-cap-max"
|
|
|
|
#define OEM_SELFTEST_PROC_FILENAME "cts_selftest"
|
|
#define OEM_LIMIT_PROC_FILENAME "cts_limit"
|
|
#define OEM_FACTORY_TEST_PROC_FILENAME "cts_factory_test"
|
|
#define OEM_RAWDATA_PROC_FILENAME "cts_rawdata"
|
|
#define OEM_MANUAL_PROC_FILENAME "cts_manual"
|
|
#define OEM_DIFFDATA_PROC_FILENAME "cts_diffdata"
|
|
#define OEM_CNEGDATA_PROC_FILENAME "cts_compensate_cap"
|
|
|
|
#define OEM_TEST_DATA_DIR "/sdcard"
|
|
#define OEM_RAWDATA_TEST_DATA_FILEPATH OEM_TEST_DATA_DIR"/FWMutualTest.csv"
|
|
#define OEM_NOISE_TEST_DATA_FILEPATH OEM_TEST_DATA_DIR"/NoiseTest.csv"
|
|
#define OEM_OPEN_TEST_DATA_FILEPATH OEM_TEST_DATA_DIR"/OpenTest.csv"
|
|
#define OEM_SHORT_TEST_DATA_FILEPATH OEM_TEST_DATA_DIR"/ShortTest.csv"
|
|
#define OEM_COMP_CAP_TEST_DATA_FILEPATH OEM_TEST_DATA_DIR"/FWCCTest.csv"
|
|
|
|
#define TOUCH_DATA_DIRECTORY_PREFIX "/sdcard"
|
|
#define RAWDATA_TEST_DATA_FILENAME "rawdata-test-data.txt"
|
|
#define NOISE_TEST_DATA_FILENAME "noise-test-data.txt"
|
|
#define OPEN_TEST_DATA_FILENAME "open-test-data.txt"
|
|
#define SHORT_TEST_DATA_FILENAME "short-test-data.txt"
|
|
#define COMP_CAP_TEST_DATA_FILENAME "comp-cap-test-data.txt"
|
|
#define STYLUS_RAWDATA_TEST_DATA_FILENAME "stylus-rawdata-test-data.txt"
|
|
#define STYLUS_NOISE_TEST_DATA_FILENAME "stylus-noise-test-data.txt"
|
|
#define STYLUS_MNT_NOISE_TEST_DATA_FILENAME "stylus-mnt-noise-test-data.txt"
|
|
|
|
#pragma pack(1)
|
|
struct cts_limit {
|
|
u8 header[7];
|
|
u8 version;
|
|
u16 int_item : 1;
|
|
u16 reset_item : 1;
|
|
u16 normal_rawdata_item : 1;
|
|
u16 normal_noise_item : 1;
|
|
u16 open_item : 1;
|
|
u16 short_item : 1;
|
|
u16 comp_cap_item : 1;
|
|
u16 gstr_rawdata_item : 1;
|
|
u16 gstrlp_rawdata_item : 1;
|
|
u16 gstr_noise_item : 1;
|
|
u16 gstrlp_noise_item : 1;
|
|
u16 stylus_rawdata_item : 1;
|
|
u16 stylus_noise_item : 1;
|
|
u16 stylus_mnt_rawdata_item : 1;
|
|
u16 type : 2;
|
|
u16 normal_rawdata_frames;
|
|
u16 normal_rawdata_min;
|
|
u16 normal_rawdata_max;
|
|
u16 normal_noise_frames;
|
|
u16 normal_noise_max;
|
|
u16 normal_open_min;
|
|
u16 normal_short_min;
|
|
u16 normal_compcap_min;
|
|
u16 normal_compcap_max;
|
|
u16 gstr_rawdata_frames;
|
|
u16 gstr_rawdata_min;
|
|
u16 gstr_rawdata_max;
|
|
u16 gstrlp_rawdata_frames;
|
|
u16 gstrlp_rawdata_min;
|
|
u16 gstrlp_rawdata_max;
|
|
u16 gstr_noise_frames;
|
|
u16 gstr_noise_max;
|
|
u16 gstrlp_noise_frames;
|
|
u16 gstrlp_noise_max;
|
|
u16 stylus_rawdata_frames;
|
|
u16 stylus_rawdata_min;
|
|
u16 stylus_rawdata_max;
|
|
u16 stylus_noise_frames;
|
|
u16 stylus_noise_max;
|
|
u16 stylus_mnt_rawdata_frames;
|
|
u16 stylus_mnt_rawdata_min;
|
|
u16 stylus_mnt_rawdata_max;
|
|
};
|
|
#pragma pack()
|
|
|
|
struct cts_oem_data {
|
|
struct proc_dir_entry *selftest_proc_entry;
|
|
struct proc_dir_entry *limit_entry;
|
|
struct proc_dir_entry *factory_test_entry;
|
|
struct proc_dir_entry *manual_proc_entry;
|
|
struct proc_dir_entry *diffdata_proc_entry;
|
|
struct proc_dir_entry *rawdata_proc_entry;
|
|
struct proc_dir_entry *cnegdata_proc_entry;
|
|
|
|
bool test_config_from_dt_has_parsed;
|
|
|
|
/* Test configuration from device tree */
|
|
bool test_reset_pin;
|
|
int reset_pin_test_result;
|
|
|
|
bool test_int_pin;
|
|
int int_pin_test_result;
|
|
|
|
bool test_rawdata;
|
|
u32 rawdata_test_frames;
|
|
int rawdata_test_result;
|
|
u16 *rawdata_test_data;
|
|
int rawdata_test_data_buff_size;
|
|
int rawdata_test_data_wr_size;
|
|
int rawdata_min;
|
|
int rawdata_max;
|
|
|
|
bool test_noise;
|
|
u32 noise_test_frames;
|
|
int noise_test_result;
|
|
u16 *noise_test_data;
|
|
int noise_test_data_buff_size;
|
|
int noise_test_data_wr_size;
|
|
int noise_max;
|
|
|
|
bool test_open;
|
|
int open_test_result;
|
|
u16 *open_test_data;
|
|
int open_test_data_buff_size;
|
|
int open_test_data_wr_size;
|
|
int open_min;
|
|
|
|
bool test_short;
|
|
int short_test_result;
|
|
u16 *short_test_data;
|
|
int short_test_data_buff_size;
|
|
int short_test_data_wr_size;
|
|
int short_min;
|
|
|
|
bool test_comp_cap;
|
|
int comp_cap_test_result;
|
|
u8 *comp_cap_test_data;
|
|
int comp_cap_test_data_buff_size;
|
|
int comp_cap_test_data_wr_size;
|
|
int comp_cap_min;
|
|
int comp_cap_max;
|
|
|
|
bool test_stylus_rawdata;
|
|
u32 stylus_rawdata_test_frames;
|
|
int stylus_rawdata_test_result;
|
|
u8 *stylus_rawdata_test_data;
|
|
int stylus_rawdata_test_data_buff_size;
|
|
int stylus_rawdata_test_data_wr_size;
|
|
int stylus_rawdata_min;
|
|
int stylus_rawdata_max;
|
|
|
|
bool test_stylus_noise;
|
|
u32 stylus_noise_test_frames;
|
|
int stylus_noise_test_result;
|
|
u8 *stylus_noise_test_data;
|
|
int stylus_noise_test_data_buff_size;
|
|
int stylus_noise_test_data_wr_size;
|
|
int stylus_noise_max;
|
|
|
|
bool test_stylus_mnt_rawdata;
|
|
u32 stylus_mnt_rawdata_test_frames;
|
|
int stylus_mnt_rawdata_test_result;
|
|
u8 *stylus_mnt_rawdata_test_data;
|
|
int stylus_mnt_rawdata_test_data_buff_size;
|
|
int stylus_mnt_rawdata_test_data_wr_size;
|
|
int stylus_mnt_rawdata_min;
|
|
int stylus_mnt_rawdata_max;
|
|
|
|
struct chipone_ts_data *cts_data;
|
|
};
|
|
|
|
/* struct proc_dir_entry *cts_tp_work_proc; */
|
|
|
|
#define ALLOC_TEST_DATA_MEM(type, size) \
|
|
do { \
|
|
if (oem_data->test_##type) { \
|
|
if (oem_data->type##_test_data == NULL) { \
|
|
cts_info(" - Alloc " #type " test data mem size %d", size); \
|
|
oem_data->type##_test_data = kmalloc(size, GFP_KERNEL); \
|
|
if (oem_data->type##_test_data == NULL) { \
|
|
cts_err("Alloc " #type " test data mem failed"); \
|
|
return -ENOMEM; \
|
|
} \
|
|
oem_data->type##_test_data_buff_size = size; \
|
|
} \
|
|
memset(oem_data->type##_test_data, 0, size); \
|
|
} \
|
|
} while (0)
|
|
|
|
/* NOTE: Any test data mem alloc failed will NOT clean other mem */
|
|
static int alloc_selftest_data_mem(struct cts_oem_data *oem_data, int nodes)
|
|
{
|
|
cts_info("Alloc selftest data");
|
|
|
|
ALLOC_TEST_DATA_MEM(rawdata,
|
|
nodes * 2 * oem_data->rawdata_test_frames);
|
|
ALLOC_TEST_DATA_MEM(noise,
|
|
nodes * 2 * (oem_data->noise_test_frames + 3));
|
|
ALLOC_TEST_DATA_MEM(open, nodes * 2);
|
|
ALLOC_TEST_DATA_MEM(short, nodes * 2 * 5);
|
|
ALLOC_TEST_DATA_MEM(comp_cap, nodes);
|
|
return 0;
|
|
}
|
|
|
|
#define FREE_TEST_DATA_MEM(type) \
|
|
do { \
|
|
if (oem_data->type##_test_data) { \
|
|
cts_info("- Free " #type " test data mem"); \
|
|
kfree(oem_data->type##_test_data); \
|
|
oem_data->type##_test_data = NULL; \
|
|
oem_data->type##_test_data_buff_size = 0; \
|
|
} \
|
|
} while(0)
|
|
static void free_selftest_data_mem(struct cts_oem_data *oem_data)
|
|
{
|
|
cts_info("Free selftest data");
|
|
|
|
FREE_TEST_DATA_MEM(rawdata);
|
|
FREE_TEST_DATA_MEM(noise);
|
|
FREE_TEST_DATA_MEM(open);
|
|
FREE_TEST_DATA_MEM(short);
|
|
FREE_TEST_DATA_MEM(comp_cap);
|
|
}
|
|
|
|
/* NOTE: Any test data mem alloc failed will NOT clean other mem
|
|
static int alloc_stylus_test_data_mem(struct cts_oem_data *oem_data, int nodes)
|
|
{
|
|
cts_info("Alloc stylus selftest data");
|
|
|
|
ALLOC_TEST_DATA_MEM(stylus_rawdata,
|
|
nodes * 2 * oem_data->stylus_rawdata_test_frames);
|
|
ALLOC_TEST_DATA_MEM(stylus_noise,
|
|
nodes * 2 * (oem_data->stylus_noise_test_frames + 3));
|
|
ALLOC_TEST_DATA_MEM(stylus_mnt_rawdata,
|
|
nodes * 2 * oem_data->stylus_mnt_rawdata_test_frames);
|
|
return 0;
|
|
}
|
|
|
|
static void free_stylus_test_data_mem(struct cts_oem_data *oem_data)
|
|
{
|
|
cts_info("Free stylus selftest data");
|
|
|
|
FREE_TEST_DATA_MEM(stylus_rawdata);
|
|
FREE_TEST_DATA_MEM(stylus_noise);
|
|
FREE_TEST_DATA_MEM(stylus_mnt_rawdata);
|
|
}
|
|
*/
|
|
#undef ALLOC_TEST_DATA_MEM
|
|
#undef FREE_TEST_DATA_MEM
|
|
|
|
static int parse_selftest_dt(struct cts_oem_data *oem_data,
|
|
struct device_node *np)
|
|
{
|
|
int ret;
|
|
|
|
cts_info("Parse selftest dt");
|
|
|
|
/** reset pin **/
|
|
oem_data->test_reset_pin = OEM_OF_DEF_PROPVAL_TEST_RESET_PIN ||
|
|
of_property_read_bool(np, OEM_OF_PROPNAME_TEST_RESET_PIN);
|
|
|
|
/** int pin **/
|
|
oem_data->test_int_pin = OEM_OF_DEF_PROPVAL_TEST_INT_PIN ||
|
|
of_property_read_bool(np, OEM_OF_PROPNAME_TEST_INT_PIN);
|
|
|
|
/** rawdata **/
|
|
oem_data->test_rawdata = OEM_OF_DEF_PROPVAL_TEST_RAWDATA ||
|
|
of_property_read_bool(np, OEM_OF_PROPNAME_TEST_RAWDATA);
|
|
if (oem_data->test_rawdata) {
|
|
oem_data->rawdata_test_frames = OEM_OF_DEF_PROPVAL_RAWDATA_FRAMES;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_RAWDATA_FRAMES,
|
|
&oem_data->rawdata_test_frames);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_RAWDATA_FRAMES"' failed %d", ret);
|
|
}
|
|
oem_data->rawdata_min = OEM_OF_DEF_PROPVAL_RAWDATA_MIN;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_RAWDATA_MIN,
|
|
(u32 *)&oem_data->rawdata_min);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_RAWDATA_MIN"' failed %d", ret);
|
|
}
|
|
oem_data->rawdata_max = OEM_OF_DEF_PROPVAL_RAWDATA_MAX;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_RAWDATA_MAX,
|
|
(u32 *)&oem_data->rawdata_max);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_RAWDATA_MAX"' failed %d", ret);
|
|
}
|
|
}
|
|
|
|
/** nosie **/
|
|
oem_data->test_noise = OEM_OF_DEF_PROPVAL_TEST_NOISE ||
|
|
of_property_read_bool(np, OEM_OF_PROPNAME_TEST_NOISE);
|
|
if (oem_data->test_noise) {
|
|
oem_data->noise_test_frames = OEM_OF_DEF_PROPVAL_NOISE_FRAMES;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_NOISE_FRAMES,
|
|
&oem_data->noise_test_frames);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_NOISE_FRAMES"' failed %d", ret);
|
|
}
|
|
oem_data->noise_max = OEM_OF_DEF_PROPVAL_NOISE_MAX;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_NOISE_MAX,
|
|
(u32 *)&oem_data->noise_max);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_NOISE_MAX"' failed %d", ret);
|
|
}
|
|
}
|
|
|
|
/** open **/
|
|
oem_data->test_open = OEM_OF_DEF_PROPVAL_TEST_OPEN ||
|
|
of_property_read_bool(np, OEM_OF_PROPNAME_TEST_OPEN);
|
|
if (oem_data->test_open) {
|
|
oem_data->open_min = OEM_OF_DEF_PROPVAL_OPEN_MIN;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_OPEN_MIN,
|
|
(u32 *)&oem_data->open_min);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_OPEN_MIN"' failed %d", ret);
|
|
}
|
|
}
|
|
|
|
/** short **/
|
|
oem_data->test_short = OEM_OF_DEF_PROPVAL_TEST_SHORT ||
|
|
of_property_read_bool(np, OEM_OF_PROPNAME_TEST_SHORT);
|
|
if (oem_data->test_short) {
|
|
oem_data->short_min = OEM_OF_DEF_PROPVAL_SHORT_MIN;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_SHORT_MIN,
|
|
(u32 *)&oem_data->short_min);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_SHORT_MIN"' failed %d", ret);
|
|
}
|
|
}
|
|
|
|
/** comp cap **/
|
|
oem_data->test_comp_cap = OEM_OF_DEF_PROPVAL_TEST_COMP_CAP ||
|
|
of_property_read_bool(np, OEM_OF_PROPNAME_TEST_COMP_CAP);
|
|
if (oem_data->test_comp_cap) {
|
|
oem_data->comp_cap_min = OEM_OF_DEF_PROPVAL_COMP_CAP_MIN;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_COMP_CAP_MIN,
|
|
(u32 *)&oem_data->comp_cap_min);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_COMP_CAP_MIN"' failed %d", ret);
|
|
}
|
|
oem_data->comp_cap_max = OEM_OF_DEF_PROPVAL_COMP_CAP_MAX;
|
|
ret = of_property_read_u32(np, OEM_OF_PROPNAME_COMP_CAP_MAX,
|
|
(u32 *)&oem_data->comp_cap_max);
|
|
if (ret) {
|
|
cts_warn("Parse '"OEM_OF_PROPNAME_COMP_CAP_MAX"' failed %d", ret);
|
|
}
|
|
}
|
|
|
|
oem_data->test_config_from_dt_has_parsed = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void print_selftest_config(const struct cts_oem_data *oem_data)
|
|
{
|
|
cts_info("Seltest configuration:");
|
|
|
|
/** reset pin **/
|
|
cts_info(" - %-32s = %c", OEM_OF_PROPNAME_TEST_RESET_PIN,
|
|
oem_data->test_reset_pin ? 'Y' : 'N');
|
|
|
|
/** int pin **/
|
|
cts_info(" - %-32s = %c", OEM_OF_PROPNAME_TEST_INT_PIN,
|
|
oem_data->test_int_pin ? 'Y' : 'N');
|
|
|
|
/** rawdata **/
|
|
cts_info(" - %-32s = %c", OEM_OF_PROPNAME_TEST_RAWDATA,
|
|
oem_data->test_rawdata ? 'Y' : 'N');
|
|
if (oem_data->test_rawdata) {
|
|
cts_info(" - %-32s = %u", OEM_OF_PROPNAME_RAWDATA_FRAMES,
|
|
oem_data->rawdata_test_frames);
|
|
cts_info(" - %-32s = %d", OEM_OF_PROPNAME_RAWDATA_MIN,
|
|
oem_data->rawdata_min);
|
|
cts_info(" - %-32s = %d", OEM_OF_PROPNAME_RAWDATA_MAX,
|
|
oem_data->rawdata_max);
|
|
}
|
|
|
|
/** noise **/
|
|
cts_info(" - %-32s = %c", OEM_OF_PROPNAME_TEST_NOISE,
|
|
oem_data->test_noise ? 'Y' : 'N');
|
|
if (oem_data->test_noise) {
|
|
cts_info(" - %-32s = %u", OEM_OF_PROPNAME_NOISE_FRAMES ,
|
|
oem_data->noise_test_frames);
|
|
cts_info(" - %-32s = %d", OEM_OF_PROPNAME_NOISE_MAX,
|
|
oem_data->noise_max);
|
|
}
|
|
|
|
/** open **/
|
|
cts_info(" - %-32s = %c", OEM_OF_PROPNAME_TEST_OPEN,
|
|
oem_data->test_open ? 'Y' : 'N');
|
|
if (oem_data->test_open) {
|
|
cts_info(" - %-32s = %d", OEM_OF_PROPNAME_OPEN_MIN,
|
|
oem_data->open_min);
|
|
}
|
|
|
|
/** short **/
|
|
cts_info(" - %-32s = %c", OEM_OF_PROPNAME_TEST_SHORT,
|
|
oem_data->test_short ? 'Y' : 'N');
|
|
if (oem_data->test_short) {
|
|
cts_info(" - %-32s = %d", OEM_OF_PROPNAME_SHORT_MIN,
|
|
oem_data->short_min);
|
|
}
|
|
|
|
/** comp cap **/
|
|
cts_info(" - %-32s = %c", OEM_OF_PROPNAME_TEST_COMP_CAP,
|
|
oem_data->test_comp_cap ? 'Y' : 'N');
|
|
if (oem_data->test_comp_cap) {
|
|
cts_info(" - %-32s = %d", OEM_OF_PROPNAME_COMP_CAP_MIN,
|
|
oem_data->comp_cap_min);
|
|
cts_info(" - %-32s = %d", OEM_OF_PROPNAME_COMP_CAP_MAX,
|
|
oem_data->comp_cap_max);
|
|
}
|
|
}
|
|
|
|
static void do_selftest(struct cts_oem_data *oem_data)
|
|
{
|
|
struct cts_test_param test_param;
|
|
int retry = 3;
|
|
|
|
cts_info("Do selftest");
|
|
|
|
/** reset pin test **/
|
|
if (oem_data->test_reset_pin) {
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
test_param.test_item = CTS_TEST_RESET_PIN;
|
|
oem_data->reset_pin_test_result =
|
|
cts_test_reset_pin(&oem_data->cts_data->cts_dev, &test_param);
|
|
if (oem_data->reset_pin_test_result) {
|
|
cts_err("Test reset pin failed %d", oem_data->reset_pin_test_result);
|
|
}
|
|
}
|
|
|
|
/** int pin test **/
|
|
if (oem_data->test_int_pin) {
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
test_param.test_item = CTS_TEST_INT_PIN;
|
|
oem_data->int_pin_test_result =
|
|
cts_test_int_pin(&oem_data->cts_data->cts_dev, &test_param);
|
|
if (oem_data->int_pin_test_result) {
|
|
cts_err("Test int pin failed %d", oem_data->int_pin_test_result);
|
|
}
|
|
}
|
|
|
|
/** rawdata test **/
|
|
if (oem_data->test_rawdata) {
|
|
struct cts_rawdata_test_priv_param priv_param = {0};
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
oem_data->rawdata_test_data_wr_size = 0;
|
|
|
|
test_param.test_item = CTS_TEST_RAWDATA;
|
|
test_param.flags =
|
|
CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE;
|
|
test_param.min = &oem_data->rawdata_min;
|
|
test_param.max = &oem_data->rawdata_max;
|
|
test_param.test_data_buf = oem_data->rawdata_test_data;
|
|
test_param.test_data_buf_size = oem_data->rawdata_test_data_buff_size;
|
|
test_param.test_data_wr_size = &oem_data->rawdata_test_data_wr_size;
|
|
|
|
priv_param.frames = oem_data->rawdata_test_frames;
|
|
test_param.priv_param = &priv_param;
|
|
test_param.priv_param_size = sizeof(priv_param);
|
|
|
|
retry = 3;
|
|
do {
|
|
oem_data->rawdata_test_result =
|
|
cts_test_rawdata(&oem_data->cts_data->cts_dev, &test_param);
|
|
} while (oem_data->rawdata_test_result < 0 && retry--);
|
|
if (oem_data->rawdata_test_result) {
|
|
cts_err("Test rawdata failed %d", oem_data->rawdata_test_result);
|
|
}
|
|
}
|
|
|
|
/** noise test **/
|
|
if (oem_data->test_noise) {
|
|
struct cts_noise_test_priv_param priv_param = {0};
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
oem_data->noise_test_data_wr_size = 0;
|
|
|
|
test_param.test_item = CTS_TEST_NOISE;
|
|
test_param.flags =
|
|
CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE;
|
|
test_param.max = &oem_data->noise_max;
|
|
test_param.test_data_buf = oem_data->noise_test_data;
|
|
test_param.test_data_buf_size = oem_data->noise_test_data_buff_size;
|
|
test_param.test_data_wr_size = &oem_data->noise_test_data_wr_size;
|
|
|
|
priv_param.frames = oem_data->noise_test_frames;
|
|
test_param.priv_param = &priv_param;
|
|
test_param.priv_param_size = sizeof(priv_param);
|
|
|
|
retry = 3;
|
|
do {
|
|
oem_data->noise_test_result =
|
|
cts_test_noise(&oem_data->cts_data->cts_dev, &test_param);
|
|
} while (oem_data->noise_test_result < 0 && retry--);
|
|
if (oem_data->noise_test_result) {
|
|
cts_err("Test noise failed %d", oem_data->noise_test_result);
|
|
}
|
|
}
|
|
|
|
/** open test **/
|
|
if (oem_data->test_open) {
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
oem_data->open_test_data_wr_size = 0;
|
|
test_param.test_item = CTS_TEST_OPEN;
|
|
test_param.flags =
|
|
CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE;
|
|
test_param.min = &oem_data->open_min;
|
|
test_param.test_data_buf = oem_data->open_test_data;
|
|
test_param.test_data_buf_size = oem_data->open_test_data_buff_size;
|
|
test_param.test_data_wr_size = &oem_data->open_test_data_wr_size;
|
|
|
|
retry = 3;
|
|
do {
|
|
oem_data->open_test_result =
|
|
cts_test_open(&oem_data->cts_data->cts_dev, &test_param);
|
|
} while (oem_data->open_test_result < 0 && retry--);
|
|
if (oem_data->open_test_result) {
|
|
cts_err("Test open failed %d", oem_data->open_test_result);
|
|
}
|
|
}
|
|
|
|
/** short test **/
|
|
if (oem_data->test_short) {
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
oem_data->short_test_data_wr_size = 0;
|
|
test_param.test_item = CTS_TEST_SHORT;
|
|
test_param.flags =
|
|
CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE;
|
|
test_param.min = &oem_data->short_min;
|
|
test_param.test_data_buf = oem_data->short_test_data;
|
|
test_param.test_data_buf_size = oem_data->short_test_data_buff_size;
|
|
test_param.test_data_wr_size = &oem_data->short_test_data_wr_size;
|
|
|
|
retry = 3;
|
|
do {
|
|
oem_data->short_test_result =
|
|
cts_test_short(&oem_data->cts_data->cts_dev, &test_param);
|
|
} while (oem_data->short_test_result < 0 && retry--);
|
|
if (oem_data->short_test_result) {
|
|
cts_err("Test short failed %d", oem_data->short_test_result);
|
|
}
|
|
}
|
|
|
|
/** comp cap test **/
|
|
if (oem_data->test_comp_cap) {
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
oem_data->comp_cap_test_data_wr_size = 0;
|
|
test_param.test_item = CTS_TEST_COMPENSATE_CAP;
|
|
test_param.flags =
|
|
CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE;
|
|
test_param.min = &oem_data->comp_cap_min;
|
|
test_param.max = &oem_data->comp_cap_max;
|
|
test_param.test_result = &oem_data->comp_cap_test_result;
|
|
test_param.test_data_buf = oem_data->comp_cap_test_data;
|
|
test_param.test_data_buf_size = oem_data->comp_cap_test_data_buff_size;
|
|
test_param.test_data_wr_size = &oem_data->comp_cap_test_data_wr_size;
|
|
|
|
retry = 3;
|
|
do {
|
|
oem_data->comp_cap_test_result =
|
|
cts_test_compensate_cap(&oem_data->cts_data->cts_dev, &test_param);
|
|
} while (oem_data->comp_cap_test_result < 0 && retry--);
|
|
if (oem_data->comp_cap_test_result) {
|
|
cts_err("Test compensate cap failed %d", oem_data->comp_cap_test_result);
|
|
}
|
|
}
|
|
|
|
/*
|
|
if (oem_data->test_stylus_rawdata) {
|
|
struct cts_rawdata_test_priv_param priv_param = {0};
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
oem_data->stylus_rawdata_test_data_wr_size = 0;
|
|
|
|
test_param.test_item = CTS_TEST_STYLUS_RAWDATA;
|
|
test_param.flags =
|
|
CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE;
|
|
test_param.min = &oem_data->stylus_rawdata_min;
|
|
test_param.max = &oem_data->stylus_rawdata_max;
|
|
test_param.test_data_buf = oem_data->stylus_rawdata_test_data;
|
|
test_param.test_data_buf_size = oem_data->stylus_rawdata_test_data_buff_size;
|
|
test_param.test_data_wr_size = &oem_data->stylus_rawdata_test_data_wr_size;
|
|
|
|
priv_param.frames = oem_data->stylus_rawdata_test_frames;
|
|
test_param.priv_param = &priv_param;
|
|
test_param.priv_param_size = sizeof(priv_param);
|
|
|
|
retry = 3;
|
|
do {
|
|
oem_data->stylus_rawdata_test_result =
|
|
cts_test_stylus_rawdata(&oem_data->cts_data->cts_dev, &test_param);
|
|
} while (oem_data->stylus_rawdata_test_result < 0 && retry--);
|
|
if (oem_data->stylus_rawdata_test_result) {
|
|
cts_err("stylus test rawdata failed %d", oem_data->stylus_rawdata_test_result);
|
|
}
|
|
}
|
|
|
|
if (oem_data->stylus_test_noise) {
|
|
struct cts_noise_test_priv_param priv_param = {0};
|
|
memset(&test_param, 0, sizeof(test_param));
|
|
oem_data->stylus_noise_test_data_wr_size = 0;
|
|
|
|
test_param.test_item = CTS_TEST_STYLUS_NOISE;
|
|
test_param.flags =
|
|
CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE;
|
|
test_param.max = &oem_data->stylus_noise_max;
|
|
test_param.test_data_buf = oem_data->stylus_noise_test_data;
|
|
test_param.test_data_buf_size = oem_data->stylus_noise_test_data_buff_size;
|
|
test_param.test_data_wr_size = &oem_data->stylus_noise_test_data_wr_size;
|
|
|
|
priv_param.frames = oem_data->stylus_noise_test_frames;
|
|
test_param.priv_param = &priv_param;
|
|
test_param.priv_param_size = sizeof(priv_param);
|
|
|
|
retry = 3;
|
|
do {
|
|
oem_data->stylus_noise_test_result =
|
|
cts_test_stylus_noise(&oem_data->cts_data->cts_dev, &test_param);
|
|
} while (oem_data->stylus_noise_test_result < 0 && retry--);
|
|
if (oem_data->stylus_noise_test_result) {
|
|
cts_err("stylus test noise failed %d", oem_data->stylus_noise_test_result);
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
static int dump_tsdata_row_to_buffer(char *buf, size_t size, const u16 *data,
|
|
int cols, const char *prefix, const char *suffix, char seperator)
|
|
{
|
|
int c, count = 0;
|
|
|
|
if (prefix) {
|
|
count += scnprintf(buf, size, "%s", prefix);
|
|
}
|
|
|
|
for (c = 0; c < cols; c++) {
|
|
count += scnprintf(buf + count, size - count,
|
|
"%4u%c ", data[c], seperator);
|
|
}
|
|
|
|
if (suffix) {
|
|
count += scnprintf(buf + count, size - count, "%s", suffix);
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
static int dump_tsdata_to_csv_file(const char *filepath,
|
|
int flags, const u16 *data, int frames, int rows, int cols)
|
|
{
|
|
#ifdef CFG_CTS_FOR_GKI
|
|
cts_info("%s(): some functions are forbiddon with GKI Version!", __func__);
|
|
return -EPERM;
|
|
#else
|
|
loff_t pos = 0;
|
|
int i, r, ret;
|
|
struct file *file;
|
|
|
|
cts_info("Dump tsdata to csv file: '%s' flags: 0x%x data: %p frames: %d row: %d col: %d",
|
|
filepath, flags, data, frames, cols, rows);
|
|
|
|
file = filp_open(filepath, flags, 0666);
|
|
if (IS_ERR(file)) {
|
|
cts_err("Open file '%s' failed %ld", filepath, PTR_ERR(file));
|
|
return PTR_ERR(file);
|
|
}
|
|
|
|
for (i = 0; i < frames; i++) {
|
|
for (r = 0; r < rows; r++) {
|
|
char linebuf[256];
|
|
int len;
|
|
|
|
len = dump_tsdata_row_to_buffer(linebuf, sizeof(linebuf),
|
|
data, cols, NULL, "\n", ',');
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
|
|
ret = kernel_write(file, linebuf, len, &pos);
|
|
#else
|
|
ret = kernel_write(file, linebuf, len, pos);
|
|
pos += len;
|
|
#endif
|
|
if (ret != len) {
|
|
cts_err("Write to file '%s' failed %d", filepath, ret);
|
|
goto close_file;
|
|
}
|
|
data += cols;
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
|
|
ret = kernel_write(file, "\n", 1, &pos);
|
|
#else
|
|
ret = kernel_write(file, "\n", 1, pos);
|
|
pos ++;
|
|
#endif
|
|
if (ret != 1) {
|
|
cts_err("Write newline to file '%s' failed %d", filepath, ret);
|
|
goto close_file;
|
|
}
|
|
}
|
|
|
|
close_file: {
|
|
int r = filp_close(file, NULL);
|
|
if (r) {
|
|
cts_err("Close file '%s' failed %d", filepath, r);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
#endif
|
|
}
|
|
|
|
static void dump_tsdata_to_seq_file(struct seq_file *m,
|
|
const u16 *data, int rows, int cols)
|
|
{
|
|
int r;
|
|
|
|
for (r = 0; r < rows; r++) {
|
|
char linebuf[256];
|
|
int len;
|
|
|
|
len = dump_tsdata_row_to_buffer(linebuf, sizeof(linebuf),
|
|
data, cols, NULL, "\n", ',');
|
|
seq_puts(m, linebuf);
|
|
|
|
data += cols;
|
|
}
|
|
}
|
|
|
|
static int dump_comp_cap_row_to_buffer(char *buf, size_t size, const u8 *cap,
|
|
int cols, const char *prefix, const char *suffix, char seperator)
|
|
{
|
|
int c, count = 0;
|
|
|
|
if (prefix) {
|
|
count += scnprintf(buf, size, "%s", prefix);
|
|
}
|
|
|
|
for (c = 0; c < cols; c++) {
|
|
count += scnprintf(buf + count, size - count,
|
|
"%3u%c ", cap[c], seperator);
|
|
}
|
|
|
|
if (suffix) {
|
|
count += scnprintf(buf + count, size - count, "%s", suffix);
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
static int dump_comp_cap_to_csv_file(const char *filepath,
|
|
int flags, const u8 *cap, int rows, int cols)
|
|
{
|
|
#ifdef CFG_CTS_FOR_GKI
|
|
cts_info("%s(): some functions are forbiddon with GKI Version!", __func__);
|
|
return -EPERM;
|
|
#else
|
|
struct file *file;
|
|
int r, ret = 0;
|
|
loff_t pos = 0;
|
|
|
|
cts_info("Dump compensate cap to csv file: '%s' flags: 0x%x row: %d col: %d",
|
|
filepath, flags, rows, cols);
|
|
|
|
file = filp_open(filepath, flags, 0666);
|
|
if (IS_ERR(file)) {
|
|
cts_err("Open file '%s' failed %ld", filepath, PTR_ERR(file));
|
|
return PTR_ERR(file);
|
|
}
|
|
|
|
for (r = 0; r < rows; r++) {
|
|
char linebuf[256];
|
|
int len;
|
|
|
|
len = dump_comp_cap_row_to_buffer(linebuf, sizeof(linebuf),
|
|
cap, cols, NULL, "\n", ',');
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
|
|
ret = kernel_write(file, linebuf, len, &pos);
|
|
#else
|
|
ret = kernel_write(file, linebuf, len, pos);
|
|
pos += len;
|
|
#endif
|
|
if (ret != len) {
|
|
cts_err("Write to file '%s' failed %d", filepath, ret);
|
|
goto close_file;
|
|
}
|
|
|
|
cap += cols;
|
|
}
|
|
|
|
close_file: {
|
|
int r = filp_close(file, NULL);
|
|
if (r) {
|
|
cts_err("Close file '%s' failed %d", filepath, ret);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
#endif
|
|
}
|
|
|
|
static void dump_comp_cap_to_seq_file(struct seq_file *m,
|
|
const u8 *data, int rows, int cols)
|
|
{
|
|
int r;
|
|
|
|
for (r = 0; r < rows; r++) {
|
|
char linebuf[256];
|
|
int len;
|
|
|
|
len = dump_comp_cap_row_to_buffer(linebuf, sizeof(linebuf),
|
|
data, cols, NULL, "\n", ',');
|
|
seq_puts(m, linebuf);
|
|
|
|
data += cols;
|
|
}
|
|
}
|
|
|
|
static int save_selftest_data_to_file(struct cts_oem_data *oem_data)
|
|
{
|
|
int rows, cols;
|
|
int ret;
|
|
|
|
cts_info("Save selftest data to file");
|
|
|
|
rows = oem_data->cts_data->cts_dev.fwdata.rows;
|
|
cols = oem_data->cts_data->cts_dev.fwdata.cols;
|
|
|
|
if (oem_data->test_rawdata) {
|
|
ret = dump_tsdata_to_csv_file(OEM_RAWDATA_TEST_DATA_FILEPATH,
|
|
O_RDWR | O_CREAT | O_TRUNC, oem_data->rawdata_test_data,
|
|
oem_data->rawdata_test_frames, cols, rows);
|
|
if (ret < 0) {
|
|
cts_err("Dump rawdata test data to file failed");
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (oem_data->test_noise) {
|
|
ret = dump_tsdata_to_csv_file(OEM_NOISE_TEST_DATA_FILEPATH,
|
|
O_RDWR | O_CREAT | O_TRUNC, oem_data->noise_test_data,
|
|
oem_data->noise_test_frames + 3, cols, rows);
|
|
if (ret < 0) {
|
|
cts_err("Dump noise test data to file failed");
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (oem_data->test_open) {
|
|
ret = dump_tsdata_to_csv_file(OEM_OPEN_TEST_DATA_FILEPATH,
|
|
O_RDWR | O_CREAT | O_TRUNC, oem_data->open_test_data,
|
|
1, cols, rows);
|
|
if (ret < 0) {
|
|
cts_err("Dump open test data to file failed");
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (oem_data->test_short) {
|
|
ret = dump_tsdata_to_csv_file(OEM_SHORT_TEST_DATA_FILEPATH,
|
|
O_RDWR | O_CREAT | O_TRUNC, oem_data->short_test_data,
|
|
5, cols, rows);
|
|
if (ret < 0) {
|
|
cts_err("Dump short test data to file failed");
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (oem_data->test_comp_cap) {
|
|
ret = dump_comp_cap_to_csv_file(OEM_COMP_CAP_TEST_DATA_FILEPATH,
|
|
O_RDWR | O_CREAT | O_TRUNC,
|
|
oem_data->comp_cap_test_data, cols, rows);
|
|
if (ret < 0) {
|
|
cts_err("Dump compensate cap test data to file failed");
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void *selftest_seq_start(struct seq_file *m, loff_t *pos)
|
|
{
|
|
return *pos < 1 ? (void *)1 : NULL;
|
|
}
|
|
|
|
static void *selftest_seq_next(struct seq_file *m, void *v, loff_t *pos)
|
|
{
|
|
++*pos;
|
|
return NULL;
|
|
}
|
|
|
|
static void selftest_seq_stop(struct seq_file *m, void *v)
|
|
{
|
|
return;
|
|
}
|
|
|
|
static int selftest_seq_show(struct seq_file *m, void *v)
|
|
{
|
|
struct chipone_ts_data *cts_data = (struct chipone_ts_data *)m->private;
|
|
struct cts_oem_data *oem_data = NULL;
|
|
int i, rows, cols;
|
|
|
|
cts_info("Show seq selftest");
|
|
|
|
if (cts_data == NULL) {
|
|
cts_err("Selftest seq file private data = NULL");
|
|
return -EFAULT;
|
|
}
|
|
|
|
oem_data = cts_data->oem_data;
|
|
rows = cts_data->cts_dev.fwdata.rows;
|
|
cols = cts_data->cts_dev.fwdata.cols;
|
|
|
|
seq_printf(m, "FW Version %04x!\n\n", cts_data->cts_dev.fwdata.version);
|
|
|
|
if (oem_data->test_reset_pin) {
|
|
seq_printf(m, "Reset-Pin Test %s!\n\n",
|
|
oem_data->reset_pin_test_result == 0 ? "PASS" : "FAIL");
|
|
}
|
|
if (oem_data->test_int_pin) {
|
|
seq_printf(m, "Int-Pin Test %s!\n\n",
|
|
oem_data->int_pin_test_result == 0 ? "PASS" : "FAIL");
|
|
}
|
|
if (oem_data->test_rawdata) {
|
|
seq_printf(m, "FW Rawdata Test");
|
|
if (oem_data->rawdata_test_result == 0) {
|
|
seq_printf(m, " PASS!\n\n");
|
|
} else if (oem_data->rawdata_test_result > 0) {
|
|
seq_printf(m, " FAIL!\n");
|
|
for(i = 0; i < oem_data->rawdata_test_frames; i++) {
|
|
dump_tsdata_to_seq_file(m, oem_data->rawdata_test_data +
|
|
i * rows * cols, cols, rows);
|
|
seq_putc(m, '\n');
|
|
}
|
|
} else {
|
|
seq_printf(m, " ERROR(%d)!\n\n", oem_data->rawdata_test_result);
|
|
}
|
|
}
|
|
if (oem_data->test_noise) {
|
|
seq_printf(m, "Noise Test");
|
|
if (oem_data->noise_test_result == 0) {
|
|
seq_printf(m, " PASS!\n\n");
|
|
} else if (oem_data->noise_test_result > 0) {
|
|
seq_printf(m, " FAIL!\n");
|
|
for(i = 0; i < oem_data->noise_test_frames; i++) {
|
|
dump_tsdata_to_seq_file(m, oem_data->noise_test_data +
|
|
i * rows * cols, rows, cols);
|
|
seq_putc(m, '\n');
|
|
}
|
|
} else {
|
|
seq_printf(m, " ERROR(%d)!\n\n", oem_data->noise_test_result);
|
|
}
|
|
}
|
|
if (oem_data->test_open) {
|
|
seq_printf(m, "Open Test");
|
|
if (oem_data->open_test_result == 0) {
|
|
seq_printf(m, " PASS!\n\n");
|
|
} else if (oem_data->open_test_result > 0) {
|
|
seq_printf(m, " FAIL!\n");
|
|
dump_tsdata_to_seq_file(m, oem_data->open_test_data,
|
|
rows, cols);
|
|
} else {
|
|
seq_printf(m, " ERROR(%d)!\n\n", oem_data->open_test_result);
|
|
}
|
|
}
|
|
if (oem_data->test_short) {
|
|
seq_printf(m, "Short Test");
|
|
if (oem_data->short_test_result == 0) {
|
|
seq_printf(m, " PASS!\n\n");
|
|
} else if (oem_data->short_test_result > 0) {
|
|
seq_printf(m, " FAIL!\n");
|
|
for (i = 0; i < 10; i++) {
|
|
dump_tsdata_to_seq_file(m, oem_data->short_test_data +
|
|
i * rows * cols, cols, rows);
|
|
seq_putc(m, '\n');
|
|
}
|
|
} else {
|
|
seq_printf(m, " ERROR(%d)!\n\n", oem_data->short_test_result);
|
|
}
|
|
}
|
|
if (oem_data->test_comp_cap) {
|
|
seq_printf(m, "Compensate-Cap Test");
|
|
if (oem_data->comp_cap_test_result == 0) {
|
|
seq_printf(m, " PASS!\n\n");
|
|
} else if (oem_data->comp_cap_test_result > 0) {
|
|
seq_printf(m, " FAIL!\n");
|
|
dump_comp_cap_to_seq_file(m, oem_data->comp_cap_test_data,
|
|
rows, cols);
|
|
} else {
|
|
seq_printf(m, " ERROR(%d)!\n\n", oem_data->comp_cap_test_result);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct seq_operations selftest_seq_ops = {
|
|
.start = selftest_seq_start,
|
|
.next = selftest_seq_next,
|
|
.stop = selftest_seq_stop,
|
|
.show = selftest_seq_show,
|
|
};
|
|
|
|
static int32_t selftest_proc_open(struct inode *inode, struct file *file)
|
|
{
|
|
struct chipone_ts_data *cts_data = pde_data(inode);
|
|
struct cts_oem_data *oem_data = NULL;
|
|
int ret;
|
|
|
|
if (cts_data == NULL) {
|
|
cts_err("Open selftest proc with cts_data = NULL");
|
|
return -EFAULT;
|
|
}
|
|
|
|
oem_data = cts_data->oem_data;
|
|
if (oem_data == NULL) {
|
|
cts_err("Open selftest proc with oem_data = NULL");
|
|
return -EFAULT;
|
|
}
|
|
|
|
cts_info("Open '/proc/" OEM_SELFTEST_PROC_FILENAME "'");
|
|
|
|
if (!oem_data->test_config_from_dt_has_parsed) {
|
|
#ifndef CONFIG_CTS_I2C_HOST
|
|
ret = parse_selftest_dt(oem_data, cts_data->pdata->spi_client->dev.of_node);
|
|
#else
|
|
ret = parse_selftest_dt(oem_data, cts_data->device->of_node);
|
|
#endif
|
|
if (ret) {
|
|
cts_err("Parse selftest dt failed %d", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
print_selftest_config(oem_data);
|
|
|
|
ret = alloc_selftest_data_mem(oem_data,
|
|
cts_data->cts_dev.fwdata.rows * cts_data->cts_dev.fwdata.cols);
|
|
if (ret) {
|
|
cts_err("Alloc test data mem failed");
|
|
return ret;
|
|
}
|
|
|
|
do_selftest(oem_data);
|
|
|
|
ret = save_selftest_data_to_file(oem_data);
|
|
if (ret) {
|
|
cts_err("Save selftest data to file failed %d", ret);
|
|
}
|
|
|
|
ret = seq_open(file, &selftest_seq_ops);
|
|
if (ret) {
|
|
cts_err("Open selftest seq file failed %d", ret);
|
|
return ret;
|
|
}
|
|
|
|
((struct seq_file *)file->private_data)->private = cts_data;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
|
static const struct file_operations selftest_proc_fops = {
|
|
.owner = THIS_MODULE,
|
|
.open = selftest_proc_open,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = seq_release,
|
|
};
|
|
#else
|
|
static const struct proc_ops selftest_proc_fops = {
|
|
.proc_open = selftest_proc_open,
|
|
.proc_read = seq_read,
|
|
.proc_lseek = seq_lseek,
|
|
.proc_release = seq_release,
|
|
};
|
|
#endif
|
|
|
|
static int cts_rawdata_show(struct seq_file *m, void *v)
|
|
{
|
|
struct chipone_ts_data *cts_data = m->private;
|
|
struct cts_device *cts_dev;
|
|
u8 *rawdata;
|
|
s16 *data;
|
|
u8 hwrows, hwcols, fwrows, fwcols;
|
|
u8 i, j;
|
|
|
|
cts_dev = &cts_data->cts_dev;
|
|
hwrows = cts_dev->hwdata->num_row;
|
|
hwcols = cts_dev->hwdata->num_col;
|
|
fwrows = cts_dev->fwdata.rows;
|
|
fwcols = cts_dev->fwdata.cols;
|
|
|
|
rawdata = kzalloc(hwrows * hwcols * 2, GFP_KERNEL);
|
|
if (rawdata == NULL) {
|
|
cts_err("Allocate rawdata failed");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
cts_lock_device(cts_dev);
|
|
cts_tcs_top_get_rawdata(cts_dev, rawdata, hwrows * hwcols * 2, 0);
|
|
cts_unlock_device(cts_dev);
|
|
|
|
data = (s16 *)rawdata;
|
|
for (i = 0; i < fwcols; i++) {
|
|
for (j = 0; j < fwrows; j++) {
|
|
seq_printf(m, "%5d", *data++);
|
|
}
|
|
seq_printf(m, "\n");
|
|
}
|
|
|
|
kfree(rawdata);
|
|
return 0;
|
|
}
|
|
static int cts_rawdata_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, cts_rawdata_show, pde_data(inode));
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
|
static const struct file_operations cts_rawdata_ops = {
|
|
.owner = THIS_MODULE,
|
|
.open = cts_rawdata_open,
|
|
.read = seq_read,
|
|
};
|
|
#else
|
|
static const struct proc_ops cts_rawdata_ops = {
|
|
.proc_open = cts_rawdata_open,
|
|
.proc_read = seq_read,
|
|
};
|
|
#endif
|
|
|
|
static int cts_diffdata_show(struct seq_file *m, void *v)
|
|
{
|
|
struct chipone_ts_data *cts_data = m->private;
|
|
struct cts_device *cts_dev;
|
|
u8 *rawdata;
|
|
s16 *data;
|
|
u8 hwrows, hwcols, fwrows, fwcols;
|
|
u8 i, j;
|
|
|
|
cts_dev = &cts_data->cts_dev;
|
|
hwrows = cts_dev->hwdata->num_row;
|
|
hwcols = cts_dev->hwdata->num_col;
|
|
fwrows = cts_dev->fwdata.rows;
|
|
fwcols = cts_dev->fwdata.cols;
|
|
|
|
rawdata = kzalloc(hwrows * hwcols * 2, GFP_KERNEL);
|
|
if (rawdata == NULL) {
|
|
cts_err("Allocate rawdata failed");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
cts_lock_device(cts_dev);
|
|
cts_tcs_top_get_real_diff(cts_dev, rawdata, hwrows * hwcols * 2, 0);
|
|
cts_unlock_device(cts_dev);
|
|
|
|
data = (s16 *)rawdata;
|
|
for (i = 0; i < fwcols; i++) {
|
|
for (j = 0; j < fwrows; j++) {
|
|
seq_printf(m, "%5d", *data++);
|
|
}
|
|
seq_printf(m, "\n");
|
|
}
|
|
|
|
kfree(rawdata);
|
|
return 0;
|
|
}
|
|
static int cts_diffdata_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, cts_diffdata_show, pde_data(inode));
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
|
static const struct file_operations cts_diffdata_ops = {
|
|
.owner = THIS_MODULE,
|
|
.open = cts_diffdata_open,
|
|
.read = seq_read,
|
|
};
|
|
#else
|
|
static const struct proc_ops cts_diffdata_ops = {
|
|
.proc_open = cts_diffdata_open,
|
|
.proc_read = seq_read,
|
|
};
|
|
#endif
|
|
|
|
static int cts_manual_show(struct seq_file *m, void *v)
|
|
{
|
|
struct chipone_ts_data *cts_data = m->private;
|
|
struct cts_device *cts_dev;
|
|
u8 *rawdata;
|
|
s16 *data;
|
|
u8 hwrows, hwcols, fwrows, fwcols;
|
|
u8 i, j;
|
|
|
|
cts_dev = &cts_data->cts_dev;
|
|
hwrows = cts_dev->hwdata->num_row;
|
|
hwcols = cts_dev->hwdata->num_col;
|
|
fwrows = cts_dev->fwdata.rows;
|
|
fwcols = cts_dev->fwdata.cols;
|
|
|
|
rawdata = kzalloc(hwrows * hwcols * 2, GFP_KERNEL);
|
|
if (rawdata == NULL) {
|
|
cts_err("Allocate rawdata failed");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
cts_lock_device(cts_dev);
|
|
cts_tcs_top_get_manual_diff(cts_dev, rawdata, hwrows * hwcols * 2, 0);
|
|
cts_unlock_device(cts_dev);
|
|
|
|
data = (s16 *)rawdata;
|
|
for (i = 0; i < fwcols; i++) {
|
|
for (j = 0; j < fwrows; j++) {
|
|
seq_printf(m, "%5d", *data++);
|
|
}
|
|
seq_printf(m, "\n");
|
|
}
|
|
|
|
kfree(rawdata);
|
|
return 0;
|
|
}
|
|
static int cts_manual_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, cts_manual_show, pde_data(inode));
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
|
static const struct file_operations cts_manual_ops = {
|
|
.owner = THIS_MODULE,
|
|
.open = cts_manual_open,
|
|
.read = seq_read,
|
|
};
|
|
#else
|
|
static const struct proc_ops cts_manual_ops = {
|
|
.proc_open = cts_manual_open,
|
|
.proc_read = seq_read,
|
|
};
|
|
#endif
|
|
|
|
static int cts_cnegdata_show(struct seq_file *m, void *v)
|
|
{
|
|
struct chipone_ts_data *cts_data = m->private;
|
|
struct cts_device *cts_dev;
|
|
u8 *rawdata;
|
|
u8 *data;
|
|
u8 hwrows, hwcols, fwrows, fwcols;
|
|
u8 i, j;
|
|
|
|
cts_dev = &cts_data->cts_dev;
|
|
hwrows = cts_dev->hwdata->num_row;
|
|
hwcols = cts_dev->hwdata->num_col;
|
|
fwrows = cts_dev->fwdata.rows;
|
|
fwcols = cts_dev->fwdata.cols;
|
|
|
|
rawdata = kzalloc(hwrows * hwcols, GFP_KERNEL);
|
|
if (rawdata == NULL) {
|
|
cts_err("Allocate rawdata failed");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
cts_lock_device(cts_dev);
|
|
cts_tcs_top_get_cnegdata(cts_dev, rawdata, hwrows * hwcols, 0);
|
|
cts_unlock_device(cts_dev);
|
|
|
|
data = (u8 *)rawdata;
|
|
for (i = 0; i < fwcols; i++) {
|
|
for (j = 0; j < fwrows; j++) {
|
|
seq_printf(m, "%5d", *data++);
|
|
}
|
|
seq_printf(m, "\n");
|
|
}
|
|
|
|
kfree(rawdata);
|
|
return 0;
|
|
}
|
|
|
|
static int cts_cnegdata_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, cts_cnegdata_show, pde_data(inode));
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
|
static const struct file_operations cts_cnegdata_ops = {
|
|
.owner = THIS_MODULE,
|
|
.open = cts_cnegdata_open,
|
|
.read = seq_read,
|
|
};
|
|
#else
|
|
static const struct proc_ops cts_cnegdata_ops = {
|
|
.proc_open = cts_cnegdata_open,
|
|
.proc_read = seq_read,
|
|
};
|
|
#endif
|
|
|
|
/* Use limit bin */
|
|
static int cts_limit_show(struct seq_file *m, void *v)
|
|
{
|
|
struct chipone_ts_data *cts_data = m->private;
|
|
struct cts_device *cts_dev = &cts_data->cts_dev;
|
|
const struct firmware *limit_fw = NULL;
|
|
struct cts_limit limit;
|
|
char header[7] = {'C', 'h', 'i', 'p', 'o', 'n', 'e'};
|
|
int ret;
|
|
|
|
ret = request_firmware(&limit_fw, CFG_CTS_FACTORY_LIMIT_FILENAME,
|
|
&cts_dev->pdata->ts_input_dev->dev);
|
|
if (ret) {
|
|
seq_printf(m, "Request %s failed!\n", CFG_CTS_FACTORY_LIMIT_FILENAME);
|
|
return 0;
|
|
}
|
|
|
|
ret = memcmp(header, limit_fw->data, sizeof(header));
|
|
if (ret) {
|
|
seq_printf(m, "LIMIT file was not matched\n");
|
|
release_firmware(limit_fw);
|
|
return 0;
|
|
} else {
|
|
cts_info("Matched limit file!");
|
|
}
|
|
|
|
memcpy(&limit, limit_fw->data, limit_fw->size);
|
|
release_firmware(limit_fw);
|
|
|
|
seq_printf(m, "Limit version: %x, type:%d\n", limit.version, limit.type);
|
|
seq_printf(m, "\n");
|
|
seq_printf(m, "Switch status:\n");
|
|
seq_printf(m, " int_item : %d\n", limit.int_item);
|
|
seq_printf(m, " reset_item : %d\n", limit.reset_item);
|
|
seq_printf(m, " normal_rawdata_item : %d\n", limit.normal_rawdata_item);
|
|
seq_printf(m, " normal_noise_item : %d\n", limit.normal_noise_item);
|
|
seq_printf(m, " open_item : %d\n", limit.open_item);
|
|
seq_printf(m, " short_item : %d\n", limit.short_item);
|
|
seq_printf(m, " comp_cap_item : %d\n", limit.comp_cap_item);
|
|
seq_printf(m, " gstr_rawdata_item : %d\n", limit.gstr_rawdata_item);
|
|
seq_printf(m, " gstrlp_rawdata_item : %d\n", limit.gstrlp_rawdata_item);
|
|
seq_printf(m, " gstr_noise_item : %d\n", limit.gstr_noise_item);
|
|
seq_printf(m, " gstrlp_noise_item : %d\n", limit.gstrlp_noise_item);
|
|
seq_printf(m, " stylus_rawdata_item : %d\n", limit.stylus_rawdata_item);
|
|
seq_printf(m, " stylus_noise_item : %d\n", limit.stylus_noise_item);
|
|
seq_printf(m, " stylus_mnt_rawdata_item : %d\n", limit.stylus_mnt_rawdata_item);
|
|
seq_printf(m, "\n");
|
|
seq_printf(m, "Threshold:\n");
|
|
seq_printf(m, " normal_rawdata_frames : %d\n", limit.normal_rawdata_frames);
|
|
seq_printf(m, " normal_rawdata_min : %d\n", limit.normal_rawdata_min);
|
|
seq_printf(m, " normal_rawdata_max : %d\n", limit.normal_rawdata_max);
|
|
seq_printf(m, " normal_noise_frames : %d\n", limit.normal_noise_frames);
|
|
seq_printf(m, " normal_noise_max : %d\n", limit.normal_noise_max);
|
|
seq_printf(m, " normal_open_min : %d\n", limit.normal_open_min);
|
|
seq_printf(m, " normal_short_min : %d\n", limit.normal_short_min);
|
|
seq_printf(m, " normal_compcap_min : %d\n", limit.normal_compcap_min);
|
|
seq_printf(m, " normal_compcap_max : %d\n", limit.normal_compcap_max);
|
|
seq_printf(m, " gstr_rawdata_frames : %d\n", limit.gstr_rawdata_frames);
|
|
seq_printf(m, " gstr_rawdata_min : %d\n", limit.gstr_rawdata_min);
|
|
seq_printf(m, " gstr_rawdata_max : %d\n", limit.gstr_rawdata_max);
|
|
seq_printf(m, " gstrlp_rawdata_frames : %d\n", limit.gstrlp_rawdata_frames);
|
|
seq_printf(m, " gstrlp_rawdata_min : %d\n", limit.gstrlp_rawdata_min);
|
|
seq_printf(m, " gstrlp_rawdata_max : %d\n", limit.gstrlp_rawdata_max);
|
|
seq_printf(m, " gstr_noise_frames : %d\n", limit.gstr_noise_frames);
|
|
seq_printf(m, " gstr_noise_max : %d\n", limit.gstr_noise_max);
|
|
seq_printf(m, " gstrlp_noise_frames : %d\n", limit.gstrlp_noise_frames);
|
|
seq_printf(m, " gstrlp_noise_max : %d\n", limit.gstrlp_noise_max);
|
|
|
|
seq_printf(m, " stylus_rawdata_frames : %d\n", limit.stylus_rawdata_frames);
|
|
seq_printf(m, " stylus_rawdata_min : %d\n", limit.stylus_rawdata_min);
|
|
seq_printf(m, " stylus_rawdata_max : %d\n", limit.stylus_rawdata_max);
|
|
seq_printf(m, " stylus_noise_frames : %d\n", limit.stylus_noise_frames);
|
|
seq_printf(m, " stylus_noise_max : %d\n", limit.stylus_noise_max);
|
|
seq_printf(m, " stylus_mnt_rawdata_frames : %d\n", limit.stylus_mnt_rawdata_frames);
|
|
seq_printf(m, " stylus_mnt_rawdata_min : %d\n", limit.stylus_mnt_rawdata_min);
|
|
seq_printf(m, " stylus_mnt_rawdata_max : %d\n", limit.stylus_mnt_rawdata_max);
|
|
|
|
return 0;
|
|
}
|
|
static int cts_limit_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, cts_limit_show, pde_data(inode));
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
|
static const struct file_operations cts_limit_ops = {
|
|
.owner = THIS_MODULE,
|
|
.open = cts_limit_open,
|
|
.read = seq_read,
|
|
};
|
|
#else
|
|
static const struct proc_ops cts_limit_ops = {
|
|
.proc_open = cts_limit_open,
|
|
.proc_read = seq_read,
|
|
};
|
|
#endif
|
|
|
|
static void cts_print_limit_value(struct cts_limit limit)
|
|
{
|
|
cts_info("limit version : %x", limit.version);
|
|
cts_info("int_item : %d", limit.int_item);
|
|
cts_info("reset_item : %d", limit.reset_item);
|
|
cts_info("normal_rawdata_item : %d", limit.normal_rawdata_item);
|
|
cts_info("normal_noise_item : %d", limit.normal_noise_item);
|
|
cts_info("open_item : %d", limit.open_item);
|
|
cts_info("short_item : %d", limit.short_item);
|
|
cts_info("comp_cap_item : %d", limit.comp_cap_item);
|
|
cts_info("gstr_rawdata_item : %d", limit.gstr_rawdata_item);
|
|
cts_info("gstrlp_rawdata_item : %d", limit.gstrlp_rawdata_item);
|
|
cts_info("gstr_noise_item : %d", limit.gstr_noise_item);
|
|
cts_info("gstrlp_noise_item : %d", limit.gstrlp_noise_item);
|
|
cts_info("stylus_rawdata_item : %d", limit.stylus_rawdata_item);
|
|
cts_info("stylus_noise_item : %d", limit.stylus_noise_item);
|
|
cts_info("stylus_mnt_raw_item : %d", limit.stylus_mnt_rawdata_item);
|
|
cts_info("type : %d", limit.type);
|
|
cts_info("----------------------------");
|
|
cts_info("normal_rawdata_frames : %d", limit.normal_rawdata_frames);
|
|
cts_info("normal_rawdata_min : %d", limit.normal_rawdata_min);
|
|
cts_info("normal_rawdata_max : %d", limit.normal_rawdata_max);
|
|
cts_info("normal_noise_frames : %d", limit.normal_noise_frames);
|
|
cts_info("normal_noise_max : %d", limit.normal_noise_max);
|
|
cts_info("normal_open_min : %d", limit.normal_open_min);
|
|
cts_info("normal_short_min : %d", limit.normal_short_min);
|
|
cts_info("normal_compcap_min : %d", limit.normal_compcap_min);
|
|
cts_info("normal_compcap_max : %d", limit.normal_compcap_max);
|
|
cts_info("gstr_rawdata_frames : %d", limit.gstr_rawdata_frames);
|
|
cts_info("gstr_rawdata_min : %d", limit.gstr_rawdata_min);
|
|
cts_info("gstr_rawdata_max : %d", limit.gstr_rawdata_max);
|
|
cts_info("gstrlp_rawdata_frames : %d", limit.gstrlp_rawdata_frames);
|
|
cts_info("gstrlp_rawdata_min : %d", limit.gstrlp_rawdata_min);
|
|
cts_info("gstrlp_rawdata_max : %d", limit.gstrlp_rawdata_max);
|
|
cts_info("gstr_noise_frames : %d", limit.gstr_noise_frames);
|
|
cts_info("gstr_noise_max : %d", limit.gstr_noise_max);
|
|
cts_info("gstrlp_noise_frames : %d", limit.gstrlp_noise_frames);
|
|
cts_info("gstrlp_noise_max : %d", limit.gstrlp_noise_max);
|
|
cts_info("stylus_rawdata_frames : %d", limit.stylus_rawdata_frames);
|
|
cts_info("stylus_rawdata_min : %d", limit.stylus_rawdata_min);
|
|
cts_info("stylus_rawdata_max : %d", limit.stylus_rawdata_max);
|
|
cts_info("stylus_noise_frames : %d", limit.stylus_noise_frames);
|
|
cts_info("stylus_noise_max : %d", limit.stylus_noise_max);
|
|
cts_info("stylus_mnt_raw_frames : %d", limit.stylus_mnt_rawdata_frames);
|
|
cts_info("stylus_mnt_raw_min : %d", limit.stylus_mnt_rawdata_min);
|
|
cts_info("stylus_mnt_raw_max : %d", limit.stylus_mnt_rawdata_max);
|
|
}
|
|
|
|
|
|
static int cts_touch_test(struct seq_file *m, void *v, struct cts_limit limit)
|
|
{
|
|
struct chipone_ts_data *cts_data = m->private;
|
|
struct cts_device *cts_dev = &cts_data->cts_dev;
|
|
|
|
s64 reset_pin_test_elapsed_time = 0;
|
|
struct cts_test_param reset_pin_test_param = {
|
|
.test_item = CTS_TEST_RESET_PIN,
|
|
.flags = 0,
|
|
.elapsed_time_ms = &reset_pin_test_elapsed_time,
|
|
};
|
|
s64 int_pin_test_elapsed_time = 0;
|
|
struct cts_test_param int_pin_test_param = {
|
|
.test_item = CTS_TEST_INT_PIN,
|
|
.flags = 0,
|
|
.elapsed_time_ms = &int_pin_test_elapsed_time,
|
|
};
|
|
struct cts_rawdata_test_priv_param rawdata_test_priv_param = {
|
|
.frames = 16,
|
|
//.work_mode = 0,
|
|
};
|
|
s64 rawdata_test_elapsed_time = 0;
|
|
struct cts_test_param rawdata_test_param = {
|
|
.test_item = CTS_TEST_RAWDATA,
|
|
.flags = CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE,
|
|
.test_data_filepath = NULL,
|
|
.num_invalid_node = 0,
|
|
.invalid_nodes = NULL,
|
|
.elapsed_time_ms = &rawdata_test_elapsed_time,
|
|
.priv_param = &rawdata_test_priv_param,
|
|
.priv_param_size = sizeof(rawdata_test_priv_param),
|
|
};
|
|
struct cts_noise_test_priv_param noise_test_priv_param = {
|
|
.frames = 50,
|
|
//.work_mode = 0,
|
|
};
|
|
s64 noise_test_elapsed_time = 0;
|
|
struct cts_test_param noise_test_param = {
|
|
.test_item = CTS_TEST_NOISE,
|
|
.flags = CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE,
|
|
.test_data_filepath = NULL,
|
|
.num_invalid_node = 0,
|
|
.invalid_nodes = NULL,
|
|
.elapsed_time_ms = &noise_test_elapsed_time,
|
|
.priv_param = &noise_test_priv_param,
|
|
.priv_param_size = sizeof(noise_test_priv_param),
|
|
};
|
|
s64 open_test_elapsed_time = 0;
|
|
struct cts_test_param open_test_param = {
|
|
.test_item = CTS_TEST_OPEN,
|
|
.flags = CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE,
|
|
.test_data_filepath = NULL,
|
|
.num_invalid_node = 0,
|
|
.invalid_nodes = NULL,
|
|
.elapsed_time_ms = &open_test_elapsed_time,
|
|
};
|
|
s64 short_test_elapsed_time = 0;
|
|
struct cts_test_param short_test_param = {
|
|
.test_item = CTS_TEST_SHORT,
|
|
.flags = CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE,
|
|
.test_data_filepath = NULL,
|
|
.num_invalid_node = 0,
|
|
.invalid_nodes = NULL,
|
|
.elapsed_time_ms = &short_test_elapsed_time,
|
|
};
|
|
s64 comp_cap_test_elapsed_time = 0;
|
|
struct cts_test_param comp_cap_test_param = {
|
|
.test_item = CTS_TEST_COMPENSATE_CAP,
|
|
.flags = CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE,
|
|
.test_data_filepath = NULL,
|
|
.num_invalid_node = 0,
|
|
.invalid_nodes = NULL,
|
|
.elapsed_time_ms = &comp_cap_test_elapsed_time,
|
|
};
|
|
|
|
int normal_rawdata_frames;
|
|
int normal_rawdata_min;
|
|
int normal_rawdata_max;
|
|
int normal_noise_frames;
|
|
int normal_noise_max;
|
|
int normal_open_min;
|
|
int normal_short_min;
|
|
int normal_compcap_min;
|
|
int normal_compcap_max;
|
|
|
|
int rawdata_test_result = 0;
|
|
int noise_test_result = 0;
|
|
int open_test_result = 0;
|
|
int short_test_result = 0;
|
|
int comp_cap_test_result = 0;
|
|
|
|
char touch_data_filepath[256];
|
|
int retry;
|
|
int result_all = 0;
|
|
|
|
snprintf(touch_data_filepath, sizeof(touch_data_filepath),
|
|
TOUCH_DATA_DIRECTORY_PREFIX"/"RAWDATA_TEST_DATA_FILENAME);
|
|
rawdata_test_param.test_data_filepath =
|
|
kstrdup(touch_data_filepath, GFP_KERNEL);
|
|
snprintf(touch_data_filepath, sizeof(touch_data_filepath),
|
|
TOUCH_DATA_DIRECTORY_PREFIX"/"NOISE_TEST_DATA_FILENAME);
|
|
noise_test_param.test_data_filepath =
|
|
kstrdup(touch_data_filepath, GFP_KERNEL);
|
|
snprintf(touch_data_filepath, sizeof(touch_data_filepath),
|
|
TOUCH_DATA_DIRECTORY_PREFIX"/"OPEN_TEST_DATA_FILENAME);
|
|
open_test_param.test_data_filepath =
|
|
kstrdup(touch_data_filepath, GFP_KERNEL);
|
|
snprintf(touch_data_filepath, sizeof(touch_data_filepath),
|
|
TOUCH_DATA_DIRECTORY_PREFIX"/"SHORT_TEST_DATA_FILENAME);
|
|
short_test_param.test_data_filepath =
|
|
kstrdup(touch_data_filepath, GFP_KERNEL);
|
|
snprintf(touch_data_filepath, sizeof(touch_data_filepath),
|
|
TOUCH_DATA_DIRECTORY_PREFIX"/"COMP_CAP_TEST_DATA_FILENAME);
|
|
comp_cap_test_param.test_data_filepath =
|
|
kstrdup(touch_data_filepath, GFP_KERNEL);
|
|
|
|
normal_rawdata_frames = limit.normal_rawdata_frames;
|
|
normal_rawdata_min = limit.normal_rawdata_min;
|
|
normal_rawdata_max = limit.normal_rawdata_max;
|
|
normal_noise_frames = limit.normal_noise_frames;
|
|
normal_noise_max = limit.normal_noise_max;
|
|
normal_open_min = limit.normal_open_min;
|
|
normal_short_min = limit.normal_short_min;
|
|
normal_compcap_min = limit.normal_compcap_min;
|
|
normal_compcap_max = limit.normal_compcap_max;
|
|
|
|
rawdata_test_priv_param.frames = normal_rawdata_frames;
|
|
rawdata_test_param.min = &normal_rawdata_min;
|
|
rawdata_test_param.max = &normal_rawdata_max;
|
|
noise_test_priv_param.frames = normal_noise_frames;
|
|
noise_test_param.max = &normal_noise_max;
|
|
open_test_param.min = &normal_open_min;
|
|
short_test_param.min = &normal_short_min;
|
|
comp_cap_test_param.min = &normal_compcap_min;
|
|
comp_cap_test_param.max = &normal_compcap_max;
|
|
|
|
if (limit.int_item && cts_test_int_pin(cts_dev, &int_pin_test_param)) {
|
|
result_all++;
|
|
}
|
|
if (limit.reset_item && cts_test_reset_pin(cts_dev, &reset_pin_test_param)) {
|
|
result_all++;
|
|
}
|
|
if (limit.normal_rawdata_item) {
|
|
retry = 3;
|
|
do {
|
|
rawdata_test_result = cts_test_rawdata(cts_dev, &rawdata_test_param);
|
|
} while (rawdata_test_result < 0 && retry--);
|
|
if (rawdata_test_result) {
|
|
result_all++;
|
|
}
|
|
}
|
|
if (limit.normal_noise_item) {
|
|
retry = 3;
|
|
do {
|
|
noise_test_result = cts_test_noise(cts_dev, &noise_test_param);
|
|
} while (noise_test_result < 0 && retry--);
|
|
if (noise_test_result) {
|
|
result_all++;
|
|
}
|
|
}
|
|
if (limit.open_item) {
|
|
retry = 3;
|
|
do {
|
|
open_test_result = cts_test_open(cts_dev, &open_test_param);
|
|
} while (open_test_result < 0 && retry--);
|
|
if (open_test_result) {
|
|
result_all++;
|
|
}
|
|
}
|
|
if (limit.short_item) {
|
|
retry = 3;
|
|
do {
|
|
short_test_result = cts_test_short(cts_dev, &short_test_param);
|
|
} while (short_test_result < 0 && retry--);
|
|
if (short_test_result) {
|
|
result_all++;
|
|
}
|
|
}
|
|
if (limit.comp_cap_item) {
|
|
retry = 3;
|
|
do {
|
|
comp_cap_test_result =
|
|
cts_test_compensate_cap(cts_dev, &comp_cap_test_param);
|
|
} while (comp_cap_test_result < 0 && retry--);
|
|
if (comp_cap_test_result) {
|
|
result_all++;
|
|
}
|
|
}
|
|
|
|
if (rawdata_test_param.test_data_filepath) {
|
|
kfree(rawdata_test_param.test_data_filepath);
|
|
}
|
|
if (noise_test_param.test_data_filepath) {
|
|
kfree(noise_test_param.test_data_filepath);
|
|
}
|
|
if (open_test_param.test_data_filepath) {
|
|
kfree(open_test_param.test_data_filepath);
|
|
}
|
|
if (short_test_param.test_data_filepath) {
|
|
kfree(short_test_param.test_data_filepath);
|
|
}
|
|
if (comp_cap_test_param.test_data_filepath) {
|
|
kfree(comp_cap_test_param.test_data_filepath);
|
|
}
|
|
|
|
return result_all;
|
|
}
|
|
|
|
static int cts_stylus_test(struct seq_file *m, void *v, struct cts_limit limit)
|
|
{
|
|
struct chipone_ts_data *cts_data = m->private;
|
|
struct cts_device *cts_dev = &cts_data->cts_dev;
|
|
|
|
struct cts_rawdata_test_priv_param stylus_rawdata_test_priv_param = {
|
|
.frames = 16,
|
|
//.work_mode = 0,
|
|
};
|
|
s64 stylus_rawdata_test_elapsed_time = 0;
|
|
struct cts_test_param stylus_rawdata_test_param = {
|
|
.test_item = CTS_TEST_STYLUS_RAWDATA,
|
|
.flags = CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE,
|
|
.test_data_filepath = NULL,
|
|
.num_invalid_node = 0,
|
|
.invalid_nodes = NULL,
|
|
.elapsed_time_ms = &stylus_rawdata_test_elapsed_time,
|
|
.priv_param = &stylus_rawdata_test_priv_param,
|
|
.priv_param_size = sizeof(stylus_rawdata_test_priv_param),
|
|
};
|
|
|
|
struct cts_noise_test_priv_param stylus_noise_test_priv_param = {
|
|
.frames = 50,
|
|
//.work_mode = 0,
|
|
};
|
|
s64 stylus_noise_test_elapsed_time = 0;
|
|
struct cts_test_param stylus_noise_test_param = {
|
|
.test_item = CTS_TEST_NOISE,
|
|
.flags = CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE,
|
|
.test_data_filepath = NULL,
|
|
.num_invalid_node = 0,
|
|
.invalid_nodes = NULL,
|
|
.elapsed_time_ms = &stylus_noise_test_elapsed_time,
|
|
.priv_param = &stylus_noise_test_priv_param,
|
|
.priv_param_size = sizeof(stylus_noise_test_priv_param),
|
|
};
|
|
|
|
struct cts_rawdata_test_priv_param stylus_mnt_rawdata_test_priv_param = {
|
|
.frames = 16,
|
|
//.work_mode = 0,
|
|
};
|
|
s64 stylus_mnt_rawdata_test_elapsed_time = 0;
|
|
struct cts_test_param stylus_mnt_rawdata_test_param = {
|
|
.test_item = CTS_TEST_STYLUS_RAWDATA,
|
|
.flags = CTS_TEST_FLAG_VALIDATE_DATA |
|
|
CTS_TEST_FLAG_VALIDATE_MIN |
|
|
CTS_TEST_FLAG_VALIDATE_MAX |
|
|
CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE |
|
|
CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE,
|
|
.test_data_filepath = NULL,
|
|
.num_invalid_node = 0,
|
|
.invalid_nodes = NULL,
|
|
.elapsed_time_ms = &stylus_mnt_rawdata_test_elapsed_time,
|
|
.priv_param = &stylus_mnt_rawdata_test_priv_param,
|
|
.priv_param_size = sizeof(stylus_mnt_rawdata_test_priv_param),
|
|
};
|
|
|
|
int stylus_rawdata_frames;
|
|
int stylus_rawdata_min;
|
|
int stylus_rawdata_max;
|
|
int stylus_noise_frames;
|
|
int stylus_noise_max;
|
|
int stylus_mnt_rawdata_frames;
|
|
int stylus_mnt_rawdata_min;
|
|
int stylus_mnt_rawdata_max;
|
|
|
|
int stylus_rawdata_test_result = 0;
|
|
int stylus_noise_test_result = 0;
|
|
int stylus_mnt_rawdata_test_result = 0;
|
|
|
|
char touch_data_filepath[256];
|
|
int retry;
|
|
int result_all = 0;
|
|
|
|
snprintf(touch_data_filepath, sizeof(touch_data_filepath),
|
|
TOUCH_DATA_DIRECTORY_PREFIX"/"STYLUS_RAWDATA_TEST_DATA_FILENAME);
|
|
stylus_rawdata_test_param.test_data_filepath =
|
|
kstrdup(touch_data_filepath, GFP_KERNEL);
|
|
snprintf(touch_data_filepath, sizeof(touch_data_filepath),
|
|
TOUCH_DATA_DIRECTORY_PREFIX"/"STYLUS_NOISE_TEST_DATA_FILENAME);
|
|
stylus_noise_test_param.test_data_filepath =
|
|
kstrdup(touch_data_filepath, GFP_KERNEL);
|
|
snprintf(touch_data_filepath, sizeof(touch_data_filepath),
|
|
TOUCH_DATA_DIRECTORY_PREFIX"/"STYLUS_MNT_NOISE_TEST_DATA_FILENAME);
|
|
stylus_mnt_rawdata_test_param.test_data_filepath =
|
|
kstrdup(touch_data_filepath, GFP_KERNEL);
|
|
|
|
stylus_rawdata_frames = limit.stylus_rawdata_frames;
|
|
stylus_rawdata_min = limit.stylus_rawdata_min;
|
|
stylus_rawdata_max = limit.stylus_rawdata_max;
|
|
stylus_noise_frames = limit.stylus_noise_frames;
|
|
stylus_noise_max = limit.stylus_noise_max;
|
|
stylus_mnt_rawdata_frames = limit.stylus_mnt_rawdata_frames;
|
|
stylus_mnt_rawdata_min = limit.stylus_mnt_rawdata_min;
|
|
stylus_mnt_rawdata_max = limit.stylus_mnt_rawdata_max;
|
|
|
|
stylus_rawdata_test_priv_param.frames = stylus_rawdata_frames;
|
|
stylus_rawdata_test_param.min = &stylus_rawdata_min;
|
|
stylus_rawdata_test_param.max = &stylus_rawdata_max;
|
|
stylus_noise_test_priv_param.frames = stylus_noise_frames;
|
|
stylus_noise_test_param.max = &stylus_noise_max;
|
|
stylus_mnt_rawdata_test_priv_param.frames = stylus_mnt_rawdata_frames;
|
|
stylus_mnt_rawdata_test_param.min = &stylus_mnt_rawdata_min;
|
|
stylus_mnt_rawdata_test_param.max = &stylus_mnt_rawdata_max;
|
|
|
|
if (limit.stylus_rawdata_item) {
|
|
retry = 3;
|
|
do {
|
|
stylus_rawdata_test_result =
|
|
cts_test_stylus_rawdata(cts_dev, &stylus_rawdata_test_param);
|
|
} while (stylus_rawdata_test_result < 0 && retry--);
|
|
if (stylus_rawdata_test_result) {
|
|
result_all++;
|
|
}
|
|
}
|
|
if (limit.stylus_noise_item) {
|
|
retry = 3;
|
|
do {
|
|
stylus_noise_test_result =
|
|
cts_test_stylus_noise(cts_dev, &stylus_noise_test_param);
|
|
} while (stylus_noise_test_result < 0 && retry--);
|
|
if (stylus_noise_test_result) {
|
|
result_all++;
|
|
}
|
|
}
|
|
if (limit.stylus_mnt_rawdata_item) {
|
|
retry = 3;
|
|
do {
|
|
stylus_mnt_rawdata_test_result =
|
|
cts_test_stylus_mnt_rawdata(cts_dev, &stylus_mnt_rawdata_test_param);
|
|
} while (stylus_mnt_rawdata_test_result < 0 && retry--);
|
|
if (stylus_mnt_rawdata_test_result) {
|
|
result_all++;
|
|
}
|
|
}
|
|
|
|
if (stylus_rawdata_test_param.test_data_filepath) {
|
|
kfree(stylus_rawdata_test_param.test_data_filepath);
|
|
}
|
|
if (stylus_noise_test_param.test_data_filepath) {
|
|
kfree(stylus_noise_test_param.test_data_filepath);
|
|
}
|
|
if (stylus_mnt_rawdata_test_param.test_data_filepath) {
|
|
kfree(stylus_mnt_rawdata_test_param.test_data_filepath);
|
|
}
|
|
|
|
return result_all;
|
|
}
|
|
|
|
|
|
static int cts_factory_test_show(struct seq_file *m, void *v)
|
|
{
|
|
struct chipone_ts_data *cts_data = m->private;
|
|
struct cts_device *cts_dev = &cts_data->cts_dev;
|
|
const struct firmware *limit_fw = NULL;
|
|
struct cts_limit limit;
|
|
char header[7] = {'C', 'h', 'i', 'p', 'o', 'n', 'e'};
|
|
|
|
ktime_t start_time, end_time, delta_time;
|
|
u16 fw_version;
|
|
int result_all = 0;
|
|
int ret;
|
|
|
|
ret = request_firmware(&limit_fw, CFG_CTS_FACTORY_LIMIT_FILENAME,
|
|
&cts_dev->pdata->ts_input_dev->dev);
|
|
if (ret) {
|
|
cts_err("Request %s failed!", CFG_CTS_FACTORY_LIMIT_FILENAME);
|
|
return 0;
|
|
}
|
|
|
|
ret = memcmp(header, limit_fw->data, sizeof(header));
|
|
if (ret) {
|
|
cts_err("LIMIT file was not matched");
|
|
release_firmware(limit_fw);
|
|
return 0;
|
|
} else {
|
|
cts_info("Matched limit file!");
|
|
}
|
|
|
|
memcpy(&limit, limit_fw->data, limit_fw->size);
|
|
release_firmware(limit_fw);
|
|
|
|
cts_print_limit_value(limit);
|
|
|
|
start_time = ktime_get();
|
|
|
|
ret = cts_tcs_get_fw_ver(cts_dev, &fw_version);
|
|
if (ret) {
|
|
cts_err("Factory test get firmware version failed");
|
|
fw_version = 0;
|
|
}
|
|
cts_info("Firmware Version: 0x%04X", fw_version);
|
|
|
|
result_all += cts_touch_test(m, v, limit);
|
|
result_all += cts_stylus_test(m, v, limit);
|
|
|
|
end_time = ktime_get();
|
|
delta_time = ktime_sub(end_time, start_time);
|
|
|
|
cts_info("Factory test, total ELAPSED TIME: %lldms",
|
|
ktime_to_ms(delta_time));
|
|
|
|
seq_printf(m, "%s\n", result_all ? "FAIL" : "PASS");
|
|
return 0;
|
|
}
|
|
|
|
static int cts_factory_test_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, cts_factory_test_show, pde_data(inode));
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
|
static const struct file_operations cts_factory_test_ops = {
|
|
.owner = THIS_MODULE,
|
|
.open = cts_factory_test_open,
|
|
.read = seq_read,
|
|
};
|
|
#else
|
|
static const struct proc_ops cts_factory_test_ops = {
|
|
.proc_open = cts_factory_test_open,
|
|
.proc_read = seq_read,
|
|
};
|
|
#endif
|
|
|
|
|
|
int cts_oem_init(struct chipone_ts_data *cts_data)
|
|
{
|
|
struct cts_oem_data *oem_data = NULL;
|
|
int ret;
|
|
|
|
if (cts_data == NULL) {
|
|
cts_err("Init with cts_data = NULL");
|
|
return -EINVAL;
|
|
}
|
|
|
|
cts_info("Init");
|
|
|
|
cts_data->oem_data = NULL;
|
|
|
|
oem_data = kzalloc(sizeof(*oem_data), GFP_KERNEL);
|
|
if (oem_data == NULL) {
|
|
cts_err("Alloc oem data failed");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
cts_info(" - Create '/proc/"OEM_SELFTEST_PROC_FILENAME"'");
|
|
oem_data->selftest_proc_entry =
|
|
proc_create_data(OEM_SELFTEST_PROC_FILENAME,
|
|
S_IRUGO, NULL, &selftest_proc_fops, cts_data);
|
|
if (oem_data->selftest_proc_entry == NULL) {
|
|
cts_err("Create '/proc/"OEM_SELFTEST_PROC_FILENAME"' failed");
|
|
ret = -EFAULT;
|
|
goto free_oem_data;
|
|
}
|
|
|
|
oem_data->limit_entry =
|
|
proc_create_data(OEM_LIMIT_PROC_FILENAME,
|
|
S_IRUGO, NULL, &cts_limit_ops, cts_data);
|
|
if (oem_data->limit_entry == NULL) {
|
|
cts_err("Create '/proc/"OEM_LIMIT_PROC_FILENAME"' failed");
|
|
ret = -EFAULT;
|
|
goto free_oem_data;
|
|
}
|
|
|
|
oem_data->factory_test_entry =
|
|
proc_create_data(OEM_FACTORY_TEST_PROC_FILENAME,
|
|
S_IRUGO, NULL, &cts_factory_test_ops, cts_data);
|
|
if (oem_data->factory_test_entry == NULL) {
|
|
cts_err("Create '/proc/"OEM_FACTORY_TEST_PROC_FILENAME"' failed");
|
|
ret = -EFAULT;
|
|
goto free_oem_data;
|
|
}
|
|
|
|
oem_data->rawdata_proc_entry = proc_create_data(OEM_RAWDATA_PROC_FILENAME,
|
|
S_IRUGO, NULL, &cts_rawdata_ops, cts_data);
|
|
if (oem_data->rawdata_proc_entry == NULL) {
|
|
cts_err("Create '/proc/"OEM_RAWDATA_PROC_FILENAME"' failed");
|
|
ret = -EFAULT;
|
|
goto free_oem_data;
|
|
}
|
|
|
|
oem_data->manual_proc_entry = proc_create_data(OEM_MANUAL_PROC_FILENAME,
|
|
S_IRUGO, NULL, &cts_manual_ops, cts_data);
|
|
if (oem_data->manual_proc_entry == NULL) {
|
|
cts_err("Create '/proc/"OEM_MANUAL_PROC_FILENAME"' failed");
|
|
ret = -EFAULT;
|
|
goto free_oem_data;
|
|
}
|
|
|
|
oem_data->diffdata_proc_entry = proc_create_data(OEM_DIFFDATA_PROC_FILENAME,
|
|
S_IRUGO, NULL, &cts_diffdata_ops, cts_data);
|
|
if (oem_data->diffdata_proc_entry == NULL) {
|
|
cts_err("Create '/proc/"OEM_DIFFDATA_PROC_FILENAME"' failed");
|
|
ret = -EFAULT;
|
|
goto free_oem_data;
|
|
}
|
|
|
|
oem_data->cnegdata_proc_entry = proc_create_data(OEM_CNEGDATA_PROC_FILENAME,
|
|
S_IRUGO, NULL, &cts_cnegdata_ops, cts_data);
|
|
if (oem_data->cnegdata_proc_entry == NULL) {
|
|
cts_err("Create '/proc/"OEM_CNEGDATA_PROC_FILENAME"' failed");
|
|
ret = -EFAULT;
|
|
goto free_oem_data;
|
|
}
|
|
|
|
cts_data->oem_data = oem_data;
|
|
oem_data->cts_data = cts_data;
|
|
return 0;
|
|
|
|
free_oem_data:
|
|
kfree(oem_data);
|
|
return ret;
|
|
}
|
|
|
|
int cts_oem_deinit(struct chipone_ts_data *cts_data)
|
|
{
|
|
struct cts_oem_data *oem_data = NULL;
|
|
|
|
if (cts_data == NULL) {
|
|
cts_err("Deinit with cts_data = NULL");
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (cts_data->oem_data == NULL) {
|
|
cts_warn("Deinit with oem_data = NULL");
|
|
return 0;
|
|
}
|
|
|
|
cts_info("Deinit");
|
|
|
|
oem_data = cts_data->oem_data;
|
|
|
|
if (oem_data->cnegdata_proc_entry) {
|
|
cts_info(" Remove '/proc/"OEM_CNEGDATA_PROC_FILENAME"'");
|
|
remove_proc_entry(OEM_CNEGDATA_PROC_FILENAME, NULL);
|
|
}
|
|
|
|
if (oem_data->selftest_proc_entry) {
|
|
cts_info(" Remove '/proc/"OEM_SELFTEST_PROC_FILENAME"'");
|
|
remove_proc_entry(OEM_SELFTEST_PROC_FILENAME, NULL);
|
|
}
|
|
|
|
if (oem_data->limit_entry) {
|
|
cts_info(" Remove '/proc/"OEM_LIMIT_PROC_FILENAME"'");
|
|
remove_proc_entry(OEM_LIMIT_PROC_FILENAME, NULL);
|
|
}
|
|
if (oem_data->factory_test_entry) {
|
|
cts_info(" Remove '/proc/"OEM_FACTORY_TEST_PROC_FILENAME"'");
|
|
remove_proc_entry(OEM_FACTORY_TEST_PROC_FILENAME, NULL);
|
|
}
|
|
|
|
if (oem_data->rawdata_proc_entry) {
|
|
cts_info(" Remove '/proc/"OEM_RAWDATA_PROC_FILENAME"'");
|
|
remove_proc_entry(OEM_RAWDATA_PROC_FILENAME, NULL);
|
|
}
|
|
|
|
if (oem_data->manual_proc_entry) {
|
|
cts_info(" Remove '/proc/"OEM_MANUAL_PROC_FILENAME"'");
|
|
remove_proc_entry(OEM_MANUAL_PROC_FILENAME, NULL);
|
|
}
|
|
|
|
if (oem_data->diffdata_proc_entry) {
|
|
cts_info(" Remove '/proc/"OEM_DIFFDATA_PROC_FILENAME"'");
|
|
remove_proc_entry(OEM_DIFFDATA_PROC_FILENAME, NULL);
|
|
}
|
|
|
|
free_selftest_data_mem(oem_data);
|
|
|
|
kfree(cts_data->oem_data);
|
|
cts_data->oem_data = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|