diff --git a/drivers/input/touchscreen/himax_mmi/Kbuild b/drivers/input/touchscreen/himax_mmi/Kbuild index fe31ec3882bd..afa33dc21608 100644 --- a/drivers/input/touchscreen/himax_mmi/Kbuild +++ b/drivers/input/touchscreen/himax_mmi/Kbuild @@ -2,13 +2,16 @@ EXTRA_CFLAGS += -Wall EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include \ -I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/himax_mmi -EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_HIMAX_DEBUG +EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_HIMAX_DEBUG \ + -DCONFIG_TOUCHSCREEN_HIMAX_INSPECT ifeq ($(filter m y, $(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET)),) obj-m := himax_mmi.o endif +himax_mmi-objs += himax_ic_HX83112.o himax_mmi-objs += himax_platform.o -himax_mmi-objs += himax_ic.o +himax_mmi-objs += himax_inspection.o +himax_mmi-objs += himax_ic_incell_core.o himax_mmi-objs += himax_common.o himax_mmi-objs += himax_debug.o diff --git a/drivers/input/touchscreen/himax_mmi/himax_common.c b/drivers/input/touchscreen/himax_mmi/himax_common.c index b222d5a1af96..72b9d40d6ef0 100644 --- a/drivers/input/touchscreen/himax_mmi/himax_common.c +++ b/drivers/input/touchscreen/himax_mmi/himax_common.c @@ -1,46 +1,81 @@ -/* Himax Android Driver Sample Code for common functions -* -* Copyright (C) 2017 Himax Corporation. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* +/* Himax Android Driver Sample Code for common functions + + Copyright (C) 2018 Himax Corporation. + + This software is licensed under the terms of the GNU General Public + License version 2, as published by the Free Software Foundation, and + may be copied, distributed, and modified under those terms. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + */ #include "himax_common.h" -#include "himax_ic.h" +#include "himax_ic_core.h" + +#ifdef HX_SMART_WAKEUP +#define GEST_SUP_NUM 26 +/*Setting cust key define (DF = double finger)*/ +/*{Double Tap, Up, Down, Left, Rright, C, Z, M, + O, S, V, W, e, m, @, (reserve), + Finger gesture, ^, >, <, f(R), f(L), Up(DF), Down(DF), + Left(DF), Right(DF)}*/ + + uint8_t gest_event[GEST_SUP_NUM] = { + 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x81, 0x1D, 0x2D, 0x3D, 0x1F, 0x2F, 0x51, 0x52, + 0x53, 0x54}; + +/*gest_event mapping to gest_key_def*/ + uint16_t gest_key_def[GEST_SUP_NUM] = { + KEY_POWER, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275}; +#endif #define SUPPORT_FINGER_DATA_CHECKSUM 0x0F #define TS_WAKE_LOCK_TIMEOUT (2 * HZ) #define FRAME_COUNT 5 -#ifdef HX_RST_PIN_FUNC -extern void himax_ic_reset(uint8_t loadconfig,uint8_t int_off); +#if defined(HX_AUTO_UPDATE_FW) || defined(HX_ZERO_FLASH) +char *i_CTPM_firmware_name = "Himax_firmware.bin"; +bool g_auto_update_flag = false; #endif - #if defined(HX_AUTO_UPDATE_FW) -unsigned char i_CTPM_FW[]= -{ -#include "HX83100_Firmware_Version_FF23.i" -}; +unsigned char *i_CTPM_FW = NULL; +int i_CTPM_FW_len; +int g_i_FW_VER = 0; +int g_i_CFG_VER = 0; +int g_i_CID_MAJ = 0; /*GUEST ID*/ +int g_i_CID_MIN = 0; /*VER for GUEST*/ #endif - -#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) -extern void himax_resend_cmd_func(bool suspended); -extern void himax_rst_cmd_recovery_func(bool suspended); +#ifdef HX_ZERO_FLASH +int g_f_0f_updat = 0; #endif struct himax_ts_data *private_ts; struct himax_ic_data *ic_data; struct himax_report_data *hx_touch_data; +struct himax_core_fp g_core_fp; +struct himax_debug *debug_data; -static int HX_TOUCH_INFO_POINT_CNT = 0; +struct proc_dir_entry *himax_touch_proc_dir; +#define HIMAX_PROC_TOUCH_FOLDER "android_touch" +#ifdef CONFIG_TOUCHSCREEN_HIMAX_DEBUG + extern int himax_debug_init(void); + extern int himax_debug_remove(void); +#endif +/*ts_work about start*/ +struct himax_target_report_data *g_target_report_data = NULL; +int himax_report_data(struct himax_ts_data *ts, int ts_path, int ts_status); +static void himax_report_all_leave_event(struct himax_ts_data *ts); +/*ts_work about end*/ +static int HX_TOUCH_INFO_POINT_CNT; unsigned long FW_VER_MAJ_FLASH_ADDR; unsigned long FW_VER_MIN_FLASH_ADDR; @@ -48,7 +83,7 @@ unsigned long CFG_VER_MAJ_FLASH_ADDR; unsigned long CFG_VER_MIN_FLASH_ADDR; unsigned long CID_VER_MAJ_FLASH_ADDR; unsigned long CID_VER_MIN_FLASH_ADDR; -//unsigned long PANEL_VERSION_ADDR; +/*unsigned long PANEL_VERSION_ADDR;*/ unsigned long FW_VER_MAJ_FLASH_LENG; unsigned long FW_VER_MIN_FLASH_LENG; @@ -56,385 +91,703 @@ unsigned long CFG_VER_MAJ_FLASH_LENG; unsigned long CFG_VER_MIN_FLASH_LENG; unsigned long CID_VER_MAJ_FLASH_LENG; unsigned long CID_VER_MIN_FLASH_LENG; -//unsigned long PANEL_VERSION_LENG; +/*unsigned long PANEL_VERSION_LENG;*/ unsigned long FW_CFG_VER_FLASH_ADDR; -#ifdef HX_AUTO_UPDATE_FW -int g_i_FW_VER = 0; -int g_i_CFG_VER = 0; -int g_i_CID_MAJ = 0; //GUEST ID -int g_i_CID_MIN = 0; //VER for GUEST -#endif - -unsigned char IC_TYPE = 11; unsigned char IC_CHECKSUM = 0; #ifdef HX_ESD_RECOVERY -u8 HX_ESD_RESET_ACTIVATE = 0; -int hx_EB_event_flag = 0; -int hx_EC_event_flag = 0; -int hx_ED_event_flag = 0; -extern int g_zero_event_count; + u8 HX_ESD_RESET_ACTIVATE = 0; + int hx_EB_event_flag = 0; + int hx_EC_event_flag = 0; + int hx_ED_event_flag = 0; + int g_zero_event_count = 0; #endif u8 HX_HW_RESET_ACTIVATE = 0; -#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) -extern int himax_touch_proc_init(void); -extern void himax_touch_proc_deinit(void); -//PROC-START -#ifdef HX_TP_PROC_FLASH_DUMP -extern void himax_ts_flash_func(void); -extern void setFlashBuffer(void); -extern bool getFlashDumpGoing(void); -extern uint8_t getSysOperation(void); -extern void setSysOperation(uint8_t operation); -#endif -#ifdef HX_TP_PROC_GUEST_INFO -extern int himax_guest_info_get_status(void); -extern void himax_guest_info_set_status(int setting); -extern int himax_read_project_id(void); -#endif - - #if defined(HX_PLATFOME_DEFINE_KEY) -extern void himax_platform_key(void); -#endif - -#ifdef HX_TP_PROC_DIAG -extern void himax_ts_diag_func(void); - -extern int16_t *getMutualBuffer(void); -extern int16_t *getMutualNewBuffer(void); -extern int16_t *getMutualOldBuffer(void); -extern int16_t *getSelfBuffer(void); -extern uint8_t getXChannel(void); -extern uint8_t getYChannel(void); -extern uint8_t getDiagCommand(void); -extern void setXChannel(uint8_t x); -extern void setYChannel(uint8_t y); -extern void setMutualBuffer(void); -extern void setMutualNewBuffer(void); -extern void setMutualOldBuffer(void); -extern uint8_t diag_coor[128]; -extern int himax_set_diag_cmd(struct himax_ic_data *ic_data,struct himax_report_data *hx_touch_data); -#ifdef HX_TP_PROC_2T2R -extern bool Is_2T2R; -extern int16_t *getMutualBuffer_2(void); -extern uint8_t getXChannel_2(void); -extern uint8_t getYChannel_2(void); -extern void setXChannel_2(uint8_t x); -extern void setYChannel_2(uint8_t y); -extern void setMutualBuffer_2(void); -#endif -#endif -//PROC-END + extern void himax_platform_key(void); #endif extern int himax_parse_dt(struct himax_ts_data *ts, - struct himax_i2c_platform_data *pdata); -extern bool himax_calculateChecksum(struct i2c_client *client, bool change_iref); -#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) -static uint8_t vk_press = 0x00; -#endif + struct himax_i2c_platform_data *pdata); + static uint8_t AA_press = 0x00; static uint8_t EN_NoiseFilter = 0x00; static uint8_t Last_EN_NoiseFilter = 0x00; -static int hx_point_num = 0; // for himax_ts_work_func use + static int p_point_num = 0xFFFF; +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) +static uint8_t vk_press = 0x00; static int tpd_key = 0x00; static int tpd_key_old = 0x00; -static int probe_fail_flag = 0; +#endif +static int probe_fail_flag; #ifdef HX_USB_DETECT_GLOBAL -bool USB_detect_flag = 0; + bool USB_detect_flag; #endif #if defined(CONFIG_FB) int fb_notifier_callback(struct notifier_block *self, - unsigned long event, void *data); + unsigned long event, void *data); #elif defined(CONFIG_HAS_EARLYSUSPEND) static void himax_ts_early_suspend(struct early_suspend *h); static void himax_ts_late_resume(struct early_suspend *h); #endif -#if defined(HX_PALM_REPORT) -int himax_palm_detect(uint8_t *buf); -#endif - #ifdef HX_GESTURE_TRACK -static int gest_pt_cnt; -static int gest_pt_x[GEST_PT_MAX_NUM]; -static int gest_pt_y[GEST_PT_MAX_NUM]; -static int gest_start_x=0,gest_start_y=0,gest_end_x=0,gest_end_y=0; -static int gest_width=0,gest_height=0,gest_mid_x=0,gest_mid_y=0; -static int gn_gesture_coor[16]; -#endif - -#ifdef HX_CHIP_STATUS_MONITOR -struct chip_monitor_data *g_chip_monitor_data; -#endif - -#if defined(HX_TP_PROC_SELF_TEST)|| defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) -extern int g_self_test_entered; + static int gest_pt_cnt; + static int gest_pt_x[GEST_PT_MAX_NUM]; + static int gest_pt_y[GEST_PT_MAX_NUM]; + static int gest_start_x, gest_start_y, gest_end_x, gest_end_y; + static int gest_width, gest_height, gest_mid_x, gest_mid_y; + static int hx_gesture_coor[16]; #endif int himax_report_data_init(void); -extern int himax_get_touch_data_size(void); -//void himax_HW_reset(uint8_t loadconfig,uint8_t int_off); -extern void himax_log_touch_data(uint8_t *buf,struct himax_report_data *hx_touch_data); -extern void himax_log_touch_event(int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched); -extern void himax_log_touch_event_detail(struct himax_ts_data *ts,int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched,uint16_t old_finger); - -#if defined(HX_ESD_RECOVERY) -extern void himax_esd_ic_reset(void); -extern int himax_ic_esd_recovery(int hx_esd_event,int hx_zero_event,int length); -#endif +extern bool hx83112_chip_detect (void); extern int himax_dev_set(struct himax_ts_data *ts); extern int himax_input_register_device(struct input_dev *input_dev); +int g_ts_dbg = 0; -#ifdef HX_ZERO_FLASH -extern void himax_0f_operation(struct work_struct *work); +/* File node for Selftest, SMWP and HSEN - Start*/ +#define HIMAX_PROC_SELF_TEST_FILE "self_test" +struct proc_dir_entry *himax_proc_self_test_file; + +extern char *g_rslt_data; +#define HIMAX_PROC_SELF_TEST_RAW_FILE "self_test_rawdata" +struct proc_dir_entry *himax_proc_self_raw_file = NULL; + +uint8_t HX_PROC_SEND_FLAG; +#ifdef HX_SMART_WAKEUP + #define HIMAX_PROC_SMWP_FILE "SMWP" + struct proc_dir_entry *himax_proc_SMWP_file = NULL; + #define HIMAX_PROC_GESTURE_FILE "GESTURE" + struct proc_dir_entry *himax_proc_GESTURE_file = NULL; + uint8_t HX_SMWP_EN = 0; #endif +#if defined(HX_SMART_WAKEUP) || defined(CONFIG_TOUCHSCREEN_HIMAX_INSPECT) +bool FAKE_POWER_KEY_SEND = true; +#endif + +#ifdef HX_HIGH_SENSE + #define HIMAX_PROC_HSEN_FILE "HSEN" + struct proc_dir_entry *himax_proc_HSEN_file = NULL; +#endif + +#if defined(HX_PALM_REPORT) +static int himax_palm_detect(uint8_t *buf) +{ + struct himax_ts_data *ts = private_ts; + int32_t loop_i; + int base = 0; + int x = 0, y = 0, w = 0; + + loop_i = 0; + base = loop_i * 4; + x = buf[base] << 8 | buf[base + 1]; + y = (buf[base + 2] << 8 | buf[base + 3]); + w = buf[(ts->nFinger_support * 4) + loop_i]; + I(" %s HX_PALM_REPORT_loopi=%d,base=%x,X=%x,Y=%x,W=%x \n", __func__, loop_i, base, x, y, w); + if ((!atomic_read(&ts->suspend_mode)) && (x == 0xFA5A) && (y == 0xFA5A) && (w == 0x00)) + return PALM_REPORT; + else + return NOT_REPORT; +} +#endif + +static ssize_t himax_self_test_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + int val = 0x00; + size_t ret = 0; + char *temp_buf; + I("%s: enter, %d \n", __func__, __LINE__); + + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + himax_int_enable(0);/* disable irq */ + private_ts->in_self_test = 1; + val = g_core_fp.fp_chip_self_test(); +#ifdef HX_ESD_RECOVERY + HX_ESD_RESET_ACTIVATE = 1; +#endif + himax_int_enable(1);/* enable irq */ + + if (val == 0x00) { + ret += snprintf(temp_buf + ret, len - ret, "Self_Test Pass\n"); + } else { + ret += snprintf(temp_buf + ret, len - ret, "Self_Test Fail\n"); + } + + private_ts->in_self_test = 0; + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; +} + +static struct file_operations himax_proc_self_test_ops = { + .owner = THIS_MODULE, + .read = himax_self_test_read, +}; + +static void *himax_self_raw_seq_start(struct seq_file *s, loff_t *pos) +{ + if (*pos >= 1) { + return NULL; + } + return (void *)((unsigned long) *pos + 1); +} + +static void *himax_self_raw_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + return NULL; +} + +static void himax_self_raw_seq_stop(struct seq_file *s, void *v) +{ +} + +static int himax_self_raw_seq_read(struct seq_file *s, void *v) +{ + size_t ret = 0; + + if (g_rslt_data != NULL) { + seq_printf(s, "%s", g_rslt_data); + } + return ret; +} +static struct seq_operations himax_self_raw_seq_ops = { + .start = himax_self_raw_seq_start, + .next = himax_self_raw_seq_next, + .stop = himax_self_raw_seq_stop, + .show = himax_self_raw_seq_read, +}; +static int himax_self_raw_proc_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &himax_self_raw_seq_ops); +}; + +static struct file_operations himax_proc_self_raw_ops = { + .owner = THIS_MODULE, + .open = himax_self_raw_proc_open, + .read = seq_read, +}; + +#ifdef HX_HIGH_SENSE +static ssize_t himax_HSEN_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + size_t count = 0; + char *temp_buf; + + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + count = snprintf(temp_buf, PAGE_SIZE, "%d\n", ts->HSEN_enable); + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return count; +} + +static ssize_t himax_HSEN_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + char buf[80] = {0}; + + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } + + if (buf[0] == '0') + ts->HSEN_enable = 0; + else if (buf[0] == '1') + ts->HSEN_enable = 1; + else + return -EINVAL; + + g_core_fp.fp_set_HSEN_enable(ts->HSEN_enable, ts->suspended); + I("%s: HSEN_enable = %d.\n", __func__, ts->HSEN_enable); + return len; +} + +static struct file_operations himax_proc_HSEN_ops = { + .owner = THIS_MODULE, + .read = himax_HSEN_read, + .write = himax_HSEN_write, +}; +#endif + +#ifdef HX_SMART_WAKEUP +static ssize_t himax_SMWP_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + size_t count = 0; + struct himax_ts_data *ts = private_ts; + char *temp_buf; + + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + count = snprintf(temp_buf, PAGE_SIZE, "%d\n", ts->SMWP_enable); + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return count; +} + +static ssize_t himax_SMWP_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + char buf[80] = {0}; + + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } + + if (buf[0] == '0') + ts->SMWP_enable = 0; + else if (buf[0] == '1') + ts->SMWP_enable = 1; + else + return -EINVAL; + + g_core_fp.fp_set_SMWP_enable(ts->SMWP_enable, ts->suspended); + HX_SMWP_EN = ts->SMWP_enable; + I("%s: SMART_WAKEUP_enable = %d.\n", __func__, HX_SMWP_EN); + return len; +} + +static struct file_operations himax_proc_SMWP_ops = { + .owner = THIS_MODULE, + .read = himax_SMWP_read, + .write = himax_SMWP_write, +}; + +static ssize_t himax_GESTURE_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + int i = 0; + size_t ret = 0; + char *temp_buf; + + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + + for (i = 0; i < GEST_SUP_NUM; i++) + ret += snprintf(temp_buf + ret, len - ret, "ges_en[%d]=%d \n", i, ts->gesture_cust_en[i]); + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + ret = 0; + } + + return ret; +} + +static ssize_t himax_GESTURE_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + int i = 0; + int j = 0; + char buf[80] = {0}; + + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } + + I("himax_GESTURE_store= %s, len = %d \n", buf, (int)len); + + for (i = 0; i < len; i++) { + if (buf[i] == '0' && j < GEST_SUP_NUM) { + ts->gesture_cust_en[j] = 0; + I("gesture en[%d]=%d \n", j, ts->gesture_cust_en[j]); + j++; + } else if (buf[i] == '1' && j < GEST_SUP_NUM) { + ts->gesture_cust_en[j] = 1; + I("gesture en[%d]=%d \n", j, ts->gesture_cust_en[j]); + j++; + } else + I("Not 0/1 or >=GEST_SUP_NUM : buf[%d] = %c\n", i, buf[i]); + } + + return len; +} + +static struct file_operations himax_proc_Gesture_ops = { + .owner = THIS_MODULE, + .read = himax_GESTURE_read, + .write = himax_GESTURE_write, +}; +#endif + +#ifdef CONFIG_TOUCHSCREEN_HIMAX_INSPECT +extern void (*fp_himax_self_test_init)(void); +#endif + +int himax_common_proc_init(void) +{ + himax_touch_proc_dir = proc_mkdir(HIMAX_PROC_TOUCH_FOLDER, NULL); + + if (himax_touch_proc_dir == NULL) { + E(" %s: himax_touch_proc_dir file create failed!\n", __func__); + return -ENOMEM; + } +#ifdef CONFIG_TOUCHSCREEN_HIMAX_INSPECT + if (fp_himax_self_test_init != NULL) + fp_himax_self_test_init(); +#endif + + himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE, (S_IRUGO), himax_touch_proc_dir, &himax_proc_self_test_ops); + if (himax_proc_self_test_file == NULL) { + E(" %s: proc self_test file create failed!\n", __func__); + goto fail_1; + } + + himax_proc_self_raw_file = proc_create(HIMAX_PROC_SELF_TEST_RAW_FILE, (S_IRUGO), himax_touch_proc_dir, &himax_proc_self_raw_ops); + if (himax_proc_self_raw_file == NULL) { + E(" %s: proc self_test file create failed!\n", __func__); + goto fail_2; + } + +#ifdef HX_HIGH_SENSE + himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE, (S_IWUSR | S_IRUGO | S_IWUGO), + himax_touch_proc_dir, &himax_proc_HSEN_ops); + + if (himax_proc_HSEN_file == NULL) { + E(" %s: proc HSEN file create failed!\n", __func__); + goto fail_3; + } + +#endif +#ifdef HX_SMART_WAKEUP + himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE, (S_IWUSR | S_IRUGO | S_IWUGO), + himax_touch_proc_dir, &himax_proc_SMWP_ops); + + if (himax_proc_SMWP_file == NULL) { + E(" %s: proc SMWP file create failed!\n", __func__); + goto fail_4; + } + + himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE, (S_IWUSR | S_IRUGO | S_IWUGO), + himax_touch_proc_dir, &himax_proc_Gesture_ops); + + if (himax_proc_GESTURE_file == NULL) { + E(" %s: proc GESTURE file create failed!\n", __func__); + goto fail_5; + } +#endif + return 0; +#ifdef HX_SMART_WAKEUP + remove_proc_entry(HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir); +fail_5: + remove_proc_entry(HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir); +fail_4: +#endif +#ifdef HX_HIGH_SENSE + remove_proc_entry(HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir); +fail_3: +#endif + remove_proc_entry(HIMAX_PROC_SELF_TEST_RAW_FILE, himax_touch_proc_dir); +fail_2: + remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir); +fail_1: + return -ENOMEM; +} + +void himax_common_proc_deinit(void) +{ + remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_SELF_TEST_RAW_FILE, himax_touch_proc_dir); +#ifdef HX_SMART_WAKEUP + remove_proc_entry(HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir); +#endif +#ifdef HX_HIGH_SENSE + remove_proc_entry(HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir); +#endif +} + +/* File node for SMWP and HSEN - End*/ int himax_input_register(struct himax_ts_data *ts) { - int ret = 0; + int ret = 0; +#if defined(HX_SMART_WAKEUP) + int i = 0; +#endif + ret = himax_dev_set(ts); - ret = himax_dev_set(ts); - if(ret < 0) - goto input_device_fail; + if (ret < 0) { + goto input_device_fail; + } - set_bit(EV_SYN, ts->input_dev->evbit); - set_bit(EV_ABS, ts->input_dev->evbit); - set_bit(EV_KEY, ts->input_dev->evbit); - -#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) + set_bit(EV_SYN, ts->input_dev->evbit); + set_bit(EV_ABS, ts->input_dev->evbit); + set_bit(EV_KEY, ts->input_dev->evbit); #if defined(HX_PLATFOME_DEFINE_KEY) - himax_platform_key(); + himax_platform_key(); #else - set_bit(KEY_BACK, ts->input_dev->keybit); - set_bit(KEY_HOME, ts->input_dev->keybit); - set_bit(KEY_MENU, ts->input_dev->keybit); - set_bit(KEY_SEARCH, ts->input_dev->keybit); - set_bit(KEY_APP_SWITCH, ts->input_dev->keybit); + set_bit(KEY_BACK, ts->input_dev->keybit); + set_bit(KEY_HOME, ts->input_dev->keybit); + set_bit(KEY_MENU, ts->input_dev->keybit); + set_bit(KEY_SEARCH, ts->input_dev->keybit); #endif -#endif - -#if defined(HX_SMART_WAKEUP) || defined(HX_PALM_REPORT) || defined(HX_INSPECT_LPWUG_TEST) - set_bit(KEY_POWER, ts->input_dev->keybit); +#if defined(HX_SMART_WAKEUP) || defined(HX_PALM_REPORT) + set_bit(KEY_POWER, ts->input_dev->keybit); #endif #if defined(HX_SMART_WAKEUP) - set_bit(KEY_CUST_01, ts->input_dev->keybit); - set_bit(KEY_CUST_02, ts->input_dev->keybit); - set_bit(KEY_CUST_03, ts->input_dev->keybit); - set_bit(KEY_CUST_04, ts->input_dev->keybit); - set_bit(KEY_CUST_05, ts->input_dev->keybit); - set_bit(KEY_CUST_06, ts->input_dev->keybit); - set_bit(KEY_CUST_07, ts->input_dev->keybit); - set_bit(KEY_CUST_08, ts->input_dev->keybit); - set_bit(KEY_CUST_09, ts->input_dev->keybit); - set_bit(KEY_CUST_10, ts->input_dev->keybit); - set_bit(KEY_CUST_11, ts->input_dev->keybit); - set_bit(KEY_CUST_12, ts->input_dev->keybit); - set_bit(KEY_CUST_13, ts->input_dev->keybit); - set_bit(KEY_CUST_14, ts->input_dev->keybit); - set_bit(KEY_CUST_15, ts->input_dev->keybit); + for (i = 1; i < GEST_SUP_NUM; i++) { + set_bit(gest_key_def[i], ts->input_dev->keybit); + } #endif - set_bit(BTN_TOUCH, ts->input_dev->keybit); - set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); - + set_bit(BTN_TOUCH, ts->input_dev->keybit); + set_bit(KEY_APPSELECT, ts->input_dev->keybit); + set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); #ifdef HX_PROTOCOL_A - //ts->input_dev->mtsize = ts->nFinger_support; - input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, - 0, 3, 0, 0); + /*ts->input_dev->mtsize = ts->nFinger_support;*/ + input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, 3, 0, 0); #else - set_bit(MT_TOOL_FINGER, ts->input_dev->keybit); + set_bit(MT_TOOL_FINGER, ts->input_dev->keybit); #if defined(HX_PROTOCOL_B_3PA) - input_mt_init_slots(ts->input_dev, ts->nFinger_support, INPUT_MT_DIRECT); + input_mt_init_slots(ts->input_dev, ts->nFinger_support, INPUT_MT_DIRECT); #else - input_mt_init_slots(ts->input_dev, ts->nFinger_support); + input_mt_init_slots(ts->input_dev, ts->nFinger_support); #endif #endif - - I("input_set_abs_params: mix_x %d, max_x %d, min_y %d, max_y %d\n", - ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); - - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0); + I("input_set_abs_params: mix_x %d, max_x %d, min_y %d, max_y %d\n", + ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0); #ifndef HX_PROTOCOL_A - input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0); - input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR,ts->pdata->abs_width_min, ts->pdata->abs_width_max, ts->pdata->abs_pressure_fuzz, 0); + input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, ts->pdata->abs_width_min, ts->pdata->abs_width_max, ts->pdata->abs_pressure_fuzz, 0); #endif -// input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0, ((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0); -// input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0, (BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0); +/* input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0, ((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0, (BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0);*/ - - if(himax_input_register_device(ts->input_dev) == 0) - return NO_ERR; - else - ret = INPUT_REGISTER_FAIL; + if (himax_input_register_device(ts->input_dev) == 0) { + return NO_ERR; + } else { + ret = INPUT_REGISTER_FAIL; + } input_device_fail: - I("%s, input device register fail!\n",__func__); - return ret; + I("%s, input device register fail!\n", __func__); + return ret; } static void calcDataSize(uint8_t finger_num) { - struct himax_ts_data *ts_data = private_ts; - ts_data->coord_data_size = 4 * finger_num; - ts_data->area_data_size = ((finger_num / 4) + (finger_num % 4 ? 1 : 0)) * 4; - ts_data->coordInfoSize = ts_data->coord_data_size + ts_data->area_data_size + 4; - ts_data->raw_data_frame_size = 128 - ts_data->coord_data_size - ts_data->area_data_size - 4 - 4 - 1; - if(ts_data->raw_data_frame_size == 0) - { - E("%s: could NOT calculate! \n", __func__); - return; - } - ts_data->raw_data_nframes = ((uint32_t)ts_data->x_channel * ts_data->y_channel + - ts_data->x_channel + ts_data->y_channel) / ts_data->raw_data_frame_size + - (((uint32_t)ts_data->x_channel * ts_data->y_channel + - ts_data->x_channel + ts_data->y_channel) % ts_data->raw_data_frame_size)? 1 : 0; - I("%s: coord_data_size: %d, area_data_size:%d, raw_data_frame_size:%d, raw_data_nframes:%d", __func__, ts_data->coord_data_size, ts_data->area_data_size, ts_data->raw_data_frame_size, ts_data->raw_data_nframes); + struct himax_ts_data *ts_data = private_ts; + ts_data->coord_data_size = 4 * finger_num; + ts_data->area_data_size = ((finger_num / 4) + (finger_num % 4 ? 1 : 0)) * 4; + ts_data->coordInfoSize = ts_data->coord_data_size + ts_data->area_data_size + 4; + ts_data->raw_data_frame_size = 128 - ts_data->coord_data_size - ts_data->area_data_size - 4 - 4 - 1; + + if (ts_data->raw_data_frame_size == 0) { + E("%s: could NOT calculate! \n", __func__); + return; + } + + ts_data->raw_data_nframes = ((uint32_t)ts_data->x_channel * ts_data->y_channel + + ts_data->x_channel + ts_data->y_channel) / ts_data->raw_data_frame_size + + (((uint32_t)ts_data->x_channel * ts_data->y_channel + + ts_data->x_channel + ts_data->y_channel) % ts_data->raw_data_frame_size) ? 1 : 0; + I("%s: coord_data_size: %d, area_data_size:%d, raw_data_frame_size:%d, raw_data_nframes:%d\n", __func__, ts_data->coord_data_size, ts_data->area_data_size, ts_data->raw_data_frame_size, ts_data->raw_data_nframes); } -void calculate_point_number(void) +static void calculate_point_number(void) { - HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4 ; + HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4; - if ( (ic_data->HX_MAX_PT % 4) == 0) - HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4 ; - else - HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) +1) * 4 ; + if ((ic_data->HX_MAX_PT % 4) == 0) { + HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4; + } else { + HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) + 1) * 4; + } } +#if defined(HX_AUTO_UPDATE_FW) +static int himax_auto_update_check(void) +{ + I("%s:Entering!\n", __func__); + if (g_core_fp.fp_fw_ver_bin() == 0) { + if (((ic_data->vendor_fw_ver < g_i_FW_VER) || (ic_data->vendor_config_ver < g_i_CFG_VER))) { + I("Need to update!\n"); + return NO_ERR; + } else { + E("No need to update!\n"); + return 1; + } + } else { + E("FW bin fail!\n"); + return 1; + } +} +static int i_get_FW(void) +{ + int ret = 0; + const struct firmware *image = NULL; -#ifdef HX_AUTO_UPDATE_FW + I("file name = %s\n", i_CTPM_firmware_name); + ret = request_firmware(&image, i_CTPM_firmware_name, private_ts->dev); + if (ret < 0) { + E("%s,fail in line%d error code=%d\n", __func__, __LINE__, ret); + return OPEN_FILE_FAIL; + } + + if (image != NULL) { + i_CTPM_FW_len = image->size; + i_CTPM_FW = kzalloc(sizeof(char)*i_CTPM_FW_len, GFP_KERNEL); + memcpy(i_CTPM_FW, image->data, sizeof(char)*i_CTPM_FW_len); + } else { + I("%s: i_CTPM_FW = NULL\n", __func__); + return OPEN_FILE_FAIL; + } + + release_firmware(image); + ret = NO_ERR; + return ret; +} static int i_update_FW(void) { - int upgrade_times = 0; - unsigned char* ImageBuffer = i_CTPM_FW; - int fullFileLength = sizeof(i_CTPM_FW); - uint8_t ret = 0, result = 0; + int upgrade_times = 0; + + uint8_t ret = 0, result = 0; + + himax_int_enable(0); - I("%s: i_fullFileLength = %d\n", __func__,fullFileLength); - himax_int_enable(private_ts->client->irq,0); update_retry: - if(fullFileLength == FW_SIZE_32k) - { - ret = fts_ctpm_fw_upgrade_with_sys_fs_32k(private_ts->client,ImageBuffer,fullFileLength,false); - } - else if(fullFileLength == FW_SIZE_60k) - { - ret = fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,ImageBuffer,fullFileLength,false); - } - else if (fullFileLength == FW_SIZE_64k) - { - ret = fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,ImageBuffer,fullFileLength,false); - } - else if (fullFileLength == FW_SIZE_124k) - { - ret = fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,ImageBuffer,fullFileLength,false); - } - else if (fullFileLength == FW_SIZE_128k) - { - ret = fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,ImageBuffer,fullFileLength,false); - } - if(ret == 0) - { - upgrade_times++; - E("%s: TP upgrade error, upgrade_times = %d\n", __func__, upgrade_times); - if(upgrade_times < 3) - goto update_retry; - else - result = -1;//upgrade fail - } - else - { - himax_read_FW_ver(private_ts->client); - himax_touch_information(private_ts->client); - result = 1;//upgrade success - I("%s: TP upgrade OK\n", __func__); - } -#ifdef HX_RST_PIN_FUNC - himax_ic_reset(true,false); -#else - himax_sense_on(private_ts->client,0); + if (i_CTPM_FW_len == FW_SIZE_32k) { + ret = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_32k(i_CTPM_FW, i_CTPM_FW_len, false); + } else if (i_CTPM_FW_len == FW_SIZE_60k) { + ret = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_60k(i_CTPM_FW, i_CTPM_FW_len, false); + } else if (i_CTPM_FW_len == FW_SIZE_64k) { + ret = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_64k(i_CTPM_FW, i_CTPM_FW_len, false); + } else if (i_CTPM_FW_len == FW_SIZE_124k) { + ret = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_124k(i_CTPM_FW, i_CTPM_FW_len, false); + } else if (i_CTPM_FW_len == FW_SIZE_128k) { + ret = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_128k(i_CTPM_FW, i_CTPM_FW_len, false); + } + + if (ret == 0) { + upgrade_times++; + E("%s: TP upgrade error, upgrade_times = %d\n", __func__, upgrade_times); + + if (upgrade_times < 3) { + goto update_retry; + } else { + result = -1; + } /*upgrade fail*/ + } else { + g_core_fp.fp_read_FW_ver(); + g_core_fp.fp_touch_information(); + result = 1;/*upgrade success*/ + I("%s: TP upgrade OK\n", __func__); + } + + kfree(i_CTPM_FW); + +#ifdef HX_RST_PIN_FUNC + g_core_fp.fp_ic_reset(true, false); +#else + g_core_fp.fp_sense_on(0x00); #endif - himax_int_enable(private_ts->client->irq,1); - return result; + himax_int_enable(1); + return result; } #endif -int himax_loadSensorConfig(struct i2c_client *client, struct himax_i2c_platform_data *pdata) + +static int himax_loadSensorConfig(struct himax_i2c_platform_data *pdata) { - - if (!client) - { - E("%s: Necessary parameters client are null!\n", __func__); - return -1; - } - - I("%s: initialization complete\n", __func__); - - return NO_ERR; + I("%s: initialization complete\n", __func__); + return NO_ERR; } #ifdef HX_ESD_RECOVERY -void himax_esd_hw_reset(void) +static void himax_esd_hw_reset(void) { - I("START_Himax TP: ESD - Reset\n"); -#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) - if (g_self_test_entered == 1) - { - I("In self test ,not TP: ESD - Reset\n"); - return; - } +#ifdef HX_ZERO_FLASH + int result = 0; #endif -#if defined(HX_CHIP_STATUS_MONITOR) - g_chip_monitor_data->HX_CHIP_POLLING_COUNT=0; + if (g_ts_dbg != 0) + I("%s: Entering \n", __func__); + + I("START_Himax TP: ESD - Reset\n"); + + if (private_ts->in_self_test == 1) { + I("In self test , not TP: ESD - Reset\n"); + return; + } + + g_core_fp.fp_esd_ic_reset(); +#ifdef HX_ZERO_FLASH + I("It will update fw after esd event in zero flash mode!\n"); + result = g_core_fp.fp_0f_operation_dirly(); + if (result) { + E("Something is wrong! Skip Update with zero flash!\n"); + goto ESCAPE_0F_UPDATE; + } + g_core_fp.fp_reload_disable(0); + g_core_fp.fp_sense_on(0x00); + himax_report_all_leave_event(private_ts); + himax_int_enable(1); +ESCAPE_0F_UPDATE: #endif - himax_esd_ic_reset(); - - I("END_Himax TP: ESD - Reset\n"); -} -#endif - -#ifdef HX_CHIP_STATUS_MONITOR -static void himax_chip_monitor_function(struct work_struct *work) //for ESD solution -{ - int ret=0; - - I(" %s: POLLING_COUNT=%x, STATUS=%x\n", __func__,g_chip_monitor_data->HX_CHIP_POLLING_COUNT,ret); - if(g_chip_monitor_data->HX_CHIP_POLLING_COUNT >= (g_chip_monitor_data->HX_POLLING_TIMES-1))//POLLING TIME - { - g_chip_monitor_data->HX_ON_HAND_SHAKING=1; - ret = himax_hand_shaking(private_ts->client); //0:Running, 1:Stop, 2:I2C Fail - g_chip_monitor_data->HX_ON_HAND_SHAKING=0; - if(ret == 2) - { - I(" %s: I2C Fail \n", __func__); - himax_esd_hw_reset(); - } - else if(ret == 1) - { - I(" %s: MCU Stop \n", __func__); - himax_esd_hw_reset(); - } - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;//clear polling counter - } - else - g_chip_monitor_data->HX_CHIP_POLLING_COUNT++; - - - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; - queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); - - return; + I("END_Himax TP: ESD - Reset\n"); } #endif @@ -442,1196 +795,1221 @@ static void himax_chip_monitor_function(struct work_struct *work) //for ESD solu #ifdef HX_GESTURE_TRACK static void gest_pt_log_coordinate(int rx, int tx) { - //driver report x y with range 0 - 255 , we scale it up to x/y pixel - gest_pt_x[gest_pt_cnt] = rx*(ic_data->HX_X_RES)/255; - gest_pt_y[gest_pt_cnt] = tx*(ic_data->HX_Y_RES)/255; + /*driver report x y with range 0 - 255 , we scale it up to x/y pixel*/ + gest_pt_x[gest_pt_cnt] = rx * (ic_data->HX_X_RES) / 255; + gest_pt_y[gest_pt_cnt] = tx * (ic_data->HX_Y_RES) / 255; } #endif -static int himax_parse_wake_event(struct himax_ts_data *ts) +static int himax_wake_event_parse(struct himax_ts_data *ts, int ts_status) { - uint8_t *buf; + uint8_t *buf; #ifdef HX_GESTURE_TRACK - int tmp_max_x=0x00,tmp_min_x=0xFFFF,tmp_max_y=0x00,tmp_min_y=0xFFFF; - int gest_len; + int tmp_max_x = 0x00, tmp_min_x = 0xFFFF, tmp_max_y = 0x00, tmp_min_y = 0xFFFF; + int gest_len; #endif - int i=0, check_FC = 0, gesture_flag = 0; + int i = 0, check_FC = 0; + int j = 0, gesture_pos = 0, gesture_flag = 0; - buf = kzalloc(hx_touch_data->event_size*sizeof(uint8_t),GFP_KERNEL); - memcpy(buf,hx_touch_data->hx_event_buf,hx_touch_data->event_size); + if (g_ts_dbg != 0) + I("%s: Entering!, ts_status=%d\n", __func__, ts_status); - for(i=0; ievent_size * sizeof(uint8_t), GFP_KERNEL); + if (buf == NULL) { + return -ENOMEM; + } - I("0x%2.2X ", buf[i]); - if (i % 8 == 7) - I("\n"); - } - I("Himax gesture_flag= %x\n",gesture_flag ); - I("Himax check_FC is %d\n", check_FC); + memcpy(buf, hx_touch_data->hx_event_buf, hx_touch_data->event_size); - if (check_FC == 0) - return 0; - if(buf[GEST_PTLG_ID_LEN] != GEST_PTLG_HDR_ID1 || - buf[GEST_PTLG_ID_LEN+1] != GEST_PTLG_HDR_ID2) - return 0; + for (i = 0; i < GEST_PTLG_ID_LEN; i++) { + for (j = 0; j < GEST_SUP_NUM; j++) { + if (buf[i] == gest_event[j]) { + gesture_flag = buf[i]; + gesture_pos = j; + break; + } + } + I("0x%2.2X ", buf[i]); + if (buf[i] == gesture_flag) { + check_FC++; + } else { + I("ID START at %x , value = 0x%2X skip the event\n", i, buf[i]); + break; + } + } + + I("Himax gesture_flag= %x\n", gesture_flag); + I("Himax check_FC is %d\n", check_FC); + + if (check_FC != GEST_PTLG_ID_LEN) { + kfree(buf); + return 0; + } + + if (buf[GEST_PTLG_ID_LEN] != GEST_PTLG_HDR_ID1 || + buf[GEST_PTLG_ID_LEN + 1] != GEST_PTLG_HDR_ID2) { + kfree(buf); + return 0; + } #ifdef HX_GESTURE_TRACK - if(buf[GEST_PTLG_ID_LEN] == GEST_PTLG_HDR_ID1 && - buf[GEST_PTLG_ID_LEN+1] == GEST_PTLG_HDR_ID2) - { - gest_len = buf[GEST_PTLG_ID_LEN+2]; - I("gest_len = %d ",gest_len); + if (buf[GEST_PTLG_ID_LEN] == GEST_PTLG_HDR_ID1 && + buf[GEST_PTLG_ID_LEN + 1] == GEST_PTLG_HDR_ID2) { + gest_len = buf[GEST_PTLG_ID_LEN + 2]; + I("gest_len = %d \n", gest_len); + i = 0; + gest_pt_cnt = 0; + I("gest doornidate start \n %s", __func__); - i = 0; - gest_pt_cnt = 0; - I("gest doornidate start \n %s",__func__); - while(i<(gest_len+1)/2) - { - gest_pt_log_coordinate(buf[GEST_PTLG_ID_LEN+4+i*2],buf[GEST_PTLG_ID_LEN+4+i*2+1]); - i++; + while (i < (gest_len + 1) / 2) { + gest_pt_log_coordinate(buf[GEST_PTLG_ID_LEN + 4 + i * 2], buf[GEST_PTLG_ID_LEN + 4 + i * 2 + 1]); + i++; + I("gest_pt_x[%d]=%d \n", gest_pt_cnt, gest_pt_x[gest_pt_cnt]); + I("gest_pt_y[%d]=%d \n", gest_pt_cnt, gest_pt_y[gest_pt_cnt]); + gest_pt_cnt += 1; + } - I("gest_pt_x[%d]=%d \n",gest_pt_cnt,gest_pt_x[gest_pt_cnt]); - I("gest_pt_y[%d]=%d \n",gest_pt_cnt,gest_pt_y[gest_pt_cnt]); + if (gest_pt_cnt) { + for (i = 0; i < gest_pt_cnt; i++) { + if (tmp_max_x < gest_pt_x[i]) + tmp_max_x = gest_pt_x[i]; + if (tmp_min_x > gest_pt_x[i]) + tmp_min_x = gest_pt_x[i]; + if (tmp_max_y < gest_pt_y[i]) + tmp_max_y = gest_pt_y[i]; + if (tmp_min_y > gest_pt_y[i]) + tmp_min_y = gest_pt_y[i]; + } - gest_pt_cnt +=1; - } - if(gest_pt_cnt) - { - for(i=0; igest_pt_x[i]) - tmp_min_x=gest_pt_x[i]; - if(tmp_max_ygest_pt_y[i]) - tmp_min_y=gest_pt_y[i]; - } - I("gest_point x_min= %d, x_max= %d, y_min= %d, y_max= %d\n",tmp_min_x,tmp_max_x,tmp_min_y,tmp_max_y); - gest_start_x=gest_pt_x[0]; - gn_gesture_coor[0] = gest_start_x; - gest_start_y=gest_pt_y[0]; - gn_gesture_coor[1] = gest_start_y; - gest_end_x=gest_pt_x[gest_pt_cnt-1]; - gn_gesture_coor[2] = gest_end_x; - gest_end_y=gest_pt_y[gest_pt_cnt-1]; - gn_gesture_coor[3] = gest_end_y; - gest_width = tmp_max_x - tmp_min_x; - gn_gesture_coor[4] = gest_width; - gest_height = tmp_max_y - tmp_min_y; - gn_gesture_coor[5] = gest_height; - gest_mid_x = (tmp_max_x + tmp_min_x)/2; - gn_gesture_coor[6] = gest_mid_x; - gest_mid_y = (tmp_max_y + tmp_min_y)/2; - gn_gesture_coor[7] = gest_mid_y; - gn_gesture_coor[8] = gest_mid_x;//gest_up_x - gn_gesture_coor[9] = gest_mid_y-gest_height/2;//gest_up_y - gn_gesture_coor[10] = gest_mid_x;//gest_down_x - gn_gesture_coor[11] = gest_mid_y+gest_height/2; //gest_down_y - gn_gesture_coor[12] = gest_mid_x-gest_width/2; //gest_left_x - gn_gesture_coor[13] = gest_mid_y; //gest_left_y - gn_gesture_coor[14] = gest_mid_x+gest_width/2; //gest_right_x - gn_gesture_coor[15] = gest_mid_y; //gest_right_y + I("gest_point x_min= %d, x_max= %d, y_min= %d, y_max= %d\n", tmp_min_x, tmp_max_x, tmp_min_y, tmp_max_y); + gest_start_x = gest_pt_x[0]; + hx_gesture_coor[0] = gest_start_x; + gest_start_y = gest_pt_y[0]; + hx_gesture_coor[1] = gest_start_y; + gest_end_x = gest_pt_x[gest_pt_cnt - 1]; + hx_gesture_coor[2] = gest_end_x; + gest_end_y = gest_pt_y[gest_pt_cnt - 1]; + hx_gesture_coor[3] = gest_end_y; + gest_width = tmp_max_x - tmp_min_x; + hx_gesture_coor[4] = gest_width; + gest_height = tmp_max_y - tmp_min_y; + hx_gesture_coor[5] = gest_height; + gest_mid_x = (tmp_max_x + tmp_min_x) / 2; + hx_gesture_coor[6] = gest_mid_x; + gest_mid_y = (tmp_max_y + tmp_min_y) / 2; + hx_gesture_coor[7] = gest_mid_y; + hx_gesture_coor[8] = gest_mid_x;/*gest_up_x*/ + hx_gesture_coor[9] = gest_mid_y - gest_height / 2; /*gest_up_y*/ + hx_gesture_coor[10] = gest_mid_x;/*gest_down_x*/ + hx_gesture_coor[11] = gest_mid_y + gest_height / 2; /*gest_down_y*/ + hx_gesture_coor[12] = gest_mid_x - gest_width / 2; /*gest_left_x*/ + hx_gesture_coor[13] = gest_mid_y; /*gest_left_y*/ + hx_gesture_coor[14] = gest_mid_x + gest_width / 2; /*gest_right_x*/ + hx_gesture_coor[15] = gest_mid_y; /*gest_right_y*/ + } + } - } - - } #endif - if(gesture_flag != 0x80) - { - if(!ts->gesture_cust_en[gesture_flag]) - { - I("%s NOT report customer key \n ",__func__); - return 0;//NOT report customer key - } - } - else - { - if(!ts->gesture_cust_en[0]) - { - I("%s NOT report report double click \n",__func__); - return 0;//NOT report power key - } - } - if(gesture_flag == 0x80) - return EV_GESTURE_PWR; - else - return gesture_flag; + kfree(buf); + + if (!ts->gesture_cust_en[gesture_pos]) { + I("%s NOT report key [%d] = %d \n", __func__, gesture_pos, gest_key_def[gesture_pos]); + g_target_report_data->SMWP_event_chk = 0; + return 0; + } else { + g_target_report_data->SMWP_event_chk = gest_key_def[gesture_pos]; + return gesture_pos; + } } -void himax_wake_check_func(void) +static void himax_wake_event_report(void) { - int ret_event = 0, KEY_EVENT = 0; + int KEY_EVENT = g_target_report_data->SMWP_event_chk; - ret_event = himax_parse_wake_event(private_ts); - switch (ret_event) - { - case EV_GESTURE_PWR: - KEY_EVENT = KEY_POWER; - break; - case EV_GESTURE_01: - KEY_EVENT = KEY_CUST_01; - break; - case EV_GESTURE_02: - KEY_EVENT = KEY_CUST_02; - break; - case EV_GESTURE_03: - KEY_EVENT = KEY_CUST_03; - break; - case EV_GESTURE_04: - KEY_EVENT = KEY_CUST_04; - break; - case EV_GESTURE_05: - KEY_EVENT = KEY_CUST_05; - break; - case EV_GESTURE_06: - KEY_EVENT = KEY_CUST_06; - break; - case EV_GESTURE_07: - KEY_EVENT = KEY_CUST_07; - break; - case EV_GESTURE_08: - KEY_EVENT = KEY_CUST_08; - break; - case EV_GESTURE_09: - KEY_EVENT = KEY_CUST_09; - break; - case EV_GESTURE_10: - KEY_EVENT = KEY_CUST_10; - break; - case EV_GESTURE_11: - KEY_EVENT = KEY_CUST_11; - break; - case EV_GESTURE_12: - KEY_EVENT = KEY_CUST_12; - break; - case EV_GESTURE_13: - KEY_EVENT = KEY_CUST_13; - break; - case EV_GESTURE_14: - KEY_EVENT = KEY_CUST_14; - break; - case EV_GESTURE_15: - KEY_EVENT = KEY_CUST_15; - break; - } - if(ret_event) - { - I(" %s SMART WAKEUP KEY event %x press\n",__func__,KEY_EVENT); - input_report_key(private_ts->input_dev, KEY_EVENT, 1); - input_sync(private_ts->input_dev); - //msleep(100); - I(" %s SMART WAKEUP KEY event %x release\n",__func__,KEY_EVENT); - input_report_key(private_ts->input_dev, KEY_EVENT, 0); - input_sync(private_ts->input_dev); - FAKE_POWER_KEY_SEND=true; + if (g_ts_dbg != 0) + I("%s: Entering! \n", __func__); + + if (KEY_EVENT) { + I(" %s SMART WAKEUP KEY event %d press\n", __func__, KEY_EVENT); + input_report_key(private_ts->input_dev, KEY_EVENT, 1); + input_sync(private_ts->input_dev); + I(" %s SMART WAKEUP KEY event %d release\n", __func__, KEY_EVENT); + input_report_key(private_ts->input_dev, KEY_EVENT, 0); + input_sync(private_ts->input_dev); + FAKE_POWER_KEY_SEND = true; #ifdef HX_GESTURE_TRACK - I("gest_start_x= %d, gest_start_y= %d, gest_end_x= %d, gest_end_y= %d\n",gest_start_x,gest_start_y, - gest_end_x,gest_end_y); - I("gest_width= %d, gest_height= %d, gest_mid_x= %d, gest_mid_y= %d\n",gest_width,gest_height, - gest_mid_x,gest_mid_y); - I("gest_up_x= %d, gest_up_y= %d, gest_down_x= %d, gest_down_y= %d\n",gn_gesture_coor[8],gn_gesture_coor[9], - gn_gesture_coor[10],gn_gesture_coor[11]); - I("gest_left_x= %d, gest_left_y= %d, gest_right_x= %d, gest_right_y= %d\n",gn_gesture_coor[12],gn_gesture_coor[13], - gn_gesture_coor[14],gn_gesture_coor[15]); + I("gest_start_x= %d, gest_start_y= %d, gest_end_x= %d, gest_end_y= %d\n", gest_start_x, gest_start_y, + gest_end_x, gest_end_y); + I("gest_width= %d, gest_height= %d, gest_mid_x= %d, gest_mid_y= %d\n", gest_width, gest_height, + gest_mid_x, gest_mid_y); + I("gest_up_x= %d, gest_up_y= %d, gest_down_x= %d, gest_down_y= %d\n", hx_gesture_coor[8], hx_gesture_coor[9], + hx_gesture_coor[10], hx_gesture_coor[11]); + I("gest_left_x= %d, gest_left_y= %d, gest_right_x= %d, gest_right_y= %d\n", hx_gesture_coor[12], hx_gesture_coor[13], + hx_gesture_coor[14], hx_gesture_coor[15]); #endif - } + g_target_report_data->SMWP_event_chk = 0; + } } #endif -#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) -static void himax_ts_button_func(int tp_key_index,struct himax_ts_data *ts) -{ - uint16_t x_position = 0, y_position = 0; - if ( tp_key_index != 0x00) - { - I("virtual key index =%x\n",tp_key_index); - if ( tp_key_index == 0x01) - { - vk_press = 1; - I("back key pressed\n"); - if (ts->pdata->virtual_key) - { - if (ts->button[0].index) - { - x_position = (ts->button[0].x_range_min + ts->button[0].x_range_max) / 2; - y_position = (ts->button[0].y_range_min + ts->button[0].y_range_max) / 2; - } -#ifdef HX_PROTOCOL_A - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); - - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - y_position); - input_mt_sync(ts->input_dev); -#else - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, - 1); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, - 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - y_position); -#endif - } - else - input_report_key(ts->input_dev, KEY_BACK, 1); - } - else if ( tp_key_index == 0x02) - { - vk_press = 1; - I("home key pressed\n"); - if (ts->pdata->virtual_key) - { - if (ts->button[1].index) - { - x_position = (ts->button[1].x_range_min + ts->button[1].x_range_max) / 2; - y_position = (ts->button[1].y_range_min + ts->button[1].y_range_max) / 2; - } -#ifdef HX_PROTOCOL_A - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - 100); - - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - y_position); - input_mt_sync(ts->input_dev); -#else - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, - 1); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, - 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - y_position); -#endif - } - else - input_report_key(ts->input_dev, KEY_HOME, 1); - } - else if ( tp_key_index == 0x04) - { - vk_press = 1; - I("APP_switch key pressed\n"); - if (ts->pdata->virtual_key) - { - if (ts->button[2].index) - { - x_position = (ts->button[2].x_range_min + ts->button[2].x_range_max) / 2; - y_position = (ts->button[2].y_range_min + ts->button[2].y_range_max) / 2; - } -#ifdef HX_PROTOCOL_A - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); - - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, - 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - y_position); - input_mt_sync(ts->input_dev); -#else - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, - 1); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, - 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - y_position); -#endif - } - else - input_report_key(ts->input_dev, KEY_APP_SWITCH, 1); - } - input_sync(ts->input_dev); - } - else/*tp_key_index =0x00*/ - { - I("virtual key released\n"); - vk_press = 0; -#ifndef HX_PROTOCOL_A - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); -#else - input_mt_sync(ts->input_dev); -#endif - input_report_key(ts->input_dev, KEY_BACK, 0); - input_report_key(ts->input_dev, KEY_HOME, 0); - input_report_key(ts->input_dev, KEY_APP_SWITCH, 0); -#ifndef HX_PROTOCOL_A - input_sync(ts->input_dev); -#endif - } -} - -void himax_report_key(struct himax_ts_data *ts) -{ - if(hx_point_num!=0) - { - //Touch KEY - if ((tpd_key_old != 0x00)&&(tpd_key == 0x00)) - { - //temp_x[0] = 0xFFFF; - //temp_y[0] = 0xFFFF; - //temp_x[1] = 0xFFFF; - //temp_y[1] = 0xFFFF; - hx_touch_data->finger_on = 0; -#ifdef HX_PROTOCOL_A - input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); -#endif - himax_ts_button_func(tpd_key,ts); - } -#ifndef HX_PROTOCOL_A - input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); -#endif - input_sync(ts->input_dev); - } - else - { - if (tpd_key != 0x00) - { - hx_touch_data->finger_on = 1; -#ifdef HX_PROTOCOL_A - input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); -#endif - himax_ts_button_func(tpd_key,ts); - - } - else if ((tpd_key_old != 0x00)&&(tpd_key == 0x00)) - { - hx_touch_data->finger_on = 0; -#ifdef HX_PROTOCOL_A - input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); -#endif - himax_ts_button_func(tpd_key,ts); - - } -#ifndef HX_PROTOCOL_A - input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); -#endif - input_sync(ts->input_dev); - } - tpd_key_old = tpd_key; - Last_EN_NoiseFilter = EN_NoiseFilter; -} -#endif - int himax_report_data_init(void) { - if(hx_touch_data->hx_coord_buf!=NULL) - { - kfree(hx_touch_data->hx_coord_buf); - } -#ifdef HX_TP_PROC_DIAG - if(hx_touch_data->hx_rawdata_buf!=NULL) - { - kfree(hx_touch_data->hx_rawdata_buf); - } -#endif + if (hx_touch_data->hx_coord_buf != NULL) { + kfree(hx_touch_data->hx_coord_buf); + } + + if (hx_touch_data->hx_rawdata_buf != NULL) { + kfree(hx_touch_data->hx_rawdata_buf); + } #if defined(HX_SMART_WAKEUP) - hx_touch_data->event_size = himax_get_touch_data_size(); - if(hx_touch_data->hx_event_buf!=NULL) - { - kfree(hx_touch_data->hx_event_buf); - } + hx_touch_data->event_size = g_core_fp.fp_get_touch_data_size(); + + if (hx_touch_data->hx_event_buf != NULL) { + kfree(hx_touch_data->hx_event_buf); + } + +#endif + hx_touch_data->touch_all_size = g_core_fp.fp_get_touch_data_size(); + hx_touch_data->raw_cnt_max = ic_data->HX_MAX_PT / 4; + hx_touch_data->raw_cnt_rmd = ic_data->HX_MAX_PT % 4; + /* more than 4 fingers */ + if (hx_touch_data->raw_cnt_rmd != 0x00) { + hx_touch_data->rawdata_size = g_core_fp.fp_cal_data_len(hx_touch_data->raw_cnt_rmd, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max); + hx_touch_data->touch_info_size = (ic_data->HX_MAX_PT + hx_touch_data->raw_cnt_max + 2) * 4; + } else { /* less than 4 fingers */ + hx_touch_data->rawdata_size = g_core_fp.fp_cal_data_len(hx_touch_data->raw_cnt_rmd, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max); + hx_touch_data->touch_info_size = (ic_data->HX_MAX_PT + hx_touch_data->raw_cnt_max + 1) * 4; + } + + if ((ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) % hx_touch_data->rawdata_size == 0) { + hx_touch_data->rawdata_frame_size = (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) / hx_touch_data->rawdata_size; + } else { + hx_touch_data->rawdata_frame_size = (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) / hx_touch_data->rawdata_size + 1; + } + + I("%s: rawdata_frame_size = %d\n", __func__, hx_touch_data->rawdata_frame_size); + I("%s: ic_data->HX_MAX_PT:%d, hx_raw_cnt_max:%d, hx_raw_cnt_rmd:%d, g_hx_rawdata_size:%d, hx_touch_data->touch_info_size:%d\n", __func__, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max, hx_touch_data->raw_cnt_rmd, hx_touch_data->rawdata_size, hx_touch_data->touch_info_size); + hx_touch_data->hx_coord_buf = kzalloc(sizeof(uint8_t) * (hx_touch_data->touch_info_size), GFP_KERNEL); + + if (hx_touch_data->hx_coord_buf == NULL) { + goto mem_alloc_fail; + } + + if (g_target_report_data == NULL) { + g_target_report_data = kzalloc(sizeof(struct himax_target_report_data), GFP_KERNEL); + if (g_target_report_data == NULL) + goto mem_alloc_fail; + g_target_report_data->x = kzalloc(sizeof(int)*(ic_data->HX_MAX_PT), GFP_KERNEL); + if (g_target_report_data->x == NULL) + goto mem_alloc_fail; + g_target_report_data->y = kzalloc(sizeof(int)*(ic_data->HX_MAX_PT), GFP_KERNEL); + if (g_target_report_data->y == NULL) + goto mem_alloc_fail; + g_target_report_data->w = kzalloc(sizeof(int)*(ic_data->HX_MAX_PT), GFP_KERNEL); + if (g_target_report_data->w == NULL) + goto mem_alloc_fail; + g_target_report_data->finger_id = kzalloc(sizeof(int)*(ic_data->HX_MAX_PT), GFP_KERNEL); + if (g_target_report_data->finger_id == NULL) + goto mem_alloc_fail; + } +#ifdef HX_SMART_WAKEUP + g_target_report_data->SMWP_event_chk = 0; #endif - hx_touch_data->touch_all_size = himax_get_touch_data_size(); - hx_touch_data->raw_cnt_max = ic_data->HX_MAX_PT/4; - hx_touch_data->raw_cnt_rmd = ic_data->HX_MAX_PT%4; + hx_touch_data->hx_rawdata_buf = kzalloc(sizeof(uint8_t) * (hx_touch_data->touch_all_size - hx_touch_data->touch_info_size), GFP_KERNEL); - if (hx_touch_data->raw_cnt_rmd != 0x00) //more than 4 fingers - { - hx_touch_data->rawdata_size = cal_data_len(hx_touch_data->raw_cnt_rmd, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max); - hx_touch_data->touch_info_size = (ic_data->HX_MAX_PT+hx_touch_data->raw_cnt_max+2)*4; - } - else //less than 4 fingers - { - hx_touch_data->rawdata_size = cal_data_len(hx_touch_data->raw_cnt_rmd, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max); - hx_touch_data->touch_info_size = (ic_data->HX_MAX_PT+hx_touch_data->raw_cnt_max+1)*4; - } - if((ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) % hx_touch_data->rawdata_size == 0) - hx_touch_data->rawdata_frame_size = (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) / hx_touch_data->rawdata_size; - else - hx_touch_data->rawdata_frame_size = (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) / hx_touch_data->rawdata_size + 1; - I("%s: rawdata_frame_size = %d ",__func__,hx_touch_data->rawdata_frame_size); - I("%s: ic_data->HX_MAX_PT:%d,hx_raw_cnt_max:%d,hx_raw_cnt_rmd:%d,g_hx_rawdata_size:%d,hx_touch_data->touch_info_size:%d\n",__func__,ic_data->HX_MAX_PT,hx_touch_data->raw_cnt_max,hx_touch_data->raw_cnt_rmd,hx_touch_data->rawdata_size,hx_touch_data->touch_info_size); - - hx_touch_data->hx_coord_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->touch_info_size),GFP_KERNEL); - if(hx_touch_data->hx_coord_buf == NULL) - goto mem_alloc_fail; -#ifdef HX_TP_PROC_DIAG - hx_touch_data->hx_rawdata_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->touch_all_size - hx_touch_data->touch_info_size),GFP_KERNEL); - if(hx_touch_data->hx_rawdata_buf == NULL) - goto mem_alloc_fail; -#endif + if (hx_touch_data->hx_rawdata_buf == NULL) { + goto mem_alloc_fail; + } #if defined(HX_SMART_WAKEUP) - hx_touch_data->hx_event_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->event_size),GFP_KERNEL); - if(hx_touch_data->hx_event_buf == NULL) - goto mem_alloc_fail; + hx_touch_data->hx_event_buf = kzalloc(sizeof(uint8_t) * (hx_touch_data->event_size), GFP_KERNEL); + + if (hx_touch_data->hx_event_buf == NULL) { + goto mem_alloc_fail; + } + #endif - - return NO_ERR; - + return NO_ERR; mem_alloc_fail: - kfree(hx_touch_data->hx_coord_buf); -#if defined(HX_TP_PROC_DIAG) - kfree(hx_touch_data->hx_rawdata_buf); -#endif + kfree(g_target_report_data->x); + kfree(g_target_report_data->y); + kfree(g_target_report_data->w); + kfree(g_target_report_data->finger_id); + kfree(g_target_report_data); + g_target_report_data = NULL; + kfree(hx_touch_data->hx_coord_buf); + kfree(hx_touch_data->hx_rawdata_buf); #if defined(HX_SMART_WAKEUP) - kfree(hx_touch_data->hx_event_buf); + kfree(hx_touch_data->hx_event_buf); #endif - - I("%s: Memory allocate fail!\n",__func__); - return MEM_ALLOC_FAIL; - + I("%s: Memory allocate fail!\n", __func__); + return MEM_ALLOC_FAIL; } - +/*start ts_work*/ #if defined(HX_USB_DETECT_GLOBAL) void himax_cable_detect_func(bool force_renew) { - struct himax_ts_data *ts; - u32 connect_status = 0; + struct himax_ts_data *ts; + u32 connect_status = 0; + connect_status = USB_detect_flag;/* upmu_is_chr_det(); */ + ts = private_ts; - connect_status = USB_detect_flag;//upmu_is_chr_det(); - ts = private_ts; - //I("Touch: cable status=%d, cable_config=%p, usb_connected=%d \n", connect_status,ts->cable_config, ts->usb_connected); - if (ts->cable_config) - { - if (((!!connect_status) != ts->usb_connected) || force_renew) - { + /* I("Touch: cable status=%d, cable_config=%p, usb_connected=%d \n", connect_status, ts->cable_config, ts->usb_connected); */ + if (ts->cable_config) { + if (((!!connect_status) != ts->usb_connected) || force_renew) { + if (!!connect_status) { + ts->cable_config[1] = 0x01; + ts->usb_connected = 0x01; + } else { + ts->cable_config[1] = 0x00; + ts->usb_connected = 0x00; + } - if (!!connect_status) - { - ts->cable_config[1] = 0x01; - ts->usb_connected = 0x01; - } - else - { - ts->cable_config[1] = 0x00; - ts->usb_connected = 0x00; - } + g_core_fp.fp_usb_detect_set(ts->cable_config); + I("%s: Cable status change: 0x%2.2X\n", __func__, ts->usb_connected); + } - himax_usb_detect_set(ts->client,ts->cable_config); - - I("%s: Cable status change: 0x%2.2X\n", __func__, ts->usb_connected); - } - //else - // I("%s: Cable status is the same as previous one, ignore.\n", __func__); - } + /* else */ + /* I("%s: Cable status is the same as previous one, ignore.\n", __func__); */ + } } #endif -static void himax_report_points(struct himax_ts_data *ts) +static int himax_ts_work_status(struct himax_ts_data *ts) { - int x = 0; - int y = 0; - int w = 0; - int base = 0; - int32_t loop_i = 0; - uint16_t old_finger = 0; + /* 1: normal, 2:SMWP */ + int result = HX_REPORT_COORD; - //I("%s:Entering\n",__func__); + hx_touch_data->diag_cmd = ts->diag_cmd; + if (hx_touch_data->diag_cmd) + result = HX_REPORT_COORD_RAWDATA; - /* finger on/press */ - if (hx_point_num != 0 ) - { - old_finger = ts->pre_finger_mask; - ts->pre_finger_mask = 0; - hx_touch_data->finger_num = hx_touch_data->hx_coord_buf[ts->coordInfoSize - 4] & 0x0F; - hx_touch_data->finger_on = 1; - AA_press = 1; - for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) - { - base = loop_i * 4; - x = hx_touch_data->hx_coord_buf[base] << 8 | hx_touch_data->hx_coord_buf[base + 1]; - y = (hx_touch_data->hx_coord_buf[base + 2] << 8 | hx_touch_data->hx_coord_buf[base + 3]); - w = hx_touch_data->hx_coord_buf[(ts->nFinger_support * 4) + loop_i]; - //x = ic_data->HX_X_RES - x; - //y = ic_data->HX_Y_RES - y; - if(x >= 0 && x <= ts->pdata->abs_x_max && y >= 0 && y <= ts->pdata->abs_y_max) - { - hx_touch_data->finger_num--; - if ((ts->debug_log_level & BIT(3)) > 0) - { - himax_log_touch_event_detail(ts,x,y,w,loop_i,EN_NoiseFilter,HX_FINGER_ON,old_finger); - } -#ifndef HX_PROTOCOL_A - - input_mt_slot(ts->input_dev, loop_i); +#ifdef HX_SMART_WAKEUP + if (atomic_read(&ts->suspend_mode) && (!FAKE_POWER_KEY_SEND) && (ts->SMWP_enable) && (!hx_touch_data->diag_cmd)) + result = HX_REPORT_SMWP_EVENT; #endif - input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, loop_i); -#ifndef HX_PROTOCOL_A - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, w); -#endif - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); - -#ifndef HX_PROTOCOL_A - ts->last_slot = loop_i; - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1); -#else - input_mt_sync(ts->input_dev); -#endif - - if (!ts->first_pressed) - { - ts->first_pressed = 1; - I("S1@%d, %d\n", x, y); - } - - ts->pre_finger_data[loop_i][0] = x; - ts->pre_finger_data[loop_i][1] = y; - if (ts->debug_log_level & BIT(1)) - himax_log_touch_event(x, y, w,loop_i,EN_NoiseFilter,HX_FINGER_ON); - - ts->pre_finger_mask = ts->pre_finger_mask + (1 << loop_i); - } - /* report coordinates */ - else - { -#ifndef HX_PROTOCOL_A - input_mt_slot(ts->input_dev, loop_i); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); -#endif - - if (loop_i == 0 && ts->first_pressed == 1) - { - ts->first_pressed = 2; - I("E1@%d, %d\n", - ts->pre_finger_data[0][0], ts->pre_finger_data[0][1]); - } - if ((ts->debug_log_level & BIT(3)) > 0) - { - himax_log_touch_event_detail(ts,x,y,w,loop_i,Last_EN_NoiseFilter,HX_FINGER_LEAVE,old_finger); - } - } - } -#ifndef HX_PROTOCOL_A - input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); -#endif - input_sync(ts->input_dev); - } - - /* finger leave/release */ - else - { -#if defined(HX_PALM_REPORT) - if(himax_palm_detect(hx_touch_data->hx_coord_buf) == NO_ERR) - { - I(" %s HX_PALM_REPORT KEY power event press\n",__func__); - input_report_key(ts->input_dev, KEY_POWER, 1); - input_sync(ts->input_dev); - msleep(100); - I(" %s HX_PALM_REPORT KEY power event release\n",__func__); - input_report_key(ts->input_dev, KEY_POWER, 0); - input_sync(ts->input_dev); - return; - } -#endif - hx_touch_data->finger_on = 0; - AA_press = 0; -#ifdef HX_PROTOCOL_A - input_mt_sync(ts->input_dev); -#endif - - for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) - { - if (((ts->pre_finger_mask >> loop_i) & 1) == 1) - { -#ifndef HX_PROTOCOL_A - input_mt_slot(ts->input_dev, loop_i); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); -#endif - } - if(ts->pre_finger_mask > 0 && (ts->debug_log_level & BIT(3)) > 0) - { - if (((ts->pre_finger_mask >> loop_i) & 1) == 1) - { - if (ts->useScreenRes) - { - I("status:%X, Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", 0, loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS, - ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter); - } - else - { - I("status:%X, Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",0, loop_i+1, ts->pre_finger_data[loop_i][0],ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter); - } - } - } - } - if (ts->pre_finger_mask > 0) - { - /*for (loop_i = 0; loop_i < ts->nFinger_support && (ts->debug_log_level & BIT(3)) > 0; loop_i++) - { - if (((ts->pre_finger_mask >> loop_i) & 1) == 1) - { - if (ts->useScreenRes) - { - I("status:%X, Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", 0, loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS, - ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter); - } - else - { - I("status:%X, Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",0, loop_i+1, ts->pre_finger_data[loop_i][0],ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter); - } - } - }*/ - ts->pre_finger_mask = 0; - } - - if (ts->first_pressed == 1) - { - ts->first_pressed = 2; - I("E1@%d, %d\n",ts->pre_finger_data[0][0], ts->pre_finger_data[0][1]); - } - - if (ts->debug_log_level & BIT(1)) - himax_log_touch_event(x, y, w,loop_i,EN_NoiseFilter,HX_FINGER_LEAVE); - - input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); - input_sync(ts->input_dev); - } - Last_EN_NoiseFilter = EN_NoiseFilter; - - //I("%s:End\n",__func__); + /* I("Now Status is %d\n", result); */ + return result; } -static void himax_report_all_leave(struct himax_ts_data *ts) +static int himax_touch_get(struct himax_ts_data *ts, uint8_t *buf, int ts_path, int ts_status) +{ + if (g_ts_dbg != 0) + I("%s: Entering, ts_status=%d! \n", __func__, ts_status); + + switch (ts_path) { + /*normal*/ + case HX_REPORT_COORD: + if ((HX_HW_RESET_ACTIVATE) +#ifdef HX_ESD_RECOVERY + || (HX_ESD_RESET_ACTIVATE) +#endif + ) { + if (!g_core_fp.fp_read_event_stack(buf, 128)) { + E("%s: can't read data from chip!\n", __func__); + ts_status = HX_TS_GET_DATA_FAIL; + goto END_FUNCTION; + } + break; + } else { + if (!g_core_fp.fp_read_event_stack(buf, hx_touch_data->touch_info_size)) { + E("%s: can't read data from chip!\n", __func__); + ts_status = HX_TS_GET_DATA_FAIL; + goto END_FUNCTION; + } + break; + } +#if defined(HX_SMART_WAKEUP) + + /*SMWP*/ + case HX_REPORT_SMWP_EVENT: + g_core_fp.fp_burst_enable(0); + + if (!g_core_fp.fp_read_event_stack(buf, hx_touch_data->event_size)) { + E("%s: can't read data from chip!\n", __func__); + ts_status = HX_TS_GET_DATA_FAIL; + goto END_FUNCTION; + } + break; +#endif + case HX_REPORT_COORD_RAWDATA: + if (!g_core_fp.fp_read_event_stack(buf, 128)) { + E("%s: can't read data from chip!\n", __func__); + ts_status = HX_TS_GET_DATA_FAIL; + goto END_FUNCTION; + } + break; + default: + break; + } + +END_FUNCTION: + return ts_status; +} + +/* start error_control*/ +static int himax_checksum_cal(struct himax_ts_data *ts, uint8_t *buf, int ts_path, int ts_status) +{ + uint16_t check_sum_cal = 0; + int32_t i = 0; + int length = 0; + int zero_cnt = 0; + int ret_val = ts_status; + + if (g_ts_dbg != 0) + I("%s: Entering, ts_status=%d! \n", __func__, ts_status); + + /* Normal */ + switch (ts_path) { + case HX_REPORT_COORD: + length = hx_touch_data->touch_info_size; + break; +#if defined(HX_SMART_WAKEUP) +/* SMWP */ + case HX_REPORT_SMWP_EVENT: + length = (GEST_PTLG_ID_LEN + GEST_PTLG_HDR_LEN); + break; +#endif + case HX_REPORT_COORD_RAWDATA: + length = hx_touch_data->touch_info_size; + break; + default: + I("%s, Neither Normal Nor SMWP error!\n", __func__); + ret_val = HX_PATH_FAIL; + goto END_FUNCTION; + } + + for (i = 0; i < length; i++) { + check_sum_cal += buf[i]; + if (buf[i] == 0x00) + zero_cnt++; + } + + if (check_sum_cal % 0x100 != 0) { + I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n", check_sum_cal); + ret_val = HX_CHKSUM_FAIL; + } else if (zero_cnt == length) { + I("[HIMAX TP MSG] All Zero event\n"); + ret_val = HX_CHKSUM_FAIL; + } + +END_FUNCTION: + if (g_ts_dbg != 0) + I("%s: END, ret_val=%d! \n", __func__, ret_val); + return ret_val; +} + +#ifdef HX_ESD_RECOVERY +#ifdef HX_ZERO_FLASH +void hx_update_dirly_0f(void) +{ + I("It will update fw after esd event in zero flash mode!\n"); + g_core_fp.fp_0f_operation_dirly(); +} +#endif +static int himax_ts_event_check(struct himax_ts_data *ts, uint8_t *buf, int ts_path, int ts_status) +{ + int hx_EB_event = 0; + int hx_EC_event = 0; + int hx_ED_event = 0; + int hx_esd_event = 0; + int hx_zero_event = 0; + int shaking_ret = 0; + + int32_t loop_i = 0; + int length = 0; + int ret_val = ts_status; + + if (g_ts_dbg != 0) + I("%s: Entering, ts_status=%d! \n", __func__, ts_status); + + /* Normal */ + switch (ts_path) { + case HX_REPORT_COORD: + length = hx_touch_data->touch_info_size; + break; +#if defined(HX_SMART_WAKEUP) +/* SMWP */ + case HX_REPORT_SMWP_EVENT: + length = (GEST_PTLG_ID_LEN + GEST_PTLG_HDR_LEN); + break; +#endif + case HX_REPORT_COORD_RAWDATA: + length = hx_touch_data->touch_info_size; + break; + default: + I("%s, Neither Normal Nor SMWP error!\n", __func__); + ret_val = HX_PATH_FAIL; + goto END_FUNCTION; + } + + if (g_ts_dbg != 0) + I("Now Path=%d, Now status=%d, length=%d\n", ts_path, ts_status, length); + + for (loop_i = 0; loop_i < length; loop_i++) { + if (ts_path == HX_REPORT_COORD || ts_path == HX_REPORT_COORD_RAWDATA) { + /* case 1 ESD recovery flow */ + if (buf[loop_i] == 0xEB) { + hx_EB_event++; + } else if (buf[loop_i] == 0xEC) { + hx_EC_event++; + } else if (buf[loop_i] == 0xED) { + hx_ED_event++; + } else if (buf[loop_i] == 0x00) { /* case 2 ESD recovery flow-Disable */ + hx_zero_event++; + } else { + hx_EB_event = 0; + hx_EC_event = 0; + hx_ED_event = 0; + hx_zero_event = 0; + g_zero_event_count = 0; + } + } + } + + if (hx_EB_event == length) { + hx_esd_event = length; + hx_EB_event_flag++; + I("[HIMAX TP MSG]: ESD event checked - ALL 0xEB.\n"); + } else if (hx_EC_event == length) { + hx_esd_event = length; + hx_EC_event_flag++; + I("[HIMAX TP MSG]: ESD event checked - ALL 0xEC.\n"); + } else if (hx_ED_event == length) { + hx_esd_event = length; + hx_ED_event_flag++; + I("[HIMAX TP MSG]: ESD event checked - ALL 0xED.\n"); + } +#ifdef HX_ZERO_FLASH + else if (hx_zero_event == length) { + /*check zero flash status*/ + if (g_core_fp.fp_0f_esd_check() < 0) { + g_zero_event_count = 6; + I("[HIMAX TP MSG]: ESD event checked - ALL Zero in ZF.\n"); + } else { + I("[HIMAX TP MSG]: Status check pass in ZF.\n"); + } + } +#endif + else { + hx_esd_event = 0; + } + + if ((hx_esd_event == length || hx_zero_event == length) + && (HX_HW_RESET_ACTIVATE == 0) + && (HX_ESD_RESET_ACTIVATE == 0) + && (hx_touch_data->diag_cmd == 0) + && (ts->in_self_test == 0)) { + shaking_ret = g_core_fp.fp_ic_esd_recovery(hx_esd_event, hx_zero_event, length); + + if (shaking_ret == HX_ESD_EVENT) { + himax_esd_hw_reset(); + ret_val = HX_ESD_EVENT; + } else if (shaking_ret == HX_ZERO_EVENT_COUNT) { + ret_val = HX_ZERO_EVENT_COUNT; + } else { + I("I2C running. Nothing to be done!\n"); + ret_val = HX_IC_RUNNING; + } + } else if (HX_ESD_RESET_ACTIVATE) { /* drop 1st interrupts after chip reset */ + HX_ESD_RESET_ACTIVATE = 0; + I("[HX_ESD_RESET_ACTIVATE]:%s: Back from reset, ready to serve.\n", __func__); + ret_val = HX_ESD_REC_OK; + } + +END_FUNCTION: + if (g_ts_dbg != 0) + I("%s: END, ret_val=%d! \n", __func__, ret_val); + + return ret_val; +} +#endif + +static int himax_err_ctrl(struct himax_ts_data *ts, uint8_t *buf, int ts_path, int ts_status) +{ +#ifdef HX_RST_PIN_FUNC + if (HX_HW_RESET_ACTIVATE) { + /* drop 1st interrupts after chip reset */ + HX_HW_RESET_ACTIVATE = 0; + I("[HX_HW_RESET_ACTIVATE]:%s: Back from reset, ready to serve.\n", __func__); + ts_status = HX_RST_OK; + goto END_FUNCTION; + } +#endif + + ts_status = himax_checksum_cal(ts, buf, ts_path, ts_status); + if (ts_status == HX_CHKSUM_FAIL) + goto CHK_FAIL; + goto END_FUNCTION; + +CHK_FAIL: +#ifdef HX_ESD_RECOVERY + ts_status = himax_ts_event_check(ts, buf, ts_path, ts_status); +#endif + + +END_FUNCTION: + if (g_ts_dbg != 0) + I("%s: END, ts_status=%d! \n", __func__, ts_status); + return ts_status; +} +/* end error_control*/ + +/* start distribute_data*/ +static int himax_distribute_touch_data(uint8_t *buf, int ts_path, int ts_status) +{ + uint8_t hx_state_info_pos = hx_touch_data->touch_info_size - 3; + + if (g_ts_dbg != 0) + I("%s: Entering, ts_status=%d! \n", __func__, ts_status); + + if (ts_path == HX_REPORT_COORD) { + memcpy(hx_touch_data->hx_coord_buf, &buf[0], hx_touch_data->touch_info_size); + + if (buf[hx_state_info_pos] != 0xFF && buf[hx_state_info_pos + 1] != 0xFF) { + memcpy(hx_touch_data->hx_state_info, &buf[hx_state_info_pos], 2); + } else { + memset(hx_touch_data->hx_state_info, 0x00, sizeof(hx_touch_data->hx_state_info)); + } + + if ((HX_HW_RESET_ACTIVATE) +#ifdef HX_ESD_RECOVERY + || (HX_ESD_RESET_ACTIVATE) +#endif + ) { + memcpy(hx_touch_data->hx_rawdata_buf, &buf[hx_touch_data->touch_info_size], hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); + } + } else if (ts_path == HX_REPORT_COORD_RAWDATA) { + memcpy(hx_touch_data->hx_coord_buf, &buf[0], hx_touch_data->touch_info_size); + + if (buf[hx_state_info_pos] != 0xFF && buf[hx_state_info_pos + 1] != 0xFF) { + memcpy(hx_touch_data->hx_state_info, &buf[hx_state_info_pos], 2); + } else { + memset(hx_touch_data->hx_state_info, 0x00, sizeof(hx_touch_data->hx_state_info)); + } + + memcpy(hx_touch_data->hx_rawdata_buf, &buf[hx_touch_data->touch_info_size], hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); +#if defined(HX_SMART_WAKEUP) + } else if (ts_path == HX_REPORT_SMWP_EVENT) { + memcpy(hx_touch_data->hx_event_buf, buf, hx_touch_data->event_size); +#endif + } else { + E("%s, Fail Path!\n", __func__); + ts_status = HX_PATH_FAIL; + } + + if (g_ts_dbg != 0) + I("%s: End, ts_status=%d! \n", __func__, ts_status); + return ts_status; +} +/* end assign_data*/ + +/* start parse_report_data*/ +int himax_parse_report_points(struct himax_ts_data *ts, int ts_path, int ts_status) +{ + int x = 0; + int y = 0; + int w = 0; + int base = 0; + int32_t loop_i = 0; + + if (g_ts_dbg != 0) + I("%s: start! \n", __func__); + + + ts->old_finger = ts->pre_finger_mask; + ts->pre_finger_mask = 0; + hx_touch_data->finger_num = hx_touch_data->hx_coord_buf[ts->coordInfoSize - 4] & 0x0F; + hx_touch_data->finger_on = 1; + AA_press = 1; + + g_target_report_data->finger_num = hx_touch_data->finger_num; + g_target_report_data->finger_on = hx_touch_data->finger_on; + + if (g_ts_dbg != 0) + I("%s:finger_num = 0x%2X, finger_on = %d \n", __func__, g_target_report_data->finger_num, g_target_report_data->finger_on); + + for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) { + base = loop_i * 4; + x = hx_touch_data->hx_coord_buf[base] << 8 | hx_touch_data->hx_coord_buf[base + 1]; + y = (hx_touch_data->hx_coord_buf[base + 2] << 8 | hx_touch_data->hx_coord_buf[base + 3]); + w = hx_touch_data->hx_coord_buf[(ts->nFinger_support * 4) + loop_i]; + + if (g_ts_dbg != 0) + D("%s: now parsing[%d]:x=%d, y=%d, w=%d\n", __func__, loop_i, x, y, w); + + if (x >= 0 && x <= ts->pdata->abs_x_max && y >= 0 && y <= ts->pdata->abs_y_max) { + hx_touch_data->finger_num--; + + g_target_report_data->x[loop_i] = x; + g_target_report_data->y[loop_i] = y; + g_target_report_data->w[loop_i] = w; + g_target_report_data->finger_id[loop_i] = 1; + + /* I("%s: g_target_report_data->x[loop_i]=%d, g_target_report_data->y[loop_i]=%d, g_target_report_data->w[loop_i]=%d", */ + /* __func__, g_target_report_data->x[loop_i], g_target_report_data->y[loop_i], g_target_report_data->w[loop_i]); */ + + + if (!ts->first_pressed) { + ts->first_pressed = 1; + I("S1@%d, %d\n", x, y); + } + + ts->pre_finger_data[loop_i][0] = x; + ts->pre_finger_data[loop_i][1] = y; + + ts->pre_finger_mask = ts->pre_finger_mask + (1 << loop_i); + } else {/* report coordinates */ + g_target_report_data->x[loop_i] = x; + g_target_report_data->y[loop_i] = y; + g_target_report_data->w[loop_i] = w; + g_target_report_data->finger_id[loop_i] = 0; + + if (loop_i == 0 && ts->first_pressed == 1) { + ts->first_pressed = 2; + I("E1@%d, %d\n", ts->pre_finger_data[0][0], ts->pre_finger_data[0][1]); + } + } + } + + if (g_ts_dbg != 0) { + for (loop_i = 0; loop_i < 10; loop_i++) { + D("DBG X=%d Y=%d ID=%d\n", g_target_report_data->x[loop_i], g_target_report_data->y[loop_i], g_target_report_data->finger_id[loop_i]); + } + D("DBG finger number %d\n", g_target_report_data->finger_num); + } + + if (g_ts_dbg != 0) + I("%s: end! \n", __func__); + return ts_status; +} + +static int himax_parse_report_data(struct himax_ts_data *ts, int ts_path, int ts_status) +{ + + if (g_ts_dbg != 0) + I("%s: start now_status=%d! \n", __func__, ts_status); + + + EN_NoiseFilter = (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT + 2] >> 3); + /* I("EN_NoiseFilter=%d\n", EN_NoiseFilter); */ + EN_NoiseFilter = EN_NoiseFilter & 0x01; + /* I("EN_NoiseFilter2=%d\n", EN_NoiseFilter); */ +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) + tpd_key = (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT + 2] >> 4); + + /* All (VK+AA)leave */ + if (tpd_key == 0x0F) { + tpd_key = 0x00; + } +#endif + p_point_num = ts->hx_point_num; + + switch (ts_path) { + case HX_REPORT_COORD: + ts_status = himax_parse_report_points(ts, ts_path, ts_status); + break; + case HX_REPORT_COORD_RAWDATA: + /* touch monitor rawdata */ + if (debug_data != NULL) { + if (debug_data->fp_set_diag_cmd(ic_data, hx_touch_data)) + I("%s: coordinate dump fail and bypass with checksum err\n", __func__); + } else { + E("%s,There is no init set_diag_cmd\n", __func__); + } + ts_status = himax_parse_report_points(ts, ts_path, ts_status); + break; +#ifdef HX_SMART_WAKEUP + case HX_REPORT_SMWP_EVENT: + himax_wake_event_parse(ts, ts_status); + break; +#endif + default: + E("%s:Fail Path!\n", __func__); + ts_status = HX_PATH_FAIL; + break; + } + if (g_ts_dbg != 0) + I("%s: end now_status=%d! \n", __func__, ts_status); + return ts_status; +} + +/* end parse_report_data*/ + +static void himax_report_all_leave_event(struct himax_ts_data *ts) { int loop_i = 0; - for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) - { + for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) { #ifndef HX_PROTOCOL_A - input_mt_slot(ts->input_dev, loop_i); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); + input_mt_slot(ts->input_dev, loop_i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); #endif - } - input_report_key(ts->input_dev, BTN_TOUCH, 0); - input_sync(ts->input_dev); + } + input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_sync(ts->input_dev); } -int himax_touch_get(struct himax_ts_data *ts,uint8_t *buf,int ts_status) +/* start report_data */ +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) +static void himax_key_report_operation(int tp_key_index, struct himax_ts_data *ts) { - int ret = 0; + uint16_t x_position = 0, y_position = 0; - switch(ts_status) - { - /*normal*/ - case 1: -#ifdef HX_TP_PROC_DIAG - hx_touch_data->diag_cmd = getDiagCommand(); + if (g_ts_dbg != 0) + I("%s: Entering \n", __func__); - if((hx_touch_data->diag_cmd) - || (HX_HW_RESET_ACTIVATE) -#ifdef HX_ESD_RECOVERY - || (HX_ESD_RESET_ACTIVATE) -#endif - ) - { - ret = himax_read_event_stack(ts->client, buf, 128); - } - else - { - ret = himax_read_event_stack(ts->client, buf, hx_touch_data->touch_info_size); - } + if (tp_key_index != 0x00) { + I("virtual key index =%x\n", tp_key_index); - if (!ret) + if (tp_key_index == 0x01) { + vk_press = 1; + I("back key pressed\n"); + + if (ts->pdata->virtual_key) { + if (ts->button[0].index) { + x_position = (ts->button[0].x_range_min + ts->button[0].x_range_max) / 2; + y_position = (ts->button[0].y_range_min + ts->button[0].y_range_max) / 2; + } + +#ifdef HX_PROTOCOL_A + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y_position); + input_mt_sync(ts->input_dev); #else - if(!himax_read_event_stack(ts->client, buf, hx_touch_data->touch_info_size)) + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y_position); #endif - { - E("%s: can't read data from chip!\n", __func__); - goto err_workqueue_out; - } - break; -#if defined(HX_SMART_WAKEUP) - /*SMWP*/ - case 2: - himax_burst_enable(ts->client, 0); - if(!himax_read_event_stack(ts->client,buf,hx_touch_data->event_size)) - { - E("%s: can't read data from chip!\n", __func__); - goto err_workqueue_out; - } - break; -#endif - default: - break; - } - return NO_ERR; + } else { + input_report_key(ts->input_dev, KEY_BACK, 1); + } + } else if (tp_key_index == 0x02) { + vk_press = 1; + I("home key pressed\n"); -err_workqueue_out: - return I2C_FAIL; + if (ts->pdata->virtual_key) { + if (ts->button[1].index) { + x_position = (ts->button[1].x_range_min + ts->button[1].x_range_max) / 2; + y_position = (ts->button[1].y_range_min + ts->button[1].y_range_max) / 2; + } -} - -int himax_checksum_cal(struct himax_ts_data *ts,uint8_t *buf,int ts_status) -{ -#if defined(HX_ESD_RECOVERY) - int hx_EB_event = 0; - int hx_EC_event = 0; - int hx_ED_event = 0; - int hx_esd_event = 0; - int hx_zero_event = 0; - int shaking_ret = 0; -#endif - uint16_t check_sum_cal = 0; - int32_t loop_i = 0; - int length = 0; - - /* Normal */ - if(ts_status == HX_REPORT_COORD) - length = hx_touch_data->touch_info_size; -#if defined(HX_SMART_WAKEUP) - /* SMWP */ - else if(ts_status == HX_REPORT_SMWP_EVENT) - length = (GEST_PTLG_ID_LEN+GEST_PTLG_HDR_LEN); -#endif - else - { - I("%s, Neither Normal Nor SMWP error!\n",__func__); - } - //I("Now status=%d,length=%d\n",ts_status,length); - for (loop_i = 0; loop_i < length; loop_i++) - { - check_sum_cal+=buf[loop_i]; - - /*if (ts->debug_log_level & BIT(0)) - { - I("P %d = 0x%2.2X ", loop_i, hx_touch_data->hx_coord_buf[loop_i]); - if (loop_i % 8 == 7) - I("\n"); - }*/ - -#ifdef HX_ESD_RECOVERY - if(ts_status == HX_REPORT_COORD) - { - /* case 1 ESD recovery flow */ - if(buf[loop_i] == 0xEB) - hx_EB_event++; - else if(buf[loop_i] == 0xEC) - hx_EC_event++; - else if(buf[loop_i] == 0xED) - hx_ED_event++; - /* case 2 ESD recovery flow-Disable */ - else if(buf[loop_i] == 0x00) - hx_zero_event++; - else - { - hx_EB_event = 0; - hx_EC_event = 0; - hx_ED_event = 0; - hx_zero_event = 0; - g_zero_event_count = 0; - } - - if(hx_EB_event == length) - { - hx_esd_event = length; - hx_EB_event_flag ++; - I("[HIMAX TP MSG]: ESD event checked - ALL 0xEB.\n"); - } - else if(hx_EC_event == length) - { - hx_esd_event = length; - hx_EC_event_flag ++; - I("[HIMAX TP MSG]: ESD event checked - ALL 0xEC.\n"); - } - else if(hx_ED_event == length) - { - hx_esd_event = length; - hx_ED_event_flag ++; - I("[HIMAX TP MSG]: ESD event checked - ALL 0xED.\n"); - } - else - { - hx_esd_event = 0; - } - } -#endif - } - - if(ts_status == HX_REPORT_COORD) - { -#ifdef HX_ESD_RECOVERY - if ((hx_esd_event == length || hx_zero_event == length) - && (HX_HW_RESET_ACTIVATE == 0) - && (HX_ESD_RESET_ACTIVATE == 0) -#if defined(HX_TP_PROC_DIAG) - && (hx_touch_data->diag_cmd == 0) -#endif -#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) - && (g_self_test_entered == 0) -#endif - ) - { - shaking_ret = himax_ic_esd_recovery(hx_esd_event,hx_zero_event,length); - if(shaking_ret == CHECKSUM_FAIL) - { - himax_esd_hw_reset(); - goto checksum_fail; - } - else if(shaking_ret == ERR_WORK_OUT) - goto err_workqueue_out; - else - { - //I("I2C running. Nothing to be done!\n"); - goto workqueue_out; - } - } - else if (HX_ESD_RESET_ACTIVATE) - { -#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) -#ifdef HX_RESUME_SEND_CMD - himax_rst_cmd_recovery_func(ts->suspended); -#endif -#endif - /* drop 1st interrupts after chip reset */ - HX_ESD_RESET_ACTIVATE = 0; - I("[HX_ESD_RESET_ACTIVATE]:%s: Back from reset, ready to serve.\n", __func__); - goto checksum_fail; - } - - else if (HX_HW_RESET_ACTIVATE) +#ifdef HX_PROTOCOL_A + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y_position); + input_mt_sync(ts->input_dev); #else - if (HX_HW_RESET_ACTIVATE) + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y_position); #endif - { -#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) -#ifdef HX_RESUME_SEND_CMD - himax_rst_cmd_recovery_func(ts->suspended); -#endif -#endif - /* drop 1st interrupts after chip reset */ - HX_HW_RESET_ACTIVATE = 0; - I("[HX_HW_RESET_ACTIVATE]:%s: Back from reset, ready to serve.\n", __func__); - goto ready_to_serve; - } - } + } else { + input_report_key(ts->input_dev, KEY_HOME, 1); + } + } else if (tp_key_index == 0x04) { + vk_press = 1; + I("APP_switch key pressed\n"); - if ((check_sum_cal % 0x100 != 0) ) - { - I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n", check_sum_cal); - goto checksum_fail; - } + if (ts->pdata->virtual_key) { + if (ts->button[2].index) { + x_position = (ts->button[2].x_range_min + ts->button[2].x_range_max) / 2; + y_position = (ts->button[2].y_range_min + ts->button[2].y_range_max) / 2; + } - /* I("%s:End\n",__func__); */ - return NO_ERR; - -ready_to_serve: - return READY_TO_SERVE; -checksum_fail: - return CHECKSUM_FAIL; -#ifdef HX_ESD_RECOVERY -err_workqueue_out: - return ERR_WORK_OUT; -workqueue_out: - return WORK_OUT; +#ifdef HX_PROTOCOL_A + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y_position); + input_mt_sync(ts->input_dev); +#else + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y_position); #endif + } else { + input_report_key(ts->input_dev, KEY_APPSELECT, 1); + } + } + input_sync(ts->input_dev); + } else { /*tp_key_index =0x00*/ + I("virtual key released\n"); + vk_press = 0; +#ifndef HX_PROTOCOL_A + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); +#else + input_mt_sync(ts->input_dev); +#endif + input_report_key(ts->input_dev, KEY_BACK, 0); + input_report_key(ts->input_dev, KEY_HOME, 0); + input_report_key(ts->input_dev, KEY_APPSELECT, 0); +#ifndef HX_PROTOCOL_A + input_sync(ts->input_dev); +#endif + } } -int himax_ts_work_status(struct himax_ts_data *ts) +void himax_finger_report_key(struct himax_ts_data *ts) { - /* 1: normal, 2:SMWP */ - int result = HX_REPORT_COORD; - uint8_t diag_cmd = 0; - -#ifdef HX_TP_PROC_DIAG - diag_cmd = getDiagCommand(); + if (ts->hx_point_num != 0) { + /*Touch KEY*/ + if ((tpd_key_old != 0x00) && (tpd_key == 0x00)) { + /* temp_x[0] = 0xFFFF; + temp_y[0] = 0xFFFF; + temp_x[1] = 0xFFFF; + temp_y[1] = 0xFFFF; */ + hx_touch_data->finger_on = 0; +#ifdef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); #endif + himax_key_report_operation(tpd_key, ts); + } -#ifdef HX_SMART_WAKEUP - if (atomic_read(&ts->suspend_mode)&&(!FAKE_POWER_KEY_SEND)&&(ts->SMWP_enable)&&(!diag_cmd)) - { - result = HX_REPORT_SMWP_EVENT; - } +#ifndef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); #endif - /* I("Now Status is %d\n",result); */ - return result; + input_sync(ts->input_dev); + } } -void himax_assign_touch_data(uint8_t *buf,int ts_status) +void himax_finger_leave_key(struct himax_ts_data *ts) { - uint8_t hx_state_info_pos = hx_touch_data->touch_info_size - 3; - - if(ts_status == HX_REPORT_COORD) - { - memcpy(hx_touch_data->hx_coord_buf,&buf[0],hx_touch_data->touch_info_size); - if(buf[hx_state_info_pos] != 0xFF && buf[hx_state_info_pos + 1] != 0xFF ) - memcpy(hx_touch_data->hx_state_info,&buf[hx_state_info_pos],2); - else - memset(hx_touch_data->hx_state_info, 0x00, sizeof(hx_touch_data->hx_state_info)); - } -#if defined(HX_SMART_WAKEUP) - else - memcpy(hx_touch_data->hx_event_buf,buf,hx_touch_data->event_size); + if (tpd_key != 0x00) { + hx_touch_data->finger_on = 1; +#ifdef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); #endif - -#ifdef HX_TP_PROC_DIAG - if((hx_touch_data->diag_cmd) - || (HX_HW_RESET_ACTIVATE) -#ifdef HX_ESD_RECOVERY - || (HX_ESD_RESET_ACTIVATE) -#endif - ) - { - memcpy(hx_touch_data->hx_rawdata_buf,&buf[hx_touch_data->touch_info_size],hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); - } + himax_key_report_operation(tpd_key, ts); + } else if ((tpd_key_old != 0x00) && (tpd_key == 0x00)) { + hx_touch_data->finger_on = 0; +#ifdef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); #endif + himax_key_report_operation(tpd_key, ts); + } +#ifndef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); +#endif + input_sync(ts->input_dev); } -void himax_coord_report(struct himax_ts_data *ts) +static void himax_report_key(struct himax_ts_data *ts) { + if (ts->hx_point_num != 0) { /* Touch KEY */ + himax_finger_report_key(ts); + } else { /* Key */ + himax_finger_leave_key(ts); + } -#if defined(HX_TP_PROC_DIAG) - //touch monitor raw data fetch - if(himax_set_diag_cmd(ic_data,hx_touch_data)) - I("%s: coordinate dump fail and bypass with checksum err\n",__func__); + tpd_key_old = tpd_key; + Last_EN_NoiseFilter = EN_NoiseFilter; +} #endif - EN_NoiseFilter = (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT+2]>>3); - //I("EN_NoiseFilter=%d\n",EN_NoiseFilter); - EN_NoiseFilter = EN_NoiseFilter & 0x01; - //I("EN_NoiseFilter2=%d\n",EN_NoiseFilter); + +/* start report_point*/ +static void himax_finger_report(struct himax_ts_data *ts) +{ + int i = 0; + bool valid = false; + if (g_ts_dbg != 0) { + I("%s:start\n", __func__); + I("hx_touch_data->finger_num=%d\n", hx_touch_data->finger_num); + } + for (i = 0; i < ts->nFinger_support; i++) { + if (g_target_report_data->x[i] >= 0 && g_target_report_data->x[i] <= ts->pdata->abs_x_max && g_target_report_data->y[i] >= 0 && g_target_report_data->y[i] <= ts->pdata->abs_y_max) + valid = true; + else + valid = false; + if (g_ts_dbg != 0) + I("valid=%d\n", valid); + if (valid) { + if (g_ts_dbg != 0) + I("g_target_report_data->x[i]=%d, g_target_report_data->y[i]=%d, g_target_report_data->w[i]=%d\n", g_target_report_data->x[i], g_target_report_data->y[i], g_target_report_data->w[i]); +#ifndef HX_PROTOCOL_A + input_mt_slot(ts->input_dev, i); +#endif + input_report_key(ts->input_dev, BTN_TOUCH, g_target_report_data->finger_on); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, g_target_report_data->w[i]); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i); +#ifndef HX_PROTOCOL_A + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, g_target_report_data->w[i]); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, g_target_report_data->w[i]); +#endif + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, g_target_report_data->x[i]); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, g_target_report_data->y[i]); +#ifndef HX_PROTOCOL_A + ts->last_slot = i; + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1); +#else + input_mt_sync(ts->input_dev); +#endif + + } else { + input_mt_slot(ts->input_dev, i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); + } + } + + input_report_key(ts->input_dev, BTN_TOUCH, g_target_report_data->finger_on); + input_sync(ts->input_dev); + + if (g_ts_dbg != 0) + I("%s:end\n", __func__); +} + +static void himax_finger_leave(struct himax_ts_data *ts) +{ + int32_t loop_i = 0; + + if (g_ts_dbg != 0) + I("%s: start! \n", __func__); +#if defined(HX_PALM_REPORT) + if (himax_palm_detect(hx_touch_data->hx_coord_buf) == PALM_REPORT) { + I(" %s HX_PALM_REPORT KEY power event press\n", __func__); + input_report_key(ts->input_dev, KEY_POWER, 1); + input_sync(ts->input_dev); + msleep(100); + + I(" %s HX_PALM_REPORT KEY power event release\n", __func__); + input_report_key(ts->input_dev, KEY_POWER, 0); + input_sync(ts->input_dev); + return; + } +#endif + + hx_touch_data->finger_on = 0; + AA_press = 0; + +#ifdef HX_PROTOCOL_A + input_mt_sync(ts->input_dev); +#endif + + for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) { + if (((ts->pre_finger_mask >> loop_i) & 1) == 1) { + input_mt_slot(ts->input_dev, loop_i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); + } + } + + if (ts->pre_finger_mask > 0) { + ts->pre_finger_mask = 0; + } + + if (ts->first_pressed == 1) { + ts->first_pressed = 2; + I("E1@%d, %d\n", ts->pre_finger_data[0][0], ts->pre_finger_data[0][1]); + } + + /* if (ts->debug_log_level & BIT(1)) */ + /* himax_log_touch_event(x, y, w, loop_i, EN_NoiseFilter, HX_FINGER_LEAVE); */ + + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); + input_sync(ts->input_dev); + + if (g_ts_dbg != 0) + I("%s: end! \n", __func__); + return; +} + +static void himax_report_points(struct himax_ts_data *ts) +{ + if (g_ts_dbg != 0) + I("%s: start! \n", __func__); + + if (ts->hx_point_num != 0) { + himax_finger_report(ts); + } else { + himax_finger_leave(ts); + } + + Last_EN_NoiseFilter = EN_NoiseFilter; + + if (g_ts_dbg != 0) + I("%s: end! \n", __func__); +} +/* end report_points*/ + +int himax_report_data(struct himax_ts_data *ts, int ts_path, int ts_status) +{ + if (g_ts_dbg != 0) + I("%s: Entering, ts_status=%d! \n", __func__, ts_status); + + if (ts_path == HX_REPORT_COORD || ts_path == HX_REPORT_COORD_RAWDATA) { + if (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT] == 0xff) { + ts->hx_point_num = 0; + } else { + ts->hx_point_num = hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f; + } + + /* Touch Point information */ + himax_report_points(ts); #if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) - tpd_key = (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT+2]>>4); - /* All (VK+AA)leave */ - if (tpd_key == 0x0F) - { - tpd_key = 0x00; - } - //I("[DEBUG] tpd_key: %x\r\n", tpd_key); -#else - tpd_key = 0x00; + /*report key(question mark)*/ + if (tpd_key && tpd_key_old) { + himax_report_key(ts); + } #endif - - p_point_num = hx_point_num; - - if (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT] == 0xff) - hx_point_num = 0; - else - hx_point_num= hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f; - - /* Touch Point information */ - if(!tpd_key && !tpd_key_old) - himax_report_points(ts); -#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) - else - himax_report_key(ts); +#ifdef HX_SMART_WAKEUP + } else if (ts_path == HX_REPORT_SMWP_EVENT) { + wake_lock_timeout(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT); + himax_wake_event_report(); #endif - /* I("%s:END\n",__func__); */ + } else { + E("%s:Fail Path!\n", __func__); + ts_status = HX_PATH_FAIL; + } + if (g_ts_dbg != 0) + I("%s: END, ts_status=%d! \n", __func__, ts_status); + return ts_status; +} +/* end report_data */ + +static int himax_ts_operation(struct himax_ts_data *ts, int ts_path, int ts_status) +{ + uint8_t hw_reset_check[2]; + uint8_t buf[128]; + + memset(buf, 0x00, sizeof(buf)); + memset(hw_reset_check, 0x00, sizeof(hw_reset_check)); + + ts_status = himax_touch_get(ts, buf, ts_path, ts_status); + if (ts_status == HX_TS_GET_DATA_FAIL) + goto END_FUNCTION; + + ts_status = himax_err_ctrl(ts, buf, ts_path, ts_status); + if (ts_status == HX_REPORT_DATA || ts_status == HX_TS_NORMAL_END) { + ts_status = himax_distribute_touch_data(buf, ts_path, ts_status); + ts_status = himax_parse_report_data(ts, ts_path, ts_status); + } else { + goto END_FUNCTION; + } + ts_status = himax_report_data(ts, ts_path, ts_status); + + +END_FUNCTION: + return ts_status; } void himax_ts_work(struct himax_ts_data *ts) { - uint8_t hw_reset_check[2]; - uint8_t buf[128]; - int check_sum_cal = 0; - //int loop_i = 0; - int ts_status = 0; -#ifdef HX_CHIP_STATUS_MONITOR - int j=0; -#endif + + int ts_status = HX_TS_NORMAL_END; + int ts_path = 0; + + if (debug_data != NULL) + debug_data->fp_ts_dbg_func(ts, HX_FINGER_ON); #if defined(HX_USB_DETECT_GLOBAL) - himax_cable_detect_func(false); + himax_cable_detect_func(false); #endif -#if defined(HX_CHIP_STATUS_MONITOR) - g_chip_monitor_data->HX_CHIP_POLLING_COUNT=0; - if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking - { - for(j=0; j<100; j++) - { - if(g_chip_monitor_data->HX_ON_HAND_SHAKING==0)//chip on hand shaking end - { - I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,j); - break; - } - else - msleep(1); - } - if(j==100) - { - E("%s:HX_ON_HAND_SHAKING timeout reject interrupt\n",__func__); - return; - } - } -#endif + ts_path = himax_ts_work_status(ts); + switch (ts_path) { + case HX_REPORT_COORD: + ts_status = himax_ts_operation(ts, ts_path, ts_status); + break; + case HX_REPORT_SMWP_EVENT: + ts_status = himax_ts_operation(ts, ts_path, ts_status); + break; + case HX_REPORT_COORD_RAWDATA: + ts_status = himax_ts_operation(ts, ts_path, ts_status); + break; + default: + E("%s:Path Fault! value=%d\n", __func__, ts_path); + goto END_FUNCTION; + break; + } - ts_status = himax_ts_work_status(ts); - if(ts_status > HX_REPORT_SMWP_EVENT || ts_status < HX_REPORT_COORD) - goto neither_normal_nor_smwp; - - memset(buf, 0x00, sizeof(buf)); - memset(hw_reset_check, 0x00, sizeof(hw_reset_check)); - - //I("New Method for ts_work\n"); - - if(himax_touch_get(ts,buf,ts_status)) - goto err_workqueue_out; - - if (ts->debug_log_level & BIT(0)) - { - - himax_log_touch_data(buf,hx_touch_data); - - } - - check_sum_cal = himax_checksum_cal(ts,buf,ts_status); - if (check_sum_cal == CHECKSUM_FAIL) - goto checksum_fail; - else if (check_sum_cal == READY_TO_SERVE) - goto ready_to_serve; - else if (check_sum_cal == ERR_WORK_OUT) - goto err_workqueue_out; - else if (check_sum_cal == WORK_OUT) - goto workqueue_out; - /* checksum calculate pass and assign data to global touch data*/ - else - himax_assign_touch_data(buf,ts_status); - - if(ts_status == HX_REPORT_COORD) - himax_coord_report(ts); -#if defined(HX_SMART_WAKEUP) - else - { - wake_lock_timeout(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT); - himax_wake_check_func(); - } -#endif - -checksum_fail: -workqueue_out: -ready_to_serve: -neither_normal_nor_smwp: - return; - -err_workqueue_out: - I("%s: Now reset the Touch chip.\n", __func__); + if (ts_status == HX_TS_GET_DATA_FAIL) + goto GET_TOUCH_FAIL; + else + goto END_FUNCTION; +GET_TOUCH_FAIL: + I("%s: Now reset the Touch chip.\n", __func__); #ifdef HX_RST_PIN_FUNC - himax_ic_reset(false,true); + g_core_fp.fp_ic_reset(false, true); #endif +END_FUNCTION: + if (debug_data != NULL) + debug_data->fp_ts_dbg_func(ts, HX_FINGER_LEAVE); - goto workqueue_out; + return; } +/*end ts_work*/ enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer) { - struct himax_ts_data *ts; - - ts = container_of(timer, struct himax_ts_data, timer); - queue_work(ts->himax_wq, &ts->work); - hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL); - return HRTIMER_NORESTART; + struct himax_ts_data *ts; + ts = container_of(timer, struct himax_ts_data, timer); + queue_work(ts->himax_wq, &ts->work); + hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL); + return HRTIMER_NORESTART; } -#if defined( HX_USB_DETECT_CALLBACK) +#if defined(HX_USB_DETECT_CALLBACK) static void himax_cable_tp_status_handler_func(int connect_status) { - struct himax_ts_data *ts; - I("Touch: cable change to %d\n", connect_status); - ts = private_ts; - if (ts->cable_config) - { - if (!atomic_read(&ts->suspend_mode)) - { - if ((!!connect_status) != ts->usb_connected) - { - if (!!connect_status) - { - ts->cable_config[1] = 0x01; - ts->usb_connected = 0x01; - } - else - { - ts->cable_config[1] = 0x00; - ts->usb_connected = 0x00; - } + struct himax_ts_data *ts; + I("Touch: cable change to %d\n", connect_status); + ts = private_ts; - i2c_himax_master_write(ts->client, ts->cable_config, - sizeof(ts->cable_config), DEFAULT_RETRY_CNT); + if (ts->cable_config) { + if (!atomic_read(&ts->suspend_mode)) { + if (connect_status != ts->usb_connected) { + if (connect_status) { + ts->cable_config[1] = 0x01; + ts->usb_connected = 0x01; + } else { + ts->cable_config[1] = 0x00; + ts->usb_connected = 0x00; + } - I("%s: Cable status change: 0x%2.2X\n", __func__, ts->cable_config[1]); - } - else - I("%s: Cable status is the same as previous one, ignore.\n", __func__); - } - else - { - if (connect_status) - ts->usb_connected = 0x01; - else - ts->usb_connected = 0x00; - I("%s: Cable status remembered: 0x%2.2X\n", __func__, ts->usb_connected); - } - } + himax_bus_master_write(ts->cable_config, + sizeof(ts->cable_config), HIMAX_I2C_RETRY_TIMES); + I("%s: Cable status change: 0x%2.2X\n", __func__, ts->cable_config[1]); + } else { + I("%s: Cable status is the same as previous one, ignore.\n", __func__); + } + } else { + if (connect_status) { + ts->usb_connected = 0x01; + } else { + ts->usb_connected = 0x00; + } + + I("%s: Cable status remembered: 0x%2.2X\n", __func__, ts->usb_connected); + } + } } -static struct t_cable_status_notifier himax_cable_status_handler = -{ - .name = "usb_tp_connected", - .func = himax_cable_tp_status_handler_func, +static struct t_cable_status_notifier himax_cable_status_handler = { + .name = "usb_tp_connected", + .func = himax_cable_tp_status_handler_func, }; #endif @@ -1639,90 +2017,58 @@ static struct t_cable_status_notifier himax_cable_status_handler = #ifdef HX_AUTO_UPDATE_FW static void himax_update_register(struct work_struct *work) { - I(" %s in", __func__); -#if defined(HX_CHIP_STATUS_MONITOR) - I("Cancel Chip monitor during auto-updating!\n"); - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; - cancel_delayed_work_sync(&private_ts->himax_chip_monitor); -#endif - if(i_update_FW() == false) - I("NOT Have new FW=NOT UPDATE=\n"); - else - I("Have new FW=UPDATE=\n"); -#ifdef HX_CHIP_STATUS_MONITOR - I("Auto-updating over, now chip monitor working!\n"); - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; - queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); -#endif + I(" %s in\n", __func__); + + if (i_get_FW() != 0) + return ; + + if (g_auto_update_flag == true) { + I("Update FW Directly"); + goto UPDATE_FW; + } + + if (himax_auto_update_check() != 0) { + return ; + } + +UPDATE_FW: + if (i_update_FW() <= 0) { + I("Auto update FW fail!\n"); + } else { + I("It have Updated\n"); + } } #endif + #ifdef CONFIG_FB static void himax_fb_register(struct work_struct *work) { - int ret = 0; - struct himax_ts_data *ts = container_of(work, struct himax_ts_data, - work_att.work); - I(" %s in\n", __func__); + int ret = 0; + struct himax_ts_data *ts = container_of(work, struct himax_ts_data, work_att.work); + I(" %s in\n", __func__); + ts->fb_notif.notifier_call = fb_notifier_callback; + ret = fb_register_client(&ts->fb_notif); - ts->fb_notif.notifier_call = fb_notifier_callback; - ret = fb_register_client(&ts->fb_notif); - if (ret) - E(" Unable to register fb_notifier: %d\n", ret); + if (ret) { + E(" Unable to register fb_notifier: %d\n", ret); + } } #endif -#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) -static void himax_ito_test_work(struct work_struct *work) -{ - I(" %s in\n", __func__); - himax_ito_test(); -} -#endif - -#ifdef HX_TP_PROC_FLASH_DUMP -static void himax_ts_flash_work_func(struct work_struct *work) -{ - himax_ts_flash_func(); -} -#endif - -#ifdef HX_TP_PROC_GUEST_INFO -static void himax_ts_guest_info_work_func(struct work_struct *work) -{ - - himax_read_project_id(); - -} -#endif - -#ifdef HX_TP_PROC_DIAG -static void himax_ts_diag_work_func(struct work_struct *work) -{ - himax_ts_diag_func(); -} -#endif - -static const char* himax_ic_type_to_string(void) { - switch(IC_TYPE) { - case HX_83112A_SERIES_PWON: return "hx83112a"; +static const char *himax_ic_type_to_string (void) { + switch (private_ts->chip_cell_type) { + case CHIP_IS_IN_CELL: return "hx83112a"; default: return "hxxxxxx"; } } -static int himax_fw_updater(struct himax_ts_data *ts, const char *fileName) { +static int himax_fw_updater (struct himax_ts_data *ts, const char *fileName) { const struct firmware *fw = NULL; int fw_type = 0; int result; - himax_int_enable(ts->client->irq, 0); -#ifdef HX_CHIP_STATUS_MONITOR - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; - cancel_delayed_work_sync(&ts->himax_chip_monitor); -#endif + himax_int_enable(0); result = request_firmware(&fw, fileName, ts->dev); if (result < 0) { @@ -1732,11 +2078,11 @@ static int himax_fw_updater(struct himax_ts_data *ts, const char *fileName) { I("%s: FW image: %02X, %02X, %02X, %02X\n", __func__, fw->data[0], fw->data[1], fw->data[2], fw->data[3]); - fw_type = (fw->size)/1024; - I("Now FW size is : %dk\n",fw_type); - switch(fw_type) { + fw_type = (fw->size)/1024; + I("Now FW size is : %dk\n", fw_type); + switch (fw_type) { case 32: - result = fts_ctpm_fw_upgrade_with_sys_fs_32k(ts->client, + result = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_32k( (unsigned char *)fw->data, fw->size, false); if (result == 0) E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); @@ -1744,7 +2090,7 @@ static int himax_fw_updater(struct himax_ts_data *ts, const char *fileName) { I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); break; case 60: - result = fts_ctpm_fw_upgrade_with_sys_fs_60k(ts->client, + result = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_60k( (unsigned char *)fw->data, fw->size, false); if (result == 0) E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); @@ -1752,7 +2098,7 @@ static int himax_fw_updater(struct himax_ts_data *ts, const char *fileName) { I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); break; case 64: - result = fts_ctpm_fw_upgrade_with_sys_fs_64k(ts->client, + result = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_64k( (unsigned char *)fw->data, fw->size, false); if (result == 0) E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); @@ -1760,7 +2106,7 @@ static int himax_fw_updater(struct himax_ts_data *ts, const char *fileName) { I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); break; case 124: - result = fts_ctpm_fw_upgrade_with_sys_fs_124k(ts->client, + result = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_124k( (unsigned char *)fw->data, fw->size, false); if (result == 0) E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); @@ -1768,7 +2114,7 @@ static int himax_fw_updater(struct himax_ts_data *ts, const char *fileName) { I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); break; case 128: - result = fts_ctpm_fw_upgrade_with_sys_fs_128k(ts->client, + result = g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_128k( (unsigned char *)fw->data, fw->size, false); if (result == 0) E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); @@ -1780,24 +2126,17 @@ static int himax_fw_updater(struct himax_ts_data *ts, const char *fileName) { break; } release_firmware(fw); - himax_read_FW_ver(ts->client); - himax_touch_information(ts->client); + g_core_fp.fp_read_FW_ver(); + g_core_fp.fp_touch_information(); #ifdef HX_RST_PIN_FUNC - himax_ic_reset(true,false); + g_core_fp.fp_ic_reset(true, false); #else - himax_sense_on(ts->client,0); + g_core_fp.fp_sense_on(0); #endif - himax_int_enable(ts->client->irq,1); + himax_int_enable(1); -#ifdef HX_CHIP_STATUS_MONITOR - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; - queue_delayed_work(ts->himax_chip_monitor_wq, - &ts->himax_chip_monitor, - g_chip_monitor_data->HX_POLLING_TIMES*HZ); -#endif - return (result <= 0)? -1: 0; + return (result <= 0) ? -1 : 0; } static ssize_t himax_sysfs_poweron_show(struct device *dev, @@ -2025,708 +2364,428 @@ device_destroy: return -ENODEV; } - -int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id) +int himax_chip_common_init(void) { -#ifdef HX_AUTO_UPDATE_FW - bool auto_update_flag = false; -#endif - int ret = 0, err = 0; - struct himax_ts_data *ts; - struct himax_i2c_platform_data *pdata; - int attr_count; - //Check I2C functionality - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - { - E("%s: i2c check functionality error\n", __func__); - err = -ENODEV; - goto err_check_functionality_failed; - } + int ret = 0, err = 0; + struct himax_ts_data *ts = private_ts; + struct himax_i2c_platform_data *pdata; + int attr_count; - ts = kzalloc(sizeof(struct himax_ts_data), GFP_KERNEL); - if (ts == NULL) - { - E("%s: allocate himax_ts_data failed\n", __func__); - err = -ENOMEM; - goto err_alloc_data_failed; - } + I("PDATA START\n"); + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - i2c_set_clientdata(client, ts); - ts->client = client; - ts->dev = &client->dev; - mutex_init(&ts->rw_lock); + if (pdata == NULL) { /*Allocate Platform data space*/ + err = -ENOMEM; + goto err_dt_platform_data_fail; + } - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (pdata == NULL) /*Allocate Platform data space*/ - { - err = -ENOMEM; - goto err_dt_platform_data_fail; - } + I("ic_data START\n"); + ic_data = kzalloc(sizeof(*ic_data), GFP_KERNEL); + if (ic_data == NULL) { /*Allocate IC data space*/ + err = -ENOMEM; + goto err_dt_ic_data_fail; + } - ic_data = kzalloc(sizeof(*ic_data), GFP_KERNEL); - if (ic_data == NULL) /*Allocate IC data space*/ - { - err = -ENOMEM; - goto err_dt_ic_data_fail; - } + /* allocate report data */ + hx_touch_data = kzalloc(sizeof(struct himax_report_data), GFP_KERNEL); + if (hx_touch_data == NULL) { + err = -ENOMEM; + goto err_alloc_touch_data_failed; + } - /* allocate report data */ - hx_touch_data = kzalloc(sizeof(struct himax_report_data),GFP_KERNEL); - if(hx_touch_data == NULL) - { - err = -ENOMEM; - goto err_alloc_touch_data_failed; - } - - if (himax_parse_dt(ts, pdata) < 0) - { - I(" pdata is NULL for DT\n"); - goto err_alloc_dt_pdata_failed; - } + if (himax_parse_dt(ts, pdata) < 0) { + I(" pdata is NULL for DT\n"); + goto err_alloc_dt_pdata_failed; + } #ifdef HX_RST_PIN_FUNC - ts->rst_gpio = pdata->gpio_reset; + ts->rst_gpio = pdata->gpio_reset; #endif - - if (himax_gpio_power_config(ts->client, pdata) < 0) - { - I(" GPIO and power config failed\n"); - goto err_gpio_power_config_failed; - } + if (himax_gpio_power_config(pdata) < 0) { + I(" GPIO and power config failed\n"); + goto err_gpio_power_config_failed; + } #ifndef CONFIG_OF - if (pdata->power) - { - ret = pdata->power(1); - if (ret < 0) - { - E("%s: power on failed\n", __func__); - goto err_power_failed; - } - } -#endif - private_ts = ts; - if (himax_ic_package_check(ts->client) == false) - { - E("Himax chip doesn NOT EXIST"); - goto err_ic_package_failed; - } + if (pdata->power) { + ret = pdata->power(1); - if (pdata->virtual_key) - ts->button = pdata->virtual_key; -#ifdef HX_TP_PROC_FLASH_DUMP - ts->flash_wq = create_singlethread_workqueue("himax_flash_wq"); - if (!ts->flash_wq) - { - E("%s: create flash workqueue failed\n", __func__); - err = -ENOMEM; - goto err_create_flash_dump_wq_failed; - } + if (ret < 0) { + E("%s: power on failed\n", __func__); + goto err_power_failed; + } + } - INIT_WORK(&ts->flash_work, himax_ts_flash_work_func); - - setSysOperation(0); - setFlashBuffer(); #endif -#ifdef HX_TP_PROC_GUEST_INFO - ts->guest_info_wq = create_singlethread_workqueue("himax_guest_info_wq"); - if (!ts->guest_info_wq) - { - E("%s: create guest info workqueue failed\n", __func__); - err = -ENOMEM; - goto err_create_guest_info_wq_failed; - } - INIT_WORK(&ts->guest_info_work, himax_ts_guest_info_work_func); -#endif + hx83112_chip_detect(); + if (g_core_fp.fp_chip_init != NULL) { + g_core_fp.fp_chip_init(); + } else { + E("%s: function point of chip_init is NULL!\n", __func__); + goto error_ic_detect_failed; + } -#ifdef HX_TP_PROC_DIAG - ts->himax_diag_wq = create_singlethread_workqueue("himax_diag"); - if (!ts->himax_diag_wq) - { - E("%s: create diag workqueue failed\n", __func__); - err = -ENOMEM; - goto err_create_diag_wq_failed; - } - INIT_DELAYED_WORK(&ts->himax_diag_delay_wrok, himax_ts_diag_work_func); -#endif + if (pdata->virtual_key) { + ts->button = pdata->virtual_key; + } #ifdef HX_AUTO_UPDATE_FW - auto_update_flag = himax_calculateChecksum(client, false); - auto_update_flag |= himax_flash_lastdata_check(client); - if(auto_update_flag) + g_auto_update_flag = (!g_core_fp.fp_calculateChecksum(false)); + g_auto_update_flag |= g_core_fp.fp_flash_lastdata_check(); + if (g_auto_update_flag) goto FW_force_upgrade; #endif - himax_read_FW_ver(client); +#ifndef HX_ZERO_FLASH + g_core_fp.fp_read_FW_ver(); +#endif #ifdef HX_AUTO_UPDATE_FW FW_force_upgrade: - auto_update_flag |= (( ic_data->vendor_fw_ver < g_i_FW_VER ) || ( ic_data->vendor_config_ver < g_i_CFG_VER )); - /* Not sure to do */ - //auto_update_flag |= ((ic_data->vendor_cid_maj_ver != g_i_CID_MAJ) || (ic_data->vendor_cid_min_ver < g_i_CID_MIN)); - if (auto_update_flag) - { - ts->himax_update_wq = create_singlethread_workqueue("HMX_update_reuqest"); - if (!ts->himax_update_wq) - { - E(" allocate syn_update_wq failed\n"); - err = -ENOMEM; - goto err_update_wq_failed; - } - INIT_DELAYED_WORK(&ts->work_update, himax_update_register); - queue_delayed_work(ts->himax_update_wq, &ts->work_update, msecs_to_jiffies(2000)); - } -#endif - -#ifdef HX_ZERO_FLASH - ts->himax_0f_update_wq = create_singlethread_workqueue("HMX_0f_update_reuqest"); - if (!ts->himax_0f_update_wq) { - E(" allocate himax_0f_update_wq failed\n"); - err = -ENOMEM; - goto err_0f_update_wq_failed; + ts->himax_update_wq = create_singlethread_workqueue("HMX_update_reuqest"); + if (!ts->himax_update_wq) { + E(" allocate syn_update_wq failed\n"); + err = -ENOMEM; + goto err_update_wq_failed; } - INIT_DELAYED_WORK(&ts->work_0f_update, himax_0f_operation); + INIT_DELAYED_WORK(&ts->work_update, himax_update_register); + queue_delayed_work(ts->himax_update_wq, &ts->work_update, msecs_to_jiffies(2000)); +#endif +#ifdef HX_ZERO_FLASH + g_auto_update_flag = true; + ts->himax_0f_update_wq = create_singlethread_workqueue("HMX_0f_update_reuqest"); + INIT_DELAYED_WORK(&ts->work_0f_update, g_core_fp.fp_0f_operation); queue_delayed_work(ts->himax_0f_update_wq, &ts->work_0f_update, msecs_to_jiffies(2000)); #endif - //Himax Power On and Load Config - if (himax_loadSensorConfig(client, pdata)) - { - E("%s: Load Sesnsor configuration failed, unload driver.\n", __func__); - goto err_detect_failed; - } - himax_power_on_init(client); - calculate_point_number(); -#ifdef HX_TP_PROC_DIAG - setXChannel(ic_data->HX_RX_NUM); // X channel - setYChannel(ic_data->HX_TX_NUM); // Y channel + /*Himax Power On and Load Config*/ + if (himax_loadSensorConfig(pdata)) { + E("%s: Load Sesnsor configuration failed, unload driver.\n", __func__); + goto err_detect_failed; + } - setMutualBuffer(); - setMutualNewBuffer(); - setMutualOldBuffer(); - if (getMutualBuffer() == NULL) - { - E("%s: mutual buffer allocate fail failed\n", __func__); - return -1; - } -#ifdef HX_TP_PROC_2T2R - if(Is_2T2R) - { - setXChannel_2(ic_data->HX_RX_NUM_2); // X channel - setYChannel_2(ic_data->HX_TX_NUM_2); // Y channel + g_core_fp.fp_power_on_init(); + calculate_point_number(); - setMutualBuffer_2(); - - if (getMutualBuffer_2() == NULL) - { - E("%s: mutual buffer 2 allocate fail failed\n", __func__); - return -1; - } - } -#endif -#endif #ifdef CONFIG_OF - ts->power = pdata->power; + ts->power = pdata->power; #endif - ts->pdata = pdata; - - ts->x_channel = ic_data->HX_RX_NUM; - ts->y_channel = ic_data->HX_TX_NUM; - ts->nFinger_support = ic_data->HX_MAX_PT; - //calculate the i2c data size - calcDataSize(ts->nFinger_support); - I("%s: calcDataSize complete\n", __func__); + ts->pdata = pdata; + ts->x_channel = ic_data->HX_RX_NUM; + ts->y_channel = ic_data->HX_TX_NUM; + ts->nFinger_support = ic_data->HX_MAX_PT; + /*calculate the i2c data size*/ + calcDataSize(ts->nFinger_support); + I("%s: calcDataSize complete\n", __func__); #ifdef CONFIG_OF - ts->pdata->abs_pressure_min = 0; - ts->pdata->abs_pressure_max = 200; - ts->pdata->abs_width_min = 0; - ts->pdata->abs_width_max = 200; - pdata->cable_config[0] = 0xF0; - pdata->cable_config[1] = 0x00; + ts->pdata->abs_pressure_min = 0; + ts->pdata->abs_pressure_max = 200; + ts->pdata->abs_width_min = 0; + ts->pdata->abs_width_max = 200; + pdata->cable_config[0] = 0xF0; + pdata->cable_config[1] = 0x00; #endif - ts->suspended = false; -#if defined( HX_USB_DETECT_CALLBACK)||defined(HX_USB_DETECT_GLOBAL) - ts->usb_connected = 0x00; - ts->cable_config = pdata->cable_config; + ts->suspended = false; +#if defined(HX_USB_DETECT_CALLBACK) || defined(HX_USB_DETECT_GLOBAL) + ts->usb_connected = 0x00; + ts->cable_config = pdata->cable_config; #endif #ifdef HX_PROTOCOL_A - ts->protocol_type = PROTOCOL_TYPE_A; + ts->protocol_type = PROTOCOL_TYPE_A; #else - ts->protocol_type = PROTOCOL_TYPE_B; + ts->protocol_type = PROTOCOL_TYPE_B; #endif - I("%s: Use Protocol Type %c\n", __func__, - ts->protocol_type == PROTOCOL_TYPE_A ? 'A' : 'B'); + I("%s: Use Protocol Type %c\n", __func__, + ts->protocol_type == PROTOCOL_TYPE_A ? 'A' : 'B'); + ret = himax_input_register(ts); + + if (ret) { + E("%s: Unable to register %s input device\n", + __func__, ts->input_dev->name); + goto err_input_register_device_failed; + } - ret = himax_input_register(ts); - if (ret) - { - E("%s: Unable to register %s input device\n", - __func__, ts->input_dev->name); - goto err_input_register_device_failed; - } #ifdef CONFIG_FB - ts->himax_att_wq = create_singlethread_workqueue("HMX_ATT_reuqest"); - if (!ts->himax_att_wq) - { - E(" allocate syn_att_wq failed\n"); - err = -ENOMEM; - goto err_get_intr_bit_failed; - } - INIT_DELAYED_WORK(&ts->work_att, himax_fb_register); - queue_delayed_work(ts->himax_att_wq, &ts->work_att, msecs_to_jiffies(15000)); -#endif + ts->himax_att_wq = create_singlethread_workqueue("HMX_ATT_reuqest"); -#if defined(HX_CHIP_STATUS_MONITOR)//for ESD solution - I("Enter HX_CHIP_STATUS_MONITOR! \n"); - - g_chip_monitor_data = kzalloc(sizeof(struct chip_monitor_data),GFP_KERNEL); - if(g_chip_monitor_data == NULL) - { - err = -ENOMEM; - goto err_alloc_monitor_data; - } - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_POLLING_TIMER = 5;//unit:sec - g_chip_monitor_data->HX_POLLING_TIMES = 2;//ex:5(timer)x2(times)=10sec(polling time) - g_chip_monitor_data->HX_ON_HAND_SHAKING = 0;// - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; - - ts->himax_chip_monitor_wq = create_singlethread_workqueue("himax_chip_monitor_wq"); - if (!ts->himax_chip_monitor_wq) - { - E(" %s: create workqueue failed\n", __func__); - err = -ENOMEM; - goto err_create_chip_monitor_wq_failed; - } - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; - - INIT_DELAYED_WORK(&ts->himax_chip_monitor, himax_chip_monitor_function); - - queue_delayed_work(ts->himax_chip_monitor_wq, &ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); + if (!ts->himax_att_wq) { + E(" allocate syn_att_wq failed\n"); + err = -ENOMEM; + goto err_get_intr_bit_failed; + } + INIT_DELAYED_WORK(&ts->work_att, himax_fb_register); + queue_delayed_work(ts->himax_att_wq, &ts->work_att, msecs_to_jiffies(15000)); #endif #ifdef HX_SMART_WAKEUP - ts->SMWP_enable=0; - wake_lock_init(&ts->ts_SMWP_wake_lock, WAKE_LOCK_SUSPEND, HIMAX_common_NAME); + ts->SMWP_enable = 0; + wake_lock_init(&ts->ts_SMWP_wake_lock, WAKE_LOCK_SUSPEND, HIMAX_common_NAME); #endif #ifdef HX_HIGH_SENSE - ts->HSEN_enable=0; + ts->HSEN_enable = 0; #endif -#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) - ts->ito_test_wq = create_singlethread_workqueue("himax_ito_test_wq"); - if (!ts->ito_test_wq) - { - E("%s: ito test workqueue failed\n", __func__); - err = -ENOMEM; - goto err_ito_test_wq_failed; - } + /*touch data init*/ + err = himax_report_data_init(); - INIT_WORK(&ts->ito_test_work, himax_ito_test_work); -#endif + if (err) { + goto err_report_data_init_failed; + } - //touch data init - err=himax_report_data_init(); - if(err) - goto err_report_data_init_failed; - -#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) - himax_touch_proc_init(); -#endif + if (himax_common_proc_init()) { + E(" %s: himax_common proc_init failed!\n", __func__); + goto err_creat_proc_file_failed; + } for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - ret = sysfs_create_file(&ts->client->dev.kobj, - &attrs[attr_count].attr); - if (ret < 0) { - dev_err(&client->dev, - "%s: Failed to create sysfs attributes\n", __func__); - goto err_sysfs; - } + ret = sysfs_create_file(&ts->client->dev.kobj, + &attrs[attr_count].attr); + if (ret < 0) { + E("%s: Failed to create sysfs attributes\n", __func__); + goto err_sysfs; + } } himax_sysfs_touchscreen(ts, true); -#if defined( HX_USB_DETECT_CALLBACK) - if (ts->cable_config) - cable_detect_register_notifier(&himax_cable_status_handler); -#endif +#if defined(HX_USB_DETECT_CALLBACK) - err = himax_ts_register_interrupt(ts->client); - if (err) - goto err_register_interrupt_failed; + if (ts->cable_config) { + cable_detect_register_notifier(&himax_cable_status_handler); + } + +#endif + err = himax_ts_register_interrupt(); + + if (err) { + goto err_register_interrupt_failed; + } + +#ifdef CONFIG_TOUCHSCREEN_HIMAX_DEBUG + if (himax_debug_init()) + E(" %s: debug initial failed!\n", __func__); +#endif #if defined(HX_AUTO_UPDATE_FW) || defined(HX_ZERO_FLASH) - if (auto_update_flag) - { - himax_int_enable(client->irq,0); - } + + if (g_auto_update_flag) { + himax_int_enable(0); + } + #endif - - return 0; - + return 0; err_register_interrupt_failed: + remove_proc_entry(HIMAX_PROC_TOUCH_FOLDER, NULL); err_sysfs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&ts->client->dev.kobj, - &attrs[attr_count].attr); - } -#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) - himax_touch_proc_deinit(); -#endif + attr_count = ARRAY_SIZE(attrs); + for (attr_count--; attr_count >= 0; attr_count--) { + sysfs_remove_file(&ts->client->dev.kobj, + &attrs[attr_count].attr); + } +err_creat_proc_file_failed: err_report_data_init_failed: - -#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) - destroy_workqueue(ts->ito_test_wq); -err_ito_test_wq_failed: -#endif #ifdef HX_SMART_WAKEUP - wake_lock_destroy(&ts->ts_SMWP_wake_lock); -#endif -#ifdef HX_CHIP_STATUS_MONITOR - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; - cancel_delayed_work_sync(&ts->himax_chip_monitor); - destroy_workqueue(ts->himax_chip_monitor_wq); -err_create_chip_monitor_wq_failed: - kfree(g_chip_monitor_data); -err_alloc_monitor_data: + wake_lock_destroy(&ts->ts_SMWP_wake_lock); #endif #ifdef CONFIG_FB cancel_delayed_work_sync(&ts->work_att); destroy_workqueue(ts->himax_att_wq); - err_get_intr_bit_failed: +err_get_intr_bit_failed: #endif - err_input_register_device_failed: +err_input_register_device_failed: input_free_device(ts->input_dev); err_detect_failed: -#ifdef HX_ZERO_FLASH - cancel_delayed_work_sync(&ts->work_0f_update); - destroy_workqueue(ts->himax_0f_update_wq); -err_0f_update_wq_failed: -#endif #ifdef HX_AUTO_UPDATE_FW - if (auto_update_flag) { + if (g_auto_update_flag) { cancel_delayed_work_sync(&ts->work_update); destroy_workqueue(ts->himax_update_wq); } err_update_wq_failed: #endif - -#ifdef HX_TP_PROC_DIAG - cancel_delayed_work_sync(&ts->himax_diag_delay_wrok); - destroy_workqueue(ts->himax_diag_wq); - err_create_diag_wq_failed: -#endif - -#ifdef HX_TP_PROC_GUEST_INFO - destroy_workqueue(ts->guest_info_wq); - err_create_guest_info_wq_failed: -#endif - -#ifdef HX_TP_PROC_FLASH_DUMP - destroy_workqueue(ts->flash_wq); - err_create_flash_dump_wq_failed: -#endif -err_ic_package_failed: - - if (gpio_is_valid(pdata->gpio_irq)) - gpio_free(pdata->gpio_irq); +error_ic_detect_failed: + if (gpio_is_valid(pdata->gpio_irq)) { + gpio_free(pdata->gpio_irq); + } #ifdef HX_RST_PIN_FUNC - if (gpio_is_valid(pdata->gpio_reset)) - gpio_free(pdata->gpio_reset); + if (gpio_is_valid(pdata->gpio_reset)) { + gpio_free(pdata->gpio_reset); + } #endif - #ifndef CONFIG_OF err_power_failed: #endif - err_gpio_power_config_failed: err_alloc_dt_pdata_failed: - kfree(hx_touch_data); + kfree(hx_touch_data); err_alloc_touch_data_failed: - kfree(ic_data); + kfree(ic_data); err_dt_ic_data_fail: - kfree(pdata); - + kfree(pdata); err_dt_platform_data_fail: - kfree(ts); - -err_alloc_data_failed: -err_check_functionality_failed: - probe_fail_flag = 1; - return err; - + kfree(ts); + probe_fail_flag = 1; + return err; } -int himax_chip_common_remove(struct i2c_client *client) +void himax_chip_common_deinit(void) { - struct himax_ts_data *ts = i2c_get_clientdata(client); - int attr_count; + struct himax_ts_data *ts = private_ts; + int attr_count = ARRAY_SIZE(attrs); -if (!ts->use_irq) -{ - hrtimer_cancel(&ts->timer); - destroy_workqueue(ts->himax_wq); -} +#ifdef CONFIG_TOUCHSCREEN_HIMAX_DEBUG + himax_debug_remove(); +#endif + + remove_proc_entry(HIMAX_PROC_TOUCH_FOLDER, NULL); + himax_common_proc_deinit(); + + if (!ts->use_irq) { + hrtimer_cancel(&ts->timer); + destroy_workqueue(ts->himax_wq); + } himax_sysfs_touchscreen(ts, false); - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + for (attr_count--; attr_count >= 0; attr_count--) { sysfs_remove_file(&ts->client->dev.kobj, - &attrs[attr_count].attr); + &attrs[attr_count].attr); } -#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) - himax_touch_proc_deinit(); -#endif -#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) - destroy_workqueue(ts->ito_test_wq); -#endif #ifdef HX_SMART_WAKEUP - wake_lock_destroy(&ts->ts_SMWP_wake_lock); -#endif -#ifdef HX_CHIP_STATUS_MONITOR - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; - cancel_delayed_work_sync(&ts->himax_chip_monitor); - destroy_workqueue(ts->himax_chip_monitor_wq); - kfree(g_chip_monitor_data); + wake_lock_destroy(&ts->ts_SMWP_wake_lock); #endif #ifdef CONFIG_FB - if (fb_unregister_client(&ts->fb_notif)) - E("Error occurred while unregistering fb_notifier.\n"); - cancel_delayed_work_sync(&ts->work_att); - destroy_workqueue(ts->himax_att_wq); + if (fb_unregister_client(&ts->fb_notif)) + E("Error occurred while unregistering fb_notifier.\n"); + cancel_delayed_work_sync(&ts->work_att); + destroy_workqueue(ts->himax_att_wq); #endif - input_free_device(ts->input_dev); + input_free_device(ts->input_dev); #ifdef HX_ZERO_FLASH - cancel_delayed_work_sync(&ts->work_0f_update); - destroy_workqueue(ts->himax_0f_update_wq); + cancel_delayed_work_sync(&ts->work_0f_update); + destroy_workqueue(ts->himax_0f_update_wq); #endif #ifdef HX_AUTO_UPDATE_FW - cancel_delayed_work_sync(&ts->work_update); - destroy_workqueue(ts->himax_update_wq); + cancel_delayed_work_sync(&ts->work_update); + destroy_workqueue(ts->himax_update_wq); #endif - -#ifdef HX_TP_PROC_DIAG - cancel_delayed_work_sync(&ts->himax_diag_delay_wrok); - destroy_workqueue(ts->himax_diag_wq); -#endif - -#ifdef HX_TP_PROC_GUEST_INFO - destroy_workqueue(ts->guest_info_wq); -#endif - -#ifdef HX_TP_PROC_FLASH_DUMP - destroy_workqueue(ts->flash_wq); -#endif - if (gpio_is_valid(ts->pdata->gpio_irq)) - gpio_free(ts->pdata->gpio_irq); + if (gpio_is_valid(ts->pdata->gpio_irq)) + gpio_free(ts->pdata->gpio_irq); #ifdef HX_RST_PIN_FUNC - if (gpio_is_valid(ts->pdata->gpio_reset)) - gpio_free(ts->pdata->gpio_reset); + if (gpio_is_valid(ts->pdata->gpio_reset)) + gpio_free(ts->pdata->gpio_reset); #endif - kfree(hx_touch_data); - kfree(ic_data); - kfree(ts->pdata); - kfree(ts); - probe_fail_flag = 0; + kfree(hx_touch_data); + kfree(ic_data); + kfree(ts->pdata); + kfree(ts); + probe_fail_flag = 0; - return 0; + return; } -#ifdef HX_INSPECT_LPWUG_TEST -void himax_press_powerkey(bool key_status) -{ - if(FAKE_POWER_KEY_SEND == key_status) - { - if(key_status == false) - { - I("Already suspend!\n"); - } - else - { - I("Already resume!\n"); - } - return ; - } - - I(" %s POWER KEY event %x press\n",__func__,KEY_POWER); - input_report_key(private_ts->input_dev, KEY_POWER, 1); - input_sync(private_ts->input_dev); - - I(" %s POWER KEY event %x release\n",__func__,KEY_POWER); - input_report_key(private_ts->input_dev, KEY_POWER, 0); - input_sync(private_ts->input_dev); - - FAKE_POWER_KEY_SEND = key_status; -} -#endif int himax_chip_common_suspend(struct himax_ts_data *ts) { - int ret; -#ifdef HX_CHIP_STATUS_MONITOR - int t = 0; -#endif + int ret; - if(ts->suspended) - { - I("%s: Already suspended. Skipped. \n", __func__); - return 0; - } - else - { - ts->suspended = true; - I("%s: enter \n", __func__); - } + if (ts->suspended) { + I("%s: Already suspended. Skipped. \n", __func__); + return 0; + } else { + ts->suspended = true; + I("%s: enter \n", __func__); + } -#ifdef HX_TP_PROC_FLASH_DUMP - if (getFlashDumpGoing()) - { - I("[himax] %s: Flash dump is going, reject suspend\n",__func__); - return 0; - } -#endif + if (debug_data != NULL && debug_data->flash_dump_going == true) { + I("[himax] %s: Flash dump is going, reject suspend\n", __func__); + return 0; + } -#ifdef HX_TP_PROC_GUEST_INFO - if (himax_guest_info_get_status()) - { - I("[himax] %s: GUEST INFO dump is going, reject suspend\n",__func__); - return 0; - } -#endif - -#ifdef HX_CHIP_STATUS_MONITOR - if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking - { - for(t=0; t<100; t++) - { - if(g_chip_monitor_data->HX_ON_HAND_SHAKING==0)//chip on hand shaking end - { - I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,t); - break; - } - else - msleep(1); - } - if(t==100) - { - E("%s:HX_ON_HAND_SHAKING timeout reject suspend\n",__func__); - return 0; - } - } - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - cancel_delayed_work_sync(&ts->himax_chip_monitor); -#endif - -#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) +#if defined(HX_SMART_WAKEUP) || defined(HX_HIGH_SENSE) || defined(HX_USB_DETECT_GLOBAL) #ifndef HX_RESUME_SEND_CMD - himax_resend_cmd_func(ts->suspended); + g_core_fp.fp_resend_cmd_func(ts->suspended); #endif #endif - -#ifdef HX_INSPECT_LPWUG_TEST - FAKE_POWER_KEY_SEND=false; -#endif - #ifdef HX_SMART_WAKEUP - if(ts->SMWP_enable) - { - atomic_set(&ts->suspend_mode, 1); - ts->pre_finger_mask = 0; - FAKE_POWER_KEY_SEND=false; - I("[himax] %s: SMART_WAKEUP enable, reject suspend\n",__func__); - return 0; - } + + if (ts->SMWP_enable) { + atomic_set(&ts->suspend_mode, 1); + ts->pre_finger_mask = 0; + FAKE_POWER_KEY_SEND = false; + I("[himax] %s: SMART_WAKEUP enable, reject suspend\n", __func__); + return 0; + } + #endif + himax_int_enable(0); + g_core_fp.fp_suspend_ic_action(); - himax_int_enable(ts->client->irq,0); + if (!ts->use_irq) { + ret = cancel_work_sync(&ts->work); - himax_suspend_ic_action(ts->client); + if (ret) { + himax_int_enable(1); + } + } - if (!ts->use_irq) - { - ret = cancel_work_sync(&ts->work); - if (ret) - himax_int_enable(ts->client->irq,1); - } + /*ts->first_pressed = 0;*/ + atomic_set(&ts->suspend_mode, 1); + ts->pre_finger_mask = 0; - //ts->first_pressed = 0; - atomic_set(&ts->suspend_mode, 1); - ts->pre_finger_mask = 0; - if (ts->pdata->powerOff3V3 && ts->pdata->power) - ts->pdata->power(0); - I("%s: END \n", __func__); - return 0; + if (ts->pdata->powerOff3V3 && ts->pdata->power) { + ts->pdata->power(0); + } + + I("%s: END \n", __func__); + return 0; } int himax_chip_common_resume(struct himax_ts_data *ts) { - -#ifdef HX_CHIP_STATUS_MONITOR - int t=0; +#if defined(HX_RST_PIN_FUNC) && defined(HX_RESUME_HW_RESET) && defined(HX_ZERO_FLASH) + int result = 0; #endif + I("%s: enter \n", __func__); - I("%s: enter \n", __func__); - if(ts->suspended == false) - { - I("%s: It had entered resume,skip this step \n", __func__); - return 0; - } - else - ts->suspended = false; + if (ts->suspended == false) { + I("%s: It had entered resume, skip this step \n", __func__); + return 0; + } else { + ts->suspended = false; + } - atomic_set(&ts->suspend_mode, 0); + atomic_set(&ts->suspend_mode, 0); - if (ts->pdata->powerOff3V3 && ts->pdata->power) - ts->pdata->power(1); + if (ts->pdata->powerOff3V3 && ts->pdata->power) { + ts->pdata->power(1); + } -#ifdef HX_CHIP_STATUS_MONITOR - if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking - { - for(t=0; t<100; t++) - { - if(g_chip_monitor_data->HX_ON_HAND_SHAKING == 0)//chip on hand shaking end - { - I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,t); - break; - } - else - msleep(1); - } - if(t==100) - { - E("%s:HX_ON_HAND_SHAKING timeout reject resume\n",__func__); - return 0; - } - } +#if defined(HX_SMART_WAKEUP) || defined(HX_HIGH_SENSE) || defined(HX_USB_DETECT_GLOBAL) + g_core_fp.fp_resend_cmd_func(ts->suspended); +#elif defined(HX_RST_PIN_FUNC) && defined(HX_RESUME_HW_RESET) + g_core_fp.fp_ic_reset(false, false); +#ifdef HX_ZERO_FLASH + I("It will update fw after esd event in zero flash mode!\n"); + result = g_core_fp.fp_0f_operation_dirly(); + if (result) { + E("Something is wrong! Skip Update with zero flash!\n"); + goto ESCAPE_0F_UPDATE; + } + g_core_fp.fp_reload_disable(0); + g_core_fp.fp_sense_on(0x00); #endif - -#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) - himax_resend_cmd_func(ts->suspended); -#elif defined(HX_RESUME_HW_RESET) - himax_ic_reset(false,false); #endif - -#ifdef HX_INSPECT_LPWUG_TEST - FAKE_POWER_KEY_SEND=true; + himax_report_all_leave_event(ts); + + g_core_fp.fp_resume_ic_action(); + himax_int_enable(1); +#if defined(HX_RST_PIN_FUNC) && defined(HX_RESUME_HW_RESET) && defined(HX_ZERO_FLASH) +ESCAPE_0F_UPDATE: #endif - - - himax_report_all_leave(ts); - - himax_resume_ic_action(ts->client); - - himax_int_enable(ts->client->irq,1); - -#ifdef HX_CHIP_STATUS_MONITOR - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; - queue_delayed_work(ts->himax_chip_monitor_wq, &ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); //for ESD solution -#endif - I("%s: END \n", __func__); - return 0; + I("%s: END \n", __func__); + return 0; } diff --git a/drivers/input/touchscreen/himax_mmi/himax_common.h b/drivers/input/touchscreen/himax_mmi/himax_common.h index c07cc782b4fc..dae45bcf5752 100644 --- a/drivers/input/touchscreen/himax_mmi/himax_common.h +++ b/drivers/input/touchscreen/himax_mmi/himax_common.h @@ -1,16 +1,16 @@ -/* Himax Android Driver Sample Code for common functions -* -* Copyright (C) 2017 Himax Corporation. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* +/* Himax Android Driver Sample Code for common functions + + Copyright (C) 2018 Himax Corporation. + + This software is licensed under the terms of the GNU General Public + License version 2, as published by the Free Software Foundation, and + may be copied, distributed, and modified under those terms. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + */ #ifndef HIMAX_COMMON_H @@ -40,87 +40,74 @@ #include "himax_platform.h" #if defined(CONFIG_FB) -#include -#include + #include + #include #elif defined(CONFIG_HAS_EARLYSUSPEND) -#include + #include #endif #ifdef CONFIG_OF -#include + #include #endif -#define HIMAX_DRIVER_VER "0.2.13.0_ABCD1234_01" + +#define HIMAX_DRIVER_VER "1.2.2.50_moto_02" #define FLASH_DUMP_FILE "/sdcard/HX_Flash_Dump.bin" #if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) - -#define HX_TP_PROC_DIAG -#define HX_TP_PROC_REGISTER -#define HX_TP_PROC_DEBUG -#define HX_TP_PROC_FLASH_DUMP -#define HX_TP_PROC_SELF_TEST -#define HX_TP_PROC_RESET -#define HX_TP_PROC_SENSE_ON_OFF -#define HX_TP_PROC_2T2R -//#define HX_TP_PROC_GUEST_INFO - -#ifdef HX_TP_PROC_SELF_TEST -//#define HX_TP_SELF_TEST_DRIVER //if enable, selftest works in driver -#define HX_ORG_SELFTEST -//#define HX_INSPECT_LPWUG_TEST -//#define HX_DOZE_TEST + #define HX_TP_PROC_2T2R + /*#define HX_TP_SELF_TEST_DRIVER*/ /*if enable, selftest works in driver*/ #endif - -int himax_touch_proc_init(void); -void himax_touch_proc_deinit(void); -#endif -//===========Himax Option function============= +/*===========Himax Option function=============*/ #define HX_RST_PIN_FUNC #define HX_RESUME_SEND_CMD #define HX_ESD_RECOVERY -//#define HX_AUTO_UPDATE_FW -//#define HX_CHIP_STATUS_MONITOR /*for ESD 2nd solution,it does not support incell,default off*/ -//#define HX_SMART_WAKEUP -//#define HX_GESTURE_TRACK -//#define HX_HIGH_SENSE -//#define HX_PALM_REPORT -//#define HX_USB_DETECT_GLOBAL -//#define HX_USB_DETECT_CALLBACK -//#define HX_PROTOCOL_A /* for MTK special platform.If turning on,it will report to system by using specific format. */ -//#define HX_RESUME_HW_RESET +/*#define HX_AUTO_UPDATE_FW*/ +/*#define HX_SMART_WAKEUP*/ +/*#define HX_GESTURE_TRACK*/ +/*#define HX_HIGH_SENSE*/ +/*#define HX_PALM_REPORT*/ +/*#define HX_USB_DETECT_GLOBAL*/ +/*#define HX_USB_DETECT_CALLBACK*/ +/*#define HX_PROTOCOL_A*/ /* for MTK special platform.If turning on,it will report to system by using specific format. */ +/*#define HX_RESUME_HW_RESET*/ #define HX_PROTOCOL_B_3PA -//#define HX_FIX_TOUCH_INFO /* if open, you need to change the touch info in the fix_touch_info*/ +/*#define HX_FIX_TOUCH_INFO*/ /* if open, you need to change the touch info in the fix_touch_info*/ +/*#define HX_ZERO_FLASH*/ +/*#define CONFIG_CHIP_DTCFG*/ +/*#undef CONFIG_FB*/ /* Enable it if driver go into suspend/resume twice */ -//#define HX_EN_SEL_BUTTON /* Support Self Virtual key ,default is close*/ -//#define HX_EN_MUT_BUTTON /* Support Mutual Virtual Key ,default is close*/ +/*#define HX_EN_SEL_BUTTON*/ /* Support Self Virtual key ,default is close*/ +/*#define HX_EN_MUT_BUTTON*/ /* Support Mutual Virtual Key ,default is close*/ #if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) -//#define HX_PLATFOME_DEFINE_KEY /* for specfic platform to set key(button) */ + /*#define HX_PLATFOME_DEFINE_KEY*/ /* for specfic platform to set key(button) */ #endif #define HX_KEY_MAX_COUNT 4 #define DEFAULT_RETRY_CNT 3 -#define HX_85XX_A_SERIES_PWON 1 -#define HX_85XX_B_SERIES_PWON 2 -#define HX_85XX_C_SERIES_PWON 3 -#define HX_85XX_D_SERIES_PWON 4 -#define HX_85XX_E_SERIES_PWON 5 -#define HX_85XX_ES_SERIES_PWON 6 -#define HX_85XX_F_SERIES_PWON 7 -#define HX_85XX_G_SERIES_PWON 8 -#define HX_85XX_H_SERIES_PWON 9 -#define HX_83100A_SERIES_PWON 10 -#define HX_83102A_SERIES_PWON 11 -#define HX_83102B_SERIES_PWON 12 -#define HX_83103A_SERIES_PWON 13 -#define HX_83110A_SERIES_PWON 14 -#define HX_83110B_SERIES_PWON 15 -#define HX_83111B_SERIES_PWON 16 -#define HX_83112A_SERIES_PWON 17 -#define HX_83112B_SERIES_PWON 18 -#define HX_83191_SERIES_PWON 19 +#define HX_85XX_A_SERIES_PWON "HX85xxA" +#define HX_85XX_B_SERIES_PWON "HX85xxB" +#define HX_85XX_C_SERIES_PWON "HX85xxC" +#define HX_85XX_D_SERIES_PWON "HX85xxD" +#define HX_85XX_E_SERIES_PWON "HX85xxE" +#define HX_85XX_ES_SERIES_PWON "HX85xxES" +#define HX_85XX_F_SERIES_PWON "HX85xxF" +#define HX_85XX_H_SERIES_PWON "HX85xxH" +#define HX_83100A_SERIES_PWON "HX83100A" +#define HX_83102A_SERIES_PWON "HX83102A" +#define HX_83102B_SERIES_PWON "HX83102B" +#define HX_83102D_SERIES_PWON "HX83102D" +#define HX_83103A_SERIES_PWON "HX83103A" +#define HX_83110A_SERIES_PWON "HX83110A" +#define HX_83110B_SERIES_PWON "HX83110B" +#define HX_83111B_SERIES_PWON "HX83111B" +#define HX_83112A_SERIES_PWON "HX83112A" +#define HX_83112B_SERIES_PWON "HX83112B" +#define HX_83112D_SERIES_PWON "HX83112D" +#define HX_83112E_SERIES_PWON "HX83112E" +#define HX_83191A_SERIES_PWON "HX83191A" #define HX_TP_BIN_CHECKSUM_SW 1 #define HX_TP_BIN_CHECKSUM_HW 2 @@ -146,169 +133,214 @@ void himax_touch_proc_deinit(void); #define LENGTH_FAIL -7 #define OPEN_FILE_FAIL -8 #define ERR_WORK_OUT -10 +#define ERR_STS_WRONG -11 +#define HW_CRC_FAIL 1 #define HX_FINGER_ON 1 #define HX_FINGER_LEAVE 2 -#define HX_REPORT_COORD 1 -#define HX_REPORT_SMWP_EVENT 2 - #define HX_FILENAME_SIZE 80 +#if defined(HX_PALM_REPORT) +#define PALM_REPORT 1 +#define NOT_REPORT -1 +#endif + +enum HX_TS_PATH { + HX_REPORT_COORD = 1, + HX_REPORT_SMWP_EVENT, + HX_REPORT_COORD_RAWDATA, +}; + +enum HX_TS_STATUS { + HX_TS_GET_DATA_FAIL = -4, + HX_ESD_EVENT, + HX_CHKSUM_FAIL, + HX_PATH_FAIL, + HX_TS_NORMAL_END = 0, + HX_ESD_REC_OK, + HX_READY_SERVE, + HX_REPORT_DATA, + HX_ESD_WARNING, + HX_IC_RUNNING, + HX_ZERO_EVENT_COUNT, + HX_RST_OK, +}; + +enum cell_type { + CHIP_IS_ON_CELL, + CHIP_IS_IN_CELL +}; #ifdef HX_FIX_TOUCH_INFO -enum fix_touch_info -{ - FIX_HX_RX_NUM = 0, - FIX_HX_TX_NUM = 0, - FIX_HX_BT_NUM = 0, - FIX_HX_X_RES = 0, - FIX_HX_Y_RES = 0, - FIX_HX_MAX_PT = 0, - FIX_HX_XY_REVERSE = false, - FIX_HX_INT_IS_EDGE = true, +enum fix_touch_info { + FIX_HX_RX_NUM = 36, + FIX_HX_TX_NUM = 18, + FIX_HX_BT_NUM = 0, + FIX_HX_X_RES = 720, + FIX_HX_Y_RES = 1520, + FIX_HX_MAX_PT = 10, + FIX_HX_XY_REVERSE = true, + FIX_HX_INT_IS_EDGE = true, #ifdef HX_TP_PROC_2T2R - FIX_HX_RX_NUM_2 = 0, - FIX_HX_TX_NUM_2 = 0 + FIX_HX_RX_NUM_2 = 0, + FIX_HX_TX_NUM_2 = 0, #endif }; #endif #ifdef HX_ZERO_FLASH -#define HX_0F_DEBUG + #define HX_SPI_OPERATION + #define HX_0F_DEBUG #endif - -struct himax_ic_data -{ - int vendor_fw_ver; - int vendor_config_ver; - int vendor_touch_cfg_ver; - int vendor_display_cfg_ver; - int vendor_cid_maj_ver; - int vendor_cid_min_ver; - int vendor_panel_ver; - int vendor_sensor_id; - int HX_RX_NUM; - int HX_TX_NUM; - int HX_BT_NUM; - int HX_X_RES; - int HX_Y_RES; - int HX_MAX_PT; - bool HX_XY_REVERSE; - bool HX_INT_IS_EDGE; +struct himax_ic_data { + int vendor_fw_ver; + int vendor_config_ver; + int vendor_touch_cfg_ver; + int vendor_display_cfg_ver; + int vendor_cid_maj_ver; + int vendor_cid_min_ver; + int vendor_panel_ver; + int vendor_sensor_id; + int HX_RX_NUM; + int HX_TX_NUM; + int HX_BT_NUM; + int HX_X_RES; + int HX_Y_RES; + int HX_MAX_PT; + bool HX_XY_REVERSE; + bool HX_INT_IS_EDGE; #ifdef HX_TP_PROC_2T2R - int HX_RX_NUM_2; - int HX_TX_NUM_2; + int HX_RX_NUM_2; + int HX_TX_NUM_2; #endif }; -struct himax_virtual_key -{ - int index; - int keycode; - int x_range_min; - int x_range_max; - int y_range_min; - int y_range_max; +struct himax_virtual_key { + int index; + int keycode; + int x_range_min; + int x_range_max; + int y_range_min; + int y_range_max; }; -struct himax_report_data -{ - int touch_all_size; - int raw_cnt_max; - int raw_cnt_rmd; - int touch_info_size; - uint8_t finger_num; - uint8_t finger_on; - uint8_t *hx_coord_buf; - uint8_t hx_state_info[2]; +struct himax_target_report_data { + int *x; + int *y; + int *w; + int *finger_id; + int finger_on; + int finger_num; +#ifdef HX_PLATFORM_DEFINE_KEY + int key_size; + int *key_x; + int *key_y; + int *key_w; +#endif +#ifdef HX_SMART_WAKEUP + int SMWP_event_chk; +#endif +}; + +struct himax_report_data { + int touch_all_size; + int raw_cnt_max; + int raw_cnt_rmd; + int touch_info_size; + uint8_t finger_num; + uint8_t finger_on; + uint8_t *hx_coord_buf; + uint8_t hx_state_info[2]; #if defined(HX_SMART_WAKEUP) - int event_size; - uint8_t *hx_event_buf; -#endif -#if defined(HX_TP_PROC_DIAG) - int rawdata_size; - uint8_t diag_cmd; - uint8_t *hx_rawdata_buf; - uint8_t rawdata_frame_size; + int event_size; + uint8_t *hx_event_buf; #endif + + int rawdata_size; + uint8_t diag_cmd; + uint8_t *hx_rawdata_buf; + uint8_t rawdata_frame_size; }; -struct himax_ts_data -{ - bool suspended; - bool force_update; - atomic_t suspend_mode; - atomic_t flash_mode; - uint8_t x_channel; - uint8_t y_channel; - uint8_t useScreenRes; - uint8_t diag_command; +struct himax_ts_data { + bool suspended; + bool force_update; + atomic_t suspend_mode; + atomic_t flash_mode; + uint8_t x_channel; + uint8_t y_channel; + uint8_t useScreenRes; + uint8_t diag_cmd; + char chip_name[30]; + uint8_t chip_cell_type; - uint8_t protocol_type; - uint8_t first_pressed; - uint8_t coord_data_size; - uint8_t area_data_size; - uint8_t coordInfoSize; - uint8_t raw_data_frame_size; - uint8_t raw_data_nframes; - uint8_t nFinger_support; - uint8_t irq_enabled; - uint8_t diag_self[50]; + uint8_t protocol_type; + uint8_t first_pressed; + uint8_t coord_data_size; + uint8_t area_data_size; + uint8_t coordInfoSize; + uint8_t raw_data_frame_size; + uint8_t raw_data_nframes; + uint8_t nFinger_support; + uint8_t irq_enabled; + uint8_t diag_self[50]; - uint16_t finger_pressed; - uint16_t last_slot; - uint16_t pre_finger_mask; + uint16_t finger_pressed; + uint16_t last_slot; + uint16_t pre_finger_mask; + uint16_t old_finger; + int hx_point_num; - uint32_t debug_log_level; - uint32_t widthFactor; - uint32_t heightFactor; - uint32_t tw_x_min; - uint32_t tw_x_max; - uint32_t tw_y_min; - uint32_t tw_y_max; - uint32_t pl_x_min; - uint32_t pl_x_max; - uint32_t pl_y_min; - uint32_t pl_y_max; - int rst_gpio; - int use_irq; - int (*power)(int on); - int pre_finger_data[10][2]; + uint32_t debug_log_level; + uint32_t widthFactor; + uint32_t heightFactor; + uint32_t tw_x_min; + uint32_t tw_x_max; + uint32_t tw_y_min; + uint32_t tw_y_max; + uint32_t pl_x_min; + uint32_t pl_x_max; + uint32_t pl_y_min; + uint32_t pl_y_max; - struct device *dev; - struct workqueue_struct *himax_wq; - struct work_struct work; - struct input_dev *input_dev; - struct hrtimer timer; - struct i2c_client *client; - struct himax_i2c_platform_data *pdata; - struct himax_virtual_key *button; - struct mutex rw_lock; + int rst_gpio; + int use_irq; + int (*power)(int on); + int pre_finger_data[10][2]; + + struct device *dev; + struct workqueue_struct *himax_wq; + struct work_struct work; + struct input_dev *input_dev; + struct hrtimer timer; + struct i2c_client *client; + struct himax_i2c_platform_data *pdata; + struct himax_virtual_key *button; + struct mutex rw_lock; + +/******* SPI-start *******/ + struct mutex spi_lock; + struct spi_device *spi; + int hx_irq; +/******* SPI-end *******/ + + int in_self_test; #if defined(CONFIG_FB) - struct notifier_block fb_notif; - struct workqueue_struct *himax_att_wq; - struct delayed_work work_att; + struct notifier_block fb_notif; + struct workqueue_struct *himax_att_wq; + struct delayed_work work_att; #elif defined(CONFIG_HAS_EARLYSUSPEND) - struct early_suspend early_suspend; -#endif -#ifdef HX_CHIP_STATUS_MONITOR - struct workqueue_struct *himax_chip_monitor_wq; - struct delayed_work himax_chip_monitor; -#endif -#ifdef HX_TP_PROC_FLASH_DUMP - struct workqueue_struct *flash_wq; - struct work_struct flash_work; -#endif -#ifdef HX_TP_PROC_GUEST_INFO - struct workqueue_struct *guest_info_wq; - struct work_struct guest_info_work; + struct early_suspend early_suspend; #endif + struct workqueue_struct *flash_wq; + struct work_struct flash_work; + #ifdef HX_AUTO_UPDATE_FW - struct workqueue_struct *himax_update_wq; - struct delayed_work work_update; + struct workqueue_struct *himax_update_wq; + struct delayed_work work_update; #endif #ifdef HX_ZERO_FLASH @@ -316,120 +348,56 @@ struct himax_ts_data struct delayed_work work_0f_update; #endif -#ifdef HX_TP_PROC_DIAG - struct workqueue_struct *himax_diag_wq; - struct delayed_work himax_diag_delay_wrok; -#endif + struct workqueue_struct *himax_diag_wq; + struct delayed_work himax_diag_delay_wrok; #ifdef HX_SMART_WAKEUP - uint8_t SMWP_enable; - uint8_t gesture_cust_en[16]; - struct wake_lock ts_SMWP_wake_lock; + uint8_t SMWP_enable; + uint8_t gesture_cust_en[26]; + struct wake_lock ts_SMWP_wake_lock; #endif #ifdef HX_HIGH_SENSE - uint8_t HSEN_enable; + uint8_t HSEN_enable; #endif -#if defined(HX_USB_DETECT_CALLBACK)||defined(HX_USB_DETECT_GLOBAL) - uint8_t usb_connected; - uint8_t *cable_config; +#if defined(HX_USB_DETECT_CALLBACK) || defined(HX_USB_DETECT_GLOBAL) + uint8_t usb_connected; + uint8_t *cable_config; #endif -#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) - struct workqueue_struct *ito_test_wq; - struct work_struct ito_test_work; -#endif }; -#ifdef HX_CHIP_STATUS_MONITOR -struct chip_monitor_data -{ - int HX_CHIP_POLLING_COUNT; - int HX_POLLING_TIMER;//unit:sec - int HX_POLLING_TIMES;//ex:5(timer)x2(times)=10sec(polling time) - int HX_ON_HAND_SHAKING;// - int HX_CHIP_MONITOR_EN; +struct himax_debug { + bool flash_dump_going; + void (*fp_ts_dbg_func)(struct himax_ts_data *ts, int start); + int (*fp_set_diag_cmd)(struct himax_ic_data *ic_data, struct himax_report_data *hx_touch_data); }; -#endif - -enum input_protocol_type -{ - PROTOCOL_TYPE_A = 0x00, - PROTOCOL_TYPE_B = 0x01, +enum input_protocol_type { + PROTOCOL_TYPE_A = 0x00, + PROTOCOL_TYPE_B = 0x01, }; #ifdef HX_HIGH_SENSE -void himax_set_HSEN_func(struct i2c_client *client,uint8_t HSEN_enable); + void himax_set_HSEN_func(uint8_t HSEN_enable); #endif #ifdef HX_SMART_WAKEUP +void himax_set_SMWP_func(uint8_t SMWP_enable); + #define GEST_PTLG_ID_LEN (4) #define GEST_PTLG_HDR_LEN (4) #define GEST_PTLG_HDR_ID1 (0xCC) #define GEST_PTLG_HDR_ID2 (0x44) #define GEST_PT_MAX_NUM (128) - -void himax_set_SMWP_func(struct i2c_client *client,uint8_t SMWP_enable); - -enum gesture_event_type -{ - EV_GESTURE_01 = 0x01, - EV_GESTURE_02, - EV_GESTURE_03, - EV_GESTURE_04, - EV_GESTURE_05, - EV_GESTURE_06, - EV_GESTURE_07, - EV_GESTURE_08, - EV_GESTURE_09, - EV_GESTURE_10, - EV_GESTURE_11, - EV_GESTURE_12, - EV_GESTURE_13, - EV_GESTURE_14, - EV_GESTURE_15, - EV_GESTURE_PWR = 0x80, -}; - -#define KEY_CUST_01 251 -#define KEY_CUST_02 252 -#define KEY_CUST_03 253 -#define KEY_CUST_04 254 -#define KEY_CUST_05 255 -#define KEY_CUST_06 256 -#define KEY_CUST_07 257 -#define KEY_CUST_08 258 -#define KEY_CUST_09 259 -#define KEY_CUST_10 260 -#define KEY_CUST_11 261 -#define KEY_CUST_12 262 -#define KEY_CUST_13 263 -#define KEY_CUST_14 264 -#define KEY_CUST_15 265 -#endif - -#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) -extern uint8_t himax_ito_test(void); -#endif - -#if defined(HX_SMART_WAKEUP) || defined(HX_INSPECT_LPWUG_TEST) -extern bool FAKE_POWER_KEY_SEND; #endif extern int irq_enable_count; -//void himax_HW_reset(uint8_t loadconfig,uint8_t int_off); +/*void himax_HW_reset(uint8_t loadconfig,uint8_t int_off);*/ -#ifdef QCT -irqreturn_t himax_ts_thread(int irq, void *ptr); -int himax_input_register(struct himax_ts_data *ts); -#endif - -extern int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id); -extern int himax_chip_common_remove(struct i2c_client *client); extern int himax_chip_common_suspend(struct himax_ts_data *ts); extern int himax_chip_common_resume(struct himax_ts_data *ts); diff --git a/drivers/input/touchscreen/himax_mmi/himax_debug.c b/drivers/input/touchscreen/himax_mmi/himax_debug.c index f97fabd3fad7..d86bf34f4b7a 100644 --- a/drivers/input/touchscreen/himax_mmi/himax_debug.c +++ b/drivers/input/touchscreen/himax_mmi/himax_debug.c @@ -1,773 +1,634 @@ -/* Himax Android Driver Sample Code for debug nodes -* -* Copyright (C) 2017 Himax Corporation. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* +/* Himax Android Driver Sample Code for debug nodes + + Copyright (C) 2018 Himax Corporation. + + This software is licensed under the terms of the GNU General Public + License version 2, as published by the Free Software Foundation, and + may be copied, distributed, and modified under those terms. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + */ #include "himax_debug.h" -#include "himax_ic.h" +#include "himax_ic_core.h" -//struct himax_debug_data* debug_data; - -extern struct himax_ic_data* ic_data; +extern struct himax_ic_data *ic_data; extern struct himax_ts_data *private_ts; -extern unsigned char IC_TYPE; +extern struct himax_core_fp g_core_fp; +extern struct himax_debug *debug_data; extern unsigned char IC_CHECKSUM; +extern int i2c_error_count; +extern struct proc_dir_entry *himax_touch_proc_dir; + extern int himax_input_register(struct himax_ts_data *ts); -#ifdef HX_CHIP_STATUS_MONITOR -extern struct chip_monitor_data *g_chip_monitor_data; +#ifdef HX_TP_PROC_2T2R + extern bool Is_2T2R; #endif #ifdef HX_RST_PIN_FUNC -extern void himax_ic_reset(uint8_t loadconfig,uint8_t int_off); + extern void himax_ic_reset(uint8_t loadconfig, uint8_t int_off); #endif -#ifdef HX_TP_PROC_DIAG #ifdef HX_TP_PROC_2T2R -extern bool Is_2T2R; -int HX_RX_NUM_2 = 0; -int HX_TX_NUM_2 = 0; -#endif -uint8_t g_diag_arr_num = 0; + bool Is_2T2R = false; + int HX_RX_NUM_2 = 0; + int HX_TX_NUM_2 = 0; #endif -#if defined(HX_SMART_WAKEUP) || defined(HX_INSPECT_LPWUG_TEST) -bool FAKE_POWER_KEY_SEND; +#if defined(HX_ZERO_FLASH) +extern char *i_CTPM_firmware_name; #endif +uint8_t g_diag_arr_num = 0; + +extern uint8_t HX_PROC_SEND_FLAG; + int g_max_mutual = 0; -int g_min_mutual = 255; +int g_min_mutual = 0xFFFF; int g_max_self = 0; -int g_min_self = 255; +int g_min_self = 0xFFFF; -#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) -int g_self_test_entered = 0; -#endif struct timespec timeStart, timeEnd, timeDelta; int g_switch_mode = 0; -extern void himax_idle_mode(struct i2c_client *client,int disable); -extern int himax_switch_mode(struct i2c_client *client,int mode); -extern void himax_return_event_stack(struct i2c_client *client); +/* ============================================================================================================= -#ifdef HX_ZERO_FLASH -extern void himax_0f_operation(struct work_struct *work); -extern void himax_0f_operation_check(void); -extern void himax_sys_reset(void); -#endif + Segment : Himax PROC Debug Function -//============================================================================================================= -// -// Segment : Himax PROC Debug Function -// -//============================================================================================================= -#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) - -#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) - -static ssize_t himax_ito_test_read(struct file *file, char *buf, - size_t len, loff_t *pos) +============================================================================================================= */ +static ssize_t himax_CRC_test_read(struct file *file, char *buf, + size_t len, loff_t *pos) { - ssize_t ret = 0; - uint8_t result = 0; - uint8_t status = 0; + ssize_t ret = 0; + uint8_t result = 0; char *temp_buf; - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); - status = ito_get_step_status(); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + g_core_fp.fp_sense_off(); + msleep(20); + result = g_core_fp.fp_calculateChecksum(false); + g_core_fp.fp_sense_on(0x01); - switch(status) - { - case 0: - ret += snprintf(temp_buf + ret, len - ret, "Step : START_TEST\n"); - break; - case 1: - ret += snprintf(temp_buf + ret, len - ret, "Step : RAW_DATA\n"); - break; - case 2: - ret += snprintf(temp_buf + ret, len - ret, "Step : PERCENT_TEST\n"); - break; - case 3: - ret += snprintf(temp_buf + ret, len - ret, "Step : DEV_TEST\n"); - break; - case 4: - ret += snprintf(temp_buf + ret, len - ret, "Step : NOISE_TEST\n"); - break; - case 9: - ret += snprintf(temp_buf + ret, len - ret, "Step : END_TEST\n"); - break; - default: - ret += snprintf(temp_buf + ret, len - ret, "Step : Null\n"); - } + if (result) { + ret += snprintf(temp_buf + ret, len - ret, "CRC test is Pass! \n"); + } else { + ret += snprintf(temp_buf + ret, len - ret, "CRC test is Fail! \n"); + } + + if (copy_to_user(buf, temp_buf, len)) { + I("%s,here:%d\n", __func__, __LINE__); + } - result = ito_get_result_status(); - if(result == 0xF) - ret += snprintf(temp_buf + ret, len - ret, "ITO test is On-going! \n"); - else if(result == 0) - ret += snprintf(temp_buf + ret, len - ret, "ITO test is Pass! \n"); - else if(result == 2) - ret += snprintf(temp_buf + ret, len - ret, "Open config file fail! \n"); - else - ret += snprintf(temp_buf + ret, len - ret, "ITO test is Fail! \n"); - HX_PROC_SEND_FLAG=1; - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); kfree(temp_buf); - } - else - HX_PROC_SEND_FLAG=0; + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } - return ret; + return ret; } -static ssize_t himax_ito_test_write(struct file *file, const char *buff, - size_t len, loff_t *pos) -{ - struct himax_ts_data *ts = private_ts; - uint8_t result = 0; - char buf[80] = {0}; - - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } - - result = ito_get_result_status(); - I("%s: buf = %s, result = %d.\n", __func__, buf, result); - - if(buf[0] == '1' && result != 0xF) - { - I("%s: buf[0] = %c.\n", __func__, buf[0]); - ito_set_step_status(0); - queue_work(ts->ito_test_wq, &ts->ito_test_work); - } - - return len; -} - -static struct file_operations himax_proc_ito_test_ops = -{ - .owner = THIS_MODULE, - .read = himax_ito_test_read, - .write = himax_ito_test_write, -}; -#endif - -static ssize_t himax_CRC_test_read(struct file *file, char *buf, - size_t len, loff_t *pos) -{ - ssize_t ret = 0; - uint8_t result = 0; - char *temp_buf; - - temp_buf = kzalloc(len,GFP_KERNEL); - - if(!HX_PROC_SEND_FLAG) - { - himax_sense_off(private_ts->client); - msleep(20); - result = himax_calculateChecksum(private_ts->client, false); - himax_sense_on(private_ts->client, 0x01); - if(result == 0) - ret += snprintf(temp_buf + ret, len - ret, "CRC test is Pass! \n"); - else - ret += snprintf(temp_buf + ret, len - ret, "CRC test is Fail! \n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - - return ret; -} - -static struct file_operations himax_proc_CRC_test_ops = -{ - .owner = THIS_MODULE, - .read = himax_CRC_test_read, +static struct file_operations himax_proc_CRC_test_ops = { + .owner = THIS_MODULE, + .read = himax_CRC_test_read, }; static ssize_t himax_vendor_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - ssize_t ret = 0; - char *temp_buf; + ssize_t ret = 0; + char *temp_buf; - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); - ret += snprintf(temp_buf + ret, len - ret, "FW_VER = 0x%2.2X \n",ic_data->vendor_fw_ver); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + ret += snprintf(temp_buf + ret, len - ret, "FW_VER = 0x%2.2X \n", ic_data->vendor_fw_ver); - if(IC_TYPE < 8) - ret += snprintf(temp_buf + ret, len - ret, "CONFIG_VER = 0x%2.2X \n",ic_data->vendor_config_ver); - else - { - ret += snprintf(temp_buf + ret, len - ret, "TOUCH_VER = 0x%2.2X \n",ic_data->vendor_touch_cfg_ver); - ret += snprintf(temp_buf + ret, len - ret, "DISPLAY_VER = 0x%2.2X \n",ic_data->vendor_display_cfg_ver); - } - if(ic_data->vendor_cid_maj_ver < 0 && ic_data->vendor_cid_min_ver < 0) - ret += snprintf(temp_buf + ret, len - ret, "CID_VER = NULL\n"); - else - ret += snprintf(temp_buf + ret, len - ret, "CID_VER = 0x%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); + if (private_ts->chip_cell_type == CHIP_IS_ON_CELL) { + ret += snprintf(temp_buf + ret, len - ret, "CONFIG_VER = 0x%2.2X \n", ic_data->vendor_config_ver); + } else { + ret += snprintf(temp_buf + ret, len - ret, "TOUCH_VER = 0x%2.2X \n", ic_data->vendor_touch_cfg_ver); + ret += snprintf(temp_buf + ret, len - ret, "DISPLAY_VER = 0x%2.2X \n", ic_data->vendor_display_cfg_ver); + } - if(ic_data->vendor_panel_ver < 0) - ret += snprintf(temp_buf + ret, len - ret, "PANEL_VER = NULL\n"); - else - ret += snprintf(temp_buf + ret, len - ret, "PANEL_VER = 0x%2.2X \n",ic_data->vendor_panel_ver); + if (ic_data->vendor_cid_maj_ver < 0 && ic_data->vendor_cid_min_ver < 0) { + ret += snprintf(temp_buf + ret, len - ret, "CID_VER = NULL\n"); + } else { + ret += snprintf(temp_buf + ret, len - ret, "CID_VER = 0x%2.2X \n", (ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); + } - ret += snprintf(temp_buf + ret, len - ret, "\n"); + if (ic_data->vendor_panel_ver < 0) { + ret += snprintf(temp_buf + ret, len - ret, "PANEL_VER = NULL\n"); + } else { + ret += snprintf(temp_buf + ret, len - ret, "PANEL_VER = 0x%2.2X \n", ic_data->vendor_panel_ver); + } - ret += snprintf(temp_buf + ret, len - ret, "Himax Touch Driver Version:\n"); - ret += snprintf(temp_buf + ret, len - ret, "%s \n", HIMAX_DRIVER_VER); + ret += snprintf(temp_buf + ret, len - ret, "\n"); + ret += snprintf(temp_buf + ret, len - ret, "Himax Touch Driver Version:\n"); + ret += snprintf(temp_buf + ret, len - ret, "%s \n", HIMAX_DRIVER_VER); + HX_PROC_SEND_FLAG = 1; - HX_PROC_SEND_FLAG=1; - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - } - else - HX_PROC_SEND_FLAG=0; + if (copy_to_user(buf, temp_buf, len)) { + I("%s,here:%d\n", __func__, __LINE__); + } - return ret; + kfree(temp_buf); + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } -static struct file_operations himax_proc_vendor_ops = -{ - .owner = THIS_MODULE, - .read = himax_vendor_read, +static struct file_operations himax_proc_vendor_ops = { + .owner = THIS_MODULE, + .read = himax_vendor_read, }; static ssize_t himax_attn_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - ssize_t ret = 0; - struct himax_ts_data *ts_data; - char *temp_buf; + ssize_t ret = 0; + struct himax_ts_data *ts_data; + char *temp_buf; + ts_data = private_ts; - ts_data = private_ts; + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + ret += snprintf(temp_buf + ret, len - ret, "attn = %x\n", himax_int_gpio_read(ts_data->pdata->gpio_irq)); - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); - ret += snprintf(temp_buf + ret, len - ret, "attn = %x\n", himax_int_gpio_read(ts_data->pdata->gpio_irq)); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } - return ret; + return ret; } -static struct file_operations himax_proc_attn_ops = -{ - .owner = THIS_MODULE, - .read = himax_attn_read, +static struct file_operations himax_proc_attn_ops = { + .owner = THIS_MODULE, + .read = himax_attn_read, }; static ssize_t himax_int_en_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - struct himax_ts_data *ts = private_ts; - size_t ret = 0; - char *temp_buf; - - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + struct himax_ts_data *ts = private_ts; + size_t ret = 0; + char *temp_buf; + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->irq_enabled); - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + ret += snprintf(temp_buf + ret, len - ret, "\n"); + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } static ssize_t himax_int_en_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - struct himax_ts_data *ts = private_ts; - char buf_tmp[12]= {0}; - int value, ret=0; + struct himax_ts_data *ts = private_ts; + char buf_tmp[12] = {0}; + int value, ret = 0; - if (len >= 12) - { - I("%s: no command exceeds 12 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf_tmp, buff, len)) - { - return -EFAULT; - } + if (len >= 12) { + I("%s: no command exceeds 12 chars.\n", __func__); + return -EFAULT; + } - if (buf_tmp[0] == '0') - value = false; - else if (buf_tmp[0] == '1') - value = true; - else - return -EINVAL; + if (copy_from_user(buf_tmp, buff, len)) { + return -EFAULT; + } - if (value) - { - ret = himax_int_en_set(ts->client); - if (ret == 0) - { - ts->irq_enabled = 1; - irq_enable_count = 1; - } - } - else - { - himax_int_enable(ts->client->irq,0); - free_irq(ts->client->irq, ts); - ts->irq_enabled = 0; - } + if (buf_tmp[0] == '0') { + value = false; + } else if (buf_tmp[0] == '1') { + value = true; + } else { + return -EINVAL; + } + if (value) { + ret = himax_int_en_set(); - return len; + if (ret == 0) { + ts->irq_enabled = 1; + irq_enable_count = 1; + } + } else { + himax_int_enable(0); + free_irq(ts->client->irq, ts); + ts->irq_enabled = 0; + } + + return len; } -static struct file_operations himax_proc_int_en_ops = -{ - .owner = THIS_MODULE, - .read = himax_int_en_read, - .write = himax_int_en_write, +static struct file_operations himax_proc_int_en_ops = { + .owner = THIS_MODULE, + .read = himax_int_en_read, + .write = himax_int_en_write, }; static ssize_t himax_layout_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - struct himax_ts_data *ts = private_ts; - size_t ret = 0; - char *temp_buf; + struct himax_ts_data *ts = private_ts; + size_t ret = 0; + char *temp_buf; - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->pdata->abs_x_min); + ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->pdata->abs_x_max); + ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->pdata->abs_y_min); + ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->pdata->abs_y_max); + ret += snprintf(temp_buf + ret, len - ret, "\n"); - ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->pdata->abs_x_min); - ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->pdata->abs_x_max); - ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->pdata->abs_y_min); - ret += snprintf(temp_buf + ret, len - ret, "%d ", ts->pdata->abs_y_max); - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); - return ret; + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } static ssize_t himax_layout_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - struct himax_ts_data *ts = private_ts; - char buf_tmp[5]; - int i = 0, j = 0, k = 0, ret; - unsigned long value; - int layout[4] = {0}; - char buf[80] = {0}; + struct himax_ts_data *ts = private_ts; + char buf_tmp[5]; + int i = 0, j = 0, k = 0, ret; + unsigned long value; + int layout[4] = {0}; + char buf[80] = {0}; - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } - for (i = 0; i < 20; i++) - { - if (buf[i] == ',' || buf[i] == '\n') - { - memset(buf_tmp, 0x0, sizeof(buf_tmp)); - if (i - j <= 5) - memcpy(buf_tmp, buf + j, i - j); - else - { - I("buffer size is over 5 char\n"); - return len; - } - j = i + 1; - if (k < 4) - { - ret = kstrtoul(buf_tmp, 10, &value); - layout[k++] = value; - } - } - } - if (k == 4) - { - ts->pdata->abs_x_min=layout[0]; - ts->pdata->abs_x_max=layout[1]; - ts->pdata->abs_y_min=layout[2]; - ts->pdata->abs_y_max=layout[3]; - I("%d, %d, %d, %d\n", - ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); - input_unregister_device(ts->input_dev); - himax_input_register(ts); - } - else - I("ERR@%d, %d, %d, %d\n", - ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); - return len; + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } + + for (i = 0; i < 20; i++) { + if (buf[i] == ',' || buf[i] == '\n') { + memset(buf_tmp, 0x0, sizeof(buf_tmp)); + + if (i - j <= 5) { + memcpy(buf_tmp, buf + j, i - j); + } else { + I("buffer size is over 5 char\n"); + return len; + } + + j = i + 1; + + if (k < 4) { + ret = kstrtoul(buf_tmp, 10, &value); + layout[k++] = value; + } + } + } + + if (k == 4) { + ts->pdata->abs_x_min = layout[0]; + ts->pdata->abs_x_max = layout[1]; + ts->pdata->abs_y_min = layout[2]; + ts->pdata->abs_y_max = layout[3]; + I("%d, %d, %d, %d\n", + ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); + input_unregister_device(ts->input_dev); + himax_input_register(ts); + } else { + I("ERR@%d, %d, %d, %d\n", + ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); + } + + return len; } -static struct file_operations himax_proc_layout_ops = -{ - .owner = THIS_MODULE, - .read = himax_layout_read, - .write = himax_layout_write, +static struct file_operations himax_proc_layout_ops = { + .owner = THIS_MODULE, + .read = himax_layout_read, + .write = himax_layout_write, }; static ssize_t himax_debug_level_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - struct himax_ts_data *ts_data; - size_t ret = 0; - char *temp_buf; - - ts_data = private_ts; - - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + struct himax_ts_data *ts_data; + size_t ret = 0; + char *temp_buf; + ts_data = private_ts; + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); ret += snprintf(temp_buf + ret, len - ret, "%d\n", ts_data->debug_log_level); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG = 1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } static ssize_t himax_debug_level_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - struct himax_ts_data *ts; - char buf_tmp[11]; - int i; - ts = private_ts; + struct himax_ts_data *ts; + char buf_tmp[11]; + int i; + ts = private_ts; - if (len >= 12) - { - I("%s: no command exceeds 12 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf_tmp, buff, len)) - { - return -EFAULT; - } + if (len >= 12) { + I("%s: no command exceeds 12 chars.\n", __func__); + return -EFAULT; + } - ts->debug_log_level = 0; - for(i=0; i='0' && buf_tmp[i]<='9' ) - ts->debug_log_level |= (buf_tmp[i]-'0'); - else if( buf_tmp[i]>='A' && buf_tmp[i]<='F' ) - ts->debug_log_level |= (buf_tmp[i]-'A'+10); - else if( buf_tmp[i]>='a' && buf_tmp[i]<='f' ) - ts->debug_log_level |= (buf_tmp[i]-'a'+10); + if (copy_from_user(buf_tmp, buff, len)) { + return -EFAULT; + } - if(i!=len-2) - ts->debug_log_level <<= 4; - } + ts->debug_log_level = 0; - if (ts->debug_log_level & BIT(3)) - { - if (ts->pdata->screenWidth > 0 && ts->pdata->screenHeight > 0 && - (ts->pdata->abs_x_max - ts->pdata->abs_x_min) > 0 && - (ts->pdata->abs_y_max - ts->pdata->abs_y_min) > 0) - { - ts->widthFactor = (ts->pdata->screenWidth << SHIFTBITS)/(ts->pdata->abs_x_max - ts->pdata->abs_x_min); - ts->heightFactor = (ts->pdata->screenHeight << SHIFTBITS)/(ts->pdata->abs_y_max - ts->pdata->abs_y_min); - if (ts->widthFactor > 0 && ts->heightFactor > 0) - ts->useScreenRes = 1; - else - { - ts->heightFactor = 0; - ts->widthFactor = 0; - ts->useScreenRes = 0; - } - } - else - I("Enable finger debug with raw position mode!\n"); - } - else - { - ts->useScreenRes = 0; - ts->widthFactor = 0; - ts->heightFactor = 0; - } + for (i = 0; i < len - 1; i++) { + if (buf_tmp[i] >= '0' && buf_tmp[i] <= '9') + ts->debug_log_level |= (buf_tmp[i] - '0'); + else if (buf_tmp[i] >= 'A' && buf_tmp[i] <= 'F') + ts->debug_log_level |= (buf_tmp[i] - 'A' + 10); + else if (buf_tmp[i] >= 'a' && buf_tmp[i] <= 'f') + ts->debug_log_level |= (buf_tmp[i] - 'a' + 10); - return len; + if (i != len - 2) + ts->debug_log_level <<= 4; + } + + if (ts->debug_log_level & BIT(3)) { + if (ts->pdata->screenWidth > 0 && ts->pdata->screenHeight > 0 && + (ts->pdata->abs_x_max - ts->pdata->abs_x_min) > 0 && + (ts->pdata->abs_y_max - ts->pdata->abs_y_min) > 0) { + ts->widthFactor = (ts->pdata->screenWidth << SHIFTBITS) / (ts->pdata->abs_x_max - ts->pdata->abs_x_min); + ts->heightFactor = (ts->pdata->screenHeight << SHIFTBITS) / (ts->pdata->abs_y_max - ts->pdata->abs_y_min); + + if (ts->widthFactor > 0 && ts->heightFactor > 0) { + ts->useScreenRes = 1; + } else { + ts->heightFactor = 0; + ts->widthFactor = 0; + ts->useScreenRes = 0; + } + } else { + I("Enable finger debug with raw position mode!\n"); + } + } else { + ts->useScreenRes = 0; + ts->widthFactor = 0; + ts->heightFactor = 0; + } + + return len; } -static struct file_operations himax_proc_debug_level_ops = -{ - .owner = THIS_MODULE, - .read = himax_debug_level_read, - .write = himax_debug_level_write, +static struct file_operations himax_proc_debug_level_ops = { + .owner = THIS_MODULE, + .read = himax_debug_level_read, + .write = himax_debug_level_write, }; -#ifdef HX_TP_PROC_REGISTER static ssize_t himax_proc_register_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - int ret = 0; - uint16_t loop_i; - uint8_t data[128]; - char *temp_buf; + int ret = 0; + uint16_t loop_i; + uint8_t data[128]; + char *temp_buf; + memset(data, 0x00, sizeof(data)); - memset(data, 0x00, sizeof(data)); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + I("himax_register_show: %02X,%02X,%02X,%02X\n", register_command[3], register_command[2], register_command[1], register_command[0]); + g_core_fp.fp_register_read(register_command, 128, data, cfg_flag); + ret += snprintf(temp_buf + ret, len - ret, "command: %02X,%02X,%02X,%02X\n", register_command[3], register_command[2], register_command[1], register_command[0]); - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + for (loop_i = 0; loop_i < 128; loop_i++) { + ret += snprintf(temp_buf + ret, len - ret, "0x%2.2X ", data[loop_i]); + if ((loop_i % 16) == 15) + ret += snprintf(temp_buf + ret, len - ret, "\n"); + } - I("himax_register_show: %02X,%02X,%02X,%02X\n", register_command[3],register_command[2],register_command[1],register_command[0]); - himax_register_read(private_ts->client, register_command, 128, data, cfg_flag); + ret += snprintf(temp_buf + ret, len - ret, "\n"); - ret += snprintf(temp_buf + ret, len - ret, "command: %02X,%02X,%02X,%02X\n", register_command[3],register_command[2],register_command[1],register_command[0]); + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); - for (loop_i = 0; loop_i < 128; loop_i++) - { - ret += snprintf(temp_buf + ret, len - ret, "0x%2.2X ", data[loop_i]); - if ((loop_i % 16) == 15) - ret += snprintf(temp_buf + ret, len - ret, "\n"); - } - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } static ssize_t himax_proc_register_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - char buf[80] = {0}; - char buf_tmp[16]; - uint8_t length = 0; - unsigned long result = 0; - uint8_t loop_i = 0; - uint16_t base = 2; - char *data_str = NULL; - uint8_t w_data[20]; - uint8_t x_pos[20]; - uint8_t count = 0; + char buf[80] = {0}; + char buf_tmp[16]; + uint8_t length = 0; + unsigned long result = 0; + uint8_t loop_i = 0; + uint16_t base = 2; + char *data_str = NULL; + uint8_t w_data[20]; + uint8_t x_pos[20]; + uint8_t count = 0; - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } - memset(buf_tmp, 0x0, sizeof(buf_tmp)); - memset(w_data, 0x0, sizeof(w_data)); - memset(x_pos, 0x0, sizeof(x_pos)); - memset(register_command, 0x0, sizeof(register_command)); + memset(buf_tmp, 0x0, sizeof(buf_tmp)); + memset(w_data, 0x0, sizeof(w_data)); + memset(x_pos, 0x0, sizeof(x_pos)); + memset(register_command, 0x0, sizeof(register_command)); - I("himax %s \n",buf); + I("himax %s \n", buf); - if ((buf[0] == 'r' || buf[0] == 'w') && buf[1] == ':' && buf[2] == 'x') - { + if ((buf[0] == 'r' || buf[0] == 'w') && buf[1] == ':' && buf[2] == 'x') { + length = strlen(buf); - length = strlen(buf); + /* I("%s: length = %d.\n", __func__,length); */ + for (loop_i = 0; loop_i < length; loop_i++) { /* find postion of 'x' */ + if (buf[loop_i] == 'x') { + x_pos[count] = loop_i; + count++; + } + } - //I("%s: length = %d.\n", __func__,length); - for (loop_i = 0; loop_i < length; loop_i++) //find postion of 'x' - { - if(buf[loop_i] == 'x') - { - x_pos[count] = loop_i; - count++; - } - } + data_str = strrchr(buf, 'x'); + I("%s: %s.\n", __func__, data_str); + length = strlen(data_str + 1) - 1; - data_str = strrchr(buf, 'x'); - I("%s: %s.\n", __func__,data_str); - length = strlen(data_str+1) - 1; + if (buf[0] == 'r') { + if (buf[3] == 'F' && buf[4] == 'E' && length == 4) { + length = length - base; + cfg_flag = 1; + memcpy(buf_tmp, data_str + base + 1, length); + } else { + cfg_flag = 0; + memcpy(buf_tmp, data_str + 1, length); + } - if (buf[0] == 'r') - { - if (buf[3] == 'F' && buf[4] == 'E' && length == 4) - { - length = length - base; - cfg_flag = true; - memcpy(buf_tmp, data_str + base +1, length); - } - else - { - cfg_flag = false; - memcpy(buf_tmp, data_str + 1, length); - } + byte_length = length / 2; - byte_length = length/2; - if (!kstrtoul(buf_tmp, 16, &result)) - { - for (loop_i = 0 ; loop_i < byte_length ; loop_i++) - { - register_command[loop_i] = (uint8_t)(result >> loop_i*8); - } - } - } - else if (buf[0] == 'w') - { - if (buf[3] == 'F' && buf[4] == 'E') - { - cfg_flag = true; - memcpy(buf_tmp, buf + base + 3, length); - } - else - { - cfg_flag = false; - memcpy(buf_tmp, buf + 3, length); - } - if(count < 3) - { - byte_length = length/2; - if (!kstrtoul(buf_tmp, 16, &result)) //command - { - for (loop_i = 0 ; loop_i < byte_length ; loop_i++) - { - register_command[loop_i] = (uint8_t)(result >> loop_i*8); - } - } - if (!kstrtoul(data_str+1, 16, &result)) //data - { - for (loop_i = 0 ; loop_i < byte_length ; loop_i++) - { - w_data[loop_i] = (uint8_t)(result >> loop_i*8); - } - } - himax_register_write(private_ts->client, register_command, byte_length, w_data, cfg_flag); - } - else - { - for (loop_i = 0; loop_i < count; loop_i++) //parsing addr after 'x' - { - memset(buf_tmp, 0x0, sizeof(buf_tmp)); - if(cfg_flag != 0 && loop_i != 0) - byte_length = 2; - else - byte_length = x_pos[1] - x_pos[0] - 2; //original - memcpy(buf_tmp, buf + x_pos[loop_i] + 1, byte_length); - //I("%s: buf_tmp = %s\n", __func__,buf_tmp); - if (!kstrtoul(buf_tmp, 16, &result)) - { - if(loop_i == 0) - { - register_command[loop_i] = (uint8_t)(result); - //I("%s: register_command = %X\n", __func__,register_command[0]); - } - else - { - w_data[loop_i - 1] = (uint8_t)(result); - //I("%s: w_data[%d] = %2X\n", __func__,loop_i - 1,w_data[loop_i - 1]); - } - } - } + if (!kstrtoul(buf_tmp, 16, &result)) { + for (loop_i = 0 ; loop_i < byte_length ; loop_i++) { + register_command[loop_i] = (uint8_t)(result >> loop_i * 8); + } + } - byte_length = count - 1; - himax_register_write(private_ts->client, register_command, byte_length, &w_data[0], cfg_flag); - } - } - else - return len; + if (strcmp(HX_85XX_H_SERIES_PWON, private_ts->chip_name) == 0 && cfg_flag == 0) + cfg_flag = 2; + } else if (buf[0] == 'w') { + if (buf[3] == 'F' && buf[4] == 'E') { + cfg_flag = 1; + memcpy(buf_tmp, buf + base + 3, length); + } else { + cfg_flag = 0; + memcpy(buf_tmp, buf + 3, length); + } - } - return len; + if (count < 3) { + byte_length = length / 2; + + if (!kstrtoul(buf_tmp, 16, &result)) { /* command */ + for (loop_i = 0 ; loop_i < byte_length ; loop_i++) { + register_command[loop_i] = (uint8_t)(result >> loop_i * 8); + } + } + + if (!kstrtoul(data_str + 1, 16, &result)) { /* data */ + for (loop_i = 0 ; loop_i < byte_length ; loop_i++) { + w_data[loop_i] = (uint8_t)(result >> loop_i * 8); + } + } + + g_core_fp.fp_register_write(register_command, byte_length, w_data, cfg_flag); + } else { + for (loop_i = 0; loop_i < count; loop_i++) { /* parsing addr after 'x' */ + memset(buf_tmp, 0x0, sizeof(buf_tmp)); + if (cfg_flag != 0 && loop_i != 0) + byte_length = 2; + else + byte_length = x_pos[1] - x_pos[0] - 2; /* original */ + + memcpy(buf_tmp, buf + x_pos[loop_i] + 1, byte_length); + + /* I("%s: buf_tmp = %s\n", __func__,buf_tmp); */ + if (!kstrtoul(buf_tmp, 16, &result)) { + if (loop_i == 0) { + register_command[loop_i] = (uint8_t)(result); + /* I("%s: register_command = %X\n", __func__,register_command[0]); */ + } else { + w_data[loop_i - 1] = (uint8_t)(result); + /* I("%s: w_data[%d] = %2X\n", __func__,loop_i - 1,w_data[loop_i - 1]); */ + } + } + } + + byte_length = count - 1; + if (strcmp(HX_85XX_H_SERIES_PWON, private_ts->chip_name) == 0 && cfg_flag == 0) + cfg_flag = 2; + g_core_fp.fp_register_write(register_command, byte_length, &w_data[0], cfg_flag); + } + } else { + return len; + } + } + + return len; } -static struct file_operations himax_proc_register_ops = -{ - .owner = THIS_MODULE, - .read = himax_proc_register_read, - .write = himax_proc_register_write, +static struct file_operations himax_proc_register_ops = { + .owner = THIS_MODULE, + .read = himax_proc_register_read, + .write = himax_proc_register_write, }; -#endif -#ifdef HX_TP_PROC_DIAG int32_t *getMutualBuffer(void) { - return diag_mutual; + return diag_mutual; } int32_t *getMutualNewBuffer(void) { - return diag_mutual_new; + return diag_mutual_new; } int32_t *getMutualOldBuffer(void) { - return diag_mutual_old; + return diag_mutual_old; } int32_t *getSelfBuffer(void) { - return &diag_self[0]; + return &diag_self[0]; +} +int32_t *getSelfNewBuffer(void) +{ + return &diag_self_new[0]; +} +int32_t *getSelfOldBuffer(void) +{ + return &diag_self_old[0]; } uint8_t getXChannel(void) { - return x_channel; + return x_channel; } uint8_t getYChannel(void) { - return y_channel; -} -uint8_t getDiagCommand(void) -{ - return g_diag_command; + return y_channel; } void setXChannel(uint8_t x) { - x_channel = x; + x_channel = x; } void setYChannel(uint8_t y) { - y_channel = y; + y_channel = y; } void setMutualBuffer(void) { @@ -785,2657 +646,2074 @@ void setMutualOldBuffer(void) #ifdef HX_TP_PROC_2T2R int32_t *getMutualBuffer_2(void) { - return diag_mutual_2; + return diag_mutual_2; } uint8_t getXChannel_2(void) { - return x_channel_2; + return x_channel_2; } uint8_t getYChannel_2(void) { - return y_channel_2; + return y_channel_2; } void setXChannel_2(uint8_t x) { - x_channel_2 = x; + x_channel_2 = x; } void setYChannel_2(uint8_t y) { - y_channel_2 = y; + y_channel_2 = y; } void setMutualBuffer_2(void) { - diag_mutual_2 = kzalloc(x_channel_2 * y_channel_2 * sizeof(int32_t), GFP_KERNEL); + diag_mutual_2 = kzalloc(x_channel_2 * y_channel_2 * sizeof(int32_t), GFP_KERNEL); } #endif -#ifdef HX_TP_PROC_DIAG -int himax_set_diag_cmd(struct himax_ic_data *ic_data,struct himax_report_data *hx_touch_data) +int himax_set_diag_cmd(struct himax_ic_data *ic_data, struct himax_report_data *hx_touch_data) { + struct himax_ts_data *ts = private_ts; int32_t *mutual_data; int32_t *self_data; - int mul_num; - int self_num; - //int RawDataLen = 0; + int mul_num; + int self_num; + /* int RawDataLen = 0; */ + hx_touch_data->diag_cmd = ts->diag_cmd; + + if (hx_touch_data->diag_cmd >= 1 && hx_touch_data->diag_cmd <= 7) { + /* Check event stack CRC */ + if (!g_core_fp.fp_diag_check_sum(hx_touch_data)) { + goto bypass_checksum_failed_packet; + } - hx_touch_data->diag_cmd = getDiagCommand(); - if (hx_touch_data->diag_cmd >= 1 && hx_touch_data->diag_cmd <= 7) - { - //Check event stack CRC - if(!diag_check_sum(hx_touch_data)) - { - goto bypass_checksum_failed_packet; - } #ifdef HX_TP_PROC_2T2R - if(Is_2T2R && (hx_touch_data->diag_cmd >= 4 && hx_touch_data->diag_cmd <= 6)) - { - mutual_data = getMutualBuffer_2(); - self_data = getSelfBuffer(); - - // initiallize the block number of mutual and self - mul_num = getXChannel_2() * getYChannel_2(); - + if (Is_2T2R && (hx_touch_data->diag_cmd >= 4 && hx_touch_data->diag_cmd <= 6)) { + mutual_data = getMutualBuffer_2(); + self_data = getSelfBuffer(); + /* initiallize the block number of mutual and self */ + mul_num = getXChannel_2() * getYChannel_2(); #ifdef HX_EN_SEL_BUTTON - self_num = getXChannel_2() + getYChannel_2() + ic_data->HX_BT_NUM; + self_num = getXChannel_2() + getYChannel_2() + ic_data->HX_BT_NUM; #else - self_num = getXChannel_2() + getYChannel_2(); + self_num = getXChannel_2() + getYChannel_2(); #endif - } - else + } else #endif - { - mutual_data = getMutualBuffer(); - self_data = getSelfBuffer(); - - // initiallize the block number of mutual and self - mul_num = getXChannel() * getYChannel(); - + { + mutual_data = getMutualBuffer(); + self_data = getSelfBuffer(); + /* initiallize the block number of mutual and self */ + mul_num = getXChannel() * getYChannel(); #ifdef HX_EN_SEL_BUTTON - self_num = getXChannel() + getYChannel() + ic_data->HX_BT_NUM; + self_num = getXChannel() + getYChannel() + ic_data->HX_BT_NUM; #else - self_num = getXChannel() + getYChannel(); + self_num = getXChannel() + getYChannel(); #endif - } - - diag_parse_raw_data(hx_touch_data,mul_num, self_num,hx_touch_data->diag_cmd, mutual_data,self_data); - - } - else if (hx_touch_data->diag_cmd == 8) - { - memset(diag_coor, 0x00, sizeof(diag_coor)); - memcpy(&(diag_coor[0]), &hx_touch_data->hx_coord_buf[0], hx_touch_data->touch_info_size); - } - //assign state info data - memcpy(&(hx_state_info[0]), &hx_touch_data->hx_state_info[0], 2); - - return NO_ERR; + } + g_core_fp.fp_diag_parse_raw_data(hx_touch_data, mul_num, self_num, hx_touch_data->diag_cmd, mutual_data, self_data); + } else if (hx_touch_data->diag_cmd == 8) { + memset(diag_coor, 0x00, sizeof(diag_coor)); + memcpy(&(diag_coor[0]), &hx_touch_data->hx_coord_buf[0], hx_touch_data->touch_info_size); + } + /* assign state info data */ + memcpy(&(hx_state_info[0]), &hx_touch_data->hx_state_info[0], 2); + return NO_ERR; bypass_checksum_failed_packet: - return 1; + return 1; } -#endif -//#if defined(HX_DEBUG_LEVEL) -void himax_log_touch_data(uint8_t *buf,struct himax_report_data *hx_touch_data) + +/* #if defined(HX_DEBUG_LEVEL) */ +extern struct himax_target_report_data *g_target_report_data; +extern struct himax_report_data *hx_touch_data; +void himax_log_touch_data(int start) { - int loop_i = 0; - int print_size = 0; + int loop_i = 0; + int print_size = 0; + uint8_t *buf; - if(!hx_touch_data->diag_cmd) - print_size = hx_touch_data->touch_info_size; - else - print_size = hx_touch_data->touch_all_size; + if (start == 1) + return; /* report data when end of ts_work*/ - for (loop_i = 0; loop_i < print_size; loop_i+=8) - { - if((loop_i + 7) >= print_size) - { - I("%s: over flow\n",__func__); - break; - } - I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i, buf[loop_i], loop_i + 1, buf[loop_i + 1]); - I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 2, buf[loop_i + 2], loop_i + 3, buf[loop_i + 3]); - I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 4, buf[loop_i + 4], loop_i + 5, buf[loop_i + 5]); - I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 6, buf[loop_i + 6], loop_i + 7, buf[loop_i + 7]); - I("\n"); - } + if (hx_touch_data->diag_cmd == 0) { + print_size = hx_touch_data->touch_info_size; + buf = kzalloc(hx_touch_data->touch_info_size*sizeof(uint8_t), GFP_KERNEL); + memcpy(buf, hx_touch_data->hx_coord_buf, hx_touch_data->touch_info_size); + } else if (hx_touch_data->diag_cmd > 0) { + print_size = hx_touch_data->touch_all_size; + buf = kzalloc(hx_touch_data->touch_info_size*sizeof(uint8_t), GFP_KERNEL); + memcpy(buf, hx_touch_data->hx_coord_buf, hx_touch_data->touch_info_size); + memcpy(&buf[hx_touch_data->touch_info_size], hx_touch_data->hx_rawdata_buf, hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); + } else { + E("%s:cmd fault\n", __func__); + } + + for (loop_i = 0; loop_i < print_size; loop_i += 8) { + if ((loop_i + 7) >= print_size) { + I("%s: over flow\n", __func__); + break; + } + + I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i, buf[loop_i], loop_i + 1, buf[loop_i + 1]); + I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 2, buf[loop_i + 2], loop_i + 3, buf[loop_i + 3]); + I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 4, buf[loop_i + 4], loop_i + 5, buf[loop_i + 5]); + I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 6, buf[loop_i + 6], loop_i + 7, buf[loop_i + 7]); + I("\n"); + } + kfree(buf); } -void himax_log_touch_event(int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched) +void himax_log_touch_event(struct himax_ts_data *ts, int start) { - if(touched == HX_FINGER_ON) - I("Finger %d=> X:%d, Y:%d W:%d, Z:%d, F:%d, N:%d\n",loop_i + 1, x, y, w, w, loop_i + 1, EN_NoiseFilter); - else if(touched == HX_FINGER_LEAVE) - I("All Finger leave\n"); - else - I("%s : wrong input!\n",__func__); + int loop_i = 0; + if (g_target_report_data->finger_on > 0 && g_target_report_data->finger_num > 0) { + for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) { + if (g_target_report_data->x[loop_i] >= 0 && g_target_report_data->x[loop_i] <= ts->pdata->abs_x_max && g_target_report_data->y[loop_i] >= 0 && g_target_report_data->y[loop_i] <= ts->pdata->abs_y_max) { + I("Finger %d=> X:%d, Y:%d W:%d, Z:%d, F:%d\n", loop_i + 1, + g_target_report_data->x[loop_i], + g_target_report_data->y[loop_i], + g_target_report_data->w[loop_i], + g_target_report_data->w[loop_i], + loop_i + 1); + } + } + } else if (g_target_report_data->finger_on == 0 && g_target_report_data->finger_num == 0) { + I("All Finger leave\n"); + } else { + I("%s : wrong input!\n", __func__); + } } void himax_log_touch_int_devation(int touched) { - - - if(touched == HX_FINGER_ON) - { - getnstimeofday(&timeStart); - /* I(" Irq start time = %ld.%06ld s\n", - timeStart.tv_sec, timeStart.tv_nsec/1000); */ - } - else if(touched == HX_FINGER_LEAVE) - { - getnstimeofday(&timeEnd); - timeDelta.tv_nsec = (timeEnd.tv_sec*1000000000+timeEnd.tv_nsec) - (timeStart.tv_sec*1000000000+timeStart.tv_nsec); - /*I("Irq finish time = %ld.%06ld s\n", - timeEnd.tv_sec, timeEnd.tv_nsec/1000);*/ - I("Touch latency = %ld us\n", timeDelta.tv_nsec/1000); - } - else - I("%s : wrong input!\n",__func__); + if (touched == HX_FINGER_ON) { + getnstimeofday(&timeStart); + /* I(" Irq start time = %ld.%06ld s\n", + timeStart.tv_sec, timeStart.tv_nsec/1000); */ + } else if (touched == HX_FINGER_LEAVE) { + getnstimeofday(&timeEnd); + timeDelta.tv_nsec = (timeEnd.tv_sec * 1000000000 + timeEnd.tv_nsec) - (timeStart.tv_sec * 1000000000 + timeStart.tv_nsec); + /* I("Irq finish time = %ld.%06ld s\n", + timeEnd.tv_sec, timeEnd.tv_nsec/1000);*/ + I("Touch latency = %ld us\n", timeDelta.tv_nsec / 1000); + } else { + I("%s : wrong input!\n", __func__); + } } -void himax_log_touch_event_detail(struct himax_ts_data *ts,int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched,uint16_t old_finger) +void himax_log_touch_event_detail(struct himax_ts_data *ts, int start) { + int loop_i = 0; - if (touched == HX_FINGER_ON) - { - if (old_finger >> loop_i == 0) - { - if (ts->useScreenRes) - { - I("status: Screen:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n", - loop_i+1, x * ts->widthFactor >> SHIFTBITS, - y * ts->heightFactor >> SHIFTBITS, w, EN_NoiseFilter); - } - else - { - I("status: Raw:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n", - loop_i+1, x, y, w, EN_NoiseFilter); - } - } - } - else if(touched == HX_FINGER_LEAVE)//if (old_finger >> loop_i == 1) - { - if (old_finger >> loop_i == 1) - { - if (ts->useScreenRes) - { - I("status: Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", - loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS, - ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, EN_NoiseFilter); //Last_EN_NoiseFilter - } - else - { - I("status: Raw:F:%02d Up, X:%d, Y:%d, N:%d\n", - loop_i+1, ts->pre_finger_data[loop_i][0], - ts->pre_finger_data[loop_i][1], EN_NoiseFilter); //Last_EN_NoiseFilter - } - } - } - else - { - I("%s : wrong input!\n",__func__); - } + if (start == HX_FINGER_LEAVE) { + for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) { + if (((ts->old_finger >> loop_i & 1) == 0) && ((ts->pre_finger_mask >> loop_i & 1) == 1)) { + if (g_target_report_data->x[loop_i] >= 0 && g_target_report_data->x[loop_i] <= ts->pdata->abs_x_max && g_target_report_data->y[loop_i] >= 0 && g_target_report_data->y[loop_i] <= ts->pdata->abs_y_max) { + I("status: Raw:F:%02d Down, X:%d, Y:%d, W:%d\n", loop_i + 1, g_target_report_data->x[loop_i], g_target_report_data->y[loop_i], g_target_report_data->w[loop_i]); + } + } else if ((((ts->old_finger >> loop_i & 1) == 1) && ((ts->pre_finger_mask >> loop_i & 1) == 0))) { + I("status: Raw:F:%02d Up, X:%d, Y:%d\n", loop_i + 1, ts->pre_finger_data[loop_i][0], ts->pre_finger_data[loop_i][1]); + } else { + /* I("dbg hx_point_num=%d,old_finger=0x%02X,pre_finger_mask=0x%02X\n",ts->hx_point_num,ts->old_finger,ts->pre_finger_mask);*/ + } + } + } } -//#endif + +void himax_ts_dbg_func(struct himax_ts_data *ts, int start) +{ + switch (ts->debug_log_level) { + case 1: + himax_log_touch_data(start); + break; + case 2: + himax_log_touch_event(ts, start); + break; + case 4: + himax_log_touch_int_devation(start); + break; + case 8: + himax_log_touch_event_detail(ts, start); + break; + } +} + +/* #endif */ static ssize_t himax_diag_arrange_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { + char buf[80] = {0}; - char buf[80] = {0}; + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } - g_diag_arr_num = buf[0] - '0'; - I("%s: g_diag_arr_num = %d \n", __func__,g_diag_arr_num); - - return len; + g_diag_arr_num = buf[0] - '0'; + I("%s: g_diag_arr_num = %d \n", __func__, g_diag_arr_num); + return len; } void himax_get_mutual_edge(void) { - int i = 0; - for(i = 0; i < (x_channel * y_channel); i++) - { - if(diag_mutual[i] > g_max_mutual) - g_max_mutual = diag_mutual[i]; - if(diag_mutual[i] < g_min_mutual) - g_min_mutual = diag_mutual[i]; - } + int i = 0; + + for (i = 0; i < (x_channel * y_channel); i++) { + if (diag_mutual[i] > g_max_mutual) + g_max_mutual = diag_mutual[i]; + + if (diag_mutual[i] < g_min_mutual) + g_min_mutual = diag_mutual[i]; + } } void himax_get_self_edge(void) { - int i = 0; - for(i = 0; i < (x_channel + y_channel); i++) - { - if(diag_self[i] > g_max_self) - g_max_self = diag_self[i]; - if(diag_self[i] < g_min_self) - g_min_self = diag_self[i]; - } + int i = 0; + + for (i = 0; i < (x_channel + y_channel); i++) { + if (diag_self[i] > g_max_self) + g_max_self = diag_self[i]; + + if (diag_self[i] < g_min_self) + g_min_self = diag_self[i]; + } } /* print first step which is row */ -static struct file_operations himax_proc_diag_arrange_ops = -{ - .owner = THIS_MODULE, - .write = himax_diag_arrange_write, +static struct file_operations himax_proc_diag_arrange_ops = { + .owner = THIS_MODULE, + .write = himax_diag_arrange_write, }; static void print_state_info(struct seq_file *s) { - //seq_printf(s, "State_info_2bytes:%3d, %3d\n",hx_state_info[0],hx_state_info[1]); - seq_printf(s, "ReCal = %d\t",hx_state_info[0] & 0x01); - seq_printf(s, "Palm = %d\t",hx_state_info[0]>>1 & 0x01); - seq_printf(s, "AC mode = %d\t",hx_state_info[0]>>2 & 0x01); - seq_printf(s, "Water = %d\n",hx_state_info[0]>>3 & 0x01); - seq_printf(s, "Glove = %d\t",hx_state_info[0]>>4 & 0x01); - seq_printf(s, "TX Hop = %d\t",hx_state_info[0]>>5 & 0x01 ); - seq_printf(s, "Base Line = %d\t",hx_state_info[0]>>6 & 0x01); - seq_printf(s, "OSR Hop = %d\t",hx_state_info[1]>>3 & 0x01); - seq_printf(s, "KEY = %d\n",hx_state_info[1]>>4 & 0x0F); + /* seq_printf(s, "State_info_2bytes:%3d, %3d\n",hx_state_info[0],hx_state_info[1]); */ + seq_printf(s, "ReCal = %d\t", hx_state_info[0] & 0x01); + seq_printf(s, "Palm = %d\t", hx_state_info[0] >> 1 & 0x01); + seq_printf(s, "AC mode = %d\t", hx_state_info[0] >> 2 & 0x01); + seq_printf(s, "Water = %d\n", hx_state_info[0] >> 3 & 0x01); + seq_printf(s, "Glove = %d\t", hx_state_info[0] >> 4 & 0x01); + seq_printf(s, "TX Hop = %d\t", hx_state_info[0] >> 5 & 0x01); + seq_printf(s, "Base Line = %d\t", hx_state_info[0] >> 6 & 0x01); + seq_printf(s, "OSR Hop = %d\t", hx_state_info[1] >> 3 & 0x01); + seq_printf(s, "KEY = %d\n", hx_state_info[1] >> 4 & 0x0F); } static void himax_diag_arrange_print(struct seq_file *s, int i, int j, int transpose) { - - if(transpose) - seq_printf(s, "%6d", diag_mutual[ j + i*x_channel]); - else - seq_printf(s, "%6d", diag_mutual[ i + j*x_channel]); + if (transpose) + seq_printf(s, "%6d", diag_mutual[j + i * x_channel]); + else + seq_printf(s, "%6d", diag_mutual[i + j * x_channel]); } /* ready to print second step which is column*/ -static void himax_diag_arrange_inloop(struct seq_file *s, int in_init,int out_init,bool transpose, int j) +static void himax_diag_arrange_inloop(struct seq_file *s, int in_init, int out_init, bool transpose, int j) { - int i; - int in_max = 0; + int i; + int in_max = 0; - if(transpose) - in_max = y_channel; - else - in_max = x_channel; + if (transpose) + in_max = y_channel; + else + in_max = x_channel; - if (in_init > 0) //bit0 = 1 - { - for(i = in_init-1; i >= 0; i--) - { - himax_diag_arrange_print(s, i, j, transpose); - } - if(transpose) - { - if(out_init > 0) - seq_printf(s, " %5d\n", diag_self[j]); - else - seq_printf(s, " %5d\n", diag_self[x_channel - j - 1]); - } - } - else //bit0 = 0 - { - for (i = 0; i < in_max; i++) - { - himax_diag_arrange_print(s, i, j, transpose); - } - if(transpose) - { - if(out_init > 0) - seq_printf(s, " %5d\n", diag_self[x_channel - j - 1]); - else - seq_printf(s, " %5d\n", diag_self[j]); - } - } + if (in_init > 0) { /* bit0 = 1 */ + for (i = in_init - 1; i >= 0; i--) { + himax_diag_arrange_print(s, i, j, transpose); + } + + if (transpose) { + if (out_init > 0) + seq_printf(s, " %5d\n", diag_self[j]); + else + seq_printf(s, " %5d\n", diag_self[x_channel - j - 1]); + } + } else { /* bit0 = 0 */ + for (i = 0; i < in_max; i++) { + himax_diag_arrange_print(s, i, j, transpose); + } + + if (transpose) { + if (out_init > 0) + seq_printf(s, " %5d\n", diag_self[x_channel - j - 1]); + else + seq_printf(s, " %5d\n", diag_self[j]); + } + } } /* print first step which is row */ static void himax_diag_arrange_outloop(struct seq_file *s, int transpose, int out_init, int in_init) { - int j; - int out_max = 0; - int self_cnt = 0; + int j; + int out_max = 0; + int self_cnt = 0; - if(transpose) - out_max = x_channel; - else - out_max = y_channel; + if (transpose) + out_max = x_channel; + else + out_max = y_channel; - if(out_init > 0) //bit1 = 1 - { - self_cnt = 1; - for(j = out_init-1; j >= 0; j--) - { - seq_printf(s, "%3c%02d%c",'[', j + 1,']'); - himax_diag_arrange_inloop(s, in_init, out_init, transpose, j); - if(!transpose) - { - seq_printf(s, " %5d\n", diag_self[y_channel + x_channel - self_cnt]); - self_cnt++; - } - } - } - else //bit1 = 0 - { - //self_cnt = x_channel; - for(j = 0; j < out_max; j++) - { - seq_printf(s, "%3c%02d%c",'[', j + 1,']'); - himax_diag_arrange_inloop(s, in_init, out_init, transpose, j); - if(!transpose) - { - seq_printf(s, " %5d\n", diag_self[j + x_channel]); - } - } - } + if (out_init > 0) { /* bit1 = 1 */ + self_cnt = 1; + + for (j = out_init - 1; j >= 0; j--) { + seq_printf(s, "%3c%02d%c", '[', j + 1, ']'); + himax_diag_arrange_inloop(s, in_init, out_init, transpose, j); + + if (!transpose) { + seq_printf(s, " %5d\n", diag_self[y_channel + x_channel - self_cnt]); + self_cnt++; + } + } + } else { /* bit1 = 0 */ + /* self_cnt = x_channel; */ + for (j = 0; j < out_max; j++) { + seq_printf(s, "%3c%02d%c", '[', j + 1, ']'); + himax_diag_arrange_inloop(s, in_init, out_init, transpose, j); + + if (!transpose) { + seq_printf(s, " %5d\n", diag_self[j + x_channel]); + } + } + } } /* determin the output format of diag */ static void himax_diag_arrange(struct seq_file *s) { - int bit2,bit1,bit0; - int i; + int bit2, bit1, bit0; + int i; + /* rotate bit */ + bit2 = g_diag_arr_num >> 2; + /* reverse Y */ + bit1 = g_diag_arr_num >> 1 & 0x1; + /* reverse X */ + bit0 = g_diag_arr_num & 0x1; - /* rotate bit */ - bit2 = g_diag_arr_num >> 2; - /* reverse Y */ - bit1 = g_diag_arr_num >> 1 & 0x1; - /* reverse X */ - bit0 = g_diag_arr_num & 0x1; + if (g_diag_arr_num < 4) { + for (i = 0 ; i <= x_channel; i++) + seq_printf(s, "%3c%02d%c", '[', i, ']'); - if (g_diag_arr_num < 4) - { - for (i = 0 ; i <= x_channel; i++) - seq_printf(s, "%3c%02d%c",'[', i,']'); - seq_printf(s,"\n"); - himax_diag_arrange_outloop(s, bit2, bit1 * y_channel, bit0 * x_channel); - seq_printf(s, "%6c",' '); - if(bit0 == 1) - { - for (i = x_channel - 1; i >= 0; i--) - seq_printf(s, "%6d", diag_self[i]); - } - else - { - for (i = 0; i < x_channel; i++) - seq_printf(s, "%6d", diag_self[i]); - } - } - else - { - for (i = 0 ; i <= y_channel; i++) - seq_printf(s, "%3c%02d%c",'[', i,']'); - seq_printf(s,"\n"); - himax_diag_arrange_outloop(s, bit2, bit1 * x_channel, bit0 * y_channel); - seq_printf(s, "%6c",' '); - if(bit1 == 1) - { - for (i = x_channel + y_channel - 1; i >= x_channel; i--) - { - seq_printf(s, "%6d", diag_self[i]); - } - } - else - { - for (i = x_channel; i < x_channel + y_channel; i++) - { - seq_printf(s, "%6d", diag_self[i]); - } - } - } + seq_printf(s, "\n"); + himax_diag_arrange_outloop(s, bit2, bit1 * y_channel, bit0 * x_channel); + seq_printf(s, "%6c", ' '); + + if (bit0 == 1) { + for (i = x_channel - 1; i >= 0; i--) + seq_printf(s, "%6d", diag_self[i]); + } else { + for (i = 0; i < x_channel; i++) + seq_printf(s, "%6d", diag_self[i]); + } + } else { + for (i = 0 ; i <= y_channel; i++) + seq_printf(s, "%3c%02d%c", '[', i, ']'); + + seq_printf(s, "\n"); + himax_diag_arrange_outloop(s, bit2, bit1 * x_channel, bit0 * y_channel); + seq_printf(s, "%6c", ' '); + + if (bit1 == 1) { + for (i = x_channel + y_channel - 1; i >= x_channel; i--) { + seq_printf(s, "%6d", diag_self[i]); + } + } else { + for (i = x_channel; i < x_channel + y_channel; i++) { + seq_printf(s, "%6d", diag_self[i]); + } + } + } } static void *himax_diag_seq_start(struct seq_file *s, loff_t *pos) { - if (*pos>=1) return NULL; - return (void *)((unsigned long) *pos+1); + if (*pos >= 1) { + return NULL; + } + return (void *)((unsigned long) *pos + 1); } static void *himax_diag_seq_next(struct seq_file *s, void *v, loff_t *pos) { - return NULL; + return NULL; } + static void himax_diag_seq_stop(struct seq_file *s, void *v) { } + static int himax_diag_seq_read(struct seq_file *s, void *v) { - size_t ret = 0; - uint32_t loop_i; - uint16_t mutual_num, self_num, width; - int dsram_type = 0; - - dsram_type = g_diag_command/10; + struct himax_ts_data *ts = private_ts; + size_t ret = 0; + uint32_t loop_i; + uint16_t mutual_num, self_num, width; + int dsram_type = 0; + dsram_type = ts->diag_cmd / 10; #ifdef HX_TP_PROC_2T2R - if(Is_2T2R &&(g_diag_command >= 4 && g_diag_command <= 6)) - { - mutual_num = x_channel_2 * y_channel_2; - self_num = x_channel_2 + y_channel_2; //don't add KEY_COUNT - width = x_channel_2; - seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel_2, y_channel_2); - } - else + if (Is_2T2R && (ts->diag_cmd >= 4 && ts->diag_cmd <= 6)) { + mutual_num = x_channel_2 * y_channel_2; + self_num = x_channel_2 + y_channel_2; /* don't add KEY_COUNT */ + width = x_channel_2; + seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel_2, y_channel_2); + } else #endif - { - mutual_num = x_channel * y_channel; - self_num = x_channel + y_channel; //don't add KEY_COUNT - width = x_channel; - seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel, y_channel); - } + { + mutual_num = x_channel * y_channel; + self_num = x_channel + y_channel; /* don't add KEY_COUNT */ + width = x_channel; + seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel, y_channel); + } - // start to show out the raw data in adb shell - if ((g_diag_command >= 1 && g_diag_command <= 3) || (g_diag_command == 7)) - { - himax_diag_arrange(s); - seq_printf(s, "\n"); + /* start to show out the raw data in adb shell */ + if ((ts->diag_cmd >= 1 && ts->diag_cmd <= 3) || (ts->diag_cmd == 7)) { + himax_diag_arrange(s); + seq_printf(s, "\n"); #ifdef HX_EN_SEL_BUTTON - seq_printf(s, "\n"); - for (loop_i = 0; loop_i < ic_data->HX_BT_NUM; loop_i++) - seq_printf(s, "%6d", diag_self[ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + loop_i]); + seq_printf(s, "\n"); + + for (loop_i = 0; loop_i < ic_data->HX_BT_NUM; loop_i++) + seq_printf(s, "%6d", diag_self[ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + loop_i]); + #endif - seq_printf(s, "ChannelEnd"); - seq_printf(s, "\n"); - } + seq_printf(s, "ChannelEnd"); + seq_printf(s, "\n"); #ifdef HX_TP_PROC_2T2R - else if(Is_2T2R && g_diag_command >= 4 && g_diag_command <= 6) - { - for (loop_i = 0; loop_i < mutual_num; loop_i++) - { - seq_printf(s, "%4d", diag_mutual_2[loop_i]); - if ((loop_i % width) == (width - 1)) - seq_printf(s, " %4d\n", diag_self[width + loop_i/width]); - } - seq_printf(s, "\n"); - for (loop_i = 0; loop_i < width; loop_i++) - { - seq_printf(s, "%4d", diag_self[loop_i]); - if (((loop_i) % width) == (width - 1)) - seq_printf(s, "\n"); - } + } else if (Is_2T2R && ts->diag_cmd >= 4 && ts->diag_cmd <= 6) { + for (loop_i = 0; loop_i < mutual_num; loop_i++) { + seq_printf(s, "%4d", diag_mutual_2[loop_i]); + + if ((loop_i % width) == (width - 1)) + seq_printf(s, " %4d\n", diag_self[width + loop_i / width]); + } + + seq_printf(s, "\n"); + + for (loop_i = 0; loop_i < width; loop_i++) { + seq_printf(s, "%4d", diag_self[loop_i]); + + if (((loop_i) % width) == (width - 1)) + seq_printf(s, "\n"); + } #ifdef HX_EN_SEL_BUTTON - seq_printf(s, "\n"); - for (loop_i = 0; loop_i < HX_BT_NUM; loop_i++) - seq_printf(s, "%4d", diag_self[ic_data->HX_RX_NUM_2 + ic_data->HX_TX_NUM_2 + loop_i]); -#endif - seq_printf(s, "ChannelEnd"); - seq_printf(s, "\n"); - } -#endif - else if (g_diag_command == 8) - { - for (loop_i = 0; loop_i < 128 ; loop_i++) - { - if ((loop_i % 16) == 0) - seq_printf(s, "LineStart:"); - seq_printf(s, "%4x", diag_coor[loop_i]); - if ((loop_i % 16) == 15) - seq_printf(s, "\n"); - } - } - else if (dsram_type > 0 && dsram_type <= 8) - { - himax_diag_arrange(s); - seq_printf(s, "ChannelEnd"); - seq_printf(s, "\n"); - } - if((g_diag_command >= 1 && g_diag_command <= 7) || dsram_type > 0) - { - /* print Mutual/Slef Maximum and Minimum */ - himax_get_mutual_edge(); - himax_get_self_edge(); - seq_printf(s, "Mutual Max:%3d, Min:%3d\n",g_max_mutual,g_min_mutual); - seq_printf(s, "Self Max:%3d, Min:%3d\n",g_max_self,g_min_self); + seq_printf(s, "\n"); - /* recovery status after print*/ - g_max_mutual = 0; - g_min_mutual = 255; - g_max_self = 0; - g_min_self = 255; - } - /*pring state info*/ - print_state_info(s); - return ret; + for (loop_i = 0; loop_i < ic_data->HX_BT_NUM; loop_i++) + seq_printf(s, "%4d", diag_self[ic_data->HX_RX_NUM_2 + ic_data->HX_TX_NUM_2 + loop_i]); + +#endif + seq_printf(s, "ChannelEnd"); + seq_printf(s, "\n"); +#endif + } else if (ts->diag_cmd == 8) { + for (loop_i = 0; loop_i < 128 ; loop_i++) { + if ((loop_i % 16) == 0) + seq_printf(s, "LineStart:"); + + seq_printf(s, "%4x", diag_coor[loop_i]); + + if ((loop_i % 16) == 15) + seq_printf(s, "\n"); + } + } else if (dsram_type > 0 && dsram_type <= 8) { + himax_diag_arrange(s); + seq_printf(s, "\n ChannelEnd"); + seq_printf(s, "\n"); + } + + if ((ts->diag_cmd >= 1 && ts->diag_cmd <= 7) || dsram_type > 0) { + /* print Mutual/Slef Maximum and Minimum */ + himax_get_mutual_edge(); + himax_get_self_edge(); + seq_printf(s, "Mutual Max:%3d, Min:%3d\n", g_max_mutual, g_min_mutual); + seq_printf(s, "Self Max:%3d, Min:%3d\n", g_max_self, g_min_self); + /* recovery status after print*/ + g_max_mutual = 0; + g_min_mutual = 0xFFFF; + g_max_self = 0; + g_min_self = 0xFFFF; + } + + /*pring state info*/ + print_state_info(s); + return ret; } -static struct seq_operations himax_diag_seq_ops = -{ - .start = himax_diag_seq_start, - .next = himax_diag_seq_next, - .stop = himax_diag_seq_stop, - .show = himax_diag_seq_read, +static struct seq_operations himax_diag_seq_ops = { + .start = himax_diag_seq_start, + .next = himax_diag_seq_next, + .stop = himax_diag_seq_stop, + .show = himax_diag_seq_read, }; static int himax_diag_proc_open(struct inode *inode, struct file *file) { - return seq_open(file, &himax_diag_seq_ops); + return seq_open(file, &himax_diag_seq_ops); }; bool DSRAM_Flag = false; -//DSRAM thread -void himax_ts_diag_func(void) +/* DSRAM thread */ +bool himax_ts_diag_func(void) { - int i=0, j=0; - unsigned int index = 0; - int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2; - uint8_t info_data[total_size]; + struct himax_ts_data *ts = private_ts; + int i = 0, j = 0; + unsigned int index = 0; + int total_size = (y_channel * x_channel + y_channel + x_channel) * 2; + uint8_t *info_data; int32_t *mutual_data; int32_t *mutual_data_new; int32_t *mutual_data_old; + int32_t *self_data; + int32_t *self_data_new; + int32_t *self_data_old; int32_t new_data; - /* 1:common dsram,2:100 frame Max,3:N-(N-1)frame */ - int dsram_type = 0; - char temp_buf[20]; - char write_buf[total_size*3]; + /* 1:common dsram,2:100 frame Max,3:N-(N-1)frame */ + int dsram_type = 0; + char temp_buf[20]; + char write_buf[total_size * 3]; - mutual_data = NULL; - mutual_data_new = NULL; - mutual_data_old = NULL; - memset(write_buf, '\0', sizeof(write_buf)); + mutual_data = NULL; + mutual_data_new = NULL; + mutual_data_old = NULL; + self_data = NULL; + self_data_new = NULL; + self_data_old = NULL; - dsram_type = g_diag_command/10; + info_data = kzalloc(total_size * sizeof(uint8_t), GFP_KERNEL); + if (info_data == NULL) + return false; - I("%s:Entering g_diag_command=%d\n!",__func__,g_diag_command); + memset(write_buf, '\0', sizeof(write_buf)); + memset(info_data, 0, total_size * sizeof(uint8_t)); + dsram_type = ts->diag_cmd / 10; + I("%s:Entering ts->diag_cmd=%d!\n", __func__, ts->diag_cmd); - if(dsram_type == 8) - { - dsram_type = 1; - I("%s Sorting Mode run sram type1 ! \n",__func__); - } + if (dsram_type == 8) { + dsram_type = 1; + I("%s Sorting Mode run sram type1 ! \n", __func__); + } - himax_burst_enable(private_ts->client, 1); - if(dsram_type == 1 || dsram_type == 2 || dsram_type == 4) - { - mutual_data = getMutualBuffer(); - } - else if(dsram_type == 3) - { - mutual_data = getMutualBuffer(); - mutual_data_new = getMutualNewBuffer(); - mutual_data_old = getMutualOldBuffer(); - } - himax_get_DSRAM_data(private_ts->client, info_data); + g_core_fp.fp_burst_enable(1); - index = 0; - for (i = 0; i < ic_data->HX_TX_NUM; i++) - { - for (j = 0; j < ic_data->HX_RX_NUM; j++) - { - new_data = (((int8_t)info_data[index + 1]) << 8 | info_data[index]); - if(dsram_type == 1 || dsram_type == 4) - { - mutual_data[i*ic_data->HX_RX_NUM+j] = new_data; - } - else if(dsram_type == 2) - { - //Keep max data - if(mutual_data[i * ic_data->HX_RX_NUM + j] < new_data) - mutual_data[i * ic_data->HX_RX_NUM + j] = new_data; - } - else if(dsram_type == 3) - { - //Cal data for [N]-[N-1] frame - mutual_data_new[i * ic_data->HX_RX_NUM + j] = new_data; - mutual_data[i * ic_data->HX_RX_NUM + j] = mutual_data_new[i * ic_data->HX_RX_NUM + j] - mutual_data_old[i * ic_data->HX_RX_NUM + j]; - } - index += 2; - } - } - if(dsram_type == 3) - { - memcpy(mutual_data_old,mutual_data_new,x_channel * y_channel * sizeof(int16_t)); //copy N data to N-1 array - } - diag_max_cnt++; - if(dsram_type >= 1 && dsram_type <= 3) - { - queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ); - } - else if(dsram_type == 4) - { - for(i = 0; i < x_channel * y_channel; i++) - { - memset(temp_buf, '\0', sizeof(temp_buf)); - if(i == (x_channel * y_channel - 1)) - snprintf(temp_buf, sizeof(temp_buf), "%4d\n\n", mutual_data[i]); - //I("%s :temp_buf = %s\n",__func__,temp_buf); - else if(i % x_channel == (x_channel - 1)) - snprintf(temp_buf, sizeof(temp_buf), "%4d\n", mutual_data[i]); - else - snprintf(temp_buf, sizeof(temp_buf), "%4d\t", mutual_data[i]); - //I("%s :mutual_data[%d] = %d, temp_buf = %s\n",__func__, i, mutual_data[i], temp_buf); - strcat(write_buf, temp_buf); - } + if (dsram_type == 1 || dsram_type == 2 || dsram_type == 4) { + mutual_data = getMutualBuffer(); + self_data = getSelfBuffer(); + } else if (dsram_type == 3) { + mutual_data = getMutualBuffer(); + mutual_data_new = getMutualNewBuffer(); + mutual_data_old = getMutualOldBuffer(); + self_data = getSelfBuffer(); + self_data_new = getSelfNewBuffer(); + self_data_old = getSelfOldBuffer(); + } - //save raw data in file - if (!IS_ERR(diag_sram_fn)) - { - I("%s create file and ready to write\n",__func__); - diag_sram_fn->f_op->write(diag_sram_fn, write_buf, sizeof(write_buf), &diag_sram_fn->f_pos); - write_counter++; - if(write_counter < write_max_count) - queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ); - else - { - filp_close(diag_sram_fn,NULL); - write_counter = 0; - } - } - } + if (g_core_fp.fp_get_DSRAM_data(info_data, DSRAM_Flag) == false) + return false; + + index = 0; + + for (i = 0; i < y_channel; i++) { /*mutual data*/ + for (j = 0; j < x_channel; j++) { + new_data = (((int8_t)info_data[index + 1] << 8) | info_data[index]); + + if (dsram_type == 1 || dsram_type == 4) { + mutual_data[i * x_channel + j] = new_data; + } else if (dsram_type == 2) { /* Keep max data */ + if (mutual_data[i * x_channel + j] < new_data) + mutual_data[i * x_channel + j] = new_data; + } else if (dsram_type == 3) { /* Cal data for [N]-[N-1] frame */ + mutual_data_new[i * x_channel + j] = new_data; + mutual_data[i * x_channel + j] = mutual_data_new[i * x_channel + j] - mutual_data_old[i * x_channel + j]; + } + index += 2; + } + } + + for (i = 0; i < x_channel + y_channel; i++) { /*self data*/ + new_data = (info_data[index + 1] << 8 | info_data[index]); + if (dsram_type == 1 || dsram_type == 4) { + self_data[i] = new_data; + } else if (dsram_type == 2) { /* Keep max data */ + if (self_data[i] < new_data) + self_data[i] = new_data; + } else if (dsram_type == 3) { /* Cal data for [N]-[N-1] frame */ + self_data_new[i] = new_data; + self_data[i] = self_data_new[i] - self_data_old[i]; + } + index += 2; + } + + kfree(info_data); + + if (dsram_type == 3) { + memcpy(mutual_data_old, mutual_data_new, x_channel * y_channel * sizeof(int32_t)); /* copy N data to N-1 array */ + memcpy(self_data_old, self_data_new, (x_channel + y_channel) * sizeof(int32_t)); /* copy N data to N-1 array */ + } + + diag_max_cnt++; + + if (dsram_type >= 1 && dsram_type <= 3) { + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1 / 10 * HZ); + } else if (dsram_type == 4) { + for (i = 0; i < x_channel * y_channel; i++) { + memset(temp_buf, '\0', sizeof(temp_buf)); + + if (i == (x_channel * y_channel - 1)) { + snprintf(temp_buf, sizeof(temp_buf), "%4d\t", mutual_data[i]); + snprintf(temp_buf, sizeof(temp_buf), "%4d\n", self_data[x_channel + y_channel - 1]); + I("%s :i = %d 3\n", __func__, i); + } else if (i % x_channel == (x_channel - 1)) { + snprintf(temp_buf, sizeof(temp_buf), "%4d\t", mutual_data[i]); + snprintf(temp_buf, sizeof(temp_buf), "%4d\n", self_data[x_channel + (i / x_channel) + 1]); + } else { + snprintf(temp_buf, sizeof(temp_buf), "%4d\t", mutual_data[i]); + } + strlcat(&write_buf[i*strlen(temp_buf)], temp_buf, strlen(temp_buf)); + } + + for (i = 0; i < x_channel; i++) { + memset(temp_buf, '\0', sizeof(temp_buf)); + if (i == x_channel - 1) + snprintf(temp_buf, sizeof(temp_buf), "%4d\n", self_data[i]); + else + snprintf(temp_buf, sizeof(temp_buf), "%4d\t", self_data[i]); + strlcat(&write_buf[(i+x_channel * y_channel)*strlen(temp_buf)], temp_buf, strlen(temp_buf)); + } + + /* save raw data in file */ + if (!IS_ERR(diag_sram_fn)) { + I("%s create file and ready to write\n", __func__); + diag_sram_fn->f_op->write(diag_sram_fn, write_buf, sizeof(write_buf), &diag_sram_fn->f_pos); + write_counter++; + + if (write_counter < write_max_count) { + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1 / 10 * HZ); + } else { + filp_close(diag_sram_fn, NULL); + write_counter = 0; + } + } + } + return true; } static ssize_t himax_diag_write(struct file *filp, const char __user *buff, size_t len, loff_t *data) { - char messages[80] = {0}; - uint8_t command[2] = {0x00, 0x00}; - uint8_t receive[1]; + struct himax_ts_data *ts = private_ts; + char messages[80] = {0}; + /*struct filename *vts_name;*/ + uint8_t command[2] = {0x00, 0x00}; + uint8_t receive[1]; + /* 0: common , other: dsram*/ + int storage_type = 0; + /* 1:IIR,2:DC,3:Bank,4:IIR2,5:IIR2_N,6:FIR2,7:Baseline,8:dump coord */ + int rawdata_type = 0; + memset(receive, 0x00, sizeof(receive)); - /* 0: common , other: dsram*/ - int storage_type = 0; - /* 1:IIR,2:DC,3:Bank,4:IIR2,5:IIR2_N,6:FIR2,7:Baseline,8:dump coord */ - int rawdata_type = 0; + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } - memset(receive, 0x00, sizeof(receive)); + if (copy_from_user(messages, buff, len)) { + return -EFAULT; + } - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(messages, buff, len)) - { - return -EFAULT; - } + I("%s:g_switch_mode = %d\n", __func__, g_switch_mode); - I("%s:g_switch_mode = %d\n",__func__,g_switch_mode); + if (messages[1] == 0x0A) { + ts->diag_cmd = messages[0] - '0'; + } else { + ts->diag_cmd = (messages[0] - '0') * 10 + (messages[1] - '0'); + } - if (messages[1] == 0x0A) - { - g_diag_command =messages[0] - '0'; - } - else - { - g_diag_command =(messages[0] - '0')*10 + (messages[1] - '0'); - } + storage_type = g_core_fp.fp_determin_diag_storage(ts->diag_cmd); + rawdata_type = g_core_fp.fp_determin_diag_rawdata(ts->diag_cmd); - storage_type = himax_determin_diag_storage(g_diag_command); - rawdata_type = himax_determin_diag_rawdata(g_diag_command); - - if(g_diag_command > 0 && rawdata_type == 0) - { - I("[Himax]g_diag_command=0x%x ,storage_type=%d, rawdata_type=%d! Maybe no support!\n" - ,g_diag_command,storage_type,rawdata_type); - g_diag_command = 0x00; - } - else - I("[Himax]g_diag_command=0x%x ,storage_type=%d, rawdata_type=%d\n",g_diag_command,storage_type,rawdata_type); + if (ts->diag_cmd > 0 && rawdata_type == 0) { + I("[Himax]ts->diag_cmd=0x%x ,storage_type=%d, rawdata_type=%d! Maybe no support!\n" + , ts->diag_cmd, storage_type, rawdata_type); + ts->diag_cmd = 0x00; + } else { + I("[Himax]ts->diag_cmd=0x%x ,storage_type=%d, rawdata_type=%d\n", ts->diag_cmd, storage_type, rawdata_type); + } memset(diag_mutual, 0x00, x_channel * y_channel * sizeof(int32_t)); /* Set data 0 */ memset(diag_self, 0x00, sizeof(diag_self)); + if (storage_type == 0 && rawdata_type > 0 && rawdata_type < 8) { + I("%s,common\n", __func__); - if (storage_type == 0 && rawdata_type > 0 && rawdata_type < 8) - { - I("%s,common\n",__func__); - if(DSRAM_Flag) - { - //1. Clear DSRAM flag - DSRAM_Flag = false; - //2. Stop DSRAM thread - cancel_delayed_work(&private_ts->himax_diag_delay_wrok); - //3. Enable ISR - himax_int_enable(private_ts->client->irq,1); + if (DSRAM_Flag) { + /* 1. Clear DSRAM flag */ + DSRAM_Flag = false; + /* 2. Stop DSRAM thread */ + cancel_delayed_work(&private_ts->himax_diag_delay_wrok); + /* 3. Enable ISR */ + himax_int_enable(1); + /*(4) FW leave sram and return to event stack*/ + g_core_fp.fp_return_event_stack(); + } - /*(4) FW leave sram and return to event stack*/ - himax_return_event_stack(private_ts->client); - } + if (g_switch_mode == 2) { + g_core_fp.fp_idle_mode(0); + g_switch_mode = g_core_fp.fp_switch_mode(0); + } - if(g_switch_mode == 2) - { - himax_idle_mode(private_ts->client,0); - g_switch_mode = himax_switch_mode(private_ts->client,0); - } - - if(g_diag_command == 0x04) - { + if (ts->diag_cmd == 0x04) { #if defined(HX_TP_PROC_2T2R) - command[0] = g_diag_command; + command[0] = ts->diag_cmd; #else - g_diag_command = 0x00; - command[0] = 0x00; + ts->diag_cmd = 0x00; + command[0] = 0x00; #endif - } - else - command[0] = g_diag_command; - himax_diag_register_set(private_ts->client, command[0]); - } - else if (storage_type > 0 && storage_type < 8 && rawdata_type > 0 && rawdata_type < 8) - { - I("%s,dsram\n",__func__); + } else { + command[0] = ts->diag_cmd; + } - diag_max_cnt = 0; + g_core_fp.fp_diag_register_set(command[0], storage_type); + } else if (storage_type > 0 && storage_type < 8 && rawdata_type > 0 && rawdata_type < 8) { + I("%s,dsram\n", __func__); + diag_max_cnt = 0; - //0. set diag flag - if(DSRAM_Flag) - { - //(1) Clear DSRAM flag - DSRAM_Flag = false; + /* 0. set diag flag */ + if (DSRAM_Flag) { + /* (1) Clear DSRAM flag */ + DSRAM_Flag = false; + /* (2) Stop DSRAM thread */ + cancel_delayed_work(&private_ts->himax_diag_delay_wrok); + /* (3) Enable ISR */ + himax_int_enable(1); + /*(4) FW leave sram and return to event stack*/ + g_core_fp.fp_return_event_stack(); + } - //(2) Stop DSRAM thread - cancel_delayed_work(&private_ts->himax_diag_delay_wrok); - //(3) Enable ISR - himax_int_enable(private_ts->client->irq,1); + /* close sorting if turn on*/ + if (g_switch_mode == 2) { + g_core_fp.fp_idle_mode(0); + g_switch_mode = g_core_fp.fp_switch_mode(0); + } - /*(4) FW leave sram and return to event stack*/ - himax_return_event_stack(private_ts->client); - } - /* close sorting if turn on*/ - if(g_switch_mode == 2) - { - himax_idle_mode(private_ts->client,0); - g_switch_mode = himax_switch_mode(private_ts->client,0); - } + command[0] = rawdata_type;/* ts->diag_cmd; */ + g_core_fp.fp_diag_register_set(command[0], storage_type); + /* 1. Disable ISR */ + himax_int_enable(0); +#if 0 + /* Open file for save raw data log */ + if (storage_type == 4) { + switch (rawdata_type) { + case 1: + vts_name = getname_kernel(IIR_DUMP_FILE); + diag_sram_fn = file_open_name(vts_name, O_CREAT | O_WRONLY, 0); + break; - switch(rawdata_type) - { - case 1: - command[0] = 0x09; //IIR - break; - case 2: - command[0] = 0x0A; //RAWDATA - break; - case 7: - command[0] = 0x0B; //DC - break; - default: - command[0] = 0x00; - E("%s: Sram no support this type !\n",__func__); - break; - } - himax_diag_register_set(private_ts->client, command[0]); + case 2: + vts_name = getname_kernel(DC_DUMP_FILE); + diag_sram_fn = file_open_name(vts_name, O_CREAT | O_WRONLY, 0); + break; - //1. Disable ISR - himax_int_enable(private_ts->client->irq,0); + case 3: + vts_name = getname_kernel(BANK_DUMP_FILE); + diag_sram_fn = file_open_name(vts_name, O_CREAT | O_WRONLY, 0); + break; - //Open file for save raw data log - if (storage_type == 4) - { - switch (rawdata_type) - { - case 1: - diag_sram_fn = filp_open(IIR_DUMP_FILE,O_CREAT | O_WRONLY,0); - break; - case 2: - diag_sram_fn = filp_open(DC_DUMP_FILE,O_CREAT | O_WRONLY,0); - break; - case 3: - diag_sram_fn = filp_open(BANK_DUMP_FILE,O_CREAT | O_WRONLY,0); - break; - default: - I("%s raw data type is not true. raw data type is %d \n",__func__, rawdata_type); - } - } + default: + I("%s raw data type is not true. raw data type is %d \n", __func__, rawdata_type); + } + } +#endif + /* 2. Start DSRAM thread */ + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2 * HZ / 100); + I("%s: Start get raw data in DSRAM\n", __func__); - //2. Start DSRAM thread - queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2*HZ/100); + if (storage_type == 4) + msleep(6000); - I("%s: Start get raw data in DSRAM\n", __func__); - if (storage_type == 4) - msleep(6000); - //3. Set DSRAM flag - DSRAM_Flag = true; + /* 3. Set DSRAM flag */ + DSRAM_Flag = true; + } else if (storage_type == 8) { + I("Soritng mode!\n"); + if (DSRAM_Flag) { + /* 1. Clear DSRAM flag */ + DSRAM_Flag = false; + /* 2. Stop DSRAM thread */ + cancel_delayed_work(&private_ts->himax_diag_delay_wrok); + /* 3. Enable ISR */ + himax_int_enable(1); + /*(4) FW leave sram and return to event stack*/ + g_core_fp.fp_return_event_stack(); + } - } - else if(storage_type == 8) - { - I("Soritng mode!\n"); + g_core_fp.fp_idle_mode(1); + g_switch_mode = g_core_fp.fp_switch_mode(1); - if(DSRAM_Flag) - { - //1. Clear DSRAM flag - DSRAM_Flag = false; - //2. Stop DSRAM thread - cancel_delayed_work(&private_ts->himax_diag_delay_wrok); - //3. Enable ISR - himax_int_enable(private_ts->client->irq,1); + if (g_switch_mode == 2) { + g_core_fp.fp_diag_register_set(command[0], storage_type); + } - /*(4) FW leave sram and return to event stack*/ - himax_return_event_stack(private_ts->client); - } + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2 * HZ / 100); + DSRAM_Flag = true; + } else { + /* set diag flag */ + if (DSRAM_Flag) { + I("return and cancel sram thread!\n"); + /* (1) Clear DSRAM flag */ + DSRAM_Flag = false; + /* (2) Stop DSRAM thread */ + cancel_delayed_work(&private_ts->himax_diag_delay_wrok); + /* (3) Enable ISR */ + himax_int_enable(1); + /*(4) FW leave sram and return to event stack*/ + g_core_fp.fp_return_event_stack(); + } - himax_idle_mode(private_ts->client,1); - g_switch_mode = himax_switch_mode(private_ts->client,1); - if(g_switch_mode == 2) - { - if(rawdata_type == 1) - command[0] = 0x09; //IIR - else if(rawdata_type == 2) - command[0] = 0x0A; //DC - else if(rawdata_type == 7) - command[0] = 0x08; //BASLINE - else - { - command[0] = 0x00; - E("%s: Now Sorting Mode does not support this command=%d\n",__func__,g_diag_command); - } - himax_diag_register_set(private_ts->client, command[0]); - } + if (g_switch_mode == 2) { + g_core_fp.fp_idle_mode(0); + g_switch_mode = g_core_fp.fp_switch_mode(0); + } - queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2*HZ/100); - DSRAM_Flag = true; + if (ts->diag_cmd != 0x00) { + E("[Himax]ts->diag_cmd error!diag_command=0x%x so reset\n", ts->diag_cmd); + command[0] = 0x00; - } - else - { - //set diag flag - if(DSRAM_Flag) - { - I("return and cancel sram thread!\n"); - //(1) Clear DSRAM flag - DSRAM_Flag = false; + if (ts->diag_cmd != 0x08) + ts->diag_cmd = 0x00; - //(2) Stop DSRAM thread - cancel_delayed_work(&private_ts->himax_diag_delay_wrok); - //(3) Enable ISR - himax_int_enable(private_ts->client->irq,1); - - /*(4) FW leave sram and return to event stack*/ - himax_return_event_stack(private_ts->client); - } - - if(g_switch_mode == 2) - { - himax_idle_mode(private_ts->client,0); - g_switch_mode = himax_switch_mode(private_ts->client,0); - } - - if(g_diag_command != 0x00) - { - - E("[Himax]g_diag_command error!diag_command=0x%x so reset\n",g_diag_command); - command[0] = 0x00; - if(g_diag_command != 0x08) - g_diag_command = 0x00; - himax_diag_register_set(private_ts->client, command[0]); - } - else - { - command[0] = 0x00; - g_diag_command = 0x00; - himax_diag_register_set(private_ts->client, command[0]); - I("return to normal g_diag_command=0x%x\n",g_diag_command); - } - } - return len; + g_core_fp.fp_diag_register_set(command[0], storage_type); + } else { + command[0] = 0x00; + ts->diag_cmd = 0x00; + g_core_fp.fp_diag_register_set(command[0], storage_type); + I("return to normal ts->diag_cmd=0x%x\n", ts->diag_cmd); + } + } + return len; } -static struct file_operations himax_proc_diag_ops = -{ - .owner = THIS_MODULE, - .open = himax_diag_proc_open, - .read = seq_read, - .write = himax_diag_write, +static struct file_operations himax_proc_diag_ops = { + .owner = THIS_MODULE, + .open = himax_diag_proc_open, + .read = seq_read, + .write = himax_diag_write, }; -#endif -#ifdef HX_TP_PROC_RESET static ssize_t himax_reset_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - char buf_tmp[12]; + char buf_tmp[12]; + + if (len >= 12) { + I("%s: no command exceeds 12 chars.\n", __func__); + return -EFAULT; + } + + if (copy_from_user(buf_tmp, buff, len)) { + return -EFAULT; + } - if (len >= 12) - { - I("%s: no command exceeds 12 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf_tmp, buff, len)) - { - return -EFAULT; - } #ifdef HX_RST_PIN_FUNC - if (buf_tmp[0] == '1') - himax_ic_reset(false,false); - else if (buf_tmp[0] == '2') - himax_ic_reset(false,true); - else if (buf_tmp[0] == '3') - himax_ic_reset(true,false); - else if (buf_tmp[0] == '4') - himax_ic_reset(true,true); - //else if (buf_tmp[0] == '5') - // ESD_HW_REST(); + + if (buf_tmp[0] == '1') { + g_core_fp.fp_ic_reset(false, false); + } else if (buf_tmp[0] == '2') { + g_core_fp.fp_ic_reset(false, true); + } else if (buf_tmp[0] == '3') { + g_core_fp.fp_ic_reset(true, false); + } else if (buf_tmp[0] == '4') { + g_core_fp.fp_ic_reset(true, true); + } + /* else if (buf_tmp[0] == '5') */ + /* ESD_HW_REST(); */ #endif - return len; + return len; } -static struct file_operations himax_proc_reset_ops = -{ - .owner = THIS_MODULE, - .write = himax_reset_write, +static struct file_operations himax_proc_reset_ops = { + .owner = THIS_MODULE, + .write = himax_reset_write, }; -#endif -#ifdef HX_TP_PROC_DEBUG static ssize_t himax_debug_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - size_t ret = 0; - char *temp_buf; + size_t ret = 0; + char *temp_buf; - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); - if (debug_level_cmd == 't') - { - if (fw_update_complete) - { - ret += snprintf(temp_buf + ret, len - ret, "FW Update Complete "); - } - else - { - ret += snprintf(temp_buf + ret, len - ret, "FW Update Fail "); - } - } - else if (debug_level_cmd == 'h') - { - if (handshaking_result == 0) - { - ret += snprintf(temp_buf + ret, len - ret, "Handshaking Result = %d (MCU Running)\n",handshaking_result); - } - else if (handshaking_result == 1) - { - ret += snprintf(temp_buf + ret, len - ret, "Handshaking Result = %d (MCU Stop)\n",handshaking_result); - } - else if (handshaking_result == 2) - { - ret += snprintf(temp_buf + ret, len - ret, "Handshaking Result = %d (I2C Error)\n",handshaking_result); - } - else - { - ret += snprintf(temp_buf + ret, len - ret, "Handshaking Result = error \n"); - } - } - else if (debug_level_cmd == 'v') - { - ret += snprintf(temp_buf + ret, len - ret, "FW_VER = 0x%2.2X \n",ic_data->vendor_fw_ver); + if (debug_level_cmd == 't') { + if (fw_update_complete) { + ret += snprintf(temp_buf + ret, len - ret, "FW Update Complete "); + } else { + ret += snprintf(temp_buf + ret, len - ret, "FW Update Fail "); + } + } else if (debug_level_cmd == 'h') { + if (handshaking_result == 0) { + ret += snprintf(temp_buf + ret, len - ret, "Handshaking Result = %d (MCU Running)\n", handshaking_result); + } else if (handshaking_result == 1) { + ret += snprintf(temp_buf + ret, len - ret, "Handshaking Result = %d (MCU Stop)\n", handshaking_result); + } else if (handshaking_result == 2) { + ret += snprintf(temp_buf + ret, len - ret, "Handshaking Result = %d (I2C Error)\n", handshaking_result); + } else { + ret += snprintf(temp_buf + ret, len - ret, "Handshaking Result = error \n"); + } + } else if (debug_level_cmd == 'v') { + ret += snprintf(temp_buf + ret, len - ret, "FW_VER = 0x%2.2X \n", ic_data->vendor_fw_ver); - if(IC_TYPE < 8) - ret += snprintf(temp_buf + ret, len - ret, "CONFIG_VER = 0x%2.2X \n",ic_data->vendor_config_ver); - else - { - ret += snprintf(temp_buf + ret, len - ret, "TOUCH_VER = 0x%2.2X \n",ic_data->vendor_touch_cfg_ver); - ret += snprintf(temp_buf + ret, len - ret, "DISPLAY_VER = 0x%2.2X \n",ic_data->vendor_display_cfg_ver); - } - if(ic_data->vendor_cid_maj_ver < 0 && ic_data->vendor_cid_min_ver < 0) - ret += snprintf(temp_buf + ret, len - ret, "CID_VER = NULL\n"); - else - ret += snprintf(temp_buf + ret, len - ret, "CID_VER = 0x%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); + if (private_ts->chip_cell_type == CHIP_IS_ON_CELL) { + ret += snprintf(temp_buf + ret, len - ret, "CONFIG_VER = 0x%2.2X \n", ic_data->vendor_config_ver); + } else { + ret += snprintf(temp_buf + ret, len - ret, "TOUCH_VER = 0x%2.2X \n", ic_data->vendor_touch_cfg_ver); + ret += snprintf(temp_buf + ret, len - ret, "DISPLAY_VER = 0x%2.2X \n", ic_data->vendor_display_cfg_ver); + } + if (ic_data->vendor_cid_maj_ver < 0 && ic_data->vendor_cid_min_ver < 0) + ret += snprintf(temp_buf + ret, len - ret, "CID_VER = NULL\n"); + else + ret += snprintf(temp_buf + ret, len - ret, "CID_VER = 0x%2.2X \n", (ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); - if(ic_data->vendor_panel_ver < 0) - ret += snprintf(temp_buf + ret, len - ret, "PANEL_VER = NULL\n"); - else - ret += snprintf(temp_buf + ret, len - ret, "PANEL_VER = 0x%2.2X \n",ic_data->vendor_panel_ver); + if (ic_data->vendor_panel_ver < 0) + ret += snprintf(temp_buf + ret, len - ret, "PANEL_VER = NULL\n"); + else + ret += snprintf(temp_buf + ret, len - ret, "PANEL_VER = 0x%2.2X \n", ic_data->vendor_panel_ver); - ret += snprintf(temp_buf + ret, len - ret, "\n"); + ret += snprintf(temp_buf + ret, len - ret, "\n"); + ret += snprintf(temp_buf + ret, len - ret, "Himax Touch Driver Version:\n"); + ret += snprintf(temp_buf + ret, len - ret, "%s \n", HIMAX_DRIVER_VER); + } else if (debug_level_cmd == 'd') { + ret += snprintf(temp_buf + ret, len - ret, "Himax Touch IC Information :\n"); + ret += snprintf(temp_buf + ret, len - ret, "%s \n", private_ts->chip_name); - ret += snprintf(temp_buf + ret, len - ret, "Himax Touch Driver Version:\n"); - ret += snprintf(temp_buf + ret, len - ret, "%s \n", HIMAX_DRIVER_VER); - } - else if (debug_level_cmd == 'd') - { - ret += snprintf(temp_buf + ret, len - ret, "Himax Touch IC Information :\n"); - switch(IC_TYPE) - { - case HX_85XX_D_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX852xD\n"); - break; - case HX_85XX_E_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX852xE\n"); - break; - case HX_85XX_ES_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX852xES\n"); - break; - case HX_85XX_F_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX852xF\n"); - break; - case HX_83100A_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83100A\n"); - break; - case HX_83102A_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83102A\n"); - break; - case HX_83102B_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83102B\n"); - break; - case HX_83103A_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83103A\n"); - break; - case HX_83110A_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83110A\n"); - break; - case HX_83110B_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83110B\n"); - break; - case HX_83111B_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83111B\n"); - break; - case HX_83112A_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83112A\n"); - break; - case HX_83112B_SERIES_PWON: - ret += snprintf(temp_buf + ret, len - ret, "IC Type : HX83112B\n"); - break; - default: - ret += snprintf(temp_buf + ret, len - ret, "IC Type error.\n"); - } - switch(IC_CHECKSUM) - { - case HX_TP_BIN_CHECKSUM_SW: - ret += snprintf(temp_buf + ret, len - ret, "IC Checksum : SW\n"); - break; - case HX_TP_BIN_CHECKSUM_HW: - ret += snprintf(temp_buf + ret, len - ret, "IC Checksum : HW\n"); - break; - case HX_TP_BIN_CHECKSUM_CRC: - ret += snprintf(temp_buf + ret, len - ret, "IC Checksum : CRC\n"); - break; - default: - ret += snprintf(temp_buf + ret, len - ret, "IC Checksum error.\n"); - } + switch (IC_CHECKSUM) { + case HX_TP_BIN_CHECKSUM_SW: + ret += snprintf(temp_buf + ret, len - ret, "IC Checksum : SW\n"); + break; - if (ic_data->HX_INT_IS_EDGE) - { - ret += snprintf(temp_buf + ret, len - ret, "Driver register Interrupt : EDGE TIRGGER\n"); - } - else - { - ret += snprintf(temp_buf + ret, len - ret, "Driver register Interrupt : LEVEL TRIGGER\n"); - } - if (private_ts->protocol_type == PROTOCOL_TYPE_A) - { - ret += snprintf(temp_buf + ret, len - ret, "Protocol : TYPE_A\n"); - } - else - { - ret += snprintf(temp_buf + ret, len - ret, "Protocol : TYPE_B\n"); - } - ret += snprintf(temp_buf + ret, len - ret, "RX Num : %d\n",ic_data->HX_RX_NUM); - ret += snprintf(temp_buf + ret, len - ret, "TX Num : %d\n",ic_data->HX_TX_NUM); - ret += snprintf(temp_buf + ret, len - ret, "BT Num : %d\n",ic_data->HX_BT_NUM); - ret += snprintf(temp_buf + ret, len - ret, "X Resolution : %d\n",ic_data->HX_X_RES); - ret += snprintf(temp_buf + ret, len - ret, "Y Resolution : %d\n",ic_data->HX_Y_RES); - ret += snprintf(temp_buf + ret, len - ret, "Max Point : %d\n",ic_data->HX_MAX_PT); - ret += snprintf(temp_buf + ret, len - ret, "XY reverse : %d\n",ic_data->HX_XY_REVERSE); + case HX_TP_BIN_CHECKSUM_HW: + ret += snprintf(temp_buf + ret, len - ret, "IC Checksum : HW\n"); + break; + + case HX_TP_BIN_CHECKSUM_CRC: + ret += snprintf(temp_buf + ret, len - ret, "IC Checksum : CRC\n"); + break; + + default: + ret += snprintf(temp_buf + ret, len - ret, "IC Checksum error.\n"); + } + + if (ic_data->HX_INT_IS_EDGE) { + ret += snprintf(temp_buf + ret, len - ret, "Driver register Interrupt : EDGE TIRGGER\n"); + } else { + ret += snprintf(temp_buf + ret, len - ret, "Driver register Interrupt : LEVEL TRIGGER\n"); + } + if (private_ts->protocol_type == PROTOCOL_TYPE_A) { + ret += snprintf(temp_buf + ret, len - ret, "Protocol : TYPE_A\n"); + } else { + ret += snprintf(temp_buf + ret, len - ret, "Protocol : TYPE_B\n"); + } + + ret += snprintf(temp_buf + ret, len - ret, "RX Num : %d\n", ic_data->HX_RX_NUM); + ret += snprintf(temp_buf + ret, len - ret, "TX Num : %d\n", ic_data->HX_TX_NUM); + ret += snprintf(temp_buf + ret, len - ret, "BT Num : %d\n", ic_data->HX_BT_NUM); + ret += snprintf(temp_buf + ret, len - ret, "X Resolution : %d\n", ic_data->HX_X_RES); + ret += snprintf(temp_buf + ret, len - ret, "Y Resolution : %d\n", ic_data->HX_Y_RES); + ret += snprintf(temp_buf + ret, len - ret, "Max Point : %d\n", ic_data->HX_MAX_PT); + ret += snprintf(temp_buf + ret, len - ret, "XY reverse : %d\n", ic_data->HX_XY_REVERSE); #ifdef HX_TP_PROC_2T2R - if(Is_2T2R) - { - ret += snprintf(temp_buf + ret, len - ret, "2T2R panel\n"); - ret += snprintf(temp_buf + ret, len - ret, "RX Num_2 : %d\n",HX_RX_NUM_2); - ret += snprintf(temp_buf + ret, len - ret, "TX Num_2 : %d\n",HX_TX_NUM_2); - } + if (Is_2T2R) { + ret += snprintf(temp_buf + ret, len - ret, "2T2R panel\n"); + ret += snprintf(temp_buf + ret, len - ret, "RX Num_2 : %d\n", HX_RX_NUM_2); + ret += snprintf(temp_buf + ret, len - ret, "TX Num_2 : %d\n", HX_TX_NUM_2); + } #endif - } - else if (debug_level_cmd == 'i') - { - if(himax_read_i2c_status(private_ts->client)) - ret += snprintf(temp_buf + ret, len - ret, "I2C communication is bad.\n"); - else - ret += snprintf(temp_buf + ret, len - ret, "I2C communication is good.\n"); - } - else if (debug_level_cmd == 'n') - { - if(himax_read_ic_trigger_type(private_ts->client) == 1) //Edgd = 1, Level = 0 - ret += snprintf(temp_buf + ret, len - ret, "IC Interrupt type is edge trigger.\n"); - else if(himax_read_ic_trigger_type(private_ts->client) == 0) - ret += snprintf(temp_buf + ret, len - ret, "IC Interrupt type is level trigger.\n"); - else - ret += snprintf(temp_buf + ret, len - ret, "Unkown IC trigger type.\n"); - if (ic_data->HX_INT_IS_EDGE) - ret += snprintf(temp_buf + ret, len - ret, "Driver register Interrupt : EDGE TIRGGER\n"); - else - ret += snprintf(temp_buf + ret, len - ret, "Driver register Interrupt : LEVEL TRIGGER\n"); - } -#if defined(HX_CHIP_STATUS_MONITOR) - else if(debug_level_cmd=='c') - { - ret += snprintf(temp_buf + ret, len - ret, "chip_monitor :%d\n", g_chip_monitor_data->HX_CHIP_MONITOR_EN); - } -#endif - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + } else if (debug_level_cmd == 'i') { + if (g_core_fp.fp_read_i2c_status()) + ret += snprintf(temp_buf + ret, len - ret, "I2C communication is bad.\n"); + else + ret += snprintf(temp_buf + ret, len - ret, "I2C communication is good.\n"); + } else if (debug_level_cmd == 'n') { + if (g_core_fp.fp_read_ic_trigger_type() == 1) /* Edgd = 1, Level = 0 */ + ret += snprintf(temp_buf + ret, len - ret, "IC Interrupt type is edge trigger.\n"); + else if (g_core_fp.fp_read_ic_trigger_type() == 0) + ret += snprintf(temp_buf + ret, len - ret, "IC Interrupt type is level trigger.\n"); + else + ret += snprintf(temp_buf + ret, len - ret, "Unkown IC trigger type.\n"); + + if (ic_data->HX_INT_IS_EDGE) + ret += snprintf(temp_buf + ret, len - ret, "Driver register Interrupt : EDGE TIRGGER\n"); + else + ret += snprintf(temp_buf + ret, len - ret, "Driver register Interrupt : LEVEL TRIGGER\n"); + } + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } +extern int g_ts_dbg; static ssize_t himax_debug_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - int result = 0; - char fileName[128]; - char buf[80] = {0}; - int fw_type = 0; + char fileName[128]; + char buf[80] = {0}; + int result = 0; +#ifndef HX_ZERO_FLASH + int fw_type = 0; const struct firmware *fw = NULL; +#endif - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } - if ( buf[0] == 'h') //handshaking - { - debug_level_cmd = buf[0]; + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } - himax_int_enable(private_ts->client->irq,0); + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } - handshaking_result = himax_hand_shaking(private_ts->client); //0:Running, 1:Stop, 2:I2C Fail - - himax_int_enable(private_ts->client->irq,1); - - return len; - } - - else if ( buf[0] == 'v') //firmware version - { - himax_int_enable(private_ts->client->irq,0); + if (buf[0] == 'h') { /* handshaking */ + debug_level_cmd = buf[0]; + himax_int_enable(0); + handshaking_result = g_core_fp.fp_hand_shaking(); /* 0:Running, 1:Stop, 2:I2C Fail */ + himax_int_enable(1); + return len; + } else if (buf[0] == 'v') { /* firmware version */ + himax_int_enable(0); #ifdef HX_RST_PIN_FUNC - himax_ic_reset(false,false); + g_core_fp.fp_ic_reset(false, false); #endif - debug_level_cmd = buf[0]; - himax_read_FW_ver(private_ts->client); + debug_level_cmd = buf[0]; + g_core_fp.fp_read_FW_ver(); #ifdef HX_RST_PIN_FUNC - himax_ic_reset(true,false); + g_core_fp.fp_ic_reset(true, false); +#else + g_core_fp.fp_system_reset(); #endif - himax_int_enable(private_ts->client->irq,1); - return len; - } + himax_int_enable(1); + /* himax_check_chip_version(); */ + return len; + } else if (buf[0] == 'd') { /* ic information */ + debug_level_cmd = buf[0]; + return len; + } else if (buf[0] == 't') { + if (buf[1] == 's' && + buf[2] == 'd' && + buf[3] == 'b' && + buf[4] == 'g' + ) { + if (buf[5] == '1') { + I("Open Ts Debug!\n"); + g_ts_dbg = 1; + } else if (buf[5] == '0') { + I("Close Ts Debug!\n"); + g_ts_dbg = 0; + } else { + E("Parameter fault for ts debug\n"); + } + goto ENDFUCTION; + } + himax_int_enable(0); + debug_level_cmd = buf[0]; + fw_update_complete = false; + memset(fileName, 0, 128); + /* parse the file name */ + snprintf(fileName, len - 2, "%s", &buf[2]); - else if ( buf[0] == 'd') //ic information - { - debug_level_cmd = buf[0]; - return len; - } +#ifdef HX_ZERO_FLASH + I("NOW Running Zero flash update!\n"); + I("%s: upgrade from file(%s) start!\n", __func__, fileName); + result = g_core_fp.fp_0f_op_file_dirly(fileName); + if (result) { + fw_update_complete = false; + I("Zero flash update fail!\n"); + goto ENDFUCTION; + } else { + fw_update_complete = true; + I("Zero flash update complete!\n"); + } + goto firmware_upgrade_done; +#else + I("NOW Running common flow update!\n"); + I("%s: upgrade from file(%s) start!\n", __func__, fileName); + result = request_firmware(&fw, fileName, private_ts->dev); - else if (buf[0] == 't') - { - - himax_int_enable(private_ts->client->irq,0); - -#ifdef HX_CHIP_STATUS_MONITOR - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; - cancel_delayed_work_sync(&private_ts->himax_chip_monitor); -#endif - - debug_level_cmd = buf[0]; - fw_update_complete = false; - - memset(fileName, 0, 128); - // parse the file name - snprintf(fileName, len-2, "%s", &buf[2]); - I("%s: upgrade from file(%s) start!\n", __func__, fileName); - result = request_firmware(&fw, fileName, private_ts->dev); if (result < 0) { I("fail to request_firmware fwpath: %s (ret:%d)\n", fileName, result); return result; } - I("%s: FW image: %02X, %02X, %02X, %02X\n", __func__, fw->data[0], fw->data[1], fw->data[2], fw->data[3]); - fw_type = (fw->size)/1024; - // start to upgrade - himax_int_enable(private_ts->client->irq,0); - I("Now FW size is : %dk\n",fw_type); - switch(fw_type) - { - case 32: - if (fts_ctpm_fw_upgrade_with_sys_fs_32k(private_ts->client, - (unsigned char *)fw->data, fw->size, false) == 0) { - E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); - fw_update_complete = false; + I("%s: FW image: %02X, %02X, %02X, %02X\n", __func__, fw->data[0], fw->data[1], fw->data[2], fw->data[3]); + fw_type = (fw->size) / 1024; + /* start to upgrade */ + himax_int_enable(0); + I("Now FW size is : %dk\n", fw_type); + + switch (fw_type) { + case 32: + if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_32k((unsigned char *)fw->data, fw->size, false) == 0) { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; } else { I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); fw_update_complete = true; - } + } break; + case 60: - if (fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client, - (unsigned char *)fw->data, fw->size, false) == 0) { - E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); - fw_update_complete = false; - } else { - I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); - fw_update_complete = true; - } - break; - case 64: - if (fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client, - (unsigned char *)fw->data, fw->size, false) == 0) { - E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); - fw_update_complete = false; + if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_60k((unsigned char *)fw->data, fw->size, false) == 0) { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; } else { I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); fw_update_complete = true; - } + } break; + + case 64: + if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_64k((unsigned char *)fw->data, fw->size, false) == 0) { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; + } else { + I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); + fw_update_complete = true; + } + break; + case 124: - if (fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client, - (unsigned char *)fw->data, fw->size, false) == 0) { - E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); - fw_update_complete = false; - } else { - I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); - fw_update_complete = true; - } - break; + if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_124k((unsigned char *)fw->data, fw->size, false) == 0) { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; + } else { + I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); + fw_update_complete = true; + } + break; + case 128: - if (fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client, - (unsigned char *)fw->data, fw->size, false) == 0) { - E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); - fw_update_complete = false; - } else { - I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); - fw_update_complete = true; - } - break; + if (g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_128k((unsigned char *)fw->data, fw->size, false) == 0) { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; + } else { + I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); + fw_update_complete = true; + } + break; - default: - E("%s: Flash command fail: %d\n", __func__, __LINE__); - fw_update_complete = false; - break; - } - release_firmware(fw); - goto firmware_upgrade_done; - //return count; - } - else if (buf[0] == 'i' && buf[1] == '2' && buf[2] == 'c') //i2c commutation - { - debug_level_cmd = 'i'; - return len; - } - - else if (buf[0] == 'i' && buf[1] == 'n' && buf[2] == 't') //INT trigger - { - debug_level_cmd = 'n'; - return len; - } -#if defined(HX_CHIP_STATUS_MONITOR) - else if(buf[0] == 'c') - { - debug_level_cmd = buf[0]; - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; - cancel_delayed_work_sync(&private_ts->himax_chip_monitor); - return len; - } + default: + E("%s: Flash command fail: %d\n", __func__, __LINE__); + fw_update_complete = false; + break; + } + release_firmware(fw); + goto firmware_upgrade_done; #endif -#ifdef HX_ZERO_FLASH - else if(buf[0] == 'z') - { - himax_0f_operation_check(); + } else if (buf[0] == 'i' && buf[1] == '2' && buf[2] == 'c') { /* i2c commutation */ + debug_level_cmd = 'i'; return len; - } - else if(buf[0] == 'p') - { + } else if (buf[0] == 'i' && buf[1] == 'n' && buf[2] == 't') { /* INT trigger */ + debug_level_cmd = 'n'; + return len; +#ifdef HX_ZERO_FLASH + } else if (buf[0] == 'z') { + result = buf[1] - '0'; + I("check type = %d \n", result); + g_core_fp.fp_0f_operation_check(result); + return len; + } else if (buf[0] == 'p') { I("NOW debug echo r!\n"); - //himax_program_sram(); + /* himax_program_sram(); */ private_ts->himax_0f_update_wq = create_singlethread_workqueue("HMX_update_0f_reuqest_write"); - if (!private_ts->himax_0f_update_wq) + + if (!private_ts->himax_0f_update_wq) E(" allocate syn_update_wq failed\n"); - - INIT_DELAYED_WORK(&private_ts->work_0f_update, himax_0f_operation); + + INIT_DELAYED_WORK(&private_ts->work_0f_update, g_core_fp.fp_0f_operation); queue_delayed_work(private_ts->himax_0f_update_wq, &private_ts->work_0f_update, msecs_to_jiffies(100)); return len; - } - else if(buf[0] == 'x') - { - himax_sys_reset(); + } else if (buf[0] == 'x') { + g_core_fp.fp_system_reset(); + return len; +#endif + } else { /* others,do nothing */ + debug_level_cmd = 0; return len; } -#endif - /* others,do nothing */ - else - { - debug_level_cmd = 0; - return len; - } + firmware_upgrade_done: - himax_read_FW_ver(private_ts->client); - himax_touch_information(private_ts->client); - + g_core_fp.fp_reload_disable(0); + g_core_fp.fp_read_FW_ver(); + g_core_fp.fp_touch_information(); #ifdef HX_RST_PIN_FUNC - himax_ic_reset(true,false); + g_core_fp.fp_ic_reset(true, false); #else - himax_sense_on(private_ts->client,0); -#endif - himax_int_enable(private_ts->client->irq,1); - -#ifdef HX_CHIP_STATUS_MONITOR - g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; - g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; - queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMES*HZ); + g_core_fp.fp_sense_on(0x00); #endif - //todo himax_chip->tp_firmware_upgrade_proceed = 0; - //todo himax_chip->suspend_state = 0; - //todo enable_irq(himax_chip->irq); - return len; + himax_int_enable(1); +/* todo himax_chip->tp_firmware_upgrade_proceed = 0; + todo himax_chip->suspend_state = 0; + todo enable_irq(himax_chip->irq); */ +ENDFUCTION: + return len; } -static struct file_operations himax_proc_debug_ops = -{ - .owner = THIS_MODULE, - .read = himax_debug_read, - .write = himax_debug_write, +static struct file_operations himax_proc_debug_ops = { + .owner = THIS_MODULE, + .read = himax_debug_read, + .write = himax_debug_write, }; static ssize_t himax_proc_FW_debug_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - int ret = 0; - uint8_t loop_i = 0; + ssize_t ret = 0; + uint8_t loop_i = 0; uint8_t tmp_data[64]; - char *temp_buf; + char *temp_buf; - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + cmd_set[0] = 0x01; + + if (g_core_fp.fp_read_FW_status(cmd_set, tmp_data) == NO_ERR) { + ret += snprintf(temp_buf + ret, len - ret, "0x%02X%02X%02X%02X :\t", cmd_set[5], cmd_set[4], cmd_set[3], cmd_set[2]); + + for (loop_i = 0; loop_i < cmd_set[1]; loop_i++) { + ret += snprintf(temp_buf + ret, len - ret, "%5d\t", tmp_data[loop_i]); + } + + ret += snprintf(temp_buf + ret, len - ret, "\n"); + } - cmd_set[0] = 0x01; - if(himax_read_FW_status(cmd_set, tmp_data) == NO_ERR) - { - ret += snprintf(temp_buf + ret, len - ret, "0x%02X%02X%02X%02X :\t",cmd_set[5],cmd_set[4],cmd_set[3],cmd_set[2]); - for (loop_i = 0; loop_i < cmd_set[1]; loop_i++) - { - ret += snprintf(temp_buf + ret, len - ret, "%5d\t", tmp_data[loop_i]); - } - ret += snprintf(temp_buf + ret, len - ret, "\n"); - } cmd_set[0] = 0x02; - if(himax_read_FW_status(cmd_set, tmp_data) == NO_ERR) - { - for (loop_i = 0; loop_i < cmd_set[1]; loop_i = loop_i + 2) - { - if ((loop_i % 16) == 0) - ret += snprintf(temp_buf + ret, len - ret, "0x%02X%02X%02X%02X :\t", - cmd_set[5],cmd_set[4],cmd_set[3]+(((cmd_set[2]+ loop_i)>>8)&0xFF), (cmd_set[2] + loop_i)&0xFF); - ret += snprintf(temp_buf + ret, len - ret, "%5d\t", tmp_data[loop_i] + (tmp_data[loop_i + 1] << 8)); - if ((loop_i % 16) == 14) - ret += snprintf(temp_buf + ret, len - ret, "\n"); - } - } - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + if (g_core_fp.fp_read_FW_status(cmd_set, tmp_data) == NO_ERR) { + for (loop_i = 0; loop_i < cmd_set[1]; loop_i = loop_i + 2) { + if ((loop_i % 16) == 0) + ret += snprintf(temp_buf + ret, len - ret, "0x%02X%02X%02X%02X :\t", + cmd_set[5], cmd_set[4], cmd_set[3] + (((cmd_set[2] + loop_i) >> 8) & 0xFF), (cmd_set[2] + loop_i) & 0xFF); + + ret += snprintf(temp_buf + ret, len - ret, "%5d\t", tmp_data[loop_i] + (tmp_data[loop_i + 1] << 8)); + + if ((loop_i % 16) == 14) + ret += snprintf(temp_buf + ret, len - ret, "\n"); + } + } + + ret += snprintf(temp_buf + ret, len - ret, "\n"); + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } -static struct file_operations himax_proc_fw_debug_ops = -{ - .owner = THIS_MODULE, - .read = himax_proc_FW_debug_read, +static struct file_operations himax_proc_fw_debug_ops = { + .owner = THIS_MODULE, + .read = himax_proc_FW_debug_read, }; static ssize_t himax_proc_DD_debug_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - int ret = 0; - uint8_t tmp_data[64]; - uint8_t loop_i = 0; - char *temp_buf; + ssize_t ret = 0; + uint8_t tmp_data[64]; + uint8_t loop_i = 0; + char *temp_buf; - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); - if(mutual_set_flag == 1) - { - if(himax_read_DD_status(cmd_set, tmp_data) == NO_ERR) - { - for (loop_i = 0; loop_i < cmd_set[0]; loop_i++) - { - if ((loop_i % 8) == 0) - ret += snprintf(temp_buf + ret, len - ret, "0x%02X : ", loop_i); - ret += snprintf(temp_buf + ret, len - ret, "0x%02X ", tmp_data[loop_i]); - if ((loop_i % 8) == 7) - ret += snprintf(temp_buf + ret, len - ret, "\n"); - } - } - } - //else - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + if (mutual_set_flag == 1) { + if (g_core_fp.fp_read_DD_status(cmd_set, tmp_data) == NO_ERR) { + for (loop_i = 0; loop_i < cmd_set[0]; loop_i++) { + if ((loop_i % 8) == 0) + ret += snprintf(temp_buf + ret, len - ret, "0x%02X : ", loop_i); + + ret += snprintf(temp_buf + ret, len - ret, "0x%02X ", tmp_data[loop_i]); + + if ((loop_i % 8) == 7) + ret += snprintf(temp_buf + ret, len - ret, "\n"); + } + } + } + + ret += snprintf(temp_buf + ret, len - ret, "\n"); + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } static ssize_t himax_proc_DD_debug_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - uint8_t i = 0; - uint8_t cnt = 2; - unsigned long result = 0; - char buf_tmp[20]; - char buf_tmp2[4]; + uint8_t i = 0; + uint8_t cnt = 2; + unsigned long result = 0; + char buf_tmp[20]; + char buf_tmp2[4]; - if (len >= 20) - { - I("%s: no command exceeds 20 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf_tmp, buff, len)) - { - return -EFAULT; - } - memset(buf_tmp2, 0x0, sizeof(buf_tmp2)); + if (len >= 20) { + I("%s: no command exceeds 20 chars.\n", __func__); + return -EFAULT; + } - if (buf_tmp[2] == 'x' && buf_tmp[6] == 'x' && buf_tmp[10] == 'x') - { - mutual_set_flag = 1; - for (i = 3; i < 12; i = i + 4) - { - memcpy(buf_tmp2, buf_tmp + i, 2); - if (!kstrtoul(buf_tmp2, 16, &result)) - cmd_set[cnt] = (uint8_t)result; - else - I("String to oul is fail in cnt = %d, buf_tmp2 = %s",cnt, buf_tmp2); - cnt--; - } - I("cmd_set[2] = %02X, cmd_set[1] = %02X, cmd_set[0] = %02X\n",cmd_set[2],cmd_set[1],cmd_set[0]); - } - else - mutual_set_flag = 0; + if (copy_from_user(buf_tmp, buff, len)) { + return -EFAULT; + } - return len; + memset(buf_tmp2, 0x0, sizeof(buf_tmp2)); + + if (buf_tmp[2] == 'x' && buf_tmp[6] == 'x' && buf_tmp[10] == 'x') { + mutual_set_flag = 1; + + for (i = 3; i < 12; i = i + 4) { + memcpy(buf_tmp2, buf_tmp + i, 2); + + if (!kstrtoul(buf_tmp2, 16, &result)) + cmd_set[cnt] = (uint8_t)result; + else + I("String to oul is fail in cnt = %d, buf_tmp2 = %s\n", cnt, buf_tmp2); + + cnt--; + } + + I("cmd_set[2] = %02X, cmd_set[1] = %02X, cmd_set[0] = %02X\n", cmd_set[2], cmd_set[1], cmd_set[0]); + } else { + mutual_set_flag = 0; + } + + return len; } -static struct file_operations himax_proc_dd_debug_ops = -{ - .owner = THIS_MODULE, - .read = himax_proc_DD_debug_read, - .write = himax_proc_DD_debug_write, +static struct file_operations himax_proc_dd_debug_ops = { + .owner = THIS_MODULE, + .read = himax_proc_DD_debug_read, + .write = himax_proc_DD_debug_write, }; -#endif - -#ifdef HX_TP_PROC_FLASH_DUMP - uint8_t getFlashCommand(void) { - return flash_command; + return flash_command; } static uint8_t getFlashDumpProgress(void) { - return flash_progress; + return flash_progress; } static uint8_t getFlashDumpComplete(void) { - return flash_dump_complete; + return flash_dump_complete; } static uint8_t getFlashDumpFail(void) { - return flash_dump_fail; + return flash_dump_fail; } uint8_t getSysOperation(void) { - return sys_operation; + return sys_operation; } static uint8_t getFlashReadStep(void) { - return flash_read_step; + return flash_read_step; } bool getFlashDumpGoing(void) { - return flash_dump_going; + return flash_dump_going; } void setFlashBuffer(void) { - flash_buffer = kzalloc(Flash_Size * sizeof(uint8_t), GFP_KERNEL); - memset(flash_buffer,0x00,Flash_Size); + flash_buffer = kzalloc(Flash_Size * sizeof(uint8_t), GFP_KERNEL); } void setSysOperation(uint8_t operation) { - sys_operation = operation; + sys_operation = operation; } void setFlashDumpProgress(uint8_t progress) { - flash_progress = progress; - //I("setFlashDumpProgress : progress = %d ,flash_progress = %d \n",progress,flash_progress); + flash_progress = progress; + /* I("setFlashDumpProgress : progress = %d ,flash_progress = %d \n",progress,flash_progress); */ } void setFlashDumpComplete(uint8_t status) { - flash_dump_complete = status; + flash_dump_complete = status; } void setFlashDumpFail(uint8_t fail) { - flash_dump_fail = fail; + flash_dump_fail = fail; } static void setFlashCommand(uint8_t command) { - flash_command = command; + flash_command = command; } static void setFlashReadStep(uint8_t step) { - flash_read_step = step; + flash_read_step = step; } void setFlashDumpGoing(bool going) { - flash_dump_going = going; + flash_dump_going = going; + debug_data->flash_dump_going = going; } static ssize_t himax_proc_flash_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - ssize_t ret = 0; - int loop_i; - uint8_t local_flash_read_step=0; - uint8_t local_flash_complete = 0; - uint8_t local_flash_progress = 0; - uint8_t local_flash_command = 0; - uint8_t local_flash_fail = 0; - char *temp_buf; + ssize_t ret = 0; + int loop_i; + uint8_t local_flash_read_step = 0; + uint8_t local_flash_complete = 0; + uint8_t local_flash_progress = 0; + uint8_t local_flash_command = 0; + uint8_t local_flash_fail = 0; + char *temp_buf; + local_flash_complete = getFlashDumpComplete(); + local_flash_progress = getFlashDumpProgress(); + local_flash_command = getFlashCommand(); + local_flash_fail = getFlashDumpFail(); + I("flash_progress = %d \n", local_flash_progress); - local_flash_complete = getFlashDumpComplete(); - local_flash_progress = getFlashDumpProgress(); - local_flash_command = getFlashCommand(); - local_flash_fail = getFlashDumpFail(); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); - I("flash_progress = %d \n",local_flash_progress); - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); - if (local_flash_fail) - { - ret += snprintf(temp_buf + ret, len - ret, "FlashStart:Fail \n"); - ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - return ret; - } + if (local_flash_fail) { + ret += snprintf(temp_buf + ret, len - ret, "FlashStart:Fail \n"); + ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); + ret += snprintf(temp_buf + ret, len - ret, "\n"); - if (!local_flash_complete) - { - ret += snprintf(temp_buf + ret, len - ret, "FlashStart:Ongoing:0x%2.2x \n",flash_progress); - ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - return ret; - } + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); - if (local_flash_command == 1 && local_flash_complete) - { - ret += snprintf(temp_buf + ret, len - ret, "FlashStart:Complete \n"); - ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - return ret; - } + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + return ret; + } - if (local_flash_command == 3 && local_flash_complete) - { - ret += snprintf(temp_buf + ret, len - ret, "FlashStart: \n"); - for(loop_i = 0; loop_i < 128; loop_i++) - { - ret += snprintf(temp_buf + ret, len - ret, "x%2.2x", flash_buffer[loop_i]); - if ((loop_i % 16) == 15) - { - ret += snprintf(temp_buf + ret, len - ret, "\n"); - } - } - ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - return ret; - } + if (!local_flash_complete) { + ret += snprintf(temp_buf + ret, len - ret, "FlashStart:Ongoing:0x%2.2x \n", flash_progress); + ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); + ret += snprintf(temp_buf + ret, len - ret, "\n"); - //flash command == 0 , report the data - local_flash_read_step = getFlashReadStep(); + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); - ret += snprintf(temp_buf + ret, len - ret, "FlashStart:%2.2x \n",local_flash_read_step); + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + return ret; + } - for (loop_i = 0; loop_i < 1024; loop_i++) - { - ret += snprintf(temp_buf + ret, len - ret, "x%2.2X", flash_buffer[local_flash_read_step*1024 + loop_i]); + if (local_flash_command == 1 && local_flash_complete) { + ret += snprintf(temp_buf + ret, len - ret, "FlashStart:Complete \n"); + ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); + ret += snprintf(temp_buf + ret, len - ret, "\n"); - if ((loop_i % 16) == 15) - { - ret += snprintf(temp_buf + ret, len - ret, "\n"); - } - } + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); - ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); - ret += snprintf(temp_buf + ret, len - ret, "\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + return ret; + } + + if (local_flash_command == 3 && local_flash_complete) { + ret += snprintf(temp_buf + ret, len - ret, "FlashStart: \n"); + + for (loop_i = 0; loop_i < 128; loop_i++) { + ret += snprintf(temp_buf + ret, len - ret, "x%2.2x", flash_buffer[loop_i]); + + if ((loop_i % 16) == 15) { + ret += snprintf(temp_buf + ret, len - ret, "\n"); + } + } + + ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); + ret += snprintf(temp_buf + ret, len - ret, "\n"); + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + return ret; + } + + /* flash command == 0 , report the data */ + local_flash_read_step = getFlashReadStep(); + ret += snprintf(temp_buf + ret, len - ret, "FlashStart:%2.2x \n", local_flash_read_step); + + for (loop_i = 0; loop_i < 1024; loop_i++) { + ret += snprintf(temp_buf + ret, len - ret, "x%2.2X", flash_buffer[local_flash_read_step * 1024 + loop_i]); + + if ((loop_i % 16) == 15) { + ret += snprintf(temp_buf + ret, len - ret, "\n"); + } + } + + ret += snprintf(temp_buf + ret, len - ret, "FlashEnd"); + ret += snprintf(temp_buf + ret, len - ret, "\n"); + + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } static ssize_t himax_proc_flash_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - char buf_tmp[6]; - unsigned long result = 0; - char buf[80] = {0}; + char buf_tmp[6]; + unsigned long result = 0; + char buf[80] = {0}; - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } - memset(buf_tmp, 0x0, sizeof(buf_tmp)); + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } - I("%s: buf = %s\n", __func__, buf); + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } - if (getSysOperation() == 1) - { - E("%s: PROC is busy , return!\n", __func__); - return len; - } + memset(buf_tmp, 0x0, sizeof(buf_tmp)); + I("%s: buf = %s\n", __func__, buf); - if (buf[0] == '0') - { - setFlashCommand(0); - if (buf[1] == ':' && buf[2] == 'x') - { - memcpy(buf_tmp, buf + 3, 2); - I("%s: read_Step = %s\n", __func__, buf_tmp); - if (!kstrtoul(buf_tmp, 16, &result)) - { - I("%s: read_Step = %lu \n", __func__, result); - setFlashReadStep(result); - } - } - } - else if (buf[0] == '1')// 1_32,1_60,1_64,1_24,1_28 for flash size 32k,60k,64k,124k,128k - { - setSysOperation(1); - setFlashCommand(1); - setFlashDumpProgress(0); - setFlashDumpComplete(0); - setFlashDumpFail(0); - if ((buf[1] == '_' ) && (buf[2] == '3' ) && (buf[3] == '2' )) - { - Flash_Size = FW_SIZE_32k; - } - else if ((buf[1] == '_' ) && (buf[2] == '6' )) - { - if (buf[3] == '0') - { - Flash_Size = FW_SIZE_60k; - } - else if (buf[3] == '4') - { - Flash_Size = FW_SIZE_64k; - } - } - else if ((buf[1] == '_' ) && (buf[2] == '2' )) - { - if (buf[3] == '4') - { - Flash_Size = FW_SIZE_124k; - } - else if (buf[3] == '8') - { - Flash_Size = FW_SIZE_128k; - } - } - queue_work(private_ts->flash_wq, &private_ts->flash_work); - } - else if (buf[0] == '2') // 2_32,2_60,2_64,2_24,2_28 for flash size 32k,60k,64k,124k,128k - { - setSysOperation(1); - setFlashCommand(2); - setFlashDumpProgress(0); - setFlashDumpComplete(0); - setFlashDumpFail(0); - if ((buf[1] == '_' ) && (buf[2] == '3' ) && (buf[3] == '2' )) - { - Flash_Size = FW_SIZE_32k; - } - else if ((buf[1] == '_' ) && (buf[2] == '6' )) - { - if (buf[3] == '0') - { - Flash_Size = FW_SIZE_60k; - } - else if (buf[3] == '4') - { - Flash_Size = FW_SIZE_64k; - } - } - else if ((buf[1] == '_' ) && (buf[2] == '2' )) - { - if (buf[3] == '4') - { - Flash_Size = FW_SIZE_124k; - } - else if (buf[3] == '8') - { - Flash_Size = FW_SIZE_128k; - } - } - queue_work(private_ts->flash_wq, &private_ts->flash_work); - } - return len; + if (getSysOperation() == 1) { + E("%s: PROC is busy , return!\n", __func__); + return len; + } + + if (buf[0] == '0') { + setFlashCommand(0); + + if (buf[1] == ':' && buf[2] == 'x') { + memcpy(buf_tmp, buf + 3, 2); + I("%s: read_Step = %s\n", __func__, buf_tmp); + + if (!kstrtoul(buf_tmp, 16, &result)) { + I("%s: read_Step = %lu \n", __func__, result); + setFlashReadStep(result); + } + } + } else if (buf[0] == '1') { /* 1_32,1_60,1_64,1_24,1_28 for flash size 32k,60k,64k,124k,128k */ + setSysOperation(1); + setFlashCommand(1); + setFlashDumpProgress(0); + setFlashDumpComplete(0); + setFlashDumpFail(0); + + if ((buf[1] == '_') && (buf[2] == '3') && (buf[3] == '2')) { + Flash_Size = FW_SIZE_32k; + } else if ((buf[1] == '_') && (buf[2] == '6')) { + if (buf[3] == '0') { + Flash_Size = FW_SIZE_60k; + } else if (buf[3] == '4') { + Flash_Size = FW_SIZE_64k; + } + } else if ((buf[1] == '_') && (buf[2] == '2')) { + if (buf[3] == '4') { + Flash_Size = FW_SIZE_124k; + } else if (buf[3] == '8') { + Flash_Size = FW_SIZE_128k; + } + } + queue_work(private_ts->flash_wq, &private_ts->flash_work); + } else if (buf[0] == '2') { /* 2_32,2_60,2_64,2_24,2_28 for flash size 32k,60k,64k,124k,128k */ + setSysOperation(1); + setFlashCommand(2); + setFlashDumpProgress(0); + setFlashDumpComplete(0); + setFlashDumpFail(0); + + if ((buf[1] == '_') && (buf[2] == '3') && (buf[3] == '2')) { + Flash_Size = FW_SIZE_32k; + } else if ((buf[1] == '_') && (buf[2] == '6')) { + if (buf[3] == '0') { + Flash_Size = FW_SIZE_60k; + } else if (buf[3] == '4') { + Flash_Size = FW_SIZE_64k; + } + } else if ((buf[1] == '_') && (buf[2] == '2')) { + if (buf[3] == '4') { + Flash_Size = FW_SIZE_124k; + } else if (buf[3] == '8') { + Flash_Size = FW_SIZE_128k; + } + } + queue_work(private_ts->flash_wq, &private_ts->flash_work); + } + + return len; } -static struct file_operations himax_proc_flash_ops = -{ - .owner = THIS_MODULE, - .read = himax_proc_flash_read, - .write = himax_proc_flash_write, +static struct file_operations himax_proc_flash_ops = { + .owner = THIS_MODULE, + .read = himax_proc_flash_read, + .write = himax_proc_flash_write, }; void himax_ts_flash_func(void) { - uint8_t local_flash_command = 0; + uint8_t local_flash_command = 0; + himax_int_enable(0); + setFlashDumpGoing(true); + /* sector = getFlashDumpSector(); */ + /* page = getFlashDumpPage(); */ + local_flash_command = getFlashCommand(); + msleep(100); + I("%s: local_flash_command = %d enter.\n", __func__, local_flash_command); - himax_int_enable(private_ts->client->irq,0); - setFlashDumpGoing(true); + if ((local_flash_command == 1 || local_flash_command == 2) || (local_flash_command == 0x0F)) { + g_core_fp.fp_flash_dump_func(local_flash_command, Flash_Size, flash_buffer); + } - //sector = getFlashDumpSector(); - //page = getFlashDumpPage(); + I("Complete~~~~~~~~~~~~~~~~~~~~~~~\n"); - local_flash_command = getFlashCommand(); +#if 0 + if (local_flash_command == 2) { + struct file *fn; + struct filename *vts_name; + vts_name = getname_kernel(FLASH_DUMP_FILE); + fn = file_open_name(vts_name, O_CREAT | O_WRONLY, 0); - msleep(100); - - I("%s: local_flash_command = %d enter.\n", __func__,local_flash_command); - - if ((local_flash_command == 1 || local_flash_command == 2)|| (local_flash_command==0x0F)) - { - himax_flash_dump_func(private_ts->client, local_flash_command,Flash_Size, flash_buffer); - } - - I("Complete~~~~~~~~~~~~~~~~~~~~~~~\n"); - - if (local_flash_command == 2) - { - struct file *fn; - - fn = filp_open(FLASH_DUMP_FILE,O_CREAT | O_WRONLY,0); - if (!IS_ERR(fn)) - { - I("%s create file and ready to write\n",__func__); - fn->f_op->write(fn,flash_buffer,Flash_Size*sizeof(uint8_t),&fn->f_pos); - filp_close(fn,NULL); - } - } - - himax_int_enable(private_ts->client->irq,1); - setFlashDumpGoing(false); - - setFlashDumpComplete(1); - setSysOperation(0); - return; - - /* Flash_Dump_i2c_transfer_error: - - himax_int_enable(private_ts->client->irq,1); - setFlashDumpGoing(false); - setFlashDumpComplete(0); - setFlashDumpFail(1); - setSysOperation(0); - return; - */ -} - -#endif - -#ifdef HX_TP_PROC_SELF_TEST -static ssize_t himax_self_test_read(struct file *file, char *buf, - size_t len, loff_t *pos) -{ - int val=0x00; - ssize_t ret = 0; - char *temp_buf; - - I("%s: enter, %d \n", __func__, __LINE__); - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); - - himax_int_enable(private_ts->client->irq,0);//disable irq - g_self_test_entered = 1; - val = himax_chip_self_test(private_ts->client); -#ifdef HX_ESD_RECOVERY - HX_ESD_RESET_ACTIVATE = 1; -#endif - himax_int_enable(private_ts->client->irq,1);//enable irq - - if (val == 0x01) - { - ret += snprintf(temp_buf + ret, len - ret, "Self_Test Pass\n"); - } - else - { - ret += snprintf(temp_buf + ret, len - ret, "Self_Test Fail\n"); - } - g_self_test_entered = 0; - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; -} - -/* -static ssize_t himax_chip_self_test_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count) -{ - char buf_tmp[2]; - unsigned long result = 0; - - memset(buf_tmp, 0x0, sizeof(buf_tmp)); - memcpy(buf_tmp, buf, 2); - if(!kstrtoul(buf_tmp, 16, &result)) - { - sel_type = (uint8_t)result; + if (!IS_ERR(fn)) { + I("%s create file and ready to write\n", __func__); + fn->f_op->write(fn, flash_buffer, Flash_Size * sizeof(uint8_t), &fn->f_pos); + filp_close(fn, NULL); } - I("sel_type = %x \r\n", sel_type); - return count; -} -*/ - -static struct file_operations himax_proc_self_test_ops = -{ - .owner = THIS_MODULE, - .read = himax_self_test_read, -}; + } #endif -#ifdef HX_TP_PROC_SENSE_ON_OFF + himax_int_enable(1); + setFlashDumpGoing(false); + setFlashDumpComplete(1); + setSysOperation(0); + return; + /* Flash_Dump_i2c_transfer_error: + + himax_int_enable(1); + setFlashDumpGoing(false); + setFlashDumpComplete(0); + setFlashDumpFail(1); + setSysOperation(0); + return; + */ +} + + + static ssize_t himax_sense_on_off_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - char buf[80] = {0}; + char buf[80] = {0}; - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } + if (len >= 80) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } - if(buf[0] == '0') - { - himax_sense_off(private_ts->client); - I("Sense off \n"); - } - else if(buf[0] == '1') - { - if(buf[1] == 's') - { - himax_sense_on(private_ts->client, 0x00); - I("Sense on re-map on, run sram \n"); - } - else - { - himax_sense_on(private_ts->client, 0x01); - I("Sense on re-map off, run flash \n"); - } - } - else - { - I("Do nothing \n"); - } - return len; + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } + + if (buf[0] == '0') { + g_core_fp.fp_sense_off(); + I("Sense off \n"); + } else if (buf[0] == '1') { + if (buf[1] == 's') { + g_core_fp.fp_sense_on(0x00); + I("Sense on re-map on, run sram \n"); + } else { + g_core_fp.fp_sense_on(0x01); + I("Sense on re-map off, run flash \n"); + } + } else { + I("Do nothing \n"); + } + + return len; } -static struct file_operations himax_proc_sense_on_off_ops = -{ - .owner = THIS_MODULE, - .write = himax_sense_on_off_write, +static struct file_operations himax_proc_sense_on_off_ops = { + .owner = THIS_MODULE, + .write = himax_sense_on_off_write, }; -#endif - -#ifdef HX_HIGH_SENSE -static ssize_t himax_HSEN_read(struct file *file, char *buf, - size_t len, loff_t *pos) -{ - struct himax_ts_data *ts = private_ts; - size_t ret = 0; - char *temp_buf; - - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); - - ret += snprintf(temp_buf + ret, len - ret, "%d\n", ts->HSEN_enable); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; -} - -static ssize_t himax_HSEN_write(struct file *file, const char *buff, - size_t len, loff_t *pos) -{ - struct himax_ts_data *ts = private_ts; - char buf[80] = {0}; - - - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } - - if (buf[0] == '0') - { - ts->HSEN_enable = 0; - } - else if (buf[0] == '1') - { - ts->HSEN_enable = 1; - } - else - return -EINVAL; - - himax_set_HSEN_enable(ts->client, ts->HSEN_enable, ts->suspended); - - I("%s: HSEN_enable = %d.\n", __func__, ts->HSEN_enable); - - return len; -} - -static struct file_operations himax_proc_HSEN_ops = -{ - .owner = THIS_MODULE, - .read = himax_HSEN_read, - .write = himax_HSEN_write, -}; -#endif - -#ifdef HX_SMART_WAKEUP -static ssize_t himax_SMWP_read(struct file *file, char *buf, - size_t len, loff_t *pos) -{ - size_t ret = 0; - struct himax_ts_data *ts = private_ts; - char *temp_buf; - - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); - - ret += snprintf(temp_buf + ret, len - ret, "%d\n", ts->SMWP_enable); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - - return ret; -} - -static ssize_t himax_SMWP_write(struct file *file, const char *buff, - size_t len, loff_t *pos) -{ - struct himax_ts_data *ts = private_ts; - char buf[80] = {0}; - - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } - - - if (buf[0] == '0') - { - ts->SMWP_enable = 0; - } - else if (buf[0] == '1') - { - ts->SMWP_enable = 1; - } - else - return -EINVAL; - - himax_set_SMWP_enable(ts->client, ts->SMWP_enable, ts->suspended); - - HX_SMWP_EN = ts->SMWP_enable; - I("%s: SMART_WAKEUP_enable = %d.\n", __func__, HX_SMWP_EN); - - return len; -} - -static struct file_operations himax_proc_SMWP_ops = -{ - .owner = THIS_MODULE, - .read = himax_SMWP_read, - .write = himax_SMWP_write, -}; - -static ssize_t himax_GESTURE_read(struct file *file, char *buf, - size_t len, loff_t *pos) -{ - struct himax_ts_data *ts = private_ts; - int i =0; - ssize_t ret = 0; - char *temp_buf; - - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); - - for(i=0; i<16; i++) - ret += snprintf(temp_buf + ret, len - ret, "ges_en[%d]=%d \n",i,ts->gesture_cust_en[i]); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG = 1; - } - else - { - HX_PROC_SEND_FLAG = 0; - ret = 0; - } - return ret; -} - -static ssize_t himax_GESTURE_write(struct file *file, const char *buff, - size_t len, loff_t *pos) -{ - struct himax_ts_data *ts = private_ts; - int i =0; - char buf[80] = {0}; - - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } - - I("himax_GESTURE_store= %s \n",buf); - for (i=0; i<16; i++) - { - if (buf[i] == '0') - ts->gesture_cust_en[i]= 0; - else if (buf[i] == '1') - ts->gesture_cust_en[i]= 1; - else - ts->gesture_cust_en[i]= 0; - I("gesture en[%d]=%d \n", i, ts->gesture_cust_en[i]); - } - return len; -} - -static struct file_operations himax_proc_Gesture_ops = -{ - .owner = THIS_MODULE, - .read = himax_GESTURE_read, - .write = himax_GESTURE_write, -}; -#endif #ifdef HX_ESD_RECOVERY static ssize_t himax_esd_cnt_read(struct file *file, char *buf, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - ssize_t ret = 0; - char *temp_buf; + size_t ret = 0; + char *temp_buf; + I("%s: enter, %d \n", __func__, __LINE__); - I("%s: enter, %d \n", __func__, __LINE__); - if(!HX_PROC_SEND_FLAG) - { - temp_buf = kzalloc(len,GFP_KERNEL); + if (!HX_PROC_SEND_FLAG) { + temp_buf = kzalloc(len, GFP_KERNEL); + ret += snprintf(temp_buf + ret, len - ret, "EB_cnt = %d, EC_cnt = %d, ED_cnt = %d\n", hx_EB_event_flag, hx_EC_event_flag, hx_ED_event_flag); - ret += snprintf(temp_buf + ret, len - ret, "EB_cnt = %d, EC_cnt = %d, ED_cnt = %d\n",hx_EB_event_flag, hx_EC_event_flag, hx_ED_event_flag); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + if (copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n", __func__, __LINE__); + + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } else { + HX_PROC_SEND_FLAG = 0; + } + + return ret; } static ssize_t himax_esd_cnt_write(struct file *file, const char *buff, - size_t len, loff_t *pos) + size_t len, loff_t *pos) { - int i =0; - char buf[12] = {0}; - - if (len >= 12) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } - - I("Clear ESD Flag \n"); - if (buf[i] == '0') - { - hx_EB_event_flag = 0; - hx_EC_event_flag = 0; - hx_ED_event_flag = 0; - } - - return len; -} - -static struct file_operations himax_proc_esd_cnt_ops = -{ - .owner = THIS_MODULE, - .read = himax_esd_cnt_read, - .write = himax_esd_cnt_write, -}; -#endif - -#ifdef HX_TP_PROC_GUEST_INFO -extern char g_guest_str[10][128]; - - - -extern int himax_guest_info_get_status(void); -extern void himax_guest_info_set_status(int setting); - - -static ssize_t himax_proc_guest_info_read(struct file *file, char *buf, - size_t len, loff_t *pos) -{ - int ret = 0; - // int loop_i; int i = 0; - int j = 0; - char *temp_buf; - // int panel_tmp_color; - temp_buf = kzalloc(len,GFP_KERNEL); + char buf[12] = {0}; - + if (len >= 12) { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } - I("guest info progress\n"); - if(!HX_PROC_SEND_FLAG) - { - if (himax_guest_info_get_status()) - { - ret += sprintf(temp_buf + ret, "Not Ready\n"); - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - return ret; - } - for(j = 0;j<4;j++) - { - ret += sprintf(temp_buf + ret,"g_guest_str%d:\n",j); - for(i = 0;i < 128; i++) - { - if(i % 16 == 0 && i > 0) - ret += sprintf(temp_buf + ret,"\n"); - ret += sprintf(temp_buf + ret,"0x%02X\t",g_guest_str[j][i]); - - } - ret += sprintf(temp_buf + ret,"\n"); - I("str[%d] %s\n",j,g_guest_str[j]); - } - ret += sprintf(temp_buf + ret,"g_guest_str8:\n"); - for(i = 0;i < 128; i++) - { - if(i % 16 == 0 && i > 0) - ret += sprintf(temp_buf + ret,"\n"); - ret += sprintf(temp_buf + ret,"0x%02X\t",g_guest_str[8][i]); - - } - ret += sprintf(temp_buf + ret,"\n"); - - I("str[8] %s\n",g_guest_str[8]); - - ret += sprintf(temp_buf + ret,"g_guest_str9:\n"); - for(i = 0;i < 128; i++) - { - if(i % 16 == 0 && i > 0) - ret += sprintf(temp_buf + ret,"\n"); - ret += sprintf(temp_buf + ret,"0x%02X\t",g_guest_str[9][i]); - } - ret += sprintf(temp_buf + ret,"\n"); - - I("str[8] %s\n",g_guest_str[9]); - - if(copy_to_user(buf, temp_buf, len)) - I("%s,here:%d\n",__func__,__LINE__); - kfree(temp_buf); - HX_PROC_SEND_FLAG=1; - } - else - HX_PROC_SEND_FLAG=0; - return ret; + if (copy_from_user(buf, buff, len)) { + return -EFAULT; + } + + I("Clear ESD Flag \n"); + + if (buf[i] == '0') { + hx_EB_event_flag = 0; + hx_EC_event_flag = 0; + hx_ED_event_flag = 0; + } + + return len; } -static ssize_t himax_proc_guest_info_write(struct file *file, const char *buff, - size_t len, loff_t *pos) -{ - - //unsigned long result = 0; - char buf[80] = {0}; - // int shift = 0; - - if (len >= 80) - { - I("%s: no command exceeds 80 chars.\n", __func__); - return -EFAULT; - } - if (copy_from_user(buf, buff, len)) - { - return -EFAULT; - } - - I("%s: buf = %s\n", __func__, buf); - - if (getSysOperation() == 1) - { - E("%s: PROC is busy , return!\n", __func__); - return len; - } - - if (buf[0] == 'r') - { - I("%s,Test to get",__func__); - queue_work(private_ts->guest_info_wq, &private_ts->guest_info_work); - - } - - return len; -} - -static struct file_operations himax_proc_guest_info_ops = -{ - .owner = THIS_MODULE, - .read = himax_proc_guest_info_read, - .write = himax_proc_guest_info_write, +static struct file_operations himax_proc_esd_cnt_ops = { + .owner = THIS_MODULE, + .read = himax_esd_cnt_read, + .write = himax_esd_cnt_write, }; #endif +static void himax_himax_data_init(void) +{ + debug_data->fp_ts_dbg_func = himax_ts_dbg_func; + debug_data->fp_set_diag_cmd = himax_set_diag_cmd; + debug_data->flash_dump_going = false; +} +static void himax_ts_flash_work_func(struct work_struct *work) +{ + himax_ts_flash_func(); +} + +static void himax_ts_diag_work_func(struct work_struct *work) +{ + himax_ts_diag_func(); +} int himax_touch_proc_init(void) { - himax_touch_proc_dir = proc_mkdir( HIMAX_PROC_TOUCH_FOLDER, NULL); - if (himax_touch_proc_dir == NULL) - { - E(" %s: himax_touch_proc_dir file create failed!\n", __func__); - return -ENOMEM; - } + himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_debug_level_ops); + if (himax_proc_debug_level_file == NULL) { + E(" %s: proc debug_level file create failed!\n", __func__); + goto fail_1; + } - himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_debug_level_ops); - if (himax_proc_debug_level_file == NULL) - { - E(" %s: proc debug_level file create failed!\n", __func__); - goto fail_1; - } + himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE, (S_IRUGO), + himax_touch_proc_dir, &himax_proc_vendor_ops); + if (himax_proc_vendor_file == NULL) { + E(" %s: proc vendor file create failed!\n", __func__); + goto fail_2; + } - himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE, (S_IRUGO), - himax_touch_proc_dir, &himax_proc_vendor_ops); - if(himax_proc_vendor_file == NULL) - { - E(" %s: proc vendor file create failed!\n", __func__); - goto fail_2; - } + himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE, (S_IRUGO), + himax_touch_proc_dir, &himax_proc_attn_ops); + if (himax_proc_attn_file == NULL) { + E(" %s: proc attn file create failed!\n", __func__); + goto fail_3; + } - himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE, (S_IRUGO), - himax_touch_proc_dir, &himax_proc_attn_ops); - if(himax_proc_attn_file == NULL) - { - E(" %s: proc attn file create failed!\n", __func__); - goto fail_3; - } + himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_int_en_ops); + if (himax_proc_int_en_file == NULL) { + E(" %s: proc int en file create failed!\n", __func__); + goto fail_4; + } - himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_int_en_ops); - if(himax_proc_int_en_file == NULL) - { - E(" %s: proc int en file create failed!\n", __func__); - goto fail_4; - } + himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_layout_ops); + if (himax_proc_layout_file == NULL) { + E(" %s: proc layout file create failed!\n", __func__); + goto fail_5; + } - himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_layout_ops); - if(himax_proc_layout_file == NULL) - { - E(" %s: proc layout file create failed!\n", __func__); - goto fail_5; - } + himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE, (S_IWUSR), + himax_touch_proc_dir, &himax_proc_reset_ops); + if (himax_proc_reset_file == NULL) { + E(" %s: proc reset file create failed!\n", __func__); + goto fail_6; + } -#ifdef HX_TP_PROC_RESET - himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE, (S_IWUSR), - himax_touch_proc_dir, &himax_proc_reset_ops); - if(himax_proc_reset_file == NULL) - { - E(" %s: proc reset file create failed!\n", __func__); - goto fail_6; - } -#endif + himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_diag_ops); + if (himax_proc_diag_file == NULL) { + E(" %s: proc diag file create failed!\n", __func__); + goto fail_7; + } -#ifdef HX_TP_PROC_DIAG - himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_diag_ops); - if(himax_proc_diag_file == NULL) - { - E(" %s: proc diag file create failed!\n", __func__); - goto fail_7; - } - himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_diag_arrange_ops); - if(himax_proc_diag_arrange_file == NULL) - { - E(" %s: proc diag file create failed!\n", __func__); - goto fail_7_1; - } -#endif + himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_diag_arrange_ops); + if (himax_proc_diag_arrange_file == NULL) { + E(" %s: proc diag file create failed!\n", __func__); + goto fail_7_1; + } -#ifdef HX_TP_PROC_REGISTER - himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_register_ops); - if(himax_proc_register_file == NULL) - { - E(" %s: proc register file create failed!\n", __func__); - goto fail_8; - } -#endif + himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_register_ops); + if (himax_proc_register_file == NULL) { + E(" %s: proc register file create failed!\n", __func__); + goto fail_8; + } -#ifdef HX_TP_PROC_DEBUG - himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_debug_ops); - if(himax_proc_debug_file == NULL) - { - E(" %s: proc debug file create failed!\n", __func__); - goto fail_9; - } + himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_debug_ops); + if (himax_proc_debug_file == NULL) { + E(" %s: proc debug file create failed!\n", __func__); + goto fail_9; + } - himax_proc_fw_debug_file = proc_create(HIMAX_PROC_FW_DEBUG_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_fw_debug_ops); - if(himax_proc_fw_debug_file == NULL) - { - E(" %s: proc fw debug file create failed!\n", __func__); - goto fail_9_1; - } + himax_proc_fw_debug_file = proc_create(HIMAX_PROC_FW_DEBUG_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_fw_debug_ops); + if (himax_proc_fw_debug_file == NULL) { + E(" %s: proc fw debug file create failed!\n", __func__); + goto fail_9_1; + } - himax_proc_dd_debug_file = proc_create(HIMAX_PROC_DD_DEBUG_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_dd_debug_ops); - if(himax_proc_dd_debug_file == NULL) - { - E(" %s: proc DD debug file create failed!\n", __func__); - goto fail_9_2; - } -#endif + himax_proc_dd_debug_file = proc_create(HIMAX_PROC_DD_DEBUG_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_dd_debug_ops); + if (himax_proc_dd_debug_file == NULL) { + E(" %s: proc DD debug file create failed!\n", __func__); + goto fail_9_2; + } -#ifdef HX_TP_PROC_FLASH_DUMP - himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE, (S_IWUSR|S_IRUGO), - himax_touch_proc_dir, &himax_proc_flash_ops); - if(himax_proc_flash_dump_file == NULL) - { - E(" %s: proc flash dump file create failed!\n", __func__); - goto fail_10; - } -#endif + himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE, (S_IWUSR | S_IRUGO), + himax_touch_proc_dir, &himax_proc_flash_ops); + if (himax_proc_flash_dump_file == NULL) { + E(" %s: proc flash dump file create failed!\n", __func__); + goto fail_10; + } -#ifdef HX_TP_PROC_SELF_TEST - himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE, (S_IRUGO), - himax_touch_proc_dir, &himax_proc_self_test_ops); - if(himax_proc_self_test_file == NULL) - { - E(" %s: proc self_test file create failed!\n", __func__); - goto fail_11; - } -#endif + himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE, (S_IWUSR | S_IRUGO | S_IWUGO), + himax_touch_proc_dir, &himax_proc_sense_on_off_ops); + if (himax_proc_SENSE_ON_OFF_file == NULL) { + E(" %s: proc SENSE_ON_OFF file create failed!\n", __func__); + goto fail_16; + } -#ifdef HX_HIGH_SENSE - himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), - himax_touch_proc_dir, &himax_proc_HSEN_ops); - if(himax_proc_HSEN_file == NULL) - { - E(" %s: proc HSEN file create failed!\n", __func__); - goto fail_13; - } -#endif - -#ifdef HX_SMART_WAKEUP - himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), - himax_touch_proc_dir, &himax_proc_SMWP_ops); - if(himax_proc_SMWP_file == NULL) - { - E(" %s: proc SMWP file create failed!\n", __func__); - goto fail_14; - } - himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), - himax_touch_proc_dir, &himax_proc_Gesture_ops); - if(himax_proc_GESTURE_file == NULL) - { - E(" %s: proc GESTURE file create failed!\n", __func__); - goto fail_15; - } -#endif - -#ifdef HX_TP_PROC_SENSE_ON_OFF - himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), - himax_touch_proc_dir, &himax_proc_sense_on_off_ops); - if(himax_proc_SENSE_ON_OFF_file == NULL) - { - E(" %s: proc SENSE_ON_OFF file create failed!\n", __func__); - goto fail_16; - } -#endif #ifdef HX_ESD_RECOVERY - himax_proc_ESD_cnt_file = proc_create(HIMAX_PROC_ESD_CNT_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), - himax_touch_proc_dir, &himax_proc_esd_cnt_ops); - if(himax_proc_ESD_cnt_file == NULL) - { - E(" %s: proc ESD cnt file create failed!\n", __func__); - goto fail_17; - } -#endif - himax_proc_CRC_test_file = proc_create(HIMAX_PROC_CRC_TEST_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), - himax_touch_proc_dir, &himax_proc_CRC_test_ops); - if(himax_proc_CRC_test_file == NULL) - { - E(" %s: proc CRC test file create failed!\n", __func__); - goto fail_18; - } -#ifdef HX_TP_PROC_GUEST_INFO - himax_proc_guest_info_file = proc_create(HIMAX_PROC_GUEST_INFO_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), - himax_touch_proc_dir, &himax_proc_guest_info_ops); - if(himax_proc_guest_info_file == NULL) - { - E(" %s: proc guest information file create failed!\n", __func__); - goto fail_19; - } -#endif - return 0 ; + himax_proc_ESD_cnt_file = proc_create(HIMAX_PROC_ESD_CNT_FILE, (S_IWUSR | S_IRUGO | S_IWUGO), + himax_touch_proc_dir, &himax_proc_esd_cnt_ops); -#ifdef HX_TP_PROC_GUEST_INFO -fail_19: - remove_proc_entry(HIMAX_PROC_GUEST_INFO_FILE, himax_touch_proc_dir); -#endif + if (himax_proc_ESD_cnt_file == NULL) { + E(" %s: proc ESD cnt file create failed!\n", __func__); + goto fail_17; + } + +#endif + himax_proc_CRC_test_file = proc_create(HIMAX_PROC_CRC_TEST_FILE, (S_IWUSR | S_IRUGO | S_IWUGO), + himax_touch_proc_dir, &himax_proc_CRC_test_ops); + + if (himax_proc_CRC_test_file == NULL) { + E(" %s: proc CRC test file create failed!\n", __func__); + goto fail_18; + } + + return 0 ; fail_18: #ifdef HX_ESD_RECOVERY - remove_proc_entry( HIMAX_PROC_ESD_CNT_FILE, himax_touch_proc_dir ); + remove_proc_entry(HIMAX_PROC_ESD_CNT_FILE, himax_touch_proc_dir); fail_17: #endif -#ifdef HX_TP_PROC_SENSE_ON_OFF - remove_proc_entry( HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir ); -fail_16: -#endif -#ifdef HX_SMART_WAKEUP - remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir ); -fail_15: - remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir ); -fail_14: -#endif -#ifdef HX_HIGH_SENSE - remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir ); -fail_13: -#endif -#ifdef HX_TP_PROC_SELF_TEST - remove_proc_entry( HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir ); -fail_11: -#endif -#ifdef HX_TP_PROC_FLASH_DUMP - remove_proc_entry( HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir ); -fail_10: -#endif -#ifdef HX_TP_PROC_DEBUG - remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir ); -fail_9: - remove_proc_entry( HIMAX_PROC_FW_DEBUG_FILE, himax_touch_proc_dir ); -fail_9_1: - remove_proc_entry( HIMAX_PROC_DD_DEBUG_FILE, himax_touch_proc_dir ); -fail_9_2: -#endif -#ifdef HX_TP_PROC_REGISTER - remove_proc_entry( HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir ); -fail_8: -#endif -#ifdef HX_TP_PROC_DIAG - remove_proc_entry( HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir ); -fail_7: - remove_proc_entry( HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir ); -fail_7_1: -#endif -#ifdef HX_TP_PROC_RESET - remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir ); -fail_6: -#endif - remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir ); -fail_5: - remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir ); -fail_4: - remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir ); -fail_3: - remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir ); -fail_2: - remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir ); + remove_proc_entry(HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir); +fail_16: remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir); +fail_10: remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir); +fail_9: remove_proc_entry(HIMAX_PROC_FW_DEBUG_FILE, himax_touch_proc_dir); +fail_9_1: remove_proc_entry(HIMAX_PROC_DD_DEBUG_FILE, himax_touch_proc_dir); +fail_9_2: remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir); +fail_8: remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir); +fail_7: remove_proc_entry(HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir); +fail_7_1: remove_proc_entry(HIMAX_PROC_RESET_FILE, himax_touch_proc_dir); +fail_6: remove_proc_entry(HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir); +fail_5: remove_proc_entry(HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir); +fail_4: remove_proc_entry(HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir); +fail_3: remove_proc_entry(HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir); +fail_2: remove_proc_entry(HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir); fail_1: - remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL ); - return -ENOMEM; + return -ENOMEM; } void himax_touch_proc_deinit(void) { - remove_proc_entry( HIMAX_PROC_CRC_TEST_FILE, himax_touch_proc_dir ); + remove_proc_entry(HIMAX_PROC_CRC_TEST_FILE, himax_touch_proc_dir); #ifdef HX_ESD_RECOVERY - remove_proc_entry( HIMAX_PROC_ESD_CNT_FILE, himax_touch_proc_dir ); + remove_proc_entry(HIMAX_PROC_ESD_CNT_FILE, himax_touch_proc_dir); #endif -#ifdef HX_TP_PROC_SENSE_ON_OFF - remove_proc_entry( HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir ); -#endif -#ifdef HX_SMART_WAKEUP - remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir ); - remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir ); -#endif -#ifdef HX_DOT_VIEW - remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir ); -#endif -#ifdef HX_TP_PROC_SELF_TEST - remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir); -#endif -#ifdef HX_TP_PROC_FLASH_DUMP - remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir); -#endif -#ifdef HX_TP_PROC_DEBUG - remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir ); - remove_proc_entry( HIMAX_PROC_FW_DEBUG_FILE, himax_touch_proc_dir ); - remove_proc_entry( HIMAX_PROC_DD_DEBUG_FILE, himax_touch_proc_dir ); -#endif -#ifdef HX_TP_PROC_REGISTER - remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir); -#endif -#ifdef HX_TP_PROC_DIAG - remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir); -#endif -#ifdef HX_TP_PROC_RESET - remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir ); -#endif -#ifdef HX_TP_PROC_GUEST_INFO - remove_proc_entry(HIMAX_PROC_GUEST_INFO_FILE, himax_touch_proc_dir); -#endif - remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir ); - remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir ); - remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir ); - remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir ); - remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir ); - remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL ); + remove_proc_entry(HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_FW_DEBUG_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_DD_DEBUG_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_RESET_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir); + remove_proc_entry(HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir); } + +int himax_debug_init(void) +{ + struct himax_ts_data *ts = private_ts; + int err = 0; + + I("%s:Enter\n", __func__); + + if (ts == NULL) { + E("%s: ts struct is NULL \n", __func__); + return -EPROBE_DEFER; + } + + debug_data = kzalloc(sizeof(*debug_data), GFP_KERNEL); + if (debug_data == NULL) { /*Allocate debug data space*/ + err = -ENOMEM; + goto err_alloc_debug_data_fail; + } + + himax_himax_data_init(); + + ts->flash_wq = create_singlethread_workqueue("himax_flash_wq"); + + if (!ts->flash_wq) { + E("%s: create flash workqueue failed\n", __func__); + err = -ENOMEM; + goto err_create_flash_dump_wq_failed; + } + + INIT_WORK(&ts->flash_work, himax_ts_flash_work_func); + setSysOperation(0); + setFlashBuffer(); + + ts->himax_diag_wq = create_singlethread_workqueue("himax_diag"); + + if (!ts->himax_diag_wq) { + E("%s: create diag workqueue failed\n", __func__); + err = -ENOMEM; + goto err_create_diag_wq_failed; + } + + INIT_DELAYED_WORK(&ts->himax_diag_delay_wrok, himax_ts_diag_work_func); + + setXChannel(ic_data->HX_RX_NUM); /*X channel*/ + setYChannel(ic_data->HX_TX_NUM); /*Y channel*/ + setMutualBuffer(); + setMutualNewBuffer(); + setMutualOldBuffer(); + + if (getMutualBuffer() == NULL) { + E("%s: mutual buffer allocate fail failed\n", __func__); + return MEM_ALLOC_FAIL; + } +#ifdef HX_TP_PROC_2T2R + + if (Is_2T2R) { + setXChannel_2(ic_data->HX_RX_NUM_2); /*X channel*/ + setYChannel_2(ic_data->HX_TX_NUM_2); /*Y channel*/ + setMutualBuffer_2(); + + if (getMutualBuffer_2() == NULL) { + E("%s: mutual buffer 2 allocate fail failed\n", __func__); + return MEM_ALLOC_FAIL; + } + } #endif + + himax_touch_proc_init(); + + return 0; + + cancel_delayed_work_sync(&ts->himax_diag_delay_wrok); + destroy_workqueue(ts->himax_diag_wq); +err_create_diag_wq_failed: + + destroy_workqueue(ts->flash_wq); +err_create_flash_dump_wq_failed: + +err_alloc_debug_data_fail: + + return err; +} + +int himax_debug_remove(void) +{ + struct himax_ts_data *ts = private_ts; + + himax_touch_proc_deinit(); + + cancel_delayed_work_sync(&ts->himax_diag_delay_wrok); + destroy_workqueue(ts->himax_diag_wq); + destroy_workqueue(ts->flash_wq); + + kfree(debug_data); + + return 0; +} + diff --git a/drivers/input/touchscreen/himax_mmi/himax_debug.h b/drivers/input/touchscreen/himax_mmi/himax_debug.h index 998a6334522a..90d634ec6d9d 100644 --- a/drivers/input/touchscreen/himax_mmi/himax_debug.h +++ b/drivers/input/touchscreen/himax_mmi/himax_debug.h @@ -1,16 +1,16 @@ -/* Himax Android Driver Sample Code for debug nodes -* -* Copyright (C) 2017 Himax Corporation. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* +/* Himax Android Driver Sample Code for debug nodes + + Copyright (C) 2018 Himax Corporation. + + This software is licensed under the terms of the GNU General Public + License version 2, as published by the Free Software Foundation, and + may be copied, distributed, and modified under those terms. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + */ #ifndef H_HIMAX_DEBUG #define H_HIMAX_DEBUG @@ -20,14 +20,12 @@ #ifdef HX_ESD_RECOVERY -extern u8 HX_ESD_RESET_ACTIVATE; -extern int hx_EB_event_flag; -extern int hx_EC_event_flag; -extern int hx_ED_event_flag; + extern u8 HX_ESD_RESET_ACTIVATE; + extern int hx_EB_event_flag; + extern int hx_EC_event_flag; + extern int hx_ED_event_flag; #endif -#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) -#define HIMAX_PROC_TOUCH_FOLDER "android_touch" #define HIMAX_PROC_DEBUG_LEVEL_FILE "debug_level" #define HIMAX_PROC_VENDOR_FILE "vendor" #define HIMAX_PROC_ATTN_FILE "attn" @@ -35,47 +33,23 @@ extern int hx_ED_event_flag; #define HIMAX_PROC_LAYOUT_FILE "layout" #define HIMAX_PROC_CRC_TEST_FILE "CRC_test" -static struct proc_dir_entry *himax_touch_proc_dir = NULL; -static struct proc_dir_entry *himax_proc_debug_level_file = NULL; -static struct proc_dir_entry *himax_proc_vendor_file = NULL; -static struct proc_dir_entry *himax_proc_attn_file = NULL; -static struct proc_dir_entry *himax_proc_int_en_file = NULL; -static struct proc_dir_entry *himax_proc_layout_file = NULL; -static struct proc_dir_entry *himax_proc_CRC_test_file = NULL; +static struct proc_dir_entry *himax_proc_debug_level_file; +static struct proc_dir_entry *himax_proc_vendor_file; +static struct proc_dir_entry *himax_proc_attn_file; +static struct proc_dir_entry *himax_proc_int_en_file; +static struct proc_dir_entry *himax_proc_layout_file; +static struct proc_dir_entry *himax_proc_CRC_test_file; -uint8_t HX_PROC_SEND_FLAG; +int himax_touch_proc_init(void); +void himax_touch_proc_deinit(void); +extern int himax_int_en_set(void); -extern int himax_touch_proc_init(void); -extern void himax_touch_proc_deinit(void); -bool getFlashDumpGoing(void); - -extern int himax_int_en_set(struct i2c_client *client); - -#ifdef HX_TP_PROC_GUEST_INFO -#define HIMAX_PROC_GUEST_INFO_FILE "guest_info" -static struct proc_dir_entry *himax_proc_guest_info_file = NULL; -#endif - -#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) -#define HIMAX_PROC_ITO_TEST_FILE "ITO_test" -static struct proc_dir_entry *himax_proc_ito_test_file = NULL; - -extern void ito_set_step_status(uint8_t status); -extern uint8_t ito_get_step_status(void); -extern void ito_set_result_status(uint8_t status); -extern uint8_t ito_get_result_status(void); - -#endif - -#ifdef HX_TP_PROC_REGISTER #define HIMAX_PROC_REGISTER_FILE "register" struct proc_dir_entry *himax_proc_register_file = NULL; uint8_t byte_length = 0; uint8_t register_command[4]; -bool cfg_flag = false; -#endif +uint8_t cfg_flag = 0; -#ifdef HX_TP_PROC_DIAG #define HIMAX_PROC_DIAG_FILE "diag" struct proc_dir_entry *himax_proc_diag_file = NULL; #define HIMAX_PROC_DIAG_ARR_FILE "diag_arr" @@ -86,133 +60,95 @@ uint8_t write_max_count = 30; #define IIR_DUMP_FILE "/sdcard/HX_IIR_Dump.txt" #define DC_DUMP_FILE "/sdcard/HX_DC_Dump.txt" #define BANK_DUMP_FILE "/sdcard/HX_BANK_Dump.txt" - #ifdef HX_TP_PROC_2T2R -static uint8_t x_channel_2 = 0; -static uint8_t y_channel_2 = 0; -static uint32_t *diag_mutual_2 = NULL; - -int32_t *getMutualBuffer_2(void); -uint8_t getXChannel_2(void); -uint8_t getYChannel_2(void); - -void setMutualBuffer_2(void); -void setXChannel_2(uint8_t x); -void setYChannel_2(uint8_t y); + static uint8_t x_channel_2; + static uint8_t y_channel_2; + static uint32_t *diag_mutual_2; + int32_t *getMutualBuffer_2(void); + uint8_t getXChannel_2(void); + uint8_t getYChannel_2(void); + void setMutualBuffer_2(void); + void setXChannel_2(uint8_t x); + void setYChannel_2(uint8_t y); #endif uint8_t x_channel = 0; uint8_t y_channel = 0; - int32_t *diag_mutual = NULL; - int32_t *diag_mutual_new = NULL; - int32_t *diag_mutual_old = NULL; +int32_t *diag_mutual = NULL; +int32_t *diag_mutual_new = NULL; +int32_t *diag_mutual_old = NULL; uint8_t diag_max_cnt = 0; uint8_t hx_state_info[2] = {0}; - -int g_diag_command = 0; -uint8_t diag_coor[128];// = {0xFF}; - int32_t diag_self[100] = {0}; - - int32_t *getMutualBuffer(void); - int32_t *getMutualNewBuffer(void); - int32_t *getMutualOldBuffer(void); - int32_t *getSelfBuffer(void); -uint8_t getDiagCommand(void); +uint8_t diag_coor[128]; +int32_t diag_self[100] = {0}; +int32_t diag_self_new[100] = {0}; +int32_t diag_self_old[100] = {0}; +int32_t *getMutualBuffer(void); +int32_t *getMutualNewBuffer(void); +int32_t *getMutualOldBuffer(void); +int32_t *getSelfBuffer(void); +int32_t *getSelfNewBuffer(void); +int32_t *getSelfOldBuffer(void); uint8_t getXChannel(void); uint8_t getYChannel(void); - void setMutualBuffer(void); void setMutualNewBuffer(void); void setMutualOldBuffer(void); void setXChannel(uint8_t x); void setYChannel(uint8_t y); -#endif -#ifdef HX_TP_PROC_DEBUG #define HIMAX_PROC_DEBUG_FILE "debug" struct proc_dir_entry *himax_proc_debug_file = NULL; #define HIMAX_PROC_FW_DEBUG_FILE "FW_debug" struct proc_dir_entry *himax_proc_fw_debug_file = NULL; #define HIMAX_PROC_DD_DEBUG_FILE "DD_debug" struct proc_dir_entry *himax_proc_dd_debug_file = NULL; - bool fw_update_complete = false; int handshaking_result = 0; unsigned char debug_level_cmd = 0; -unsigned char upgrade_fw[128*1024]; uint8_t cmd_set[8]; uint8_t mutual_set_flag = 0; -#endif -#ifdef HX_TP_PROC_FLASH_DUMP #define HIMAX_PROC_FLASH_DUMP_FILE "flash_dump" struct proc_dir_entry *himax_proc_flash_dump_file = NULL; - static int Flash_Size = 131072; -static uint8_t *flash_buffer = NULL; -static uint8_t flash_command = 0; -static uint8_t flash_read_step = 0; -static uint8_t flash_progress = 0; -static uint8_t flash_dump_complete = 0; -static uint8_t flash_dump_fail = 0; -static uint8_t sys_operation = 0; -static bool flash_dump_going = false; - +static uint8_t *flash_buffer; +static uint8_t flash_command; +static uint8_t flash_read_step; +static uint8_t flash_progress; +static uint8_t flash_dump_complete; +static uint8_t flash_dump_fail; +static uint8_t sys_operation; +static bool flash_dump_going; static uint8_t getFlashDumpComplete(void); static uint8_t getFlashDumpFail(void); static uint8_t getFlashDumpProgress(void); static uint8_t getFlashReadStep(void); uint8_t getFlashCommand(void); uint8_t getSysOperation(void); - static void setFlashCommand(uint8_t command); static void setFlashReadStep(uint8_t step); - void setFlashBuffer(void); void setFlashDumpComplete(uint8_t complete); void setFlashDumpFail(uint8_t fail); void setFlashDumpProgress(uint8_t progress); void setSysOperation(uint8_t operation); void setFlashDumpGoing(bool going); +bool getFlashDumpGoing(void); -#endif -#ifdef HX_TP_PROC_SELF_TEST -#define HIMAX_PROC_SELF_TEST_FILE "self_test" -struct proc_dir_entry *himax_proc_self_test_file = NULL; uint32_t **raw_data_array; uint8_t X_NUM = 0, Y_NUM = 0; uint8_t sel_type = 0x0D; -#endif -#ifdef HX_TP_PROC_RESET #define HIMAX_PROC_RESET_FILE "reset" struct proc_dir_entry *himax_proc_reset_file = NULL; -#endif -#ifdef HX_HIGH_SENSE -#define HIMAX_PROC_HSEN_FILE "HSEN" -struct proc_dir_entry *himax_proc_HSEN_file = NULL; -#endif - -#ifdef HX_TP_PROC_SENSE_ON_OFF #define HIMAX_PROC_SENSE_ON_OFF_FILE "SenseOnOff" struct proc_dir_entry *himax_proc_SENSE_ON_OFF_file = NULL; -#endif - -#ifdef HX_SMART_WAKEUP -#define HIMAX_PROC_SMWP_FILE "SMWP" -struct proc_dir_entry *himax_proc_SMWP_file = NULL; -#define HIMAX_PROC_GESTURE_FILE "GESTURE" -struct proc_dir_entry *himax_proc_GESTURE_file = NULL; -uint8_t HX_SMWP_EN = 0; -//extern bool FAKE_POWER_KEY_SEND; -#endif #ifdef HX_ESD_RECOVERY -#define HIMAX_PROC_ESD_CNT_FILE "ESD_cnt" -struct proc_dir_entry *himax_proc_ESD_cnt_file = NULL; -#endif - + #define HIMAX_PROC_ESD_CNT_FILE "ESD_cnt" + struct proc_dir_entry *himax_proc_ESD_cnt_file = NULL; #endif #endif diff --git a/drivers/input/touchscreen/himax_mmi/himax_ic.c b/drivers/input/touchscreen/himax_mmi/himax_ic.c deleted file mode 100644 index 7019c4034c81..000000000000 --- a/drivers/input/touchscreen/himax_mmi/himax_ic.c +++ /dev/null @@ -1,4036 +0,0 @@ -/* Himax Android Driver Sample Code for HX83112 chipset -* -* Copyright (C) 2017 Himax Corporation. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -*/ - -#include "himax_ic.h" - -extern int i2c_error_count; - -extern unsigned long FW_VER_MAJ_FLASH_ADDR; -extern unsigned long FW_VER_MIN_FLASH_ADDR; -extern unsigned long CFG_VER_MAJ_FLASH_ADDR; -extern unsigned long CFG_VER_MIN_FLASH_ADDR; -extern unsigned long CID_VER_MAJ_FLASH_ADDR; -extern unsigned long CID_VER_MIN_FLASH_ADDR; - -extern unsigned long FW_VER_MAJ_FLASH_LENG; -extern unsigned long FW_VER_MIN_FLASH_LENG; -extern unsigned long CFG_VER_MAJ_FLASH_LENG; -extern unsigned long CFG_VER_MIN_FLASH_LENG; -extern unsigned long CID_VER_MAJ_FLASH_LENG; -extern unsigned long CID_VER_MIN_FLASH_LENG; - -#ifdef HX_AUTO_UPDATE_FW -extern int g_i_FW_VER; -extern int g_i_CFG_VER; -extern int g_i_CID_MAJ; -extern int g_i_CID_MIN; -extern unsigned char i_CTPM_FW[]; -#endif - -extern unsigned char IC_TYPE; -extern unsigned char IC_CHECKSUM; - -extern bool DSRAM_Flag; - -extern struct himax_ic_data* ic_data; -extern struct himax_ts_data *private_ts; - -int himax_touch_data_size = 128; - -char* g_himax_inspection_mode[]= -{ - "HIMAX_INSPECTION_OPEN", - "HIMAX_INSPECTION_MICRO_OPEN", - "HIMAX_INSPECTION_SHORT", - "HIMAX_INSPECTION_RAWDATA", - "HIMAX_INSPECTION_NOISE", - "HIMAX_INSPECTION_SORTING", - "HIMAX_INSPECTION_BACK_NORMAL", -#ifdef HX_DOZE_TEST - "HIMAX_INSPECTION_DOZE_RAWDATA", - "HIMAX_INSPECTION_DOZE_NOISE", -#endif -#ifdef HX_INSPECT_LPWUG_TEST - "HIMAX_INSPECTION_LPWUG_RAWDATA", - "HIMAX_INSPECTION_LPWUG_NOISE", - "HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA", - "HIMAX_INSPECTION_LPWUG_IDLE_NOISE", -#endif -}; - -#ifdef HX_TP_PROC_2T2R -bool Is_2T2R = false; -#endif - -#ifdef HX_USB_DETECT_GLOBAL -//extern kal_bool upmu_is_chr_det(void); -extern void himax_cable_detect_func(bool force_renew); -#endif - -int himax_get_touch_data_size(void) -{ - return himax_touch_data_size; -} - -#ifdef HX_RST_PIN_FUNC -extern void himax_rst_gpio_set(int pinnum, uint8_t value); -extern int himax_report_data_init(void); -extern u8 HX_HW_RESET_ACTIVATE; - -void himax_pin_reset(void) -{ - I("%s: Now reset the Touch chip.\n", __func__); - himax_rst_gpio_set(private_ts->rst_gpio, 0); - msleep(20); - himax_rst_gpio_set(private_ts->rst_gpio, 1); - msleep(20); -} - -void himax_reload_config(void) -{ - if(himax_report_data_init()) - E("%s: allocate data fail\n",__func__); - - himax_sense_on(private_ts->client, 0x00); -} - -void himax_irq_switch(int switch_on) -{ - int ret = 0; - if(switch_on) - { - - if (private_ts->use_irq) - himax_int_enable(private_ts->client->irq,switch_on); - else - hrtimer_start(&private_ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - } - else - { - if (private_ts->use_irq) - himax_int_enable(private_ts->client->irq,switch_on); - else - { - hrtimer_cancel(&private_ts->timer); - ret = cancel_work_sync(&private_ts->work); - } - } -} - -void himax_ic_reset(uint8_t loadconfig,uint8_t int_off) -{ - struct himax_ts_data *ts = private_ts; - - HX_HW_RESET_ACTIVATE = 0; - - I("%s,status: loadconfig=%d,int_off=%d\n",__func__,loadconfig,int_off); - - if (ts->rst_gpio >= 0) - { - if(int_off) - { - himax_irq_switch(0); - } - - himax_pin_reset(); - if(loadconfig) - { - himax_reload_config(); - } - if(int_off) - { - himax_irq_switch(1); - } - } - -} -#endif - -#if defined(HX_ESD_RECOVERY) -int g_zero_event_count = 0; -int himax_ic_esd_recovery(int hx_esd_event,int hx_zero_event,int length) -{ - if(g_zero_event_count > 5) - { - g_zero_event_count = 0; - I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n"); - goto checksum_fail; - } - - if(hx_esd_event == length) - { - g_zero_event_count = 0; - goto checksum_fail; - } - else if(hx_zero_event == length) - { - g_zero_event_count++; - I("[HIMAX TP MSG]: ALL Zero event is %d times.\n",g_zero_event_count); - goto err_workqueue_out; - } - -checksum_fail: - return CHECKSUM_FAIL; -err_workqueue_out: - return WORK_OUT; -} -void himax_esd_ic_reset(void) -{ - HX_ESD_RESET_ACTIVATE = 0; -#ifdef HX_RST_PIN_FUNC - himax_pin_reset(); -#endif - E("%s:\n", __func__); -} -#endif - -int himax_hand_shaking(struct i2c_client *client) //0:Running, 1:Stop, 2:I2C Fail -{ - int result = 0; - - return result; -} - -void himax_idle_mode(struct i2c_client *client,int disable) -{ - int retry = 20; - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t switch_cmd = 0x00; - - I("%s:entering\n",__func__); - do - { - - I("%s,now %d times\n!",__func__,retry); - - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x70; - tmp_addr[0] = 0x88; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - - if(disable) - switch_cmd = 0x17; - else - switch_cmd = 0x1F; - - tmp_data[0] = switch_cmd; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - himax_register_read(client, tmp_addr, 4, tmp_data, false); - I("%s:After turn ON/OFF IDLE Mode [0] = 0x%02X,[1] = 0x%02X,[2] = 0x%02X,[3] = 0x%02X\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]); - - retry--; - msleep(10); - - } - while((tmp_data[0] != switch_cmd) && retry > 0); - - I("%s: setting OK!\n",__func__); - -} - -int himax_write_read_reg(struct i2c_client *client,uint8_t *tmp_addr,uint8_t *tmp_data,uint8_t hb,uint8_t lb) -{ - int cnt = 0; - - do - { - himax_flash_write_burst(client, tmp_addr, tmp_data); - - msleep(10); - himax_register_read(client, tmp_addr, 4, tmp_data, false); - //I("%s:Now tmp_data[0]=0x%02X,[1]=0x%02X,[2]=0x%02X,[3]=0x%02X\n",__func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]); - } - while((tmp_data[1] != hb && tmp_data[0] != lb) && cnt++ < 100); - - if(cnt == 99) - return -1; - - I("Now register 0x%08X : high byte=0x%02X,low byte=0x%02X\n",tmp_addr[3],tmp_data[1],tmp_data[0]); - return NO_ERR; -} - -int himax_determin_diag_rawdata(int diag_command) -{ - return diag_command%10; -} - -int himax_determin_diag_storage(int diag_command) -{ - return diag_command/10; -} - -void himax_reload_disable(struct i2c_client *client,int on) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - I("%s:entering\n",__func__); - - if(on)/*reload disable*/ - { - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0xA5; tmp_data[0] = 0x5A; - } - else/*reload enable*/ - { - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; - } - - himax_flash_write_burst(client, tmp_addr, tmp_data); - - I("%s: setting OK!\n",__func__); -} - -int himax_switch_mode(struct i2c_client *client,int mode) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t mode_wirte_cmd; - uint8_t mode_read_cmd; - int result = -1; - int retry = 200; - - I("%s: Entering\n",__func__); - - if(mode == 0) /*normal mode*/ - { - mode_wirte_cmd = 0x00; - mode_read_cmd = 0x99; - } - else /*sorting mode*/ - { - mode_wirte_cmd = 0xAA; - mode_read_cmd = 0xCC; - } - - himax_sense_off(client); - - //himax_interface_on(client); - - /* */ - - /* clean up FW status */ - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - //msleep(30); - - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x04; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = mode_wirte_cmd; - tmp_data[0] = mode_wirte_cmd; - himax_flash_write_burst(client, tmp_addr, tmp_data); - //msleep(30); - - himax_idle_mode(client,1); - himax_reload_disable(client,1); - - // To stable the sorting //skip frames - if(mode) - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x70; - tmp_addr[0] = 0xF4; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x08; - himax_flash_write_burst(client, tmp_addr, tmp_data); - } - else - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x72; - tmp_addr[0] = 0x94; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x50;/*0x50 normal mode 80 frame*/ - /* N Frame Sorting*/ - himax_flash_write_burst(client, tmp_addr, tmp_data); - - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x70; - tmp_addr[0] = 0xF4; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x14; - himax_flash_write_burst(client, tmp_addr, tmp_data); - } - - himax_sense_on(client,0x01); - I("mode_wirte_cmd(0)=0x%2.2X,mode_wirte_cmd(1)=0x%2.2X\n",tmp_data[0],tmp_data[1]); - while(retry!=0) - { - I("[%d]Read 10007F04!\n",retry); - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x04; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - msleep(100); - I("mode_read_cmd(0)=0x%2.2X,mode_read_cmd(1)=0x%2.2X\n",tmp_data[0],tmp_data[1]); - if(tmp_data[0] == mode_read_cmd && tmp_data[1] == mode_read_cmd) - { - I("Read OK!\n"); - result = 0; - break; - } - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0xA8; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - if(tmp_data[0] == 0x00 && tmp_data[1] == 0x00 && tmp_data[2] == 0x00 && tmp_data[3] == 0x00) - { - E("%s,: FW Stop!\n",__func__); - break; - } - retry--; - } - - if(result == 0) - { - if(mode == 0) - return 1; //normal mode - else - return 2; //sorting mode - } - else - return -1; //change mode fail -} - -void himax_return_event_stack(struct i2c_client *client) -{ - int retry = 20; - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - I("%s:entering\n",__func__); - do - { - - I("%s,now %d times\n!",__func__,retry); - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - himax_register_read(client, tmp_addr, 4, tmp_data, false); - retry--; - msleep(10); - - } - while((tmp_data[1] != 0x00 && tmp_data[0] != 0x00) && retry > 0); - - I("%s: End of setting!\n",__func__); - -} - -void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - I("diag_command = %d\n", diag_command ); - - himax_interface_on(client); - - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x02; - tmp_addr[1] = 0x04; - tmp_addr[0] = 0xB4; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = diag_command; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - himax_register_read(client, tmp_addr, 4, tmp_data, false); - I("%s: tmp_data[3]=0x%02X,tmp_data[2]=0x%02X,tmp_data[1]=0x%02X,tmp_data[0]=0x%02X!\n", - __func__,tmp_data[3],tmp_data[2],tmp_data[1],tmp_data[0]); - -} - -void himax_init_psl(struct i2c_client *client) //power saving level -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - //============================================================== - // SCU_Power_State_PW : 0x9000_00A0 ==> 0x0000_0000 (Reset PSL) - //============================================================== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0xA0; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_register_write(client, tmp_addr, 4, tmp_data, false); - - I("%s: power saving level reset OK!\n",__func__); -} - -void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer) -{ - uint8_t tmp_addr[4]; - uint8_t buffer[256]; - int page_prog_start = 0; - - himax_sense_off(client); - himax_burst_enable(client, 1); - - for (page_prog_start = 0; page_prog_start < Flash_Size; page_prog_start = page_prog_start + 128) - { - - tmp_addr[0] = page_prog_start % 0x100; - tmp_addr[1] = (page_prog_start >> 8) % 0x100; - tmp_addr[2] = (page_prog_start >> 16) % 0x100; - tmp_addr[3] = page_prog_start / 0x1000000; - himax_register_read(client, tmp_addr,128,buffer,false); - memcpy(&flash_buffer[page_prog_start],buffer,128); - } - - himax_burst_enable(client, 0); - himax_sense_on(client, 0x01); - - return; - -} - -#ifdef HX_ORG_SELFTEST -int himax_chip_self_test(struct i2c_client *client) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[128]; - uint8_t self_test_info[24]; - int pf_value=0x00; - uint8_t test_result_id = 0; - int i; - - memset(tmp_addr, 0x00, sizeof(tmp_addr)); - memset(tmp_data, 0x00, sizeof(tmp_data)); - - himax_interface_on(client); - himax_sense_off(client); - - - himax_burst_enable(client, 1); - - // 0x10007f18 -> 0x00006AA6 - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x18; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x6A; - tmp_data[0] = 0xA6; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //Set criteria 0x10007F1C [0,1]=aa/up,down=, [2-3]=key/up,down, [4]=iir_max_ulmt - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x1C; - tmp_data[3] = 0x00; - tmp_data[2] = 0xFF; - tmp_data[1] = 0x00; - tmp_data[0] = 0xFF; - tmp_data[7] = 0x00; - tmp_data[6] = 0x00; - tmp_data[5] = 0x00; - tmp_data[4] = 0xFF; - himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 8); - - // 0x10007294 -> 0x0000190 //SET IIR_MAX FRAMES - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x72; - tmp_addr[0] = 0x94; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x01; - tmp_data[0] = 0x90; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //Disable IDLE Mode - himax_idle_mode(client,1); - himax_reload_disable(client,1); - - //start selftest // leave safe mode - himax_sense_on(client, 1); - - //Hand shaking -> 0x100007f8 waiting 0xA66A - for(i = 0; i < 1000; i++) - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x18; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X, cnt=%d\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3],i); - msleep(10); - if(tmp_data[1] == 0xA6 && tmp_data[0] == 0x6A ) - { - I("%s Data ready goto moving data\n", __func__); - break; - } - } - - himax_sense_off(client); - msleep(20); - - //===================================== - // Read test result ID : 0x10007f24 ==> bit[2][1][0] = [key][AA][avg] => 0xF = PASS - //===================================== - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x24; - himax_register_read(client, tmp_addr, 24, self_test_info, false); - - test_result_id = self_test_info[0]; - - I("%s: check test result, test_result_id=%x, test_result=%x\n", __func__ - ,test_result_id,self_test_info[0]); - - I("raw top 1 = %d\n",self_test_info[3]*256+self_test_info[2]); - I("raw top 2 = %d\n",self_test_info[5]*256+self_test_info[4]); - I("raw top 3 = %d\n",self_test_info[7]*256+self_test_info[6]); - - I("raw last 1 = %d\n",self_test_info[9]*256+self_test_info[8]); - I("raw last 2 = %d\n",self_test_info[11]*256+self_test_info[10]); - I("raw last 3 = %d\n",self_test_info[13]*256+self_test_info[12]); - - I("raw key 1 = %d\n",self_test_info[15]*256+self_test_info[14]); - I("raw key 2 = %d\n",self_test_info[17]*256+self_test_info[16]); - I("raw key 3 = %d\n",self_test_info[19]*256+self_test_info[18]); - - if (test_result_id==0xAA) - { - I("[Himax]: self-test pass\n"); - pf_value = 0x1; - } - else - { - E("[Himax]: self-test fail\n"); - /* E("[Himax]: bank_avg = %d, bank_max = %d,%d,%d, bank_min = %d,%d,%d, key = %d,%d,%d\n", - tmp_data[1],tmp_data[2],tmp_data[3],tmp_data[4],tmp_data[5],tmp_data[6],tmp_data[7], - tmp_data[8],tmp_data[9],tmp_data[10]); */ - pf_value = 0x0; - } - - //Enable IDLE Mode - himax_idle_mode(client,0); - himax_reload_disable(client,0); - - himax_sense_on(client, 0); - msleep(120); - - return pf_value; -} - -#else -//static uint16_t gInspectGridData[ic_data->HX_RX_NUM * ic_data->HX_TX_NUM] = { 0 }; -//static int16_t gInspectNoiseData[ic_data->HX_RX_NUM * ic_data->HX_TX_NUM] = { 0 }; -static uint8_t NOISEMAX; - -int himax_switch_mode_inspection(struct i2c_client *client,int mode) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - I("%s: Entering\n",__func__); - - //Stop Handshaking - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; - himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4); - - //Swtich Mode - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x04; - switch (mode) - { - case HIMAX_INSPECTION_SORTING: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_SORTING_START; tmp_data[0] = PWD_SORTING_START; - break; - case HIMAX_INSPECTION_OPEN: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_OPEN_START; tmp_data[0] = PWD_OPEN_START; - break; - case HIMAX_INSPECTION_MICRO_OPEN: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_OPEN_START; tmp_data[0] = PWD_OPEN_START; - break; - case HIMAX_INSPECTION_SHORT: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_SHORT_START; tmp_data[0] = PWD_SHORT_START; - break; - case HIMAX_INSPECTION_RAWDATA: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_RAWDATA_START; tmp_data[0] = PWD_RAWDATA_START; - break; - case HIMAX_INSPECTION_NOISE: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_NOISE_START; tmp_data[0] = PWD_NOISE_START; - break; -#ifdef HX_DOZE_TEST - case HIMAX_INSPECTION_DOZE_RAWDATA: - case HIMAX_INSPECTION_DOZE_NOISE: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_DOZE_START; tmp_data[0] = PWD_DOZE_START; - break; -#endif -#ifdef HX_INSPECT_LPWUG_TEST - case HIMAX_INSPECTION_LPWUG_RAWDATA: - case HIMAX_INSPECTION_LPWUG_NOISE: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_LPWUG_START; tmp_data[0] = PWD_LPWUG_START; - break; - case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: - case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_LPWUG_IDLE_START; tmp_data[0] = PWD_LPWUG_IDLE_START; - break; -#endif - } - himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4); - - I("%s: End of setting!\n",__func__); - - return 0; - -} - - - -uint32_t himax_get_rawdata(struct i2c_client *client, uint32_t RAW[], uint32_t datalen) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t *tmp_rawdata; - uint8_t retry = 0; - uint16_t checksum_cal; - uint32_t i = 0; -//======================== - uint8_t max_i2c_size = 128; - int address = 0; - int total_read_times = 0; - int total_size = datalen * 2 + 4; - int total_size_temp; -#if 1 - uint32_t j = 0; - uint32_t index = 0; - uint32_t Min_DATA = 0xFFFFFFFF; - uint32_t Max_DATA = 0x00000000; -#endif - - tmp_rawdata = kzalloc(sizeof(uint8_t)*(datalen*2),GFP_KERNEL); - - /*1 Set Data Ready PWD*/ - while (retry < 300) { - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; - tmp_data[1] = Data_PWD1; - tmp_data[0] = Data_PWD0; - himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4); - - himax_register_read(client, tmp_addr, 4, tmp_data, false); - if ((tmp_data[0] == Data_PWD0 && tmp_data[1] == Data_PWD1) || - (tmp_data[0] == Data_PWD1 && tmp_data[1] == Data_PWD0)) { - break; - } - - retry++; - msleep(1); - } - - if (retry >= 200) { - return 1; - } - else { - retry = 0; - } - - while (retry < 200) { - if (tmp_data[0] == Data_PWD1 && tmp_data[1] == Data_PWD0) { - break; - } - - retry++; - msleep(1); - himax_register_read(client, tmp_addr, 4, tmp_data, false); - } - - if (retry >= 200) { - return 1; - } - else { - retry = 0; - } - - /*2 Read Data from SRAM*/ - while (retry < 10) { - checksum_cal = 0; -// - total_size_temp = total_size; - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00; - - if (total_size % max_i2c_size == 0) - { - total_read_times = total_size / max_i2c_size; - } - else - { - total_read_times = total_size / max_i2c_size + 1; - } - - for (i = 0; i < (total_read_times); i++) - { - if ( total_size_temp >= max_i2c_size) - { - himax_register_read(client, tmp_addr, max_i2c_size, &tmp_rawdata[i*max_i2c_size], false); - total_size_temp = total_size_temp - max_i2c_size; - } - else - { - //I("last total_size_temp=%d\n",total_size_temp); - himax_register_read(client, tmp_addr, total_size_temp % max_i2c_size, &tmp_rawdata[i*max_i2c_size], false); - } - - address = ((i+1)*max_i2c_size); - tmp_addr[1] = (uint8_t)((address>>8)&0x00FF); - tmp_addr[0] = (uint8_t)((address)&0x00FF); - } - -// - /*3 Check Checksum*/ - for (i = 2; i < datalen * 2 + 4; i = i + 2) { - checksum_cal += tmp_rawdata[i + 1] * 256 + tmp_rawdata[i]; - } - - if (checksum_cal == 0) { - break; - } - - retry++; - } - - if(checksum_cal != 0) - { - E("%s: Get rawdata checksum fail!\n",__func__); - return -1; - } - - /*4 Copy Data*/ - for (i = 0; i < ic_data->HX_TX_NUM*ic_data->HX_RX_NUM; i++) { - RAW[i] = tmp_rawdata[(i * 2) + 1 + 4] * 256 + tmp_rawdata[(i * 2) + 4]; - } - -#if 1 - for (j = 0; j < ic_data->HX_TX_NUM; j++) { - if (j == 0) { - printk(" RX%2d", j + 1); - } - else { - printk(" RX%2d", j + 1); - } - } - printk("\n"); - - for (i = 0; i < ic_data->HX_RX_NUM; i++) { - printk("TX%2d", i + 1); - for (j = 0; j < ic_data->HX_TX_NUM; j++) { - printk("%5d ", RAW[index]); - if (RAW[index] > Max_DATA) { - Max_DATA = RAW[index]; - } - if (RAW[index] < Min_DATA) { - Min_DATA = RAW[index]; - } - index++; - } - printk("\n"); - } - I("Max = %5d, Min = %5d \n", Max_DATA, Min_DATA); -#endif - return HX_INSPECT_OK; -} - -void himax_switch_data_type(struct i2c_client *client, uint8_t checktype) -{ - uint8_t datatype = 0; - - switch (checktype) - { - case HIMAX_INSPECTION_OPEN: - datatype = DATA_OPEN; - break; - case HIMAX_INSPECTION_MICRO_OPEN: - datatype = DATA_MICRO_OPEN; - break; - case HIMAX_INSPECTION_SHORT: - datatype = DATA_SHORT; - break; - case HIMAX_INSPECTION_RAWDATA: - datatype = DATA_RAWDATA; - break; - case HIMAX_INSPECTION_NOISE: - datatype = DATA_NOISE; - break; - case HIMAX_INSPECTION_BACK_NORMAL: - datatype = DATA_BACK_NORMAL; - break; -#ifdef HX_DOZE_TEST - case HIMAX_INSPECTION_DOZE_RAWDATA: - datatype = DATA_DOZE_RAWDATA; - break; - case HIMAX_INSPECTION_DOZE_NOISE: - datatype = DATA_DOZE_NOISE; - break; -#endif -#ifdef HX_INSPECT_LPWUG_TEST - case HIMAX_INSPECTION_LPWUG_RAWDATA: - datatype = DATA_LPWUG_RAWDATA; - break; - case HIMAX_INSPECTION_LPWUG_NOISE: - datatype = DATA_LPWUG_NOISE; - break; - case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: - datatype = DATA_LPWUG_IDLE_RAWDATA; - break; - case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: - datatype = DATA_LPWUG_IDLE_NOISE; - break; -#endif - default: - E("Wrong type=%d\n",checktype); - break; - } - himax_diag_register_set(client, datatype); -} - -void himax_set_N_frame(struct i2c_client *client, uint16_t Nframe, uint8_t checktype) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - //IIR MAX - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x72; tmp_addr[0] = 0x94; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; - tmp_data[1] = (uint8_t)((Nframe & 0xFF00) >> 8); - tmp_data[0] = (uint8_t)(Nframe & 0x00FF); - himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4); - - //skip frame - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x70; tmp_addr[0] = 0xF4; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - - switch (checktype) - { -#ifdef HX_DOZE_TEST - case HIMAX_INSPECTION_DOZE_RAWDATA: - case HIMAX_INSPECTION_DOZE_NOISE: - tmp_data[0] = BS_DOZE; - break; -#endif -#ifdef HX_INSPECT_LPWUG_TEST - case HIMAX_INSPECTION_LPWUG_RAWDATA: - case HIMAX_INSPECTION_LPWUG_NOISE: - tmp_data[0] = BS_LPWUG; - break; - case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: - case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: - tmp_data[0] = BS_LPWUG_dile; - break; -#endif - case HIMAX_INSPECTION_RAWDATA: - case HIMAX_INSPECTION_NOISE: - tmp_data[0] = BS_RAWDATANOISE; - break; - default: - tmp_data[0] = BS_OPENSHORT; - break; - } - himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4); -} - -void himax_get_noise_base(struct i2c_client *client) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x70; tmp_addr[0] = 0x8C; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - - NOISEMAX = tmp_data[3]; -} - -uint32_t himax_check_mode(struct i2c_client *client, uint8_t checktype) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t wait_pwd[2] = {0}; - // uint8_t count = 0; - - switch (checktype) { - case HIMAX_INSPECTION_OPEN: - wait_pwd[0] = PWD_OPEN_END; - wait_pwd[1] = PWD_OPEN_END; - break; - case HIMAX_INSPECTION_MICRO_OPEN: - wait_pwd[0] = PWD_OPEN_END; - wait_pwd[1] = PWD_OPEN_END; - break; - case HIMAX_INSPECTION_SHORT: - wait_pwd[0] = PWD_SHORT_END; - wait_pwd[1] = PWD_SHORT_END; - break; - case HIMAX_INSPECTION_RAWDATA: - wait_pwd[0] = PWD_RAWDATA_END; - wait_pwd[1] = PWD_RAWDATA_END; - break; - case HIMAX_INSPECTION_NOISE: - wait_pwd[0] = PWD_NOISE_END; - wait_pwd[1] = PWD_NOISE_END; - break; -#ifdef HX_DOZE - case HIMAX_INSPECTION_DOZE_RAWDATA: - case HIMAX_INSPECTION_DOZE_NOISE: - wait_pwd[0] = PWD_DOZE_END; - wait_pwd[1] = PWD_DOZE_END; - break; -#endif -#ifdef HX_INSPECT_LPWUG_TEST - case HIMAX_INSPECTION_LPWUG_RAWDATA: - case HIMAX_INSPECTION_LPWUG_NOISE: - wait_pwd[0] = PWD_LPWUG_END; - wait_pwd[1] = PWD_LPWUG_END; - break; - case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: - case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: - wait_pwd[0] = PWD_LPWUG_IDLE_END; - wait_pwd[1] = PWD_LPWUG_IDLE_END; - break; -#endif - default: - E("Wrong type=%d\n",checktype); - break; - } - - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x04; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - I("%s: himax_wait_sorting_mode, tmp_data[0]=%x,tmp_data[1]=%x\n", __func__, tmp_data[0],tmp_data[1]); - - if (wait_pwd[0] == tmp_data[0] && wait_pwd[1] == tmp_data[1]) { - I("Change to mode=%s\n",g_himax_inspection_mode[checktype]); - return 0; - } - else - return 1; -} - -uint32_t himax_wait_sorting_mode(struct i2c_client *client, uint8_t checktype) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t wait_pwd[2] = {0}; - int count = 0; - - switch (checktype) { - case HIMAX_INSPECTION_OPEN: - wait_pwd[0] = PWD_OPEN_END; - wait_pwd[1] = PWD_OPEN_END; - break; - case HIMAX_INSPECTION_MICRO_OPEN: - wait_pwd[0] = PWD_OPEN_END; - wait_pwd[1] = PWD_OPEN_END; - break; - case HIMAX_INSPECTION_SHORT: - wait_pwd[0] = PWD_SHORT_END; - wait_pwd[1] = PWD_SHORT_END; - break; - case HIMAX_INSPECTION_RAWDATA: - wait_pwd[0] = PWD_RAWDATA_END; - wait_pwd[1] = PWD_RAWDATA_END; - break; - case HIMAX_INSPECTION_NOISE: - wait_pwd[0] = PWD_NOISE_END; - wait_pwd[1] = PWD_NOISE_END; - break; -#ifdef HX_DOZE_TEST - case HIMAX_INSPECTION_DOZE_RAWDATA: - case HIMAX_INSPECTION_DOZE_NOISE: - wait_pwd[0] = PWD_DOZE_END; - wait_pwd[1] = PWD_DOZE_END; - break; -#endif -#ifdef HX_INSPECT_LPWUG_TEST - case HIMAX_INSPECTION_LPWUG_RAWDATA: - case HIMAX_INSPECTION_LPWUG_NOISE: - wait_pwd[0] = PWD_LPWUG_END; - wait_pwd[1] = PWD_LPWUG_END; - break; - case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: - case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: - wait_pwd[0] = PWD_LPWUG_IDLE_END; - wait_pwd[1] = PWD_LPWUG_IDLE_END; - break; -#endif - default: - E("Wrong type=%d\n",checktype); - break; - } - - do { - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x04; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - I("%s: himax_wait_sorting_mode, tmp_data[0]=%x,tmp_data[1]=%x\n", __func__, tmp_data[0],tmp_data[1]); - - if (wait_pwd[0] == tmp_data[0] && wait_pwd[1] == tmp_data[1]) { - return 0; - } - - tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0xA8; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - I("%s: 0x900000A8, tmp_data[0]=%x,tmp_data[1]=%x,tmp_data[2]=%x,tmp_data[3]=%x \n", __func__, tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]); - - tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0xE4; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - I("%s: 0x900000E4, tmp_data[0]=%x,tmp_data[1]=%x,tmp_data[2]=%x,tmp_data[3]=%x \n", __func__, tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]); - - tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0xF8; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - I("%s: 0x900000F8, tmp_data[0]=%x,tmp_data[1]=%x,tmp_data[2]=%x,tmp_data[3]=%x \n", __func__, tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]); - I("Now retry %d times!\n",count++); - msleep(50); - } while (count < 200); - - return 1; -} - -int himax_check_notch(int index) -{ - if ((index >= SKIP_NOTCH_START) && (index <= SKIP_NOTCH_END)) - return 1; - else if((index >= SKIP_DUMMY_START) && (index <= SKIP_DUMMY_END)) - return 1; - else - return 0; -} - -uint32_t mpTestFunc(struct i2c_client *client, uint8_t checktype, uint32_t datalen) -{ - uint32_t i/*, j*/, ret = 0; - uint32_t RAW[datalen]; - //uint16_t* pInspectGridData = &gInspectGridData[0]; - //uint16_t* pInspectNoiseData = &gInspectNoiseData[0]; - if(himax_check_mode(client,checktype)) - { - I("Need Change Mode ,target=%s",g_himax_inspection_mode[checktype]); - - himax_sense_off(client); - - himax_reload_disable(client,1); - - himax_switch_mode_inspection(client, checktype); - - if (checktype == HIMAX_INSPECTION_NOISE) - { - himax_set_N_frame(client, NOISEFRAME, checktype); - himax_get_noise_base(client); - } -#ifdef HX_DOZE_TEST - else if(checktype == HIMAX_INSPECTION_DOZE_RAWDATA || checktype == HIMAX_INSPECTION_DOZE_NOISE) - { - I("N frame = %d\n",10); - himax_set_N_frame(client, 10, checktype); - } -#endif - else if(checktype >= HIMAX_INSPECTION_LPWUG_RAWDATA ) - { - I("N frame = %d\n",1); - himax_set_N_frame(client, 1, checktype); - } - else - { - himax_set_N_frame(client, 2, checktype); - } - - himax_sense_on(client, 1); - - ret = himax_wait_sorting_mode(client, checktype); - if (ret) - { - E("%s: himax_wait_sorting_mode FAIL\n", __func__); - return ret; - } - } - - himax_switch_data_type(client, checktype); - - ret = himax_get_rawdata(client, RAW, datalen); - if (ret) - { - E("%s: himax_get_rawdata FAIL\n", __func__); - return ret; - } - - /* back to normal */ - himax_switch_data_type(client, HIMAX_INSPECTION_BACK_NORMAL); - - //Check Data - switch (checktype) - { - case HIMAX_INSPECTION_OPEN: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > OPENMAX || RAW[i] < OPENMIN) - { - E("%s: open test FAIL\n", __func__); - return HX_INSPECT_EOPEN; - } - } - I("%s: open test PASS\n", __func__); - break; - - case HIMAX_INSPECTION_MICRO_OPEN: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > M_OPENMAX || RAW[i] < M_OPENMIN) - { - E("%s: open test FAIL\n", __func__); - return HX_INSPECT_EMOPEN; - } - } - I("%s: open test PASS\n", __func__); - break; - - case HIMAX_INSPECTION_SHORT: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > SHORTMAX || RAW[i] < SHORTMIN) - { - E("%s: short test FAIL\n", __func__); - return HX_INSPECT_ESHORT; - } - } - I("%s: short test PASS\n", __func__); - break; - - case HIMAX_INSPECTION_RAWDATA: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > RAWMAX || RAW[i] < RAWMIN) - { - E("%s: rawdata test FAIL\n", __func__); - return HX_INSPECT_ERAW; - } - } - I("%s: rawdata test PASS\n", __func__); - break; - - case HIMAX_INSPECTION_NOISE: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > NOISEMAX) - { - E("%s: noise test FAIL\n", __func__); - return HX_INSPECT_ENOISE; - } - } - I("%s: noise test PASS\n", __func__); - break; -#ifdef HX_DOZE_TEST - case HIMAX_INSPECTION_DOZE_RAWDATA: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > DOZE_RAWDATA_MAX || RAW[i] < DOZE_RAWDATA_MIN) - { - E("%s: HIMAX_INSPECTION_DOZE_RAWDATA FAIL\n", __func__); - return HX_INSPECT_ERAW; - } - } - I("%s: HIMAX_INSPECTION_DOZE_RAWDATA PASS\n", __func__); - break; - case HIMAX_INSPECTION_DOZE_NOISE: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > DOZE_NOISE_MAX || RAW[i] < DOZE_NOISE_MIN) - { - E("%s: HIMAX_INSPECTION_DOZE_NOISE FAIL\n", __func__); - return HX_INSPECT_ENOISE; - } - } - I("%s: HIMAX_INSPECTION_DOZE_NOISE PASS\n", __func__); - break; -#endif -#ifdef HX_INSPECT_LPWUG_TEST - case HIMAX_INSPECTION_LPWUG_RAWDATA: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > LPWUG_RAWDATA_MAX || RAW[i] < LPWUG_RAWDATA_MIN) - { - E("%s: HIMAX_INSPECTION_LPWUG_RAWDATA FAIL\n", __func__); - return HX_INSPECT_ERAW; - } - } - I("%s: HIMAX_INSPECTION_LPWUG_RAWDATA PASS\n", __func__); - break; - case HIMAX_INSPECTION_LPWUG_NOISE: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > LPWUG_NOISE_MAX || RAW[i] < LPWUG_NOISE_MIN) - { - E("%s: HIMAX_INSPECTION_LPWUG_NOISE FAIL\n", __func__); - return HX_INSPECT_ENOISE; - } - } - I("%s: HIMAX_INSPECTION_LPWUG_NOISE PASS\n", __func__); - break; - case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > LPWUG_IDLE_RAWDATA_MAX || RAW[i] < LPWUG_IDLE_RAWDATA_MIN) - { - E("%s: HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA FAIL\n", __func__); - return HX_INSPECT_ERAW; - } - } - I("%s: HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA PASS\n", __func__); - break; - case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: - for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) - { - if (himax_check_notch(i)) - { - continue; - } - if (RAW[i] > LPWUG_IDLE_NOISE_MAX || RAW[i] < LPWUG_IDLE_NOISE_MIN) - { - E("%s: HIMAX_INSPECTION_LPWUG_IDLE_NOISE FAIL\n", __func__); - return HX_INSPECT_ENOISE; - } - } - I("%s: HIMAX_INSPECTION_LPWUG_IDLE_NOISE PASS\n", __func__); - break; -#endif - default: - E("Wrong type=%d\n",checktype); - break; - } - - return HX_INSPECT_OK; -} - -extern void himax_press_powerkey(bool key_status); -int himax_chip_self_test(struct i2c_client *client) -{ - int ret = HX_INSPECT_OK; - I("%s:IN\n", __func__); - - //1. Open Test - I("[MP_OPEN_TEST_RAW]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_OPEN, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("1. Open Test: End %d\n\n\n", ret); - - //2. Micro-Open Test - I("[MP_MICRO_OPEN_TEST_RAW]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_MICRO_OPEN, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("2. Micro Open Test: End %d\n\n\n", ret); - - //3. Short Test - I("[MP_SHORT_TEST_RAW]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_SHORT, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("3. Short Test: End %d\n\n\n", ret); - - //4. RawData Test - I("==========================================\n"); - I("[MP_RAW_TEST_RAW]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_RAWDATA, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM)+ic_data->HX_TX_NUM+ic_data->HX_RX_NUM); - I("4. Short Test: End %d\n\n\n", ret); - - //5. Noise Test - I("[MP_NOISE_TEST_RAW]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_NOISE, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("5. Noise Test: End %d\n\n\n", ret); - - -#ifdef HX_DOZE_TEST - //6. DOZE RAWDATA - I("[MP_DOZE_TEST_RAW]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_DOZE_RAWDATA, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("6. MP_DOZE_TEST_RAW: End %d\n\n\n", ret); - - //7. DOZE NOISE - I("[MP_DOZE_TEST_NOISE]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_DOZE_NOISE, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("7. MP_DOZE_TEST_NOISE: End %d\n\n\n", ret); -#endif -#ifdef HX_INSPECT_LPWUG_TEST - - himax_press_powerkey(false); - - //8. LPWUG RAWDATA - I("[MP_LPWUG_TEST_RAW]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_LPWUG_RAWDATA, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("8. MP_LPWUG_TEST_RAW: End %d\n\n\n", ret); - - //9. LPWUG NOISE - I("[MP_LPWUG_TEST_NOISE]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_LPWUG_NOISE, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("9. MP_LPWUG_TEST_NOISE: End %d\n\n\n", ret); - - //10. LPWUG IDLE RAWDATA - I("[MP_LPWUG_IDLE_TEST_RAW]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("10. MP_LPWUG_IDLE_TEST_RAW: End %d\n\n\n", ret); - - //11. LPWUG IDLE RAWDATA - I("[MP_LPWUG_IDLE_TEST_NOISE]\n"); - ret = mpTestFunc(client, HIMAX_INSPECTION_LPWUG_IDLE_NOISE, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); - I("11. MP_LPWUG_IDLE_TEST_NOISE: End %d\n\n\n", ret); - - himax_press_powerkey(true); -#endif - himax_sense_off(client); - himax_set_N_frame(client, 1, HIMAX_INSPECTION_NOISE); - himax_sense_on(client, 0); - - I("thp_afe_inspect_OUT = %d \n", ret); - I("%s:OUT", __func__); - return HX_INSPECT_OK; -} - -#endif - -void himax_set_HSEN_enable(struct i2c_client *client, uint8_t HSEN_enable, bool suspended) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - //Enable:0x10007F14 = 0xA55AA55A - - if(HSEN_enable) - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x14; - tmp_data[3] = 0xA5; - tmp_data[2] = 0x5A; - tmp_data[1] = 0xA5; - tmp_data[0] = 0x5A; - himax_flash_write_burst(client, tmp_addr, tmp_data); - } - else - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x14; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - } -} - -int himax_palm_detect(uint8_t *buf) -{ - - return GESTURE_DETECT_FAIL; - -} - -void himax_set_SMWP_enable(struct i2c_client *client, uint8_t SMWP_enable, bool suspended) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t back_data[4]; - uint8_t retry_cnt = 0; - - himax_sense_off(client); - - //Enable:0x10007F10 = 0xA55AA55A - do - { - if(SMWP_enable) - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x10; - tmp_data[3] = 0xA5; - tmp_data[2] = 0x5A; - tmp_data[1] = 0xA5; - tmp_data[0] = 0x5A; - himax_flash_write_burst(client, tmp_addr, tmp_data); - back_data[3] = 0XA5; - back_data[2] = 0X5A; - back_data[1] = 0XA5; - back_data[0] = 0X5A; - } - else - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x10; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - back_data[3] = 0X00; - back_data[2] = 0X00; - back_data[1] = 0X00; - back_data[0] = 0x00; - } - himax_register_read(client, tmp_addr, 4, tmp_data, false); - //I("%s: tmp_data[0]=%d, SMWP_enable=%d, retry_cnt=%d \n", __func__, tmp_data[0],SMWP_enable,retry_cnt); - retry_cnt++; - } - while((tmp_data[3] != back_data[3] || tmp_data[2] != back_data[2] || tmp_data[1] != back_data[1] || tmp_data[0] != back_data[0] ) && retry_cnt < HIMAX_REG_RETRY_TIMES); - - himax_sense_on(client,0); - -} - -void himax_usb_detect_set(struct i2c_client *client,uint8_t *cable_config) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - //Enable:0x10007F38 = 0xA55AA55A - - if(cable_config[1] == 0x01) - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x38; - tmp_data[3] = 0xA5; - tmp_data[2] = 0x5A; - tmp_data[1] = 0xA5; - tmp_data[0] = 0x5A; - himax_flash_write_burst(client, tmp_addr, tmp_data); - } - else - { - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x7F; - tmp_addr[0] = 0x38; - tmp_data[3] = 0x77; - tmp_data[2] = 0x88; - tmp_data[1] = 0x77; - tmp_data[0] = 0x88; - himax_flash_write_burst(client, tmp_addr, tmp_data); - } -} - -void himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte) -{ - uint8_t tmp_data[4]; - - tmp_data[0] = 0x31; - if ( i2c_himax_write(client, 0x13,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return; - } - - tmp_data[0] = (0x10 | auto_add_4_byte); - if ( i2c_himax_write(client, 0x0D,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return; - } - - //isBusrtOn = true; -} - -int himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data, bool cfg_flag) -{ - uint8_t tmp_data[4]; - int i = 0; - int address = 0; - if(cfg_flag == false) - { - if(read_length>256) - { - E("%s: read len over 256!\n", __func__); - return LENGTH_FAIL; - } - if (read_length > 4) - himax_burst_enable(client, 1); - else - himax_burst_enable(client, 0); - - address = (read_addr[3] << 24) + (read_addr[2] << 16) + (read_addr[1] << 8) + read_addr[0]; - i = address; - tmp_data[0] = (uint8_t)i; - tmp_data[1] = (uint8_t)(i >> 8); - tmp_data[2] = (uint8_t)(i >> 16); - tmp_data[3] = (uint8_t)(i >> 24); - if ( i2c_himax_write(client, 0x00,tmp_data, 4, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return I2C_FAIL; - } - tmp_data[0] = 0x00; - if ( i2c_himax_write(client, 0x0C,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return I2C_FAIL; - } - - if ( i2c_himax_read(client, 0x08,read_data, read_length, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return I2C_FAIL; - } - if (read_length > 4) - himax_burst_enable(client, 0); - } - else - { - if(i2c_himax_read(client, read_addr[0], read_data,read_length,DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return I2C_FAIL; - } - } - return 0; -} - -int himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data) -{ - uint8_t data_byte[8]; - int i = 0, j = 0; - - for (i = 0; i < 4; i++) - { - data_byte[i] = reg_byte[i]; - } - for (j = 4; j < 8; j++) - { - data_byte[j] = write_data[j-4]; - } - - if ( i2c_himax_write(client, 0x00,data_byte, 8, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return I2C_FAIL; - } - return 0; - -} - -void himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length) -{ - uint8_t data_byte[256]; - int i = 0, j = 0; - - for (i = 0; i < 4; i++) - { - data_byte[i] = reg_byte[i]; - } - for (j = 4; j < length + 4; j++) - { - data_byte[j] = write_data[j - 4]; - } - - if ( i2c_himax_write(client, 0x00,data_byte, length + 4, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return; - } -} - -void himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data, bool cfg_flag) -{ - int i =0, address = 0; - if(cfg_flag == false) - { - address = (write_addr[3] << 24) + (write_addr[2] << 16) + (write_addr[1] << 8) + write_addr[0]; - - for (i = address; i < address + write_length; i++) - { - if (write_length > 4) - { - himax_burst_enable(client, 1); - } - else - { - himax_burst_enable(client, 0); - } - himax_flash_write_burst_lenth(client, write_addr, write_data, write_length); - } - } - else if(cfg_flag == true) - { - if(i2c_himax_write(client, write_addr[0], write_data,write_length,DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return; - } - } - else - { - E("%s: cfg_flag = %d, value is wrong!\n", __func__,cfg_flag); - return; - } -} - -bool himax_sense_off(struct i2c_client *client) -{ - uint8_t cnt = 0; - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - //===================================== - // FW ISR=0 - //===================================== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x5C; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0xA5; - - himax_flash_write_burst(client, tmp_addr, tmp_data); - msleep(20); - - do - { - //=========================================== - // 0x31 ==> 0x27 - //=========================================== - tmp_data[0] = 0x27; - if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return false; - } - //=========================================== - // 0x32 ==> 0x95 - //=========================================== - tmp_data[0] = 0x95; - if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return false; - } - - // ====================== - // Check enter_save_mode - // ====================== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0xA8; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - - I("%s: Check enter_save_mode data[0]=%X \n", __func__,tmp_data[0]); - - if (tmp_data[0] == 0x0C) - { - //===================================== - // Reset TCON - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x02; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x20; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - msleep(1); - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x01; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //===================================== - // Reset ADC - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x02; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x94; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - msleep(1); - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x01; - himax_flash_write_burst(client, tmp_addr, tmp_data); - return true; - } - else - { - msleep(10); -#ifdef HX_RST_PIN_FUNC - himax_ic_reset(false,false); -#endif - } - } - while (cnt++ < 15); - - return false; -} - -bool himax_enter_safe_mode(struct i2c_client *client) -{ - uint8_t cnt = 0; - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - do - { - //=========================================== - // 0x31 ==> 0x27 - //=========================================== - tmp_data[0] = 0x27; - if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return false; - } - //=========================================== - // 0x32 ==> 0x95 - //=========================================== - tmp_data[0] = 0x95; - if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return false; - } - - //=========================================== - // 0x31 ==> 0x00 - //=========================================== - tmp_data[0] = 0x00; - if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return false; - } - msleep(10); - //=========================================== - // 0x31 ==> 0x27 - //=========================================== - tmp_data[0] = 0x27; - if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return false; - } - //=========================================== - // 0x32 ==> 0x95 - //=========================================== - tmp_data[0] = 0x95; - if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return false; - } - - // ====================== - // Check enter_save_mode - // ====================== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0xA8; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - - I("%s: Check enter_save_mode data[0]=%X \n", __func__,tmp_data[0]); - - if (tmp_data[0] == 0x0C) - { - //===================================== - // Reset TCON - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x02; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x20; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - msleep(1); - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x01; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //===================================== - // Reset ADC - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x02; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x94; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - msleep(1); - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x01; - himax_flash_write_burst(client, tmp_addr, tmp_data); - return true; - } - else - { - msleep(10); -#ifdef HX_RST_PIN_FUNC - himax_ic_reset(false,false); -#endif - } - } - while (cnt++ < 15); - - return false; -} - -void himax_interface_on(struct i2c_client *client) -{ - uint8_t tmp_data[5]; - uint8_t tmp_data2[2]; - int cnt = 0; - - //Read a dummy register to wake up I2C. - if ( i2c_himax_read(client, 0x08, tmp_data,4,DEFAULT_RETRY_CNT) < 0) // to knock I2C - { - E("%s: i2c access fail!\n", __func__); - return; - } - - do - { - //=========================================== - // Enable continuous burst mode : 0x13 ==> 0x31 - //=========================================== - tmp_data[0] = 0x31; - if ( i2c_himax_write(client, 0x13,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return; - } - //=========================================== - // AHB address auto +4 : 0x0D ==> 0x11 - // Do not AHB address auto +4 : 0x0D ==> 0x10 - //=========================================== - tmp_data[0] = (0x10); - if ( i2c_himax_write(client, 0x0D,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return; - } - - // Check cmd - i2c_himax_read(client, 0x13, tmp_data,1,DEFAULT_RETRY_CNT); - i2c_himax_read(client, 0x0D, tmp_data2,1,DEFAULT_RETRY_CNT); - - if (tmp_data[0] == 0x31 && tmp_data2[0] == 0x10) - { - //isBusrtOn = true; - break; - } - msleep(1); - } - while (++cnt < 10); - - if (cnt > 0) - I("%s:Polling burst mode: %d times", __func__,cnt); - -} - -bool wait_wip(struct i2c_client *client, int Timing) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t in_buffer[10]; - //uint8_t out_buffer[20]; - int retry_cnt = 0; - - //===================================== - // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780 - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x10; - tmp_data[3] = 0x00; - tmp_data[2] = 0x02; - tmp_data[1] = 0x07; - tmp_data[0] = 0x80; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - in_buffer[0] = 0x01; - - do - { - //===================================== - // SPI Transfer Control : 0x8000_0020 ==> 0x4200_0003 - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x20; - tmp_data[3] = 0x42; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x03; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //===================================== - // SPI Command : 0x8000_0024 ==> 0x0000_0005 - // read 0x8000_002C for 0x01, means wait success - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x24; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x05; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - in_buffer[0] = in_buffer[1] = in_buffer[2] = in_buffer[3] = 0xFF; - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x2C; - himax_register_read(client, tmp_addr, 4, in_buffer, false); - - if ((in_buffer[0] & 0x01) == 0x00) - return true; - - retry_cnt++; - - if (in_buffer[0] != 0x00 || in_buffer[1] != 0x00 || in_buffer[2] != 0x00 || in_buffer[3] != 0x00) - I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, buffer[1]=%d, buffer[2]=%d, buffer[3]=%d \n", __func__, - retry_cnt,in_buffer[0],in_buffer[1],in_buffer[2],in_buffer[3]); - - if (retry_cnt > 100) - { - E("%s: Wait wip error!\n", __func__); - return false; - } - msleep(Timing); - } - while ((in_buffer[0] & 0x01) == 0x01); - return true; -} - -void himax_sense_on(struct i2c_client *client, uint8_t FlashMode) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - int retry = 0; - - I("Enter %s \n", __func__); - - himax_interface_on(client); - //===================================== - // Clear FW ISR - //===================================== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x5C; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - - himax_flash_write_burst(client, tmp_addr, tmp_data); - msleep(20); - - if(!FlashMode) - { -#ifdef HX_RST_PIN_FUNC - himax_ic_reset(false,false); -#else - //===AHBI2C_SystemReset========== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x18; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x55; - himax_register_write(client, tmp_addr, 4, tmp_data, false); -#endif - } - else - { - do - { - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x98; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x53; - himax_register_write(client, tmp_addr, 4, tmp_data, false); - - tmp_addr[0] = 0xE4; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - - I("%s:Read status from IC = %X,%X\n", __func__, tmp_data[0],tmp_data[1]); - - } - while((tmp_data[1] != 0x01 || tmp_data[0] != 0x00) && retry++ < 5); - - if(retry >= 5) - { - E("%s: Fail:\n", __func__); -#ifdef HX_RST_PIN_FUNC - himax_ic_reset(false,false); -#else - //===AHBI2C_SystemReset========== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x18; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x55; - himax_register_write(client, tmp_addr, 4, tmp_data, false); -#endif - } - else - { - I("%s:OK and Read status from IC = %X,%X\n", __func__, tmp_data[0],tmp_data[1]); - - /* reset code*/ - tmp_data[0] = 0x00; - if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - } - if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - } - - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x98; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_register_write(client, tmp_addr, 4, tmp_data, false); - } - } -} - -void himax_chip_erase(struct i2c_client *client) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - himax_interface_on(client); - - /* init psl */ - himax_init_psl(client); - - //===================================== - // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780 - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x10; - tmp_data[3] = 0x00; - tmp_data[2] = 0x02; - tmp_data[1] = 0x07; - tmp_data[0] = 0x80; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //===================================== - // Chip Erase - // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000 - // 2. 0x8000_0024 ==> 0x0000_0006 - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x20; - tmp_data[3] = 0x47; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x24; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x06; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //===================================== - // Chip Erase - // Erase Command : 0x8000_0024 ==> 0x0000_00C7 - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x24; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0xC7; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - msleep(2000); - - if (!wait_wip(client, 100)) - E("%s:83112_Chip_Erase Fail\n", __func__); - -} - -bool himax_block_erase(struct i2c_client *client, int start_addr, int length) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint32_t page_prog_start = 0; - - himax_interface_on(client); - - /* init psl */ - himax_init_psl(client); - - //===================================== - // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780 - //===================================== - tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10; - tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80; - himax_flash_write_burst(client, tmp_addr, tmp_data); - for (page_prog_start = start_addr; page_prog_start < start_addr + length; page_prog_start = page_prog_start + 0x10000) - { - //===================================== - // Chip Erase - // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000//control - // 2. 0x8000_0024 ==> 0x0000_0006//WREN - //===================================== - tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20; - tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //===================================== - // Block Erase - // Erase Command : 0x8000_0028 ==> 0x0000_0000 //SPI addr - // 0x8000_0020 ==> 0x6700_0000 //control - // 0x8000_0024 ==> 0x0000_00D8 //BE - //===================================== - tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28; - //tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;// Flash start address 1st : 0x0000_0000 - tmp_data[3] = (page_prog_start >> 24)&0xFF; - tmp_data[2] = (page_prog_start >> 16)&0xFF; - tmp_data[1] = (page_prog_start >> 8)&0xFF; - tmp_data[0] = page_prog_start&0xFF; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20; - tmp_data[3] = 0x67; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xD8; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - msleep(1000); - - if (!wait_wip(client, 100)) - { - E("%s:83102_Erase Fail\n", __func__); - return false; - } - } - return true; -} -bool himax_sector_erase(struct i2c_client *client, int start_addr) -{ - return true; -} - -void himax_sram_write(struct i2c_client *client, uint8_t *FW_content) -{ - -} - -bool himax_sram_verify(struct i2c_client *client, uint8_t *FW_File, int FW_Size) -{ - return true; -} - -void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size) -{ - int page_prog_start = 0; - int program_length = 48; - int i = 0, j = 0, k = 0; - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t buring_data[256]; // Read for flash data, 128K - // 4 bytes for 0x80002C padding - - himax_interface_on(client); - - //===================================== - // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780 - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x10; - tmp_data[3] = 0x00; - tmp_data[2] = 0x02; - tmp_data[1] = 0x07; - tmp_data[0] = 0x80; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - for (page_prog_start = 0; page_prog_start < FW_Size; page_prog_start = page_prog_start + 256) - { - //msleep(5); - //===================================== - // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000 - // 2. 0x8000_0024 ==> 0x0000_0006 - //===================================== - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x20; - tmp_data[3] = 0x47; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x24; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x06; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //================================= - // SPI Transfer Control - // Set 256 bytes page write : 0x8000_0020 ==> 0x610F_F000 - // Set read start address : 0x8000_0028 ==> 0x0000_0000 - //================================= - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x20; - tmp_data[3] = 0x61; - tmp_data[2] = 0x0F; - tmp_data[1] = 0xF0; - tmp_data[0] = 0x00; - // data bytes should be 0x6100_0000 + ((word_number)*4-1)*4096 = 0x6100_0000 + 0xFF000 = 0x610F_F000 - // Programmable size = 1 page = 256 bytes, word_number = 256 byte / 4 = 64 - himax_flash_write_burst(client, tmp_addr, tmp_data); - - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x28; - //tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; // Flash start address 1st : 0x0000_0000 - - if (page_prog_start < 0x100) - { - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = (uint8_t)page_prog_start; - } - else if (page_prog_start >= 0x100 && page_prog_start < 0x10000) - { - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = (uint8_t)(page_prog_start >> 8); - tmp_data[0] = (uint8_t)page_prog_start; - } - else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000) - { - tmp_data[3] = 0x00; - tmp_data[2] = (uint8_t)(page_prog_start >> 16); - tmp_data[1] = (uint8_t)(page_prog_start >> 8); - tmp_data[0] = (uint8_t)page_prog_start; - } - - himax_flash_write_burst(client, tmp_addr, tmp_data); - - - //================================= - // Send 16 bytes data : 0x8000_002C ==> 16 bytes data - //================================= - buring_data[0] = 0x2C; - buring_data[1] = 0x00; - buring_data[2] = 0x00; - buring_data[3] = 0x80; - - for (i = /*0*/page_prog_start, j = 0; i < 16 + page_prog_start/**/; i++, j++) /// <------ bin file - { - buring_data[j + 4] = FW_content[i]; - } - - - if ( i2c_himax_write(client, 0x00,buring_data, 20, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return; - } - //================================= - // Write command : 0x8000_0024 ==> 0x0000_0002 - //================================= - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x24; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x02; - himax_flash_write_burst(client, tmp_addr, tmp_data); - - //================================= - // Send 240 bytes data : 0x8000_002C ==> 240 bytes data - //================================= - - for (j = 0; j < 5; j++) - { - for (i = (page_prog_start + 16 + (j * 48)), k = 0; i < (page_prog_start + 16 + (j * 48)) + program_length; i++, k++) /// <------ bin file - { - buring_data[k+4] = FW_content[i];//(byte)i; - } - - if ( i2c_himax_write(client, 0x00,buring_data, program_length+4, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return; - } - - } - - if (!wait_wip(client, 1)) - E("%s:83112_Flash_Programming Fail\n", __func__); - } -} - - -bool Calculate_CRC_with_AP(unsigned char *FW_content, int CRC_from_FW, int mode) -{ - return true; -} - -uint32_t himax_hw_check_CRC(struct i2c_client *client, uint8_t *start_addr, int reload_length) -{ - uint32_t result = 0; - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - int cnt = 0, ret = 0; - int length = reload_length / 4; - - //CRC4 // 0x8005_0020 <= from, 0x8005_0028 <= 0x0099_length - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x05; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x20; - //tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0xFB; tmp_data[0] = 0x00; - ret = himax_flash_write_burst(client, tmp_addr, start_addr); - if ( ret < 0) - { - E("%s: i2c access fail!\n", __func__); - return 1; - } - - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x05; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x28; - tmp_data[3] = 0x00; - tmp_data[2] = 0x99; - tmp_data[1] = (length >> 8); - tmp_data[0] = length; - ret = himax_flash_write_burst(client, tmp_addr, tmp_data); - if ( ret < 0) - { - E("%s: i2c access fail!\n", __func__); - return 1; - } - - cnt = 0; - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x05; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x00; - do - { - ret = himax_register_read(client, tmp_addr, 4, tmp_data, false); - if ( ret < 0) - { - E("%s: i2c access fail!\n", __func__); - return 1; - } - - if ((tmp_data[0] & 0x01) != 0x01) - { - tmp_addr[3] = 0x80; - tmp_addr[2] = 0x05; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x18; - ret = himax_register_read(client, tmp_addr, 4, tmp_data, false); - if ( ret < 0) - { - E("%s: i2c access fail!\n", __func__); - return 1; - } - I("%s: tmp_data[3]=%X, tmp_data[2]=%X, tmp_data[1]=%X, tmp_data[0]=%X \n", __func__, tmp_data[3], tmp_data[2], tmp_data[1], tmp_data[0]); - result = ((tmp_data[3] << 24) + (tmp_data[2] << 16) + (tmp_data[1] << 8) + tmp_data[0]); - break; - } - } - while (cnt++ < 100); - - return result; -} - -void himax_flash_page_write(struct i2c_client *client, uint8_t *write_addr, uint8_t *write_data) -{ - -} - -void himax_set_reload_cmd(uint8_t *write_data, int idx, uint32_t cmd_from, uint32_t cmd_to, uint32_t cmd_beat) -{ - int index = idx * 12; - int i; - for (i = 3; i >= 0; i--) - { - write_data[index + i] = (cmd_from >> (8 * i)); - write_data[index + 4 + i] = (cmd_to >> (8 * i)); - write_data[index + 8 + i] = (cmd_beat >> (8 * i)); - } -} - -bool himax_program_reload(struct i2c_client *client) -{ - return true; -} - -int fts_ctpm_fw_upgrade_with_sys_fs_32k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) -{ - /* Not use */ - return 0; -} - -int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) -{ - /* Not use */ - return 0; -} - -int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) -{ - - //int CRC_from_FW = 0; - int burnFW_success = 0; - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - if (len != FW_SIZE_64k) //64k - { - E("%s: The file size is not 64K bytes\n", __func__); - return false; - } - -#ifdef HX_RST_PIN_FUNC - himax_ic_reset(false,false); -#else - //===AHBI2C_SystemReset========== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x18; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x55; - himax_register_write(client, tmp_addr, 4, tmp_data, false); -#endif - - himax_enter_safe_mode(client); - //himax_chip_erase(client); - himax_block_erase(client,0x00,FW_SIZE_64k); - himax_flash_programming(client, fw, FW_SIZE_64k); - - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - - if(himax_hw_check_CRC(client,tmp_data, FW_SIZE_64k) == 0) - { - burnFW_success = 1; - } - else - { - burnFW_success = 0; - } - /*RawOut select initial*/ - tmp_addr[3] = 0x80;tmp_addr[2] = 0x02;tmp_addr[1] = 0x04;tmp_addr[0] = 0xB4; - tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00; - himax_register_write(client,tmp_addr, 4, tmp_data, false); - - /*DSRAM func initial*/ - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x07;tmp_addr[0] = 0xFC; - tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00; - himax_register_write(client,tmp_addr, 4, tmp_data, false); - -#ifdef HX_RST_PIN_FUNC - himax_ic_reset(false,false); -#else - //===AHBI2C_SystemReset========== - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x18; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x55; - himax_register_write(client, tmp_addr, 4, tmp_data, false); -#endif - return burnFW_success; - -} - -int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) -{ - /* Not use */ - return 0; -} - -int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) -{ - /* Not use */ - return 0; -} - -void himax_touch_information(struct i2c_client *client) -{ -#ifndef HX_FIX_TOUCH_INFO - uint8_t cmd[4]; - char data[12] = {0}; - - I("%s:IC_TYPE =%d\n", __func__,IC_TYPE); - - if(IC_TYPE == HX_83112A_SERIES_PWON) - { - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0xF4; - himax_register_read(client, cmd, 8, data, false); - ic_data->HX_RX_NUM = data[2]; - ic_data->HX_TX_NUM = data[3]; - ic_data->HX_MAX_PT = data[4]; - //I("%s : HX_RX_NUM=%d,ic_data->HX_TX_NUM=%d,ic_data->HX_MAX_PT=%d\n",__func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT); - - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0xFA; - himax_register_read(client, cmd, 4, data, false); - //I("%s : c_data->HX_XY_REVERSE=0x%2.2X\n",__func__,data[1]); - if((data[1] & 0x04) == 0x04) - { - ic_data->HX_XY_REVERSE = true; - } - else - { - ic_data->HX_XY_REVERSE = false; - } - - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0xFC; - himax_register_read(client, cmd, 4, data, false); - ic_data->HX_Y_RES = data[0]*256; - ic_data->HX_Y_RES = ic_data->HX_Y_RES + data[1]; - ic_data->HX_X_RES = data[2]*256 + data[3]; - //I("%s : ic_data->HX_Y_RES=%d,ic_data->HX_X_RES=%d \n",__func__,ic_data->HX_Y_RES,ic_data->HX_X_RES); - - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0x88; - himax_register_read(client, cmd, 4, data, false); - //I("%s : data[0]=0x%2.2X,data[1]=0x%2.2X,data[2]=0x%2.2X,data[3]=0x%2.2X\n",__func__,data[0],data[1],data[2],data[3]); - I("data[1] & 0x01 = %d\n",(data[1] & 0x01)); - if((data[1] & 0x01) == 1) /* R10007089H */ - { - ic_data->HX_INT_IS_EDGE = true; - } - else - { - ic_data->HX_INT_IS_EDGE = false; - } - - if (ic_data->HX_RX_NUM > 50) - ic_data->HX_RX_NUM = 32; - if (ic_data->HX_TX_NUM > 30) - ic_data->HX_TX_NUM = 18; - if (ic_data->HX_MAX_PT > 10) - ic_data->HX_MAX_PT = 10; - if (ic_data->HX_Y_RES > 3000) - ic_data->HX_Y_RES = 1280; - if (ic_data->HX_X_RES > 2000) - ic_data->HX_X_RES = 720; - - /*Read number of MKey R100070E8H*/ - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0xE8; - himax_register_read(client, cmd, 4,data, false); - //I("%s: data[0] = 0x%02X,data[1] = 0x%02X,data[2] = 0x%02X,data[3] = 0x%02X\n", __func__,data[0],data[1],data[2],data[3]); - ic_data->HX_BT_NUM = data[0] & 0x03; - } - else - { - ic_data->HX_RX_NUM = 0; - ic_data->HX_TX_NUM = 0; - ic_data->HX_BT_NUM = 0; - ic_data->HX_X_RES = 0; - ic_data->HX_Y_RES = 0; - ic_data->HX_MAX_PT = 0; - ic_data->HX_XY_REVERSE = false; - ic_data->HX_INT_IS_EDGE = false; - } -#else - ic_data->HX_RX_NUM = FIX_HX_RX_NUM; - ic_data->HX_TX_NUM = FIX_HX_TX_NUM; - ic_data->HX_BT_NUM = FIX_HX_BT_NUM; - ic_data->HX_X_RES = FIX_HX_X_RES; - ic_data->HX_Y_RES = FIX_HX_Y_RES; - ic_data->HX_MAX_PT = FIX_HX_MAX_PT; - ic_data->HX_XY_REVERSE = FIX_HX_XY_REVERSE; - ic_data->HX_INT_IS_EDGE = FIX_HX_INT_IS_EDGE; -#endif - I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d \n", __func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT); - I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d \n", __func__,ic_data->HX_XY_REVERSE,ic_data->HX_Y_RES,ic_data->HX_X_RES); - I("%s:HX_INT_IS_EDGE =%d \n", __func__,ic_data->HX_INT_IS_EDGE); -} - -int himax_read_i2c_status(struct i2c_client *client) -{ - return i2c_error_count; // -} - -int himax_read_ic_trigger_type(struct i2c_client *client) -{ - uint8_t cmd[4]; - char data[12] = {0}; - int trigger_type = false; - - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0x88; - himax_register_read(client, cmd, 4, data, false); - if((data[1] & 0x01) == 1) - { - trigger_type = true; - } - else - { - trigger_type = false; - } - - return trigger_type; -} - -void himax_read_FW_ver(struct i2c_client *client) -{ - uint8_t cmd[4],cmd_2[4]; - uint8_t data[64],data_2[64]; - int retry = 200; - int reload_status = 0; - - himax_sense_on(client,0); - - while(reload_status == 0) - { - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x7f; - cmd[0] = 0x00; - himax_register_read(client, cmd, 4, data, false); - - cmd_2[3] = 0x10; - cmd_2[2] = 0x00; - cmd_2[1] = 0x72; - cmd_2[0] = 0xc0; - himax_register_read(client, cmd_2, 4, data_2, false); - - if((data[3]==0x00 && data[2]==0x00 && data[1]==0x3A && data[0]==0xA3 ) - ||(data_2[3]==0x00 && data_2[2]==0x00 && data_2[1]==0x72 && data_2[0]==0xC0 )) - { - I("reload OK! \n"); - reload_status = 1; - break; - } - else if(retry == 0) - { - E("reload 20 times! fail \n"); - ic_data->vendor_panel_ver = 0; - ic_data->vendor_fw_ver = 0; - ic_data->vendor_config_ver = 0; - ic_data->vendor_touch_cfg_ver = 0; - ic_data->vendor_display_cfg_ver = 0; - ic_data->vendor_cid_maj_ver = 0; - ic_data->vendor_cid_min_ver = 0; - return; - } - else - { - retry --; - msleep(10); - if (retry % 10 == 0) - I("reload fail ,delay 10ms retry=%d\n",retry); - } - } - I("%s : data[0]=0x%2.2X,data[1]=0x%2.2X,data[2]=0x%2.2X,data[3]=0x%2.2X\n",__func__,data[0],data[1],data[2],data[3]); - I("reload_status=%d\n",reload_status); - - himax_sense_off(client); - - //===================================== - // Read FW version : 0x1000_7004 but 05,06 are the real addr for FW Version - //===================================== - - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0x04; - himax_register_read(client, cmd, 4, data, false); - - ic_data->vendor_panel_ver = data[0]; - ic_data->vendor_fw_ver = data[1] << 8 | data[2]; - - I("PANEL_VER : %X \n",ic_data->vendor_panel_ver); - I("FW_VER : %X \n",ic_data->vendor_fw_ver); - - - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0x84; - himax_register_read(client, cmd, 4, data, false); - - ic_data->vendor_config_ver = data[2] << 8 | data[3]; - //I("CFG_VER : %X \n",ic_data->vendor_config_ver); - ic_data->vendor_touch_cfg_ver = data[2]; - I("TOUCH_VER : %X \n",ic_data->vendor_touch_cfg_ver); - ic_data->vendor_display_cfg_ver = data[3]; - I("DISPLAY_VER : %X \n",ic_data->vendor_display_cfg_ver); - - - cmd[3] = 0x10; - cmd[2] = 0x00; - cmd[1] = 0x70; - cmd[0] = 0x00; - himax_register_read(client, cmd, 4, data, false); - - ic_data->vendor_cid_maj_ver = data[2] ; - ic_data->vendor_cid_min_ver = data[3]; - - I("CID_VER : %X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); - return; -} - -bool himax_ic_package_check(struct i2c_client *client) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - uint8_t ret_data = 0x00; - int i = 0; - - himax_enter_safe_mode(client); - - for (i = 0; i < 5; i++) - { -// Product ID - // Touch - tmp_addr[3] = 0x90; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0xD0; - himax_register_read(client, tmp_addr, 4, tmp_data, false); - - I("%s:Read driver IC ID = %X,%X,%X\n", __func__, tmp_data[3],tmp_data[2],tmp_data[1]); - if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && ((tmp_data[1] == 0x2a)||(tmp_data[1] == 0x2b))) - { - IC_TYPE = HX_83112A_SERIES_PWON; - IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC; - //Himax: Set FW and CFG Flash Address - FW_VER_MAJ_FLASH_ADDR = 49157; //0x00C005 - FW_VER_MAJ_FLASH_LENG = 1; - FW_VER_MIN_FLASH_ADDR = 49158; //0x00C006 - FW_VER_MIN_FLASH_LENG = 1; - CFG_VER_MAJ_FLASH_ADDR = 49408; //0x00C100 - CFG_VER_MAJ_FLASH_LENG = 1; - CFG_VER_MIN_FLASH_ADDR = 49409; //0x00C101 - CFG_VER_MIN_FLASH_LENG = 1; - CID_VER_MAJ_FLASH_ADDR = 49154; //0x00C002 - CID_VER_MAJ_FLASH_LENG = 1; - CID_VER_MIN_FLASH_ADDR = 49155; //0x00C003 - CID_VER_MIN_FLASH_LENG = 1; - //PANEL_VERSION_ADDR = 49156; //0x00C004 - //PANEL_VERSION_LENG = 1; -#ifdef HX_AUTO_UPDATE_FW - g_i_FW_VER = i_CTPM_FW[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[FW_VER_MIN_FLASH_ADDR]; - g_i_CFG_VER = i_CTPM_FW[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[CFG_VER_MIN_FLASH_ADDR]; - g_i_CID_MAJ = i_CTPM_FW[CID_VER_MAJ_FLASH_ADDR]; - g_i_CID_MIN = i_CTPM_FW[CID_VER_MIN_FLASH_ADDR]; -#endif - I("Himax IC package 83112_in\n"); - ret_data = true; - break; - } - else - { - ret_data = false; - E("%s:Read driver ID register Fail:\n", __func__); - } - } - - return ret_data; -} - -void himax_power_on_init(struct i2c_client *client) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - I("%s:\n", __func__); - himax_touch_information(client); - - /*RawOut select initial*/ - tmp_addr[3] = 0x80;tmp_addr[2] = 0x02;tmp_addr[1] = 0x04;tmp_addr[0] = 0xB4; - tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00; - himax_register_write(client,tmp_addr, 4, tmp_data, false); - - /*DSRAM func initial*/ - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x07;tmp_addr[0] = 0xFC; - tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00; - himax_register_write(client,tmp_addr, 4, tmp_data, false); - - himax_sense_on(client, 0x00); -} - -bool himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length) -{ - uint8_t cmd[4]; - - // AHB_I2C Burst Read Off - cmd[0] = 0x00; - if ( i2c_himax_write(client, 0x11,cmd, 1, DEFAULT_RETRY_CNT) < 0) - { - E("%s: i2c access fail!\n", __func__); - return 0; - } - - i2c_himax_read(client, 0x30, buf, length,DEFAULT_RETRY_CNT); - - // AHB_I2C Burst Read On - cmd[0] = 0x01; - if ( i2c_himax_write(client, 0x11,cmd, 1, 3) < 0) - { - E("%s: i2c access fail!\n", __func__); - return 0; - } - return 1; -} - -void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data) -{ - int i = 0; - //int cnt = 0; - unsigned char tmp_addr[4]; - unsigned char tmp_data[4]; - uint8_t max_i2c_size = 128; - uint8_t x_num = ic_data->HX_RX_NUM; - uint8_t y_num = ic_data->HX_TX_NUM; - int m_key_num = 0; - int total_size = (x_num * y_num + x_num + y_num) * 2 + 4; - int total_size_temp; - int mutual_data_size = x_num * y_num * 2; - int total_read_times = 0; - int address = 0; - uint8_t *temp_info_data; //max mkey size = 8 - uint16_t check_sum_cal = 0; - int fw_run_flag = -1; - //uint16_t temp_check_sum_cal = 0; - - temp_info_data = kzalloc(sizeof(uint8_t)*(total_size + 8),GFP_KERNEL); - - /*1. Read number of MKey R100070E8H to determin data size*/ - m_key_num = ic_data->HX_BT_NUM; - //I("%s,m_key_num=%d\n",__func__,m_key_num); - total_size += m_key_num*2; - - /* 2. Start DSRAM Rawdata and Wait Data Ready */ - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x5A; - tmp_data[0] = 0xA5; - fw_run_flag = himax_write_read_reg(client,tmp_addr,tmp_data,0xA5,0x5A); - - if(fw_run_flag < 0) - { - I("%s Data NOT ready => bypass \n", __func__); - kfree(temp_info_data); - return; - } - - /* 3. Read RawData */ - total_size_temp = total_size; - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x00; - - if (total_size % max_i2c_size == 0) - { - total_read_times = total_size / max_i2c_size; - } - else - { - total_read_times = total_size / max_i2c_size + 1; - } - - for (i = 0; i < (total_read_times); i++) - { - if ( total_size_temp >= max_i2c_size) - { - himax_register_read(client, tmp_addr, max_i2c_size, &temp_info_data[i*max_i2c_size], false); - total_size_temp = total_size_temp - max_i2c_size; - } - else - { - //I("last total_size_temp=%d\n",total_size_temp); - himax_register_read(client, tmp_addr, total_size_temp % max_i2c_size, &temp_info_data[i*max_i2c_size], false); - } - - address = ((i+1)*max_i2c_size); - tmp_addr[1] = (uint8_t)((address>>8)&0x00FF); - tmp_addr[0] = (uint8_t)((address)&0x00FF); - } - - /* 4. FW stop outputing */ - //I("DSRAM_Flag=%d\n",DSRAM_Flag); - if(DSRAM_Flag == false) - { - //I("Return to Event Stack!\n"); - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - himax_flash_write_burst(client, tmp_addr, tmp_data); - } - else - { - //I("Continue to SRAM!\n"); - tmp_addr[3] = 0x10; - tmp_addr[2] = 0x00; - tmp_addr[1] = 0x00; - tmp_addr[0] = 0x00; - tmp_data[3] = 0x11; - tmp_data[2] = 0x22; - tmp_data[1] = 0x33; - tmp_data[0] = 0x44; - himax_flash_write_burst(client, tmp_addr, tmp_data); - } - - /* 5. Data Checksum Check */ - for (i = 2; i < total_size; i=i+2)/* 2:PASSWORD NOT included */ - { - check_sum_cal += (temp_info_data[i+1]*256 + temp_info_data[i]); - } - - if (check_sum_cal % 0x10000 != 0) - { - I("%s check_sum_cal fail=%2X \n", __func__, check_sum_cal); - kfree(temp_info_data); - return; - } - else - { - memcpy(info_data, &temp_info_data[4], mutual_data_size * sizeof(uint8_t)); - //I("%s checksum PASS \n", __func__); - } - kfree(temp_info_data); -} - -bool himax_calculateChecksum(struct i2c_client *client, bool change_iref) -{ - uint8_t CRC_result = 0; - uint8_t tmp_data[4]; - - tmp_data[3] = 0x00; - tmp_data[2] = 0x00; - tmp_data[1] = 0x00; - tmp_data[0] = 0x00; - - CRC_result = himax_hw_check_CRC(client,tmp_data, FW_SIZE_64k); - - msleep(50); - - return CRC_result; -} - -bool himax_flash_lastdata_check(struct i2c_client *client) -{ - uint8_t tmp_addr[4]; - uint32_t start_addr = 0xFF80; - uint32_t temp_addr = 0; - uint32_t flash_page_len = 0x80; - uint8_t flash_tmp_buffer[128]; - - for (temp_addr = start_addr; temp_addr < (start_addr + flash_page_len); temp_addr = temp_addr + flash_page_len) - { - //I("temp_addr=%d,tmp_addr[0]=0x%2X,tmp_addr[1]=0x%2X,tmp_addr[2]=0x%2X,tmp_addr[3]=0x%2X\n",temp_addr,tmp_addr[0],tmp_addr[1],tmp_addr[2],tmp_addr[3]); - tmp_addr[0] = temp_addr % 0x100; - tmp_addr[1] = (temp_addr >> 8) % 0x100; - tmp_addr[2] = (temp_addr >> 16) % 0x100; - tmp_addr[3] = temp_addr / 0x1000000; - himax_register_read(client, tmp_addr ,flash_page_len, &flash_tmp_buffer[0], false); - } - - if((!flash_tmp_buffer[flash_page_len-4]) && (!flash_tmp_buffer[flash_page_len-3]) && (!flash_tmp_buffer[flash_page_len-2]) && (!flash_tmp_buffer[flash_page_len-1])) - { - return 1;//FAIL - } - else - { - I("flash_buffer[FFFC]=0x%2X,flash_buffer[FFFD]=0x%2X,flash_buffer[FFFE]=0x%2X,flash_buffer[FFFF]=0x%2X\n", - flash_tmp_buffer[flash_page_len-4],flash_tmp_buffer[flash_page_len-3],flash_tmp_buffer[flash_page_len-2],flash_tmp_buffer[flash_page_len-1]); - return 0;//PASS - } -} - -//ts_work -int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max) -{ - int RawDataLen; - if (raw_cnt_rmd != 0x00) - { - RawDataLen = 128 - ((HX_MAX_PT+raw_cnt_max+3)*4) - 1; - } - else - { - RawDataLen = 128 - ((HX_MAX_PT+raw_cnt_max+2)*4) - 1; - } - return RawDataLen; -} - -bool diag_check_sum( struct himax_report_data *hx_touch_data ) //return checksum value -{ - uint16_t check_sum_cal = 0; - int i; - - //Check 128th byte CRC - for (i = 0, check_sum_cal = 0; i < (hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); i=i+2) - { - check_sum_cal += (hx_touch_data->hx_rawdata_buf[i+1]*256 + hx_touch_data->hx_rawdata_buf[i]); - } - if (check_sum_cal % 0x10000 != 0) - { - I("%s fail=%2X \n", __func__, check_sum_cal); - return 0; - //goto bypass_checksum_failed_packet; - } - - return 1; -} - - -void diag_parse_raw_data(struct himax_report_data *hx_touch_data,int mul_num, int self_num,uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data) -{ - int RawDataLen_word; - int index = 0; - int temp1, temp2,i; - - if (hx_touch_data->hx_rawdata_buf[0] == 0x3A - && hx_touch_data->hx_rawdata_buf[1] == 0xA3 - && hx_touch_data->hx_rawdata_buf[2] > 0 - && hx_touch_data->hx_rawdata_buf[3] == diag_cmd ) - { - RawDataLen_word = hx_touch_data->rawdata_size/2; - index = (hx_touch_data->hx_rawdata_buf[2] - 1) * RawDataLen_word; - //I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n", index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num); - //I("RawDataLen=%d , RawDataLen_word=%d , hx_touch_info_size=%d\n", RawDataLen, RawDataLen_word, hx_touch_info_size); - for (i = 0; i < RawDataLen_word; i++) - { - temp1 = index + i; - - if (temp1 < mul_num) - { - //mutual - mutual_data[index + i] = ((int8_t)hx_touch_data->hx_rawdata_buf[i*2 + 4 + 1])*256 + hx_touch_data->hx_rawdata_buf[i*2 + 4]; //4: RawData Header, 1:HSB - } - else - { - //self - temp1 = i + index; - temp2 = self_num + mul_num; - - if (temp1 >= temp2) - { - break; - } - self_data[i + index - mul_num] = (hx_touch_data->hx_rawdata_buf[i * 2 + 4 + 1] << 8) + - hx_touch_data->hx_rawdata_buf[i * 2 + 4]; /* 4: RawData Header */ - } - } - } - -} -uint8_t himax_read_DD_status(uint8_t *cmd_set, uint8_t *tmp_data) -{ - int cnt = 0; - uint8_t req_size = cmd_set[0]; - uint8_t cmd_addr[4] = {0xFC, 0x00, 0x00, 0x90}; //0x900000FC -> cmd and hand shaking - uint8_t tmp_addr[4] = {0x80, 0x7F, 0x00, 0x10}; //0x10007F80 -> data space - - cmd_set[3] = 0xAA; - himax_register_write(private_ts->client, cmd_addr, 4, cmd_set, 0); - - I("%s: cmd_set[0] = 0x%02X,cmd_set[1] = 0x%02X,cmd_set[2] = 0x%02X,cmd_set[3] = 0x%02X\n", __func__,cmd_set[0],cmd_set[1],cmd_set[2],cmd_set[3]); - - for (cnt = 0; cnt < 100; cnt++) //doing hand shaking 0xAA -> 0xBB - { - himax_register_read(private_ts->client, cmd_addr, 4, tmp_data, false); - //I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X, cnt=%d\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3],cnt); - msleep(10); - if(tmp_data[3] == 0xBB) - { - I("%s Data ready goto moving data\n", __func__); - break; - } - else if(cnt >= 99) - { - I("%s Data not ready in FW \n", __func__); - return FW_NOT_READY; - } - } - himax_register_read(private_ts->client, tmp_addr, req_size, tmp_data, false); - return NO_ERR; -} - -int himax_read_FW_status(uint8_t *state_addr, uint8_t *tmp_addr) -{ - uint8_t req_size = 0; - uint8_t status_addr[4] = {0x44, 0x7F, 0x00, 0x10}; //0x10007F44 - uint8_t cmd_addr[4] = {0xF8, 0x00, 0x00, 0x90}; //0x900000F8 - - if(state_addr[0]==0x01) - { - state_addr[1]= 0x04; - state_addr[2]= status_addr[0];state_addr[3]= status_addr[1];state_addr[4]= status_addr[2];state_addr[5]= status_addr[3]; - req_size = 0x04; - himax_sense_off(private_ts->client); - himax_register_read(private_ts->client, status_addr, req_size, tmp_addr, false); - himax_sense_on(private_ts->client,1); - } - else if(state_addr[0]==0x02) - { - state_addr[1]= 0x30; - state_addr[2]= cmd_addr[0];state_addr[3]= cmd_addr[1];state_addr[4]= cmd_addr[2];state_addr[5]= cmd_addr[3]; - req_size = 0x30; - himax_register_read(private_ts->client, cmd_addr, req_size, tmp_addr, false); - } - - return NO_ERR; -} - -#ifdef HX_TP_PROC_GUEST_INFO -#define HX_GUEST_INFO_SIZE 10 -#define HX_GUEST_INFO_LEN_SIZE 4 -int g_guest_info_ongoing = 0; //0 stop //1 ongoing -char g_guest_str[10][128]; - - - -int himax_guest_info_get_status(void) -{ - return g_guest_info_ongoing; -} -void himax_guest_info_set_status(int setting) -{ - g_guest_info_ongoing = setting; -} - -void himax_guest_info_read(uint32_t start_addr,uint8_t *flash_tmp_buffer) -{ - uint32_t temp_addr = 0; - uint8_t tmp_addr[4]; - uint32_t flash_page_len = 0x1000; - - - I("Reading guest info in start_addr = %d !\n",start_addr); - for (temp_addr = start_addr; temp_addr < (start_addr + flash_page_len); temp_addr = temp_addr + 128) - { - - //I("temp_addr=%d,tmp_addr[0]=0x%2X,tmp_addr[1]=0x%2X,tmp_addr[2]=0x%2X,tmp_addr[3]=0x%2X\n",temp_addr,tmp_addr[0],tmp_addr[1],tmp_addr[2],tmp_addr[3]); - tmp_addr[0] = temp_addr % 0x100; - tmp_addr[1] = (temp_addr >> 8) % 0x100; - tmp_addr[2] = (temp_addr >> 16) % 0x100; - tmp_addr[3] = temp_addr / 0x1000000; - himax_register_read(private_ts->client, tmp_addr ,128,&flash_tmp_buffer[temp_addr - start_addr],false); - // memcpy(&flash_tmp_buffer[temp_addr - start_addr],buffer,128); - } -} - -int himax_read_project_id(void) -{ - // uint8_t tmp_addr[4]; - uint32_t panel_color_addr = 0x10000;/*64k*/ - - uint32_t info_len; - uint32_t flash_page_len = 0x1000;/*4k*/ - uint8_t *flash_tmp_buffer = NULL; - // uint32_t temp_addr = 0; - char temp_str[128]; - int i = 0; - int custom_info_temp = 0; - - himax_guest_info_set_status(1); - - flash_tmp_buffer = kzalloc(HX_GUEST_INFO_SIZE * flash_page_len * sizeof(uint8_t), GFP_KERNEL); - himax_sense_off(private_ts->client); - himax_burst_enable(private_ts->client, 1); - - - - for(custom_info_temp = 0; custom_info_temp < HX_GUEST_INFO_SIZE;custom_info_temp++) - { - himax_guest_info_read(panel_color_addr+custom_info_temp*flash_page_len,&flash_tmp_buffer[custom_info_temp*flash_page_len]); - - info_len = flash_tmp_buffer[custom_info_temp*flash_page_len] - + (flash_tmp_buffer[custom_info_temp*flash_page_len+1] << 8) - + (flash_tmp_buffer[custom_info_temp*flash_page_len+2] << 16) - + (flash_tmp_buffer[custom_info_temp*flash_page_len+3] << 24); - I("Now custom_info_temp = %d,[0]=%d,[1]=%d,[2]=%d,[3]=%d,info_len=%d\n" - ,custom_info_temp - ,flash_tmp_buffer[custom_info_temp*flash_page_len] - ,flash_tmp_buffer[custom_info_temp*flash_page_len+1] - ,flash_tmp_buffer[custom_info_temp*flash_page_len+2] - ,flash_tmp_buffer[custom_info_temp*flash_page_len+3] - ,info_len); - - if(info_len > 128) - info_len = 128; - - for(i = 0;i < info_len; i++) - temp_str[i] = flash_tmp_buffer[custom_info_temp*flash_page_len+HX_GUEST_INFO_LEN_SIZE+i]; - - I("g_guest_str[%d] size = %d\n",custom_info_temp,info_len); - memcpy(&g_guest_str[custom_info_temp][0],temp_str,info_len); - if(custom_info_temp == 0) - { - for( i = 0; i< 128 ; i++) - { - if(i % 16 == 0 && i > 0) - I("\n"); - I("g_guest_str[%d][%d] = 0x%02X",custom_info_temp,i,g_guest_str[custom_info_temp][i]); - } - } - } - himax_burst_enable(private_ts->client, 0); - himax_sense_on(private_ts->client, 0x01); - - - kfree(flash_tmp_buffer); - himax_guest_info_set_status(0); - return NO_ERR; -} -#endif - - -#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) -void himax_resend_cmd_func(bool suspended) -{ - struct himax_ts_data *ts; - - ts = private_ts; - -#ifdef HX_SMART_WAKEUP - himax_set_SMWP_enable(ts->client,ts->SMWP_enable,suspended); -#endif -#ifdef HX_HIGH_SENSE - himax_set_HSEN_enable(ts->client,ts->HSEN_enable,suspended); -#endif -#ifdef HX_USB_DETECT_GLOBAL - himax_cable_detect_func(true); -#endif -} - -void himax_rst_cmd_recovery_func(bool suspended) -{ - -} -#endif - -void himax_resume_ic_action(struct i2c_client *client) -{ - return; -} - -void himax_suspend_ic_action(struct i2c_client *client) -{ - return; -} - -#ifdef HX_ZERO_FLASH -int G_POWERONOF = 1; -void himax_sys_reset(void) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - // 0x10007f00 -> 0x0000A55A //Diable Flash Reload - tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x00; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x9A; tmp_data[0] = 0xA9; - himax_flash_write_burst(private_ts->client,tmp_addr, tmp_data); - - msleep(100); - - tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x18; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x55; - himax_register_write(private_ts->client,tmp_addr, 4, tmp_data, false); -} -void himax_clean_sram_0f(uint8_t *addr,int write_len,int type) -{ - int total_read_times = 0; - int max_bus_size = 128; - int total_size_temp = 0; - int total_size = 0; - int address = 0; - int i = 0; - - uint8_t fix_data = 0x00; - uint8_t tmp_addr[4]; - uint8_t tmp_data[128]={0}; - - I("%s,Entering \n",__func__); - - total_size = write_len; - - total_size_temp = write_len; - - I("[log]enable start!\n"); - himax_burst_enable(private_ts->client,1); - I("[log]enable end!\n"); - - tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0]; - I("%s, write addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); - - - switch(type) - { - case 0: - fix_data = 0x00; - break; - case 1: - fix_data = 0xAA; - break; - case 2: - fix_data = 0xBB; - break; - } - - for(i = 0;i<128;i++) - { - tmp_data[i] = fix_data; - } - - - I("%s, total size=%d\n",__func__,total_size); - - if (total_size_temp % max_bus_size == 0) - { - total_read_times = total_size_temp / max_bus_size; - } - else - { - total_read_times = total_size_temp / max_bus_size + 1; - } - - for (i = 0; i < (total_read_times); i++) - { - I("[log]write %d time start!\n",i); - if ( total_size_temp >= max_bus_size) - { - himax_flash_write_burst_lenth(private_ts->client,tmp_addr,tmp_data, max_bus_size); - total_size_temp = total_size_temp - max_bus_size; - } - else - { - I("last total_size_temp=%d\n",total_size_temp); - himax_flash_write_burst_lenth(private_ts->client,tmp_addr,tmp_data, total_size_temp % max_bus_size); - } - address = ((i+1)*max_bus_size); - tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF); - tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF); - - msleep(10); - } - - I("%s,END \n",__func__); -} - -void himax_write_sram_0f(const struct firmware *fw_entry,uint8_t *addr,int start_index,int write_len) -{ - int total_read_times = 0; - int max_bus_size = 128; - int total_size_temp = 0; - int total_size = 0; - int address = 0; - int i = 0; - - uint8_t tmp_addr[4]; - uint8_t *tmp_data; - uint32_t now_addr; - - I("%s,Entering \n",__func__); - - total_size = 65536; - - total_size_temp = write_len; - - I("[log]enable start!\n"); - himax_burst_enable(private_ts->client,1); - I("[log]enable end!\n"); - - tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0]; - I("%s, write addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); - now_addr = (addr[3] << 24) + (addr[2] << 16) + (addr[1] << 8) + addr[0]; - I("now addr= 0x%08X\n",now_addr); - - I("%s, total size=%d\n",__func__,total_size); - - //I("[log]locate start!\n"); - tmp_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL); - //I("[log]enable end!\n"); - //I("[log]memcpy start!\n"); - memcpy(tmp_data,fw_entry->data,total_size); - //I("[log]memcpy end!\n"); - - I("tmp_data size=%d\n",(int)sizeof(tmp_data)); - - for(i = 0;i<10;i++) - { - I("[%d] 0x%2.2X",i,tmp_data[i]); - } - I("\n"); - if (total_size_temp % max_bus_size == 0) - { - total_read_times = total_size_temp / max_bus_size; - } - else - { - total_read_times = total_size_temp / max_bus_size + 1; - } - - for (i = 0; i < (total_read_times); i++) - { - I("[log]write %d time start!\n",i); - if ( total_size_temp >= max_bus_size) - { - himax_flash_write_burst_lenth(private_ts->client,tmp_addr,&(tmp_data[start_index+i*max_bus_size]), max_bus_size); - total_size_temp = total_size_temp - max_bus_size; - } - else - { - I("last total_size_temp=%d\n",total_size_temp); - himax_flash_write_burst_lenth(private_ts->client,tmp_addr,&(tmp_data[start_index+i*max_bus_size]), total_size_temp % max_bus_size); - } - I("[log]write %d time end!\n",i); - address = ((i+1)*max_bus_size); - tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF); - if(tmp_addr[0] < addr[0]) - tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF) + 1; - else - tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF); - - - msleep(10); - } - I("%s,END \n",__func__); - kfree(tmp_data); -} - -void himax_firmware_update_0f(const struct firmware *fw_entry) -{ - uint8_t tmp_addr[4]; - uint8_t tmp_data[4]; - - I("%s,Entering \n",__func__); - - tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x18; - tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x55; - himax_register_write(private_ts->client,tmp_addr, 4, tmp_data, false); - - himax_sense_off(private_ts->client); - - himax_chip_erase(private_ts->client); - - /* first 48K */ - tmp_addr[3] = 0x08;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00; - himax_write_sram_0f(fw_entry,tmp_addr,0,0xC000); - - - /* clean */ - if(G_POWERONOF == 1) - { - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00; - himax_clean_sram_0f(tmp_addr,32768,0); - } - - /*last 16k*/ - /*config info*/ - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x00; - if(G_POWERONOF == 1) - himax_write_sram_0f(fw_entry,tmp_addr,0xC000,132); - else - himax_clean_sram_0f(tmp_addr,132,2); - /*FW config*/ - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x84; - if(G_POWERONOF == 1) - himax_write_sram_0f(fw_entry,tmp_addr,0xC0FE,512); //0xc100-2 - else - himax_clean_sram_0f(tmp_addr,512,1); - /*ADC config*/ - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x78;tmp_addr[0] = 0x00; - if(G_POWERONOF == 1) - himax_write_sram_0f(fw_entry,tmp_addr,0xD000,376); - else - himax_clean_sram_0f(tmp_addr,376,2); - - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x79;tmp_addr[0] = 0x78; - if(G_POWERONOF == 1) - himax_write_sram_0f(fw_entry,tmp_addr,0xD178,376); - else - himax_clean_sram_0f(tmp_addr,376,2); - - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x7A;tmp_addr[0] = 0xF0; - if(G_POWERONOF == 1) - himax_write_sram_0f(fw_entry,tmp_addr,0xD000,376); - else - himax_clean_sram_0f(tmp_addr,376,2); - - //G_POWERONOF = 0; - - I("%s,END \n",__func__); -} -void himax_0f_operation(struct work_struct *work) -{ - int err = NO_ERR; - const struct firmware *fw_entry = NULL; - char *firmware_name = "himax.bin"; - uint8_t tmp_data[4]; - - I("%s,Entering \n",__func__); - I("file name = %s\n",firmware_name); - err = request_firmware(&fw_entry, firmware_name, private_ts->dev); - if (err < 0) { - E("%s,fail in line%d error code=%d\n",__func__,__LINE__,err); - //goto err_request_firmware; - return ; - } - himax_firmware_update_0f(fw_entry); - release_firmware(fw_entry); - - tmp_data[0] = 0x00;tmp_data[1] = 0x00;tmp_data[2] = 0x00;tmp_data[3] = 0x08; - if(himax_hw_check_CRC(private_ts->client,tmp_data, 0xC000) == 0) - { - I("%s,HW CRC OK!\n",__func__); - } - else - { - E("%s,HW CRC FAIL!\n",__func__); - } - - msleep(100); - himax_sys_reset(); - msleep(100); - himax_int_enable(private_ts->client->irq,1); - - I("%s,END \n",__func__); - return ; -} - -#ifdef HX_0F_DEBUG -void himax_read_sram_0f(const struct firmware *fw_entry,uint8_t *addr,int start_index,int read_len) -{ - int total_read_times = 0; - int max_i2c_size = 128; - int total_size_temp = 0; - int total_size = 0; - int address = 0; - int i = 0,j = 0; - int not_same = 0; - - uint8_t tmp_addr[4]; - uint8_t *temp_info_data; - int *not_same_buff; - - I("%s,Entering \n",__func__); - - himax_burst_enable(private_ts->client,1); - - total_size = read_len; - - total_size_temp = read_len; - - temp_info_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL); - not_same_buff = kzalloc(sizeof(int)*total_size,GFP_KERNEL); - - - tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0]; - I("%s, read addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); - - I("%s, total size=%d\n",__func__,total_size); - - himax_burst_enable(private_ts->client,1); - - if (total_size % max_i2c_size == 0) - { - total_read_times = total_size / max_i2c_size; - } - else - { - total_read_times = total_size / max_i2c_size + 1; - } - - for (i = 0; i < (total_read_times); i++) - { - if ( total_size_temp >= max_i2c_size) - { - himax_register_read(private_ts->client,tmp_addr, max_i2c_size, &temp_info_data[i*max_i2c_size], false); - total_size_temp = total_size_temp - max_i2c_size; - } - else - { - //I("last total_size_temp=%d\n",total_size_temp); - himax_register_read(private_ts->client,tmp_addr, total_size_temp % max_i2c_size, &temp_info_data[i*max_i2c_size], false); - } - - address = ((i+1)*max_i2c_size); - tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF); - if(tmp_addr[0] < addr[0]) - tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF) + 1; - else - tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF); - - msleep(10); - } - I("%s,READ Start \n",__func__); - I("%s,start_index = %d \n",__func__,start_index); - j = start_index; - for(i = 0;i < read_len;i++,j++) - { - if(fw_entry->data[j] != temp_info_data[i]) - { - not_same++; - not_same_buff[i] = 1; - } - - - - - I("0x%2.2X,",temp_info_data[i]); - - if (i > 0 && i%16 == 15) - printk("\n"); - } - I("%s,READ END \n",__func__); - I("%s,Not Same count=%d\n",__func__,not_same); - if(not_same != 0) - { - j = start_index; - for(i = 0;idata[j]); - } - for(i = 0;iclient,1); - - total_size = read_len; - - total_size_temp = read_len; - - temp_info_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL); - - - tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0]; - I("%s, read addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); - - I("%s, total size=%d\n",__func__,total_size); - - if (total_size % max_bus_size == 0) - { - total_read_times = total_size / max_bus_size; - } - else - { - total_read_times = total_size / max_bus_size + 1; - } - - for (i = 0; i < (total_read_times); i++) - { - if ( total_size_temp >= max_bus_size) - { - himax_register_read(private_ts->client,tmp_addr, max_bus_size, &temp_info_data[i*max_bus_size], false); - total_size_temp = total_size_temp - max_bus_size; - } - else - { - //I("last total_size_temp=%d\n",total_size_temp); - himax_register_read(private_ts->client,tmp_addr, total_size_temp % max_bus_size, &temp_info_data[i*max_bus_size], false); - } - - address = ((i+1)*max_bus_size); - tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF); - tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF); - - msleep(10); - } - I("%s, NOW addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); - /*for(i = 0;i 0 && i%16 == 15) - printk("\n"); - }*/ - - - I("Now Write File start!\n"); - fn = filp_open("/sdcard/dump_dsram.txt",O_CREAT | O_WRONLY ,0); - if (!IS_ERR(fn)) - { - I("%s create file and ready to write\n",__func__); - fn->f_op->write(fn,temp_info_data,read_len*sizeof(uint8_t),&fn->f_pos); - filp_close(fn,NULL); - } - I("Now Write File End!\n"); - - - I("%s,END \n",__func__); - - kfree(temp_info_data); -} - -void himax_firmware_read_0f(const struct firmware *fw_entry) -{ - uint8_t tmp_addr[4]; - - I("%s,Entering \n",__func__); - /* first 48K */ - tmp_addr[3] = 0x08;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00; - himax_read_sram_0f(fw_entry,tmp_addr,0,0xC000); - - /*last 16k*/ - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x00; - himax_read_sram_0f(fw_entry,tmp_addr,0xC000,132); - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x84; - himax_read_sram_0f(fw_entry,tmp_addr,0xC0FE,512);//0xc100-2 - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x78;tmp_addr[0] = 0x00; - himax_read_sram_0f(fw_entry,tmp_addr,0xD000,376); - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x79;tmp_addr[0] = 0x78; - himax_read_sram_0f(fw_entry,tmp_addr,0xD178,376); - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x7A;tmp_addr[0] = 0xF0; - himax_read_sram_0f(fw_entry,tmp_addr,0xD000,376); - - tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00; - himax_read_all_sram(tmp_addr,32768); - I("%s,END \n",__func__); -} - -void himax_0f_operation_check(void) -{ - int err = NO_ERR; - const struct firmware *fw_entry = NULL; - char *firmware_name = "himax.bin"; - - - I("%s,Entering \n",__func__); - I("file name = %s\n",firmware_name); - - err = request_firmware(&fw_entry, firmware_name, private_ts->dev); - if (err < 0) { - E("%s,fail in line%d error code=%d\n",__func__,__LINE__,err); - //goto err_request_firmware; - return ; - } - - I("first 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[0],fw_entry->data[1],fw_entry->data[2],fw_entry->data[3]); - I("next 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[4],fw_entry->data[5],fw_entry->data[6],fw_entry->data[7]); - I("and next 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[8],fw_entry->data[9],fw_entry->data[10],fw_entry->data[11]); - - himax_firmware_read_0f(fw_entry); - - release_firmware(fw_entry); - I("%s,END \n",__func__); - return ; -} -#endif - -#endif diff --git a/drivers/input/touchscreen/himax_mmi/himax_ic.h b/drivers/input/touchscreen/himax_mmi/himax_ic.h deleted file mode 100644 index 685ca92da55d..000000000000 --- a/drivers/input/touchscreen/himax_mmi/himax_ic.h +++ /dev/null @@ -1,212 +0,0 @@ -/* Himax Android Driver Sample Code for HX83112 chipset -* -* Copyright (C) 2017 Himax Corporation. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -*/ - -#include "himax_platform.h" -#include "himax_common.h" -#include - -#define HIMAX_REG_RETRY_TIMES 5 - -#ifdef HX_ESD_RECOVERY -extern u8 HX_ESD_RESET_ACTIVATE; -#endif - -#ifndef HX_ORG_SELFTEST -#define BS_RAWDATANOISE 10 -#define BS_OPENSHORT 0 - -#ifdef HX_INSPECT_LPWUG_TEST -#define BS_LPWUG 1 -#define BS_LPWUG_dile 1 -#endif - -#ifdef HX_DOZE_TEST -#define BS_DOZE 1 -#endif - -// skip notch & dummy -#define SKIP_NOTCH_START 5 -#define SKIP_NOTCH_END 10 -#define SKIP_DUMMY_START 23 //TX+SKIP_NOTCH_START -#define SKIP_DUMMY_END 28 // TX+SKIP_NOTCH_END - -//Himax MP Limit -#define RAWMIN 10000 -#define RAWMAX 20000 -#define SHORTMIN 0 -#define SHORTMAX 150 -#define OPENMIN 50 -#define OPENMAX 500 -#define M_OPENMIN 50 -#define M_OPENMAX 500 -#define NOISEFRAME BS_RAWDATANOISE+1 -#define UNIFMAX 500 -#ifdef HX_DOZE_TEST -#define DOZE_NOISE_MAX 9999 -#define DOZE_NOISE_MIN 0 -#define DOZE_RAWDATA_MAX 9999 -#define DOZE_RAWDATA_MIN 0 -#endif -#ifdef HX_INSPECT_LPWUG_TEST -#define LPWUG_NOISE_MAX 9999 -#define LPWUG_NOISE_MIN 0 -#define LPWUG_RAWDATA_MAX 9999 -#define LPWUG_RAWDATA_MIN 0 - -#define LPWUG_IDLE_NOISE_MAX 9999 -#define LPWUG_IDLE_NOISE_MIN 0 -#define LPWUG_IDLE_RAWDATA_MAX 9999 -#define LPWUG_IDLE_RAWDATA_MIN 0 -#endif - -//Himax MP Password -#define PWD_OPEN_START 0x77 -#define PWD_OPEN_END 0x88 -#define PWD_SHORT_START 0x11 -#define PWD_SHORT_END 0x33 -#define PWD_RAWDATA_START 0x00 -#define PWD_RAWDATA_END 0x99 -#define PWD_NOISE_START 0x00 -#define PWD_NOISE_END 0x99 -#define PWD_SORTING_START 0xAA -#define PWD_SORTING_END 0xCC - -#ifdef HX_DOZE_TEST -#define PWD_DOZE_START 0x22 -#define PWD_DOZE_END 0x44 -#endif - -#ifdef HX_INSPECT_LPWUG_TEST -#define PWD_LPWUG_START 0x55 -#define PWD_LPWUG_END 0x66 - -#define PWD_LPWUG_IDLE_START 0x50 -#define PWD_LPWUG_IDLE_END 0x60 -#endif - -//Himax DataType -#define DATA_OPEN 0x0B -#define DATA_MICRO_OPEN 0x0C -#define DATA_SHORT 0x0A -#define DATA_RAWDATA 0x0A -#define DATA_NOISE 0x0F -#define DATA_BACK_NORMAL 0x00 -#define DATA_LPWUG_RAWDATA 0x0C -#define DATA_LPWUG_NOISE 0x0F -#define DATA_DOZE_RAWDATA 0x0A -#define DATA_DOZE_NOISE 0x0F -#define DATA_LPWUG_IDLE_RAWDATA 0x0A -#define DATA_LPWUG_IDLE_NOISE 0x0F - -//Himax Data Ready Password -#define Data_PWD0 0xA5 -#define Data_PWD1 0x5A - -typedef enum -{ - HIMAX_INSPECTION_OPEN, - HIMAX_INSPECTION_MICRO_OPEN, - HIMAX_INSPECTION_SHORT, - HIMAX_INSPECTION_RAWDATA, - HIMAX_INSPECTION_NOISE, - HIMAX_INSPECTION_SORTING, - HIMAX_INSPECTION_BACK_NORMAL, -#ifdef HX_DOZE_TEST - HIMAX_INSPECTION_DOZE_RAWDATA, - HIMAX_INSPECTION_DOZE_NOISE, -#endif -#ifdef HX_INSPECT_LPWUG_TEST - HIMAX_INSPECTION_LPWUG_RAWDATA, - HIMAX_INSPECTION_LPWUG_NOISE, - HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA, - HIMAX_INSPECTION_LPWUG_IDLE_NOISE, -#endif -}THP_INSPECTION_ENUM; - -/* Error code of AFE Inspection */ -typedef enum -{ - HX_INSPECT_OK = 0, /* OK */ - HX_INSPECT_ESPI = (1 << 0), /* SPI communication error */ - HX_INSPECT_ERAW = (1 << 1), /* Raw data error */ - HX_INSPECT_ENOISE = (1 << 2), /* Noise error */ - HX_INSPECT_EOPEN = (1 << 3), /* Sensor open error */ - HX_INSPECT_EMOPEN = (1 << 4), /* Sensor micro open error */ - HX_INSPECT_ESHORT = (1 << 5), /* Sensor short error */ - HX_INSPECT_ERC = (1 << 6), /* Sensor RC error */ - HX_INSPECT_EPIN = (1 << 7), /* Errors of TSVD!¢FFTSHD!¢FFTRCST!¢FFTRCRQ and other PINs - when Report Rate Switching between 60 Hz and 120 Hz */ - HX_INSPECT_EOTHER = (1 << 8) /* All other errors */ -} HX_INSPECT_ERR_ENUM; - -#endif -enum fw_image_type -{ - fw_image_32k = 0x01, - fw_image_48k, - fw_image_60k, - fw_image_64k, - fw_image_124k, - fw_image_128k, -}; - -int himax_hand_shaking(struct i2c_client *client); -void himax_set_SMWP_enable(struct i2c_client *client,uint8_t SMWP_enable, bool suspended); -void himax_set_HSEN_enable(struct i2c_client *client,uint8_t HSEN_enable, bool suspended); -void himax_usb_detect_set(struct i2c_client *client,uint8_t *cable_config); -int himax_determin_diag_rawdata(int diag_command); -int himax_determin_diag_storage(int diag_command); -void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command); -void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer); -int himax_chip_self_test(struct i2c_client *client); -void himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte); -int himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data, bool cfg_flag); -void himax_flash_read(struct i2c_client *client, uint8_t *reg_byte, uint8_t *read_data); -int himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data); -void himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length); -void himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data, bool cfg_flag); -bool himax_sense_off(struct i2c_client *client); -void himax_interface_on(struct i2c_client *client); -bool wait_wip(struct i2c_client *client, int Timing); -void himax_sense_on(struct i2c_client *client, uint8_t FlashMode); -void himax_chip_erase(struct i2c_client *client); -bool himax_block_erase(struct i2c_client *client, int start_addr, int length); -void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size); -int himax_check_CRC(struct i2c_client *client, int mode); -int fts_ctpm_fw_upgrade_with_sys_fs_32k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); -int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); -int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); -int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); -int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); -void himax_touch_information(struct i2c_client *client); -int himax_read_i2c_status(struct i2c_client *client); -int himax_read_ic_trigger_type(struct i2c_client *client); -void himax_read_FW_ver(struct i2c_client *client); -bool himax_ic_package_check(struct i2c_client *client); -void himax_power_on_init(struct i2c_client *client); -bool himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length); -void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data); -bool himax_calculateChecksum(struct i2c_client *client, bool change_iref); -bool himax_flash_lastdata_check(struct i2c_client *client); -bool himax_program_reload(struct i2c_client *client); -uint8_t himax_read_DD_status(uint8_t *cmd_set, uint8_t *tmp_data); -int himax_read_FW_status(uint8_t *state_addr, uint8_t *tmp_addr); -void himax_resume_ic_action(struct i2c_client *client); -void himax_suspend_ic_action(struct i2c_client *client); - -//ts_work -int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max); -bool diag_check_sum(struct himax_report_data *hx_touch_data); //return checksum value -void diag_parse_raw_data(struct himax_report_data *hx_touch_data,int mul_num, int self_num,uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data); \ No newline at end of file diff --git a/drivers/input/touchscreen/himax_mmi/himax_ic_HX83112.c b/drivers/input/touchscreen/himax_mmi/himax_ic_HX83112.c new file mode 100644 index 000000000000..bb17eb4886dc --- /dev/null +++ b/drivers/input/touchscreen/himax_mmi/himax_ic_HX83112.c @@ -0,0 +1,316 @@ +/* Himax Android Driver Sample Code for HX83112 chipset + + Copyright (C) 2018 Himax Corporation. + + This software is licensed under the terms of the GNU General Public + License version 2, as published by the Free Software Foundation, and + may be copied, distributed, and modified under those terms. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ + +#include "himax_ic_HX83112.h" +extern struct himax_ts_data *private_ts; +extern struct himax_core_fp g_core_fp; +extern struct ic_operation *pic_op; +extern struct fw_operation *pfw_op; +#ifdef HX_ZERO_FLASH +extern struct zf_operation *pzf_op; +#endif + +extern int i2c_error_count; +extern unsigned char IC_TYPE; +extern unsigned char IC_CHECKSUM; +extern bool DSRAM_Flag; + +extern unsigned long FW_VER_MAJ_FLASH_ADDR; +extern unsigned long FW_VER_MIN_FLASH_ADDR; +extern unsigned long CFG_VER_MAJ_FLASH_ADDR; +extern unsigned long CFG_VER_MIN_FLASH_ADDR; +extern unsigned long CID_VER_MAJ_FLASH_ADDR; +extern unsigned long CID_VER_MIN_FLASH_ADDR; + +extern unsigned long FW_VER_MAJ_FLASH_LENG; +extern unsigned long FW_VER_MIN_FLASH_LENG; +extern unsigned long CFG_VER_MAJ_FLASH_LENG; +extern unsigned long CFG_VER_MIN_FLASH_LENG; +extern unsigned long CID_VER_MAJ_FLASH_LENG; +extern unsigned long CID_VER_MIN_FLASH_LENG; + +#ifdef HX_AUTO_UPDATE_FW +extern int g_i_FW_VER; +extern int g_i_CFG_VER; +extern int g_i_CID_MAJ; +extern int g_i_CID_MIN; +extern unsigned char *i_CTPM_FW; +#endif + +#ifdef HX_TP_PROC_2T2R + extern bool Is_2T2R; +#endif + +#ifdef HX_USB_DETECT_GLOBAL +extern void himax_cable_detect_func (bool force_renew); +#endif + + +static void hx83112_chip_init (void) +{ + + private_ts->chip_cell_type = CHIP_IS_IN_CELL; + I ("%s:IC cell type = %d\n", __func__, private_ts->chip_cell_type); + IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC; + /*Himax: Set FW and CFG Flash Address*/ + FW_VER_MAJ_FLASH_ADDR = 49157; /*0x00C005*/ + FW_VER_MAJ_FLASH_LENG = 1; + FW_VER_MIN_FLASH_ADDR = 49158; /*0x00C006*/ + FW_VER_MIN_FLASH_LENG = 1; + CFG_VER_MAJ_FLASH_ADDR = 49408; /*0x00C100*/ + CFG_VER_MAJ_FLASH_LENG = 1; + CFG_VER_MIN_FLASH_ADDR = 49409; /*0x00C101*/ + CFG_VER_MIN_FLASH_LENG = 1; + CID_VER_MAJ_FLASH_ADDR = 49154; /*0x00C002*/ + CID_VER_MAJ_FLASH_LENG = 1; + CID_VER_MIN_FLASH_ADDR = 49155; /*0x00C003*/ + CID_VER_MIN_FLASH_LENG = 1; +} + +static bool hx83112_sense_off(void) +{ + uint8_t cnt = 0; + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + + do { + /*=========================================== + I2C_password[7:0] set Enter safe mode : 0x31 ==> 0x27 + ===========================================*/ + tmp_data[0] = pic_op->data_i2c_psw_lb[0]; + + if (himax_bus_write(pic_op->adr_i2c_psw_lb[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return false; + } + + /*=========================================== + I2C_password[15:8] set Enter safe mode :0x32 ==> 0x95 + ===========================================*/ + tmp_data[0] = pic_op->data_i2c_psw_ub[0]; + + if (himax_bus_write(pic_op->adr_i2c_psw_ub[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return false; + } + + /*=========================================== + I2C_password[7:0] set Enter safe mode : 0x31 ==> 0x00 + ===========================================*/ + tmp_data[0] = 0x00; + + if (himax_bus_write(pic_op->adr_i2c_psw_lb[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return false; + } + + /*=========================================== + I2C_password[7:0] set Enter safe mode : 0x31 ==> 0x27 + ===========================================*/ + tmp_data[0] = pic_op->data_i2c_psw_lb[0]; + + if (himax_bus_write(pic_op->adr_i2c_psw_lb[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return false; + } + + /*=========================================== + I2C_password[15:8] set Enter safe mode :0x32 ==> 0x95 + ===========================================*/ + tmp_data[0] = pic_op->data_i2c_psw_ub[0]; + + if (himax_bus_write(pic_op->adr_i2c_psw_ub[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return false; + } + + /* ====================== + Check enter_save_mode + ======================*/ + g_core_fp.fp_register_read(pic_op->addr_cs_central_state, FOUR_BYTE_ADDR_SZ, tmp_data, 0); + I("%s: Check enter_save_mode data[0]=%X \n", __func__, tmp_data[0]); + + if (tmp_data[0] == 0x0C) { + /*===================================== + Reset TCON + =====================================*/ + g_core_fp.fp_flash_write_burst(pic_op->addr_tcon_on_rst, pic_op->data_rst); + msleep(1); + tmp_data[3] = pic_op->data_rst[3]; + tmp_data[2] = pic_op->data_rst[2]; + tmp_data[1] = pic_op->data_rst[1]; + tmp_data[0] = pic_op->data_rst[0] | 0x01; + g_core_fp.fp_flash_write_burst(pic_op->addr_tcon_on_rst, tmp_data); + /*===================================== + Reset ADC + =====================================*/ + g_core_fp.fp_flash_write_burst(pic_op->addr_adc_on_rst, pic_op->data_rst); + msleep(1); + tmp_data[3] = pic_op->data_rst[3]; + tmp_data[2] = pic_op->data_rst[2]; + tmp_data[1] = pic_op->data_rst[1]; + tmp_data[0] = pic_op->data_rst[0] | 0x01; + g_core_fp.fp_flash_write_burst(pic_op->addr_adc_on_rst, tmp_data); + return true; + } else { + msleep(10); +#ifdef HX_RST_PIN_FUNC + g_core_fp.fp_ic_reset(false, false); +#endif + } + } while (cnt++ < 15); + + return false; +} + +static void hx83112_func_re_init (void) +{ + g_core_fp.fp_sense_off = hx83112_sense_off; + g_core_fp.fp_chip_init = hx83112_chip_init; +} + +static void hx83112_reg_re_init (void) +{ +} + +bool hx83112_chip_detect (void) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + bool ret_data = false; + int i = 0; + himax_mcu_in_cmd_struct_init(); + himax_mcu_in_cmd_init(); + + hx83112_reg_re_init(); + hx83112_func_re_init(); + + g_core_fp.fp_sense_off(); + + for (i = 0; i < 5; i++) { + g_core_fp.fp_register_read (pfw_op->addr_icid_addr, FOUR_BYTE_DATA_SZ, tmp_data, false); + I("%s:Read driver IC ID = %X, %X, %X\n", __func__, tmp_data[3], tmp_data[2], tmp_data[1]); + + if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && ((tmp_data[1] == 0x2a) || (tmp_data[1] == 0x2b) || (tmp_data[1] == 0x2e))) { + if (tmp_data[1] == 0x2a) { + strlcpy (private_ts->chip_name, HX_83112A_SERIES_PWON, 30); + } else if (tmp_data[1] == 0x2b) { + strlcpy (private_ts->chip_name, HX_83112B_SERIES_PWON, 30); + } + + I("%s:IC name = %s\n", __func__, private_ts->chip_name); + + I("Himax IC package %x%x%x in\n", tmp_data[3], tmp_data[2], tmp_data[1]); + ret_data = true; + break; + } else { + ret_data = false; + E("%s:Read driver ID register Fail:\n", __func__); + E("Could NOT find Himax Chipset \n"); + E("Please check 1.VCCD,VCCA,VSP,VSN \n"); + E("2. LCM_RST,TP_RST \n"); + E("3. Power On Sequence \n"); + } + } + + return ret_data; +} + +#if 0 +#ifdef CONFIG_CHIP_DTCFG +static int himax_hx83112_probe(struct platform_device *pdev) +{ + I("%s:Enter\n", __func__); + g_core_fp.fp_chip_detect = hx83112_chip_detect; + + return 0; +} + +static int himax_hx83112_remove(struct platform_device *pdev) +{ + g_core_fp.fp_chip_detect = NULL; + g_core_fp.fp_chip_init = NULL; + return 0; +} + + +#ifdef CONFIG_OF +static const struct of_device_id himax_hx83112_mttable[] = { + { .compatible = "himax,hx83112"}, + { }, +}; +#else +#define himax_hx83112_mttabl NULL +#endif + +static struct platform_driver himax_hx83112_driver = { + .probe = himax_hx83112_probe, + .remove = himax_hx83112_remove, + .driver = { + .name = "HIMAX_HX83112", + .owner = THIS_MODULE, + .of_match_table = himax_hx83112_mttable, + }, +}; + +static int __init himax_hx83112_init(void) +{ + I("%s\n", __func__); + platform_driver_register(&himax_hx83112_driver); + return 0; +} + +static void __exit himax_hx83112_exit(void) +{ + platform_driver_unregister(&himax_hx83112_driver); +} + +#else +static int himax_hx83112_probe(void) +{ + I("%s:Enter\n", __func__); + + g_core_fp.fp_chip_detect = hx83112_chip_detect; + + return 0; +} + +static int himax_hx83112_remove(void) +{ + g_core_fp.fp_chip_detect = NULL; + g_core_fp.fp_chip_init = NULL; + return 0; +} + +static int __init himax_hx83112_init(void) +{ + int ret = 0; + + I("%s\n", __func__); + ret = himax_hx83112_probe(); + return 0; +} + +static void __exit himax_hx83112_exit(void) +{ + himax_hx83112_remove(); +} +#endif + +module_init(himax_hx83112_init); +module_exit(himax_hx83112_exit); + +MODULE_DESCRIPTION("HIMAX HX83112 touch driver"); +MODULE_LICENSE("GPL"); +#endif + diff --git a/drivers/input/touchscreen/himax_mmi/himax_ic_HX83112.h b/drivers/input/touchscreen/himax_mmi/himax_ic_HX83112.h new file mode 100644 index 000000000000..f861ad55a485 --- /dev/null +++ b/drivers/input/touchscreen/himax_mmi/himax_ic_HX83112.h @@ -0,0 +1,19 @@ +/* Himax Android Driver Sample Code for HX83112 chipset + + Copyright (C) 2018 Himax Corporation. + + This software is licensed under the terms of the GNU General Public + License version 2, as published by the Free Software Foundation, and + may be copied, distributed, and modified under those terms. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ + +#include "himax_platform.h" +#include "himax_common.h" +#include "himax_ic_core.h" +#include diff --git a/drivers/input/touchscreen/himax_mmi/himax_ic_core.h b/drivers/input/touchscreen/himax_mmi/himax_ic_core.h new file mode 100644 index 000000000000..83a18a754d98 --- /dev/null +++ b/drivers/input/touchscreen/himax_mmi/himax_ic_core.h @@ -0,0 +1,717 @@ +#include "himax_platform.h" +#include "himax_common.h" +#include + +#define EIGHT_BYTE_DATA_SZ 8 +#define FOUR_BYTE_DATA_SZ 4 +#define FOUR_BYTE_ADDR_SZ 4 +#define FLASH_RW_MAX_LEN 256 +#define FLASH_WRITE_BURST_SZ 8 +#define PROGRAM_SZ 48 +#define MAX_I2C_TRANS_SZ 128 +#define HIMAX_REG_RETRY_TIMES 5 +#define FW_BIN_16K_SZ 0x4000 +#define HIMAX_TOUCH_DATA_SIZE 128 +#define MASK_BIT_0 0x01 +#define MASK_BIT_1 0x02 +#define MASK_BIT_2 0x04 + +#define FW_SECTOR_PER_BLOCK 8 +#define FW_PAGE_PER_SECTOR 64 +#define FW_PAGE_SEZE 128 +#define HX256B 0x100 +#define HX4K 0x1000 +#define HX_32K_SZ 0x8000 +#define HX_40K_SZ 0xA000 +#define HX_48K_SZ 0xC000 +#define HX64K 0x10000 +#define HX124K 0x1f000 +#define HX4000K 0x1000000 + +#define HX_NORMAL_MODE 1 +#define HX_SORTING_MODE 2 +#define HX_CHANGE_MODE_FAIL (-1) +#define HX_RW_REG_FAIL (-1) + + +#define CORE_INIT +#define CORE_IC +#define CORE_FW +#define CORE_FLASH +#define CORE_SRAM +#define CORE_DRIVER + +#define HX_0F_DEBUG + +#ifdef HX_ESD_RECOVERY + extern u8 HX_ESD_RESET_ACTIVATE; +#endif + +#ifdef CORE_INIT + void himax_mcu_in_cmd_struct_init(void); + /*void himax_mcu_in_cmd_struct_free(void);*/ + void himax_in_parse_assign_cmd(uint32_t addr, uint8_t *cmd, int len); + void himax_mcu_in_cmd_init(void); + + void himax_mcu_on_cmd_struct_init(void); + /*static void himax_mcu_on_cmd_struct_free(void);*/ + void himax_on_parse_assign_cmd(uint32_t addr, uint8_t *cmd, int len); + void himax_mcu_on_cmd_init(void); +#endif + +#if defined(CORE_IC) + #define ic_adr_ahb_addr_byte_0 0x00 + #define ic_adr_ahb_rdata_byte_0 0x08 + #define ic_adr_ahb_access_direction 0x0c + #define ic_adr_conti 0x13 + #define ic_adr_incr4 0x0D + #define ic_adr_i2c_psw_lb 0x31 + #define ic_adr_i2c_psw_ub 0x32 + #define ic_cmd_ahb_access_direction_read 0x00 + #define ic_cmd_conti 0x31 + #define ic_cmd_incr4 0x10 + #define ic_cmd_i2c_psw_lb 0x27 + #define ic_cmd_i2c_psw_ub 0x95 + #define ic_adr_tcon_on_rst 0x80020020 + #define ic_addr_adc_on_rst 0x80020094 + #define ic_adr_psl 0x900000A0 + #define ic_adr_cs_central_state 0x900000A8 + #define ic_cmd_rst 0x00000000 + + #define on_ic_adr_ahb_addr_byte_0 0x00 + #define on_ic_adr_ahb_rdata_byte_0 0x08 + #define on_ic_adr_ahb_access_direction 0x0c + #define on_ic_adr_conti 0x13 + #define on_ic_adr_incr4 0x0D + #define on_ic_cmd_ahb_access_direction_read 0x00 + #define on_ic_cmd_conti 0x31 + #define on_ic_cmd_incr4 0x10 + #define on_ic_adr_mcu_ctrl 0x82 + #define on_ic_cmd_mcu_on 0x25 + #define on_ic_cmd_mcu_off 0xDA + #define on_ic_adr_sleep_ctrl 0x99 + #define on_ic_cmd_sleep_in 0x80 + #define on_ic_adr_tcon_ctrl 0x80020000 + #define on_ic_cmd_tcon_on 0x00000000 + #define on_ic_adr_wdg_ctrl 0x9000800C + #define on_ic_cmd_wdg_psw 0x0000AC53 + #define on_ic_adr_wdg_cnt_ctrl 0x90008010 + #define on_ic_cmd_wdg_cnt_clr 0x000035CA +#endif + +#if defined(CORE_FW) + #define fw_addr_system_reset 0x90000018 + #define fw_addr_safe_mode_release_pw 0x90000098 + #define fw_addr_ctrl_fw 0x9000005c + #define fw_addr_flag_reset_event 0x900000e4 + #define fw_addr_hsen_enable 0x10007F14 + #define fw_addr_smwp_enable 0x10007F10 + #define fw_usb_detect_addr 0x10007F38 + #define fw_addr_program_reload_from 0x00000000 + #define fw_addr_program_reload_to 0x08000000 + #define fw_addr_program_reload_page_write 0x0000fb00 + #define fw_addr_raw_out_sel 0x800204b4 + #define fw_addr_reload_status 0x80050000 + #define fw_addr_reload_crc32_result 0x80050018 + #define fw_addr_reload_addr_from 0x80050020 + #define fw_addr_reload_addr_cmd_beat 0x80050028 + #define fw_data_system_reset 0x00000055 + #define fw_data_safe_mode_release_pw_active 0x00000053 + #define fw_data_safe_mode_release_pw_reset 0x00000000 + #define fw_data_clear 0x00000000 + #define fw_data_program_reload_start 0x0A3C3000 + #define fw_data_program_reload_compare 0x04663000 + #define fw_data_program_reload_break 0x15E75678 + #define fw_addr_selftest_addr_en 0x10007F18 + #define fw_addr_selftest_result_addr 0x10007f24 + #define fw_data_selftest_request 0x00006AA6 + #define fw_addr_criteria_addr 0x10007f1c + #define fw_data_criteria_aa_top 0x64 + #define fw_data_criteria_aa_bot 0x00 + #define fw_data_criteria_key_top 0x64 + #define fw_data_criteria_key_bot 0x00 + #define fw_data_criteria_avg_top 0x64 + #define fw_data_criteria_avg_bot 0x00 + #define fw_addr_set_frame_addr 0x10007294 + #define fw_data_set_frame 0x0000000A + #define fw_data_selftest_ack_hb 0xa6 + #define fw_data_selftest_ack_lb 0x6a + #define fw_data_selftest_pass 0xaa + #define fw_data_normal_cmd 0x00 + #define fw_data_normal_status 0x99 + #define fw_data_sorting_cmd 0xaa + #define fw_data_sorting_status 0xcc + #define fw_data_idle_dis_pwd 0x17 + #define fw_data_idle_en_pwd 0x1f + #define fw_addr_sorting_mode_en 0x10007f04 + #define fw_addr_fw_mode_status 0x10007088 + #define fw_addr_icid_addr 0x900000d0 + #define fw_addr_trigger_addr 0x10007088 + #define fw_addr_fw_ver_addr 0x10007004 + #define fw_addr_fw_cfg_addr 0x10007084 + #define fw_addr_fw_vendor_addr 0x10007000 + #define fw_addr_fw_state_addr 0x900000f8 + #define fw_addr_fw_dbg_msg_addr 0x10007f44 + #define fw_addr_chk_fw_status 0x900000a8 + #define fw_addr_dd_handshak_addr 0x900000fc + #define fw_addr_dd_data_addr 0x10007f80 + #define fw_data_dd_request 0xaa + #define fw_data_dd_ack 0xbb + #define fw_data_rawdata_ready_hb 0xa3 + #define fw_data_rawdata_ready_lb 0x3a + #define fw_addr_ahb_addr 0x11 + #define fw_data_ahb_dis 0x00 + #define fw_data_ahb_en 0x01 + #define fw_addr_event_addr 0x30 + #define fw_func_handshaking_pwd 0xA55AA55A + #define fw_func_handshaking_end 0x77887788 + + #define on_fw_addr_smwp_enable 0xA2 + #define on_fw_usb_detect_addr 0xA4 + #define on_fw_addr_program_reload_from 0x00000000 + #define on_fw_addr_raw_out_sel 0x98 + #define on_fw_addr_flash_checksum 0x80000044 + #define on_fw_data_flash_checksum 0x00000491 + #define on_fw_addr_crc_value 0x80000050 + #define on_fw_data_safe_mode_release_pw_active 0x00000053 + #define on_fw_data_safe_mode_release_pw_reset 0x00000000 + #define on_fw_addr_criteria_addr 0x9A + #define on_fw_data_selftest_pass 0xaa + #define on_fw_addr_reK_crtl 0x8000000C + #define on_fw_data_reK_en 0x02 + #define on_fw_data_reK_dis 0xFD + #define on_fw_data_rst_init 0xF0 + #define on_fw_data_dc_set 0x02 + #define on_fw_data_bank_set 0x03 + #define on_fw_addr_selftest_addr_en 0x98 + #define on_fw_addr_selftest_result_addr 0x9B + #define on_fw_data_selftest_request 0x06 + #define on_fw_data_thx_avg_mul_dc_lsb 0x22 + #define on_fw_data_thx_avg_mul_dc_msb 0x0B + #define on_fw_data_thx_mul_dc_up_low_bud 0x64 + #define on_fw_data_thx_avg_slf_dc_lsb 0x14 + #define on_fw_data_thx_avg_slf_dc_msb 0x05 + #define on_fw_data_thx_slf_dc_up_low_bud 0x64 + #define on_fw_data_thx_slf_bank_up 0x40 + #define on_fw_data_thx_slf_bank_low 0x00 + #define on_fw_data_idle_dis_pwd 0x40 + #define on_fw_data_idle_en_pwd 0x00 + #define on_fw_addr_fw_mode_status 0x99 + #define on_fw_addr_icid_addr 0x900000d0 + #define on_fw_addr_trigger_addr 0x10007088 + #define on_fw_addr_fw_ver_start 0x90 + #define on_fw_data_rawdata_ready_hb 0xa3 + #define on_fw_data_rawdata_ready_lb 0x3a + #define on_fw_addr_ahb_addr 0x11 + #define on_fw_data_ahb_dis 0x00 + #define on_fw_data_ahb_en 0x01 + #define on_fw_addr_event_addr 0x30 +#endif + +#if defined(CORE_FLASH) + #define flash_addr_ctrl_base 0x80000000 + #define flash_addr_spi200_trans_fmt (flash_addr_ctrl_base + 0x10) + #define flash_addr_spi200_trans_ctrl (flash_addr_ctrl_base + 0x20) + #define flash_addr_spi200_cmd (flash_addr_ctrl_base + 0x24) + #define flash_addr_spi200_addr (flash_addr_ctrl_base + 0x28) + #define flash_addr_spi200_data (flash_addr_ctrl_base + 0x2c) + #define flash_addr_spi200_bt_num (flash_addr_ctrl_base + 0xe8) + #define flash_data_spi200_trans_fmt 0x00020780 + #define flash_data_spi200_trans_ctrl_1 0x42000003 + #define flash_data_spi200_trans_ctrl_2 0x47000000 + #define flash_data_spi200_trans_ctrl_3 0x67000000 + #define flash_data_spi200_trans_ctrl_4 0x610ff000 + #define flash_data_spi200_trans_ctrl_5 0x694002ff + #define flash_data_spi200_cmd_1 0x00000005 + #define flash_data_spi200_cmd_2 0x00000006 + #define flash_data_spi200_cmd_3 0x000000C7 + #define flash_data_spi200_cmd_4 0x000000D8 + #define flash_data_spi200_cmd_5 0x00000020 + #define flash_data_spi200_cmd_6 0x00000002 + #define flash_data_spi200_cmd_7 0x0000003b + #define flash_data_spi200_addr 0x00000000 + + #define on_flash_addr_ctrl_base 0x80000000 + #define on_flash_addr_ctrl_auto 0x80000004 + #define on_flash_data_main_erase 0x0000A50D + #define on_flash_data_auto 0xA5 + #define on_flash_data_main_read 0x03 + #define on_flash_data_page_write 0x05 + #define on_flash_data_spp_read 0x10 + #define on_flash_data_sfr_read 0x14 + #define on_flash_addr_ahb_ctrl 0x80000020 + #define on_flash_data_ahb_squit 0x00000001 + #define on_flash_addr_unlock_0 0x00000000 + #define on_flash_addr_unlock_4 0x00000004 + #define on_flash_addr_unlock_8 0x00000008 + #define on_flash_addr_unlock_c 0x0000000C + #define on_flash_data_cmd0 0x28178EA0 + #define on_flash_data_cmd1 0x0A0E03FF + #define on_flash_data_cmd2 0x8C203D0C + #define on_flash_data_cmd3 0x00300263 + #define on_flash_data_lock 0x03400000 +#endif + +#if defined(CORE_SRAM) + #define sram_adr_mkey 0x100070E8 + #define sram_adr_rawdata_addr 0x10000000 + #define sram_adr_rawdata_end 0x00000000 + #define sram_cmd_conti 0x44332211 + #define sram_cmd_fin 0x00000000 + #define sram_passwrd_start 0x5AA5 + #define sram_passwrd_end 0xA55A + + #define on_sram_adr_rawdata_addr 0x080002E0 + #define on_sram_adr_rawdata_end 0x00000000 + #define on_sram_cmd_conti 0x44332211 + #define on_sram_cmd_fin 0x00000000 + #define on_sram_passwrd_start 0x5AA5 + #define on_sram_passwrd_end 0xA55A +#endif + +#if defined(CORE_DRIVER) + #define driver_addr_fw_define_flash_reload 0x10007f00 + #define driver_addr_fw_define_2nd_flash_reload 0x100072c0 + #define driver_data_fw_define_flash_reload_dis 0x0000a55a + #define driver_data_fw_define_flash_reload_en 0x00000000 + #define driver_addr_fw_define_int_is_edge 0x10007089 + #define driver_addr_fw_define_rxnum_txnum_maxpt 0x100070f4 + #define driver_data_fw_define_rxnum_txnum_maxpt_sorting 0x00000008 + #define driver_data_fw_define_rxnum_txnum_maxpt_normal 0x00000014 + #define driver_addr_fw_define_xy_res_enable 0x100070fa + #define driver_addr_fw_define_x_y_res 0x100070fc + + #define on_driver_addr_fw_define_int_is_edge 0x10007089 + #define on_driver_addr_fw_rx_tx_maxpt_num 0x0800001C + #define on_driver_addr_fw_xy_rev_int_edge 0x0800000C + #define on_driver_addr_fw_define_x_y_res 0x08000030 +#endif + +#if defined(HX_ZERO_FLASH) + #define zf_addr_dis_flash_reload 0x10007f00 + #define zf_data_dis_flash_reload 0x00009AA9 + #define zf_addr_system_reset 0x90000018 + #define zf_data_system_reset 0x00000055 + #define zf_data_sram_start_addr 0x08000000 + #define zf_data_sram_clean 0x10000000 + #define zf_data_cfg_info 0x10007000 + #define zf_data_fw_cfg_1 0x10007084 + #define zf_data_fw_cfg_2 0x10007264 + #define zf_data_fw_cfg_3 0x10007300 + #define zf_data_adc_cfg_1 0x10006A00 + #define zf_data_adc_cfg_2 0x10007B28 + #define zf_data_adc_cfg_3 0x10007AF0 + #define zf_data_map_table 0x10007500 + #define zf_data_mode_switch 0x10007294 + #define zf_addr_sts_chk 0x900000A8 + #define zf_data_activ_sts 0x05 + #define zf_addr_activ_relod 0x90000048 + #define zf_data_activ_in 0xEC + +struct zf_info{ + uint8_t sram_addr[4]; + int write_size; + uint32_t fw_addr; +}; +#endif + +struct ic_operation { + uint8_t addr_ahb_addr_byte_0[1]; + uint8_t addr_ahb_rdata_byte_0[1]; + uint8_t addr_ahb_access_direction[1]; + uint8_t addr_conti[1]; + uint8_t addr_incr4[1]; + uint8_t adr_i2c_psw_lb[1]; + uint8_t adr_i2c_psw_ub[1]; + uint8_t data_ahb_access_direction_read[1]; + uint8_t data_conti[1]; + uint8_t data_incr4[1]; + uint8_t data_i2c_psw_lb[1]; + uint8_t data_i2c_psw_ub[1]; + uint8_t addr_tcon_on_rst[4]; + uint8_t addr_adc_on_rst[4]; + uint8_t addr_psl[4]; + uint8_t addr_cs_central_state[4]; + uint8_t data_rst[4]; +}; + +struct fw_operation { + uint8_t addr_system_reset[4]; + uint8_t addr_safe_mode_release_pw[4]; + uint8_t addr_ctrl_fw_isr[4]; + uint8_t addr_flag_reset_event[4]; + uint8_t addr_hsen_enable[4]; + uint8_t addr_smwp_enable[4]; + uint8_t addr_program_reload_from[4]; + uint8_t addr_program_reload_to[4]; + uint8_t addr_program_reload_page_write[4]; + uint8_t addr_raw_out_sel[4]; + uint8_t addr_reload_status[4]; + uint8_t addr_reload_crc32_result[4]; + uint8_t addr_reload_addr_from[4]; + uint8_t addr_reload_addr_cmd_beat[4]; + uint8_t addr_selftest_addr_en[4]; + uint8_t addr_criteria_addr[4]; + uint8_t addr_set_frame_addr[4]; + uint8_t addr_selftest_result_addr[4]; + uint8_t addr_sorting_mode_en[4]; + uint8_t addr_fw_mode_status[4]; + uint8_t addr_icid_addr[4]; + uint8_t addr_trigger_addr[4]; + uint8_t addr_fw_ver_addr[4]; + uint8_t addr_fw_cfg_addr[4]; + uint8_t addr_fw_vendor_addr[4]; + uint8_t addr_fw_state_addr[4]; + uint8_t addr_fw_dbg_msg_addr[4]; + uint8_t addr_chk_fw_status[4]; + uint8_t addr_dd_handshak_addr[4]; + uint8_t addr_dd_data_addr[4]; + uint8_t data_system_reset[4]; + uint8_t data_safe_mode_release_pw_active[4]; + uint8_t data_safe_mode_release_pw_reset[4]; + uint8_t data_clear[4]; + uint8_t data_program_reload_start[4]; + uint8_t data_program_reload_compare[4]; + uint8_t data_program_reload_break[4]; + uint8_t data_selftest_request[4]; + uint8_t data_criteria_aa_top[1]; + uint8_t data_criteria_aa_bot[1]; + uint8_t data_criteria_key_top[1]; + uint8_t data_criteria_key_bot[1]; + uint8_t data_criteria_avg_top[1]; + uint8_t data_criteria_avg_bot[1]; + uint8_t data_set_frame[4]; + uint8_t data_selftest_ack_hb[1]; + uint8_t data_selftest_ack_lb[1]; + uint8_t data_selftest_pass[1]; + uint8_t data_normal_cmd[1]; + uint8_t data_normal_status[1]; + uint8_t data_sorting_cmd[1]; + uint8_t data_sorting_status[1]; + uint8_t data_dd_request[1]; + uint8_t data_dd_ack[1]; + uint8_t data_idle_dis_pwd[1]; + uint8_t data_idle_en_pwd[1]; + uint8_t data_rawdata_ready_hb[1]; + uint8_t data_rawdata_ready_lb[1]; + uint8_t addr_ahb_addr[1]; + uint8_t data_ahb_dis[1]; + uint8_t data_ahb_en[1]; + uint8_t addr_event_addr[1]; + uint8_t addr_usb_detect[4]; +}; + +struct flash_operation { + uint8_t addr_spi200_trans_fmt[4]; + uint8_t addr_spi200_trans_ctrl[4]; + uint8_t addr_spi200_cmd[4]; + uint8_t addr_spi200_addr[4]; + uint8_t addr_spi200_data[4]; + uint8_t addr_spi200_bt_num[4]; + + uint8_t data_spi200_trans_fmt[4]; + uint8_t data_spi200_trans_ctrl_1[4]; + uint8_t data_spi200_trans_ctrl_2[4]; + uint8_t data_spi200_trans_ctrl_3[4]; + uint8_t data_spi200_trans_ctrl_4[4]; + uint8_t data_spi200_trans_ctrl_5[4]; + uint8_t data_spi200_cmd_1[4]; + uint8_t data_spi200_cmd_2[4]; + uint8_t data_spi200_cmd_3[4]; + uint8_t data_spi200_cmd_4[4]; + uint8_t data_spi200_cmd_5[4]; + uint8_t data_spi200_cmd_6[4]; + uint8_t data_spi200_cmd_7[4]; + uint8_t data_spi200_addr[4]; +}; + +struct sram_operation { + uint8_t addr_mkey[4]; + uint8_t addr_rawdata_addr[4]; + uint8_t addr_rawdata_end[4]; + uint8_t data_conti[4]; + uint8_t data_fin[4]; + uint8_t passwrd_start[2]; + uint8_t passwrd_end[2]; +}; + +struct driver_operation { + uint8_t addr_fw_define_flash_reload[4]; + uint8_t addr_fw_define_2nd_flash_reload[4]; + uint8_t addr_fw_define_int_is_edge[4]; + uint8_t addr_fw_define_rxnum_txnum_maxpt[4]; + uint8_t addr_fw_define_xy_res_enable[4]; + uint8_t addr_fw_define_x_y_res[4]; + uint8_t data_fw_define_flash_reload_dis[4]; + uint8_t data_fw_define_flash_reload_en[4]; + uint8_t data_fw_define_rxnum_txnum_maxpt_sorting[4]; + uint8_t data_fw_define_rxnum_txnum_maxpt_normal[4]; +}; + +struct zf_operation { + uint8_t addr_dis_flash_reload[4]; + uint8_t data_dis_flash_reload[4]; + uint8_t addr_system_reset[4]; + uint8_t data_system_reset[4]; + uint8_t data_sram_start_addr[4]; + uint8_t data_sram_clean[4]; + uint8_t data_cfg_info[4]; + uint8_t data_fw_cfg_1[4]; + uint8_t data_fw_cfg_2[4]; + uint8_t data_fw_cfg_3[4]; + uint8_t data_adc_cfg_1[4]; + uint8_t data_adc_cfg_2[4]; + uint8_t data_adc_cfg_3[4]; + uint8_t data_map_table[4]; + uint8_t data_mode_switch[4]; + uint8_t addr_sts_chk[4]; + uint8_t data_activ_sts[1]; + uint8_t addr_activ_relod[4]; + uint8_t data_activ_in[1]; +}; + +struct himax_core_command_operation { + struct ic_operation *ic_op; + struct fw_operation *fw_op; + struct flash_operation *flash_op; + struct sram_operation *sram_op; + struct driver_operation *driver_op; + struct zf_operation *zf_op; +}; + +struct on_ic_operation { + uint8_t addr_ahb_addr_byte_0[1]; + uint8_t addr_ahb_rdata_byte_0[1]; + uint8_t addr_ahb_access_direction[1]; + uint8_t addr_conti[1]; + uint8_t addr_incr4[1]; + uint8_t adr_mcu_ctrl[1]; + uint8_t data_ahb_access_direction_read[1]; + uint8_t data_conti[1]; + uint8_t data_incr4[1]; + uint8_t cmd_mcu_on[1]; + uint8_t cmd_mcu_off[1]; + uint8_t adr_sleep_ctrl[1]; + uint8_t cmd_sleep_in[1]; + uint8_t adr_tcon_ctrl[4]; + uint8_t cmd_tcon_on[4]; + uint8_t adr_wdg_ctrl[4]; + uint8_t cmd_wdg_psw[4]; + uint8_t adr_wdg_cnt_ctrl[4]; + uint8_t cmd_wdg_cnt_clr[4]; +}; + +struct on_fw_operation { + uint8_t addr_smwp_enable[1]; + uint8_t addr_program_reload_from[4]; + uint8_t addr_raw_out_sel[1]; + uint8_t addr_flash_checksum[4]; + uint8_t data_flash_checksum[4]; + uint8_t addr_crc_value[4]; + uint8_t addr_reload_status[4]; + uint8_t addr_reload_crc32_result[4]; + uint8_t addr_reload_addr_from[4]; + uint8_t addr_reload_addr_cmd_beat[4]; + uint8_t addr_set_frame_addr[4]; + uint8_t addr_fw_mode_status[1]; + uint8_t addr_icid_addr[4]; + uint8_t addr_trigger_addr[4]; + uint8_t addr_fw_ver_start[1]; + uint8_t data_safe_mode_release_pw_active[4]; + uint8_t data_safe_mode_release_pw_reset[4]; + uint8_t data_clear[4]; + uint8_t addr_criteria_addr[1]; + uint8_t data_selftest_pass[1]; + uint8_t addr_reK_crtl[4]; + uint8_t data_reK_en[1]; + uint8_t data_reK_dis[1]; + uint8_t data_rst_init[1]; + uint8_t data_dc_set[1]; + uint8_t data_bank_set[1]; + uint8_t addr_selftest_addr_en[1]; + uint8_t addr_selftest_result_addr[1]; + uint8_t data_selftest_request[1]; + uint8_t data_thx_avg_mul_dc_lsb[1]; + uint8_t data_thx_avg_mul_dc_msb[1]; + uint8_t data_thx_mul_dc_up_low_bud[1]; + uint8_t data_thx_avg_slf_dc_lsb[1]; + uint8_t data_thx_avg_slf_dc_msb[1]; + uint8_t data_thx_slf_dc_up_low_bud[1]; + uint8_t data_thx_slf_bank_up[1]; + uint8_t data_thx_slf_bank_low[1]; + uint8_t data_idle_dis_pwd[1]; + uint8_t data_idle_en_pwd[1]; + uint8_t data_rawdata_ready_hb[1]; + uint8_t data_rawdata_ready_lb[1]; + uint8_t addr_ahb_addr[1]; + uint8_t data_ahb_dis[1]; + uint8_t data_ahb_en[1]; + uint8_t addr_event_addr[1]; + uint8_t addr_usb_detect[1]; +}; + +struct on_flash_operation { + uint8_t addr_ctrl_base[4]; + uint8_t addr_ctrl_auto[4]; + uint8_t data_main_erase[4]; + uint8_t data_auto[1]; + uint8_t data_main_read[1]; + uint8_t data_page_write[1]; + uint8_t data_sfr_read[1]; + uint8_t data_spp_read[1]; + uint8_t addr_ahb_ctrl[4]; + uint8_t data_ahb_squit[4]; + + uint8_t addr_unlock_0[4]; + uint8_t addr_unlock_4[4]; + uint8_t addr_unlock_8[4]; + uint8_t addr_unlock_c[4]; + uint8_t data_cmd0[4]; + uint8_t data_cmd1[4]; + uint8_t data_cmd2[4]; + uint8_t data_cmd3[4]; + uint8_t data_lock[4]; +}; + +struct on_sram_operation { + uint8_t addr_rawdata_addr[4]; + uint8_t addr_rawdata_end[4]; + uint8_t data_conti[4]; + uint8_t data_fin[4]; + uint8_t passwrd_start[2]; + uint8_t passwrd_end[2]; +}; + +struct on_driver_operation { + uint8_t addr_fw_define_int_is_edge[4]; + uint8_t addr_fw_rx_tx_maxpt_num[4]; + uint8_t addr_fw_xy_rev_int_edge[4]; + uint8_t addr_fw_define_x_y_res[4]; + uint8_t data_fw_define_rxnum_txnum_maxpt_sorting[4]; + uint8_t data_fw_define_rxnum_txnum_maxpt_normal[4]; +}; + +struct himax_on_core_command_operation { + struct on_ic_operation *ic_op; + struct on_fw_operation *fw_op; + struct on_flash_operation *flash_op; + struct on_sram_operation *sram_op; + struct on_driver_operation *driver_op; +}; + +struct himax_core_fp { +#ifdef CORE_IC + void (*fp_burst_enable)(uint8_t auto_add_4_byte); + int (*fp_register_read)(uint8_t *read_addr, uint32_t read_length, uint8_t *read_data, uint8_t cfg_flag); + int (*fp_flash_write_burst)(uint8_t *reg_byte, uint8_t *write_data); + void (*fp_flash_write_burst_lenth)(uint8_t *reg_byte, uint8_t *write_data, uint32_t length); + void (*fp_register_write)(uint8_t *write_addr, uint32_t write_length, uint8_t *write_data, uint8_t cfg_flag); + void (*fp_interface_on)(void); + void (*fp_sense_on)(uint8_t FlashMode); + void (*fp_tcon_on)(void); + bool (*fp_watch_dog_off)(void); + bool (*fp_sense_off)(void); + void (*fp_sleep_in)(void); + bool (*fp_wait_wip)(int Timing); + void (*fp_init_psl)(void); + void (*fp_resume_ic_action)(void); + void (*fp_suspend_ic_action)(void); + void (*fp_power_on_init)(void); +#endif + +#ifdef CORE_FW + void (*fp_parse_raw_data)(struct himax_report_data *hx_touch_data, int mul_num, int self_num, uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data); + void (*fp_system_reset)(void); + bool (*fp_Calculate_CRC_with_AP)(unsigned char *FW_content, int CRC_from_FW, int mode); + uint32_t (*fp_check_CRC)(uint8_t *start_addr, int reload_length); + void (*fp_set_reload_cmd)(uint8_t *write_data, int idx, uint32_t cmd_from, uint32_t cmd_to, uint32_t cmd_beat); + bool (*fp_program_reload)(void); + void (*fp_set_SMWP_enable)(uint8_t SMWP_enable, bool suspended); + void (*fp_set_HSEN_enable)(uint8_t HSEN_enable, bool suspended); + void (*fp_diag_register_set)(uint8_t diag_command, uint8_t storage_type); +#ifdef HX_TP_SELF_TEST_DRIVER + void (*fp_control_reK)(bool enable); +#endif + int (*fp_chip_self_test)(void); + void (*fp_idle_mode)(int disable); + void (*fp_reload_disable)(int disable); + bool (*fp_check_chip_version)(void); + int (*fp_read_ic_trigger_type)(void); + int (*fp_read_i2c_status)(void); + void (*fp_read_FW_ver)(void); + bool (*fp_read_event_stack)(uint8_t *buf, uint8_t length); + void (*fp_return_event_stack)(void); + bool (*fp_calculateChecksum)(bool change_iref); + int (*fp_read_FW_status)(uint8_t *state_addr, uint8_t *tmp_addr); + void (*fp_irq_switch)(int switch_on); + int (*fp_assign_sorting_mode)(uint8_t *tmp_data); + int (*fp_check_sorting_mode)(uint8_t *tmp_data); + int (*fp_switch_mode)(int mode); + uint8_t (*fp_read_DD_status)(uint8_t *cmd_set, uint8_t *tmp_data); +#endif + +#ifdef CORE_FLASH + void (*fp_chip_erase)(void); + bool (*fp_block_erase)(int start_addr, int length); + bool (*fp_sector_erase)(int start_addr); + void (*fp_flash_programming)(uint8_t *FW_content, int FW_Size); + void (*fp_flash_page_write)(uint8_t *write_addr, int length, uint8_t *write_data); + int (*fp_fts_ctpm_fw_upgrade_with_sys_fs_32k)(unsigned char *fw, int len, bool change_iref); + int (*fp_fts_ctpm_fw_upgrade_with_sys_fs_60k)(unsigned char *fw, int len, bool change_iref); + int (*fp_fts_ctpm_fw_upgrade_with_sys_fs_64k)(unsigned char *fw, int len, bool change_iref); + int (*fp_fts_ctpm_fw_upgrade_with_sys_fs_124k)(unsigned char *fw, int len, bool change_iref); + int (*fp_fts_ctpm_fw_upgrade_with_sys_fs_128k)(unsigned char *fw, int len, bool change_iref); + void (*fp_flash_dump_func)(uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer); + bool (*fp_flash_lastdata_check)(void); + bool (*fp_ahb_squit)(void); + void (*fp_flash_read)(uint8_t *r_data, int start_addr, int length); + bool (*fp_sfr_rw)(uint8_t *addr, int length, uint8_t *data, uint8_t rw_ctrl); + bool (*fp_lock_flash)(void); + bool (*fp_unlock_flash)(void); + void (*fp_init_auto_func)(void); +#endif + +#ifdef CORE_SRAM + void (*fp_sram_write)(uint8_t *FW_content); + bool (*fp_sram_verify)(uint8_t *FW_File, int FW_Size); + bool (*fp_get_DSRAM_data)(uint8_t *info_data, bool DSRAM_Flag); +#endif + +#ifdef CORE_DRIVER + bool (*fp_chip_detect)(void); + void (*fp_chip_init)(void); +#ifdef HX_AUTO_UPDATE_FW + int (*fp_fw_ver_bin)(void); +#endif + void (*fp_pin_reset)(void); + void (*fp_touch_information)(void); + void (*fp_reload_config)(void); + int (*fp_get_touch_data_size)(void); + void (*fp_usb_detect_set)(uint8_t *cable_config); + int (*fp_hand_shaking)(void); + int (*fp_determin_diag_rawdata)(int diag_command); + int (*fp_determin_diag_storage)(int diag_command); + int (*fp_cal_data_len)(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max); + bool (*fp_diag_check_sum)(struct himax_report_data *hx_touch_data); + void (*fp_diag_parse_raw_data)(struct himax_report_data *hx_touch_data, int mul_num, int self_num, uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data); + void (*fp_ic_reset)(uint8_t loadconfig, uint8_t int_off); + int (*fp_ic_esd_recovery)(int hx_esd_event, int hx_zero_event, int length); + void (*fp_esd_ic_reset)(void); + void (*fp_resend_cmd_func)(bool suspended); +#endif +#ifdef HX_ZERO_FLASH + void (*fp_clean_sram_0f)(uint8_t *addr, int write_len, int type); + void (*fp_write_sram_0f)(const struct firmware *fw_entry, uint8_t *addr, int start_index, uint32_t write_len); + void (*fp_firmware_update_0f)(const struct firmware *fw_entry); + int (*fp_0f_operation_dirly)(void); + int (*fp_0f_op_file_dirly)(char *file_name); + void (*fp_0f_operation)(struct work_struct *work); + int (*fp_0f_esd_check)(void); +#ifdef HX_0F_DEBUG + void (*fp_read_sram_0f)(const struct firmware *fw_entry, uint8_t *addr, int start_index, int read_len); + void (*fp_read_all_sram)(uint8_t *addr, int read_len); + void (*fp_firmware_read_0f)(const struct firmware *fw_entry, int type); + void (*fp_0f_operation_check)(int type); +#endif +#endif +}; diff --git a/drivers/input/touchscreen/himax_mmi/himax_ic_incell_core.c b/drivers/input/touchscreen/himax_mmi/himax_ic_incell_core.c new file mode 100644 index 000000000000..e4d08641b659 --- /dev/null +++ b/drivers/input/touchscreen/himax_mmi/himax_ic_incell_core.c @@ -0,0 +1,2775 @@ + +#include "himax_ic_core.h" + +#if defined(HX_AUTO_UPDATE_FW) || defined(HX_ZERO_FLASH) + extern char *i_CTPM_firmware_name; +#endif +#ifdef HX_AUTO_UPDATE_FW + extern int g_i_FW_VER; + extern int g_i_CFG_VER; + extern int g_i_CID_MAJ; + extern int g_i_CID_MIN; + extern unsigned char *i_CTPM_FW; +#endif +#ifdef HX_ZERO_FLASH +extern int g_f_0f_updat; +#endif + +extern unsigned long FW_VER_MAJ_FLASH_ADDR; +extern unsigned long FW_VER_MIN_FLASH_ADDR; +extern unsigned long CFG_VER_MAJ_FLASH_ADDR; +extern unsigned long CFG_VER_MIN_FLASH_ADDR; +extern unsigned long CID_VER_MAJ_FLASH_ADDR; +extern unsigned long CID_VER_MIN_FLASH_ADDR; + +extern unsigned long FW_VER_MAJ_FLASH_LENG; +extern unsigned long FW_VER_MIN_FLASH_LENG; +extern unsigned long CFG_VER_MAJ_FLASH_LENG; +extern unsigned long CFG_VER_MIN_FLASH_LENG; +extern unsigned long CID_VER_MAJ_FLASH_LENG; +extern unsigned long CID_VER_MIN_FLASH_LENG; + +extern struct himax_ic_data *ic_data; +extern struct himax_ts_data *private_ts; +extern unsigned char IC_CHECKSUM; + +#ifdef HX_ESD_RECOVERY +extern int g_zero_event_count; +#endif + +#ifdef HX_RST_PIN_FUNC + extern u8 HX_HW_RESET_ACTIVATE; + extern void himax_rst_gpio_set(int pinnum, uint8_t value); +#endif + +#if defined(HX_USB_DETECT_GLOBAL) +extern void himax_cable_detect_func(bool force_renew); +#endif + +extern int himax_report_data_init(void); +extern int i2c_error_count; + +struct himax_core_command_operation *g_core_cmd_op = NULL; +struct ic_operation *pic_op = NULL; +struct fw_operation *pfw_op = NULL; +struct flash_operation *pflash_op = NULL; +struct sram_operation *psram_op = NULL; +struct driver_operation *pdriver_op = NULL; +#ifdef HX_ZERO_FLASH +struct zf_operation *pzf_op = NULL; +#endif + +extern struct himax_core_fp g_core_fp; + +#ifdef CORE_IC +/* IC side start*/ +static void himax_mcu_burst_enable(uint8_t auto_add_4_byte) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + /*I("%s,Entering \n",__func__);*/ + tmp_data[0] = pic_op->data_conti[0]; + + if (himax_bus_write(pic_op->addr_conti[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return; + } + + tmp_data[0] = (pic_op->data_incr4[0] | auto_add_4_byte); + + if (himax_bus_write(pic_op->addr_incr4[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return; + } +} + +static int himax_mcu_register_read(uint8_t *read_addr, uint32_t read_length, uint8_t *read_data, uint8_t cfg_flag) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + int i = 0; + int address = 0; + + /*I("%s,Entering \n",__func__);*/ + + if (cfg_flag == false) { + if (read_length > FLASH_RW_MAX_LEN) { + E("%s: read len over %d!\n", __func__, FLASH_RW_MAX_LEN); + return LENGTH_FAIL; + } + + if (read_length > FOUR_BYTE_DATA_SZ) { + g_core_fp.fp_burst_enable(1); + } else { + g_core_fp.fp_burst_enable(0); + } + + address = (read_addr[3] << 24) + (read_addr[2] << 16) + (read_addr[1] << 8) + read_addr[0]; + i = address; + tmp_data[0] = (uint8_t)i; + tmp_data[1] = (uint8_t)(i >> 8); + tmp_data[2] = (uint8_t)(i >> 16); + tmp_data[3] = (uint8_t)(i >> 24); + + if (himax_bus_write(pic_op->addr_ahb_addr_byte_0[0], tmp_data, FOUR_BYTE_DATA_SZ, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return I2C_FAIL; + } + + tmp_data[0] = pic_op->data_ahb_access_direction_read[0]; + + if (himax_bus_write(pic_op->addr_ahb_access_direction[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return I2C_FAIL; + } + + if (himax_bus_read(pic_op->addr_ahb_rdata_byte_0[0], read_data, read_length, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return I2C_FAIL; + } + + if (read_length > FOUR_BYTE_DATA_SZ) { + g_core_fp.fp_burst_enable(0); + } + } else { + if (himax_bus_read(read_addr[0], read_data, read_length, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return I2C_FAIL; + } + } + return NO_ERR; +} + +static int himax_mcu_flash_write_burst(uint8_t *reg_byte, uint8_t *write_data) +{ + uint8_t data_byte[FLASH_WRITE_BURST_SZ]; + int i = 0, j = 0; + int data_byte_sz = sizeof(data_byte); + + for (i = 0; i < FOUR_BYTE_ADDR_SZ; i++) { + data_byte[i] = reg_byte[i]; + } + + for (j = FOUR_BYTE_ADDR_SZ; j < data_byte_sz; j++) { + data_byte[j] = write_data[j - FOUR_BYTE_ADDR_SZ]; + } + + if (himax_bus_write(pic_op->addr_ahb_addr_byte_0[0], data_byte, data_byte_sz, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return I2C_FAIL; + } + return NO_ERR; +} + +static void himax_mcu_flash_write_burst_lenth(uint8_t *reg_byte, uint8_t *write_data, uint32_t length) +{ + uint8_t *data_byte; + int i = 0, j = 0; + + /* if (length + FOUR_BYTE_ADDR_SZ > FLASH_RW_MAX_LEN) { + E("%s: write len over %d!\n", __func__, FLASH_RW_MAX_LEN); + return; + } */ + + data_byte = kzalloc(sizeof(uint8_t)*(length + 4), GFP_KERNEL); + + for (i = 0; i < FOUR_BYTE_ADDR_SZ; i++) { + data_byte[i] = reg_byte[i]; + } + + for (j = FOUR_BYTE_ADDR_SZ; j < length + FOUR_BYTE_ADDR_SZ; j++) { + data_byte[j] = write_data[j - FOUR_BYTE_ADDR_SZ]; + } + + if (himax_bus_write(pic_op->addr_ahb_addr_byte_0[0], data_byte, length + FOUR_BYTE_ADDR_SZ, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + kfree(data_byte); + return; + } + kfree(data_byte); +} + +static void himax_mcu_register_write(uint8_t *write_addr, uint32_t write_length, uint8_t *write_data, uint8_t cfg_flag) +{ + int i, address; + + /*I("%s,Entering \n", __func__);*/ + if (cfg_flag == false) { + address = (write_addr[3] << 24) + (write_addr[2] << 16) + (write_addr[1] << 8) + write_addr[0]; + + for (i = address; i < address + write_length; i++) { + if (write_length > FOUR_BYTE_DATA_SZ) { + g_core_fp.fp_burst_enable(1); + } else { + g_core_fp.fp_burst_enable(0); + } + + g_core_fp.fp_flash_write_burst_lenth(write_addr, write_data, write_length); + } + } else if (cfg_flag == true) { + if (himax_bus_write(write_addr[0], write_data, write_length, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return; + } + } else { + E("%s: cfg_flag = %d, value is wrong!\n", __func__, cfg_flag); + return; + } +} + +static int himax_write_read_reg(uint8_t *tmp_addr, uint8_t *tmp_data, uint8_t hb, uint8_t lb) +{ + int cnt = 0; + + do { + g_core_fp.fp_flash_write_burst(tmp_addr, tmp_data); + msleep(10); + g_core_fp.fp_register_read(tmp_addr, 4, tmp_data, 0); + /* I("%s:Now tmp_data[0]=0x%02X,[1]=0x%02X,[2]=0x%02X,[3]=0x%02X\n", + __func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]);*/ + } while ((tmp_data[1] != hb && tmp_data[0] != lb) && cnt++ < 100); + + if (cnt == 99) { + return HX_RW_REG_FAIL; + } + + I("Now register 0x%08X : high byte=0x%02X,low byte=0x%02X\n", tmp_addr[3], tmp_data[1], tmp_data[0]); + return NO_ERR; +} + +static void himax_mcu_interface_on(void) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t tmp_data2[FOUR_BYTE_DATA_SZ]; + int cnt = 0; + + /* Read a dummy register to wake up I2C.*/ + if (himax_bus_read(pic_op->addr_ahb_rdata_byte_0[0], tmp_data, FOUR_BYTE_DATA_SZ, HIMAX_I2C_RETRY_TIMES) < 0) {/* to knock I2C*/ + E("%s: i2c access fail!\n", __func__); + return; + } + + do { + tmp_data[0] = pic_op->data_conti[0]; + + if (himax_bus_write(pic_op->addr_conti[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return; + } + + tmp_data[0] = pic_op->data_incr4[0]; + + if (himax_bus_write(pic_op->addr_incr4[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return; + } + + /*Check cmd*/ + himax_bus_read(pic_op->addr_conti[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES); + himax_bus_read(pic_op->addr_incr4[0], tmp_data2, 1, HIMAX_I2C_RETRY_TIMES); + + if (tmp_data[0] == pic_op->data_conti[0] && tmp_data2[0] == pic_op->data_incr4[0]) { + break; + } + + msleep(1); + } while (++cnt < 10); + + if (cnt > 0) { + I("%s:Polling burst mode: %d times\n", __func__, cnt); + } +} + +static bool himax_mcu_wait_wip(int Timing) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + int retry_cnt = 0; + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_fmt, pflash_op->data_spi200_trans_fmt); + tmp_data[0] = 0x01; + + do { + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_ctrl, pflash_op->data_spi200_trans_ctrl_1); + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_cmd, pflash_op->data_spi200_cmd_1); + tmp_data[0] = tmp_data[1] = tmp_data[2] = tmp_data[3] = 0xFF; + g_core_fp.fp_register_read(pflash_op->addr_spi200_data, 4, tmp_data, 0); + + if ((tmp_data[0] & 0x01) == 0x00) { + return true; + } + + retry_cnt++; + + if (tmp_data[0] != 0x00 || tmp_data[1] != 0x00 || tmp_data[2] != 0x00 || tmp_data[3] != 0x00) + I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, buffer[1]=%d, buffer[2]=%d, buffer[3]=%d \n", + __func__, retry_cnt, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]); + + if (retry_cnt > 100) { + E("%s: Wait wip error!\n", __func__); + return false; + } + + msleep(Timing); + } while ((tmp_data[0] & 0x01) == 0x01); + + return true; +} + +static void himax_mcu_sense_on(uint8_t FlashMode) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + int retry = 0; + I("Enter %s \n", __func__); + g_core_fp.fp_interface_on(); + g_core_fp.fp_register_write(pfw_op->addr_ctrl_fw_isr, + sizeof(pfw_op->data_clear), pfw_op->data_clear, false); + msleep(20); + + if (!FlashMode) { +#ifdef HX_RST_PIN_FUNC + g_core_fp.fp_ic_reset(false, false); +#else + g_core_fp.fp_system_reset(); +#endif + } else { + do { + g_core_fp.fp_register_write(pfw_op->addr_safe_mode_release_pw, + sizeof(pfw_op->data_safe_mode_release_pw_active), pfw_op->data_safe_mode_release_pw_active, false); + + g_core_fp.fp_register_read(pfw_op->addr_flag_reset_event, FOUR_BYTE_DATA_SZ, tmp_data, 0); + I("%s:Read status from IC = %X,%X\n", __func__, tmp_data[0], tmp_data[1]); + } while ((tmp_data[1] != 0x01 || tmp_data[0] != 0x00) && retry++ < 5); + + if (retry >= 5) { + E("%s: Fail:\n", __func__); +#ifdef HX_RST_PIN_FUNC + g_core_fp.fp_ic_reset(false, false); +#else + g_core_fp.fp_system_reset(); +#endif + } else { + I("%s:OK and Read status from IC = %X,%X\n", __func__, tmp_data[0], tmp_data[1]); + /* reset code*/ + tmp_data[0] = 0x00; + + if (himax_bus_write(pic_op->adr_i2c_psw_lb[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + } + + if (himax_bus_write(pic_op->adr_i2c_psw_ub[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + } + + g_core_fp.fp_register_write(pfw_op->addr_safe_mode_release_pw, + sizeof(pfw_op->data_safe_mode_release_pw_reset), pfw_op->data_safe_mode_release_pw_reset, false); + } + } +} + +static bool himax_mcu_sense_off(void) +{ + uint8_t cnt = 0; + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + + do { + tmp_data[0] = pic_op->data_i2c_psw_lb[0]; + + if (himax_bus_write(pic_op->adr_i2c_psw_lb[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return false; + } + + tmp_data[0] = pic_op->data_i2c_psw_ub[0]; + + if (himax_bus_write(pic_op->adr_i2c_psw_ub[0], tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return false; + } + + g_core_fp.fp_register_read(pic_op->addr_cs_central_state, FOUR_BYTE_ADDR_SZ, tmp_data, 0); + I("%s: Check enter_save_mode data[0]=%X \n", __func__, tmp_data[0]); + + if (tmp_data[0] == 0x0C) { + g_core_fp.fp_flash_write_burst(pic_op->addr_tcon_on_rst, pic_op->data_rst); + msleep(1); + tmp_data[3] = pic_op->data_rst[3]; + tmp_data[2] = pic_op->data_rst[2]; + tmp_data[1] = pic_op->data_rst[1]; + tmp_data[0] = pic_op->data_rst[0] | 0x01; + g_core_fp.fp_flash_write_burst(pic_op->addr_tcon_on_rst, tmp_data); + + g_core_fp.fp_flash_write_burst(pic_op->addr_adc_on_rst, pic_op->data_rst); + msleep(1); + tmp_data[3] = pic_op->data_rst[3]; + tmp_data[2] = pic_op->data_rst[2]; + tmp_data[1] = pic_op->data_rst[1]; + tmp_data[0] = pic_op->data_rst[0] | 0x01; + g_core_fp.fp_flash_write_burst(pic_op->addr_adc_on_rst, tmp_data); + return true; + } else { + msleep(10); +#ifdef HX_RST_PIN_FUNC + g_core_fp.fp_ic_reset(false, false); +#endif + } + } while (cnt++ < 15); + + return false; +} + +static void himax_mcu_init_psl(void) /*power saving level*/ +{ + g_core_fp.fp_register_write(pic_op->addr_psl, sizeof(pic_op->data_rst), pic_op->data_rst, false); + I("%s: power saving level reset OK!\n", __func__); +} + +static void himax_mcu_resume_ic_action(void) +{ + /* Nothing to do */ +} + +static void himax_mcu_suspend_ic_action(void) +{ + /* Nothing to do */ +} + +static void himax_mcu_power_on_init(void) +{ + I("%s:\n", __func__); + g_core_fp.fp_touch_information(); + /*RawOut select initial*/ + g_core_fp.fp_register_write(pfw_op->addr_raw_out_sel, sizeof(pfw_op->data_clear), pfw_op->data_clear, false); + /*DSRAM func initial*/ + g_core_fp.fp_assign_sorting_mode(pfw_op->data_clear); + g_core_fp.fp_sense_on(0x00); +} + +/* IC side end*/ +#endif + +#ifdef CORE_FW +/* FW side start*/ +static void diag_mcu_parse_raw_data(struct himax_report_data *hx_touch_data, int mul_num, int self_num, uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data) +{ + int RawDataLen_word; + int index = 0; + int temp1, temp2, i; + + if (hx_touch_data->hx_rawdata_buf[0] == pfw_op->data_rawdata_ready_lb[0] + && hx_touch_data->hx_rawdata_buf[1] == pfw_op->data_rawdata_ready_hb[0] + && hx_touch_data->hx_rawdata_buf[2] > 0 + && hx_touch_data->hx_rawdata_buf[3] == diag_cmd) { + RawDataLen_word = hx_touch_data->rawdata_size / 2; + index = (hx_touch_data->hx_rawdata_buf[2] - 1) * RawDataLen_word; + + /* I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n", index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num); + I("RawDataLen=%d , RawDataLen_word=%d , hx_touch_info_size=%d\n", RawDataLen, RawDataLen_word, hx_touch_info_size);*/ + for (i = 0; i < RawDataLen_word; i++) { + temp1 = index + i; + + if (temp1 < mul_num) { /*mutual*/ + mutual_data[index + i] = ((int8_t)hx_touch_data->hx_rawdata_buf[i * 2 + 4 + 1]) * 256 + hx_touch_data->hx_rawdata_buf[i * 2 + 4]; + } else { /*self*/ + temp1 = i + index; + temp2 = self_num + mul_num; + + if (temp1 >= temp2) { + break; + } + + self_data[i + index - mul_num] = (((int8_t)hx_touch_data->hx_rawdata_buf[i * 2 + 4 + 1]) << 8) + + hx_touch_data->hx_rawdata_buf[i * 2 + 4]; + } + } + } +} + +static void himax_mcu_system_reset(void) +{ + g_core_fp.fp_register_write(pfw_op->addr_system_reset, sizeof(pfw_op->data_system_reset), pfw_op->data_system_reset, false); +} + +static bool himax_mcu_Calculate_CRC_with_AP(unsigned char *FW_content, int CRC_from_FW, int mode) +{ + return true; +} + +static uint32_t himax_mcu_check_CRC(uint8_t *start_addr, int reload_length) +{ + uint32_t result = 0; + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + int cnt = 0, ret = 0; + int length = reload_length / FOUR_BYTE_DATA_SZ; + + ret = g_core_fp.fp_flash_write_burst(pfw_op->addr_reload_addr_from, start_addr); + if (ret < NO_ERR) { + E("%s: i2c access fail!\n", __func__); + return HW_CRC_FAIL; + } + + tmp_data[3] = 0x00; tmp_data[2] = 0x99; tmp_data[1] = (length >> 8); tmp_data[0] = length; + ret = g_core_fp.fp_flash_write_burst(pfw_op->addr_reload_addr_cmd_beat, tmp_data); + if (ret < NO_ERR) { + E("%s: i2c access fail!\n", __func__); + return HW_CRC_FAIL; + } + cnt = 0; + + do { + ret = g_core_fp.fp_register_read(pfw_op->addr_reload_status, FOUR_BYTE_DATA_SZ, tmp_data, 0); + if (ret < NO_ERR) { + E("%s: i2c access fail!\n", __func__); + return HW_CRC_FAIL; + } + + if ((tmp_data[0] & 0x01) != 0x01) { + ret = g_core_fp.fp_register_read(pfw_op->addr_reload_crc32_result, FOUR_BYTE_DATA_SZ, tmp_data, 0); + if (ret < NO_ERR) { + E("%s: i2c access fail!\n", __func__); + return HW_CRC_FAIL; + } + I("%s: tmp_data[3]=%X, tmp_data[2]=%X, tmp_data[1]=%X, tmp_data[0]=%X \n", __func__, tmp_data[3], tmp_data[2], tmp_data[1], tmp_data[0]); + result = ((tmp_data[3] << 24) + (tmp_data[2] << 16) + (tmp_data[1] << 8) + tmp_data[0]); + break; + } else { + I("Waiting for HW ready!\n"); + msleep(1); + } + + } while (cnt++ < 100); + + return result; +} + +static void himax_mcu_set_reload_cmd(uint8_t *write_data, int idx, uint32_t cmd_from, uint32_t cmd_to, uint32_t cmd_beat) +{ + int index = idx * 12; + int i; + + for (i = 3; i >= 0; i--) { + write_data[index + i] = (cmd_from >> (8 * i)); + write_data[index + 4 + i] = (cmd_to >> (8 * i)); + write_data[index + 8 + i] = (cmd_beat >> (8 * i)); + } +} + +static bool himax_mcu_program_reload(void) +{ + return true; +} + +static void himax_mcu_set_SMWP_enable(uint8_t SMWP_enable, bool suspended) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t back_data[FOUR_BYTE_DATA_SZ]; + uint8_t retry_cnt = 0; + + do { + if (SMWP_enable) { + himax_in_parse_assign_cmd(fw_func_handshaking_pwd, tmp_data, 4); + g_core_fp.fp_flash_write_burst(pfw_op->addr_smwp_enable, tmp_data); + himax_in_parse_assign_cmd(fw_func_handshaking_pwd, back_data, 4); + } else { + himax_in_parse_assign_cmd(fw_data_safe_mode_release_pw_reset, tmp_data, 4); + g_core_fp.fp_flash_write_burst(pfw_op->addr_smwp_enable, tmp_data); + himax_in_parse_assign_cmd(fw_data_safe_mode_release_pw_reset, back_data, 4); + } + + g_core_fp.fp_register_read(pfw_op->addr_smwp_enable, FOUR_BYTE_DATA_SZ, tmp_data, 0); + /*I("%s: tmp_data[0]=%d, SMWP_enable=%d, retry_cnt=%d \n", __func__, tmp_data[0],SMWP_enable,retry_cnt);*/ + retry_cnt++; + } while ((tmp_data[3] != back_data[3] || tmp_data[2] != back_data[2] || tmp_data[1] != back_data[1] || tmp_data[0] != back_data[0]) && retry_cnt < HIMAX_REG_RETRY_TIMES); +} + +static void himax_mcu_set_HSEN_enable(uint8_t HSEN_enable, bool suspended) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t back_data[FOUR_BYTE_DATA_SZ]; + uint8_t retry_cnt = 0; + + do { + if (HSEN_enable) { + himax_in_parse_assign_cmd(fw_func_handshaking_pwd, tmp_data, 4); + g_core_fp.fp_flash_write_burst(pfw_op->addr_hsen_enable, tmp_data); + himax_in_parse_assign_cmd(fw_func_handshaking_pwd, back_data, 4); + } else { + himax_in_parse_assign_cmd(fw_data_safe_mode_release_pw_reset, tmp_data, 4); + g_core_fp.fp_flash_write_burst(pfw_op->addr_hsen_enable, tmp_data); + himax_in_parse_assign_cmd(fw_data_safe_mode_release_pw_reset, back_data, 4); + } + + g_core_fp.fp_register_read(pfw_op->addr_hsen_enable, FOUR_BYTE_DATA_SZ, tmp_data, 0); + /*I("%s: tmp_data[0]=%d, HSEN_enable=%d, retry_cnt=%d \n", __func__, tmp_data[0],HSEN_enable,retry_cnt);*/ + retry_cnt++; + } while ((tmp_data[3] != back_data[3] || tmp_data[2] != back_data[2] || tmp_data[1] != back_data[1] || tmp_data[0] != back_data[0]) && retry_cnt < HIMAX_REG_RETRY_TIMES); +} + +static void himax_mcu_usb_detect_set(uint8_t *cable_config) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t back_data[FOUR_BYTE_DATA_SZ]; + uint8_t retry_cnt = 0; + + do { + if (cable_config[1] == 0x01) { + himax_in_parse_assign_cmd(fw_func_handshaking_pwd, tmp_data, 4); + g_core_fp.fp_flash_write_burst(pfw_op->addr_usb_detect, tmp_data); + himax_in_parse_assign_cmd(fw_func_handshaking_pwd, back_data, 4); + I("%s: USB detect status IN!\n", __func__); + } else { + himax_in_parse_assign_cmd(fw_data_safe_mode_release_pw_reset, tmp_data, 4); + g_core_fp.fp_flash_write_burst(pfw_op->addr_usb_detect, tmp_data); + himax_in_parse_assign_cmd(fw_data_safe_mode_release_pw_reset, back_data, 4); + I("%s: USB detect status OUT!\n", __func__); + } + + g_core_fp.fp_register_read(pfw_op->addr_usb_detect, FOUR_BYTE_DATA_SZ, tmp_data, 0); + /*I("%s: tmp_data[0]=%d, USB detect=%d, retry_cnt=%d \n", __func__, tmp_data[0],cable_config[1] ,retry_cnt);*/ + retry_cnt++; + } while ((tmp_data[3] != back_data[3] || tmp_data[2] != back_data[2] || tmp_data[1] != back_data[1] || tmp_data[0] != back_data[0]) && retry_cnt < HIMAX_REG_RETRY_TIMES); +} + +static void himax_mcu_diag_register_set(uint8_t diag_command, uint8_t storage_type) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t back_data[FOUR_BYTE_DATA_SZ]; + uint8_t cnt = 50; + + if (diag_command > 0 && storage_type % 8 > 0) + tmp_data[0] = diag_command + 0x08; + else + tmp_data[0] = diag_command; + I("diag_command = %d, tmp_data[0] = %X\n", diag_command, tmp_data[0]); + g_core_fp.fp_interface_on(); + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; + do { + g_core_fp.fp_flash_write_burst(pfw_op->addr_raw_out_sel, tmp_data); + g_core_fp.fp_register_read(pfw_op->addr_raw_out_sel, FOUR_BYTE_DATA_SZ, back_data, 0); + I("%s: back_data[3]=0x%02X,back_data[2]=0x%02X,back_data[1]=0x%02X,back_data[0]=0x%02X!\n", + __func__, back_data[3], back_data[2], back_data[1], back_data[0]); + cnt--; + } while (tmp_data[0] != back_data[0] && cnt > 0); +} + +static int himax_mcu_chip_self_test(void) +{ + uint8_t tmp_data[FLASH_WRITE_BURST_SZ]; + uint8_t self_test_info[20]; + int pf_value = 0x00; + uint8_t test_result_id = 0; + int i; + memset(tmp_data, 0x00, sizeof(tmp_data)); + g_core_fp.fp_interface_on(); + g_core_fp.fp_sense_off(); + g_core_fp.fp_burst_enable(1); + g_core_fp.fp_flash_write_burst(pfw_op->addr_selftest_addr_en, pfw_op->data_selftest_request); + /*Set criteria 0x10007F1C [0,1]=aa/up,down=, [2-3]=key/up,down, [4-5]=avg/up,down*/ + tmp_data[0] = pfw_op->data_criteria_aa_top[0]; + tmp_data[1] = pfw_op->data_criteria_aa_bot[0]; + tmp_data[2] = pfw_op->data_criteria_key_top[0]; + tmp_data[3] = pfw_op->data_criteria_key_bot[0]; + tmp_data[4] = pfw_op->data_criteria_avg_top[0]; + tmp_data[5] = pfw_op->data_criteria_avg_bot[0]; + tmp_data[6] = 0x00; + tmp_data[7] = 0x00; + g_core_fp.fp_flash_write_burst_lenth(pfw_op->addr_criteria_addr, tmp_data, FLASH_WRITE_BURST_SZ); + g_core_fp.fp_flash_write_burst(pfw_op->addr_set_frame_addr, pfw_op->data_set_frame); + /*Disable IDLE Mode*/ + g_core_fp.fp_idle_mode(1); + /*Diable Flash Reload*/ + g_core_fp.fp_reload_disable(1); + /*start selftest // leave safe mode*/ + g_core_fp.fp_sense_on(0x01); + + /*Hand shaking*/ + for (i = 0; i < 1000; i++) { + g_core_fp.fp_register_read(pfw_op->addr_selftest_addr_en, 4, tmp_data, 0); + I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X, cnt=%d\n", + __func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3], i); + msleep(10); + + if (tmp_data[1] == pfw_op->data_selftest_ack_hb[0] && tmp_data[0] == pfw_op->data_selftest_ack_lb[0]) { + I("%s Data ready goto moving data\n", __func__); + break; + } + } + + g_core_fp.fp_sense_off(); + msleep(20); + /*===================================== + Read test result ==> bit[2][1][0] = [key][AA][avg] => 0xF = PASS + =====================================*/ + g_core_fp.fp_register_read(pfw_op->addr_selftest_result_addr, 20, self_test_info, 0); + test_result_id = self_test_info[0]; + I("%s: check test result, test_result_id=%x, test_result=%x\n", __func__ + , test_result_id, self_test_info[0]); + I("raw top 1 = %d\n", self_test_info[3] * 256 + self_test_info[2]); + I("raw top 2 = %d\n", self_test_info[5] * 256 + self_test_info[4]); + I("raw top 3 = %d\n", self_test_info[7] * 256 + self_test_info[6]); + I("raw last 1 = %d\n", self_test_info[9] * 256 + self_test_info[8]); + I("raw last 2 = %d\n", self_test_info[11] * 256 + self_test_info[10]); + I("raw last 3 = %d\n", self_test_info[13] * 256 + self_test_info[12]); + I("raw key 1 = %d\n", self_test_info[15] * 256 + self_test_info[14]); + I("raw key 2 = %d\n", self_test_info[17] * 256 + self_test_info[16]); + I("raw key 3 = %d\n", self_test_info[19] * 256 + self_test_info[18]); + + if (test_result_id == pfw_op->data_selftest_pass[0]) { + I("[Himax]: self-test pass\n"); + pf_value = 0x0; + } else { + E("[Himax]: self-test fail\n"); + /* E("[Himax]: bank_avg = %d, bank_max = %d,%d,%d, bank_min = %d,%d,%d, key = %d,%d,%d\n", + tmp_data[1],tmp_data[2],tmp_data[3],tmp_data[4],tmp_data[5],tmp_data[6],tmp_data[7], + tmp_data[8],tmp_data[9],tmp_data[10]); */ + pf_value = 0x1; + } + + /*Enable IDLE Mode*/ + g_core_fp.fp_idle_mode(0); +#ifndef HX_ZERO_FLASH + /* Enable Flash Reload //recovery*/ + g_core_fp.fp_reload_disable(0); +#endif + g_core_fp.fp_sense_on(0x00); + msleep(120); + return pf_value; +} + +static void himax_mcu_idle_mode(int disable) +{ + int retry = 20; + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t switch_cmd = 0x00; + I("%s:entering\n", __func__); + + do { + I("%s,now %d times!\n", __func__, retry); + g_core_fp.fp_register_read(pfw_op->addr_fw_mode_status, FOUR_BYTE_DATA_SZ, tmp_data, 0); + + if (disable) { + switch_cmd = pfw_op->data_idle_dis_pwd[0]; + } else { + switch_cmd = pfw_op->data_idle_en_pwd[0]; + } + + tmp_data[0] = switch_cmd; + g_core_fp.fp_flash_write_burst(pfw_op->addr_fw_mode_status, tmp_data); + g_core_fp.fp_register_read(pfw_op->addr_fw_mode_status, FOUR_BYTE_DATA_SZ, tmp_data, 0); + I("%s:After turn ON/OFF IDLE Mode [0] = 0x%02X,[1] = 0x%02X,[2] = 0x%02X,[3] = 0x%02X\n", + __func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]); + retry--; + msleep(10); + } while ((tmp_data[0] != switch_cmd) && retry > 0); + + I("%s: setting OK!\n", __func__); +} + +static void himax_mcu_reload_disable(int disable) +{ + I("%s:entering\n", __func__); + + if (disable) { /*reload disable*/ + g_core_fp.fp_flash_write_burst(pdriver_op->addr_fw_define_flash_reload, pdriver_op->data_fw_define_flash_reload_dis); + } else { /*reload enable*/ + g_core_fp.fp_flash_write_burst(pdriver_op->addr_fw_define_flash_reload, pdriver_op->data_fw_define_flash_reload_en); + } + + I("%s: setting OK!\n", __func__); +} + +static bool himax_mcu_check_chip_version(void) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t ret_data = false; + int i = 0; + + for (i = 0; i < 5; i++) { + g_core_fp.fp_register_read(pfw_op->addr_icid_addr, FOUR_BYTE_DATA_SZ, tmp_data, 0); + I("%s:Read driver IC ID = %X,%X,%X\n", __func__, tmp_data[3], tmp_data[2], tmp_data[1]); + + if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x10) && (tmp_data[1] == 0x2a)) { + strlcpy(private_ts->chip_name, HX_83102A_SERIES_PWON, 30); + ret_data = true; + break; + } else { + ret_data = false; + E("%s:Read driver ID register Fail:\n", __func__); + } + } + + return ret_data; +} + +static int himax_mcu_read_ic_trigger_type(void) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + int trigger_type = false; + g_core_fp.fp_register_read(pfw_op->addr_trigger_addr, FOUR_BYTE_DATA_SZ, tmp_data, 0); + + if ((tmp_data[1] & 0x01) == 1) { + trigger_type = true; + } + + return trigger_type; +} + +static int himax_mcu_read_i2c_status(void) +{ + return i2c_error_count; +} + +static void himax_mcu_read_FW_ver(void) +{ + uint8_t data[FOUR_BYTE_DATA_SZ]; + uint8_t data_2[FOUR_BYTE_DATA_SZ]; + int retry = 200; + int reload_status = 0; + + g_core_fp.fp_sense_on(0x00); + + while (reload_status == 0) { + g_core_fp.fp_register_read(pdriver_op->addr_fw_define_flash_reload, FOUR_BYTE_DATA_SZ, data, 0); + g_core_fp.fp_register_read(pdriver_op->addr_fw_define_2nd_flash_reload, FOUR_BYTE_DATA_SZ, data_2, 0); + + if ((data[1] == 0x3A && data[0] == 0xA3) + || (data_2[1] == 0x72 && data_2[0] == 0xC0)) { + I("reload OK! \n"); + reload_status = 1; + break; + } else if (retry == 0) { + E("reload 20 times! fail \n"); + E("Maybe NOT have FW in chipset \n"); + E("Maybe Wrong FW in chipset \n"); + ic_data->vendor_panel_ver = 0; + ic_data->vendor_fw_ver = 0; + ic_data->vendor_config_ver = 0; + ic_data->vendor_touch_cfg_ver = 0; + ic_data->vendor_display_cfg_ver = 0; + ic_data->vendor_cid_maj_ver = 0; + ic_data->vendor_cid_min_ver = 0; + return; + } else { + retry--; + msleep(10); + if (retry % 10 == 0) + I("reload fail ,delay 10ms retry=%d\n", retry); + } + } + + I("%s : data[0]=0x%2.2X,data[1]=0x%2.2X,data_2[0]=0x%2.2X,data_2[1]=0x%2.2X\n", __func__, data[0], data[1], data_2[0], data_2[1]); + I("reload_status=%d\n", reload_status); + /*===================================== + Read FW version + =====================================*/ + g_core_fp.fp_sense_off(); + g_core_fp.fp_register_read(pfw_op->addr_fw_ver_addr, FOUR_BYTE_DATA_SZ, data, 0); + ic_data->vendor_panel_ver = data[0]; + ic_data->vendor_fw_ver = data[1] << 8 | data[2]; + I("PANEL_VER : %X \n", ic_data->vendor_panel_ver); + I("FW_VER : %X \n", ic_data->vendor_fw_ver); + g_core_fp.fp_register_read(pfw_op->addr_fw_cfg_addr, FOUR_BYTE_DATA_SZ, data, 0); + ic_data->vendor_config_ver = data[2] << 8 | data[3]; + /*I("CFG_VER : %X \n",ic_data->vendor_config_ver);*/ + ic_data->vendor_touch_cfg_ver = data[2]; + I("TOUCH_VER : %X \n", ic_data->vendor_touch_cfg_ver); + ic_data->vendor_display_cfg_ver = data[3]; + I("DISPLAY_VER : %X \n", ic_data->vendor_display_cfg_ver); + g_core_fp.fp_register_read(pfw_op->addr_fw_vendor_addr, FOUR_BYTE_DATA_SZ, data, 0); + ic_data->vendor_cid_maj_ver = data[2] ; + ic_data->vendor_cid_min_ver = data[3]; + I("CID_VER : %X \n", (ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); +} + +static bool himax_mcu_read_event_stack(uint8_t *buf, uint8_t length) +{ + uint8_t cmd[FOUR_BYTE_DATA_SZ]; + /* AHB_I2C Burst Read Off */ + cmd[0] = pfw_op->data_ahb_dis[0]; + + if (himax_bus_write(pfw_op->addr_ahb_addr[0], cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return 0; + } + + himax_bus_read(pfw_op->addr_event_addr[0], buf, length, HIMAX_I2C_RETRY_TIMES); + /* AHB_I2C Burst Read On */ + cmd[0] = pfw_op->data_ahb_en[0]; + + if (himax_bus_write(pfw_op->addr_ahb_addr[0], cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return 0; + } + + return 1; +} + +static void himax_mcu_return_event_stack(void) +{ + int retry = 20, i; + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + I("%s:entering\n", __func__); + + do { + I("now %d times!\n", retry); + + for (i = 0; i < FOUR_BYTE_DATA_SZ; i++) { + tmp_data[i] = psram_op->addr_rawdata_end[i]; + } + + g_core_fp.fp_flash_write_burst(psram_op->addr_rawdata_addr, tmp_data); + g_core_fp.fp_register_read(psram_op->addr_rawdata_addr, FOUR_BYTE_DATA_SZ, tmp_data, 0); + retry--; + msleep(10); + } while ((tmp_data[1] != psram_op->addr_rawdata_end[1] && tmp_data[0] != psram_op->addr_rawdata_end[0]) && retry > 0); + + I("%s: End of setting!\n", __func__); +} + +static bool himax_mcu_calculateChecksum(bool change_iref) +{ + uint8_t CRC_result = 0, i; + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + + for (i = 0; i < FOUR_BYTE_DATA_SZ; i++) { + tmp_data[i] = psram_op->addr_rawdata_end[i]; + } + + CRC_result = g_core_fp.fp_check_CRC(tmp_data, FW_SIZE_64k); + msleep(50); + + if (CRC_result != 0) { + I("%s: CRC Fail=%d\n", __func__, CRC_result); + } + return (CRC_result == 0) ? true : false; +} + +static int himax_mcu_read_FW_status(uint8_t *state_addr, uint8_t *tmp_addr) +{ + uint8_t i; + uint8_t req_size = 0; + uint8_t status_addr[FOUR_BYTE_DATA_SZ]; + uint8_t cmd_addr[FOUR_BYTE_DATA_SZ]; + + if (state_addr[0] == 0x01) { + state_addr[1] = 0x04; + + for (i = 0; i < FOUR_BYTE_DATA_SZ; i++) { + state_addr[i + 2] = pfw_op->addr_fw_dbg_msg_addr[i]; + status_addr[i] = pfw_op->addr_fw_dbg_msg_addr[i]; + } + + req_size = 0x04; + g_core_fp.fp_register_read(status_addr, req_size, tmp_addr, 0); + } else if (state_addr[0] == 0x02) { + state_addr[1] = 0x30; + + for (i = 0; i < FOUR_BYTE_DATA_SZ; i++) { + state_addr[i + 2] = pfw_op->addr_fw_dbg_msg_addr[i]; + cmd_addr[i] = pfw_op->addr_fw_dbg_msg_addr[i]; + } + + req_size = 0x30; + g_core_fp.fp_register_read(cmd_addr, req_size, tmp_addr, 0); + } + + return NO_ERR; +} + +static void himax_mcu_irq_switch(int switch_on) +{ + if (switch_on) { + if (private_ts->use_irq) { + himax_int_enable(switch_on); + } else { + hrtimer_start(&private_ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + } + } else { + if (private_ts->use_irq) { + himax_int_enable(switch_on); + } else { + hrtimer_cancel(&private_ts->timer); + cancel_work_sync(&private_ts->work); + } + } +} + +static int himax_mcu_assign_sorting_mode(uint8_t *tmp_data) +{ + + I("%s:Now tmp_data[3]=0x%02X,tmp_data[2]=0x%02X,tmp_data[1]=0x%02X,tmp_data[0]=0x%02X\n", __func__, tmp_data[3], tmp_data[2], tmp_data[1], tmp_data[0]); + g_core_fp.fp_flash_write_burst(pfw_op->addr_sorting_mode_en, tmp_data); + + return NO_ERR; +} + +static int himax_mcu_check_sorting_mode(uint8_t *tmp_data) +{ + + g_core_fp.fp_register_read(pfw_op->addr_sorting_mode_en, FOUR_BYTE_DATA_SZ, tmp_data, 0); + I("%s: tmp_data[0]=%x,tmp_data[1]=%x\n", __func__, tmp_data[0], tmp_data[1]); + + return NO_ERR; +} + +static int himax_mcu_switch_mode(int mode) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t mode_wirte_cmd; + uint8_t mode_read_cmd; + int result = -1; + int retry = 200; + I("%s: Entering\n", __func__); + + if (mode == 0) { /* normal mode */ + mode_wirte_cmd = pfw_op->data_normal_cmd[0]; + mode_read_cmd = pfw_op->data_normal_status[0]; + } else { /* sorting mode */ + mode_wirte_cmd = pfw_op->data_sorting_cmd[0]; + mode_read_cmd = pfw_op->data_sorting_status[0]; + } + + g_core_fp.fp_sense_off(); + /*g_core_fp.fp_interface_on();*/ + /* clean up FW status */ + g_core_fp.fp_flash_write_burst(psram_op->addr_rawdata_addr, psram_op->addr_rawdata_end); + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = mode_wirte_cmd; + tmp_data[0] = mode_wirte_cmd; + g_core_fp.fp_assign_sorting_mode(tmp_data); + g_core_fp.fp_idle_mode(1); + g_core_fp.fp_reload_disable(1); + + /* To stable the sorting*/ + if (mode) { + g_core_fp.fp_flash_write_burst(pdriver_op->addr_fw_define_rxnum_txnum_maxpt, pdriver_op->data_fw_define_rxnum_txnum_maxpt_sorting); + } else { + g_core_fp.fp_flash_write_burst(pfw_op->addr_set_frame_addr, pfw_op->data_set_frame); + g_core_fp.fp_flash_write_burst(pdriver_op->addr_fw_define_rxnum_txnum_maxpt, pdriver_op->data_fw_define_rxnum_txnum_maxpt_normal); + } + + g_core_fp.fp_sense_on(0x01); + + while (retry != 0) { + I("[%d] %s Read\n", retry, __func__); + g_core_fp.fp_check_sorting_mode(tmp_data); + msleep(100); + I("mode_read_cmd(0)=0x%2.2X,mode_read_cmd(1)=0x%2.2X\n", tmp_data[0], tmp_data[1]); + + if (tmp_data[0] == mode_read_cmd && tmp_data[1] == mode_read_cmd) { + I("Read OK!\n"); + result = 0; + break; + } + + g_core_fp.fp_register_read(pfw_op->addr_chk_fw_status, FOUR_BYTE_DATA_SZ, tmp_data, 0); + + if (tmp_data[0] == 0x00 && tmp_data[1] == 0x00 && tmp_data[2] == 0x00 && tmp_data[3] == 0x00) { + E("%s,: FW Stop!\n", __func__); + break; + } + + retry--; + } + + if (result == 0) { + if (mode == 0) { /*normal mode*/ + return HX_NORMAL_MODE; + } else { /*sorting mode*/ + return HX_SORTING_MODE; + } + } else { /*change mode fail*/ + return HX_CHANGE_MODE_FAIL; + } +} + +static uint8_t himax_mcu_read_DD_status(uint8_t *cmd_set, uint8_t *tmp_data) +{ + int cnt = 0; + uint8_t req_size = cmd_set[0]; + cmd_set[3] = pfw_op->data_dd_request[0]; + g_core_fp.fp_register_write(pfw_op->addr_dd_handshak_addr, FOUR_BYTE_DATA_SZ, cmd_set, 0); + I("%s: cmd_set[0] = 0x%02X,cmd_set[1] = 0x%02X,cmd_set[2] = 0x%02X,cmd_set[3] = 0x%02X\n", + __func__, cmd_set[0], cmd_set[1], cmd_set[2], cmd_set[3]); + + /* Doing hand shaking 0xAA -> 0xBB */ + for (cnt = 0; cnt < 100; cnt++) { + g_core_fp.fp_register_read(pfw_op->addr_dd_handshak_addr, FOUR_BYTE_DATA_SZ, tmp_data, 0); + msleep(10); + + if (tmp_data[3] == pfw_op->data_dd_ack[0]) { + I("%s Data ready goto moving data\n", __func__); + break; + } else { + if (cnt >= 99) { + I("%s Data not ready in FW \n", __func__); + return FW_NOT_READY; + } + } + } + + g_core_fp.fp_register_read(pfw_op->addr_dd_data_addr, req_size, tmp_data, 0); + return NO_ERR; +} +/* FW side end*/ +#endif + +#ifdef CORE_FLASH +/* FLASH side start*/ +static void himax_mcu_chip_erase(void) +{ + g_core_fp.fp_interface_on(); + + /* Reset power saving level */ + if (g_core_fp.fp_init_psl != NULL) { + g_core_fp.fp_init_psl(); + } + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_fmt, pflash_op->data_spi200_trans_fmt); + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_ctrl, pflash_op->data_spi200_trans_ctrl_2); + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_cmd, pflash_op->data_spi200_cmd_2); + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_cmd, pflash_op->data_spi200_cmd_3); + msleep(2000); + + if (!g_core_fp.fp_wait_wip(100)) { + E("%s: Chip_Erase Fail\n", __func__); + } +} + +static bool himax_mcu_block_erase(int start_addr, int length) /*complete not yet*/ +{ + uint32_t page_prog_start = 0; + uint32_t block_size = 0x10000; + + uint8_t tmp_data[4] = {0}; + + g_core_fp.fp_interface_on(); + + g_core_fp.fp_init_psl(); + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_fmt, pflash_op->data_spi200_trans_fmt); + + for (page_prog_start = start_addr; page_prog_start < start_addr + length; page_prog_start = page_prog_start + block_size) { + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_ctrl, pflash_op->data_spi200_trans_ctrl_2); + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_cmd, pflash_op->data_spi200_cmd_2); + + tmp_data[3] = (page_prog_start >> 24)&0xFF; + tmp_data[2] = (page_prog_start >> 16)&0xFF; + tmp_data[1] = (page_prog_start >> 8)&0xFF; + tmp_data[0] = page_prog_start&0xFF; + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_addr, tmp_data); + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_ctrl, pflash_op->data_spi200_trans_ctrl_3); + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_cmd, pflash_op->data_spi200_cmd_4); + msleep(1000); + + if (!g_core_fp.fp_wait_wip(100)) { + E("%s:Erase Fail\n", __func__); + return false; + } + } + + I("%s:END\n", __func__); + return true; +} + +static bool himax_mcu_sector_erase(int start_addr) +{ + return true; +} + +static void himax_mcu_flash_programming(uint8_t *FW_content, int FW_Size) +{ + int page_prog_start = 0, i = 0, j = 0, k = 0; + int program_length = PROGRAM_SZ; + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t buring_data[FLASH_RW_MAX_LEN]; /* Read for flash data, 128K*/ + /* 4 bytes for padding*/ + g_core_fp.fp_interface_on(); + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_fmt, pflash_op->data_spi200_trans_fmt); + + for (page_prog_start = 0; page_prog_start < FW_Size; page_prog_start += FLASH_RW_MAX_LEN) { + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_ctrl, pflash_op->data_spi200_trans_ctrl_2); + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_cmd, pflash_op->data_spi200_cmd_2); + + /*Programmable size = 1 page = 256 bytes, word_number = 256 byte / 4 = 64*/ + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_trans_ctrl, pflash_op->data_spi200_trans_ctrl_4); + + /* Flash start address 1st : 0x0000_0000*/ + if (page_prog_start < 0x100) { + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = (uint8_t)page_prog_start; + } else if (page_prog_start >= 0x100 && page_prog_start < 0x10000) { + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = (uint8_t)(page_prog_start >> 8); + tmp_data[0] = (uint8_t)page_prog_start; + } else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000) { + tmp_data[3] = 0x00; + tmp_data[2] = (uint8_t)(page_prog_start >> 16); + tmp_data[1] = (uint8_t)(page_prog_start >> 8); + tmp_data[0] = (uint8_t)page_prog_start; + } + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_addr, tmp_data); + + for (i = 0; i < FOUR_BYTE_ADDR_SZ; i++) { + buring_data[i] = pflash_op->addr_spi200_data[i]; + } + + for (i = page_prog_start, j = 0; i < 16 + page_prog_start; i++, j++) { + buring_data[j + FOUR_BYTE_ADDR_SZ] = FW_content[i]; + } + + if (himax_bus_write(pic_op->addr_ahb_addr_byte_0[0], buring_data, FOUR_BYTE_ADDR_SZ + 16, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return; + } + + g_core_fp.fp_flash_write_burst(pflash_op->addr_spi200_cmd, pflash_op->data_spi200_cmd_6); + + for (j = 0; j < 5; j++) { + for (i = (page_prog_start + 16 + (j * 48)), k = 0; i < (page_prog_start + 16 + (j * 48)) + program_length; i++, k++) { + buring_data[k + FOUR_BYTE_ADDR_SZ] = FW_content[i]; + } + + if (himax_bus_write(pic_op->addr_ahb_addr_byte_0[0], buring_data, program_length + FOUR_BYTE_ADDR_SZ, HIMAX_I2C_RETRY_TIMES) < 0) { + E("%s: i2c access fail!\n", __func__); + return; + } + } + + if (!g_core_fp.fp_wait_wip(1)) { + E("%s:Flash_Programming Fail\n", __func__); + } + } +} + +static void himax_mcu_flash_page_write(uint8_t *write_addr, int length, uint8_t *write_data) +{ +} + +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_32k(unsigned char *fw, int len, bool change_iref) +{ + /* Not use */ + return 0; +} + +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_60k(unsigned char *fw, int len, bool change_iref) +{ + /* Not use */ + return 0; +} + +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_64k(unsigned char *fw, int len, bool change_iref) +{ + int burnFW_success = 0; + + if (len != FW_SIZE_64k) { + E("%s: The file size is not 64K bytes\n", __func__); + return false; + } + +#ifdef HX_RST_PIN_FUNC + g_core_fp.fp_ic_reset(false, false); +#else + g_core_fp.fp_system_reset(); +#endif + g_core_fp.fp_sense_off(); + g_core_fp.fp_block_erase(0x00, FW_SIZE_64k); + g_core_fp.fp_flash_programming(fw, FW_SIZE_64k); + + if (g_core_fp.fp_check_CRC(pfw_op->addr_program_reload_from, FW_SIZE_64k) == 0) { + burnFW_success = 1; + } + + /*RawOut select initial*/ + g_core_fp.fp_register_write(pfw_op->addr_raw_out_sel, sizeof(pfw_op->data_clear), pfw_op->data_clear, false); + /*DSRAM func initial*/ + g_core_fp.fp_assign_sorting_mode(pfw_op->data_clear); + +#ifdef HX_RST_PIN_FUNC + g_core_fp.fp_ic_reset(false, false); +#else + /*System reset*/ + g_core_fp.fp_system_reset(); +#endif + return burnFW_success; +} + +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_124k(unsigned char *fw, int len, bool change_iref) +{ + /* Not use */ + return 0; +} + +static int himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_128k(unsigned char *fw, int len, bool change_iref) +{ + /* Not use */ + return 0; +} + +static void himax_mcu_flash_dump_func(uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer) +{ + uint8_t tmp_addr[FOUR_BYTE_DATA_SZ]; + uint8_t buffer[256]; + int page_prog_start = 0; + g_core_fp.fp_sense_off(); + g_core_fp.fp_burst_enable(1); + + for (page_prog_start = 0; page_prog_start < Flash_Size; page_prog_start += 128) { + tmp_addr[0] = page_prog_start % 0x100; + tmp_addr[1] = (page_prog_start >> 8) % 0x100; + tmp_addr[2] = (page_prog_start >> 16) % 0x100; + tmp_addr[3] = page_prog_start / 0x1000000; + himax_mcu_register_read(tmp_addr, 128, buffer, 0); + memcpy(&flash_buffer[page_prog_start], buffer, 128); + } + + g_core_fp.fp_burst_enable(0); + g_core_fp.fp_sense_on(0x01); +} + +static bool himax_mcu_flash_lastdata_check(void) +{ + uint8_t tmp_addr[4]; + uint32_t start_addr = 0xFF80; + uint32_t temp_addr = 0; + uint32_t flash_page_len = 0x80; + uint8_t flash_tmp_buffer[128]; + + for (temp_addr = start_addr; temp_addr < (start_addr + flash_page_len); temp_addr = temp_addr + flash_page_len) { + /*I("temp_addr=%d,tmp_addr[0]=0x%2X, tmp_addr[1]=0x%2X,tmp_addr[2]=0x%2X,tmp_addr[3]=0x%2X\n", temp_addr,tmp_addr[0], tmp_addr[1], tmp_addr[2],tmp_addr[3]);*/ + tmp_addr[0] = temp_addr % 0x100; + tmp_addr[1] = (temp_addr >> 8) % 0x100; + tmp_addr[2] = (temp_addr >> 16) % 0x100; + tmp_addr[3] = temp_addr / 0x1000000; + g_core_fp.fp_register_read(tmp_addr, flash_page_len, &flash_tmp_buffer[0], 0); + } + + if ((!flash_tmp_buffer[flash_page_len-4]) && (!flash_tmp_buffer[flash_page_len-3]) && (!flash_tmp_buffer[flash_page_len-2]) && (!flash_tmp_buffer[flash_page_len-1])) { + I("Fail, Last four Bytes are " + "flash_buffer[FFFC]=0x%2X,flash_buffer[FFFD]=0x%2X,flash_buffer[FFFE]=0x%2X,flash_buffer[FFFF]=0x%2X\n", + flash_tmp_buffer[flash_page_len-4], flash_tmp_buffer[flash_page_len-3], flash_tmp_buffer[flash_page_len-2], flash_tmp_buffer[flash_page_len-1]); + return 1;/*FAIL*/ + } else if ((flash_tmp_buffer[flash_page_len-4] == 0xFF) && (flash_tmp_buffer[flash_page_len-3] == 0xFF) && (flash_tmp_buffer[flash_page_len-2] == 0xFF) && (flash_tmp_buffer[flash_page_len-1] == 0xFF)) { + I("Fail, Last four Bytes are " + "flash_buffer[FFFC]=0x%2X,flash_buffer[FFFD]=0x%2X,flash_buffer[FFFE]=0x%2X,flash_buffer[FFFF]=0x%2X\n", + flash_tmp_buffer[flash_page_len-4], flash_tmp_buffer[flash_page_len-3], flash_tmp_buffer[flash_page_len-2], flash_tmp_buffer[flash_page_len-1]); + return 1; + } else { + I("flash_buffer[FFFC]=0x%2X,flash_buffer[FFFD]=0x%2X,flash_buffer[FFFE]=0x%2X,flash_buffer[FFFF]=0x%2X\n", + flash_tmp_buffer[flash_page_len-4], flash_tmp_buffer[flash_page_len-3], flash_tmp_buffer[flash_page_len-2], flash_tmp_buffer[flash_page_len-1]); + return 0;/*PASS*/ + } +} +/* FLASH side end*/ +#endif + +#ifdef CORE_SRAM +/* SRAM side start*/ +static void himax_mcu_sram_write(uint8_t *FW_content) +{ +} + +static bool himax_mcu_sram_verify(uint8_t *FW_File, int FW_Size) +{ + return true; +} + +static bool himax_mcu_get_DSRAM_data(uint8_t *info_data, bool DSRAM_Flag) +{ + int i = 0; + unsigned char tmp_addr[FOUR_BYTE_ADDR_SZ]; + unsigned char tmp_data[FOUR_BYTE_DATA_SZ]; + uint8_t max_i2c_size = MAX_I2C_TRANS_SZ; + uint8_t x_num = ic_data->HX_RX_NUM; + uint8_t y_num = ic_data->HX_TX_NUM; + /*int m_key_num = 0;*/ + int total_size = (x_num * y_num + x_num + y_num) * 2 + 4; + int total_size_temp; + int mutual_data_size = x_num * y_num * 2; + int total_read_times = 0; + int address = 0; + uint8_t *temp_info_data; /*max mkey size = 8*/ + uint16_t check_sum_cal = 0; + int fw_run_flag = -1; + + temp_info_data = kzalloc(sizeof(uint8_t) * (total_size + 8), GFP_KERNEL); + /*1. Read number of MKey R100070E8H to determin data size*/ + /*m_key_num = ic_data->HX_BT_NUM; + I("%s,m_key_num=%d\n",__func__ ,m_key_num); + total_size += m_key_num * 2; + 2. Start DSRAM Rawdata and Wait Data Ready */ + tmp_data[3] = 0x00; tmp_data[2] = 0x00; + tmp_data[1] = psram_op->passwrd_start[1]; + tmp_data[0] = psram_op->passwrd_start[0]; + fw_run_flag = himax_write_read_reg(psram_op->addr_rawdata_addr, tmp_data, psram_op->passwrd_end[1], psram_op->passwrd_end[0]); + + if (fw_run_flag < 0) { + I("%s Data NOT ready => bypass \n", __func__); + kfree(temp_info_data); + return false; + } + + /* 3. Read RawData */ + total_size_temp = total_size; + I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X\n", + __func__, psram_op->addr_rawdata_addr[0], psram_op->addr_rawdata_addr[1], psram_op->addr_rawdata_addr[2], psram_op->addr_rawdata_addr[3]); + tmp_addr[0] = psram_op->addr_rawdata_addr[0]; + tmp_addr[1] = psram_op->addr_rawdata_addr[1]; + tmp_addr[2] = psram_op->addr_rawdata_addr[2]; + tmp_addr[3] = psram_op->addr_rawdata_addr[3]; + + if (total_size % max_i2c_size == 0) { + total_read_times = total_size / max_i2c_size; + } else { + total_read_times = total_size / max_i2c_size + 1; + } + + for (i = 0; i < total_read_times; i++) { + address = (psram_op->addr_rawdata_addr[3] << 24) + + (psram_op->addr_rawdata_addr[2] << 16) + + (psram_op->addr_rawdata_addr[1] << 8) + + psram_op->addr_rawdata_addr[0] + i * max_i2c_size; + /*I("%s address = %08X \n", __func__, address);*/ + + tmp_addr[3] = (uint8_t)((address >> 24) & 0x00FF); + tmp_addr[2] = (uint8_t)((address >> 16) & 0x00FF); + tmp_addr[1] = (uint8_t)((address >> 8) & 0x00FF); + tmp_addr[0] = (uint8_t)((address) & 0x00FF); + + if (total_size_temp >= max_i2c_size) { + g_core_fp.fp_register_read(tmp_addr, max_i2c_size, &temp_info_data[i * max_i2c_size], 0); + total_size_temp = total_size_temp - max_i2c_size; + } else { + /*I("last total_size_temp=%d\n",total_size_temp);*/ + g_core_fp.fp_register_read(tmp_addr, total_size_temp % max_i2c_size, &temp_info_data[i * max_i2c_size], 0); + } + } + + /* 4. FW stop outputing */ + /*I("DSRAM_Flag=%d\n",DSRAM_Flag);*/ + if (DSRAM_Flag == false || private_ts->diag_cmd == 0) { + /*I("Return to Event Stack!\n");*/ + g_core_fp.fp_flash_write_burst(psram_op->addr_rawdata_addr, psram_op->data_fin); + } else { + /*I("Continue to SRAM!\n");*/ + g_core_fp.fp_flash_write_burst(psram_op->addr_rawdata_addr, psram_op->data_conti); + } + + /* 5. Data Checksum Check */ + for (i = 2; i < total_size; i += 2) { /* 2:PASSWORD NOT included */ + check_sum_cal += (temp_info_data[i + 1] * 256 + temp_info_data[i]); + } + + if (check_sum_cal % 0x10000 != 0) { + I("%s check_sum_cal fail=%2X \n", __func__, check_sum_cal); + kfree(temp_info_data); + return false; + } else { + memcpy(info_data, &temp_info_data[4], mutual_data_size * sizeof(uint8_t)); + /*I("%s checksum PASS \n", __func__);*/ + } + + kfree(temp_info_data); + return true; +} +/* SRAM side end*/ +#endif + +#ifdef CORE_DRIVER +static bool himax_mcu_detect_ic(void) +{ + I("%s: use default incell detect.\n", __func__); + + return 0; +} + + +static void himax_mcu_init_ic(void) +{ + I("%s: use default incell init.\n", __func__); +} + +#ifdef HX_AUTO_UPDATE_FW +static int himax_mcu_fw_ver_bin(void) +{ + I("%s: use default incell address.\n", __func__); + I("%s:Entering!\n", __func__); + if (i_CTPM_FW != NULL) { + I("Catch fw version in bin file!\n"); + g_i_FW_VER = (i_CTPM_FW[FW_VER_MAJ_FLASH_ADDR] << 8) | i_CTPM_FW[FW_VER_MIN_FLASH_ADDR]; + g_i_CFG_VER = (i_CTPM_FW[CFG_VER_MAJ_FLASH_ADDR] << 8) | i_CTPM_FW[CFG_VER_MIN_FLASH_ADDR]; + g_i_CID_MAJ = i_CTPM_FW[CID_VER_MAJ_FLASH_ADDR]; + g_i_CID_MIN = i_CTPM_FW[CID_VER_MIN_FLASH_ADDR]; + } else { + I("FW data is null!\n"); + return 1; + } + return NO_ERR; +} +#endif + + +#ifdef HX_RST_PIN_FUNC +static void himax_mcu_pin_reset(void) +{ + I("%s: Now reset the Touch chip.\n", __func__); + himax_rst_gpio_set(private_ts->rst_gpio, 0); + msleep(20); + himax_rst_gpio_set(private_ts->rst_gpio, 1); + msleep(50); +} + +static void himax_mcu_ic_reset(uint8_t loadconfig, uint8_t int_off) +{ + struct himax_ts_data *ts = private_ts; + HX_HW_RESET_ACTIVATE = 1; + I("%s,status: loadconfig=%d,int_off=%d\n", __func__, loadconfig, int_off); + + if (ts->rst_gpio >= 0) { + if (int_off) { + g_core_fp.fp_irq_switch(0); + } + + g_core_fp.fp_pin_reset(); + + if (loadconfig) { + g_core_fp.fp_reload_config(); + } + + if (int_off) { + g_core_fp.fp_irq_switch(1); + } + } +} +#endif + +static void himax_mcu_touch_information(void) +{ +#ifndef HX_FIX_TOUCH_INFO + char data[EIGHT_BYTE_DATA_SZ] = {0}; + + g_core_fp.fp_register_read(pdriver_op->addr_fw_define_rxnum_txnum_maxpt, EIGHT_BYTE_DATA_SZ, data, 0); + ic_data->HX_RX_NUM = data[2]; + ic_data->HX_TX_NUM = data[3]; + ic_data->HX_MAX_PT = data[4]; + /*I("%s : HX_RX_NUM=%d,ic_data->HX_TX_NUM=%d,ic_data->HX_MAX_PT=%d\n",__func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT);*/ + g_core_fp.fp_register_read(pdriver_op->addr_fw_define_xy_res_enable, FOUR_BYTE_DATA_SZ, data, 0); + + /*I("%s : c_data->HX_XY_REVERSE=0x%2.2X\n",__func__,data[1]);*/ + if ((data[1] & 0x04) == 0x04) { + ic_data->HX_XY_REVERSE = true; + } else { + ic_data->HX_XY_REVERSE = false; + } + + g_core_fp.fp_register_read(pdriver_op->addr_fw_define_x_y_res, FOUR_BYTE_DATA_SZ, data, 0); + ic_data->HX_Y_RES = data[0] * 256 + data[1]; + ic_data->HX_X_RES = data[2] * 256 + data[3]; + /*I("%s : ic_data->HX_Y_RES=%d,ic_data->HX_X_RES=%d \n",__func__,ic_data->HX_Y_RES,ic_data->HX_X_RES);*/ + + g_core_fp.fp_register_read(pdriver_op->addr_fw_define_int_is_edge, FOUR_BYTE_DATA_SZ, data, 0); + /*I("%s : data[0]=0x%2.2X,data[1]=0x%2.2X,data[2]=0x%2.2X,data[3]=0x%2.2X\n",__func__,data[0],data[1],data[2],data[3]); + I("data[0] & 0x01 = %d\n",(data[0] & 0x01));*/ + if ((data[1] & 0x01) == 1) { + ic_data->HX_INT_IS_EDGE = true; + } else { + ic_data->HX_INT_IS_EDGE = false; + } + + if (ic_data->HX_RX_NUM > 40) { + ic_data->HX_RX_NUM = 32; + } + + if (ic_data->HX_TX_NUM > 20) { + ic_data->HX_TX_NUM = 18; + } + + if (ic_data->HX_MAX_PT > 10) { + ic_data->HX_MAX_PT = 10; + } + + if (ic_data->HX_Y_RES > 2000) { + ic_data->HX_Y_RES = 1280; + } + + if (ic_data->HX_X_RES > 2000) { + ic_data->HX_X_RES = 720; + } + + /*1. Read number of MKey R100070E8H to determin data size*/ + g_core_fp.fp_register_read(psram_op->addr_mkey, FOUR_BYTE_DATA_SZ, data, 0); + /* I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X\n", + __func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]);*/ + ic_data->HX_BT_NUM = data[0] & 0x03; +#else + ic_data->HX_RX_NUM = FIX_HX_RX_NUM; + ic_data->HX_TX_NUM = FIX_HX_TX_NUM; + ic_data->HX_BT_NUM = FIX_HX_BT_NUM; + ic_data->HX_X_RES = FIX_HX_X_RES; + ic_data->HX_Y_RES = FIX_HX_Y_RES; + ic_data->HX_MAX_PT = FIX_HX_MAX_PT; + ic_data->HX_XY_REVERSE = FIX_HX_XY_REVERSE; + ic_data->HX_INT_IS_EDGE = FIX_HX_INT_IS_EDGE; +#endif + I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d \n", __func__, ic_data->HX_RX_NUM, ic_data->HX_TX_NUM, ic_data->HX_MAX_PT); + I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d \n", __func__, ic_data->HX_XY_REVERSE, ic_data->HX_Y_RES, ic_data->HX_X_RES); + I("%s:HX_INT_IS_EDGE =%d \n", __func__, ic_data->HX_INT_IS_EDGE); +} + +static void himax_mcu_reload_config(void) +{ + if (himax_report_data_init()) { + E("%s: allocate data fail\n", __func__); + } + g_core_fp.fp_sense_on(0x00); +} + +static int himax_mcu_get_touch_data_size(void) +{ + return HIMAX_TOUCH_DATA_SIZE; +} + +static int himax_mcu_hand_shaking(void) +{ + /* 0:Running, 1:Stop, 2:I2C Fail */ + int result = 0; + return result; +} + +static int himax_mcu_determin_diag_rawdata(int diag_command) +{ + return diag_command % 10; +} + +static int himax_mcu_determin_diag_storage(int diag_command) +{ + return diag_command / 10; +} + +static int himax_mcu_cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max) +{ + int RawDataLen; + + if (raw_cnt_rmd != 0x00) { + RawDataLen = MAX_I2C_TRANS_SZ - ((HX_MAX_PT + raw_cnt_max + 3) * 4) - 1; + } else { + RawDataLen = MAX_I2C_TRANS_SZ - ((HX_MAX_PT + raw_cnt_max + 2) * 4) - 1; + } + + return RawDataLen; +} + +static bool himax_mcu_diag_check_sum(struct himax_report_data *hx_touch_data) +{ + uint16_t check_sum_cal = 0; + int i; + + /* Check 128th byte CRC */ + for (i = 0, check_sum_cal = 0; i < (hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); i += 2) { + check_sum_cal += (hx_touch_data->hx_rawdata_buf[i + 1] * FLASH_RW_MAX_LEN + hx_touch_data->hx_rawdata_buf[i]); + } + + if (check_sum_cal % HX64K != 0) { + I("%s fail=%2X \n", __func__, check_sum_cal); + return 0; + } + + return 1; +} + +static void himax_mcu_diag_parse_raw_data(struct himax_report_data *hx_touch_data, int mul_num, int self_num, uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data) +{ + diag_mcu_parse_raw_data(hx_touch_data, mul_num, self_num, diag_cmd, mutual_data, self_data); +} + +#ifdef HX_ESD_RECOVERY +static int himax_mcu_ic_esd_recovery(int hx_esd_event, int hx_zero_event, int length) +{ + int ret_val = NO_ERR; + + if (g_zero_event_count > 5) { + g_zero_event_count = 0; + I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n"); + ret_val = HX_ESD_EVENT; + goto END_FUNCTION; + } + + if (hx_esd_event == length) { + g_zero_event_count = 0; + ret_val = HX_ESD_EVENT; + goto END_FUNCTION; + } else if (hx_zero_event == length) { + g_zero_event_count++; + I("[HIMAX TP MSG]: ALL Zero event is %d times.\n", g_zero_event_count); + ret_val = HX_ZERO_EVENT_COUNT; + goto END_FUNCTION; + } + +END_FUNCTION: + return ret_val; +} + +static void himax_mcu_esd_ic_reset(void) +{ + HX_ESD_RESET_ACTIVATE = 0; +#ifdef HX_RST_PIN_FUNC + himax_mcu_pin_reset(); +#endif + I("%s:\n", __func__); +} +#endif +#endif + +#if defined(HX_SMART_WAKEUP) || defined(HX_HIGH_SENSE) || defined(HX_USB_DETECT_GLOBAL) +static void himax_mcu_resend_cmd_func (bool suspended) +{ +#if defined(HX_SMART_WAKEUP) || defined(HX_HIGH_SENSE) + struct himax_ts_data *ts = private_ts; +#endif +#ifdef HX_SMART_WAKEUP + g_core_fp.fp_set_SMWP_enable(ts->SMWP_enable, suspended); +#endif +#ifdef HX_HIGH_SENSE + g_core_fp.fp_set_HSEN_enable(ts->HSEN_enable, suspended); +#endif +#ifdef HX_USB_DETECT_GLOBAL + himax_cable_detect_func(true); +#endif +} +#endif + +#ifdef HX_ZERO_FLASH +int G_POWERONOF = 1; + +void hx_dis_rload_0f(int disable) +{ + /*Diable Flash Reload*/ + g_core_fp.fp_flash_write_burst (pzf_op->addr_dis_flash_reload, pzf_op->data_dis_flash_reload); +} + +void himax_mcu_clean_sram_0f(uint8_t *addr, int write_len, int type) +{ + int total_read_times = 0; + int max_bus_size = MAX_I2C_TRANS_SZ; + int total_size_temp = 0; + int total_size = 0; + int address = 0; + int i = 0; + + uint8_t fix_data = 0x00; + uint8_t tmp_addr[4]; + uint8_t tmp_data[MAX_I2C_TRANS_SZ] = {0}; + + I("%s, Entering \n", __func__); + + total_size = write_len; + + if (total_size > 4096) { + max_bus_size = 4096; + } + + total_size_temp = write_len; + + g_core_fp.fp_burst_enable (1); + + tmp_addr[3] = addr[3]; + tmp_addr[2] = addr[2]; + tmp_addr[1] = addr[1]; + tmp_addr[0] = addr[0]; + I("%s, write addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n", __func__, tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); + + switch (type) { + case 0: + fix_data = 0x00; + break; + case 1: + fix_data = 0xAA; + break; + case 2: + fix_data = 0xBB; + break; + } + + for (i = 0; i < MAX_I2C_TRANS_SZ; i++) { + tmp_data[i] = fix_data; + } + + I("%s, total size=%d\n", __func__, total_size); + + if (total_size_temp % max_bus_size == 0) { + total_read_times = total_size_temp / max_bus_size; + } else { + total_read_times = total_size_temp / max_bus_size + 1; + } + + for (i = 0; i < (total_read_times); i++) { + I("[log]write %d time start!\n", i); + if (total_size_temp >= max_bus_size) { + g_core_fp.fp_flash_write_burst_lenth (tmp_addr, tmp_data, max_bus_size); + total_size_temp = total_size_temp - max_bus_size; + } else { + I("last total_size_temp=%d\n", total_size_temp); + g_core_fp.fp_flash_write_burst_lenth (tmp_addr, tmp_data, total_size_temp % max_bus_size); + } + address = ((i+1) * max_bus_size); + tmp_addr[1] = addr[1] + (uint8_t) ((address>>8) & 0x00FF); + tmp_addr[0] = addr[0] + (uint8_t) ((address) & 0x00FF); + + msleep (10); + } + + I("%s, END \n", __func__); +} + +void himax_mcu_write_sram_0f(const struct firmware *fw_entry, uint8_t *addr, int start_index, uint32_t write_len) +{ + int total_read_times = 0; + int max_bus_size = MAX_I2C_TRANS_SZ; + int total_size_temp = 0; + int address = 0; + int i = 0; + + uint8_t tmp_addr[4]; + uint8_t *tmp_data; + + total_size_temp = write_len; + I("%s, Entering - total write size=%d\n", __func__, total_size_temp); + +#if defined(HX_SPI_OPERATION) + if (write_len > 4096) { + max_bus_size = 4096; + } else { + max_bus_size = write_len; + } +#else + if (write_len > 240) { + max_bus_size = 240; + } else { + max_bus_size = write_len; + } +#endif + + g_core_fp.fp_burst_enable (1); + + tmp_addr[3] = addr[3]; + tmp_addr[2] = addr[2]; + tmp_addr[1] = addr[1]; + tmp_addr[0] = addr[0]; + I("%s, write addr = 0x%02X%02X%02X%02X\n", __func__, tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); + + tmp_data = kzalloc (sizeof (uint8_t) * max_bus_size, GFP_KERNEL); + if (tmp_data == NULL) { + I("%s: Can't allocate enough buf \n", __func__); + return; + } + + /* + for(i = 0;i<10;i++) + { + I("[%d] 0x%2.2X", i, tmp_data[i]); + } + I("\n"); + */ + if (total_size_temp % max_bus_size == 0) { + total_read_times = total_size_temp / max_bus_size; + } else { + total_read_times = total_size_temp / max_bus_size + 1; + } + + for (i = 0; i < (total_read_times); i++) { + /*I("[log]write %d time start!\n", i); + I("[log]addr[3]=0x%02X, addr[2]=0x%02X, addr[1]=0x%02X, addr[0]=0x%02X!\n", tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]);*/ + + if (total_size_temp >= max_bus_size) { + memcpy (tmp_data, &fw_entry->data[start_index+i * max_bus_size], max_bus_size); + g_core_fp.fp_flash_write_burst_lenth (tmp_addr, tmp_data, max_bus_size); + total_size_temp = total_size_temp - max_bus_size; + } else { + memcpy (tmp_data, &fw_entry->data[start_index+i * max_bus_size], total_size_temp % max_bus_size); + I("last total_size_temp=%d\n", total_size_temp % max_bus_size); + g_core_fp.fp_flash_write_burst_lenth (tmp_addr, tmp_data, total_size_temp % max_bus_size); + } + + /*I("[log]write %d time end!\n", i);*/ + address = ((i+1) * max_bus_size); + tmp_addr[0] = addr[0] + (uint8_t) ((address) & 0x00FF); + + if (tmp_addr[0] < addr[0]) { + tmp_addr[1] = addr[1] + (uint8_t) ((address>>8) & 0x00FF) + 1; + } else { + tmp_addr[1] = addr[1] + (uint8_t) ((address>>8) & 0x00FF); + } + + + udelay (100); + } + I("%s, End \n", __func__); + kfree (tmp_data); +} + +int himax_sram_write_crc_check(const struct firmware *fw_entry, uint8_t *addr, int strt_idx, uint32_t len) +{ + int retry = 0; + int crc = -1; + + do { + g_core_fp.fp_write_sram_0f (fw_entry, addr, strt_idx, len); + crc = g_core_fp.fp_check_CRC (addr, len); + retry++; + I("%s, HW CRC %s in %d time \n", __func__, (crc == 0)?"OK":"Fail", retry); + } while (crc != 0 && retry < 3); + + return crc; +} + +int himax_zf_part_info(const struct firmware *fw_entry) +{ + int part_num = 0; + int ret = 0; + int i = 0; + uint8_t buf[16]; + struct zf_info *zf_info_arr; + + /*1. get number of partition*/ + part_num = fw_entry->data[HX64K + 12]; + I("%s, Number of partition is %d\n", __func__, part_num); + if (part_num <= 0) + part_num = 1; + + /*2. initial struct of array*/ + zf_info_arr = kzalloc(part_num * sizeof(struct zf_info), GFP_KERNEL); + if (zf_info_arr == NULL) { + E("%s, Allocate ZF info array failed!\n", __func__); + return MEM_ALLOC_FAIL; + } + + for (i = 0; i < part_num; i++) { + /*3. get all partition*/ + memcpy(buf, &fw_entry->data[i * 0x10 + HX64K], 16); + memcpy(zf_info_arr[i].sram_addr, buf, 4); + zf_info_arr[i].write_size = buf[5] << 8 | buf[4]; + zf_info_arr[i].fw_addr = buf[9] << 8 | buf[8]; + I("%s,[%d] SRAM addr = %02X%02X%02X%02X!\n", __func__, i, zf_info_arr[i].sram_addr[3], zf_info_arr[i].sram_addr[2], + zf_info_arr[i].sram_addr[1], zf_info_arr[i].sram_addr[0]); + I("%s,[%d] fw_addr = %04X!\n", __func__, i, zf_info_arr[i].fw_addr); + I("%s,[%d] write_size = %d!\n", __func__, i, zf_info_arr[i].write_size); + + /*4. write to sram*/ + if (G_POWERONOF == 1) { + if (himax_sram_write_crc_check(fw_entry, zf_info_arr[i].sram_addr, zf_info_arr[i].fw_addr, zf_info_arr[i].write_size) != 0) { + E("%s, HW CRC FAIL\n", __func__); + } + } else { + g_core_fp.fp_clean_sram_0f(zf_info_arr[i].sram_addr, zf_info_arr[i].write_size, 2); + } + } + + kfree (zf_info_arr); + + return ret; +} + +void himax_mcu_firmware_update_0f(const struct firmware *fw_entry) +{ + int ret = 0; + + I("%s,Entering - total FW size=%d\n", __func__, (int)fw_entry->size); + + g_core_fp.fp_register_write(pzf_op->addr_system_reset, 4, pzf_op->data_system_reset, false); + + g_core_fp.fp_sense_off(); + + /* first 48K */ + if (himax_sram_write_crc_check(fw_entry, pzf_op->data_sram_start_addr, 0, HX_48K_SZ) != 0) + E("%s, HW CRC FAIL - Main SRAM 48K\n", __func__); + if ((int)fw_entry->size > HX64K) { + ret = himax_zf_part_info(fw_entry); + } else { + /*config info*/ + if (G_POWERONOF == 1) { + if (himax_sram_write_crc_check(fw_entry, pzf_op->data_cfg_info, 0xC000, 128) != 0) + E("Config info CRC Fail!\n"); + } else { + g_core_fp.fp_clean_sram_0f(pzf_op->data_cfg_info, 128, 2); + } + + if (G_POWERONOF == 1) { + if (himax_sram_write_crc_check(fw_entry, pzf_op->data_fw_cfg_1, 0xC100, 528) != 0) + E("FW config 1 CRC Fail!\n"); + } else { + g_core_fp.fp_clean_sram_0f(pzf_op->data_fw_cfg_1, 528, 1); + } + + if (G_POWERONOF == 1) { + if (himax_sram_write_crc_check(fw_entry, pzf_op->data_fw_cfg_3, 0xCA00, 128) != 0) + E("FW config 3 CRC Fail!\n"); + } else { + g_core_fp.fp_clean_sram_0f(pzf_op->data_fw_cfg_3, 128, 2); + } + + /*ADC config*/ + if (G_POWERONOF == 1) { + if (himax_sram_write_crc_check(fw_entry, pzf_op->data_adc_cfg_1, 0xD640, 1200) != 0) + E("ADC config 1 CRC Fail!\n"); + } else { + g_core_fp.fp_clean_sram_0f(pzf_op->data_adc_cfg_1, 1200, 2); + } + + if (G_POWERONOF == 1) { + if (himax_sram_write_crc_check(fw_entry, pzf_op->data_adc_cfg_2, 0xD320, 800) != 0) + E("ADC config 2 CRC Fail!\n"); + } else { + g_core_fp.fp_clean_sram_0f(pzf_op->data_adc_cfg_2, 800, 2); + } + + /*mapping table*/ + if (G_POWERONOF == 1) { + if (himax_sram_write_crc_check(fw_entry, pzf_op->data_map_table, 0xE000, 1536) != 0) + E("Mapping table CRC Fail!\n"); + } else { + g_core_fp.fp_clean_sram_0f(pzf_op->data_map_table, 1536, 2); + } + } + + /* set n frame=0*/ + if (G_POWERONOF == 1) { + g_core_fp.fp_write_sram_0f(fw_entry, pzf_op->data_mode_switch, 0xC30C, 4); + } else { + g_core_fp.fp_clean_sram_0f(pzf_op->data_mode_switch, 4, 2); + } + + /*DSRAM func initial*/ + g_core_fp.fp_assign_sorting_mode(pfw_op->data_clear); + + I("%s, End \n", __func__); +} + +int hx_0f_op_file_dirly(char *file_name) +{ + int err = NO_ERR; + const struct firmware *fw_entry = NULL; + + + I("%s, Entering \n", __func__); + I("file name = %s\n", file_name); + err = request_firmware (&fw_entry, file_name, private_ts->dev); + if (err < 0) { + E("%s, fail in line%d error code=%d,file maybe fail\n", __func__, __LINE__, err); + return err; + } + + himax_int_enable (0); + + if (g_f_0f_updat == 1) { + I("%s:[Warning]Other thread is updating now!\n", __func__); + err = -1; + return err; + } else { + I("%s:Entering Update Flow!\n", __func__); + g_f_0f_updat = 1; + } + + g_core_fp.fp_firmware_update_0f (fw_entry); + release_firmware (fw_entry); + + g_f_0f_updat = 0; + I("%s, END \n", __func__); + return err; +} + +int himax_mcu_0f_operation_dirly(void) +{ + int err = NO_ERR; + const struct firmware *fw_entry = NULL; + + + I("%s, Entering \n", __func__); + I("file name = %s\n", i_CTPM_firmware_name); + err = request_firmware (&fw_entry, i_CTPM_firmware_name, private_ts->dev); + if (err < 0) { + E("%s, fail in line%d error code=%d,file maybe fail\n", __func__, __LINE__, err); + return err; + } + + himax_int_enable (0); + + if (g_f_0f_updat == 1) { + I("%s:[Warning]Other thread is updating now!\n", __func__); + err = -1; + return err; + } else { + I("%s:Entering Update Flow!\n", __func__); + g_f_0f_updat = 1; + } + + g_core_fp.fp_firmware_update_0f (fw_entry); + release_firmware (fw_entry); + + g_f_0f_updat = 0; + I("%s, END \n", __func__); + return err; +} +void himax_mcu_0f_operation(struct work_struct *work) +{ + int err = NO_ERR; + const struct firmware *fw_entry = NULL; + + + I("%s, Entering \n", __func__); + I("file name = %s\n", i_CTPM_firmware_name); + err = request_firmware (&fw_entry, i_CTPM_firmware_name, private_ts->dev); + if (err < 0) { + E("%s, fail in line%d error code=%d,file maybe fail\n", __func__, __LINE__, err); + return ; + } + + if (g_f_0f_updat == 1) { + I("%s:[Warning]Other thread is updating now!\n", __func__); + return ; + } else { + I("%s:Entering Update Flow!\n", __func__); + g_f_0f_updat = 1; + } + + himax_int_enable (0); + + g_core_fp.fp_firmware_update_0f (fw_entry); + release_firmware (fw_entry); + + g_core_fp.fp_reload_disable(0); + msleep (10); + g_core_fp.fp_read_FW_ver(); + g_core_fp.fp_touch_information(); + msleep (10); + g_core_fp.fp_sense_on(0x00); + msleep (10); + I("%s:End \n", __func__); + himax_int_enable (1); + + g_f_0f_updat = 0; + I("%s, END \n", __func__); + return ; +} + +static int himax_mcu_0f_esd_check(void) +{ + uint8_t tmp_data[FOUR_BYTE_DATA_SZ]; + int ret = NO_ERR; + + I("Enter %s\n", __func__); + + g_core_fp.fp_register_read(pzf_op->addr_sts_chk, FOUR_BYTE_DATA_SZ, tmp_data, 0); + + if (tmp_data[0] != pzf_op->data_activ_sts[0]) { + ret = ERR_STS_WRONG; + I("%s:status : %8X = %2X\n", __func__, zf_addr_sts_chk, tmp_data[0]); + } + + g_core_fp.fp_register_read(pzf_op->addr_activ_relod, FOUR_BYTE_DATA_SZ, tmp_data, 0); + + if (tmp_data[0] != pzf_op->data_activ_in[0]) { + ret = ERR_STS_WRONG; + I("%s:status : %8X = %2X\n", __func__, zf_addr_activ_relod, tmp_data[0]); + } + + return ret; +} + + +#ifdef HX_0F_DEBUG +void himax_mcu_read_sram_0f(const struct firmware *fw_entry, uint8_t *addr, int start_index, int read_len) +{ + int total_read_times = 0; + int max_bus_size = MAX_I2C_TRANS_SZ; + int total_size_temp = 0; + int total_size = 0; + int address = 0; + int i = 0, j = 0; + int not_same = 0; + + uint8_t tmp_addr[4]; + uint8_t *temp_info_data; + int *not_same_buff; + + I("%s, Entering \n", __func__); + + g_core_fp.fp_burst_enable (1); + + total_size = read_len; + + total_size_temp = read_len; + +#if defined(HX_SPI_OPERATION) + if (read_len > 2048) { + max_bus_size = 2048; + } else { + max_bus_size = read_len; + } +#else + if (read_len > 240) { + max_bus_size = 240; + } else { + max_bus_size = read_len; + } +#endif + + + temp_info_data = kzalloc (sizeof (uint8_t) * total_size, GFP_KERNEL); + not_same_buff = kzalloc (sizeof (int) * total_size, GFP_KERNEL); + + + tmp_addr[3] = addr[3]; + tmp_addr[2] = addr[2]; + tmp_addr[1] = addr[1]; + tmp_addr[0] = addr[0]; + I("%s, read addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n", __func__, tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); + + I("%s, total size=%d\n", __func__, total_size); + + g_core_fp.fp_burst_enable (1); + + if (total_size % max_bus_size == 0) { + total_read_times = total_size / max_bus_size; + } else { + total_read_times = total_size / max_bus_size + 1; + } + + for (i = 0; i < (total_read_times); i++) { + if (total_size_temp >= max_bus_size) { + g_core_fp.fp_register_read (tmp_addr, max_bus_size, &temp_info_data[i*max_bus_size], false); + total_size_temp = total_size_temp - max_bus_size; + } else { + g_core_fp.fp_register_read (tmp_addr, total_size_temp % max_bus_size, &temp_info_data[i*max_bus_size], false); + } + + address = ((i+1) * max_bus_size); + tmp_addr[0] = addr[0] + (uint8_t) ((address) & 0x00FF); + if (tmp_addr[0] < addr[0]) { + tmp_addr[1] = addr[1] + (uint8_t) ((address>>8) & 0x00FF) + 1; + } else { + tmp_addr[1] = addr[1] + (uint8_t) ((address>>8) & 0x00FF); + } + + msleep (10); + } + I("%s, READ Start \n", __func__); + I("%s, start_index = %d \n", __func__, start_index); + j = start_index; + for (i = 0; i < read_len; i++, j++) { + if (fw_entry->data[j] != temp_info_data[i]) { + not_same++; + not_same_buff[i] = 1; + } + + I("0x%2.2X, ", temp_info_data[i]); + + if (i > 0 && i%16 == 15) { + printk ("\n"); + } + } + I("%s, READ END \n", __func__); + I("%s, Not Same count=%d\n", __func__, not_same); + if (not_same != 0) { + j = start_index; + for (i = 0; i < read_len; i++, j++) { + if (not_same_buff[i] == 1) { + I("bin = [%d] 0x%2.2X\n", i, fw_entry->data[j]); + } + } + for (i = 0; i < read_len; i++, j++) { + if (not_same_buff[i] == 1) { + I("sram = [%d] 0x%2.2X \n", i, temp_info_data[i]); + } + } + } + I("%s, READ END \n", __func__); + I("%s, Not Same count=%d\n", __func__, not_same); + I("%s, END \n", __func__); + + kfree (not_same_buff); + kfree (temp_info_data); +} + +void himax_mcu_read_all_sram(uint8_t *addr, int read_len) +{ + int total_read_times = 0; + int max_bus_size = MAX_I2C_TRANS_SZ; + int total_size_temp = 0; + int total_size = 0; + int address = 0; + int i = 0; + /* + struct file *fn; + struct filename *vts_name; + */ + + uint8_t tmp_addr[4]; + uint8_t *temp_info_data; + + I("%s, Entering \n", __func__); + + g_core_fp.fp_burst_enable (1); + + total_size = read_len; + + total_size_temp = read_len; + + temp_info_data = kzalloc (sizeof (uint8_t) * total_size, GFP_KERNEL); + + + tmp_addr[3] = addr[3]; + tmp_addr[2] = addr[2]; + tmp_addr[1] = addr[1]; + tmp_addr[0] = addr[0]; + I("%s, read addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n", __func__, tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); + + I("%s, total size=%d\n", __func__, total_size); + + if (total_size % max_bus_size == 0) { + total_read_times = total_size / max_bus_size; + } else { + total_read_times = total_size / max_bus_size + 1; + } + + for (i = 0; i < (total_read_times); i++) { + if (total_size_temp >= max_bus_size) { + g_core_fp.fp_register_read (tmp_addr, max_bus_size, &temp_info_data[i*max_bus_size], false); + total_size_temp = total_size_temp - max_bus_size; + } else { + g_core_fp.fp_register_read (tmp_addr, total_size_temp % max_bus_size, &temp_info_data[i*max_bus_size], false); + } + + address = ((i+1) * max_bus_size); + tmp_addr[1] = addr[1] + (uint8_t) ((address>>8) & 0x00FF); + tmp_addr[0] = addr[0] + (uint8_t) ((address) & 0x00FF); + + msleep (10); + } + I("%s, NOW addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n", __func__, tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); + /*for(i = 0;i 0 && i%16 == 15) + printk("\n"); + }*/ + + /* need modify + I("Now Write File start!\n"); + vts_name = getname_kernel("/sdcard/dump_dsram.txt"); + fn = file_open_name(vts_name, O_CREAT | O_WRONLY, 0); + if (!IS_ERR (fn)) { + I("%s create file and ready to write\n", __func__); + fn->f_op->write (fn, temp_info_data, read_len*sizeof (uint8_t), &fn->f_pos); + filp_close (fn, NULL); + } + I("Now Write File End!\n"); + */ + + I("%s, END \n", __func__); + + kfree (temp_info_data); +} + +void himax_mcu_firmware_read_0f(const struct firmware *fw_entry, int type) +{ + uint8_t tmp_addr[4]; + + I("%s, Entering \n", __func__); + if (type == 0) { /* first 48K */ + g_core_fp.fp_read_sram_0f (fw_entry, pzf_op->data_sram_start_addr, 0, HX_48K_SZ); + g_core_fp.fp_read_all_sram (tmp_addr, 0xC000); + } else { /*last 16k*/ + g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_cfg_info, 0xC000, 132); + + /*FW config*/ + g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_fw_cfg_1, 0xC0FE, 484); + g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_fw_cfg_2, 0xC9DE, 36); + g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_fw_cfg_3, 0xCA00, 72); + + /*ADC config*/ + + g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_adc_cfg_1, 0xD630, 1188); + g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_adc_cfg_2, 0xD318, 792); + + + /*mapping table*/ + g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_map_table, 0xE000, 1536); + + /* set n frame=0*/ + g_core_fp.fp_read_sram_0f(fw_entry, pzf_op->data_mode_switch, 0xC30C, 4); + } + + I("%s, END \n", __func__); +} + +void himax_mcu_0f_operation_check(int type) +{ + int err = NO_ERR; + const struct firmware *fw_entry = NULL; + /* char *firmware_name = "himax.bin"; */ + + + I("%s, Entering \n", __func__); + I("file name = %s\n", i_CTPM_firmware_name); + + + err = request_firmware(&fw_entry, i_CTPM_firmware_name, private_ts->dev); + if (err < 0) { + E("%s, fail in line%d error code=%d\n", __func__, __LINE__, err); + return ; + } + + I("first 4 bytes 0x%2X, 0x%2X, 0x%2X, 0x%2X !\n", fw_entry->data[0], fw_entry->data[1], fw_entry->data[2], fw_entry->data[3]); + I("next 4 bytes 0x%2X, 0x%2X, 0x%2X, 0x%2X !\n", fw_entry->data[4], fw_entry->data[5], fw_entry->data[6], fw_entry->data[7]); + I("and next 4 bytes 0x%2X, 0x%2X, 0x%2X, 0x%2X !\n", fw_entry->data[8], fw_entry->data[9], fw_entry->data[10], fw_entry->data[11]); + + g_core_fp.fp_firmware_read_0f(fw_entry, type); + + release_firmware(fw_entry); + I("%s, END \n", __func__); + return ; +} +#endif + +#endif + +#ifdef CORE_INIT +/* init start */ +static void himax_mcu_fp_init(void) +{ +#ifdef CORE_IC + g_core_fp.fp_burst_enable = himax_mcu_burst_enable; + g_core_fp.fp_register_read = himax_mcu_register_read; + g_core_fp.fp_flash_write_burst = himax_mcu_flash_write_burst; + g_core_fp.fp_flash_write_burst_lenth = himax_mcu_flash_write_burst_lenth; + g_core_fp.fp_register_write = himax_mcu_register_write; + g_core_fp.fp_interface_on = himax_mcu_interface_on; + g_core_fp.fp_sense_on = himax_mcu_sense_on; + g_core_fp.fp_sense_off = himax_mcu_sense_off; + g_core_fp.fp_wait_wip = himax_mcu_wait_wip; + g_core_fp.fp_init_psl = himax_mcu_init_psl; + g_core_fp.fp_resume_ic_action = himax_mcu_resume_ic_action; + g_core_fp.fp_suspend_ic_action = himax_mcu_suspend_ic_action; + g_core_fp.fp_power_on_init = himax_mcu_power_on_init; +#endif +#ifdef CORE_FW + g_core_fp.fp_system_reset = himax_mcu_system_reset; + g_core_fp.fp_Calculate_CRC_with_AP = himax_mcu_Calculate_CRC_with_AP; + g_core_fp.fp_check_CRC = himax_mcu_check_CRC; + g_core_fp.fp_set_reload_cmd = himax_mcu_set_reload_cmd; + g_core_fp.fp_program_reload = himax_mcu_program_reload; + g_core_fp.fp_set_SMWP_enable = himax_mcu_set_SMWP_enable; + g_core_fp.fp_set_HSEN_enable = himax_mcu_set_HSEN_enable; + g_core_fp.fp_usb_detect_set = himax_mcu_usb_detect_set; + g_core_fp.fp_diag_register_set = himax_mcu_diag_register_set; + g_core_fp.fp_chip_self_test = himax_mcu_chip_self_test; + g_core_fp.fp_idle_mode = himax_mcu_idle_mode; + g_core_fp.fp_reload_disable = himax_mcu_reload_disable; + g_core_fp.fp_check_chip_version = himax_mcu_check_chip_version; + g_core_fp.fp_read_ic_trigger_type = himax_mcu_read_ic_trigger_type; + g_core_fp.fp_read_i2c_status = himax_mcu_read_i2c_status; + g_core_fp.fp_read_FW_ver = himax_mcu_read_FW_ver; + g_core_fp.fp_read_event_stack = himax_mcu_read_event_stack; + g_core_fp.fp_return_event_stack = himax_mcu_return_event_stack; + g_core_fp.fp_calculateChecksum = himax_mcu_calculateChecksum; + g_core_fp.fp_read_FW_status = himax_mcu_read_FW_status; + g_core_fp.fp_irq_switch = himax_mcu_irq_switch; + g_core_fp.fp_assign_sorting_mode = himax_mcu_assign_sorting_mode; + g_core_fp.fp_check_sorting_mode = himax_mcu_check_sorting_mode; + g_core_fp.fp_switch_mode = himax_mcu_switch_mode; + g_core_fp.fp_read_DD_status = himax_mcu_read_DD_status; +#endif +#ifdef CORE_FLASH + g_core_fp.fp_chip_erase = himax_mcu_chip_erase; + g_core_fp.fp_block_erase = himax_mcu_block_erase; + g_core_fp.fp_sector_erase = himax_mcu_sector_erase; + g_core_fp.fp_flash_programming = himax_mcu_flash_programming; + g_core_fp.fp_flash_page_write = himax_mcu_flash_page_write; + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_32k = himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_32k; + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_60k = himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_60k; + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_64k = himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_64k; + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_124k = himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_124k; + g_core_fp.fp_fts_ctpm_fw_upgrade_with_sys_fs_128k = himax_mcu_fts_ctpm_fw_upgrade_with_sys_fs_128k; + g_core_fp.fp_flash_dump_func = himax_mcu_flash_dump_func; + g_core_fp.fp_flash_lastdata_check = himax_mcu_flash_lastdata_check; +#endif +#ifdef CORE_SRAM + g_core_fp.fp_sram_write = himax_mcu_sram_write; + g_core_fp.fp_sram_verify = himax_mcu_sram_verify; + g_core_fp.fp_get_DSRAM_data = himax_mcu_get_DSRAM_data; +#endif +#ifdef CORE_DRIVER + g_core_fp.fp_chip_detect = himax_mcu_detect_ic; + g_core_fp.fp_chip_init = himax_mcu_init_ic; +#ifdef HX_AUTO_UPDATE_FW + g_core_fp.fp_fw_ver_bin = himax_mcu_fw_ver_bin; +#endif +#ifdef HX_RST_PIN_FUNC + g_core_fp.fp_pin_reset = himax_mcu_pin_reset; + g_core_fp.fp_ic_reset = himax_mcu_ic_reset; +#endif + g_core_fp.fp_touch_information = himax_mcu_touch_information; + g_core_fp.fp_reload_config = himax_mcu_reload_config; + g_core_fp.fp_get_touch_data_size = himax_mcu_get_touch_data_size; + g_core_fp.fp_hand_shaking = himax_mcu_hand_shaking; + g_core_fp.fp_determin_diag_rawdata = himax_mcu_determin_diag_rawdata; + g_core_fp.fp_determin_diag_storage = himax_mcu_determin_diag_storage; + g_core_fp.fp_cal_data_len = himax_mcu_cal_data_len; + g_core_fp.fp_diag_check_sum = himax_mcu_diag_check_sum; + g_core_fp.fp_diag_parse_raw_data = himax_mcu_diag_parse_raw_data; +#ifdef HX_ESD_RECOVERY + g_core_fp.fp_ic_esd_recovery = himax_mcu_ic_esd_recovery; + g_core_fp.fp_esd_ic_reset = himax_mcu_esd_ic_reset; +#endif +#if defined(HX_SMART_WAKEUP) || defined(HX_HIGH_SENSE) || defined(HX_USB_DETECT_GLOBAL) + g_core_fp.fp_resend_cmd_func = himax_mcu_resend_cmd_func; +#endif +#endif +#ifdef HX_ZERO_FLASH + g_core_fp.fp_reload_disable = hx_dis_rload_0f; + g_core_fp.fp_clean_sram_0f = himax_mcu_clean_sram_0f; + g_core_fp.fp_write_sram_0f = himax_mcu_write_sram_0f; + g_core_fp.fp_firmware_update_0f = himax_mcu_firmware_update_0f; + g_core_fp.fp_0f_operation = himax_mcu_0f_operation; + g_core_fp.fp_0f_operation_dirly = himax_mcu_0f_operation_dirly; + g_core_fp.fp_0f_op_file_dirly = hx_0f_op_file_dirly; + g_core_fp.fp_0f_esd_check = himax_mcu_0f_esd_check; +#ifdef HX_0F_DEBUG + g_core_fp.fp_read_sram_0f = himax_mcu_read_sram_0f; + g_core_fp.fp_read_all_sram = himax_mcu_read_all_sram; + g_core_fp.fp_firmware_read_0f = himax_mcu_firmware_read_0f; + g_core_fp.fp_0f_operation_check = himax_mcu_0f_operation_check; +#endif +#endif +} + +void himax_mcu_in_cmd_struct_init(void) +{ + I("%s: Entering!\n", __func__); + g_core_cmd_op = kzalloc(sizeof(struct himax_core_command_operation), GFP_KERNEL); + g_core_cmd_op->ic_op = kzalloc(sizeof(struct ic_operation), GFP_KERNEL); + g_core_cmd_op->fw_op = kzalloc(sizeof(struct fw_operation), GFP_KERNEL); + g_core_cmd_op->flash_op = kzalloc(sizeof(struct flash_operation), GFP_KERNEL); + g_core_cmd_op->sram_op = kzalloc(sizeof(struct sram_operation), GFP_KERNEL); + g_core_cmd_op->driver_op = kzalloc(sizeof(struct driver_operation), GFP_KERNEL); + pic_op = g_core_cmd_op->ic_op; + pfw_op = g_core_cmd_op->fw_op; + pflash_op = g_core_cmd_op->flash_op; + psram_op = g_core_cmd_op->sram_op; + pdriver_op = g_core_cmd_op->driver_op; +#ifdef HX_ZERO_FLASH + g_core_cmd_op->zf_op = kzalloc(sizeof(struct zf_operation), GFP_KERNEL); + pzf_op = g_core_cmd_op->zf_op; +#endif + himax_mcu_fp_init(); +} + +/* +static void himax_mcu_in_cmd_struct_free(void) +{ + pic_op = NULL; + pfw_op = NULL; + pflash_op = NULL; + psram_op = NULL; + pdriver_op = NULL; + kfree(g_core_cmd_op); + kfree(g_core_cmd_op->ic_op); + kfree(g_core_cmd_op->flash_op); + kfree(g_core_cmd_op->sram_op); + kfree(g_core_cmd_op->driver_op); +} +*/ + +void himax_in_parse_assign_cmd(uint32_t addr, uint8_t *cmd, int len) +{ + /*I("%s: Entering!\n", __func__);*/ + switch (len) { + case 1: + cmd[0] = addr; + /*I("%s: cmd[0] = 0x%02X\n", __func__, cmd[0]);*/ + break; + + case 2: + cmd[0] = addr % 0x100; + cmd[1] = (addr >> 8) % 0x100; + /*I("%s: cmd[0] = 0x%02X,cmd[1] = 0x%02X\n", __func__, cmd[0], cmd[1]);*/ + break; + + case 4: + cmd[0] = addr % 0x100; + cmd[1] = (addr >> 8) % 0x100; + cmd[2] = (addr >> 16) % 0x100; + cmd[3] = addr / 0x1000000; + /* I("%s: cmd[0] = 0x%02X,cmd[1] = 0x%02X,cmd[2] = 0x%02X,cmd[3] = 0x%02X\n", + __func__, cmd[0], cmd[1], cmd[2], cmd[3]);*/ + break; + + default: + E("%s: input length fault,len = %d!\n", __func__, len); + } +} + +void himax_mcu_in_cmd_init(void) +{ + I("%s: Entering!\n", __func__); +#ifdef CORE_IC + himax_in_parse_assign_cmd(ic_adr_ahb_addr_byte_0, pic_op->addr_ahb_addr_byte_0, sizeof(pic_op->addr_ahb_addr_byte_0)); + himax_in_parse_assign_cmd(ic_adr_ahb_rdata_byte_0, pic_op->addr_ahb_rdata_byte_0, sizeof(pic_op->addr_ahb_rdata_byte_0)); + himax_in_parse_assign_cmd(ic_adr_ahb_access_direction, pic_op->addr_ahb_access_direction, sizeof(pic_op->addr_ahb_access_direction)); + himax_in_parse_assign_cmd(ic_adr_conti, pic_op->addr_conti, sizeof(pic_op->addr_conti)); + himax_in_parse_assign_cmd(ic_adr_incr4, pic_op->addr_incr4, sizeof(pic_op->addr_incr4)); + himax_in_parse_assign_cmd(ic_adr_i2c_psw_lb, pic_op->adr_i2c_psw_lb, sizeof(pic_op->adr_i2c_psw_lb)); + himax_in_parse_assign_cmd(ic_adr_i2c_psw_ub, pic_op->adr_i2c_psw_ub, sizeof(pic_op->adr_i2c_psw_ub)); + himax_in_parse_assign_cmd(ic_cmd_ahb_access_direction_read, pic_op->data_ahb_access_direction_read, sizeof(pic_op->data_ahb_access_direction_read)); + himax_in_parse_assign_cmd(ic_cmd_conti, pic_op->data_conti, sizeof(pic_op->data_conti)); + himax_in_parse_assign_cmd(ic_cmd_incr4, pic_op->data_incr4, sizeof(pic_op->data_incr4)); + himax_in_parse_assign_cmd(ic_cmd_i2c_psw_lb, pic_op->data_i2c_psw_lb, sizeof(pic_op->data_i2c_psw_lb)); + himax_in_parse_assign_cmd(ic_cmd_i2c_psw_ub, pic_op->data_i2c_psw_ub, sizeof(pic_op->data_i2c_psw_ub)); + himax_in_parse_assign_cmd(ic_adr_tcon_on_rst, pic_op->addr_tcon_on_rst, sizeof(pic_op->addr_tcon_on_rst)); + himax_in_parse_assign_cmd(ic_addr_adc_on_rst, pic_op->addr_adc_on_rst, sizeof(pic_op->addr_adc_on_rst)); + himax_in_parse_assign_cmd(ic_adr_psl, pic_op->addr_psl, sizeof(pic_op->addr_psl)); + himax_in_parse_assign_cmd(ic_adr_cs_central_state, pic_op->addr_cs_central_state, sizeof(pic_op->addr_cs_central_state)); + himax_in_parse_assign_cmd(ic_cmd_rst, pic_op->data_rst, sizeof(pic_op->data_rst)); +#endif +#ifdef CORE_FW + himax_in_parse_assign_cmd(fw_addr_system_reset, pfw_op->addr_system_reset, sizeof(pfw_op->addr_system_reset)); + himax_in_parse_assign_cmd(fw_addr_safe_mode_release_pw, pfw_op->addr_safe_mode_release_pw, sizeof(pfw_op->addr_safe_mode_release_pw)); + himax_in_parse_assign_cmd(fw_addr_ctrl_fw, pfw_op->addr_ctrl_fw_isr, sizeof(pfw_op->addr_ctrl_fw_isr)); + himax_in_parse_assign_cmd(fw_addr_flag_reset_event, pfw_op->addr_flag_reset_event, sizeof(pfw_op->addr_flag_reset_event)); + himax_in_parse_assign_cmd(fw_addr_hsen_enable, pfw_op->addr_hsen_enable, sizeof(pfw_op->addr_hsen_enable)); + himax_in_parse_assign_cmd(fw_addr_smwp_enable, pfw_op->addr_smwp_enable, sizeof(pfw_op->addr_smwp_enable)); + himax_in_parse_assign_cmd(fw_addr_program_reload_from, pfw_op->addr_program_reload_from, sizeof(pfw_op->addr_program_reload_from)); + himax_in_parse_assign_cmd(fw_addr_program_reload_to, pfw_op->addr_program_reload_to, sizeof(pfw_op->addr_program_reload_to)); + himax_in_parse_assign_cmd(fw_addr_program_reload_page_write, pfw_op->addr_program_reload_page_write, sizeof(pfw_op->addr_program_reload_page_write)); + himax_in_parse_assign_cmd(fw_addr_raw_out_sel, pfw_op->addr_raw_out_sel, sizeof(pfw_op->addr_raw_out_sel)); + himax_in_parse_assign_cmd(fw_addr_reload_status, pfw_op->addr_reload_status, sizeof(pfw_op->addr_reload_status)); + himax_in_parse_assign_cmd(fw_addr_reload_crc32_result, pfw_op->addr_reload_crc32_result, sizeof(pfw_op->addr_reload_crc32_result)); + himax_in_parse_assign_cmd(fw_addr_reload_addr_from, pfw_op->addr_reload_addr_from, sizeof(pfw_op->addr_reload_addr_from)); + himax_in_parse_assign_cmd(fw_addr_reload_addr_cmd_beat, pfw_op->addr_reload_addr_cmd_beat, sizeof(pfw_op->addr_reload_addr_cmd_beat)); + himax_in_parse_assign_cmd(fw_addr_selftest_addr_en, pfw_op->addr_selftest_addr_en, sizeof(pfw_op->addr_selftest_addr_en)); + himax_in_parse_assign_cmd(fw_addr_criteria_addr, pfw_op->addr_criteria_addr, sizeof(pfw_op->addr_criteria_addr)); + himax_in_parse_assign_cmd(fw_addr_set_frame_addr, pfw_op->addr_set_frame_addr, sizeof(pfw_op->addr_set_frame_addr)); + himax_in_parse_assign_cmd(fw_addr_selftest_result_addr, pfw_op->addr_selftest_result_addr, sizeof(pfw_op->addr_selftest_result_addr)); + himax_in_parse_assign_cmd(fw_addr_sorting_mode_en, pfw_op->addr_sorting_mode_en, sizeof(pfw_op->addr_sorting_mode_en)); + himax_in_parse_assign_cmd(fw_addr_fw_mode_status, pfw_op->addr_fw_mode_status, sizeof(pfw_op->addr_fw_mode_status)); + himax_in_parse_assign_cmd(fw_addr_icid_addr, pfw_op->addr_icid_addr, sizeof(pfw_op->addr_icid_addr)); + himax_in_parse_assign_cmd(fw_addr_trigger_addr, pfw_op->addr_trigger_addr, sizeof(pfw_op->addr_trigger_addr)); + himax_in_parse_assign_cmd(fw_addr_fw_ver_addr, pfw_op->addr_fw_ver_addr, sizeof(pfw_op->addr_fw_ver_addr)); + himax_in_parse_assign_cmd(fw_addr_fw_cfg_addr, pfw_op->addr_fw_cfg_addr, sizeof(pfw_op->addr_fw_cfg_addr)); + himax_in_parse_assign_cmd(fw_addr_fw_vendor_addr, pfw_op->addr_fw_vendor_addr, sizeof(pfw_op->addr_fw_vendor_addr)); + himax_in_parse_assign_cmd(fw_addr_fw_state_addr, pfw_op->addr_fw_state_addr, sizeof(pfw_op->addr_fw_state_addr)); + himax_in_parse_assign_cmd(fw_addr_fw_dbg_msg_addr, pfw_op->addr_fw_dbg_msg_addr, sizeof(pfw_op->addr_fw_dbg_msg_addr)); + himax_in_parse_assign_cmd(fw_addr_chk_fw_status, pfw_op->addr_chk_fw_status, sizeof(pfw_op->addr_chk_fw_status)); + himax_in_parse_assign_cmd(fw_addr_dd_handshak_addr, pfw_op->addr_dd_handshak_addr, sizeof(pfw_op->addr_dd_handshak_addr)); + himax_in_parse_assign_cmd(fw_addr_dd_data_addr, pfw_op->addr_dd_data_addr, sizeof(pfw_op->addr_dd_data_addr)); + himax_in_parse_assign_cmd(fw_data_system_reset, pfw_op->data_system_reset, sizeof(pfw_op->data_system_reset)); + himax_in_parse_assign_cmd(fw_data_safe_mode_release_pw_active, pfw_op->data_safe_mode_release_pw_active, sizeof(pfw_op->data_safe_mode_release_pw_active)); + himax_in_parse_assign_cmd(fw_data_clear, pfw_op->data_clear, sizeof(pfw_op->data_clear)); + himax_in_parse_assign_cmd(fw_data_safe_mode_release_pw_reset, pfw_op->data_safe_mode_release_pw_reset, sizeof(pfw_op->data_safe_mode_release_pw_reset)); + himax_in_parse_assign_cmd(fw_data_program_reload_start, pfw_op->data_program_reload_start, sizeof(pfw_op->data_program_reload_start)); + himax_in_parse_assign_cmd(fw_data_program_reload_compare, pfw_op->data_program_reload_compare, sizeof(pfw_op->data_program_reload_compare)); + himax_in_parse_assign_cmd(fw_data_program_reload_break, pfw_op->data_program_reload_break, sizeof(pfw_op->data_program_reload_break)); + himax_in_parse_assign_cmd(fw_data_selftest_request, pfw_op->data_selftest_request, sizeof(pfw_op->data_selftest_request)); + himax_in_parse_assign_cmd(fw_data_criteria_aa_top, pfw_op->data_criteria_aa_top, sizeof(pfw_op->data_criteria_aa_top)); + himax_in_parse_assign_cmd(fw_data_criteria_aa_bot, pfw_op->data_criteria_aa_bot, sizeof(pfw_op->data_criteria_aa_bot)); + himax_in_parse_assign_cmd(fw_data_criteria_key_top, pfw_op->data_criteria_key_top, sizeof(pfw_op->data_criteria_key_top)); + himax_in_parse_assign_cmd(fw_data_criteria_key_bot, pfw_op->data_criteria_key_bot, sizeof(pfw_op->data_criteria_key_bot)); + himax_in_parse_assign_cmd(fw_data_criteria_avg_top, pfw_op->data_criteria_avg_top, sizeof(pfw_op->data_criteria_avg_top)); + himax_in_parse_assign_cmd(fw_data_criteria_avg_bot, pfw_op->data_criteria_avg_bot, sizeof(pfw_op->data_criteria_avg_bot)); + himax_in_parse_assign_cmd(fw_data_set_frame, pfw_op->data_set_frame, sizeof(pfw_op->data_set_frame)); + himax_in_parse_assign_cmd(fw_data_selftest_ack_hb, pfw_op->data_selftest_ack_hb, sizeof(pfw_op->data_selftest_ack_hb)); + himax_in_parse_assign_cmd(fw_data_selftest_ack_lb, pfw_op->data_selftest_ack_lb, sizeof(pfw_op->data_selftest_ack_lb)); + himax_in_parse_assign_cmd(fw_data_selftest_pass, pfw_op->data_selftest_pass, sizeof(pfw_op->data_selftest_pass)); + himax_in_parse_assign_cmd(fw_data_normal_cmd, pfw_op->data_normal_cmd, sizeof(pfw_op->data_normal_cmd)); + himax_in_parse_assign_cmd(fw_data_normal_status, pfw_op->data_normal_status, sizeof(pfw_op->data_normal_status)); + himax_in_parse_assign_cmd(fw_data_sorting_cmd, pfw_op->data_sorting_cmd, sizeof(pfw_op->data_sorting_cmd)); + himax_in_parse_assign_cmd(fw_data_sorting_status, pfw_op->data_sorting_status, sizeof(pfw_op->data_sorting_status)); + himax_in_parse_assign_cmd(fw_data_dd_request, pfw_op->data_dd_request, sizeof(pfw_op->data_dd_request)); + himax_in_parse_assign_cmd(fw_data_dd_ack, pfw_op->data_dd_ack, sizeof(pfw_op->data_dd_ack)); + himax_in_parse_assign_cmd(fw_data_idle_dis_pwd, pfw_op->data_idle_dis_pwd, sizeof(pfw_op->data_idle_dis_pwd)); + himax_in_parse_assign_cmd(fw_data_idle_en_pwd, pfw_op->data_idle_en_pwd, sizeof(pfw_op->data_idle_en_pwd)); + himax_in_parse_assign_cmd(fw_data_rawdata_ready_hb, pfw_op->data_rawdata_ready_hb, sizeof(pfw_op->data_rawdata_ready_hb)); + himax_in_parse_assign_cmd(fw_data_rawdata_ready_lb, pfw_op->data_rawdata_ready_lb, sizeof(pfw_op->data_rawdata_ready_lb)); + himax_in_parse_assign_cmd(fw_addr_ahb_addr, pfw_op->addr_ahb_addr, sizeof(pfw_op->addr_ahb_addr)); + himax_in_parse_assign_cmd(fw_data_ahb_dis, pfw_op->data_ahb_dis, sizeof(pfw_op->data_ahb_dis)); + himax_in_parse_assign_cmd(fw_data_ahb_en, pfw_op->data_ahb_en, sizeof(pfw_op->data_ahb_en)); + himax_in_parse_assign_cmd(fw_addr_event_addr, pfw_op->addr_event_addr, sizeof(pfw_op->addr_event_addr)); + himax_in_parse_assign_cmd(fw_usb_detect_addr, pfw_op->addr_usb_detect, sizeof(pfw_op->addr_usb_detect)); +#endif +#ifdef CORE_FLASH + himax_in_parse_assign_cmd(flash_addr_spi200_trans_fmt, pflash_op->addr_spi200_trans_fmt, sizeof(pflash_op->addr_spi200_trans_fmt)); + himax_in_parse_assign_cmd(flash_addr_spi200_trans_ctrl, pflash_op->addr_spi200_trans_ctrl, sizeof(pflash_op->addr_spi200_trans_ctrl)); + himax_in_parse_assign_cmd(flash_addr_spi200_cmd, pflash_op->addr_spi200_cmd, sizeof(pflash_op->addr_spi200_cmd)); + himax_in_parse_assign_cmd(flash_addr_spi200_addr, pflash_op->addr_spi200_addr, sizeof(pflash_op->addr_spi200_addr)); + himax_in_parse_assign_cmd(flash_addr_spi200_data, pflash_op->addr_spi200_data, sizeof(pflash_op->addr_spi200_data)); + himax_in_parse_assign_cmd(flash_addr_spi200_bt_num, pflash_op->addr_spi200_bt_num, sizeof(pflash_op->addr_spi200_bt_num)); + himax_in_parse_assign_cmd(flash_data_spi200_trans_fmt, pflash_op->data_spi200_trans_fmt, sizeof(pflash_op->data_spi200_trans_fmt)); + himax_in_parse_assign_cmd(flash_data_spi200_trans_ctrl_1, pflash_op->data_spi200_trans_ctrl_1, sizeof(pflash_op->data_spi200_trans_ctrl_1)); + himax_in_parse_assign_cmd(flash_data_spi200_trans_ctrl_2, pflash_op->data_spi200_trans_ctrl_2, sizeof(pflash_op->data_spi200_trans_ctrl_2)); + himax_in_parse_assign_cmd(flash_data_spi200_trans_ctrl_3, pflash_op->data_spi200_trans_ctrl_3, sizeof(pflash_op->data_spi200_trans_ctrl_3)); + himax_in_parse_assign_cmd(flash_data_spi200_trans_ctrl_4, pflash_op->data_spi200_trans_ctrl_4, sizeof(pflash_op->data_spi200_trans_ctrl_4)); + himax_in_parse_assign_cmd(flash_data_spi200_trans_ctrl_5, pflash_op->data_spi200_trans_ctrl_5, sizeof(pflash_op->data_spi200_trans_ctrl_5)); + himax_in_parse_assign_cmd(flash_data_spi200_cmd_1, pflash_op->data_spi200_cmd_1, sizeof(pflash_op->data_spi200_cmd_1)); + himax_in_parse_assign_cmd(flash_data_spi200_cmd_2, pflash_op->data_spi200_cmd_2, sizeof(pflash_op->data_spi200_cmd_2)); + himax_in_parse_assign_cmd(flash_data_spi200_cmd_3, pflash_op->data_spi200_cmd_3, sizeof(pflash_op->data_spi200_cmd_3)); + himax_in_parse_assign_cmd(flash_data_spi200_cmd_4, pflash_op->data_spi200_cmd_4, sizeof(pflash_op->data_spi200_cmd_4)); + himax_in_parse_assign_cmd(flash_data_spi200_cmd_5, pflash_op->data_spi200_cmd_5, sizeof(pflash_op->data_spi200_cmd_5)); + himax_in_parse_assign_cmd(flash_data_spi200_cmd_6, pflash_op->data_spi200_cmd_6, sizeof(pflash_op->data_spi200_cmd_6)); + himax_in_parse_assign_cmd(flash_data_spi200_cmd_7, pflash_op->data_spi200_cmd_7, sizeof(pflash_op->data_spi200_cmd_7)); + himax_in_parse_assign_cmd(flash_data_spi200_addr, pflash_op->data_spi200_addr, sizeof(pflash_op->data_spi200_addr)); +#endif +#ifdef CORE_SRAM + /* sram start*/ + himax_in_parse_assign_cmd(sram_adr_mkey, psram_op->addr_mkey, sizeof(psram_op->addr_mkey)); + himax_in_parse_assign_cmd(sram_adr_rawdata_addr, psram_op->addr_rawdata_addr, sizeof(psram_op->addr_rawdata_addr)); + himax_in_parse_assign_cmd(sram_adr_rawdata_end, psram_op->addr_rawdata_end, sizeof(psram_op->addr_rawdata_end)); + himax_in_parse_assign_cmd(sram_cmd_conti, psram_op->data_conti, sizeof(psram_op->data_conti)); + himax_in_parse_assign_cmd(sram_cmd_fin, psram_op->data_fin, sizeof(psram_op->data_fin)); + himax_in_parse_assign_cmd(sram_passwrd_start, psram_op->passwrd_start, sizeof(psram_op->passwrd_start)); + himax_in_parse_assign_cmd(sram_passwrd_end, psram_op->passwrd_end, sizeof(psram_op->passwrd_end)); + /* sram end*/ +#endif +#ifdef CORE_DRIVER + himax_in_parse_assign_cmd(driver_addr_fw_define_flash_reload, pdriver_op->addr_fw_define_flash_reload, sizeof(pdriver_op->addr_fw_define_flash_reload)); + himax_in_parse_assign_cmd(driver_addr_fw_define_2nd_flash_reload, pdriver_op->addr_fw_define_2nd_flash_reload, sizeof(pdriver_op->addr_fw_define_2nd_flash_reload)); + himax_in_parse_assign_cmd(driver_addr_fw_define_int_is_edge, pdriver_op->addr_fw_define_int_is_edge, sizeof(pdriver_op->addr_fw_define_int_is_edge)); + himax_in_parse_assign_cmd(driver_addr_fw_define_rxnum_txnum_maxpt, pdriver_op->addr_fw_define_rxnum_txnum_maxpt, sizeof(pdriver_op->addr_fw_define_rxnum_txnum_maxpt)); + himax_in_parse_assign_cmd(driver_addr_fw_define_xy_res_enable, pdriver_op->addr_fw_define_xy_res_enable, sizeof(pdriver_op->addr_fw_define_xy_res_enable)); + himax_in_parse_assign_cmd(driver_addr_fw_define_x_y_res, pdriver_op->addr_fw_define_x_y_res, sizeof(pdriver_op->addr_fw_define_x_y_res)); + himax_in_parse_assign_cmd(driver_data_fw_define_flash_reload_dis, pdriver_op->data_fw_define_flash_reload_dis, sizeof(pdriver_op->data_fw_define_flash_reload_dis)); + himax_in_parse_assign_cmd(driver_data_fw_define_flash_reload_en, pdriver_op->data_fw_define_flash_reload_en, sizeof(pdriver_op->data_fw_define_flash_reload_en)); + himax_in_parse_assign_cmd(driver_data_fw_define_rxnum_txnum_maxpt_sorting, pdriver_op->data_fw_define_rxnum_txnum_maxpt_sorting, sizeof(pdriver_op->data_fw_define_rxnum_txnum_maxpt_sorting)); + himax_in_parse_assign_cmd(driver_data_fw_define_rxnum_txnum_maxpt_normal, pdriver_op->data_fw_define_rxnum_txnum_maxpt_normal, sizeof(pdriver_op->data_fw_define_rxnum_txnum_maxpt_normal)); +#endif +#ifdef HX_ZERO_FLASH + himax_in_parse_assign_cmd(zf_addr_dis_flash_reload, pzf_op->addr_dis_flash_reload, sizeof(pzf_op->addr_dis_flash_reload)); + himax_in_parse_assign_cmd(zf_data_dis_flash_reload, pzf_op->data_dis_flash_reload, sizeof(pzf_op->data_dis_flash_reload)); + himax_in_parse_assign_cmd(zf_addr_system_reset, pzf_op->addr_system_reset, sizeof(pzf_op->addr_system_reset)); + himax_in_parse_assign_cmd(zf_data_system_reset, pzf_op->data_system_reset, sizeof(pzf_op->data_system_reset)); + himax_in_parse_assign_cmd(zf_data_sram_start_addr, pzf_op->data_sram_start_addr, sizeof(pzf_op->data_sram_start_addr)); + himax_in_parse_assign_cmd(zf_data_sram_clean, pzf_op->data_sram_clean, sizeof(pzf_op->data_sram_clean)); + himax_in_parse_assign_cmd(zf_data_cfg_info, pzf_op->data_cfg_info, sizeof(pzf_op->data_cfg_info)); + himax_in_parse_assign_cmd(zf_data_fw_cfg_1, pzf_op->data_fw_cfg_1, sizeof(pzf_op->data_fw_cfg_1)); + himax_in_parse_assign_cmd(zf_data_fw_cfg_2, pzf_op->data_fw_cfg_2, sizeof(pzf_op->data_fw_cfg_2)); + himax_in_parse_assign_cmd(zf_data_fw_cfg_2, pzf_op->data_fw_cfg_3, sizeof(pzf_op->data_fw_cfg_3)); + himax_in_parse_assign_cmd(zf_data_adc_cfg_1, pzf_op->data_adc_cfg_1, sizeof(pzf_op->data_adc_cfg_1)); + himax_in_parse_assign_cmd(zf_data_adc_cfg_2, pzf_op->data_adc_cfg_2, sizeof(pzf_op->data_adc_cfg_2)); + himax_in_parse_assign_cmd(zf_data_adc_cfg_3, pzf_op->data_adc_cfg_3, sizeof(pzf_op->data_adc_cfg_3)); + himax_in_parse_assign_cmd(zf_data_map_table, pzf_op->data_map_table, sizeof(pzf_op->data_map_table)); + himax_in_parse_assign_cmd(zf_data_mode_switch, pzf_op->data_mode_switch, sizeof(pzf_op->data_mode_switch)); + himax_in_parse_assign_cmd(zf_addr_sts_chk, pzf_op->addr_sts_chk, sizeof(pzf_op->addr_sts_chk)); + himax_in_parse_assign_cmd(zf_data_activ_sts, pzf_op->data_activ_sts, sizeof(pzf_op->data_activ_sts)); + himax_in_parse_assign_cmd(zf_addr_activ_relod, pzf_op->addr_activ_relod, sizeof(pzf_op->addr_activ_relod)); + himax_in_parse_assign_cmd(zf_data_activ_in, pzf_op->data_activ_in, sizeof(pzf_op->data_activ_in)); +#endif +} + +/* init end*/ +#endif diff --git a/drivers/input/touchscreen/himax_mmi/himax_inspection.c b/drivers/input/touchscreen/himax_mmi/himax_inspection.c new file mode 100644 index 000000000000..89caff07ca71 --- /dev/null +++ b/drivers/input/touchscreen/himax_mmi/himax_inspection.c @@ -0,0 +1,1250 @@ +#include "himax_inspection.h" + +extern struct himax_core_fp g_core_fp; +extern struct himax_ts_data *private_ts; +extern struct himax_ic_data *ic_data; + +void himax_inspection_init(void); + +void (*fp_himax_self_test_init)(void) = himax_inspection_init; + +#ifdef HX_ESD_RECOVERY + extern u8 HX_ESD_RESET_ACTIVATE; +#endif + +#ifdef HX_INSPECT_LPWUG_TEST +static void himax_press_powerkey(void) +{ + I(" %s POWER KEY event %x press\n", __func__, KEY_POWER); + input_report_key(private_ts->input_dev, KEY_POWER, 1); + input_sync(private_ts->input_dev); + + I(" %s POWER KEY event %x release\n", __func__, KEY_POWER); + input_report_key(private_ts->input_dev, KEY_POWER, 0); + input_sync(private_ts->input_dev); +} +#endif +static uint8_t NOISEMAX; + +#if 0 +static int hx_test_data_pop_out(char *rslt_buf, char *filepath) +{ + + struct file *raw_file = NULL; + struct filename *vts_name = NULL; + mm_segment_t fs; + loff_t pos = 0; + int ret_val = NO_ERR; + I("%s: Entering!\n", __func__); + I("data size=0x%04X\n", (uint32_t)strlen(rslt_buf)); + vts_name = getname_kernel(filepath); + + raw_file = file_open_name(vts_name, O_TRUNC|O_CREAT|O_RDWR, 0660); + if (IS_ERR(raw_file)) { + E("%s open file failed = %ld\n", __func__, PTR_ERR(raw_file)); + ret_val = -EIO; + goto SAVE_DATA_ERR; + } + + fs = get_fs(); + set_fs(get_ds()); + vfs_write(raw_file, rslt_buf, 0x1000 * HX_CRITERIA_ITEM * sizeof(char), &pos); + if (raw_file != NULL) { + filp_close(raw_file, NULL); + } + set_fs(fs); + +SAVE_DATA_ERR: + I("%s: End!\n", __func__); + return ret_val; +} +#endif + +static int hx_test_data_get(uint32_t RAW[], char *start_log, char *result, int now_item) +{ + uint32_t i; + + ssize_t len = 0; + char *testdata = NULL; + uint32_t SZ_SIZE = 0x1000; + + I("%s: Entering, Now type=%s!\n", __func__, g_himax_inspection_mode[now_item]); + + testdata = kzalloc(sizeof(char) * SZ_SIZE, GFP_KERNEL); + + len += snprintf((testdata + len), SZ_SIZE - len, "%s", start_log); + for (i = 0 ; i < ic_data->HX_TX_NUM * ic_data->HX_RX_NUM ; i++) { + if (i > 1 && ((i + 1) % ic_data->HX_RX_NUM) == 0) { + len += snprintf((testdata + len), SZ_SIZE - len, "%5d,\n", RAW[i]); + } else { + len += snprintf((testdata + len), SZ_SIZE - len, "%5d,", RAW[i]); + } + } + len += snprintf((testdata + len), SZ_SIZE - len, "\n%s", result); + + memcpy(&g_rslt_data[g_rslt_data_len], testdata, len); + g_rslt_data_len += len; + I("%s: g_rslt_data_len=%d!\n", __func__, g_rslt_data_len); + + /*memcpy(&g_rslt_data[now_item * SZ_SIZE], testdata, SZ_SIZE);*/ + /* dbg */ + /*for(i = 0; i < SZ_SIZE; i++) + { + I("0x%04X, ", g_rslt_data[i + (now_item * SZ_SIZE)]); + if (i > 0 && (i % 16 == 15)) + printk("\n"); + }*/ + + kfree(testdata); + I("%s: End!\n", __func__); + return NO_ERR; + +} + +static int himax_switch_mode_inspection(int mode) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + I("%s: Entering\n", __func__); + + /*Stop Handshaking*/ + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; + g_core_fp.fp_flash_write_burst_lenth(tmp_addr, tmp_data, 4); + + /*Swtich Mode*/ + switch (mode) { + case HIMAX_INSPECTION_SORTING: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_SORTING_START; tmp_data[0] = PWD_SORTING_START; + break; + case HIMAX_INSPECTION_OPEN: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_OPEN_START; tmp_data[0] = PWD_OPEN_START; + break; + case HIMAX_INSPECTION_MICRO_OPEN: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_OPEN_START; tmp_data[0] = PWD_OPEN_START; + break; + case HIMAX_INSPECTION_SHORT: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_SHORT_START; tmp_data[0] = PWD_SHORT_START; + break; +#ifdef HX_GAP_TEST + case HIMAX_INSPECTION_GAPTEST_RAW: +#endif + case HIMAX_INSPECTION_RAWDATA: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_RAWDATA_START; tmp_data[0] = PWD_RAWDATA_START; + break; + case HIMAX_INSPECTION_NOISE: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_NOISE_START; tmp_data[0] = PWD_NOISE_START; + break; +#ifdef HX_ACT_IDLE_TEST + case HIMAX_INSPECTION_ACT_IDLE_RAWDATA: + case HIMAX_INSPECTION_ACT_IDLE_NOISE: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_ACT_IDLE_START; tmp_data[0] = PWD_ACT_IDLE_START; + break; +#endif +#ifdef HX_INSPECT_LPWUG_TEST + case HIMAX_INSPECTION_LPWUG_RAWDATA: + case HIMAX_INSPECTION_LPWUG_NOISE: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_LPWUG_START; tmp_data[0] = PWD_LPWUG_START; + break; + case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: + case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = PWD_LPWUG_IDLE_START; tmp_data[0] = PWD_LPWUG_IDLE_START; + break; +#endif + default: + I("%s,Nothing to be done!\n", __func__); + break; + } + + if (g_core_fp.fp_assign_sorting_mode != NULL) + g_core_fp.fp_assign_sorting_mode(tmp_data); + I("%s: End of setting!\n", __func__); + + return 0; + +} + +static int himax_get_rawdata(uint32_t RAW[], uint32_t datalen) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t *tmp_rawdata; + uint8_t retry = 0; + uint16_t checksum_cal; + uint32_t i = 0; + + uint8_t max_i2c_size = 128; + int address = 0; + int total_read_times = 0; + int total_size = datalen * 2 + 4; + int total_size_temp; +#if 1 + uint32_t j = 0; + uint32_t index = 0; + uint32_t Min_DATA = 0xFFFFFFFF; + uint32_t Max_DATA = 0x00000000; +#endif + + tmp_rawdata = kzalloc(sizeof(uint8_t) * (datalen * 2), GFP_KERNEL); + + /*1 Set Data Ready PWD*/ + while (retry < 300) { + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; tmp_data[2] = 0x00; + tmp_data[1] = Data_PWD1; + tmp_data[0] = Data_PWD0; + g_core_fp.fp_flash_write_burst_lenth(tmp_addr, tmp_data, 4); + + g_core_fp.fp_register_read(tmp_addr, 4, tmp_data, false); + if ((tmp_data[0] == Data_PWD0 && tmp_data[1] == Data_PWD1) || + (tmp_data[0] == Data_PWD1 && tmp_data[1] == Data_PWD0)) { + break; + } + + retry++; + msleep(1); + } + + if (retry >= 200) { + kfree(tmp_rawdata); + return 1; + } else { + retry = 0; + } + + while (retry < 200) { + if (tmp_data[0] == Data_PWD1 && tmp_data[1] == Data_PWD0) { + break; + } + + retry++; + msleep(1); + g_core_fp.fp_register_read(tmp_addr, 4, tmp_data, false); + } + + if (retry >= 200) { + kfree(tmp_rawdata); + return 1; + } else { + retry = 0; + } + + /*2 Read Data from SRAM*/ + while (retry < 10) { + checksum_cal = 0; + total_size_temp = total_size; + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00; + + if (total_size % max_i2c_size == 0) { + total_read_times = total_size / max_i2c_size; + } else { + total_read_times = total_size / max_i2c_size + 1; + } + + for (i = 0 ; i < (total_read_times) ; i++) { + if (total_size_temp >= max_i2c_size) { + g_core_fp.fp_register_read(tmp_addr, max_i2c_size, &tmp_rawdata[i*max_i2c_size], false); + total_size_temp = total_size_temp - max_i2c_size; + } else { + /*I("last total_size_temp=%d\n", total_size_temp);*/ + g_core_fp.fp_register_read(tmp_addr, total_size_temp % max_i2c_size, &tmp_rawdata[i*max_i2c_size], false); + } + + address = ((i+1)*max_i2c_size); + tmp_addr[1] = (uint8_t)((address>>8)&0x00FF); + tmp_addr[0] = (uint8_t)((address)&0x00FF); + } + + /*3 Check Checksum*/ + for (i = 2 ; i < datalen * 2 + 4 ; i = i + 2) { + checksum_cal += tmp_rawdata[i + 1] * 256 + tmp_rawdata[i]; + } + + if (checksum_cal == 0) { + break; + } + + retry++; + } + + if (checksum_cal != 0) { + E("%s: Get rawdata checksum fail!\n", __func__); + kfree(tmp_rawdata); + return HX_CHKSUM_FAIL; + } + + /*4 Copy Data*/ + for (i = 0 ; i < ic_data->HX_TX_NUM * ic_data->HX_RX_NUM ; i++) { + RAW[i] = tmp_rawdata[(i * 2) + 1 + 4] * 256 + tmp_rawdata[(i * 2) + 4]; + } + +#if 1 + for (j = 0; j < ic_data->HX_RX_NUM; j++) { + if (j == 0) { + printk(" RX%2d", j + 1); + } else { + printk(" RX%2d", j + 1); + } + } + printk("\n"); + + for (i = 0 ; i < ic_data->HX_TX_NUM ; i++) { + printk("TX%2d", i + 1); + for (j = 0 ; j < ic_data->HX_RX_NUM ; j++) { + printk("%5d ", RAW[index]); + if (RAW[index] > Max_DATA) { + Max_DATA = RAW[index]; + } + if (RAW[index] < Min_DATA) { + Min_DATA = RAW[index]; + } + index++; + } + printk("\n"); + } + I("Max = %5d, Min = %5d \n", Max_DATA, Min_DATA); +#endif + + kfree(tmp_rawdata); + return HX_INSPECT_OK; +} + +static void himax_switch_data_type(uint8_t checktype) +{ + uint8_t datatype = 0x00; + + switch (checktype) { + case HIMAX_INSPECTION_SORTING: + datatype = DATA_SORTING; + break; + case HIMAX_INSPECTION_OPEN: + datatype = DATA_OPEN; + break; + case HIMAX_INSPECTION_MICRO_OPEN: + datatype = DATA_MICRO_OPEN; + break; + case HIMAX_INSPECTION_SHORT: + datatype = DATA_SHORT; + break; + case HIMAX_INSPECTION_RAWDATA: + datatype = DATA_RAWDATA; + break; + case HIMAX_INSPECTION_NOISE: + datatype = DATA_NOISE; + break; + case HIMAX_INSPECTION_BACK_NORMAL: + datatype = DATA_BACK_NORMAL; + break; +#ifdef HX_GAP_TEST + case HIMAX_INSPECTION_GAPTEST_RAW: + datatype = DATA_RAWDATA; + break; +#endif +#ifdef HX_ACT_IDLE_TEST + case HIMAX_INSPECTION_ACT_IDLE_RAWDATA: + datatype = DATA_ACT_IDLE_RAWDATA; + break; + case HIMAX_INSPECTION_ACT_IDLE_NOISE: + datatype = DATA_ACT_IDLE_NOISE; + break; +#endif +#ifdef HX_INSPECT_LPWUG_TEST + case HIMAX_INSPECTION_LPWUG_RAWDATA: + datatype = DATA_LPWUG_RAWDATA; + break; + case HIMAX_INSPECTION_LPWUG_NOISE: + datatype = DATA_LPWUG_NOISE; + break; + case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: + datatype = DATA_LPWUG_IDLE_RAWDATA; + break; + case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: + datatype = DATA_LPWUG_IDLE_NOISE; + break; +#endif + default: + E("Wrong type=%d\n", checktype); + break; + } + g_core_fp.fp_diag_register_set(datatype, 0x00); +} + +static void himax_set_N_frame(uint16_t Nframe, uint8_t checktype) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + /*IIR MAX*/ + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x72; tmp_addr[0] = 0x94; + tmp_data[3] = 0x00; tmp_data[2] = 0x00; + tmp_data[1] = (uint8_t)((Nframe & 0xFF00) >> 8); + tmp_data[0] = (uint8_t)(Nframe & 0x00FF); + g_core_fp.fp_flash_write_burst_lenth(tmp_addr, tmp_data, 4); + + /*skip frame*/ + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x70; tmp_addr[0] = 0xF4; + g_core_fp.fp_register_read(tmp_addr, 4, tmp_data, false); + + switch (checktype) { +#ifdef HX_ACT_IDLE_TEST + case HIMAX_INSPECTION_ACT_IDLE_RAWDATA: + case HIMAX_INSPECTION_ACT_IDLE_NOISE: + tmp_data[0] = BS_ACT_IDLE; + break; +#endif +#ifdef HX_INSPECT_LPWUG_TEST + case HIMAX_INSPECTION_LPWUG_RAWDATA: + case HIMAX_INSPECTION_LPWUG_NOISE: + tmp_data[0] = BS_LPWUG; + break; + case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: + case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: + tmp_data[0] = BS_LPWUG_dile; + break; +#endif + case HIMAX_INSPECTION_RAWDATA: + case HIMAX_INSPECTION_NOISE: + tmp_data[0] = BS_RAWDATANOISE; + break; + default: + tmp_data[0] = BS_OPENSHORT; + break; + } + g_core_fp.fp_flash_write_burst_lenth(tmp_addr, tmp_data, 4); +} + +static void himax_get_noise_base(void) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x70; tmp_addr[0] = 0x8C; + g_core_fp.fp_register_read(tmp_addr, 4, tmp_data, false); + + g_inspection_criteria[IDX_NOISEMAX][0] = tmp_data[3]; + I("%s: g_inspection_criteria[IDX_NOISEMAX]=%d\n", __func__, g_inspection_criteria[IDX_NOISEMAX][0]); +} + +static uint32_t himax_check_mode(uint8_t checktype) +{ + uint8_t tmp_data[4] = {0}; + uint8_t wait_pwd[2] = {0}; + + switch (checktype) { + case HIMAX_INSPECTION_SORTING: + wait_pwd[0] = PWD_SORTING_END; + wait_pwd[1] = PWD_SORTING_END; + break; + case HIMAX_INSPECTION_OPEN: + wait_pwd[0] = PWD_OPEN_END; + wait_pwd[1] = PWD_OPEN_END; + break; + case HIMAX_INSPECTION_MICRO_OPEN: + wait_pwd[0] = PWD_OPEN_END; + wait_pwd[1] = PWD_OPEN_END; + break; + case HIMAX_INSPECTION_SHORT: + wait_pwd[0] = PWD_SHORT_END; + wait_pwd[1] = PWD_SHORT_END; + break; + case HIMAX_INSPECTION_RAWDATA: + wait_pwd[0] = PWD_RAWDATA_END; + wait_pwd[1] = PWD_RAWDATA_END; + break; + case HIMAX_INSPECTION_NOISE: + wait_pwd[0] = PWD_NOISE_END; + wait_pwd[1] = PWD_NOISE_END; + break; +#ifdef HX_ACT_IDLE + case HIMAX_INSPECTION_ACT_IDLE_RAWDATA: + case HIMAX_INSPECTION_ACT_IDLE_NOISE: + wait_pwd[0] = PWD_ACT_IDLE_END; + wait_pwd[1] = PWD_ACT_IDLE_END; + break; +#endif +#ifdef HX_INSPECT_LPWUG_TEST + case HIMAX_INSPECTION_LPWUG_RAWDATA: + case HIMAX_INSPECTION_LPWUG_NOISE: + wait_pwd[0] = PWD_LPWUG_END; + wait_pwd[1] = PWD_LPWUG_END; + break; + case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: + case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: + wait_pwd[0] = PWD_LPWUG_IDLE_END; + wait_pwd[1] = PWD_LPWUG_IDLE_END; + break; +#endif + default: + E("Wrong type=%d\n", checktype); + break; + } + + if (g_core_fp.fp_check_sorting_mode != NULL) + g_core_fp.fp_check_sorting_mode(tmp_data); + + if ((wait_pwd[0] == tmp_data[0]) && (wait_pwd[1] == tmp_data[1])) { + I("Change to mode=%s\n", g_himax_inspection_mode[checktype]); + return 0; + } else { + return 1; + } +} + +static uint32_t himax_wait_sorting_mode(uint8_t checktype) +{ + uint8_t tmp_addr[4] = {0}; + uint8_t tmp_data[4] = {0}; + uint8_t wait_pwd[2] = {0}; + int count = 0; + + switch (checktype) { + case HIMAX_INSPECTION_SORTING: + wait_pwd[0] = PWD_SORTING_END; + wait_pwd[1] = PWD_SORTING_END; + break; + case HIMAX_INSPECTION_OPEN: + wait_pwd[0] = PWD_OPEN_END; + wait_pwd[1] = PWD_OPEN_END; + break; + case HIMAX_INSPECTION_MICRO_OPEN: + wait_pwd[0] = PWD_OPEN_END; + wait_pwd[1] = PWD_OPEN_END; + break; + case HIMAX_INSPECTION_SHORT: + wait_pwd[0] = PWD_SHORT_END; + wait_pwd[1] = PWD_SHORT_END; + break; + case HIMAX_INSPECTION_RAWDATA: + wait_pwd[0] = PWD_RAWDATA_END; + wait_pwd[1] = PWD_RAWDATA_END; + break; + case HIMAX_INSPECTION_NOISE: + wait_pwd[0] = PWD_NOISE_END; + wait_pwd[1] = PWD_NOISE_END; + break; +#ifdef HX_GAP_TEST + case HIMAX_INSPECTION_GAPTEST_RAW: + wait_pwd[0] = PWD_RAWDATA_END; + wait_pwd[1] = PWD_RAWDATA_END; + break; +#endif +#ifdef HX_ACT_IDLE_TEST + case HIMAX_INSPECTION_ACT_IDLE_RAWDATA: + case HIMAX_INSPECTION_ACT_IDLE_NOISE: + wait_pwd[0] = PWD_ACT_IDLE_END; + wait_pwd[1] = PWD_ACT_IDLE_END; + break; +#endif +#ifdef HX_INSPECT_LPWUG_TEST + case HIMAX_INSPECTION_LPWUG_RAWDATA: + case HIMAX_INSPECTION_LPWUG_NOISE: + wait_pwd[0] = PWD_LPWUG_END; + wait_pwd[1] = PWD_LPWUG_END; + break; + case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: + case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: + wait_pwd[0] = PWD_LPWUG_IDLE_END; + wait_pwd[1] = PWD_LPWUG_IDLE_END; + break; +#endif + default: + I("No Change Mode and now type=%d\n", checktype); + break; + } + + do { + if (g_core_fp.fp_check_sorting_mode != NULL) + g_core_fp.fp_check_sorting_mode(tmp_data); + if ((wait_pwd[0] == tmp_data[0]) && (wait_pwd[1] == tmp_data[1])) { + return 0; + } + + tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0xA8; + g_core_fp.fp_register_read(tmp_addr, 4, tmp_data, false); + I("%s: 0x900000A8, tmp_data[0]=%x,tmp_data[1]=%x,tmp_data[2]=%x,tmp_data[3]=%x \n", __func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]); + + tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0xE4; + g_core_fp.fp_register_read(tmp_addr, 4, tmp_data, false); + I("%s: 0x900000E4, tmp_data[0]=%x,tmp_data[1]=%x,tmp_data[2]=%x,tmp_data[3]=%x \n", __func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]); + + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x40; + g_core_fp.fp_register_read(tmp_addr, 4, tmp_data, false); + I("%s: 0x10007F40,tmp_data[0]=%x,tmp_data[1]=%x,tmp_data[2]=%x,tmp_data[3]=%x \n", __func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]); + I("Now retry %d times!\n", count++); + msleep(50); + } while (count < 50); + + return 1; +} +#if 0 +static int himax_check_notch(int index) +{ + if (SKIP_NOTCH_START < 0 && SKIP_NOTCH_END < 0 && SKIP_DUMMY_START < 0 && SKIP_DUMMY_START < 0) { + /* no support notch */ + return 0; + } + if ((index >= SKIP_NOTCH_START) && (index <= SKIP_NOTCH_END)) + return 1; + else if ((index >= SKIP_DUMMY_START) && (index <= SKIP_DUMMY_END)) + return 1; + else + return 0; +} +#endif +static uint32_t mpTestFunc(uint8_t checktype, uint32_t datalen) +{ + uint32_t i/*, j*/, ret = 0; + uint32_t RAW[datalen]; + char *rslt_log; + char *start_log; + int ret_val; + + /*uint16_t* pInspectGridData = &gInspectGridData[0];*/ + /*uint16_t* pInspectNoiseData = &gInspectNoiseData[0];*/ + I("Now Check type = %d\n", checktype); + + if (himax_check_mode(checktype)) { + I("Need Change Mode ,target=%s\n", g_himax_inspection_mode[checktype]); + + g_core_fp.fp_sense_off(); + +#ifndef HX_ZERO_FLASH + if (g_core_fp.fp_reload_disable != NULL) + g_core_fp.fp_reload_disable(1); +#endif + + himax_switch_mode_inspection(checktype); + + if (checktype == HIMAX_INSPECTION_NOISE) { + himax_set_N_frame(NOISEFRAME, checktype); + himax_get_noise_base(); +#ifdef HX_ACT_IDLE_TEST + } else if (checktype == HIMAX_INSPECTION_ACT_IDLE_RAWDATA || checktype == HIMAX_INSPECTION_ACT_IDLE_NOISE) { + I("N frame = %d\n", 10); + himax_set_N_frame(10, checktype); +#endif +#ifdef HX_INSPECT_LPWUG_TEST + } else if (checktype >= HIMAX_INSPECTION_LPWUG_RAWDATA) { + I("N frame = %d\n", 1); + himax_set_N_frame(1, checktype); +#endif + } else { + himax_set_N_frame(2, checktype); + } + + g_core_fp.fp_sense_on(1); + + ret = himax_wait_sorting_mode(checktype); + if (ret) { + E("%s: himax_wait_sorting_mode FAIL\n", __func__); + return ret; + } + } + + himax_switch_data_type(checktype); + + ret = himax_get_rawdata(RAW, datalen); + if (ret) { + E("%s: himax_get_rawdata FAIL\n", __func__); + return ret; + } + + /* back to normal */ + himax_switch_data_type(HIMAX_INSPECTION_BACK_NORMAL); + + I("%s: Init OK, start to test!\n", __func__); + rslt_log = kzalloc(256 * sizeof(char), GFP_KERNEL); + start_log = kzalloc(256 * sizeof(char), GFP_KERNEL); + + snprintf(start_log, 256 * sizeof(char), "\n%s%s\n", g_himax_inspection_mode[checktype], ": data as follow!\n"); + + /*Check Data*/ + switch (checktype) { + case HIMAX_INSPECTION_SORTING: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] < g_inspection_criteria[IDX_SORTMIN][i]) { + E("%s: sorting mode open test FAIL\n", __func__); + ret_val = HX_INSPECT_EOPEN; + goto FAIL_END; + } + } + I("%s: sorting mode open test PASS\n", __func__); + break; + case HIMAX_INSPECTION_OPEN: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_OPENMAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_OPENMIN][i]) { + E("%s: open test FAIL\n", __func__); + ret_val = HX_INSPECT_EOPEN; + goto FAIL_END; + } + } + I("%s: open test PASS\n", __func__); + break; + case HIMAX_INSPECTION_MICRO_OPEN: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_M_OPENMAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_M_OPENMIN][i]) { + E("%s: open test FAIL\n", __func__); + ret_val = HX_INSPECT_EMOPEN; + goto FAIL_END; + } + } + I("%s: open test PASS\n", __func__); + break; + case HIMAX_INSPECTION_SHORT: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_SHORTMAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_SHORTMIN][i]) { + E("%s: short test FAIL\n", __func__); + ret_val = HX_INSPECT_ESHORT; + goto FAIL_END; + } + } + I("%s: short test PASS\n", __func__); + break; + case HIMAX_INSPECTION_RAWDATA: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /* I("Now new compare, datalen=%d!\n",ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); */ + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_RAWMAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_RAWMIN][i]) { + E("%s: rawdata test FAIL:RAW[%d]=%d\n", __func__, i, RAW[i]); + I("%s: Now Criteria max=%d,min=%d\n", __func__, g_inspection_criteria[IDX_RAWMAX][i], g_inspection_criteria[IDX_RAWMIN][i]); + ret_val = HX_INSPECT_ERAW; + goto FAIL_END; + } + } + I("%s: rawdata test PASS\n", __func__); + break; + case HIMAX_INSPECTION_NOISE: + I("NOISEMAX=%d\n", NOISEMAX); + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_NOISEMAX][i]) { + I("g_inspection_criteria[IDX_NOISEMAX][%d]=%d\n", i, g_inspection_criteria[IDX_NOISEMAX][i]); + I("RAW[%d]=%d\n", i, RAW[i]); + E("%s: noise test FAIL\n", __func__); + ret_val = HX_INSPECT_ENOISE; + goto FAIL_END; + } + } + I("%s: noise test PASS\n", __func__); + break; +#ifdef HX_GAP_TEST + case HIMAX_INSPECTION_GAPTEST_RAW: + if (himax_gap_test_vertical_raw(HIMAX_INSPECTION_GAPTEST_RAW, RAW) != NO_ERR) { + E("%s: HIMAX_INSPECTION_GAPTEST_RAW FAIL\n", __func__); + ret_val = HX_INSPECT_EGAP_RAW; + goto FAIL_END; + } + if (himax_gap_test_honrizontal_raw(HIMAX_INSPECTION_GAPTEST_RAW, RAW) != NO_ERR) { + E("%s: HIMAX_INSPECTION_GAPTEST_RAW FAIL\n", __func__); + ret_val = HX_INSPECT_EGAP_RAW; + goto FAIL_END; + } + break; +#endif +#ifdef HX_ACT_IDLE_TEST + case HIMAX_INSPECTION_ACT_IDLE_RAWDATA: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_ACT_IDLE_RAWDATA_MAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_ACT_IDLE_RAWDATA_MIN][i]) { + E("%s: HIMAX_INSPECTION_ACT_IDLE_RAWDATA FAIL\n", __func__); + ret_val = HX_INSPECT_EACT_IDLE_RAW; + goto FAIL_END; + } + } + I("%s: HIMAX_INSPECTION_ACT_IDLE_RAWDATA PASS\n", __func__); + break; + case HIMAX_INSPECTION_ACT_IDLE_NOISE: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_ACT_IDLE_NOISE_MAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_ACT_IDLE_NOISE_MIN][i]) { + E("%s: HIMAX_INSPECTION_ACT_IDLE_NOISE FAIL\n", __func__); + ret_val = HX_INSPECT_EACT_IDLE_NOISE; + goto FAIL_END; + } + } + I("%s: HIMAX_INSPECTION_ACT_IDLE_NOISE PASS\n", __func__); + break; +#endif +#ifdef HX_INSPECT_LPWUG_TEST + case HIMAX_INSPECTION_LPWUG_RAWDATA: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_LPWUG_RAWDATA_MAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_LPWUG_RAWDATA_MIN][i]) { + E("%s: HIMAX_INSPECTION_LPWUG_RAWDATA FAIL\n", __func__); + ret_val = HX_INSPECT_ELPWUG_RAW; + goto FAIL_END; + } + } + I("%s: HIMAX_INSPECTION_LPWUG_RAWDATA PASS\n", __func__); + break; + case HIMAX_INSPECTION_LPWUG_NOISE: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_LPWUG_NOISE_MAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_LPWUG_NOISE_MIN][i]) { + E("%s: HIMAX_INSPECTION_LPWUG_NOISE FAIL\n", __func__); + ret_val = HX_INSPECT_ELPWUG_NOISE; + goto FAIL_END; + } + } + I("%s: HIMAX_INSPECTION_LPWUG_NOISE PASS\n", __func__); + break; + case HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA: + for (i = 0; i < (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM); i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_LPWUG_IDLE_RAWDATA_MAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_LPWUG_IDLE_RAWDATA_MIN][i]) { + E("%s: HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA FAIL\n", __func__); + ret_val = HX_INSPECT_ELPWUG_IDLE_RAW; + goto FAIL_END; + } + } + I("%s: HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA PASS\n", __func__); + break; + case HIMAX_INSPECTION_LPWUG_IDLE_NOISE: + for (i = 0 ; i < (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) ; i++) { + /*if (himax_check_notch(i)) { + continue; + }*/ + if ((int)RAW[i] > g_inspection_criteria[IDX_LPWUG_IDLE_NOISE_MAX][i] || (int)RAW[i] < g_inspection_criteria[IDX_LPWUG_IDLE_NOISE_MIN][i]) { + E("%s: HIMAX_INSPECTION_LPWUG_IDLE_NOISE FAIL\n", __func__); + ret_val = HX_INSPECT_ELPWUG_IDLE_NOISE; + goto FAIL_END; + } + } + I("%s: HIMAX_INSPECTION_LPWUG_IDLE_NOISE PASS\n", __func__); + break; +#endif + default: + E("Wrong type=%d\n", checktype); + break; + } + + ret_val = HX_INSPECT_OK; + snprintf(rslt_log, 256 * sizeof(char), "\n%s%s\n", g_himax_inspection_mode[checktype], " Test Pass!\n"); + I("pass write log\n"); + goto END_FUNC; + +FAIL_END: + snprintf(rslt_log, 256 * sizeof(char), "\n%s%s\n", g_himax_inspection_mode[checktype], " Test Fail!\n"); + I("fail write log\n"); +END_FUNC: + hx_test_data_get(RAW, start_log, rslt_log, checktype); + kfree(rslt_log); + return ret_val; +} + +/* parsing Criteria start */ +static int himax_get_criteria_size(void) +{ + int result = 0; + + result = HX_CRITERIA_SIZE; + + return result; +} + +/* claculate 10's power function */ +static int himax_power_cal(int pow, int number) +{ + int i = 0; + int result = 1; + + for (i = 0 ; i < pow ; i++) + result *= 10; + result = result * number; + + return result; + +} + +/* String to int */ +static int hiamx_parse_str2int(char *str) +{ + int i = 0; + int temp_cal = 0; + int result = 0; + int str_len = strlen(str); + int negtive_flag = 0; + for (i = 0; i < strlen(str) ; i++) { + if (str[i] == '-') { + negtive_flag = 1; + continue; + } + temp_cal = str[i] - '0'; + result += himax_power_cal(str_len-i-1, temp_cal); /* str's the lowest char is the number's the highest number + So we should reverse this number before using the power function + -1: starting number is from 0 ex:10^0 = 1,10^1=10*/ + } + + if (negtive_flag == 1) + result = 0 - result; + + return result; +} + +#if 0 +static int himax_count_comma(const struct firmware *file_entry) +{ + int i = 0; + int result = 0; + for (i = 0; i < file_entry->size; i++) { + if (file_entry->data[i] == ASCII_COMMA) + result++; + } + return result; +} +#endif + +/* Get sub-string from original string by using some charaters */ +static int himax_saperate_comma(const struct firmware *file_entry, char **result, int str_size) +{ + int count = 0; + int str_count = 0; /* now string*/ + int char_count = 0; /* now char count in string*/ + + do { + switch (file_entry->data[count]) { + case ASCII_COMMA: + case ACSII_SPACE: + case ASCII_CR: + case ASCII_LF: + count++; + /* If end of line as above condifiton, differencing the count of char. + If char_count != 0 it's meaning this string is parsing over . + The Next char is belong to next string */ + if (char_count != 0) { + char_count = 0; + str_count++; + } + break; + default: + result[str_count][char_count++] = file_entry->data[count]; + count++; + break; + } + } while (count < file_entry->size && str_count < str_size); + + return 0; +} + +static int hx_diff_str(char *str1, char *str2) +{ + int i = 0; + int err = -1; + int result = 0; /* zero is all same, non-zero is not same index*/ + int str1_len = strlen(str1); + int str2_len = strlen(str2); + if (str1_len != str2_len) { + I("%s:Size different!\n", __func__); + return err; + } + + for (i = 0 ; i < str1_len ; i++) { + if (str1[i] != str2[i]) { + result = i + 1; + I("%s: different in %d!\n", __func__ , result); + return result; + } + } + + return result; +} + +static int hx_get_crtra_by_name(char **result) +{ + int i = 0; + /* count of criteria type */ + int count_type = 0; + /* count of criteria data */ + int count_data = 0; + int err = HX_INSPECT_OK; + int crtra_count = himax_get_criteria_size(); + int all_mut_len = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM; + /* get criteria and assign to a global array(2-Dimensional/int) */ + for (i = 0 ; i < (crtra_count * (all_mut_len) + crtra_count) ; i++) { + /* It have get one page(all mutual) criteria data! + And we should skip the string of criteria name! + */ + if (i == 0 || i == ((i / (all_mut_len)) + (i / (all_mut_len) * (all_mut_len)))) { + count_data = 0; + /* change to next type */ + if (i != 0) + count_type++; + if (hx_diff_str(g_hx_inspt_crtra_name[count_type], result[i]) != 0) { + E("%s:Name Not match!\n", __func__); + E("can recognize[%d]=%s\n", count_type, g_hx_inspt_crtra_name[count_type]); + E("get from file[%d]=%s\n", i, result[i]); + E("Please check criteria file again!\n"); + err = HX_INSPECT_EFILE; + return err; + } + continue; + } + /* change string to int*/ + g_inspection_criteria[count_type][count_data] = hiamx_parse_str2int(result[i]); + /* dbg + I("[%d]g_inspection_criteria[%d][%d]=%d\n", i, count_type, count_data, g_inspection_criteria[count_type][count_data]); + */ + count_data++; + + } + + return err; +} + +static int himax_parse_criteria_file(void) +{ + int err = HX_INSPECT_OK; + const struct firmware *file_entry = NULL; + char *file_name = "hx_criteria.csv"; + char **result; + int i = 0; + + int crtra_count = himax_get_criteria_size(); + int data_size = 0; /* The maximum of number Data*/ + int all_mut_len = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM; + int str_max_len = 128; + int result_all_len = 0; + int file_size = 0; + + I("%s,Entering \n", __func__); + I("file name = %s\n", file_name); + + /* default path is /system/etc/firmware */ + err = request_firmware(&file_entry, file_name, private_ts->dev); + if (err < 0) { + E("%s,fail in line%d error code=%d\n", __func__, __LINE__, err); + err = HX_INSPECT_EFILE; + goto END_FUNC_REQ_FAIL; + } + + /* size of criteria include name string */ + data_size = ((all_mut_len) * crtra_count) + crtra_count; + + /* init the array which store original criteria and include name string*/ + result = kzalloc(data_size * sizeof(char *), GFP_KERNEL); + for (i = 0 ; i < data_size ; i++) + result[i] = kzalloc(str_max_len * sizeof(char), GFP_KERNEL); + + result_all_len = data_size; + file_size = file_entry->size; + I("Now result_all_len=%d\n", result_all_len); + I("Now file_size=%d\n", file_size); + + /* dbg */ + I("first 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n", file_entry->data[0], file_entry->data[1], file_entry->data[2], file_entry->data[3]); + + /* parse value in to result array(1-Dimensional/String) */ + himax_saperate_comma(file_entry, result, data_size); + + err = hx_get_crtra_by_name(result); + if (err != HX_INSPECT_OK) { + E("%s:Load criteria from file fail, go end!\n", __func__); + goto END_FUNC; + } + + /* for dbg + for (i = 0; i < (((ic_data->HX_TX_NUM*ic_data->HX_RX_NUM)*6)+6); i++) + { + if (i%32 ==0 && i >0) + I("\n"); + I("[%d]%s", i, result[i]); + }*/ +END_FUNC: + for (i = 0 ; i < data_size ; i++) + kfree(result[i]); + kfree(result); + release_firmware(file_entry); +END_FUNC_REQ_FAIL: + I("%s,END \n", __func__); + return err; +} +/* parsing Criteria end */ + +int himax_self_test_data_init(void) +{ + int ret = HX_INSPECT_OK; + int i = 0; + + g_inspection_criteria = kzalloc(sizeof(int *) * HX_CRITERIA_SIZE, GFP_KERNEL); + for (i = 0 ; i < HX_CRITERIA_SIZE ; i++) { + g_inspection_criteria[i] = kzalloc(sizeof(int) * (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM), GFP_KERNEL); + } + ret = himax_parse_criteria_file(); + + g_file_path = kzalloc(256 * sizeof(char), GFP_KERNEL); + /*memset(g_rslt_data, '\0', 0x1000 * HX_CRITERIA_ITEM * sizeof(char));*/ + snprintf(g_file_path, 256 * sizeof(char), "%s%s", HX_RSLT_OUT_PATH, HX_RSLT_OUT_FILE); + + return ret; +} + +static void himax_self_test_data_deinit(void) +{ + int i = 0; + + /*dbg*//* + for (i = 0; i < HX_CRITERIA_ITEM; i++) + I("%s:[%d]%d\n", __func__, i, g_inspection_criteria[i]);*/ + if (g_inspection_criteria != NULL) { + for (i = 0 ; i < HX_CRITERIA_SIZE ; i++) { + kfree(g_inspection_criteria[i]); + } + kfree(g_inspection_criteria); + I("Now it have free the g_inspection_criteria!\n"); + } else { + I("No Need to free g_inspection_criteria!\n"); + } + kfree(g_file_path); +} + +int himax_chip_self_test(void) +{ + uint32_t ret = HX_INSPECT_OK; + I("%s:IN\n", __func__); + + ret = himax_self_test_data_init(); + if (ret != HX_INSPECT_OK) { + E("himax_self_test_data_init fail!\n"); + goto END_FUNC; + } + + /*1. Open Test*/ + I("[MP_OPEN_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_OPEN, (ic_data->HX_TX_NUM*ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("1. Open Test: End %d\n\n\n", ret); + + /*2. Micro-Open Test*/ + I("[MP_MICRO_OPEN_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_MICRO_OPEN, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("2. Micro Open Test: End %d\n\n\n", ret); + + /*3. Short Test*/ + I("[MP_SHORT_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_SHORT, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("3. Short Test: End %d\n\n\n", ret); + + /*4. RawData Test*/ + I("==========================================\n"); + I("[MP_RAW_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_RAWDATA, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("%d. %s: End %d\n\n\n", HIMAX_INSPECTION_RAWDATA, g_himax_inspection_mode[HIMAX_INSPECTION_RAWDATA], ret); + + /*5. Noise Test*/ + I("[MP_NOISE_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_NOISE, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("5. Noise Test: End %d\n\n\n", ret); + +#ifdef HX_GAP_TEST + /*6. GAP Test*/ + I("[MP_GAP_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_GAPTEST_RAW, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("6. MP_GAP_TEST_RAW: End %d\n\n\n", ret); +#endif + +#ifdef HX_ACT_IDLE_TEST + /*7. ACT_IDLE RAWDATA*/ + I("[MP_ACT_IDLE_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_ACT_IDLE_RAWDATA, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("7. MP_ACT_IDLE_TEST_RAW: End %d\n\n\n", ret); + + /*8. ACT_IDLE NOISE*/ + I("[MP_ACT_IDLE_TEST_NOISE]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_ACT_IDLE_NOISE, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("8. MP_ACT_IDLE_TEST_NOISE: End %d\n\n\n", ret); +#endif +#ifdef HX_INSPECT_LPWUG_TEST + himax_press_powerkey(); + + /*9. LPWUG RAWDATA*/ + I("[MP_LPWUG_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_LPWUG_RAWDATA, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("9. MP_LPWUG_TEST_RAW: End %d\n\n\n", ret); + + /*10. LPWUG NOISE*/ + I("[MP_LPWUG_TEST_NOISE]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_LPWUG_NOISE, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("10. MP_LPWUG_TEST_NOISE: End %d\n\n\n", ret); + + /*11. LPWUG IDLE RAWDATA*/ + I("[MP_LPWUG_IDLE_TEST_RAW]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("11. MP_LPWUG_IDLE_TEST_RAW: End %d\n\n\n", ret); + + /*12. LPWUG IDLE RAWDATA*/ + I("[MP_LPWUG_IDLE_TEST_NOISE]\n"); + ret += mpTestFunc(HIMAX_INSPECTION_LPWUG_IDLE_NOISE, (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM) + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM); + I("12. MP_LPWUG_IDLE_TEST_NOISE: End %d\n\n\n", ret); + + himax_press_powerkey(); +#endif + /*hx_test_data_pop_out(g_rslt_data, g_file_path);*/ + g_core_fp.fp_sense_off(); + himax_set_N_frame(1, HIMAX_INSPECTION_NOISE); +#ifndef HX_ZERO_FLASH + if (g_core_fp.fp_reload_disable != NULL) + g_core_fp.fp_reload_disable(0); +#endif + g_core_fp.fp_sense_on(0); + +END_FUNC: + himax_self_test_data_deinit(); + + + I("thp_afe_inspect_OUT = %d \n", ret); + + if (ret != 0) + ret = 1; + + I("%s:OUT\n", __func__); + return ret; +} + +void himax_inspection_init(void) +{ + I("%s: enter, %d \n", __func__, __LINE__); + HX_CRITERIA_ITEM = 5; +#ifdef HX_GAP_TEST + HX_CRITERIA_ITEM += 1; +#endif +#ifdef HX_INSPECT_LPWUG_TEST + HX_CRITERIA_ITEM += 4; +#endif +#ifdef HX_ACT_IDLE_TEST + HX_CRITERIA_ITEM += 2; +#endif + /* Noise Just one criteria*/ + HX_CRITERIA_SIZE = HX_CRITERIA_ITEM * 2 - 1; + I("There is %d HX_CRITERIA_ITEM and %d HX_CRITERIA_SIZE\n", HX_CRITERIA_ITEM, HX_CRITERIA_SIZE); + + g_rslt_data = kzalloc(0x1000 * HX_CRITERIA_ITEM * sizeof(char), GFP_KERNEL); + + g_core_fp.fp_chip_self_test = himax_chip_self_test; + + return; +} diff --git a/drivers/input/touchscreen/himax_mmi/himax_inspection.h b/drivers/input/touchscreen/himax_mmi/himax_inspection.h new file mode 100644 index 000000000000..d8c318de7d9a --- /dev/null +++ b/drivers/input/touchscreen/himax_mmi/himax_inspection.h @@ -0,0 +1,238 @@ + +#include "himax_platform.h" +#include "himax_common.h" +#include "himax_ic_core.h" + +/*#define HX_GAP_TEST*/ +/*#define HX_INSPECT_LPWUG_TEST*/ +/*#define HX_ACT_IDLE_TEST*/ + +#define HX_RSLT_OUT_PATH "/sdcard/" +#define HX_RSLT_OUT_FILE "hx_test_result.txt" +char *g_file_path; +char *g_rslt_data; +uint32_t g_rslt_data_len = 0; + + +#define BS_RAWDATANOISE 10 +#define BS_OPENSHORT 0 + +#ifdef HX_INSPECT_LPWUG_TEST +#define BS_LPWUG 1 +#define BS_LPWUG_dile 1 +#endif + +#ifdef HX_ACT_IDLE_TEST +#define BS_ACT_IDLE 1 +#endif + +/* skip notch & dummy */ +#define SKIP_NOTCH_START 5 +#define SKIP_NOTCH_END 10 +/* TX+SKIP_NOTCH_START */ +#define SKIP_DUMMY_START 23 +/* TX+SKIP_NOTCH_END*/ +#define SKIP_DUMMY_END 28 + + +#define NOISEFRAME (BS_RAWDATANOISE+1) +#define UNIFMAX 500 + + +/*Himax MP Password*/ +#define PWD_OPEN_START 0x77 +#define PWD_OPEN_END 0x88 +#define PWD_SHORT_START 0x11 +#define PWD_SHORT_END 0x33 +#define PWD_RAWDATA_START 0x00 +#define PWD_RAWDATA_END 0x99 +#define PWD_NOISE_START 0x00 +#define PWD_NOISE_END 0x99 +#define PWD_SORTING_START 0xAA +#define PWD_SORTING_END 0xCC + +#ifdef HX_ACT_IDLE_TEST +#define PWD_ACT_IDLE_START 0x22 +#define PWD_ACT_IDLE_END 0x44 +#endif + +#ifdef HX_INSPECT_LPWUG_TEST +#define PWD_LPWUG_START 0x55 +#define PWD_LPWUG_END 0x66 + +#define PWD_LPWUG_IDLE_START 0x50 +#define PWD_LPWUG_IDLE_END 0x60 +#endif + +/*Himax DataType*/ +#define DATA_SORTING 0x0A +#define DATA_OPEN 0x0B +#define DATA_MICRO_OPEN 0x0C +#define DATA_SHORT 0x0A +#define DATA_RAWDATA 0x0A +#define DATA_NOISE 0x0F +#define DATA_BACK_NORMAL 0x00 +#define DATA_LPWUG_RAWDATA 0x0C +#define DATA_LPWUG_NOISE 0x0F +#define DATA_ACT_IDLE_RAWDATA 0x0A +#define DATA_ACT_IDLE_NOISE 0x0F +#define DATA_LPWUG_IDLE_RAWDATA 0x0A +#define DATA_LPWUG_IDLE_NOISE 0x0F + +/*Himax Data Ready Password*/ +#define Data_PWD0 0xA5 +#define Data_PWD1 0x5A + +/* ASCII format */ +#define ASCII_LF (0x0A) +#define ASCII_CR (0x0D) +#define ASCII_COMMA (0x2C) +#define ASCII_ZERO (0x30) +#define CHAR_EL '\0' +#define CHAR_NL '\n' +#define ACSII_SPACE (0x20) +/* INSOECTION Setting */ +int HX_CRITERIA_ITEM; +int HX_CRITERIA_SIZE; + +typedef enum { + HIMAX_INSPECTION_OPEN, + HIMAX_INSPECTION_MICRO_OPEN, + HIMAX_INSPECTION_SHORT, + HIMAX_INSPECTION_RAWDATA, + HIMAX_INSPECTION_NOISE, + HIMAX_INSPECTION_SORTING, + HIMAX_INSPECTION_BACK_NORMAL, +#ifdef HX_GAP_TEST + HIMAX_INSPECTION_GAPTEST_RAW, +#endif +#ifdef HX_ACT_IDLE_TEST + HIMAX_INSPECTION_ACT_IDLE_RAWDATA, + HIMAX_INSPECTION_ACT_IDLE_NOISE, +#endif +#ifdef HX_INSPECT_LPWUG_TEST + HIMAX_INSPECTION_LPWUG_RAWDATA, + HIMAX_INSPECTION_LPWUG_NOISE, + HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA, + HIMAX_INSPECTION_LPWUG_IDLE_NOISE, +#endif +} THP_INSPECTION_ENUM; + +char *g_himax_inspection_mode[] = { + "HIMAX_INSPECTION_OPEN", + "HIMAX_INSPECTION_MICRO_OPEN", + "HIMAX_INSPECTION_SHORT", + "HIMAX_INSPECTION_RAWDATA", + "HIMAX_INSPECTION_NOISE", + "HIMAX_INSPECTION_SORTING", + "HIMAX_INSPECTION_BACK_NORMAL", +#ifdef HX_GAP_TEST + "HIMAX_INSPECTION_GAPTEST_RAW", +#endif +#ifdef HX_ACT_IDLE_TEST + "HIMAX_INSPECTION_ACT_IDLE_RAWDATA", + "HIMAX_INSPECTION_ACT_IDLE_NOISE", +#endif +#ifdef HX_INSPECT_LPWUG_TEST + "HIMAX_INSPECTION_LPWUG_RAWDATA", + "HIMAX_INSPECTION_LPWUG_NOISE", + "HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA", + "HIMAX_INSPECTION_LPWUG_IDLE_NOISE", +#endif +}; + +/* for criteria */ +int **g_inspection_criteria; +char *g_hx_inspt_crtra_name[] = { + "CRITERIA_RAW_MIN", + "CRITERIA_RAW_MAX", + "CRITERIA_SHORT_MIN", + "CRITERIA_SHORT_MAX", + "CRITERIA_OPEN_MIN", + "CRITERIA_OPEN_MAX", + "CRITERIA_MICRO_OPEN_MIN", + "CRITERIA_MICRO_OPEN_MAX", + "CRITERIA_NOISE", + "CRITERIA_SORT_MIN", + "CRITERIA_SORT_MAX", +#ifdef HX_GAP_TEST + "CRITERIA_GAP_RAW_MIN", + "CRITERIA_GAP_RAW_MAX", +#endif +#ifdef HX_ACT_IDLE_TEST + "ACT_IDLE_NOISE_MIN", + "ACT_IDLE_NOISE_MAX", + "ACT_IDLE_RAWDATA_MIN", + "ACT_IDLE_RAWDATA_MAX", +#endif +#ifdef HX_INSPECT_LPWUG_TEST + "LPWUG_NOISE_MIN", + "LPWUG_NOISE_MAX", + "LPWUG_RAWDATA_MIN", + "LPWUG_RAWDATA_MAX", + "LPWUG_IDLE_NOISE_MIN", + "LPWUG_IDLE_NOISE_MAX", + "LPWUG_IDLE_RAWDATA_MIN", + "LPWUG_IDLE_RAWDATA_MAX" +#endif +}; +typedef enum { + IDX_RAWMIN = 0, + IDX_RAWMAX, + IDX_SHORTMIN, + IDX_SHORTMAX, + IDX_OPENMIN, + IDX_OPENMAX, + IDX_M_OPENMIN, + IDX_M_OPENMAX, + IDX_NOISEMAX, + IDX_SORTMIN, + IDX_SORTMAX, +#ifdef HX_GAP_TEST + IDX_GAP_RAWMAX, + IDX_GAP_RAWMIN, +#endif +#ifdef HX_ACT_IDLE_TEST + IDX_ACT_IDLE_NOISE_MIN, + IDX_ACT_IDLE_NOISE_MAX, + IDX_ACT_IDLE_RAWDATA_MIN, + IDX_ACT_IDLE_RAWDATA_MAX, +#endif +#ifdef HX_INSPECT_LPWUG_TEST + IDX_LPWUG_NOISE_MIN, + IDX_LPWUG_NOISE_MAX, + IDX_LPWUG_RAWDATA_MIN, + IDX_LPWUG_RAWDATA_MAX, + + IDX_LPWUG_IDLE_NOISE_MIN, + IDX_LPWUG_IDLE_NOISE_MAX, + IDX_LPWUG_IDLE_RAWDATA_MIN, + IDX_LPWUG_IDLE_RAWDATA_MAX, +#endif +} HX_CRITERIA_ENUM; + +/* Error code of Inspection */ +typedef enum { + HX_INSPECT_OK = 0, /* OK */ + HX_INSPECT_ESPI = 1 << 1, /* SPI communication error */ + HX_INSPECT_ERAW = 2 << 1, /* Raw data error */ + HX_INSPECT_ENOISE = 3 << 1, /* Noise error */ + HX_INSPECT_EOPEN = 4 << 1, /* Sensor open error */ + HX_INSPECT_EMOPEN = 5 << 1, /* Sensor micro open error */ + HX_INSPECT_ESHORT = 6 << 1, /* Sensor short error */ +#ifdef HX_GAP_TEST + HX_INSPECT_EGAP_RAW = 8 << 1, /* Sensor short error */ +#endif +#ifdef HX_ACT_IDLE_TEST + HX_INSPECT_EACT_IDLE_RAW = 9 << 1, /* ACT_IDLE RAW ERROR */ + HX_INSPECT_EACT_IDLE_NOISE = 10 << 1, /* ACT_IDLE NOISE ERROR */ +#endif +#ifdef HX_INSPECT_LPWUG_TEST + HX_INSPECT_ELPWUG_RAW = 11 << 1, /* LPWUG RAW ERROR */ + HX_INSPECT_ELPWUG_NOISE = 12 << 1, /* LPWUG NOISE ERROR */ + HX_INSPECT_ELPWUG_IDLE_RAW = 13 << 1, /* LPWUG IDLE RAW ERROR */ + HX_INSPECT_ELPWUG_IDLE_NOISE = 14 << 1, /* LPWUG IDLE NOISE ERROR */ +#endif + HX_INSPECT_EFILE = 15 << 1, /*Criteria file error*/ + HX_INSPECT_EOTHER = 16 << 1, /* All other errors */ +} HX_INSPECT_ERR_ENUM; diff --git a/drivers/input/touchscreen/himax_mmi/himax_platform.c b/drivers/input/touchscreen/himax_mmi/himax_platform.c index e87cc568de9d..2a8047e05bbb 100644 --- a/drivers/input/touchscreen/himax_mmi/himax_platform.c +++ b/drivers/input/touchscreen/himax_mmi/himax_platform.c @@ -1,776 +1,785 @@ -/* Himax Android Driver Sample Code for QCT platform -* -* Copyright (C) 2017 Himax Corporation. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* +/* Himax Android Driver Sample Code for QCT platform + + Copyright (C) 2018 Himax Corporation. + + This software is licensed under the terms of the GNU General Public + License version 2, as published by the Free Software Foundation, and + may be copied, distributed, and modified under those terms. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + */ #include "himax_platform.h" #include "himax_common.h" -#include "himax_ic.h" int i2c_error_count = 0; int irq_enable_count = 0; -extern struct himax_ic_data* ic_data; +extern struct himax_ic_data *ic_data; extern struct himax_ts_data *private_ts; extern void himax_ts_work(struct himax_ts_data *ts); extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer); -#ifdef HX_TP_PROC_DIAG -extern uint8_t getDiagCommand(void); -#endif - -extern void himax_log_touch_int_devation(int touched); - +extern int himax_chip_common_init(void); +extern void himax_chip_common_deinit(void); int himax_dev_set(struct himax_ts_data *ts) { - int ret = 0; + int ret = 0; + ts->input_dev = input_allocate_device(); - ts->input_dev = input_allocate_device(); - if (ts->input_dev == NULL) - { - ret = -ENOMEM; - E("%s: Failed to allocate input device\n", __func__); - return ret; - } - ts->input_dev->name = "himax-touchscreen"; + if (ts->input_dev == NULL) { + ret = -ENOMEM; + E("%s: Failed to allocate input device\n", __func__); + return ret; + } - return ret; + ts->input_dev->name = "himax-touchscreen"; + return ret; } int himax_input_register_device(struct input_dev *input_dev) { - return input_register_device(input_dev); + return input_register_device(input_dev); } #if defined(HX_PLATFOME_DEFINE_KEY) void himax_platform_key(void) { - I("Nothing to be done! Plz cancel it!\n"); + I("Nothing to be done! Plz cancel it!\n"); } #endif void himax_vk_parser(struct device_node *dt, - struct himax_i2c_platform_data *pdata) + struct himax_i2c_platform_data *pdata) { - u32 data = 0; - uint8_t cnt = 0, i = 0; - uint32_t coords[4] = {0}; - struct device_node *node, *pp = NULL; - struct himax_virtual_key *vk; + u32 data = 0; + uint8_t cnt = 0, i = 0; + uint32_t coords[4] = {0}; + struct device_node *node, *pp = NULL; + struct himax_virtual_key *vk; + node = of_parse_phandle(dt, "virtualkey", 0); - node = of_parse_phandle(dt, "virtualkey", 0); - if (node == NULL) - { - I(" DT-No vk info in DT"); - return; - } - else - { - while ((pp = of_get_next_child(node, pp))) - cnt++; - if (!cnt) - return; + if (node == NULL) { + I(" DT-No vk info in DT\n"); + return; + } else { + while ((pp = of_get_next_child(node, pp))) + cnt++; - vk = kzalloc(cnt * (sizeof *vk), GFP_KERNEL); - pp = NULL; - while ((pp = of_get_next_child(node, pp))) - { - if (of_property_read_u32(pp, "idx", &data) == 0) - vk[i].index = data; - if (of_property_read_u32_array(pp, "range", coords, 4) == 0) - { - vk[i].x_range_min = coords[0], vk[i].x_range_max = coords[1]; - vk[i].y_range_min = coords[2], vk[i].y_range_max = coords[3]; - } - else - I(" range faile"); - i++; - } - pdata->virtual_key = vk; - for (i = 0; i < cnt; i++) - I(" vk[%d] idx:%d x_min:%d, y_max:%d", i,pdata->virtual_key[i].index, - pdata->virtual_key[i].x_range_min, pdata->virtual_key[i].y_range_max); - } + if (!cnt) + return; + + vk = kzalloc(cnt * (sizeof *vk), GFP_KERNEL); + pp = NULL; + + while ((pp = of_get_next_child(node, pp))) { + if (of_property_read_u32(pp, "idx", &data) == 0) + vk[i].index = data; + + if (of_property_read_u32_array(pp, "range", coords, 4) == 0) { + vk[i].x_range_min = coords[0], vk[i].x_range_max = coords[1]; + vk[i].y_range_min = coords[2], vk[i].y_range_max = coords[3]; + } else { + I(" range faile\n"); + } + + i++; + } + + pdata->virtual_key = vk; + + for (i = 0; i < cnt; i++) + I(" vk[%d] idx:%d x_min:%d, y_max:%d\n", i, pdata->virtual_key[i].index, + pdata->virtual_key[i].x_range_min, pdata->virtual_key[i].y_range_max); + } } int himax_parse_dt(struct himax_ts_data *ts, - struct himax_i2c_platform_data *pdata) + struct himax_i2c_platform_data *pdata) { - int rc, coords_size = 0; - uint32_t coords[4] = {0}; - struct property *prop; - struct device_node *dt = ts->client->dev.of_node; - u32 data = 0; + int rc, coords_size = 0; + uint32_t coords[4] = {0}; + struct property *prop; + struct device_node *dt = private_ts->client->dev.of_node; + u32 data = 0; + prop = of_find_property(dt, "himax,panel-coords", NULL); - prop = of_find_property(dt, "himax,panel-coords", NULL); - if (prop) - { - coords_size = prop->length / sizeof(u32); - if (coords_size != 4) - D(" %s:Invalid panel coords size %d", __func__, coords_size); - } + if (prop) { + coords_size = prop->length / sizeof(u32); - if (of_property_read_u32_array(dt, "himax,panel-coords", coords, coords_size) == 0) - { - pdata->abs_x_min = coords[0], pdata->abs_x_max = coords[1]; - pdata->abs_y_min = coords[2], pdata->abs_y_max = coords[3]; - I(" DT-%s:panel-coords = %d, %d, %d, %d\n", __func__, pdata->abs_x_min, - pdata->abs_x_max, pdata->abs_y_min, pdata->abs_y_max); - } + if (coords_size != 4) + D(" %s:Invalid panel coords size %d\n", __func__, coords_size); + } - prop = of_find_property(dt, "himax,display-coords", NULL); - if (prop) - { - coords_size = prop->length / sizeof(u32); - if (coords_size != 4) - D(" %s:Invalid display coords size %d", __func__, coords_size); - } - rc = of_property_read_u32_array(dt, "himax,display-coords", coords, coords_size); - if (rc && (rc != -EINVAL)) - { - D(" %s:Fail to read display-coords %d\n", __func__, rc); - return rc; - } - pdata->screenWidth = coords[1]; - pdata->screenHeight = coords[3]; - I(" DT-%s:display-coords = (%d, %d)", __func__, pdata->screenWidth, - pdata->screenHeight); + if (of_property_read_u32_array(dt, "himax,panel-coords", coords, coords_size) == 0) { + pdata->abs_x_min = coords[0], pdata->abs_x_max = coords[1]; + pdata->abs_y_min = coords[2], pdata->abs_y_max = coords[3]; + I(" DT-%s:panel-coords = %d, %d, %d, %d\n", __func__, pdata->abs_x_min, + pdata->abs_x_max, pdata->abs_y_min, pdata->abs_y_max); + } - pdata->gpio_irq = of_get_named_gpio(dt, "himax,irq-gpio", 0); - if (!gpio_is_valid(pdata->gpio_irq)) - { - I(" DT:gpio_irq value is not valid\n"); - } + prop = of_find_property(dt, "himax,display-coords", NULL); - pdata->gpio_reset = of_get_named_gpio(dt, "himax,rst-gpio", 0); - if (!gpio_is_valid(pdata->gpio_reset)) - { - I(" DT:gpio_rst value is not valid\n"); - } - pdata->gpio_3v3_en = of_get_named_gpio(dt, "himax,3v3-gpio", 0); - if (!gpio_is_valid(pdata->gpio_3v3_en)) - { - I(" DT:gpio_3v3_en value is not valid\n"); - } - I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d", pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en); + if (prop) { + coords_size = prop->length / sizeof(u32); - if (of_property_read_u32(dt, "report_type", &data) == 0) - { - pdata->protocol_type = data; - I(" DT:protocol_type=%d", pdata->protocol_type); - } + if (coords_size != 4) + D(" %s:Invalid display coords size %d\n", __func__, coords_size); + } - himax_vk_parser(dt, pdata); + rc = of_property_read_u32_array(dt, "himax,display-coords", coords, coords_size); - return 0; + if (rc && (rc != -EINVAL)) { + D(" %s:Fail to read display-coords %d\n", __func__, rc); + return rc; + } + + pdata->screenWidth = coords[1]; + pdata->screenHeight = coords[3]; + I(" DT-%s:display-coords = (%d, %d)\n", __func__, pdata->screenWidth, + pdata->screenHeight); + pdata->gpio_irq = of_get_named_gpio(dt, "himax,irq-gpio", 0); + + if (!gpio_is_valid(pdata->gpio_irq)) { + I(" DT:gpio_irq value is not valid\n"); + } + + pdata->gpio_reset = of_get_named_gpio(dt, "himax,rst-gpio", 0); + + if (!gpio_is_valid(pdata->gpio_reset)) { + I(" DT:gpio_rst value is not valid\n"); + } + + pdata->gpio_3v3_en = of_get_named_gpio(dt, "himax,3v3-gpio", 0); + + if (!gpio_is_valid(pdata->gpio_3v3_en)) { + I(" DT:gpio_3v3_en value is not valid\n"); + } + + I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d\n", pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en); + + if (of_property_read_u32(dt, "report_type", &data) == 0) { + pdata->protocol_type = data; + I(" DT:protocol_type=%d\n", pdata->protocol_type); + } + + himax_vk_parser(dt, pdata); + return 0; } -int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry) +int himax_bus_read(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry) { - int retry; - struct i2c_msg msg[] = - { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = &command, - }, - { - .addr = client->addr, - .flags = I2C_M_RD, - .len = length, - .buf = data, - } - }; + int retry; + struct i2c_client *client = private_ts->client; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &command, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = data, + } + }; + mutex_lock(&private_ts->rw_lock); - mutex_lock(&private_ts->rw_lock); - for (retry = 0; retry < toRetry; retry++) - { - if (i2c_transfer(client->adapter, msg, 2) == 2) - break; - msleep(20); - } - if (retry == toRetry) - { - E("%s: i2c_read_block retry over %d\n", - __func__, toRetry); - i2c_error_count = toRetry; + for (retry = 0; retry < toRetry; retry++) { + if (i2c_transfer(client->adapter, msg, 2) == 2) + break; + + msleep(20); + } + + if (retry == toRetry) { + E("%s: i2c_read_block retry over %d\n", + __func__, toRetry); + i2c_error_count = toRetry; mutex_unlock(&private_ts->rw_lock); - return -EIO; - } - mutex_unlock(&private_ts->rw_lock); - return 0; + return -EIO; + } + mutex_unlock(&private_ts->rw_lock); + return 0; } -int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry) +int himax_bus_write(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry) { - int retry/*, loop_i*/; - uint8_t buf[length + 1]; + int retry/*, loop_i*/; + uint8_t buf[length + 1]; + struct i2c_client *client = private_ts->client; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = length + 1, + .buf = buf, + } + }; + mutex_lock(&private_ts->rw_lock); + buf[0] = command; + memcpy(buf + 1, data, length); - struct i2c_msg msg[] = - { - { - .addr = client->addr, - .flags = 0, - .len = length + 1, - .buf = buf, - } - }; + for (retry = 0; retry < toRetry; retry++) { + if (i2c_transfer(client->adapter, msg, 1) == 1) + break; - mutex_lock(&private_ts->rw_lock); - buf[0] = command; - memcpy(buf+1, data, length); + msleep(20); + } - for (retry = 0; retry < toRetry; retry++) - { - if (i2c_transfer(client->adapter, msg, 1) == 1) - break; - msleep(20); - } - - if (retry == toRetry) - { - E("%s: i2c_write_block retry over %d\n", - __func__, toRetry); - i2c_error_count = toRetry; + if (retry == toRetry) { + E("%s: i2c_write_block retry over %d\n", + __func__, toRetry); + i2c_error_count = toRetry; mutex_unlock(&private_ts->rw_lock); - return -EIO; - } - mutex_unlock(&private_ts->rw_lock); - return 0; + return -EIO; + } + mutex_unlock(&private_ts->rw_lock); + return 0; } -int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry) +int himax_bus_write_command(uint8_t command, uint8_t toRetry) { - return i2c_himax_write(client, command, NULL, 0, toRetry); + return himax_bus_write(command, NULL, 0, toRetry); } -int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry) +int himax_bus_master_write(uint8_t *data, uint32_t length, uint8_t toRetry) { - int retry/*, loop_i*/; - uint8_t buf[length]; + int retry/*, loop_i*/; + uint8_t buf[length]; + struct i2c_client *client = private_ts->client; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = length, + .buf = buf, + } + }; + mutex_lock(&private_ts->rw_lock); + memcpy(buf, data, length); - struct i2c_msg msg[] = - { - { - .addr = client->addr, - .flags = 0, - .len = length, - .buf = buf, - } - }; - mutex_lock(&private_ts->rw_lock); - memcpy(buf, data, length); + for (retry = 0; retry < toRetry; retry++) { + if (i2c_transfer(client->adapter, msg, 1) == 1) + break; - for (retry = 0; retry < toRetry; retry++) - { - if (i2c_transfer(client->adapter, msg, 1) == 1) - break; - msleep(20); - } + msleep(20); + } - if (retry == toRetry) - { - E("%s: i2c_write_block retry over %d\n", - __func__, toRetry); - i2c_error_count = toRetry; + if (retry == toRetry) { + E("%s: i2c_write_block retry over %d\n", + __func__, toRetry); + i2c_error_count = toRetry; mutex_unlock(&private_ts->rw_lock); - return -EIO; - } - mutex_unlock(&private_ts->rw_lock); - return 0; + return -EIO; + } + + mutex_unlock(&private_ts->rw_lock); + return 0; } -void himax_int_enable(int irqnum, int enable) +void himax_int_enable(int enable) { - if (enable == 1 && irq_enable_count == 0) - { - enable_irq(irqnum); - irq_enable_count++; - private_ts->irq_enabled = 1; - } - else if (enable == 0 && irq_enable_count == 1) - { - disable_irq_nosync(irqnum); - irq_enable_count--; - private_ts->irq_enabled = 0; - } - I("irq_enable_count = %d", irq_enable_count); + int irqnum = 0; + irqnum = private_ts->client->irq; + + if (enable == 1 && irq_enable_count == 0) { + enable_irq(irqnum); + irq_enable_count++; + private_ts->irq_enabled = 1; + } else if (enable == 0 && irq_enable_count == 1) { + disable_irq_nosync(irqnum); + irq_enable_count--; + private_ts->irq_enabled = 0; + } + + I("irq_enable_count = %d\n", irq_enable_count); } #ifdef HX_RST_PIN_FUNC void himax_rst_gpio_set(int pinnum, uint8_t value) { - // gpio_direction_output(pinnum, value); // old - gpio_set_value(pinnum, value); + gpio_direction_output(pinnum, value); } #endif uint8_t himax_int_gpio_read(int pinnum) { - return gpio_get_value(pinnum); + return gpio_get_value(pinnum); } #if defined(CONFIG_HMX_DB) -static int himax_regulator_configure(struct i2c_client *client,struct himax_i2c_platform_data *pdata) +static int himax_regulator_configure(struct himax_i2c_platform_data *pdata) { - int retval; - pdata->vcc_dig = regulator_get(&client->dev, - "vdd"); - if (IS_ERR(pdata->vcc_dig)) - { - E("%s: Failed to get regulator vdd\n", - __func__); - retval = PTR_ERR(pdata->vcc_dig); - return retval; - } - pdata->vcc_ana = regulator_get(&client->dev, - "avdd"); - if (IS_ERR(pdata->vcc_ana)) - { - E("%s: Failed to get regulator avdd\n", - __func__); - retval = PTR_ERR(pdata->vcc_ana); - regulator_put(pdata->vcc_ana); - return retval; - } + int retval; + struct i2c_client *client = private_ts->client; + pdata->vcc_dig = regulator_get(&client->dev, "vdd"); - return 0; + if (IS_ERR(pdata->vcc_dig)) { + E("%s: Failed to get regulator vdd\n", + __func__); + retval = PTR_ERR(pdata->vcc_dig); + return retval; + } + + pdata->vcc_ana = regulator_get(&client->dev, "avdd"); + + if (IS_ERR(pdata->vcc_ana)) { + E("%s: Failed to get regulator avdd\n", + __func__); + retval = PTR_ERR(pdata->vcc_ana); + regulator_put(pdata->vcc_ana); + return retval; + } + + return 0; }; static int himax_power_on(struct himax_i2c_platform_data *pdata, bool on) { - int retval; + int retval; - if (on) - { - retval = regulator_enable(pdata->vcc_dig); - if (retval) - { - E("%s: Failed to enable regulator vdd\n", - __func__); - return retval; - } - msleep(100); - retval = regulator_enable(pdata->vcc_ana); - if (retval) - { - E("%s: Failed to enable regulator avdd\n", - __func__); - regulator_disable(pdata->vcc_dig); - return retval; - } - } - else - { - regulator_disable(pdata->vcc_dig); - regulator_disable(pdata->vcc_ana); - } + if (on) { + retval = regulator_enable(pdata->vcc_dig); - return 0; + if (retval) { + E("%s: Failed to enable regulator vdd\n", + __func__); + return retval; + } + + msleep(100); + retval = regulator_enable(pdata->vcc_ana); + + if (retval) { + E("%s: Failed to enable regulator avdd\n", + __func__); + regulator_disable(pdata->vcc_dig); + return retval; + } + } else { + regulator_disable(pdata->vcc_dig); + regulator_disable(pdata->vcc_ana); + } + + return 0; } -int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata) +int himax_gpio_power_config(struct himax_i2c_platform_data *pdata) { - int error; + int error; + struct i2c_client *client = private_ts->client; + error = himax_regulator_configure(pdata); - error = himax_regulator_configure(client, pdata); - if (error) - { - E("Failed to intialize hardware\n"); - goto err_regulator_not_on; - } + if (error) { + E("Failed to intialize hardware\n"); + goto err_regulator_not_on; + } #ifdef HX_RST_PIN_FUNC - if (gpio_is_valid(pdata->gpio_reset)) - { - /* configure touchscreen reset out gpio */ - error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio"); - if (error) - { - E("unable to request gpio [%d]\n", - pdata->gpio_reset); - goto err_regulator_on; - } - error = gpio_direction_output(pdata->gpio_reset, 0); - if (error) - { - E("unable to set direction for gpio [%d]\n", - pdata->gpio_reset); - goto err_gpio_reset_req; - } - } + if (gpio_is_valid(pdata->gpio_reset)) { + /* configure touchscreen reset out gpio */ + error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio"); + + if (error) { + E("unable to request gpio [%d]\n", + pdata->gpio_reset); + goto err_regulator_on; + } + + error = gpio_direction_output(pdata->gpio_reset, 0); + + if (error) { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_reset); + goto err_gpio_reset_req; + } + } + #endif + error = himax_power_on(pdata, true); - error = himax_power_on(pdata, true); - if (error) - { - E("Failed to power on hardware\n"); - goto err_gpio_reset_req; - } + if (error) { + E("Failed to power on hardware\n"); + goto err_gpio_reset_req; + } - if (gpio_is_valid(pdata->gpio_irq)) - { - /* configure touchscreen irq gpio */ - error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq"); - if (error) - { - E("unable to request gpio [%d]\n", - pdata->gpio_irq); - goto err_power_on; - } - error = gpio_direction_input(pdata->gpio_irq); - if (error) - { - E("unable to set direction for gpio [%d]\n", - pdata->gpio_irq); - goto err_gpio_irq_req; - } - client->irq = gpio_to_irq(pdata->gpio_irq); - } - else - { - E("irq gpio not provided\n"); - goto err_power_on; - } + if (gpio_is_valid(pdata->gpio_irq)) { + /* configure touchscreen irq gpio */ + error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq"); - msleep(20); + if (error) { + E("unable to request gpio [%d]\n", + pdata->gpio_irq); + goto err_power_on; + } + + error = gpio_direction_input(pdata->gpio_irq); + + if (error) { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_irq); + goto err_gpio_irq_req; + } + + client->irq = gpio_to_irq(pdata->gpio_irq); + } else { + E("irq gpio not provided\n"); + goto err_power_on; + } + + msleep(20); #ifdef HX_RST_PIN_FUNC - if (gpio_is_valid(pdata->gpio_reset)) - { - error = gpio_direction_output(pdata->gpio_reset, 1); - if (error) - { - E("unable to set direction for gpio [%d]\n", - pdata->gpio_reset); - goto err_gpio_irq_req; - } - } -#endif - return 0; + if (gpio_is_valid(pdata->gpio_reset)) { + error = gpio_direction_output(pdata->gpio_reset, 1); + + if (error) { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_reset); + goto err_gpio_irq_req; + } + } + +#endif + return 0; err_gpio_irq_req: - if (gpio_is_valid(pdata->gpio_irq)) - gpio_free(pdata->gpio_irq); + + if (gpio_is_valid(pdata->gpio_irq)) + gpio_free(pdata->gpio_irq); + err_power_on: - himax_power_on(pdata, false); + himax_power_on(pdata, false); err_gpio_reset_req: #ifdef HX_RST_PIN_FUNC - if (gpio_is_valid(pdata->gpio_reset)) - gpio_free(pdata->gpio_reset); + + if (gpio_is_valid(pdata->gpio_reset)) + gpio_free(pdata->gpio_reset); + err_regulator_on: #endif err_regulator_not_on: - - return error; + return error; } #else -int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata) +int himax_gpio_power_config(struct himax_i2c_platform_data *pdata) { - int error=0; - + int error = 0; + struct i2c_client *client = private_ts->client; #ifdef HX_RST_PIN_FUNC - if (pdata->gpio_reset >= 0) - { - error = gpio_request(pdata->gpio_reset, "himax-reset"); - if (error < 0) - { - E("%s: request reset pin failed\n", __func__); - return error; - } - } -#endif - if (pdata->gpio_3v3_en >= 0) - { - error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en"); - if (error < 0) - { - E("%s: request 3v3_en pin failed\n", __func__); - goto err_3v3_en_request; - } - gpio_direction_output(pdata->gpio_3v3_en, 1); - I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en)); - } - if (gpio_is_valid(pdata->gpio_irq)) - { - /* configure touchscreen irq gpio */ - error = gpio_request(pdata->gpio_irq, "himax_gpio_irq"); - if (error) - { - E("unable to request gpio [%d]\n",pdata->gpio_irq); - goto err_irq_request; - } - error = gpio_direction_input(pdata->gpio_irq); - if (error) - { - E("unable to set direction for gpio [%d]\n",pdata->gpio_irq); - goto err_irq_set_direction; - } - client->irq = gpio_to_irq(pdata->gpio_irq); - } - else - { - E("irq gpio not provided\n"); - goto err_irq_request; - } -#ifdef HX_RST_PIN_FUNC - if (pdata->gpio_reset >= 0) - { - error = gpio_direction_output(pdata->gpio_reset, 0); - if (error) - { - E("unable to set direction for gpio [%d]\n", - pdata->gpio_reset); - goto err_rst_set_value; - } - msleep(20); - error = gpio_direction_output(pdata->gpio_reset, 1); - if (error) - { - E("unable to set direction for gpio [%d]\n", - pdata->gpio_reset); - goto err_rst_set_value; - } - } -#endif - return 0; + if (pdata->gpio_reset >= 0) { + error = gpio_request(pdata->gpio_reset, "himax-reset"); + + if (error < 0) { + E("%s: request reset pin failed\n", __func__); + return error; + } + } -#ifdef HX_RST_PIN_FUNC -err_rst_set_value: #endif -err_irq_set_direction: - if (gpio_is_valid(pdata->gpio_irq)) - gpio_free(pdata->gpio_irq); -err_irq_request: - if (gpio_is_valid(pdata->gpio_3v3_en)) - gpio_free(pdata->gpio_3v3_en); -err_3v3_en_request: - if (gpio_is_valid(pdata->gpio_reset)) - gpio_free(pdata->gpio_reset); - return error; + + if (pdata->gpio_3v3_en >= 0) { + error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en"); + + if (error < 0) { + E("%s: request 3v3_en pin failed\n", __func__); + goto err_3v3_en_request; + } + + gpio_direction_output(pdata->gpio_3v3_en, 1); + I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en)); + } + + if (gpio_is_valid(pdata->gpio_irq)) { + /* configure touchscreen irq gpio */ + error = gpio_request(pdata->gpio_irq, "himax_gpio_irq"); + + if (error) { + E("unable to request gpio [%d]\n", pdata->gpio_irq); + goto err_irq_request; + } + + error = gpio_direction_input(pdata->gpio_irq); + + if (error) { + E("unable to set direction for gpio [%d]\n", pdata->gpio_irq); + goto err_irq_set_direction; + } + + client->irq = gpio_to_irq(pdata->gpio_irq); + } else { + E("irq gpio not provided\n"); + goto err_irq_request; + } + +#ifdef HX_RST_PIN_FUNC + + if (pdata->gpio_reset >= 0) { + error = gpio_direction_output(pdata->gpio_reset, 0); + if (error) { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_reset); + goto err_rst_set_value; + } + msleep(20); + error = gpio_direction_output(pdata->gpio_reset, 1); + + if (error) { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_reset); + goto err_rst_set_value; + } + } + +#endif + return 0; +#ifdef HX_RST_PIN_FUNC + err_rst_set_value: +#endif + err_irq_set_direction: + if (gpio_is_valid(pdata->gpio_irq)) + gpio_free(pdata->gpio_irq); + err_irq_request: + if (gpio_is_valid(pdata->gpio_3v3_en)) + gpio_free(pdata->gpio_3v3_en); + err_3v3_en_request: + if (gpio_is_valid(pdata->gpio_reset)) + gpio_free(pdata->gpio_reset); + + return error; } #endif static void himax_ts_isr_func(struct himax_ts_data *ts) { - himax_ts_work(ts); + himax_ts_work(ts); } irqreturn_t himax_ts_thread(int irq, void *ptr) { - struct himax_ts_data *ts = ptr; + himax_ts_isr_func((struct himax_ts_data *)ptr); - if (ts->debug_log_level & BIT(2)) - { - himax_log_touch_int_devation(HX_FINGER_ON); - } - - himax_ts_isr_func((struct himax_ts_data *)ptr); - - if(ts->debug_log_level & BIT(2)) - { - himax_log_touch_int_devation(HX_FINGER_LEAVE); - } - return IRQ_HANDLED; + return IRQ_HANDLED; } static void himax_ts_work_func(struct work_struct *work) { - struct himax_ts_data *ts = container_of(work, struct himax_ts_data, work); - himax_ts_work(ts); + struct himax_ts_data *ts = container_of(work, struct himax_ts_data, work); + himax_ts_work(ts); } -int himax_int_register_trigger(struct i2c_client *client) +int himax_int_register_trigger(void) { - int ret = 0; - struct himax_ts_data *ts = i2c_get_clientdata(client); + int ret = 0; + struct himax_ts_data *ts = private_ts; + struct i2c_client *client = private_ts->client; - if(ic_data->HX_INT_IS_EDGE) - { - I("%s edge triiger falling\n ",__func__); - ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, ts); - } - else - { - I("%s level trigger low\n ",__func__); - ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ts); - } - return ret; + if (ic_data->HX_INT_IS_EDGE) { + I("%s edge triiger falling\n ", __func__); + ret = request_threaded_irq(client->irq, NULL, himax_ts_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, ts); + } + + else { + I("%s level trigger low\n ", __func__); + ret = request_threaded_irq(client->irq, NULL, himax_ts_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ts); + } + + return ret; } -int himax_int_en_set(struct i2c_client *client) +int himax_int_en_set(void) { - int ret = NO_ERR; - ret = himax_int_register_trigger(client); - return ret; + int ret = NO_ERR; + ret = himax_int_register_trigger(); + return ret; } -int himax_ts_register_interrupt(struct i2c_client *client) +int himax_ts_register_interrupt(void) { - struct himax_ts_data *ts = i2c_get_clientdata(client); - int ret = 0; + struct himax_ts_data *ts = private_ts; + struct i2c_client *client = private_ts->client; + int ret = 0; + ts->irq_enabled = 0; - ts->irq_enabled = 0; - //Work functon - if (client->irq) /*INT mode*/ - { - ts->use_irq = 1; - ret = himax_int_register_trigger(client); - if (ret == 0) - { - ts->irq_enabled = 1; - irq_enable_count = 1; - I("%s: irq enabled at qpio: %d\n", __func__, client->irq); + /* Work functon */ + if (client->irq) {/*INT mode*/ + ts->use_irq = 1; + ret = himax_int_register_trigger(); + + if (ret == 0) { + ts->irq_enabled = 1; + irq_enable_count = 1; + I("%s: irq enabled at qpio: %d\n", __func__, client->irq); #ifdef HX_SMART_WAKEUP - irq_set_irq_wake(client->irq, 1); + irq_set_irq_wake(client->irq, 1); #endif - } - else - { - ts->use_irq = 0; - E("%s: request_irq failed\n", __func__); - } - } - else - { - I("%s: client->irq is empty, use polling mode.\n", __func__); - } + } else { + ts->use_irq = 0; + E("%s: request_irq failed\n", __func__); + } + } else { + I("%s: client->irq is empty, use polling mode.\n", __func__); + } - if (!ts->use_irq) /*if use polling mode need to disable HX_ESD_RECOVERY function*/ - { - ts->himax_wq = create_singlethread_workqueue("himax_touch"); + if (!ts->use_irq) {/*if use polling mode need to disable HX_ESD_RECOVERY function*/ + ts->himax_wq = create_singlethread_workqueue("himax_touch"); + INIT_WORK(&ts->work, himax_ts_work_func); + hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + ts->timer.function = himax_ts_timer_func; + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + I("%s: polling mode enabled\n", __func__); + } - INIT_WORK(&ts->work, himax_ts_work_func); - - hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - ts->timer.function = himax_ts_timer_func; - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - I("%s: polling mode enabled\n", __func__); - } - return ret; + return ret; } static int himax_common_suspend(struct device *dev) { - struct himax_ts_data *ts = dev_get_drvdata(dev); - - I("%s: enter \n", __func__); - - himax_chip_common_suspend(ts); - return 0; + struct himax_ts_data *ts = dev_get_drvdata(dev); + I("%s: enter \n", __func__); + himax_chip_common_suspend(ts); + return 0; } static int himax_common_resume(struct device *dev) { - struct himax_ts_data *ts = dev_get_drvdata(dev); - - I("%s: enter \n", __func__); - - himax_chip_common_resume(ts); - return 0; + struct himax_ts_data *ts = dev_get_drvdata(dev); + I("%s: enter \n", __func__); + himax_chip_common_resume(ts); + return 0; } #if defined(CONFIG_FB) int fb_notifier_callback(struct notifier_block *self, - unsigned long event, void *data) + unsigned long event, void *data) { - struct fb_event *evdata = data; - int *blank; - struct himax_ts_data *ts= - container_of(self, struct himax_ts_data, fb_notif); + struct fb_event *evdata = data; + int *blank; + struct himax_ts_data *ts = + container_of(self, struct himax_ts_data, fb_notif); + I(" %s\n", __func__); - I(" %s\n", __func__); - if (evdata && evdata->data && event == FB_EVENT_BLANK && ts && - ts->client) - { - blank = evdata->data; - switch (*blank) - { - case FB_BLANK_UNBLANK: - himax_common_resume(&ts->client->dev); - break; + if (evdata && evdata->data && event == FB_EVENT_BLANK && ts && + ts->client) { + blank = evdata->data; - case FB_BLANK_POWERDOWN: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_NORMAL: - himax_common_suspend(&ts->client->dev); - break; - } - } + switch (*blank) { + case FB_BLANK_UNBLANK: + himax_common_resume(&ts->client->dev); + break; + case FB_BLANK_POWERDOWN: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_NORMAL: + himax_common_suspend(&ts->client->dev); + break; + } + } - return 0; + return 0; } #endif -static const struct i2c_device_id himax_common_ts_id[] = +int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id) { - {HIMAX_common_NAME, 0 }, - {} + int ret = 0; + struct himax_ts_data *ts; + + I("%s:Enter \n", __func__); + + /* Check I2C functionality */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + E("%s: i2c check functionality error\n", __func__); + ret = -ENODEV; + goto err_check_functionality_failed; + } + + ts = kzalloc(sizeof(struct himax_ts_data), GFP_KERNEL); + if (ts == NULL) { + E("%s: allocate himax_ts_data failed\n", __func__); + ret = -ENOMEM; + goto err_alloc_data_failed; + } + + i2c_set_clientdata(client, ts); + ts->client = client; + ts->dev = &client->dev; + mutex_init(&ts->rw_lock); + private_ts = ts; + + ret = himax_chip_common_init(); + + err_alloc_data_failed: + err_check_functionality_failed: + + return ret; +} + +int himax_chip_common_remove(struct i2c_client *client) +{ + himax_chip_common_deinit(); + + return 0; +} + +static const struct i2c_device_id himax_common_ts_id[] = { + {HIMAX_common_NAME, 0 }, + {} }; -static const struct dev_pm_ops himax_common_pm_ops = -{ +static const struct dev_pm_ops himax_common_pm_ops = { #if (!defined(CONFIG_FB)) - .suspend = himax_common_suspend, - .resume = himax_common_resume, + .suspend = himax_common_suspend, + .resume = himax_common_resume, #endif }; #ifdef CONFIG_OF -static struct of_device_id himax_match_table[] = -{ - {.compatible = "himax,hxcommon" }, - {}, +static struct of_device_id himax_match_table[] = { + {.compatible = "himax,hxcommon" }, + {}, }; #else #define himax_match_table NULL #endif -static struct i2c_driver himax_common_driver = -{ - .id_table = himax_common_ts_id, - .probe = himax_chip_common_probe, - .remove = himax_chip_common_remove, - .driver = { - .name = HIMAX_common_NAME, - .owner = THIS_MODULE, - .of_match_table = himax_match_table, +static struct i2c_driver himax_common_driver = { + .id_table = himax_common_ts_id, + .probe = himax_chip_common_probe, + .remove = himax_chip_common_remove, + .driver = { + .name = HIMAX_common_NAME, + .owner = THIS_MODULE, + .of_match_table = himax_match_table, #ifdef CONFIG_PM - .pm = &himax_common_pm_ops, + .pm = &himax_common_pm_ops, #endif - }, + }, }; static int __init himax_common_init(void) { - I("Himax common touch panel driver init\n"); - if(i2c_add_driver(&himax_common_driver) < 0) { - E("Failed to add Driver!\n"); - } - return 0; + I("Himax common touch panel driver init\n"); + i2c_add_driver(&himax_common_driver); + + return 0; } static void __exit himax_common_exit(void) { - i2c_del_driver(&himax_common_driver); + i2c_del_driver(&himax_common_driver); } module_init(himax_common_init); diff --git a/drivers/input/touchscreen/himax_mmi/himax_platform.h b/drivers/input/touchscreen/himax_mmi/himax_platform.h index 70def61909fa..7694a4c167d7 100644 --- a/drivers/input/touchscreen/himax_mmi/himax_platform.h +++ b/drivers/input/touchscreen/himax_mmi/himax_platform.h @@ -1,16 +1,16 @@ -/* Himax Android Driver Sample Code for QCT platform -* -* Copyright (C) 2017 Himax Corporation. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* +/* Himax Android Driver Sample Code for QCT platform + + Copyright (C) 2018 Himax Corporation. + + This software is licensed under the terms of the GNU General Public + License version 2, as published by the Free Software Foundation, and + may be copied, distributed, and modified under those terms. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + */ #ifndef HIMAX_PLATFORM_H @@ -23,10 +23,10 @@ #include #include #if defined(CONFIG_HMX_DB) -#include + #include #endif -#define QCT +#define HIMAX_I2C_RETRY_TIMES 10 #if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) #define D(x...) printk("[HXTP] " x) @@ -34,9 +34,10 @@ #define W(x...) printk("[HXTP][WARNING] " x) #define E(x...) printk("[HXTP][ERROR] " x) #define DIF(x...) \ +do { \ if (debug_flag) \ - printk("[HXTP][DEBUG] " x) \ -} while(0) + printk("[HXTP][DEBUG] " x) \ + } while (0) #else #define D(x...) #define I(x...) @@ -46,85 +47,84 @@ #endif #if defined(CONFIG_HMX_DB) -/* Analog voltage @2.7 V */ -#define HX_VTG_MIN_UV 2700000 -#define HX_VTG_MAX_UV 3300000 -#define HX_ACTIVE_LOAD_UA 15000 -#define HX_LPM_LOAD_UA 10 -/* Digital voltage @1.8 V */ -#define HX_VTG_DIG_MIN_UV 1800000 -#define HX_VTG_DIG_MAX_UV 1800000 -#define HX_ACTIVE_LOAD_DIG_UA 10000 -#define HX_LPM_LOAD_DIG_UA 10 + /* Analog voltage @2.7 V */ + #define HX_VTG_MIN_UV 2700000 + #define HX_VTG_MAX_UV 3300000 + #define HX_ACTIVE_LOAD_UA 15000 + #define HX_LPM_LOAD_UA 10 + /* Digital voltage @1.8 V */ + #define HX_VTG_DIG_MIN_UV 1800000 + #define HX_VTG_DIG_MAX_UV 1800000 + #define HX_ACTIVE_LOAD_DIG_UA 10000 + #define HX_LPM_LOAD_DIG_UA 10 -#define HX_I2C_VTG_MIN_UV 1800000 -#define HX_I2C_VTG_MAX_UV 1800000 -#define HX_I2C_LOAD_UA 10000 -#define HX_I2C_LPM_LOAD_UA 10 + #define HX_I2C_VTG_MIN_UV 1800000 + #define HX_I2C_VTG_MAX_UV 1800000 + #define HX_I2C_LOAD_UA 10000 + #define HX_I2C_LPM_LOAD_UA 10 #endif #define HIMAX_common_NAME "himax_tp" #define HIMAX_I2C_ADDR 0x48 #define INPUT_DEV_NAME "himax-touchscreen" -struct himax_i2c_platform_data -{ - int abs_x_min; - int abs_x_max; - int abs_x_fuzz; - int abs_y_min; - int abs_y_max; - int abs_y_fuzz; - int abs_pressure_min; - int abs_pressure_max; - int abs_pressure_fuzz; - int abs_width_min; - int abs_width_max; - int screenWidth; - int screenHeight; - uint8_t fw_version; - uint8_t tw_id; - uint8_t powerOff3V3; - uint8_t cable_config[2]; - uint8_t protocol_type; - int gpio_irq; - int gpio_reset; - int gpio_3v3_en; - int (*power)(int on); - void (*reset)(void); - struct himax_virtual_key *virtual_key; - struct kobject *vk_obj; - struct kobj_attribute *vk2Use; +struct himax_i2c_platform_data { + int abs_x_min; + int abs_x_max; + int abs_x_fuzz; + int abs_y_min; + int abs_y_max; + int abs_y_fuzz; + int abs_pressure_min; + int abs_pressure_max; + int abs_pressure_fuzz; + int abs_width_min; + int abs_width_max; + int screenWidth; + int screenHeight; + uint8_t fw_version; + uint8_t tw_id; + uint8_t powerOff3V3; + uint8_t cable_config[2]; + uint8_t protocol_type; + int gpio_irq; + int gpio_reset; + int gpio_3v3_en; + int (*power)(int on); + void (*reset)(void); + struct himax_virtual_key *virtual_key; + struct kobject *vk_obj; + struct kobj_attribute *vk2Use; - int hx_config_size; + int hx_config_size; #if defined(CONFIG_HMX_DB) - bool i2c_pull_up; - bool digital_pwr_regulator; - int reset_gpio; - u32 reset_gpio_flags; - int irq_gpio; - u32 irq_gpio_flags; + bool i2c_pull_up; + bool digital_pwr_regulator; + int reset_gpio; + u32 reset_gpio_flags; + int irq_gpio; + u32 irq_gpio_flags; - struct regulator *vcc_ana; //For Dragon Board - struct regulator *vcc_dig; //For Dragon Board - struct regulator *vcc_i2c; //For Dragon Board + struct regulator *vcc_ana; /* For Dragon Board */ + struct regulator *vcc_dig; /* For Dragon Board */ + struct regulator *vcc_i2c; /* For Dragon Board */ #endif }; extern int irq_enable_count; -extern int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry); -extern int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry); -extern int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry); -extern int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry); -extern void himax_int_enable(int irqnum, int enable); -extern int himax_ts_register_interrupt(struct i2c_client *client); +extern int himax_bus_read(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry); +extern int himax_bus_write(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry); +extern int himax_bus_write_command(uint8_t command, uint8_t toRetry); +extern int himax_bus_master_write(uint8_t *data, uint32_t length, uint8_t toRetry); +extern void himax_int_enable(int enable); +extern int himax_ts_register_interrupt(void); extern uint8_t himax_int_gpio_read(int pinnum); -extern int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata); +extern int himax_gpio_power_config(struct himax_i2c_platform_data *pdata); #if defined(CONFIG_FB) -extern int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); + extern int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); #endif #endif