From c4c449b15dbf3bfd9980ce947c2a5952583d01d1 Mon Sep 17 00:00:00 2001 From: wingte49 Date: Thu, 31 Mar 2022 14:42:56 +0800 Subject: [PATCH] : Rhodec: Uptade chipone_tddi_fhd_mmi driver Modify: 1.add rawdata collection function 2.update interrupt data collection process 3.add ioctl debugging equipment interface 4.revice the production and testing process Change-Id: Id4130107cdb085aaf5981685766f37804ac6ddc4 Reviewed-on: https://gerrit.mot.com/2230586 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Yeqing Wang Reviewed-by: Wei Deng Reviewed-by: Jun Weng Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- .../chipone_tddi_fhd_mmi/cts_config.h | 3 +- .../chipone_tddi_fhd_mmi/cts_core.c | 80 ++++--- .../chipone_tddi_fhd_mmi/cts_core.h | 10 +- .../chipone_tddi_fhd_mmi/cts_firmware.h | 1 + .../chipone_tddi_fhd_mmi/cts_hostcomm.c | 2 +- .../chipone_tddi_fhd_mmi/cts_sysfs.c | 196 ++++++++++++++++++ .../chipone_tddi_fhd_mmi/cts_tcs.c | 103 ++++----- .../chipone_tddi_fhd_mmi/cts_tcs.h | 8 +- .../chipone_tddi_fhd_mmi/cts_test.c | 22 +- .../chipone_tddi_fhd_mmi/cts_tool.c | 126 ++++++++++- 10 files changed, 433 insertions(+), 118 deletions(-) diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_config.h b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_config.h index 37fe31d4ba1d..d1c5898887b8 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_config.h +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_config.h @@ -23,7 +23,8 @@ #endif -#define CFG_CTS_FORCE_UP +//#define CFG_CTS_FORCE_UP +#define CFG_DUMP_INT_DATA #define CONFIG_GENERIC_HARDIRQS //#define CFG_CTS_FW_LOG_REDIRECT diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.c b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.c index cfd16324ca58..ee4926bc3526 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.c +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.c @@ -1371,7 +1371,7 @@ int cts_send_command(const struct cts_device *cts_dev, u8 cmd) 0); } -static int cts_get_touchinfo(const struct cts_device *cts_dev, +static int cts_get_touchinfo(struct cts_device *cts_dev, struct cts_device_touch_info *touch_info) { cts_dbg("Get touch info"); @@ -1937,8 +1937,11 @@ void cts_show_fw_log(struct cts_device *cts_dev) } #endif +extern int cts_tcs_clr_data_ready_flag(const struct cts_device *cts_dev); +extern int cts_tcs_clr_gstr_ready_flag(const struct cts_device *cts_dev); int cts_irq_handler(struct cts_device *cts_dev) { + struct cts_device_touch_info *touch_info; u8 pwrmode = 3; int ret; @@ -1949,53 +1952,63 @@ int cts_irq_handler(struct cts_device *cts_dev) return -EINVAL; } + touch_info = &cts_dev->rtdata.touch_info; + ret = cts_get_touchinfo(cts_dev, touch_info); + if (ret) { + cts_err("Get touch info failed %d", ret); + return ret; + } if (unlikely(cts_dev->rtdata.suspended)) { #ifdef CFG_CTS_GESTURE if (cts_dev->rtdata.gesture_wakeup_enabled) { struct cts_device_gesture_info *gesture_info; gesture_info = &cts_dev->rtdata.gesture_info; + memcpy(gesture_info, touch_info, sizeof(struct cts_device_gesture_info)); - ret = cts_get_gesture_info(cts_dev, gesture_info); + ret = cts_plat_process_gesture_info(cts_dev->pdata, gesture_info); - if (ret) - cts_warn("Get gesture info failed %d", ret); + if (cts_dev->fwdata.int_data_method != INT_DATA_METHOD_HOST) { + if (ret) + cts_err("Process gesture info failed %d", ret); /* return ret; */ + if (cts_tcs_clr_gstr_ready_flag(cts_dev)) + cts_err("Clear gesture ready flag failed"); /** - Issure another suspend with gesture wakeup command to device * after get gesture info. */ - ret = cts_dev->ops->set_pwr_mode(cts_dev, pwrmode); - if (ret) - cts_warn("Reenter suspend with gesture wakeup failed %d", ret); - ret = cts_plat_process_gesture_info(cts_dev->pdata, gesture_info); - if (ret) { - cts_err("Process gesture info failed %d", ret); + ret = cts_dev->ops->set_pwr_mode(cts_dev, pwrmode); + if (ret) + cts_warn("Reenter suspend with gesture wakeup failed %d", ret); + } else { + if (cts_tcs_clr_data_ready_flag(cts_dev)) + cts_err("Clear data ready flag failed"); return ret; } - } else + } else { cts_warn("IRQ triggered while device suspended " "without gesture wakeup enable"); + } #endif /* CFG_CTS_GESTURE */ } else { - struct cts_device_touch_info *touch_info; - - touch_info = &cts_dev->rtdata.touch_info; - - ret = cts_get_touchinfo(cts_dev, touch_info); - if (ret) { - cts_err("Get touch info failed %d", ret); - return ret; - } -#ifdef CFG_CTS_FW_LOG_REDIRECT - if (touch_info->vkey_state == CTS_FW_LOG_REDIRECT_SIGN) { - if (cts_is_fw_log_redirect(cts_dev)) - cts_show_fw_log(cts_dev); - } -#endif cts_dbg("Touch info: vkey_state %x, num_msg %u", touch_info->vkey_state, touch_info->num_msg); + if (cts_dev->fwdata.int_data_method != INT_DATA_METHOD_NONE + && cts_dev->fwdata.int_data_method != INT_DATA_METHOD_DEBUG) { + if (cts_tcs_clr_data_ready_flag(cts_dev)) { + cts_err("Clear data ready flag failed"); + } + } +#ifdef CFG_CTS_PALM_DETECT + if (CFG_CTS_PALM_ID == touch_info->vkey_state) { + cts_report_palm_event(cts_dev->pdata); + cts_plat_release_all_touch(cts_dev->pdata); + return 0; + } +#endif + ret = cts_plat_process_touch_msg(cts_dev->pdata, touch_info->msgs, touch_info->num_msg); @@ -2063,12 +2076,17 @@ int cts_resume_device(struct cts_device *cts_dev) { int ret = 0; int retries = 3; + u8 tdata[4] = { 'R', 'S', 'T', '!' }; cts_info("Resume device"); /* Check whether device is in normal mode */ while (--retries >= 0) { #ifdef CFG_CTS_HAS_RESET_PIN + ret = cts_hw_reg_writesb_retry(cts_dev, 0x300F8, tdata, + sizeof(tdata), 3, 1); + if (ret != 0) + cts_err("0x300F8 write 0 failed"); cts_reset_device(cts_dev); #endif cts_set_normal_addr(cts_dev); @@ -3217,6 +3235,16 @@ int cts_reset_device(struct cts_device *cts_dev) cts_err("BUG! reset_device should NOT be null!"); return -EIO; } + +int cts_spi_xtrans(const struct cts_device *cts_dev, u8 *tx, size_t txlen, u8 *rx, size_t rxlen) +{ + if (cts_dev->ops->spi_xtrans) { + return cts_dev->ops->spi_xtrans(cts_dev, tx, txlen, rx, rxlen); + } + + return -1; +} + static struct file *cts_log_filp; static int cts_log_to_file_level; extern int cts_write_file(struct file *filp, const void *data, size_t size); diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.h b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.h index 25bcbb463060..90518567f407 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.h +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.h @@ -271,6 +271,11 @@ struct cts_device_rtdata { bool updating; bool testing; +#ifdef CFG_DUMP_INT_DATA + bool dumping; + u32 dump_cnt; +#endif + bool gesture_wakeup_enabled; bool charger_exist; bool fw_log_redirect_enabled; @@ -301,7 +306,7 @@ struct cts_dev_ops { u8 *esd_method); int (*get_gestureinfo)(const struct cts_device *cts_dev, struct cts_device_gesture_info *gesture_info); - int (*get_touchinfo)(const struct cts_device *cts_dev, + int (*get_touchinfo)(struct cts_device *cts_dev, struct cts_device_touch_info *touch_info); int (*get_esd_protection)(const struct cts_device *cts_dev, u8 *esd_protection); @@ -396,6 +401,7 @@ struct cts_dev_ops { int (*set_int_test)(const struct cts_device *cts_dev, u8 enable); int (*set_int_pin)(const struct cts_device *cts_dev, u8 high); int (*get_module_id)(const struct cts_device *cts_dev, u32 *modId); + int (*spi_xtrans)(const struct cts_device *cts_dev, u8 *tx, size_t txlen, u8 *rx, size_t rxlen); }; struct cts_device { @@ -942,7 +948,7 @@ extern bool cts_is_fwid_valid(u16 fwid); extern void cts_deinit_rtdata(struct cts_device *cts_dev); extern int cts_reset_device(struct cts_device *cts_dev); - +extern int cts_spi_xtrans(const struct cts_device *cts_dev, u8 *tx, size_t txlen, u8 *rx, size_t rxlen); int touch_set_state(int state, int panel_idx); int check_touch_state(int *state, int panel_idx); #endif /* CTS_CORE_H */ diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_firmware.h b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_firmware.h index 6d057eae8367..b8eec9a170a1 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_firmware.h +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_firmware.h @@ -4,6 +4,7 @@ #include "cts_config.h" #include +#include struct cts_firmware { const char *name; /* MUST set to non-NULL if driver builtin firmware */ diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_hostcomm.c b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_hostcomm.c index 0890bd5c743f..fd361da9921f 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_hostcomm.c +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_hostcomm.c @@ -251,7 +251,7 @@ int cts_hostcomm_write_fw_reg(const struct cts_device *cts_dev, u32 addr, return cts_fw_reg_writesb(cts_dev, addr, regbuf, size); } -int cts_hostcomm_get_touchinfo(const struct cts_device *cts_dev, +int cts_hostcomm_get_touchinfo(struct cts_device *cts_dev, struct cts_device_touch_info *touch_info) { memset(touch_info, 0, sizeof(*touch_info)); diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sysfs.c b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sysfs.c index 88c3192d5fab..7010782ab3de 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sysfs.c +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sysfs.c @@ -2671,7 +2671,9 @@ static ssize_t int_data_types_store(struct device *dev, return -EINVAL; } + cts_lock_device(&cts_data->cts_dev); ret = cts_set_int_data_types(&cts_data->cts_dev, type); + cts_unlock_device(&cts_data->cts_dev); if (ret) return -EIO; return count; @@ -2713,7 +2715,9 @@ static ssize_t int_data_method_store(struct device *dev, return -EINVAL; } + cts_lock_device(&cts_data->cts_dev); ret = cts_set_int_data_method(&cts_data->cts_dev, method); + cts_unlock_device(&cts_data->cts_dev); if (ret) return -EIO; return count; @@ -2722,6 +2726,195 @@ static ssize_t int_data_method_store(struct device *dev, static DEVICE_ATTR(int_data_method, S_IWUSR | S_IRUGO, int_data_method_show, int_data_method_store); + +#ifdef CFG_DUMP_INT_DATA +/* For dump bin file */ +static int cts_write_intdata(struct file *filp, const void *data, size_t size) +{ + loff_t pos; + ssize_t ret; + + pos = filp->f_pos; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0) + ret = kernel_write(filp, data, size, &pos); +#else + ret = kernel_write(filp, data, size, pos); +#endif + + if (ret >= 0) { + filp->f_pos += ret; + } + + return ret; +} + +u32 old_cnt; +struct file *cts_int_data_filp = NULL; +char chipone_bin_path[64] = "/sdcard/chipone.bin"; +void cts_dump_int_tsdata(const u8 *data, size_t size) +{ + if (cts_int_data_filp) { + cts_write_intdata(cts_int_data_filp, data, size); + } +} + +static int cts_start_dump_int_data_to_file(const char *filepath, bool append) +{ + int ret; + u8 header[24] = { 0x00 }; + + cts_info("Start dump test data to file '%s'", filepath); + + cts_int_data_filp = filp_open(filepath, + O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), + S_IRUGO | S_IWUGO); + if (IS_ERR(cts_int_data_filp)) { + ret = PTR_ERR(cts_int_data_filp); + cts_int_data_filp = NULL; + cts_err("Open file '%s' for test data failed %d", + filepath, ret); + return ret; + } + + if (cts_int_data_filp) + cts_dump_int_tsdata(header, sizeof(header)); + + return 0; +} + +static void cts_stop_dump_int_data_to_file(void) +{ + int r; + + cts_info("Stop dump test data to file"); + + if (cts_int_data_filp) { + r = filp_close(cts_int_data_filp, NULL); + if (r) { + cts_err("Close test data file failed %d", r); + } + cts_int_data_filp = NULL; + } else { + cts_warn("Stop dump tsdata to file with filp = NULL"); + } +} + +static void cts_redump_header_data_to_file(struct chipone_ts_data *cts_data, + const char *filepath, bool append) +{ + int ret; + u32 cnt; + u8 header[24] = { + /* Flag */ 'C', 'h', 'i', 'p', 'o', 'n', 'e', + /* Header len */ 0x10, + /* Version */ 0x00, 0x00, 0x01 , 0x00, + /* Data type */ 0x00, 0x00, + /* Rows and Cols */ 32, 18, + /* Frame cnt */ 0x00, 0x00, 0x00, 0x00, + /* Total time */ 0x00, 0x00, 0x00, 0x00 + }; + + header[12] = cts_data->cts_dev.fwdata.int_data_types & 0xFF; + header[13] = (cts_data->cts_dev.fwdata.int_data_types >> 8) & 0xFF; + header[14] = cts_data->cts_dev.fwdata.rows; + header[15] = cts_data->cts_dev.fwdata.cols; + + if (old_cnt == 0) { + cnt = 0xffffffff - cts_data->cts_dev.rtdata.dump_cnt; + } else { + cnt = old_cnt; + } + + header[16] = cnt & 0xff; + header[17] = (cnt >> 8) & 0xff; + header[18] = (cnt >> 16) & 0xff; + header[19] = (cnt >> 24) & 0xff; + + cts_int_data_filp = filp_open(filepath, + O_WRONLY | O_CREAT | O_WRONLY, + S_IRUGO | S_IWUGO); + if (IS_ERR(cts_int_data_filp)) { + ret = PTR_ERR(cts_int_data_filp); + cts_int_data_filp = NULL; + cts_err("Open file '%s' for test data failed %d", + filepath, ret); + return; + } + + if (cts_int_data_filp) + cts_dump_int_tsdata(header, sizeof(header)); + + if (cts_int_data_filp) { + int r = filp_close(cts_int_data_filp, NULL); + if (r) { + cts_err("Close test data file failed %d", r); + } + cts_int_data_filp = NULL; + } else { + cts_warn("Stop dump tsdata to file with filp = NULL"); + } + + return; +} + +static ssize_t dump_int_data_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct chipone_ts_data *cts_data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "Dumping: %s\n", + cts_data->cts_dev.rtdata.dumping ? "Y" : "N"); +} + +static ssize_t dump_int_data_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct chipone_ts_data *cts_data = dev_get_drvdata(dev); + u8 dumping = 0; + int ret = 0; + + parse_arg(buf, count); + + if (argc != 2) { + cts_err("Invalid num args != 2%d", argc); + return -EFAULT; + } + + ret = kstrtou8(argv[0], 0, &dumping); + if (ret) { + cts_err("Invalid int data dumping: %s", argv[0]); + return -EINVAL; + } + if (!!dumping) { + if (cts_int_data_filp) { + cts_err("IS Dumpping ... , please stop dumping then restart."); + return -EINVAL; + } + } + + ret = kstrtou32(argv[1], 0, &old_cnt); + if (ret) { + cts_err("Invalid int data dump cnt: %s", argv[1]); + return -EINVAL; + } + + if (!!dumping) { + cts_data->cts_dev.rtdata.dump_cnt = old_cnt; + cts_start_dump_int_data_to_file(chipone_bin_path, false); + } else { + cts_stop_dump_int_data_to_file(); + cts_redump_header_data_to_file(cts_data, chipone_bin_path, true); + } + cts_data->cts_dev.rtdata.dumping = !!dumping; + + return count; +} + +static DEVICE_ATTR(dump_int_data, S_IWUSR | S_IRUGO, + dump_int_data_show, dump_int_data_store); +#endif + static struct attribute *cts_dev_misc_atts[] = { &dev_attr_ic_type.attr, &dev_attr_program_mode.attr, @@ -2748,6 +2941,9 @@ static struct attribute *cts_dev_misc_atts[] = { #endif /* CFG_CTS_GESTURE */ &dev_attr_int_data_types.attr, &dev_attr_int_data_method.attr, +#ifdef CFG_DUMP_INT_DATA + &dev_attr_dump_int_data.attr, +#endif NULL }; diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.c b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.c index 823c85cd0443..aac848b496ba 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.c +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.c @@ -1145,90 +1145,57 @@ int cts_tcs_get_gestureinfo(const struct cts_device *cts_dev, struct cts_device_gesture_info *gesture_info) { int ret = 0; - size_t size = cts_dev->fwdata.int_data_size; - - if (!size) - size = TOUCH_INFO_SIZ + TCS_REPLY_TAIL_SIZ; - - memset(gesture_info, 0, sizeof(*gesture_info)); - - if ((cts_dev->fwdata.int_data_method == INT_DATA_METHOD_NONE) || - (cts_dev->fwdata.int_data_method == INT_DATA_METHOD_DEBUG)) { - dump_flag = 0; - ret = - cts_tcs_spi_read_1_cs(cts_dev, - TP_STD_CMD_TP_DATA_COORDINATES_RO, - cts_dev->rtdata.int_data, size); - dump_flag = 1; - mdelay(1); - if (cts_tcs_clr_gstr_ready_flag(cts_dev)) - cts_err("Clear gesture ready flag failed"); - - if (!ret) - memcpy(gesture_info, cts_dev->rtdata.int_data, - sizeof(*gesture_info)); + size_t size = sizeof(*gesture_info) + TCS_REPLY_TAIL_SIZ; + ret = cts_tcs_spi_read_1_cs(cts_dev, TP_STD_CMD_TP_DATA_COORDINATES_RO, + cts_dev->rtdata.int_data, size); + if (cts_tcs_clr_gstr_ready_flag(cts_dev)) { + cts_err("Clear gesture ready flag failed"); + } + if (ret < 0) { + cts_err("Get gesture info failed: ret=%d", ret); return ret; - } else if (cts_dev->fwdata.int_data_method == INT_DATA_METHOD_HOST || - cts_dev->fwdata.int_data_method == INT_DATA_METHOD_POLLING) { - dump_flag = 0; - ret = - cts_tcs_spi_read_1_cs(cts_dev, - TP_STD_CMD_TP_DATA_COORDINATES_RO, - cts_dev->rtdata.int_data, size); - dump_flag = 1; - mdelay(1); - if (cts_tcs_clr_gstr_ready_flag(cts_dev)) - cts_err("Clear gesture ready flag failed"); - - if (!ret) - memcpy(gesture_info, cts_dev->rtdata.int_data, sizeof(*gesture_info)); - return ret; + } + if (!ret) { + memcpy(gesture_info, cts_dev->rtdata.int_data, sizeof(*gesture_info)); } return ret; } -int cts_tcs_get_touchinfo(const struct cts_device *cts_dev, +#ifdef CFG_DUMP_INT_DATA +extern void cts_dump_int_tsdata(const u8 *data, size_t size); +#endif +int cts_tcs_get_touchinfo(struct cts_device *cts_dev, struct cts_device_touch_info *touch_info) { int ret = -1; size_t size = cts_dev->fwdata.int_data_size; + u8 method = cts_dev->fwdata.int_data_method; if (!size) - size = TOUCH_INFO_SIZ + TCS_REPLY_TAIL_SIZ; + size = TOUCH_INFO_SIZ; memset(touch_info, 0, sizeof(*touch_info)); - if ((cts_dev->fwdata.int_data_method == INT_DATA_METHOD_NONE) || - (cts_dev->fwdata.int_data_method == INT_DATA_METHOD_DEBUG)) { - dump_flag = 0; - ret = - cts_tcs_spi_read_1_cs(cts_dev, - TP_STD_CMD_TP_DATA_COORDINATES_RO, - cts_dev->rtdata.int_data, size); - dump_flag = 1; - if (!ret) { - memcpy(touch_info, cts_dev->rtdata.int_data, - sizeof(*touch_info)); - } + ret = cts_tcs_spi_read_1_cs(cts_dev, TP_STD_CMD_TP_DATA_COORDINATES_RO, + cts_dev->rtdata.int_data, size); + if (ret) { + cts_err("tcs_spi_read_1_cs failed"); + return ret; + } - return ret; - } else if (cts_dev->fwdata.int_data_method == INT_DATA_METHOD_HOST || - cts_dev->fwdata.int_data_method == INT_DATA_METHOD_POLLING) { - dump_flag = 0; - ret = - cts_tcs_spi_read_1_cs(cts_dev, - TP_STD_CMD_TP_DATA_COORDINATES_RO, - cts_dev->rtdata.int_data, size); - dump_flag = 1; - mdelay(1); - if (cts_tcs_clr_data_ready_flag(cts_dev)) - cts_err("Clear data ready flag failed"); - if (!ret) - memcpy(touch_info, cts_dev->rtdata.int_data, - sizeof(*touch_info)); - return ret; + memcpy(touch_info, cts_dev->rtdata.int_data, sizeof(*touch_info)); + + if (method == INT_DATA_METHOD_HOST) { +#ifdef CFG_DUMP_INT_DATA + if (cts_dev->rtdata.dumping) { + if ((--cts_dev->rtdata.dump_cnt) == 0) + cts_dev->rtdata.dumping = false; + cts_dump_int_tsdata(cts_dev->rtdata.int_data, size - 5); + } +#endif + udelay(200); } return ret; @@ -1697,7 +1664,7 @@ struct cts_dev_ops tcs_ops = { .get_int_mode = cts_tcs_get_int_mode, .get_int_keep_time = cts_tcs_get_int_keep_time, .get_esd_method = cts_tcs_get_esd_method, - .get_gestureinfo = cts_tcs_get_gestureinfo, + .get_gestureinfo = cts_tcs_get_gestureinfo, .get_touchinfo = cts_tcs_get_touchinfo, .get_esd_protection = cts_tcs_get_esd_protection, .get_data_ready_flag = cts_tcs_get_data_ready_flag, diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.h b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.h index ec8ba18f923d..739ac654ec61 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.h +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.h @@ -49,7 +49,7 @@ int cts_tcs_get_int_keep_time(const struct cts_device *cts_dev, u16 *int_keep_time); int cts_tcs_get_esd_method(const struct cts_device *cts_dev, u8 *esd_method); -int cts_tcs_get_touchinfo(const struct cts_device *cts_dev, +int cts_tcs_get_touchinfo(struct cts_device *cts_dev, struct cts_device_touch_info *touch_info); int cts_tcs_get_esd_protection(const struct cts_device *cts_dev, u8 *esd_protection); @@ -136,6 +136,7 @@ enum TcsCmdIndex { TP_STD_CMD_SYS_STS_WORK_MODE_RW, TP_STD_CMD_SYS_STS_DAT_RDY_FLAG_RW, TP_STD_CMD_SYS_STS_PWR_STATE_RW, + TP_STD_CMD_SYS_STS_CHARGER_PLUGIN_RW, TP_STD_CMD_SYS_STS_DDI_CODE_VER_RO, TP_STD_CMD_SYS_STS_DAT_TRANS_IN_NORMAL_RW, TP_STD_CMD_SYS_STS_VSTIM_LVL_RW, @@ -150,6 +151,8 @@ enum TcsCmdIndex { TP_STD_CMD_SYS_STS_DATA_CAPTURE_SUPPORT_RO, TP_STD_CMD_SYS_STS_DATA_CAPTURE_EN_RW, TP_STD_CMD_SYS_STS_DATA_CAPTURE_FUNC_MAP_RW, + TP_STD_CMD_SYS_STS_PANEL_DIRECTION_RW, + TP_STD_CMD_SYS_STS_GAME_MODE_RW, TP_STD_CMD_GSTR_WAKEUP_EN_RW, TP_STD_CMD_GSTR_DAT_RDY_FLAG_GSTR_RW, @@ -200,6 +203,7 @@ static TcsCmdValue_t TcsCmdValue[] = { { 0, 2, 1, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_WORK_MODE_RW */ { 0, 2, 3, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_DAT_RDY_FLAG_RW */ { 0, 2, 4, 1, 1, 1 }, /* TP_STD_CMD_SYS_STS_PWR_STATE_RW */ + { 0, 2, 5, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_CHARGER_PLUGIN_RW */ { 0, 2, 6, 1, 0, 0 }, /* TP_STD_CMD_SYS_STS_DDI_CODE_VER_RO */ { 0, 2, 7, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_DAT_TRANS_IN_NORMAL_RW */ { 0, 2, 8, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_VSTIM_LVL_RW */ @@ -214,6 +218,8 @@ static TcsCmdValue_t TcsCmdValue[] = { { 0, 2, 63, 1, 0, 0 }, /* TP_STD_CMD_SYS_STS_DATA_CAPTURE_SUPPORT_RO */ { 0, 2, 64, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_DATA_CAPTURE_EN_RW */ { 0, 2, 65, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_DATA_CAPTURE_FUNC_MAP_RW */ + { 0, 2, 66, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_PANEL_DIRECTION_RW */ + { 0, 2, 78, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_GAME_MODE_RW */ { 0, 3, 1, 1, 1, 0 }, /* TP_STD_CMD_GSTR_WAKEUP_EN_RW */ { 0, 3, 30, 1, 1, 0 }, /* TP_STD_CMD_GSTR_DAT_RDY_FLAG_GSTR_RW */ diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_test.c b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_test.c index 03c9ab489bb1..604a57703b08 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_test.c +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_test.c @@ -977,6 +977,7 @@ int cts_test_rawdata(struct cts_device *cts_dev, struct cts_test_param *param) int num_nodes; int tsdata_frame_size; int frame; + int fail_frame = 0; u16 *rawdata = NULL; ktime_t start_time, end_time, delta_time; int i; @@ -1095,6 +1096,8 @@ int cts_test_rawdata(struct cts_device *cts_dev, struct cts_test_param *param) param->min, param->max); if (ret) { cts_err("Rawdata test failed %d", ret); + fail_frame++; + cts_err("Rawdata test has %d nodes failed", ret); if (stop_test_if_validate_fail) break; } @@ -1122,17 +1125,16 @@ free_mem: show_test_result: end_time = ktime_get(); delta_time = ktime_sub(end_time, start_time); - if (ret > 0) - cts_info("Rawdata test has %d nodes FAIL, ELAPSED TIME: %lldms", - ret, ktime_to_ms(delta_time)); - else if (ret < 0) - cts_info("Rawdata test FAIL %d(%s), ELAPSED TIME: %lldms", - ret, cts_strerror(ret), ktime_to_ms(delta_time)); - else - cts_info("Rawdata test PASS, ELAPSED TIME: %lldms", - ktime_to_ms(delta_time)); - return ret; + if (fail_frame > 0) { + cts_info("Rawdata test has %d frame(s) FAIL, ELAPSED TIME: %lldms", + fail_frame, ktime_to_ms(delta_time)); + } else if (fail_frame == 0) { + cts_info("Rawdata test PASS, ELAPSED TIME: %lldms", + ktime_to_ms(delta_time)); + } + + return fail_frame; } int cts_test_noise(struct cts_device *cts_dev, struct cts_test_param *param) diff --git a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tool.c b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tool.c index eb2672bd75a2..7d9f0d684a9c 100644 --- a/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tool.c +++ b/drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tool.c @@ -9,6 +9,10 @@ #ifdef CONFIG_CTS_LEGACY_TOOL +#define CTS_TOOL_IOCTL_TCS_RW_BUF_MAX_SIZ 1024 +#define CTS_TOOL_IOCTL_TCS_RW_OPFLAG_READ 1 +#define CTS_TOOL_IOCTL_TCS_RW_OPFLAG_WRITE 2 + #pragma pack(1) /** Tool command structure */ struct cts_tool_cmd { @@ -24,6 +28,13 @@ struct cts_tool_cmd { u8 data[PAGE_SIZE]; }; +struct cts_ioctl_tcs_rw_data { + u32 opflags; + u32 txlen; + u32 rxlen; + u8 __user *txbuf; + u8 __user *rxbuf; +}; #pragma pack() #define CTS_TOOL_CMD_HEADER_LENGTH (16) @@ -45,6 +56,7 @@ enum cts_tool_cmd_code { CTS_TOOL_CMD_TCS_READ_DDI_CMD = 30, CTS_TOOL_CMD_TCS_READ_FW_CMD = 32, CTS_TOOL_CMD_GET_BASE_DATA = 34, + CTS_TOOL_CMD_GET_INT_DATAS = 36, CTS_TOOL_CMD_UPDATE_PANEL_PARAM_IN_SRAM = 1, CTS_TOOL_CMD_DOWNLOAD_FIRMWARE_WITH_FILENAME = 3, @@ -58,6 +70,7 @@ enum cts_tool_cmd_code { CTS_TOOL_CMD_TCS_WRITE_FW_CMD = 25, CTS_TOOL_CMD_TCS_ENABLE_GET_RAWDATA_CMD = 27, CTS_TOOL_CMD_TCS_DISABLE_GET_RAWDATA_CMD = 29, + CTS_TOOL_CMD_SET_INT_DATA_TYPE_AND_METHOD = 31, }; @@ -67,17 +80,19 @@ struct cts_test_ioctl_data { }; -#define CTS_TOOL_IOCTL_GET_DRIVER_VERSION _IOR('C', 0x00, unsigned int *) -#define CTS_TOOL_IOCTL_GET_DEVICE_TYPE _IOR('C', 0x01, unsigned int *) -#define CTS_TOOL_IOCTL_GET_FW_VERSION _IOR('C', 0x02, unsigned short *) -#define CTS_TOOL_IOCTL_GET_RESOLUTION _IOR('C', 0x03, unsigned int *) /* X in LSW, Y in MSW */ -#define CTS_TOOL_IOCTL_GET_ROW_COL _IOR('C', 0x04, unsigned int *) /* row in LSW, col in MSW */ -#define CTS_TOOL_IOCTL_GET_MODULE_ID _IOWR('C', 0x05, unsigned int *) +#define CTS_TOOL_IOCTL_GET_DRIVER_VERSION _IOR('C', 0x00, u32 *) +#define CTS_TOOL_IOCTL_GET_DEVICE_TYPE _IOR('C', 0x01, u32 *) +#define CTS_TOOL_IOCTL_GET_FW_VERSION _IOR('C', 0x02, u16 *) +#define CTS_TOOL_IOCTL_GET_RESOLUTION _IOR('C', 0x03, u32 *) /* X in LSW, Y in MSW */ +#define CTS_TOOL_IOCTL_GET_ROW_COL _IOR('C', 0x04, u32 *) /* row in LSW, col in MSW */ +#define CTS_TOOL_IOCTL_GET_MODULE_ID _IOWR('C', 0x05, u32 *) #define CTS_TOOL_IOCTL_TEST _IOWR('C', 0x10, struct cts_test_ioctl_data *) #define CTS_TOOL_IOCTL_RDWR_REG _IOWR('C', 0x20, struct cts_rdwr_reg_ioctl_data *) #define CTS_TOOL_IOCTL_UPGRADE_FW _IOWR('C', 0x21, struct cts_upgrade_fw_ioctl_data *) +#define CTS_TOOL_IOCTL_TCS_RW _IOWR('C', 0x30, struct cts_ioctl_tcs_rw_data *) + #define CTS_DRIVER_VERSION_CODE ((CFG_CTS_DRIVER_MAJOR_VERSION << 16) | \ (CFG_CTS_DRIVER_MINOR_VERSION << 8) | \ (CFG_CTS_DRIVER_PATCH_VERSION << 0)) @@ -185,7 +200,10 @@ static ssize_t cts_tool_read(struct file *file, ret); } break; - + case CTS_TOOL_CMD_GET_INT_DATAS: + memcpy((u8 *)cmd->data, cts_dev->rtdata.int_data, cts_dev->fwdata.int_data_size); + cmd->data_len = cts_dev->fwdata.int_data_size; + break; case CTS_TOOL_CMD_READ_HOSTCOMM: ret = cts_fw_reg_readb(cts_dev, get_unaligned_le16(cmd->addr), cmd->data); @@ -447,6 +465,10 @@ static ssize_t cts_tool_write(struct file *file, if (ret) cts_err("Disable get touch data failed"); break; + case CTS_TOOL_CMD_SET_INT_DATA_TYPE_AND_METHOD: + cts_set_int_data_types(cts_dev, cmd->data[0]); + cts_set_int_data_method(cts_dev, cmd->data[1]); + break; case CTS_TOOL_CMD_UPDATE_PANEL_PARAM_IN_SRAM: cts_info("Write panel param len %u data\n", cmd->data_len); ret = cts_fw_reg_writesb(cts_dev, CTS_DEVICE_FW_REG_PANEL_PARAM, @@ -638,6 +660,89 @@ static ssize_t cts_tool_write(struct file *file, return ret ? 0 : cmd->data_len + CTS_TOOL_CMD_HEADER_LENGTH; } + +static long cts_ioctl_tcs_rw(struct cts_device *cts_dev, + struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + struct cts_ioctl_tcs_rw_data rwdata; + u8 *txbuf = NULL; + u8 *rxbuf = NULL; + + if (copy_from_user(&rwdata, + (struct cts_ioctl_tcs_rw_data __user *)arg, + sizeof(rwdata))) { + cts_err("Copy ioctl tcs rw arg to kernel failed"); + return -EFAULT; + } + + if ((rwdata.opflags != CTS_TOOL_IOCTL_TCS_RW_OPFLAG_READ) && + (rwdata.opflags != CTS_TOOL_IOCTL_TCS_RW_OPFLAG_WRITE)) + { + cts_err("ioctl tcs rw with invalid opflags %u", rwdata.opflags); + return -EINVAL; + } + + if (rwdata.txlen > CTS_TOOL_IOCTL_TCS_RW_BUF_MAX_SIZ) { + cts_err("Send too long: %d", rwdata.txlen); + return -EINVAL; + } + + if (rwdata.rxlen > CTS_TOOL_IOCTL_TCS_RW_BUF_MAX_SIZ) { + cts_err("Recv too long: %d", rwdata.rxlen); + return -EINVAL; + } + + if (!rwdata.txbuf || !rwdata.rxbuf) { + cts_err("Txbuf of Rxbuf is NULL!"); + return -EINVAL; + } + + txbuf = memdup_user(rwdata.txbuf, rwdata.txlen); + if (IS_ERR(txbuf)) { + ret = PTR_ERR(txbuf); + cts_err("Memdup txbuf failed %d", ret); + txbuf = NULL; + goto free_buf; + } + + rxbuf = memdup_user(rwdata.rxbuf, rwdata.rxlen); + if (IS_ERR(rxbuf)) { + ret = PTR_ERR(rxbuf); + cts_err("Memdup rxbuf failed %d", ret); + rxbuf = NULL; + goto free_buf; + } + + cts_lock_device(cts_dev); + ret = cts_spi_xtrans(cts_dev, txbuf, rwdata.txlen, rxbuf, rwdata.rxlen); + cts_unlock_device(cts_dev); + if (ret < 0) { + cts_err("Trans failed %d", ret); + goto free_buf; + } + + ret = copy_to_user(rwdata.rxbuf, rxbuf, rwdata.rxlen); + if (ret < 0) { + cts_err("Copy to user failed %d", ret); + goto free_buf; + } + + ret = 0; + +free_buf: + if (txbuf) { + kfree(txbuf); + txbuf = NULL; + } + if (rxbuf) { + kfree(rxbuf); + rxbuf = NULL; + } + + return ret; +} + static int cts_ioctl_test(struct cts_device *cts_dev, u32 ntests, struct cts_test_param *tests) { @@ -1065,7 +1170,7 @@ static long cts_tool_ioctl(struct file *file, unsigned int cmd, unsigned int modid; int ret; - cts_info("ioctl, cmd=0x%04x, arg=0x%02lx", cmd, arg); + cts_info("ioctl, cmd=0x%016x, arg=0x%016lx", cmd, arg); cts_data = file->private_data; if (cts_data == NULL) { @@ -1121,7 +1226,10 @@ static long cts_tool_ioctl(struct file *file, unsigned int cmd, } return cts_ioctl_test(cts_dev, test_arg.ntests, tests_pa); - } + } + case CTS_TOOL_IOCTL_TCS_RW:{ + return cts_ioctl_tcs_rw(cts_dev, file, cmd, arg); + } default: break;