summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuper Liu <supercjliu@google.com>2023-04-06 05:19:59 +0000
committerSuper Liu <supercjliu@google.com>2023-04-06 08:02:14 +0000
commit8da5744724d93c45251f91a2f09c5420de8da65c (patch)
tree9d21ed3b371727a1e000b8b5fb1e0644c67a4c11
parenta17332d87e6dd4f008e9575cb2f5a15fffa24fe9 (diff)
downloadgoodix_touch-8da5744724d93c45251f91a2f09c5420de8da65c.tar.gz
Revert^2 "touch/goodix: Import driver v1.2.5"
a17332d87e6dd4f008e9575cb2f5a15fffa24fe9 Change-Id: I6bd8676543a4370522f1df88c676f2075659e12e
-rw-r--r--goodix_brl_fwupdate.c466
-rw-r--r--goodix_brl_hw.c259
-rw-r--r--goodix_brl_i2c.c50
-rw-r--r--goodix_brl_spi.c166
-rw-r--r--goodix_cfg_bin.c2
-rw-r--r--goodix_ts_core.c875
-rw-r--r--goodix_ts_core.h292
-rw-r--r--goodix_ts_gesture.c345
-rw-r--r--goodix_ts_inspect.c20
-rw-r--r--goodix_ts_proc.c333
-rw-r--r--goodix_ts_tools.c195
-rw-r--r--goodix_ts_utils.c15
12 files changed, 1098 insertions, 1920 deletions
diff --git a/goodix_brl_fwupdate.c b/goodix_brl_fwupdate.c
index 0fb81e6..f7136fa 100644
--- a/goodix_brl_fwupdate.c
+++ b/goodix_brl_fwupdate.c
@@ -137,67 +137,12 @@ struct update_info_t update_brd = {
ENABLE_MISCTL_BRD,
};
-/**
- * fw_subsys_info - subsytem firmware information
- * @type: sybsystem type
- * @size: firmware size
- * @flash_addr: flash address
- * @data: firmware data
- */
-struct fw_subsys_info {
- u8 type;
- u32 size;
- u32 flash_addr;
- const u8 *data;
-};
-
-/**
- * firmware_summary
- * @size: fw total length
- * @checksum: checksum of fw
- * @hw_pid: mask pid string
- * @hw_pid: mask vid code
- * @fw_pid: fw pid string
- * @fw_vid: fw vid code
- * @subsys_num: number of fw subsystem
- * @chip_type: chip type
- * @protocol_ver: firmware packing
- * protocol version
- * @bus_type: 0 represent I2C, 1 for SPI
- * @subsys: sybsystem info
- */
-#pragma pack(1)
-struct firmware_summary {
- u32 size;
- u32 checksum;
- u8 hw_pid[6];
- u8 hw_vid[3];
- u8 fw_pid[FW_PID_LEN];
- u8 fw_vid[FW_VID_LEN];
- u8 subsys_num;
- u8 chip_type;
- u8 protocol_ver;
- u8 bus_type;
- u8 flash_protect;
- // u8 reserved[8];
- struct fw_subsys_info subsys[FW_SUBSYS_MAX_NUM];
-};
-#pragma pack()
-
-/**
- * firmware_data - firmware data structure
- * @fw_summary: firmware information
- * @firmware: firmware data structure
- */
-struct firmware_data {
- struct firmware_summary fw_summary;
- const struct firmware *firmware;
- struct firmware *fw_sysfs;
-};
-
-struct config_data {
- u8 *data;
- int size;
+enum compare_status {
+ COMPARE_EQUAL = 0,
+ COMPARE_NOCODE,
+ COMPARE_PIDMISMATCH,
+ COMPARE_FW_NOTEQUAL,
+ COMPARE_CFG_NOTEQUAL,
};
#pragma pack(1)
@@ -218,90 +163,6 @@ struct goodix_flash_cmd {
};
#pragma pack()
-enum update_status {
- UPSTA_NOTWORK = 0,
- UPSTA_PREPARING,
- UPSTA_UPDATING,
- UPSTA_SUCCESS,
- UPSTA_FAILED
-};
-
-enum compare_status {
- COMPARE_EQUAL = 0,
- COMPARE_NOCODE,
- COMPARE_PIDMISMATCH,
- COMPARE_FW_NOTEQUAL,
- COMPARE_CFG_NOTEQUAL,
-};
-
-/**
- * fw_update_ctrl - structure used to control the
- * firmware update process
- * @initialized: struct init state
- * @mode: indicate weather reflash config or not, fw data source,
- * and run on block mode or not.
- * @status: update status
- * @progress: indicate the progress of update
- * @fw_data: firmware data
- * @fw_name: firmware name
- * @attr_fwimage: sysfs bin attrs, for storing fw image
- * @fw_data_src: firmware data source form sysfs, request or head file
- * @kobj: pointer to the sysfs kobject
- */
-struct fw_update_ctrl {
- struct mutex mutex;
- int initialized;
- char fw_name[GOODIX_MAX_STR_LABEL_LEN];
- int mode;
- enum update_status status;
- int spend_time;
-
- struct firmware_data fw_data;
- struct goodix_ic_config *ic_config;
- struct goodix_ts_core *core_data;
- struct update_info_t *update_info;
-
- struct attribute_group attrs;
- struct kobject *kobj;
-};
-static struct fw_update_ctrl goodix_fw_update_ctrl;
-static struct goodix_ic_config one_binary_cfg;
-
-static int goodix_fw_update_reset(int delay)
-{
- struct goodix_ts_hw_ops *hw_ops;
-
- hw_ops = goodix_fw_update_ctrl.core_data->hw_ops;
- return hw_ops->reset(goodix_fw_update_ctrl.core_data, delay);
-}
-
-static int get_fw_version_info(struct goodix_fw_version *fw_version)
-{
- struct goodix_ts_hw_ops *hw_ops =
- goodix_fw_update_ctrl.core_data->hw_ops;
-
- return hw_ops->read_version(
- goodix_fw_update_ctrl.core_data, fw_version);
-}
-
-static int goodix_reg_write(
- unsigned int addr, unsigned char *data, unsigned int len)
-{
- struct goodix_ts_hw_ops *hw_ops =
- goodix_fw_update_ctrl.core_data->hw_ops;
-
- return hw_ops->write(goodix_fw_update_ctrl.core_data, addr, data, len);
-}
-
-static int goodix_reg_read(
- unsigned int addr, unsigned char *data, unsigned int len)
-{
- struct goodix_ts_hw_ops *hw_ops =
- goodix_fw_update_ctrl.core_data->hw_ops;
-
- return hw_ops->read(goodix_fw_update_ctrl.core_data, addr, data, len);
-}
-
/**
* goodix_parse_firmware - parse firmware header information
* and subsystem information from firmware data buffer
@@ -311,26 +172,24 @@ static int goodix_reg_read(
* return: 0 - OK, < 0 - error
*/
/* sizeof(length) + sizeof(checksum) */
-
-static int goodix_parse_firmware(struct firmware_data *fw_data)
+static int goodix_parse_firmware(struct goodix_ts_core *cd,
+ struct firmware_data *fw_data)
{
const struct firmware *firmware;
struct firmware_summary *fw_summary;
unsigned int i, fw_offset, info_offset;
u32 checksum;
- int ic_type = goodix_fw_update_ctrl.core_data->bus->ic_type;
+ int ic_type = cd->bus->ic_type;
int subsys_info_offset =
- goodix_fw_update_ctrl.update_info->subsys_info_offset;
- int header_size = goodix_fw_update_ctrl.update_info->header_size;
+ cd->update_ctrl.update_info->subsys_info_offset;
+ int header_size = cd->update_ctrl.update_info->header_size;
+ struct goodix_ic_config *one_binary_cfg = &cd->update_ctrl.one_binary_cfg;
int r = 0;
fw_summary = &fw_data->fw_summary;
/* copy firmware head info */
- if (goodix_fw_update_ctrl.mode & UPDATE_MODE_SRC_SYSFS)
- firmware = fw_data->fw_sysfs;
- else
- firmware = fw_data->firmware;
+ firmware = fw_data->firmware;
if (firmware->size < subsys_info_offset) {
ts_err("Invalid firmware size:%zu", firmware->size);
@@ -407,10 +266,10 @@ static int goodix_parse_firmware(struct firmware_data *fw_data)
ts_debug("Subsystem Ptr:%p", fw_summary->subsys[i].data);
if (fw_summary->subsys[i].type == CONFIG_DATA_TYPE) {
- one_binary_cfg.len = fw_summary->subsys[i].size;
- memcpy(one_binary_cfg.data, fw_summary->subsys[i].data,
- one_binary_cfg.len);
- goodix_fw_update_ctrl.ic_config = &one_binary_cfg;
+ one_binary_cfg->len = fw_summary->subsys[i].size;
+ memcpy(one_binary_cfg->data, fw_summary->subsys[i].data,
+ one_binary_cfg->len);
+ cd->update_ctrl.ic_config = one_binary_cfg;
}
}
@@ -442,33 +301,29 @@ err_size:
static int goodix_fw_version_compare(struct fw_update_ctrl *fwu_ctrl)
{
int ret = 0;
- struct goodix_fw_version fw_version;
+ struct goodix_ts_core *cd = fwu_ctrl->core_data;
+ struct goodix_fw_version *ic_ver = &cd->fw_version;
+ struct goodix_ic_info *ic_info = &cd->ic_info;
struct firmware_summary *fw_summary = &fwu_ctrl->fw_data.fw_summary;
- u32 config_id_reg = goodix_fw_update_ctrl.update_info->config_id_reg;
u32 file_cfg_id;
- u32 ic_cfg_id;
/* compare fw_version */
- ret = get_fw_version_info(&fw_version);
- if (ret)
- return -EINVAL;
-
- if (!memcmp(fw_version.rom_pid, GOODIX_NOCODE, 6) ||
- !memcmp(fw_version.patch_pid, GOODIX_NOCODE, 6)) {
+ if (!memcmp(ic_ver->rom_pid, GOODIX_NOCODE, 6) ||
+ !memcmp(ic_ver->patch_pid, GOODIX_NOCODE, 6)) {
ts_info("there is no code in the chip");
return COMPARE_NOCODE;
}
- if (memcmp(fw_version.patch_pid, fw_summary->fw_pid, FW_PID_LEN)) {
- ts_err("Product ID mismatch:%s != %s", fw_version.patch_pid,
+ if (memcmp(ic_ver->patch_pid, fw_summary->fw_pid, FW_PID_LEN)) {
+ ts_err("Product ID mismatch:%s != %s", ic_ver->patch_pid,
fw_summary->fw_pid);
return COMPARE_PIDMISMATCH;
}
- ret = memcmp(fw_version.patch_vid, fw_summary->fw_vid, FW_VID_LEN);
+ ret = memcmp(ic_ver->patch_vid, fw_summary->fw_vid, FW_VID_LEN);
if (ret) {
ts_info("active firmware version:%*ph", FW_VID_LEN,
- fw_version.patch_vid);
+ ic_ver->patch_vid);
ts_info("firmware file version: %*ph", FW_VID_LEN,
fw_summary->fw_vid);
return COMPARE_FW_NOTEQUAL;
@@ -479,10 +334,8 @@ static int goodix_fw_version_compare(struct fw_update_ctrl *fwu_ctrl)
if (fwu_ctrl->ic_config && fwu_ctrl->ic_config->len > 0) {
file_cfg_id =
goodix_get_file_config_id(fwu_ctrl->ic_config->data);
- goodix_reg_read(
- config_id_reg, (u8 *)&ic_cfg_id, sizeof(ic_cfg_id));
- if (ic_cfg_id != file_cfg_id) {
- ts_info("ic_cfg_id:0x%x != file_cfg_id:0x%x", ic_cfg_id,
+ if (ic_info->version.config_id != file_cfg_id) {
+ ts_info("ic_cfg_id:0x%x != file_cfg_id:0x%x", ic_info->version.config_id,
file_cfg_id);
return COMPARE_CFG_NOTEQUAL;
}
@@ -502,7 +355,7 @@ static int goodix_fw_version_compare(struct fw_update_ctrl *fwu_ctrl)
* return: 0 write success and confirm ok
* < 0 failed
*/
-static int goodix_reg_write_confirm(
+static int goodix_reg_write_confirm(struct goodix_ts_core *cd,
unsigned int addr, unsigned char *data, unsigned int len)
{
u8 *cfm = NULL;
@@ -518,11 +371,11 @@ static int goodix_reg_write_confirm(
}
for (i = 0; i < GOODIX_BUS_RETRY_TIMES; i++) {
- r = goodix_reg_write(addr, data, len);
+ r = cd->hw_ops->write(cd, addr, data, len);
if (r < 0)
goto exit;
- r = goodix_reg_read(addr, cfm, len);
+ r = cd->hw_ops->read(cd, addr, cfm, len);
if (r < 0)
goto exit;
@@ -547,11 +400,11 @@ exit:
* @fw_data: firmware data
* return 0 ok, <0 error
*/
-static int goodix_load_isp(struct firmware_data *fw_data)
+static int goodix_load_isp(struct goodix_ts_core *cd, struct firmware_data *fw_data)
{
struct goodix_fw_version isp_fw_version;
struct fw_subsys_info *fw_isp;
- u32 isp_ram_reg = goodix_fw_update_ctrl.update_info->isp_ram_reg;
+ u32 isp_ram_reg = cd->update_ctrl.update_info->isp_ram_reg;
u8 reg_val[8] = { 0x00 };
int r;
@@ -559,8 +412,8 @@ static int goodix_load_isp(struct firmware_data *fw_data)
fw_isp = &fw_data->fw_summary.subsys[0];
ts_info("Loading ISP start");
- r = goodix_reg_write_confirm(
- isp_ram_reg, (u8 *)fw_isp->data, fw_isp->size);
+ r = goodix_reg_write_confirm(cd, isp_ram_reg,
+ (u8 *)fw_isp->data, fw_isp->size);
if (r < 0) {
ts_err("Loading ISP error");
return r;
@@ -570,17 +423,16 @@ static int goodix_load_isp(struct firmware_data *fw_data)
/* SET BOOT OPTION TO 0X55 */
memset(reg_val, 0x55, 8);
- r = goodix_reg_write_confirm(HW_REG_CPU_RUN_FROM, reg_val, 8);
+ r = goodix_reg_write_confirm(cd, HW_REG_CPU_RUN_FROM, reg_val, 8);
if (r < 0) {
ts_err("Failed set REG_CPU_RUN_FROM flag");
return r;
}
ts_info("Success write [8]0x55 to 0x%x", HW_REG_CPU_RUN_FROM);
- if (goodix_fw_update_reset(100))
- ts_err("reset abnormal");
+ cd->hw_ops->reset(cd, 100);
/*check isp state */
- if (get_fw_version_info(&isp_fw_version)) {
+ if (cd->hw_ops->read_version(cd, &isp_fw_version)) {
ts_err("failed read isp version");
return -2;
}
@@ -606,6 +458,8 @@ static int goodix_update_prepare(struct fw_update_ctrl *fwu_ctrl)
u32 misctl_reg = fwu_ctrl->update_info->misctl_reg;
u32 watch_dog_reg = fwu_ctrl->update_info->watch_dog_reg;
u32 enable_misctl_val = fwu_ctrl->update_info->enable_misctl_val;
+ struct goodix_ts_core *cd = fwu_ctrl->core_data;
+ struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
u8 reg_val[4] = { 0 };
u8 temp_buf[64] = { 0 };
int retry = 20;
@@ -613,18 +467,17 @@ static int goodix_update_prepare(struct fw_update_ctrl *fwu_ctrl)
/*reset IC*/
ts_info("firmware update, reset");
- if (goodix_fw_update_reset(5))
- ts_err("reset abnormal");
+ hw_ops->reset(cd, 5);
retry = 100;
/* Hold cpu*/
do {
reg_val[0] = 0x01;
reg_val[1] = 0x00;
- r = goodix_reg_write(HOLD_CPU_REG_W, reg_val, 2);
- r |= goodix_reg_read(HOLD_CPU_REG_R, &temp_buf[0], 4);
- r |= goodix_reg_read(HOLD_CPU_REG_R, &temp_buf[4], 4);
- r |= goodix_reg_read(HOLD_CPU_REG_R, &temp_buf[8], 4);
+ r = hw_ops->write(cd, HOLD_CPU_REG_W, reg_val, 2);
+ r |= hw_ops->read(cd, HOLD_CPU_REG_R, &temp_buf[0], 4);
+ r |= hw_ops->read(cd, HOLD_CPU_REG_R, &temp_buf[4], 4);
+ r |= hw_ops->read(cd, HOLD_CPU_REG_R, &temp_buf[8], 4);
if (!r && !memcmp(&temp_buf[0], &temp_buf[4], 4) &&
!memcmp(&temp_buf[4], &temp_buf[8], 4) &&
!memcmp(&temp_buf[0], &temp_buf[8], 4)) {
@@ -641,20 +494,20 @@ static int goodix_update_prepare(struct fw_update_ctrl *fwu_ctrl)
ts_info("Success hold CPU");
/* enable misctl clock */
- if (fwu_ctrl->core_data->bus->ic_type == IC_TYPE_BERLIN_D ||
- fwu_ctrl->core_data->bus->ic_type == IC_TYPE_NOTTINGHAM)
- goodix_reg_write(misctl_reg, (u8 *)&enable_misctl_val, 4);
+ if (cd->bus->ic_type == IC_TYPE_BERLIN_D ||
+ cd->bus->ic_type == IC_TYPE_NOTTINGHAM)
+ hw_ops->write(cd, misctl_reg, (u8 *)&enable_misctl_val, 4);
else
- goodix_reg_write(misctl_reg, (u8 *)&enable_misctl_val, 1);
+ hw_ops->write(cd, misctl_reg, (u8 *)&enable_misctl_val, 1);
ts_info("enable misctl clock");
- if (fwu_ctrl->core_data->bus->ic_type == IC_TYPE_BERLIN_A) {
+ if (cd->bus->ic_type == IC_TYPE_BERLIN_A) {
/* open ESD_KEY */
retry = 20;
do {
reg_val[0] = 0x95;
- r = goodix_reg_write(ESD_KEY_REG, reg_val, 1);
- r |= goodix_reg_read(ESD_KEY_REG, temp_buf, 1);
+ r = hw_ops->write(cd, ESD_KEY_REG, reg_val, 1);
+ r |= hw_ops->read(cd, ESD_KEY_REG, temp_buf, 1);
if (!r && temp_buf[0] == 0x01)
break;
usleep_range(1000, 1100);
@@ -670,11 +523,11 @@ static int goodix_update_prepare(struct fw_update_ctrl *fwu_ctrl)
/* disable watch dog */
reg_val[0] = 0x00;
- r = goodix_reg_write(watch_dog_reg, reg_val, 1);
+ r = hw_ops->write(cd, watch_dog_reg, reg_val, 1);
ts_info("disable watch dog");
/* load ISP code and run form isp */
- r = goodix_load_isp(&fwu_ctrl->fw_data);
+ r = goodix_load_isp(cd, &fwu_ctrl->fw_data);
if (r < 0)
ts_err("Failed load and run isp");
@@ -684,17 +537,18 @@ static int goodix_update_prepare(struct fw_update_ctrl *fwu_ctrl)
/* goodix_send_flash_cmd: send command to read or write flash data
* @flash_cmd: command need to send.
*/
-static int goodix_send_flash_cmd(struct goodix_flash_cmd *flash_cmd)
+static int goodix_send_flash_cmd(struct goodix_ts_core *cd,
+ struct goodix_flash_cmd *flash_cmd)
{
int i, ret, retry;
struct goodix_flash_cmd tmp_cmd;
- u32 flash_cmd_reg = goodix_fw_update_ctrl.update_info->flash_cmd_reg;
+ u32 flash_cmd_reg = cd->update_ctrl.update_info->flash_cmd_reg;
ts_info("try send flash cmd:%*ph", (int)sizeof(flash_cmd->buf),
flash_cmd->buf);
memset(tmp_cmd.buf, 0, sizeof(tmp_cmd));
- ret = goodix_reg_write(
- flash_cmd_reg, flash_cmd->buf, sizeof(flash_cmd->buf));
+ ret = cd->hw_ops->write(cd, flash_cmd_reg,
+ flash_cmd->buf, sizeof(flash_cmd->buf));
if (ret) {
ts_err("failed send flash cmd %d", ret);
return ret;
@@ -702,8 +556,8 @@ static int goodix_send_flash_cmd(struct goodix_flash_cmd *flash_cmd)
retry = 5;
for (i = 0; i < retry; i++) {
- ret = goodix_reg_read(
- flash_cmd_reg, tmp_cmd.buf, sizeof(tmp_cmd.buf));
+ ret = cd->hw_ops->read(cd, flash_cmd_reg,
+ tmp_cmd.buf, sizeof(tmp_cmd.buf));
if (!ret && tmp_cmd.ack == FLASH_CMD_ACK_CHK_PASS)
break;
usleep_range(5000, 5100);
@@ -721,8 +575,8 @@ static int goodix_send_flash_cmd(struct goodix_flash_cmd *flash_cmd)
msleep(50);
retry = 20;
for (i = 0; i < retry; i++) {
- ret = goodix_reg_read(
- flash_cmd_reg, tmp_cmd.buf, sizeof(tmp_cmd.buf));
+ ret = cd->hw_ops->read(cd, flash_cmd_reg,
+ tmp_cmd.buf, sizeof(tmp_cmd.buf));
if (!ret && tmp_cmd.ack == FLASH_CMD_ACK_CHK_PASS &&
tmp_cmd.status == FLASH_CMD_W_STATUS_WRITE_OK) {
ts_info("flash status check pass");
@@ -760,16 +614,17 @@ static int goodix_send_flash_cmd(struct goodix_flash_cmd *flash_cmd)
}
}
-static int goodix_flash_package(
- u8 subsys_type, u8 *pkg, u32 flash_addr, u16 pkg_len)
+static int goodix_flash_package(struct goodix_ts_core *cd,
+ u8 subsys_type, u8 *pkg,
+ u32 flash_addr, u16 pkg_len)
{
int ret, retry;
struct goodix_flash_cmd flash_cmd;
- u32 isp_buffer_reg = goodix_fw_update_ctrl.update_info->isp_buffer_reg;
+ u32 isp_buffer_reg = cd->update_ctrl.update_info->isp_buffer_reg;
retry = 2;
do {
- ret = goodix_reg_write(isp_buffer_reg, pkg, pkg_len);
+ ret = cd->hw_ops->write(cd, isp_buffer_reg, pkg, pkg_len);
if (ret < 0) {
ts_err("Failed to write firmware packet");
return ret;
@@ -786,7 +641,7 @@ static int goodix_flash_package(
goodix_append_checksum(
&(flash_cmd.buf[2]), 9, CHECKSUM_MODE_U8_LE);
- ret = goodix_send_flash_cmd(&flash_cmd);
+ ret = goodix_send_flash_cmd(cd, &flash_cmd);
if (!ret) {
ts_info("success write package to 0x%05X, len %d",
flash_addr, pkg_len - 4);
@@ -807,7 +662,8 @@ static int goodix_flash_package(
* @subsys: subsystem information
* return: 0 ok, < 0 error
*/
-static int goodix_flash_subsystem(struct fw_subsys_info *subsys)
+static int goodix_flash_subsystem(struct goodix_ts_core *cd,
+ struct fw_subsys_info *subsys)
{
u32 data_size, offset;
u32 total_size;
@@ -840,7 +696,7 @@ static int goodix_flash_subsystem(struct fw_subsys_info *subsys)
goodix_append_checksum(
fw_packet, data_size, CHECKSUM_MODE_U16_LE);
- r = goodix_flash_package(subsys->type, fw_packet,
+ r = goodix_flash_package(cd, subsys->type, fw_packet,
subsys_base_addr + offset, data_size + 4);
if (r) {
ts_err("failed flash to 0x%05X,size:%u bytes",
@@ -884,7 +740,7 @@ static int goodix_flash_firmware(struct fw_update_ctrl *fw_ctrl)
subsys_cfg.size = GOODIX_CFG_MAX_SIZE;
subsys_cfg.flash_addr = config_data_reg;
subsys_cfg.type = CONFIG_DATA_TYPE;
- r = goodix_flash_subsystem(&subsys_cfg);
+ r = goodix_flash_subsystem(fw_ctrl->core_data, &subsys_cfg);
if (r) {
ts_err("failed flash config with ISP, %d", r);
return r;
@@ -895,7 +751,7 @@ static int goodix_flash_firmware(struct fw_update_ctrl *fw_ctrl)
for (i = 1; i < fw_num && retry;) {
ts_info("--- Start to flash subsystem[%d] ---", i);
fw_x = &fw_summary->subsys[i];
- r = goodix_flash_subsystem(fw_x);
+ r = goodix_flash_subsystem(fw_ctrl->core_data, fw_x);
if (r == 0) {
ts_info("--- End flash subsystem[%d]: OK ---", i);
i++;
@@ -922,10 +778,24 @@ exit_flash:
*/
static int goodix_update_finish(struct fw_update_ctrl *fwu_ctrl)
{
+ struct goodix_ts_core *cd = fwu_ctrl->core_data;
int ret;
- if (goodix_fw_update_reset(100))
- ts_err("reset abnormal");
+ /* step 1: reset IC */
+ cd->hw_ops->reset(cd, 100);
+ /* step 2: read version */
+ ret = cd->hw_ops->read_version(cd, &cd->fw_version);
+ if (ret < 0) {
+ ts_err("still failed to read version after upgraded");
+ return -EFAULT;
+ }
+ /* step 3: read ic info */
+ ret = cd->hw_ops->get_ic_info(cd, &cd->ic_info);
+ if (ret < 0) {
+ ts_err("still failed to read ic info after upgraded");
+ return -EFAULT;
+ }
+
ret = goodix_fw_version_compare(fwu_ctrl);
if (ret == COMPARE_EQUAL || ret == COMPARE_CFG_NOTEQUAL)
return 0;
@@ -946,7 +816,7 @@ int goodix_fw_update_proc(struct fw_update_ctrl *fwu_ctrl)
int retry1 = FW_UPDATE_RETRY;
int ret = 0;
- ret = goodix_parse_firmware(&fwu_ctrl->fw_data);
+ ret = goodix_parse_firmware(fwu_ctrl->core_data, &fwu_ctrl->fw_data);
if (ret < 0)
return ret;
@@ -1008,7 +878,10 @@ static ssize_t update_en_store(struct device *dev,
{
int ret = 0;
int mode = 0;
- struct fw_update_ctrl *fw_ctrl = &goodix_fw_update_ctrl;
+ struct device *device =
+ container_of(((struct kobject *)dev)->parent, struct device, kobj);
+ struct goodix_ts_core *cd = dev_get_drvdata(device);
+ struct fw_update_ctrl *fw_ctrl = &cd->update_ctrl;
if (!buf || count <= 0) {
ts_err("invalid params");
@@ -1035,7 +908,7 @@ static ssize_t update_en_store(struct device *dev,
return -EINVAL;
}
- ret = goodix_do_fw_update(NULL, mode);
+ ret = goodix_do_fw_update(cd, mode);
if (!ret) {
ts_info("success do update work");
return count;
@@ -1044,36 +917,18 @@ static ssize_t update_en_store(struct device *dev,
return -EINVAL;
}
-static ssize_t fwimage_write(struct file *file, struct kobject *kobj,
- struct bin_attribute *attr, char *buf, loff_t pos, size_t count)
-{
- struct firmware **fw = &goodix_fw_update_ctrl.fw_data.fw_sysfs;
-
- if (*fw == NULL) {
- *fw = kzalloc(sizeof(**fw), GFP_KERNEL);
- if (*fw == NULL)
- return -ENOMEM;
- (*fw)->data = vmalloc(GOODIX_FW_MAX_SIEZE);
- if ((*fw)->data == NULL) {
- kfree(*fw);
- *fw = NULL;
- return -ENOMEM;
- }
- }
-
- if (pos + count > GOODIX_FW_MAX_SIEZE)
- return -EFAULT;
- memcpy((u8 *)&(*fw)->data[pos], buf, count);
- (*fw)->size = pos + count;
-
- return count;
-}
-
-/* return fw_update result */
+/*
+ * [GOOG]
+ * return fw_update result
+ */
static ssize_t result_show(
- struct device *dev, struct device_attribute *attr, char *buf)
+ struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct fw_update_ctrl *fw_ctrl = &goodix_fw_update_ctrl;
+ struct device *device =
+ container_of(((struct kobject *)dev)->parent, struct device, kobj);
+ struct goodix_ts_core *cd = dev_get_drvdata(device);
+ struct fw_update_ctrl *fw_ctrl = &cd->update_ctrl;
char str[GOODIX_MAX_STR_LABEL_LEN] = { 0 };
int r = -EINVAL;
@@ -1099,57 +954,51 @@ static ssize_t result_show(
break;
}
- r = snprintf(buf, PAGE_SIZE, "result:%s spend_time:%dms\n", str,
- fw_ctrl->spend_time);
+ r = snprintf(buf, PAGE_SIZE, "result:%s spend_time:%dms\n",
+ str, fw_ctrl->spend_time);
return r;
}
+/* [GOOG] */
static DEVICE_ATTR_WO(update_en);
static DEVICE_ATTR_RO(result);
-static struct attribute *goodix_attrs[] = {
+static struct attribute *goodix_fwu_attrs[] = {
&dev_attr_update_en.attr,
&dev_attr_result.attr,
- NULL,
-};
-
-static BIN_ATTR_WO(fwimage, 0);
-static struct bin_attribute *goodix_bin_attrs[] = {
- &bin_attr_fwimage,
- NULL,
+ NULL
};
-static int goodix_fw_sysfs_init(
- struct goodix_ts_core *core_data, struct fw_update_ctrl *fw_ctrl)
+static int goodix_fw_sysfs_init(struct goodix_ts_core *core_data,
+ struct fw_update_ctrl *fw_ctrl)
{
int ret = 0;
- fw_ctrl->kobj =
- kobject_create_and_add("fwupdate", &core_data->pdev->dev.kobj);
+ fw_ctrl->kobj = kobject_create_and_add("fwupdate",
+ &core_data->pdev->dev.kobj);
if (!fw_ctrl->kobj) {
ts_err("failed create sub dir for fwupdate");
return -EINVAL;
}
- fw_ctrl->attrs.attrs = goodix_attrs;
- fw_ctrl->attrs.bin_attrs = goodix_bin_attrs;
+ /* [GOOG] */
+ fw_ctrl->attrs.attrs = goodix_fwu_attrs;
ret = sysfs_create_group(fw_ctrl->kobj, &fw_ctrl->attrs);
if (ret) {
ts_err("Cannot create sysfs structure!\n");
kobject_put(fw_ctrl->kobj);
- return -ENODEV;
}
+ /*~[GOOG]*/
return ret;
}
-static void goodix_fw_sysfs_remove(void)
+static void goodix_fw_sysfs_remove(struct goodix_ts_core *cd)
{
- struct fw_update_ctrl *fw_ctrl = &goodix_fw_update_ctrl;
+ struct fw_update_ctrl *fw_ctrl = &cd->update_ctrl;
- sysfs_remove_group(fw_ctrl->kobj, &fw_ctrl->attrs);
- kobject_put(fw_ctrl->kobj);
+ sysfs_remove_group(fw_ctrl->kobj, &fw_ctrl->attrs); /* [GOOG] */
}
/**
@@ -1201,6 +1050,7 @@ static inline void goodix_release_firmware(struct firmware_data *fw_data)
static int goodix_fw_update_thread(void *data)
{
struct fw_update_ctrl *fwu_ctrl = data;
+ struct goodix_ts_core *cd = fwu_ctrl->core_data;
ktime_t start, end;
int r = -EINVAL;
@@ -1210,7 +1060,10 @@ static int goodix_fw_update_thread(void *data)
mutex_lock(&fwu_ctrl->mutex);
ts_debug("notify update start");
- goodix_ts_blocking_notify(NOTIFY_FWUPDATE_START, NULL);
+ if (cd->init_stage >= CORE_INIT_STAGE2) {
+ cd->hw_ops->irq_enable(cd, 0);
+ goodix_ts_esd_off(cd);
+ }
if (fwu_ctrl->mode & UPDATE_MODE_SRC_REQUEST) {
ts_info("Firmware request update starts");
@@ -1218,21 +1071,6 @@ static int goodix_fw_update_thread(void *data)
&fwu_ctrl->fw_data, fwu_ctrl->fw_name);
if (r < 0)
goto out;
- } else if (fwu_ctrl->mode & UPDATE_MODE_SRC_SYSFS) {
- if (!fwu_ctrl->fw_data.fw_sysfs) {
- ts_err("Invalid firmware from sysfs");
- r = -EINVAL;
- goto out;
- }
- if (fwu_ctrl->fw_data.fw_sysfs->size < 4096) {
- ts_err("Invalid firmware size[%ld] from sysfs",
- fwu_ctrl->fw_data.fw_sysfs->size);
- vfree(fwu_ctrl->fw_data.fw_sysfs->data);
- kfree(fwu_ctrl->fw_data.fw_sysfs);
- fwu_ctrl->fw_data.fw_sysfs = NULL;
- r = -EINVAL;
- goto out;
- }
} else {
ts_err("unknown update mode 0x%x", fwu_ctrl->mode);
r = -EINVAL;
@@ -1244,13 +1082,8 @@ static int goodix_fw_update_thread(void *data)
r = goodix_fw_update_proc(fwu_ctrl);
/* clean */
- if (fwu_ctrl->mode & UPDATE_MODE_SRC_SYSFS) {
- vfree(fwu_ctrl->fw_data.fw_sysfs->data);
- kfree(fwu_ctrl->fw_data.fw_sysfs);
- fwu_ctrl->fw_data.fw_sysfs = NULL;
- } else if (fwu_ctrl->mode & UPDATE_MODE_SRC_REQUEST) {
+ if (fwu_ctrl->mode & UPDATE_MODE_SRC_REQUEST)
goodix_release_firmware(&fwu_ctrl->fw_data);
- }
out:
fwu_ctrl->mode = UPDATE_MODE_DEFAULT;
mutex_unlock(&fwu_ctrl->mutex);
@@ -1258,23 +1091,25 @@ out:
if (r) {
ts_err("fw update failed, %d", r);
fwu_ctrl->status = UPSTA_FAILED;
- goodix_ts_blocking_notify(NOTIFY_FWUPDATE_FAILED, NULL);
} else {
ts_info("fw update success");
fwu_ctrl->status = UPSTA_SUCCESS;
- goodix_ts_blocking_notify(NOTIFY_FWUPDATE_SUCCESS, NULL);
}
end = ktime_get();
fwu_ctrl->spend_time = ktime_to_ms(ktime_sub(end, start));
+ if (cd->init_stage >= CORE_INIT_STAGE2) {
+ cd->hw_ops->irq_enable(cd, 1);
+ goodix_ts_esd_on(cd);
+ }
return r;
}
-int goodix_do_fw_update(struct goodix_ic_config *ic_config, int mode)
+int goodix_do_fw_update(struct goodix_ts_core *cd, int mode)
{
struct task_struct *fwu_thrd;
- struct fw_update_ctrl *fwu_ctrl = &goodix_fw_update_ctrl;
+ struct fw_update_ctrl *fwu_ctrl = &cd->update_ctrl;
int ret;
if (!fwu_ctrl->initialized) {
@@ -1283,7 +1118,7 @@ int goodix_do_fw_update(struct goodix_ic_config *ic_config, int mode)
}
fwu_ctrl->mode = mode;
- fwu_ctrl->ic_config = ic_config;
+ fwu_ctrl->ic_config = cd->ic_configs[CONFIG_TYPE_NORMAL];
ts_debug("fw update mode 0x%x", mode);
if (fwu_ctrl->mode & UPDATE_MODE_BLOCK) {
ret = goodix_fw_update_thread(fwu_ctrl);
@@ -1309,37 +1144,34 @@ int goodix_fw_update_init(struct goodix_ts_core *core_data)
return -ENODEV;
}
- mutex_init(&goodix_fw_update_ctrl.mutex);
- goodix_fw_update_ctrl.core_data = core_data;
- goodix_fw_update_ctrl.mode = 0;
+ mutex_init(&core_data->update_ctrl.mutex);
+ core_data->update_ctrl.core_data = core_data;
+ core_data->update_ctrl.mode = 0;
- strlcpy(goodix_fw_update_ctrl.fw_name, core_data->board_data.fw_name,
- sizeof(goodix_fw_update_ctrl.fw_name));
+ strlcpy(core_data->update_ctrl.fw_name, core_data->board_data.fw_name,
+ sizeof(core_data->update_ctrl.fw_name));
- ret = goodix_fw_sysfs_init(core_data, &goodix_fw_update_ctrl);
+ ret = goodix_fw_sysfs_init(core_data, &core_data->update_ctrl);
if (ret) {
ts_err("failed create fwupate sysfs node");
return ret;
}
if (core_data->bus->ic_type == IC_TYPE_BERLIN_A)
- goodix_fw_update_ctrl.update_info = &update_bra;
+ core_data->update_ctrl.update_info = &update_bra;
else if (core_data->bus->ic_type == IC_TYPE_BERLIN_B)
- goodix_fw_update_ctrl.update_info = &update_brb;
+ core_data->update_ctrl.update_info = &update_brb;
else
- goodix_fw_update_ctrl.update_info = &update_brd;
+ core_data->update_ctrl.update_info = &update_brd;
- goodix_fw_update_ctrl.initialized = 1;
+ core_data->update_ctrl.initialized = 1;
return 0;
}
-void goodix_fw_update_uninit(void)
+void goodix_fw_update_uninit(struct goodix_ts_core *core_data)
{
- if (!goodix_fw_update_ctrl.initialized)
+ if (!core_data->update_ctrl.initialized)
return;
-
- mutex_lock(&goodix_fw_update_ctrl.mutex);
- goodix_fw_sysfs_remove();
- goodix_fw_update_ctrl.initialized = 0;
- mutex_unlock(&goodix_fw_update_ctrl.mutex);
- mutex_destroy(&goodix_fw_update_ctrl.mutex);
+ goodix_fw_sysfs_remove(core_data);
+ core_data->update_ctrl.initialized = 0;
+ mutex_destroy(&core_data->update_ctrl.mutex);
}
diff --git a/goodix_brl_hw.c b/goodix_brl_hw.c
index acfd294..4b94946 100644
--- a/goodix_brl_hw.c
+++ b/goodix_brl_hw.c
@@ -79,6 +79,10 @@ static int brl_dev_confirm(struct goodix_ts_core *cd)
u8 tx_buf[8] = { 0 };
u8 rx_buf[8] = { 0 };
+ if (cd->bus->ic_type == IC_TYPE_BERLIN_A &&
+ cd->bus->bus_type == GOODIX_BUS_TYPE_SPI)
+ return brl_select_spi_mode(cd);
+
memset(tx_buf, DEV_CONFIRM_VAL, sizeof(tx_buf));
while (retry--) {
ret = hw_ops->write(
@@ -114,11 +118,6 @@ static int brl_reset_after(struct goodix_ts_core *cd)
ts_info("IN");
- /* select spi mode */
- ret = brl_select_spi_mode(cd);
- if (ret < 0)
- return ret;
-
/* hold cpu */
retry = GOODIX_RETRY_10;
while (retry--) {
@@ -283,7 +282,7 @@ int brl_resume(struct goodix_ts_core *cd)
rcv_buf[0], rcv_buf[1]);
return -EINVAL;
} else {
- ts_info("Secceed to exit sleep mode with retry: %d", 19 - retry);
+ ts_info("Succeed to exit sleep mode with retry: %d", 19 - retry);
}
return 0;
@@ -850,7 +849,7 @@ static int convert_ic_info(struct goodix_ic_info *info, const u8 *data)
return 0;
}
-static void print_ic_info(struct goodix_ic_info *ic_info)
+void print_ic_info(struct goodix_ic_info *ic_info)
{
struct goodix_ic_info_version *version = &ic_info->version;
struct goodix_ic_info_feature *feature = &ic_info->feature;
@@ -975,8 +974,6 @@ static int brl_get_ic_info(
return ret;
}
- print_ic_info(ic_info);
-
/* check some key info */
if (!ic_info->misc.cmd_addr || !ic_info->misc.fw_buffer_addr ||
!ic_info->misc.touch_data_addr) {
@@ -1019,6 +1016,7 @@ static int brl_esd_check(struct goodix_ts_core *cd)
#define IRQ_EVENT_HEAD_LEN 8
#define BYTES_PER_POINT 14
+#define BYTES_STYLUS_LEN 16
#define COOR_DATA_CHECKSUM_SIZE 2
#define GOODIX_TOUCH_EVENT 0x80
@@ -1028,69 +1026,42 @@ static int brl_esd_check(struct goodix_ts_core *cd)
#define GOODIX_FP_EVENT 0x08
#define POINT_TYPE_STYLUS_HOVER 0x01
#define POINT_TYPE_STYLUS 0x03
-static int point_struct_len;
-static void goodix_parse_finger(
- struct goodix_touch_data *touch_data, u8 *buf, int touch_num)
+static void goodix_parse_finger(struct goodix_ts_core *cd,
+ struct goodix_touch_data *touch_data,
+ u8 *buf, int id)
{
- unsigned int id = 0;
- u8 *coor_data;
- int i;
- struct goodix_ts_coords *coord;
-
- coor_data = &buf[IRQ_EVENT_HEAD_LEN];
- for (i = 0; i < touch_num; i++) {
- id = (coor_data[0] >> 4) & 0x0F;
- if (id >= GOODIX_MAX_TOUCH) {
- ts_info("invalid finger id =%d", id);
- touch_data->touch_num = 0;
- return;
- }
- coord = &touch_data->coords[id];
-
- coord->status = TS_TOUCH;
- coord->x = le16_to_cpup((__le16 *)(coor_data + 2));
- coord->y = le16_to_cpup((__le16 *)(coor_data + 4));
- coord->w = le16_to_cpup((__le16 *)(coor_data + 6));
-
- if (point_struct_len > 8) {
- coord->p = coor_data[8];
- coord->major = le16_to_cpup((__le16 *)(coor_data + 9));
- coord->minor = le16_to_cpup((__le16 *)(coor_data + 11));
- coord->angle = (signed char)coor_data[13];
- }
-
- coor_data += point_struct_len;
- }
- touch_data->touch_num = touch_num;
+ int point_struct_len = cd->ic_info.misc.point_struct_len;
+ struct goodix_ts_coords *coord = &touch_data->coords[id]; /* [GOOG] */
+
+ coord->status = TS_TOUCH;
+ coord->x = le16_to_cpup((__le16 *)(buf + 2));
+ coord->y = le16_to_cpup((__le16 *)(buf + 4));
+ coord->w = le16_to_cpup((__le16 *)(buf + 6));
+ if (point_struct_len > 8) {
+ coord->p = buf[8];
+ coord->major = le16_to_cpup((__le16 *)(buf + 9));
+ coord->minor = le16_to_cpup((__le16 *)(buf + 11));
+ coord->angle = (signed char)buf[13];
+ }
+ touch_data->touch_num += 1;
}
static unsigned int goodix_pen_btn_code[] = { BTN_STYLUS, BTN_STYLUS2 };
static void goodix_parse_pen(
- struct goodix_pen_data *pen_data, u8 *buf, int touch_num)
+ struct goodix_pen_data *pen_data, u8 *event_head, u8 *buf)
{
- unsigned int id = 0;
u8 cur_key_map = 0;
- u8 *coor_data;
int16_t x_angle, y_angle;
int i;
- pen_data->coords.tool_type = BTN_TOOL_PEN;
-
- if (touch_num) {
- pen_data->coords.status = TS_TOUCH;
- coor_data = &buf[IRQ_EVENT_HEAD_LEN];
-
- id = (coor_data[0] >> 4) & 0x0F;
- pen_data->coords.x = le16_to_cpup((__le16 *)(coor_data + 2));
- pen_data->coords.y = le16_to_cpup((__le16 *)(coor_data + 4));
- pen_data->coords.p = le16_to_cpup((__le16 *)(coor_data + 6));
- x_angle = le16_to_cpup((__le16 *)(coor_data + 8));
- y_angle = le16_to_cpup((__le16 *)(coor_data + 10));
- pen_data->coords.tilt_x = x_angle / 100;
- pen_data->coords.tilt_y = y_angle / 100;
- } else {
- pen_data->coords.status = TS_RELEASE;
- }
+ pen_data->coords.status = TS_TOUCH;
+ pen_data->coords.x = le16_to_cpup((__le16 *)(buf + 2));
+ pen_data->coords.y = le16_to_cpup((__le16 *)(buf + 4));
+ pen_data->coords.p = le16_to_cpup((__le16 *)(buf + 6));
+ x_angle = le16_to_cpup((__le16 *)(buf + 8));
+ y_angle = le16_to_cpup((__le16 *)(buf + 10));
+ pen_data->coords.tilt_x = x_angle / 100;
+ pen_data->coords.tilt_y = y_angle / 100;
cur_key_map = (buf[3] & 0x0F) >> 1;
for (i = 0; i < GOODIX_MAX_PEN_KEY; i++) {
@@ -1101,7 +1072,7 @@ static void goodix_parse_pen(
}
}
-static int goodix_update_heatmap(struct goodix_ts_core *cd, uint8_t *event_data)
+static int goodix_update_heatmap(struct goodix_ts_core *cd, u8 *event_data)
{
struct goodix_ic_info_misc *misc = &cd->ic_info.misc;
int tx = cd->ic_info.parm.drv_num;
@@ -1130,113 +1101,90 @@ static int goodix_touch_handler(struct goodix_ts_core *cd,
struct goodix_ic_info_misc *misc = &cd->ic_info.misc;
struct goodix_touch_data *touch_data = &ts_event->touch_data;
struct goodix_pen_data *pen_data = &ts_event->pen_data;
+ u8 *data = event_data->data;
+ u8 touch_num;
+ int checksum_len = 0;
int ret = 0;
- u8 point_type = 0;
- static u8 pre_finger_num;
- static u8 pre_pen_num;
-
- if (event_data->touches > GOODIX_MAX_TOUCH) {
- ts_debug("invalid touch num %d", event_data->touches);
- return -EINVAL;
- }
+ u8 point_type;
+ int tid;
+ int i;
- if (event_data->touches > 0) {
- point_type = event_data->data[0] & 0x0F;
- if (point_type == POINT_TYPE_STYLUS ||
- point_type == POINT_TYPE_STYLUS_HOVER) {
- ret = checksum_cmp(event_data->data, 16 + 2, CHECKSUM_MODE_U8_LE);
- if (ret) {
- ts_debug("touch data checksum error");
- ts_debug("data:%*ph", 16 + 2, event_data->data);
- return -EINVAL;
- }
- } else {
- point_struct_len = misc->point_struct_len;
- ret = checksum_cmp(event_data->data,
- event_data->touches * point_struct_len + 2,
- CHECKSUM_MODE_U8_LE);
- if (ret) {
- ts_debug("touch data checksum error");
- ts_debug("data:%*ph",
- event_data->touches * point_struct_len +
- 2,
- event_data->data);
- return -EINVAL;
+ touch_data->touch_num = 0; /* [GOOG] */
+ touch_num = event_data->touches;
+ if (touch_num > 0) {
+ /*
+ * [GOOG]
+ * Touch Packet: 8 bytes header + data(stylus or finger).
+ */
+ for (i = 0; i < touch_num; i++) {
+ point_type = event_data->type;
+ tid = (data[0] >> 4) & 0x0F;
+ if (point_type == POINT_TYPE_STYLUS ||
+ point_type == POINT_TYPE_STYLUS_HOVER) {
+ goodix_parse_pen(pen_data, (u8 *)event_data, data);
+ checksum_len += BYTES_STYLUS_LEN;
+ data += BYTES_STYLUS_LEN;
+ } else {
+ /* [GOOG] */
+ if (tid >= GOODIX_MAX_TOUCH)
+ ts_info("invalid touch#%d id %d", i, tid);
+ else
+ goodix_parse_finger(cd, touch_data, data, tid);
+ checksum_len += misc->point_struct_len;
+ data += misc->point_struct_len;
}
}
- }
-
- goodix_update_heatmap(cd, (u8 *)event_data);
-
- ts_event->fp_flag = event_data->fp_flag;
-
- if (event_data->touches > 0 &&
- (point_type == POINT_TYPE_STYLUS ||
- point_type == POINT_TYPE_STYLUS_HOVER)) {
- /* stylus info */
- if (pre_finger_num) {
- ts_event->event_type = EVENT_TOUCH;
- goodix_parse_finger(touch_data, (u8 *)event_data, 0);
- pre_finger_num = 0;
- } else {
- pre_pen_num = 1;
- ts_event->event_type = EVENT_PEN;
- goodix_parse_pen(pen_data, (u8 *)event_data,
- event_data->touches);
- }
- } else {
- /* finger info */
- if (pre_pen_num) {
- ts_event->event_type = EVENT_PEN;
- goodix_parse_pen(pen_data, (u8 *)event_data, 0);
- pre_pen_num = 0;
- } else {
- ts_event->event_type = EVENT_TOUCH;
- goodix_parse_finger(touch_data, (u8 *)event_data,
- event_data->touches);
- pre_finger_num = event_data->touches;
+ ret = checksum_cmp(event_data->data,
+ checksum_len + 2,
+ CHECKSUM_MODE_U8_LE);
+ if (ret) {
+ ts_debug("touch data checksum error");
+ return -EINVAL;
}
}
- if (event_data->status_changed)
- ts_event->event_type |= EVENT_STATUS;
+ goodix_update_heatmap(cd, (u8 *)event_data); /* [GOOG] */
- /* process custom info */
- if (event_data->custom_coor_info_flag)
- ts_debug("TODO add custom info process function");
+ ts_event->fp_flag = event_data->fp_flag;
+ ts_event->event_type |= EVENT_TOUCH;
+ if (cd->board_data.pen_enable)
+ ts_event->event_type |= EVENT_PEN;
return 0;
}
-static int brl_event_handler(
- struct goodix_ts_core *cd, struct goodix_ts_event *ts_event)
+static int brl_event_handler(struct goodix_ts_core *cd,
+ struct goodix_ts_event *ts_event)
{
struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
struct goodix_ic_info_misc *misc = &cd->ic_info.misc;
+/* [GOOG] */
struct goodix_ts_event_data *event_data;
int ret;
+ if (!cd->touch_frame_package || !cd->touch_frame_size)
+ return -ENOMEM;
+
ret = hw_ops->read_fast(cd, misc->touch_data_addr,
- cd->touch_frame_package, cd->touch_frame_size);
+ cd->touch_frame_package, cd->touch_frame_size);
if (ret) {
ts_debug("failed get event head data");
return ret;
}
+ event_data = (struct goodix_ts_event_data *)cd->touch_frame_package->data;
- event_data =
- (struct goodix_ts_event_data *)cd->touch_frame_package->data;
if (event_data->type == 0x00) {
ts_debug("invalid touch head");
return -EINVAL;
}
if (checksum_cmp((u8 *)event_data, IRQ_EVENT_HEAD_LEN,
- CHECKSUM_MODE_U8_LE)) {
+ CHECKSUM_MODE_U8_LE)) {
ts_debug("touch head checksum err[%*ph]", IRQ_EVENT_HEAD_LEN,
event_data);
- hw_ops->after_event_handler(cd);
return -EINVAL;
}
+/*~[GOOG]*/
/* clean event buffer */
memset(ts_event, 0, sizeof(*ts_event));
@@ -1245,9 +1193,32 @@ static int brl_event_handler(
ts_event->clear_count1 = event_data->clear_count1;
ts_event->clear_count2 = event_data->clear_count2;
/* read status event */
- if (event_data->status_changed)
+ if (event_data->status_changed) {
+ ts_event->event_type |= EVENT_STATUS;
hw_ops->read(cd, 0x1021C, (u8 *)&ts_event->status_data,
sizeof(ts_event->status_data));
+ }
+
+/*
+ * [GOOG]
+ * Use goodix_update_heatmap() to do the heatmap process and
+ * move after_event_handler() into goodix_ts_core.c.
+ *
+ // read done
+ hw_ops->after_event_handler(cd);
+
+ if (cd->heatmap_buffer) {
+ offset = 248 + misc->frame_data_head_len +
+ misc->fw_attr_len + misc->fw_log_len + 8;
+ memcpy(cd->heatmap_diff, &pre_buf[offset], tx * rx * 2);
+ goodix_rotate_abcd2cbad(tx, rx, cd->heatmap_diff);
+ offset = 248 + misc->frame_data_head_len +
+ misc->fw_attr_len + misc->fw_log_len +
+ misc->mutual_struct_len + 10;
+ memcpy(cd->heatmap_selfdiff, &pre_buf[offset], (tx + rx) * 2);
+ }
+ *~[GOOG]
+ */
if (event_data->type & (GOODIX_TOUCH_EVENT >> 4))
return goodix_touch_handler(cd, ts_event,
@@ -1256,7 +1227,7 @@ static int brl_event_handler(
if (event_data->type & (GOODIX_REQUEST_EVENT >> 4)) {
struct goodix_ts_request_event_data *request =
(struct goodix_ts_request_event_data *)event_data;
- ts_event->event_type = EVENT_REQUEST;
+ ts_event->event_type |= EVENT_REQUEST;
if (request->request_type == BRL_REQUEST_CODE_CONFIG)
ts_event->request_code = REQUEST_TYPE_CONFIG;
else if (request->request_type == BRL_REQUEST_CODE_RESET)
@@ -1292,9 +1263,7 @@ static int brl_event_handler(
if (event_data->type & (GOODIX_GESTURE_EVENT >> 4)) {
struct goodix_ts_gesture_event_data *gesture =
(struct goodix_ts_gesture_event_data *)event_data;
- ts_event->event_type = EVENT_GESTURE;
- if (event_data->status_changed)
- ts_event->event_type |= EVENT_STATUS;
+ ts_event->event_type |= EVENT_GESTURE;
ts_event->gesture_data.gesture_type = gesture->gesture_type;
ts_event->gesture_data.touches = gesture->touches;
memcpy(ts_event->gesture_data.data, gesture->data,
@@ -1394,7 +1363,7 @@ static int brld_get_cap_data(
/* disable irq & close esd */
brl_irq_enable(cd, false);
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
info->buff[0] = rx;
info->buff[1] = tx;
@@ -1441,7 +1410,7 @@ exit:
brl_send_cmd(cd, &temp_cmd);
/* enable irq & esd */
brl_irq_enable(cd, true);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
return ret;
}
@@ -1472,7 +1441,7 @@ static int brl_get_capacitance_data(
/* disable irq & close esd */
brl_irq_enable(cd, false);
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
/* switch rawdata mode */
temp_cmd.cmd = GOODIX_CMD_RAWDATA;
@@ -1535,7 +1504,7 @@ exit:
brl_write(cd, flag_addr, &val, 1);
/* enable irq & esd */
brl_irq_enable(cd, true);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
return ret;
}
diff --git a/goodix_brl_i2c.c b/goodix_brl_i2c.c
index 60018a6..b1409f2 100644
--- a/goodix_brl_i2c.c
+++ b/goodix_brl_i2c.c
@@ -25,8 +25,6 @@
#define GOODIX_BUS_RETRY_TIMES 2
#define GOODIX_REG_ADDR_SIZE 4
-static struct platform_device *goodix_pdev;
-struct goodix_bus_interface goodix_i2c_bus;
static int goodix_i2c_read(struct device *dev, unsigned int reg,
unsigned char *data, unsigned int len)
@@ -156,15 +154,10 @@ write_exit:
return r;
}
-static void goodix_pdev_release(struct device *dev)
-{
- ts_info("goodix pdev released");
- kfree(goodix_pdev);
-}
-
static int goodix_i2c_probe(
struct i2c_client *client, const struct i2c_device_id *dev_id)
{
+ struct goodix_device_resource *dev_res;
int ret = 0;
ts_info("goodix i2c probe in");
@@ -172,52 +165,45 @@ static int goodix_i2c_probe(
if (!ret)
return -EIO;
+ dev_res = kzalloc(sizeof(*dev_res), GFP_KERNEL);
+ if (!dev_res)
+ return -ENOMEM;
+ goodix_device_register(dev_res);
+
/* get ic type */
- ret = goodix_get_ic_type(client->dev.of_node, &goodix_i2c_bus);
+ ret = goodix_get_ic_type(client->dev.of_node, &dev_res->bus);
if (ret < 0)
return ret;
- goodix_i2c_bus.bus_type = GOODIX_BUS_TYPE_I2C;
- goodix_i2c_bus.dev = &client->dev;
- goodix_i2c_bus.read = goodix_i2c_read;
- goodix_i2c_bus.write = goodix_i2c_write;
- /* ts core device */
- goodix_pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
- if (!goodix_pdev)
- return -ENOMEM;
+ dev_res->bus.bus_type = GOODIX_BUS_TYPE_I2C;
+ dev_res->bus.dev = &client->dev;
+ dev_res->bus.read = goodix_i2c_read;
+ dev_res->bus.write = goodix_i2c_write;
- goodix_pdev->name = GOODIX_CORE_DRIVER_NAME;
- goodix_pdev->id = 0;
- goodix_pdev->num_resources = 0;
- /*
- * you can find this platform dev in
- * /sys/devices/platform/goodix_ts.0
- * goodix_pdev->dev.parent = &client->dev;
- */
- goodix_pdev->dev.platform_data = &goodix_i2c_bus;
- goodix_pdev->dev.release = goodix_pdev_release;
+ dev_res->pdev.name = GOODIX_CORE_DRIVER_NAME;
+ dev_res->pdev.id = dev_res->id;
+ dev_res->pdev.num_resources = 0;
/* register platform device, then the goodix_ts_core
* module will probe the touch device.
*/
- ret = platform_device_register(goodix_pdev);
+ ret = platform_device_register(&dev_res->pdev);
if (ret) {
ts_err("failed register goodix platform device, %d", ret);
goto err_pdev;
}
ts_info("i2c probe out");
- return ret;
+ return 0;
err_pdev:
- kfree(goodix_pdev);
- goodix_pdev = NULL;
+ kfree(dev_res);
ts_info("i2c probe out, %d", ret);
return ret;
}
static int goodix_i2c_remove(struct i2c_client *client)
{
- platform_device_unregister(goodix_pdev);
+ // platform_device_unregister(goodix_pdev);
return 0;
}
diff --git a/goodix_brl_spi.c b/goodix_brl_spi.c
index b7d82da..e3421b9 100644
--- a/goodix_brl_spi.c
+++ b/goodix_brl_spi.c
@@ -36,9 +36,6 @@
#define SPI_WRITE_FLAG 0xF0
#define SPI_READ_FLAG 0xF1
-static struct platform_device *goodix_pdev;
-struct goodix_bus_interface goodix_spi_bus;
-
/**
* goodix_spi_read_bra- read device register through spi bus
* @dev: pointer to device data
@@ -51,6 +48,8 @@ static int goodix_spi_read_bra(struct device *dev, unsigned int addr,
unsigned char *data, unsigned int len)
{
struct spi_device *spi = to_spi_device(dev);
+ struct goodix_ts_core *cd = dev_get_drvdata(dev);
+ struct goodix_bus_interface *bus = cd->bus;
u8 *rx_buf = NULL;
u8 *tx_buf = NULL;
struct spi_transfer xfers;
@@ -58,12 +57,12 @@ static int goodix_spi_read_bra(struct device *dev, unsigned int addr,
int ret = 0;
int buf_len = SPI_READ_PREFIX_LEN + len;
- mutex_lock(&goodix_spi_bus.mutex);
+ mutex_lock(&bus->mutex);
if (buf_len <= SPI_PREALLOC_RX_BUF_SIZE &&
buf_len <= SPI_PREALLOC_TX_BUF_SIZE) {
- rx_buf = goodix_spi_bus.rx_buf;
- tx_buf = goodix_spi_bus.tx_buf;
+ rx_buf = bus->rx_buf;
+ tx_buf = bus->tx_buf;
memset(tx_buf, 0, buf_len);
} else {
rx_buf = kzalloc(buf_len, GFP_KERNEL);
@@ -108,13 +107,13 @@ static int goodix_spi_read_bra(struct device *dev, unsigned int addr,
memcpy(data, &rx_buf[SPI_READ_PREFIX_LEN], len);
err_spi_transfer:
- if (tx_buf != goodix_spi_bus.tx_buf)
+ if (tx_buf != bus->tx_buf)
kfree(tx_buf);
err_alloc_tx_buf:
- if (rx_buf != goodix_spi_bus.rx_buf)
+ if (rx_buf != bus->rx_buf)
kfree(rx_buf);
err_alloc_rx_buf:
- mutex_unlock(&goodix_spi_bus.mutex);
+ mutex_unlock(&bus->mutex);
return ret;
}
@@ -122,6 +121,8 @@ static int goodix_spi_read(struct device *dev, unsigned int addr,
unsigned char *data, unsigned int len)
{
struct spi_device *spi = to_spi_device(dev);
+ struct goodix_ts_core *cd = dev_get_drvdata(dev);
+ struct goodix_bus_interface *bus = cd->bus;
u8 *rx_buf = NULL;
u8 *tx_buf = NULL;
struct spi_transfer xfers;
@@ -129,16 +130,15 @@ static int goodix_spi_read(struct device *dev, unsigned int addr,
int ret = 0;
int buf_len = SPI_READ_PREFIX_LEN - 1 + len;
- if (goodix_spi_bus.dma_mode_enabled && buf_len >= 64) {
+ if (bus->dma_mode_enabled && buf_len >= 64)
buf_len = ALIGN(buf_len, 4);
- }
- mutex_lock(&goodix_spi_bus.mutex);
+ mutex_lock(&bus->mutex);
if (buf_len <= SPI_PREALLOC_RX_BUF_SIZE &&
buf_len <= SPI_PREALLOC_TX_BUF_SIZE) {
- rx_buf = goodix_spi_bus.rx_buf;
- tx_buf = goodix_spi_bus.tx_buf;
+ rx_buf = bus->rx_buf;
+ tx_buf = bus->tx_buf;
memset(tx_buf, 0, buf_len);
} else {
rx_buf = kzalloc(buf_len, GFP_KERNEL);
@@ -173,7 +173,8 @@ static int goodix_spi_read(struct device *dev, unsigned int addr,
xfers.rx_buf = rx_buf;
xfers.len = buf_len;
xfers.cs_change = 0;
- if (goodix_spi_bus.dma_mode_enabled) xfers.bits_per_word = buf_len >= 64 ? 32 : 8;
+ if (bus->dma_mode_enabled)
+ xfers.bits_per_word = buf_len >= 64 ? 32 : 8;
spi_message_add_tail(&xfers, &spi_msg);
ret = spi_sync(spi, &spi_msg);
if (ret < 0) {
@@ -183,32 +184,37 @@ static int goodix_spi_read(struct device *dev, unsigned int addr,
memcpy(data, &rx_buf[SPI_READ_PREFIX_LEN - 1], len);
err_spi_transfer:
- if (tx_buf != goodix_spi_bus.tx_buf)
+ if (tx_buf != bus->tx_buf)
kfree(tx_buf);
err_alloc_tx_buf:
- if (rx_buf != goodix_spi_bus.rx_buf)
+ if (rx_buf != bus->rx_buf)
kfree(rx_buf);
err_alloc_rx_buf:
- mutex_unlock(&goodix_spi_bus.mutex);
+ mutex_unlock(&bus->mutex);
return ret;
}
+/* [GOOG]
+ * This SPI transaction will direct read into `struct goodix_rx_package`.
+ * And, the package are comprised of `SPI prefix header` + `data`.
+ */
static int goodix_spi_read_fast(struct device *dev, unsigned int addr,
struct goodix_rx_package *package, unsigned int len)
{
struct spi_device *spi = to_spi_device(dev);
+ struct goodix_ts_core *cd = dev_get_drvdata(dev);
+ struct goodix_bus_interface *bus = cd->bus;
u8 *tx_buf = NULL;
struct spi_transfer xfers;
struct spi_message spi_msg;
int ret = 0;
int buf_len = SPI_READ_PREFIX_LEN - 1 + len;
- if (goodix_spi_bus.dma_mode_enabled && buf_len >= 64) {
+ if (bus->dma_mode_enabled && buf_len >= 64)
buf_len = ALIGN(buf_len, 4);
- }
if (buf_len <= SPI_PREALLOC_TX_BUF_SIZE) {
- tx_buf = goodix_spi_bus.tx_buf;
+ tx_buf = bus->tx_buf;
} else {
tx_buf = kzalloc(buf_len, GFP_KERNEL);
if (!tx_buf) {
@@ -220,7 +226,7 @@ static int goodix_spi_read_fast(struct device *dev, unsigned int addr,
spi_message_init(&spi_msg);
memset(&xfers, 0, sizeof(xfers));
- mutex_lock(&goodix_spi_bus.mutex);
+ mutex_lock(&bus->mutex);
/*spi_read tx_buf format: 0xF1 + addr(4bytes) + data*/
tx_buf[0] = SPI_READ_FLAG;
@@ -236,12 +242,13 @@ static int goodix_spi_read_fast(struct device *dev, unsigned int addr,
xfers.rx_buf = package->header;
xfers.len = buf_len;
xfers.cs_change = 0;
- if (goodix_spi_bus.dma_mode_enabled) xfers.bits_per_word = buf_len >= 64 ? 32 : 8;
+ if (bus->dma_mode_enabled)
+ xfers.bits_per_word = buf_len >= 64 ? 32 : 8;
spi_message_add_tail(&xfers, &spi_msg);
ret = spi_sync(spi, &spi_msg);
- mutex_unlock(&goodix_spi_bus.mutex);
+ mutex_unlock(&bus->mutex);
if (ret < 0) {
ts_err("spi transfer error:%d", ret);
@@ -249,7 +256,7 @@ static int goodix_spi_read_fast(struct device *dev, unsigned int addr,
}
err_spi_transfer:
- if (tx_buf != goodix_spi_bus.tx_buf)
+ if (tx_buf != bus->tx_buf)
kfree(tx_buf);
return ret;
}
@@ -266,18 +273,19 @@ static int goodix_spi_write(struct device *dev, unsigned int addr,
unsigned char *data, unsigned int len)
{
struct spi_device *spi = to_spi_device(dev);
+ struct goodix_ts_core *cd = dev_get_drvdata(dev);
+ struct goodix_bus_interface *bus = cd->bus;
u8 *tx_buf = NULL;
struct spi_transfer xfers;
struct spi_message spi_msg;
int ret = 0;
int buf_len = SPI_WRITE_PREFIX_LEN + len;
- if (goodix_spi_bus.dma_mode_enabled && buf_len >= 64) {
+ if (bus->dma_mode_enabled && buf_len >= 64)
buf_len = ALIGN(buf_len, 4);
- }
if (buf_len <= SPI_PREALLOC_TX_BUF_SIZE) {
- tx_buf = goodix_spi_bus.tx_buf;
+ tx_buf = bus->tx_buf;
} else {
tx_buf = kzalloc(buf_len, GFP_KERNEL);
if (!tx_buf) {
@@ -289,7 +297,7 @@ static int goodix_spi_write(struct device *dev, unsigned int addr,
spi_message_init(&spi_msg);
memset(&xfers, 0, sizeof(xfers));
- mutex_lock(&goodix_spi_bus.mutex);
+ mutex_lock(&bus->mutex);
tx_buf[0] = SPI_WRITE_FLAG;
tx_buf[1] = (addr >> 24) & 0xFF;
@@ -300,28 +308,24 @@ static int goodix_spi_write(struct device *dev, unsigned int addr,
xfers.tx_buf = tx_buf;
xfers.len = buf_len;
xfers.cs_change = 0;
- if (goodix_spi_bus.dma_mode_enabled) xfers.bits_per_word = buf_len >= 64 ? 32 : 8;
+ if (bus->dma_mode_enabled)
+ xfers.bits_per_word = buf_len >= 64 ? 32 : 8;
spi_message_add_tail(&xfers, &spi_msg);
ret = spi_sync(spi, &spi_msg);
- mutex_unlock(&goodix_spi_bus.mutex);
+ mutex_unlock(&bus->mutex);
if (ret < 0)
ts_err("spi transfer error:%d", ret);
- if (tx_buf != goodix_spi_bus.tx_buf)
+ if (tx_buf != bus->tx_buf)
kfree(tx_buf);
return ret;
}
-static void goodix_pdev_release(struct device *dev)
-{
- ts_info("goodix pdev released");
- kfree(goodix_pdev);
-}
-
static int goodix_spi_probe(struct spi_device *spi)
{
+ struct goodix_device_resource *dev_res;
int ret = 0;
ts_info("goodix spi probe in");
@@ -329,7 +333,7 @@ static int goodix_spi_probe(struct spi_device *spi)
/* init spi_device */
spi->mode = SPI_MODE_0;
spi->bits_per_word = 8;
- spi->rt = true;
+ spi->rt = true; /* [GOOG] */
ret = spi_setup(spi);
if (ret) {
@@ -337,83 +341,71 @@ static int goodix_spi_probe(struct spi_device *spi)
return ret;
}
+ dev_res = kzalloc(sizeof(*dev_res), GFP_KERNEL);
+ if (!dev_res)
+ return -ENOMEM;
+ goodix_device_register(dev_res);
+
/* get ic type */
- ret = goodix_get_ic_type(spi->dev.of_node, &goodix_spi_bus);
+ ret = goodix_get_ic_type(spi->dev.of_node, &dev_res->bus);
if (ret < 0)
- return ret;
+ goto err_get_ic_type;
- goodix_spi_bus.bus_type = GOODIX_BUS_TYPE_SPI;
- goodix_spi_bus.dev = &spi->dev;
- if (goodix_spi_bus.ic_type == IC_TYPE_BERLIN_A) {
- goodix_spi_bus.read = goodix_spi_read_bra;
+ dev_res->bus.bus_type = GOODIX_BUS_TYPE_SPI;
+ dev_res->bus.dev = &spi->dev;
+ if (dev_res->bus.ic_type == IC_TYPE_BERLIN_A) {
+ dev_res->bus.read = goodix_spi_read_bra;
} else {
- goodix_spi_bus.read = goodix_spi_read;
- goodix_spi_bus.read_fast = goodix_spi_read_fast;
+ dev_res->bus.read = goodix_spi_read;
+ dev_res->bus.read_fast = goodix_spi_read_fast;
}
- goodix_spi_bus.write = goodix_spi_write;
+ dev_res->bus.write = goodix_spi_write;
- goodix_spi_bus.rx_buf = kzalloc(SPI_PREALLOC_RX_BUF_SIZE, GFP_KERNEL);
- if (!goodix_spi_bus.rx_buf) {
- return -ENOMEM;
- }
- goodix_spi_bus.tx_buf = kzalloc(SPI_PREALLOC_TX_BUF_SIZE, GFP_KERNEL);
- if (!goodix_spi_bus.tx_buf) {
+ /* [GOOG] */
+ dev_res->bus.rx_buf = kzalloc(SPI_PREALLOC_RX_BUF_SIZE, GFP_KERNEL);
+ dev_res->bus.tx_buf = kzalloc(SPI_PREALLOC_TX_BUF_SIZE, GFP_KERNEL);
+ if (!dev_res->bus.rx_buf || !dev_res->bus.tx_buf) {
ret = -ENOMEM;
- goto err_alloc_tx_buf;
+ goto err_pdev;
}
+ mutex_init(&dev_res->bus.mutex);
- mutex_init(&goodix_spi_bus.mutex);
-
- goodix_spi_bus.dma_mode_enabled = false;
+ dev_res->bus.dma_mode_enabled = false;
#ifdef CONFIG_GOOG_TOUCH_INTERFACE
- goodix_spi_bus.dma_mode_enabled = goog_check_spi_dma_enabled(spi);
- ts_info("dma_mode: %s\n", goodix_spi_bus.dma_mode_enabled ? "enabled" : "disabled");
+ dev_res->bus.dma_mode_enabled = goog_check_spi_dma_enabled(spi);
+ ts_info("dma_mode: %s\n", dev_res->bus.dma_mode_enabled ? "enabled" : "disabled");
#endif
- /* ts core device */
- goodix_pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
- if (!goodix_pdev) {
- ret = -ENOMEM;
- goto err_alloc_pdev;
- }
-
- goodix_pdev->name = GOODIX_CORE_DRIVER_NAME;
- goodix_pdev->id = 0;
- goodix_pdev->num_resources = 0;
- /*
- * you can find this platform dev in
- * /sys/devices/platform/goodix_ts.0
- * goodix_pdev->dev.parent = &client->dev;
- */
- goodix_pdev->dev.platform_data = &goodix_spi_bus;
- goodix_pdev->dev.release = goodix_pdev_release;
+ // platform device init
+ dev_res->pdev.name = GOODIX_CORE_DRIVER_NAME;
+ dev_res->pdev.id = dev_res->id;
+ dev_res->pdev.num_resources = 0;
/* register platform device, then the goodix_ts_core
* module will probe the touch device.
*/
- ret = platform_device_register(goodix_pdev);
+ ret = platform_device_register(&dev_res->pdev);
if (ret) {
ts_err("failed register goodix platform device, %d", ret);
- goto err_register_platform_device;
+ goto err_pdev;
}
ts_info("spi probe out");
return 0;
-err_register_platform_device:
- kfree(goodix_pdev);
-err_alloc_pdev:
- kfree(goodix_spi_bus.tx_buf);
-err_alloc_tx_buf:
- kfree(goodix_spi_bus.rx_buf);
-
+err_pdev:
+ kfree(dev_res->bus.rx_buf);
+ kfree(dev_res->bus.tx_buf);
+err_get_ic_type:
+ kfree(dev_res);
ts_info("spi probe out, %d", ret);
return ret;
}
static int goodix_spi_remove(struct spi_device *spi)
{
- platform_device_unregister(goodix_pdev);
+ /* goodix_ts_core_exit() will unregister device(s) */
+ // platform_device_unregister(dev_res->pdev);
return 0;
}
diff --git a/goodix_cfg_bin.c b/goodix_cfg_bin.c
index f7fef30..ab24e6a 100644
--- a/goodix_cfg_bin.c
+++ b/goodix_cfg_bin.c
@@ -114,7 +114,7 @@ static int goodix_read_cfg_bin(struct device *dev, const char *cfg_name,
if (!ret)
break;
ts_info("get cfg bin retry:[%d]", GOODIX_RETRY_3 - retry);
- msleep(200);
+ msleep(300);
}
if (retry < 0) {
ts_err("failed get cfg bin[%s] error:%d", cfg_name, ret);
diff --git a/goodix_ts_core.c b/goodix_ts_core.c
index 120c4f5..2380555 100644
--- a/goodix_ts_core.c
+++ b/goodix_ts_core.c
@@ -31,257 +31,60 @@
// #include "../../../video/fbdev/core/fb_firefly.h"
#define GOODIX_DEFAULT_CFG_NAME "goodix_cfg_group.cfg"
-#define GOOIDX_INPUT_PHYS "goodix_ts/input0"
-struct goodix_module goodix_modules;
-int core_module_prob_sate = CORE_MODULE_UNPROBED;
+struct goodix_device_manager goodix_devices;
-static const struct dev_pm_ops dev_pm_ops;
+static const struct dev_pm_ops dev_pm_ops; /* [GOOG] */
-static int goodix_send_ic_config(struct goodix_ts_core *cd, int type);
-/**
- * __do_register_ext_module - register external module
- * to register into touch core modules structure
- * return 0 on success, otherwise return < 0
- */
-static int __do_register_ext_module(struct goodix_ext_module *module)
+static void goodix_device_manager_init(void)
{
- struct goodix_ext_module *ext_module, *next;
- struct list_head *insert_point = &goodix_modules.head;
-
- /* prority level *must* be set */
- if (module->priority == EXTMOD_PRIO_RESERVED) {
- ts_err("Priority of module [%s] needs to be set", module->name);
- return -EINVAL;
- }
- mutex_lock(&goodix_modules.mutex);
- /* find insert point for the specified priority */
- if (!list_empty(&goodix_modules.head)) {
- list_for_each_entry_safe(
- ext_module, next, &goodix_modules.head, list)
- {
- if (ext_module == module) {
- ts_info("Module [%s] already exists",
- module->name);
- mutex_unlock(&goodix_modules.mutex);
- return 0;
- }
- }
-
- /* smaller priority value with higher priority level */
- list_for_each_entry_safe(
- ext_module, next, &goodix_modules.head, list)
- {
- if (ext_module->priority >= module->priority) {
- insert_point = &ext_module->list;
- break;
- }
- }
- }
-
- if (module->funcs && module->funcs->init) {
- if (module->funcs->init(goodix_modules.core_data, module) < 0) {
- ts_err("Module [%s] init error",
- module->name ? module->name : " ");
- mutex_unlock(&goodix_modules.mutex);
- return -EFAULT;
- }
- }
-
- list_add(&module->list, insert_point->prev);
- mutex_unlock(&goodix_modules.mutex);
-
- return 0;
-}
-
-static void goodix_register_ext_module_work(struct work_struct *work)
-{
- struct goodix_ext_module *module =
- container_of(work, struct goodix_ext_module, work);
-
- ts_info("module register work IN");
-
- /* driver probe failed */
- if (core_module_prob_sate != CORE_MODULE_PROB_SUCCESS) {
- ts_err("Can't register ext_module core error");
+ if (goodix_devices.initialized)
return;
- }
-
- if (__do_register_ext_module(module))
- ts_err("failed register module: %s", module->name);
- else
- ts_info("success register module: %s", module->name);
+ goodix_devices.initialized = true;
+ INIT_LIST_HEAD(&goodix_devices.list);
+ mutex_init(&goodix_devices.mutex);
}
-static void goodix_core_module_init(void)
+static void goodix_device_manager_exit(void)
{
- if (goodix_modules.initialized)
- return;
- goodix_modules.initialized = true;
- INIT_LIST_HEAD(&goodix_modules.head);
- mutex_init(&goodix_modules.mutex);
-}
-
-/**
- * goodix_register_ext_module - interface for register external module
- * to the core. This will create a workqueue to finish the real register
- * work and return immediately. The user need to check the final result
- * to make sure registe is success or fail.
- *
- * @module: pointer to external module to be register
- * return: 0 ok, <0 failed
- */
-int goodix_register_ext_module(struct goodix_ext_module *module)
-{
- if (!module)
- return -EINVAL;
-
- ts_info("IN");
-
- goodix_core_module_init();
- INIT_WORK(&module->work, goodix_register_ext_module_work);
- schedule_work(&module->work);
-
- ts_info("OUT");
- return 0;
-}
-
-/**
- * goodix_register_ext_module_no_wait
- * return: 0 ok, <0 failed
- */
-int goodix_register_ext_module_no_wait(struct goodix_ext_module *module)
-{
- if (!module)
- return -EINVAL;
-
- ts_info("IN");
- goodix_core_module_init();
- /* driver probe failed */
- if (core_module_prob_sate != CORE_MODULE_PROB_SUCCESS) {
- ts_err("Can't register ext_module core error");
- return -EINVAL;
- }
- return __do_register_ext_module(module);
-}
-
-/**
- * goodix_unregister_ext_module - interface for external module
- * to unregister external modules
- *
- * @module: pointer to external module
- * return: 0 ok, <0 failed
- */
-int goodix_unregister_ext_module(struct goodix_ext_module *module)
-{
- struct goodix_ext_module *ext_module, *next;
- bool found = false;
-
- if (!module)
- return -EINVAL;
-
- if (!goodix_modules.initialized)
- return -EINVAL;
-
- if (!goodix_modules.core_data)
- return -ENODEV;
+ struct goodix_device_resource *res, *next;
- mutex_lock(&goodix_modules.mutex);
- if (!list_empty(&goodix_modules.head)) {
- list_for_each_entry_safe(
- ext_module, next, &goodix_modules.head, list)
- {
- if (ext_module == module) {
- found = true;
- break;
- }
+ if (!list_empty(&goodix_devices.list)) {
+ list_for_each_entry_safe(res, next, &goodix_devices.list, list) {
+ platform_device_unregister(&res->pdev);
+ kfree(res);
}
- } else {
- mutex_unlock(&goodix_modules.mutex);
- return 0;
}
-
- if (!found) {
- ts_debug("Module [%s] never registed", module->name);
- mutex_unlock(&goodix_modules.mutex);
- return 0;
- }
-
- list_del(&module->list);
- mutex_unlock(&goodix_modules.mutex);
-
- if (module->funcs && module->funcs->exit)
- module->funcs->exit(goodix_modules.core_data, module);
-
- ts_info("Module [%s] unregistered", module->name ? module->name : " ");
- return 0;
-}
-
-static void goodix_ext_sysfs_release(struct kobject *kobj)
-{
- ts_info("Kobject released!");
-}
-
-#define to_ext_module(kobj) container_of(kobj, struct goodix_ext_module, kobj)
-#define to_ext_attr(attr) container_of(attr, struct goodix_ext_attribute, attr)
-
-static ssize_t goodix_ext_sysfs_show(
- struct kobject *kobj, struct attribute *attr, char *buf)
-{
- struct goodix_ext_module *module = to_ext_module(kobj);
- struct goodix_ext_attribute *ext_attr = to_ext_attr(attr);
-
- if (ext_attr->show)
- return ext_attr->show(module, buf);
-
- return -EIO;
}
-static ssize_t goodix_ext_sysfs_store(struct kobject *kobj,
- struct attribute *attr, const char *buf, size_t count)
+int goodix_device_register(struct goodix_device_resource *device)
{
- struct goodix_ext_module *module = to_ext_module(kobj);
- struct goodix_ext_attribute *ext_attr = to_ext_attr(attr);
-
- if (ext_attr->store)
- return ext_attr->store(module, buf, count);
-
- return -EIO;
-}
-
-static const struct sysfs_ops goodix_ext_ops = { .show = goodix_ext_sysfs_show,
- .store = goodix_ext_sysfs_store };
+ if (!device)
+ return -ENXIO;
-static struct kobj_type goodix_ext_ktype = {
- .release = goodix_ext_sysfs_release,
- .sysfs_ops = &goodix_ext_ops,
-};
+ mutex_lock(&goodix_devices.mutex);
+ list_add(&device->list, &goodix_devices.list);
+ device->id = goodix_devices.nums++;
+ sprintf(device->name, "%s.%d", GOODIX_CORE_DRIVER_NAME, device->id);
+ mutex_unlock(&goodix_devices.mutex);
+ ts_info("register device %s", device->name);
-struct kobj_type *goodix_get_default_ktype(void)
-{
- return &goodix_ext_ktype;
+ return 0;
}
-struct kobject *goodix_get_default_kobj(void)
-{
- struct kobject *kobj = NULL;
-
- if (goodix_modules.core_data && goodix_modules.core_data->pdev)
- kobj = &goodix_modules.core_data->pdev->dev.kobj;
- return kobj;
-}
+static int goodix_send_ic_config(struct goodix_ts_core *cd, int type);
/* show driver information */
-static ssize_t driver_info_show(
- struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t driver_info_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- return snprintf(
- buf, PAGE_SIZE, "DriverVersion:%s\n", GOODIX_DRIVER_VERSION);
+ return snprintf(buf, PAGE_SIZE, "DriverVersion:%s\n",
+ GOODIX_DRIVER_VERSION);
}
/* show chip infoamtion */
-static ssize_t chip_info_show(
- struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t chip_info_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct goodix_ts_core *cd = dev_get_drvdata(dev);
struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
@@ -670,13 +473,15 @@ static ssize_t goodix_ts_esd_info_show(
static ssize_t goodix_ts_esd_info_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
+ struct goodix_ts_core *cd = dev_get_drvdata(dev);
+
if (!buf || count <= 0)
return -EINVAL;
if (buf[0] != '0')
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
else
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
return count;
}
@@ -706,35 +511,19 @@ static ssize_t goodix_ts_debug_log_store(struct device *dev,
return count;
}
-#define GOODIX_MAX_PEN_FREQ_DATA_LEN 16
-#define GOODIX_HOGP_INFO_LEN 3
-
-#pragma pack(1)
-struct goodix_hid_hogp {
- u16 pressure;
- u8 key;
-};
-#pragma pack()
-
-struct goodix_ble_data {
- u8 freq[GOODIX_MAX_PEN_FREQ_DATA_LEN];
- u8 hogp[GOODIX_HOGP_INFO_LEN];
- int hogp_ready;
- int freq_ready;
- struct mutex lock;
-} goodix_ble_data;
-
int goodix_update_pen_freq(struct goodix_ts_core *cd, u8 *data, int len)
{
- if (len > sizeof(goodix_ble_data.freq)) {
+ struct goodix_ble_data *ble_data = &cd->ble_data;
+
+ if (len > sizeof(ble_data->freq)) {
ts_err("pen freq data exceed limit");
return -EINVAL;
}
- mutex_lock(&goodix_ble_data.lock);
- memset(goodix_ble_data.freq, 0, sizeof(goodix_ble_data.freq));
- memcpy(goodix_ble_data.freq, data, len);
- goodix_ble_data.freq_ready = 1;
- mutex_unlock(&goodix_ble_data.lock);
+ mutex_lock(&ble_data->lock);
+ memset(ble_data->freq, 0, sizeof(ble_data->freq));
+ memcpy(ble_data->freq, data, len);
+ ble_data->freq_ready = 1;
+ mutex_unlock(&ble_data->lock);
sysfs_notify(&cd->pdev->dev.kobj, NULL, "pen_freq");
ts_debug("send pen freq hop event");
return 0;
@@ -744,11 +533,14 @@ int goodix_update_pen_freq(struct goodix_ts_core *cd, u8 *data, int len)
static ssize_t goodix_ts_pen_freq_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
- mutex_lock(&goodix_ble_data.lock);
- memcpy(buf, goodix_ble_data.freq, sizeof(goodix_ble_data.freq));
- goodix_ble_data.freq_ready = 0;
- mutex_unlock(&goodix_ble_data.lock);
- return sizeof(goodix_ble_data.freq);
+ struct goodix_ts_core *core_data = dev_get_drvdata(dev);
+ struct goodix_ble_data *ble_data = &core_data->ble_data;
+
+ mutex_lock(&ble_data->lock);
+ memcpy(buf, ble_data->freq, sizeof(ble_data->freq));
+ ble_data->freq_ready = 0;
+ mutex_unlock(&ble_data->lock);
+ return sizeof(ble_data->freq);
}
/* debug level store */
@@ -757,12 +549,13 @@ static ssize_t goodix_ts_pen_debug_store(struct device *dev,
{
int pen_freq;
struct goodix_ts_core *core_data = dev_get_drvdata(dev);
+ struct goodix_ble_data *ble_data = &core_data->ble_data;
sscanf(buf, "%d", &pen_freq);
ts_debug("set new pen_freq %d", pen_freq);
- goodix_ble_data.freq[0] = 0xC0;
- goodix_ble_data.freq[1] = 1;
- goodix_ble_data.freq[2] = pen_freq & 0xFF;
+ ble_data->freq[0] = 0xC0;
+ ble_data->freq[1] = 1;
+ ble_data->freq[2] = pen_freq & 0xFF;
sysfs_notify(&core_data->pdev->dev.kobj, NULL, "pen_freq");
return count;
@@ -772,18 +565,20 @@ static ssize_t goodix_ts_pen_hogp_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct goodix_hid_hogp *tmp_prs;
+ struct goodix_ts_core *core_data = dev_get_drvdata(dev);
+ struct goodix_ble_data *ble_data = &core_data->ble_data;
- if (count < sizeof(goodix_ble_data.hogp)) {
+ if (count < sizeof(ble_data->hogp)) {
ts_err("data count to short");
return -EINVAL;
}
- mutex_lock(&goodix_ble_data.lock);
- memcpy(goodix_ble_data.hogp, buf, sizeof(goodix_ble_data.hogp));
- goodix_ble_data.hogp_ready = 1;
- mutex_unlock(&goodix_ble_data.lock);
+ mutex_lock(&ble_data->lock);
+ memcpy(ble_data->hogp, buf, sizeof(ble_data->hogp));
+ ble_data->hogp_ready = 1;
+ mutex_unlock(&ble_data->lock);
- tmp_prs = (struct goodix_hid_hogp *)goodix_ble_data.hogp;
+ tmp_prs = (struct goodix_hid_hogp *)ble_data->hogp;
ts_debug("set ble pen data: %d, key %x", tmp_prs->pressure,
tmp_prs->key);
return count;
@@ -841,6 +636,7 @@ static void goodix_ts_sysfs_exit(struct goodix_ts_core *core_data)
sysfs_remove_group(&core_data->pdev->dev.kobj, &sysfs_group);
}
+/* [GOOG] */
#if IS_ENABLED(CONFIG_TOUCHSCREEN_MOTION_FILTER)
int set_continuously_report_enabled(struct device *dev, bool enabled)
{
@@ -907,10 +703,10 @@ int set_sensing_enabled(struct device *dev, bool enabled)
if (enabled) {
cd->hw_ops->resume(cd);
cd->hw_ops->irq_enable(cd, true);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
ts_info("set sense ON");
} else {
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
cd->hw_ops->irq_enable(cd, false);
cd->hw_ops->suspend(cd);
ts_info("set sense OFF");
@@ -969,8 +765,8 @@ static int get_mutual_sensor_data(
cmd->buffer = (u8 *)cd->mutual_data;
cmd->size = tx * rx * sizeof(uint16_t);
} else {
- /* close esd */
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ /* disable esd */
+ goodix_ts_esd_off(cd);
ret = -EINVAL;
if (cmd->type == GTI_SENSOR_DATA_TYPE_MS_DIFF) {
@@ -985,9 +781,8 @@ static int get_mutual_sensor_data(
cmd->buffer = (u8 *)cd->mutual_data_manual;
cmd->size = tx * rx * sizeof(uint16_t);
}
-
/* enable esd */
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
}
return ret;
}
@@ -1006,7 +801,7 @@ static int get_self_sensor_data(
} else {
/* disable irq & close esd */
cd->hw_ops->irq_enable(cd, false);
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
ret = -EINVAL;
if (cmd->type == GTI_SENSOR_DATA_TYPE_SS_DIFF) {
@@ -1024,7 +819,7 @@ static int get_self_sensor_data(
/* enable irq & esd */
cd->hw_ops->irq_enable(cd, true);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
}
return ret;
}
@@ -1188,8 +983,10 @@ static int gti_ping(void *private_data, struct gti_ping_cmd *cmd)
static int gti_selftest(void *private_data, struct gti_selftest_cmd *cmd)
{
+ struct goodix_ts_core *cd = private_data;
+
cmd->result = GTI_SELFTEST_RESULT_DONE;
- return driver_test_selftest(cmd->buffer);
+ return driver_test_selftest(cd, cmd->buffer);
}
static int gti_get_context_driver(void *private_data,
@@ -1207,6 +1004,7 @@ static int gti_set_report_rate(void *private_data,
}
#endif
+/*~[GOOG] */
/* prosfs create */
static int rawdata_proc_show(struct seq_file *m, void *v)
@@ -1257,8 +1055,8 @@ exit:
static int rawdata_proc_open(struct inode *inode, struct file *file)
{
- return single_open_size(
- file, rawdata_proc_show, PDE_DATA(inode), PAGE_SIZE * 10);
+ return single_open_size(file, rawdata_proc_show,
+ PDE_DATA(inode), PAGE_SIZE * 10);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0))
@@ -1279,78 +1077,51 @@ static const struct file_operations rawdata_proc_fops = {
static int goodix_ts_procfs_init(struct goodix_ts_core *core_data)
{
+ int dev_id = core_data->pdev->id;
struct proc_dir_entry *proc_entry;
- int ret = 0;
+ char proc_node[32] = {0};
+ int ret = 0; /* [GOOG] */
- proc_entry = proc_mkdir("goodix_ts", NULL);
- if (proc_entry == NULL) {
- ts_err("failed to create proc entry: goodix_ts");
- return -ENOMEM;
- }
+ sprintf(proc_node, "goodix_ts.%d", dev_id);
- proc_entry = proc_create_data("goodix_ts/tp_capacitance_data", 0664,
- NULL, &rawdata_proc_fops, core_data);
- if (proc_entry == NULL) {
- ts_err("failed to create proc entry: goodix_ts/tp_capacitance_data");
+ core_data->proc_dir_entry = proc_mkdir(proc_node, NULL);
+ if (!core_data->proc_dir_entry)
+ return -ENOMEM;
+ proc_entry = proc_create_data("tp_capacitance_data",
+ 0664, core_data->proc_dir_entry, &rawdata_proc_fops, core_data);
+ if (!proc_entry) {
+ ts_err("failed to create proc entry: goodix_ts.%d/tp_capacitance_data",
+ dev_id);
ret = -ENOMEM;
goto err_create_data;
}
ret = driver_test_proc_init(core_data);
if (ret != 0) {
- ts_err("failed to create proc entry: goodix_ts/driver_test");
+ ts_err("failed to create proc entry: goodix_ts.%d/driver_test", dev_id);
ret = -ENOMEM;
goto err_create_driver;
}
- return ret;
+
+ return 0;
err_create_driver:
- remove_proc_entry("goodix_ts/tp_capacitance_data", NULL);
+ remove_proc_entry("tp_capacitance_data", core_data->proc_dir_entry);
err_create_data:
- remove_proc_entry("goodix_ts", NULL);
+ remove_proc_entry(proc_node, NULL);
return ret;
}
static void goodix_ts_procfs_exit(struct goodix_ts_core *core_data)
{
- driver_test_proc_remove();
- remove_proc_entry("goodix_ts/tp_capacitance_data", NULL);
- remove_proc_entry("goodix_ts", NULL);
-}
+ int dev_id = core_data->pdev->id;
+ char proc_node[32] = {0};
-/* event notifier */
-static BLOCKING_NOTIFIER_HEAD(ts_notifier_list);
-/**
- * goodix_ts_register_client - register a client notifier
- * @nb: notifier block to callback on events
- * see enum ts_notify_event in goodix_ts_core.h
- */
-int goodix_ts_register_notifier(struct notifier_block *nb)
-{
- return blocking_notifier_chain_register(&ts_notifier_list, nb);
-}
+ sprintf(proc_node, "goodix_ts.%d", dev_id);
-/**
- * goodix_ts_unregister_client - unregister a client notifier
- * @nb: notifier block to callback on events
- * see enum ts_notify_event in goodix_ts_core.h
- */
-int goodix_ts_unregister_notifier(struct notifier_block *nb)
-{
- return blocking_notifier_chain_unregister(&ts_notifier_list, nb);
-}
-
-/**
- * fb_notifier_call_chain - notify clients of fb_events
- * see enum ts_notify_event in goodix_ts_core.h
- */
-int goodix_ts_blocking_notify(enum ts_notify_event evt, void *v)
-{
- int ret;
-
- ret = blocking_notifier_call_chain(
- &ts_notifier_list, (unsigned long)evt, v);
- return ret;
+ driver_test_proc_remove(core_data);
+ remove_proc_entry("tp_capacitance_data", core_data->proc_dir_entry);
+ remove_proc_entry(proc_node, NULL);
}
#if IS_ENABLED(CONFIG_OF)
@@ -1619,8 +1390,8 @@ static void goodix_ts_report_pen(
{
struct input_dev *dev = cd->pen_dev;
int i;
- static unsigned int pen_pressure;
struct goodix_hid_hogp *hogp;
+ struct goodix_ble_data *ble_data = &cd->ble_data;
char trace_tag[128];
ktime_t pen_ktime;
@@ -1635,21 +1406,21 @@ static void goodix_ts_report_pen(
ktime_to_ns(ktime_sub(pen_ktime, cd->coords_timestamp)));
ATRACE_BEGIN(trace_tag);
input_report_key(dev, BTN_TOUCH, 1);
- input_report_key(dev, pen_data->coords.tool_type, 1);
+ input_report_key(dev, BTN_TOOL_PEN, 1);
input_report_abs(dev, ABS_X, pen_data->coords.x);
input_report_abs(dev, ABS_Y, pen_data->coords.y);
- mutex_lock(&goodix_ble_data.lock);
- if (goodix_ble_data.hogp_ready) {
- hogp = (struct goodix_hid_hogp *)goodix_ble_data.hogp;
- pen_pressure = hogp->pressure;
+ mutex_lock(&ble_data->lock);
+ if (ble_data->hogp_ready) {
+ hogp = (struct goodix_hid_hogp *)ble_data->hogp;
+ cd->pen_pressure = hogp->pressure;
ts_debug("update pen pressure from ble %d",
- pen_pressure);
+ cd->pen_pressure);
}
- goodix_ble_data.hogp_ready = 0;
- mutex_unlock(&goodix_ble_data.lock);
+ ble_data->hogp_ready = 0;
+ mutex_unlock(&ble_data->lock);
- if (pen_data->coords.p && pen_pressure)
- pen_data->coords.p = pen_pressure;
+ if (pen_data->coords.p && cd->pen_pressure)
+ pen_data->coords.p = cd->pen_pressure;
input_report_abs(dev, ABS_PRESSURE, pen_data->coords.p);
if (pen_data->coords.p == 0)
input_report_abs(dev, ABS_DISTANCE, 1);
@@ -1670,9 +1441,9 @@ static void goodix_ts_report_pen(
ktime_to_ns(cd->coords_timestamp), ktime_to_ns(pen_ktime),
ktime_to_ns(ktime_sub(pen_ktime, cd->coords_timestamp)));
ATRACE_BEGIN(trace_tag);
- pen_pressure = 0;
+ cd->pen_pressure = 0;
input_report_key(dev, BTN_TOUCH, 0);
- input_report_key(dev, pen_data->coords.tool_type, 0);
+ input_report_key(dev, BTN_TOOL_PEN, 0);
}
/* report pen button */
for (i = 0; i < GOODIX_MAX_PEN_KEY; i++) {
@@ -1850,9 +1621,8 @@ static int goodix_ts_request_handle(
else if (ts_event->request_code == REQUEST_TYPE_RESET)
ret = hw_ops->reset(cd, GOODIX_NORMAL_RESET_DELAY_MS);
else if (ts_event->request_code == REQUEST_TYPE_UPDATE)
- ret = goodix_do_fw_update(
- NULL, UPDATE_MODE_FORCE | UPDATE_MODE_BLOCK |
- UPDATE_MODE_SRC_REQUEST);
+ ret = goodix_do_fw_update(cd, UPDATE_MODE_FORCE | UPDATE_MODE_BLOCK |
+ UPDATE_MODE_SRC_REQUEST);
else if (ts_event->request_code == REQUEST_PEN_FREQ_HOP)
ret = goodix_update_pen_freq(cd, ts_event->request_data,
sizeof(ts_event->request_data));
@@ -1949,7 +1719,6 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data)
{
struct goodix_ts_core *core_data = data;
struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops;
- struct goodix_ext_module *ext_module, *next;
struct goodix_ts_event *ts_event = &core_data->ts_event;
struct goodix_ts_esd *ts_esd = &core_data->ts_esd;
int ret;
@@ -1962,29 +1731,18 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data)
}
#endif
- /*
+/* [GOOG]
+ * Remove the control to enable/disable the interrupt for bottom-half.
+ disable_irq_nosync(core_data->irq);
+ */
+
+ /* [GOOG]
* Since we received an interrupt from touch firmware, it means touch
* firmware is still alive. So skip esd check once.
*/
ts_esd->skip_once = true;
core_data->irq_trig_cnt++;
- /* inform external module */
- mutex_lock(&goodix_modules.mutex);
- list_for_each_entry_safe(ext_module, next, &goodix_modules.head, list)
- {
- if (!ext_module->funcs->irq_event)
- continue;
- ret = ext_module->funcs->irq_event(core_data, ext_module);
- if (ret == EVT_CANCEL_IRQEVT) {
- mutex_unlock(&goodix_modules.mutex);
-#if IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE) && IS_ENABLED(CONFIG_GTI_PM)
- goog_pm_wake_unlock_nosync(core_data->gti, GTI_PM_WAKELOCK_TYPE_IRQ);
-#endif
- return IRQ_HANDLED;
- }
- }
- mutex_unlock(&goodix_modules.mutex);
/* read touch data from touch device */
ret = hw_ops->event_handler(core_data, ts_event);
@@ -2012,10 +1770,16 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data)
goodix_ts_request_handle(core_data, ts_event);
if (ts_event->event_type & EVENT_STATUS)
goodix_ts_report_status(core_data, ts_event);
+ if (ts_event->event_type & EVENT_GESTURE)
+ goodix_ts_report_gesture(core_data, ts_event);
/* read done */
- hw_ops->after_event_handler(core_data);
+ hw_ops->after_event_handler(core_data); /* [GOOG] */
}
+/* [GOOG]
+ * Remove the control to enable/disable the interrupt for bottom-half.
+ enable_irq(core_data->irq);
+ */
#if IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE) && IS_ENABLED(CONFIG_GTI_PM)
goog_pm_wake_unlock_nosync(core_data->gti, GTI_PM_WAKELOCK_TYPE_IRQ);
@@ -2240,6 +2004,7 @@ static int goodix_ts_input_dev_config(struct goodix_ts_core *core_data)
{
struct goodix_ts_board_data *ts_bdata = board_data(core_data);
struct input_dev *input_dev = NULL;
+ int dev_id = core_data->pdev->id;
int r;
input_dev = input_allocate_device();
@@ -2248,12 +2013,15 @@ static int goodix_ts_input_dev_config(struct goodix_ts_core *core_data)
return -ENOMEM;
}
- input_dev->name = GOODIX_CORE_DRIVER_NAME;
- input_dev->phys = GOOIDX_INPUT_PHYS;
- input_dev->uniq = "goodix_ts";
- input_dev->id.product = 0xDEAD;
- input_dev->id.vendor = 0xBEEF;
- input_dev->id.version = 10427;
+ sprintf(core_data->input_name, "%s%d", GOODIX_CORE_DRIVER_NAME, dev_id);
+ input_dev->dev.parent = &core_data->pdev->dev; /* [GOOG] */
+ input_dev->name = core_data->input_name;
+ input_dev->uniq = input_dev->name;
+ input_dev->phys = input_dev->name;
+ input_dev->id.bustype = core_data->bus->bus_type;
+ input_dev->id.product = 0x0100 + dev_id;
+ input_dev->id.vendor = 0x27C6;
+ input_dev->id.version = 0x0100;
set_bit(EV_SYN, input_dev->evbit);
set_bit(EV_KEY, input_dev->evbit);
@@ -2302,6 +2070,7 @@ static int goodix_ts_pen_dev_config(struct goodix_ts_core *core_data)
{
struct goodix_ts_board_data *ts_bdata = board_data(core_data);
struct input_dev *pen_dev = NULL;
+ int dev_id = core_data->pdev->id;
int r;
pen_dev = input_allocate_device();
@@ -2310,12 +2079,15 @@ static int goodix_ts_pen_dev_config(struct goodix_ts_core *core_data)
return -ENOMEM;
}
- pen_dev->name = GOODIX_PEN_DRIVER_NAME;
- pen_dev->phys = "goodix_ts,pen/input0";
- pen_dev->uniq = "goodix_ts,pen";
- pen_dev->id.product = 0xDEAD;
- pen_dev->id.vendor = 0xBEEF;
- pen_dev->id.version = 10427;
+ sprintf(core_data->input_pen_name, "%s%d%s", GOODIX_CORE_DRIVER_NAME, dev_id, ",pen");
+ pen_dev->dev.parent = &core_data->pdev->dev; /* [GOOG] */
+ pen_dev->name = core_data->input_pen_name;
+ pen_dev->uniq = pen_dev->name;
+ pen_dev->phys = pen_dev->name;
+ pen_dev->id.bustype = core_data->bus->bus_type;
+ pen_dev->id.product = 0x0200 + dev_id;
+ pen_dev->id.vendor = 0x27C6;
+ pen_dev->id.version = 0x0100;
pen_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
set_bit(ABS_X, pen_dev->absbit);
@@ -2362,7 +2134,7 @@ void goodix_ts_pen_dev_remove(struct goodix_ts_core *core_data)
{
if (!core_data->pen_dev)
return;
- mutex_destroy(&goodix_ble_data.lock);
+ mutex_destroy(&core_data->ble_data.lock);
input_unregister_device(core_data->pen_dev);
core_data->pen_dev = NULL;
}
@@ -2420,7 +2192,7 @@ exit:
/**
* goodix_ts_esd_on - turn on esd protection
*/
-static void goodix_ts_esd_on(struct goodix_ts_core *cd)
+void goodix_ts_esd_on(struct goodix_ts_core *cd)
{
struct goodix_ic_info_misc *misc = &cd->ic_info.misc;
struct goodix_ts_esd *ts_esd = &cd->ts_esd;
@@ -2441,7 +2213,7 @@ static void goodix_ts_esd_on(struct goodix_ts_core *cd)
/**
* goodix_ts_esd_off - turn off esd protection
*/
-static void goodix_ts_esd_off(struct goodix_ts_core *cd)
+void goodix_ts_esd_off(struct goodix_ts_core *cd)
{
struct goodix_ts_esd *ts_esd = &cd->ts_esd;
int ret;
@@ -2455,40 +2227,6 @@ static void goodix_ts_esd_off(struct goodix_ts_core *cd)
}
/**
- * goodix_esd_notifier_callback - notification callback
- * under certain condition, we need to turn off/on the esd
- * protector, we use kernel notify call chain to achieve this.
- *
- * for example: before firmware update we need to turn off the
- * esd protector and after firmware update finished, we should
- * turn on the esd protector.
- */
-static int goodix_esd_notifier_callback(
- struct notifier_block *nb, unsigned long action, void *data)
-{
- struct goodix_ts_esd *ts_esd =
- container_of(nb, struct goodix_ts_esd, esd_notifier);
-
- switch (action) {
- case NOTIFY_FWUPDATE_START:
- case NOTIFY_SUSPEND:
- case NOTIFY_ESD_OFF:
- goodix_ts_esd_off(ts_esd->ts_core);
- break;
- case NOTIFY_FWUPDATE_FAILED:
- case NOTIFY_FWUPDATE_SUCCESS:
- case NOTIFY_RESUME:
- case NOTIFY_ESD_ON:
- goodix_ts_esd_on(ts_esd->ts_core);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-/**
* goodix_ts_esd_init - initialize esd protection
*/
int goodix_ts_esd_init(struct goodix_ts_core *cd)
@@ -2504,8 +2242,6 @@ int goodix_ts_esd_init(struct goodix_ts_core *cd)
INIT_DELAYED_WORK(&ts_esd->esd_work, goodix_ts_esd_work);
ts_esd->ts_core = cd;
atomic_set(&ts_esd->esd_on, 0);
- ts_esd->esd_notifier.notifier_call = goodix_esd_notifier_callback;
- goodix_ts_register_notifier(&ts_esd->esd_notifier);
goodix_ts_esd_on(cd);
return 0;
@@ -2516,10 +2252,13 @@ void goodix_ts_esd_uninit(struct goodix_ts_core *cd)
struct goodix_ts_esd *ts_esd = &cd->ts_esd;
if (atomic_read(&ts_esd->esd_on))
goodix_ts_esd_off(cd);
- goodix_ts_unregister_notifier(&ts_esd->esd_notifier);
}
-#if !IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE)
+#if IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE)
+static void goodix_ts_release_connects(struct goodix_ts_core *core_data)
+{
+}
+#else
static void goodix_ts_release_connects(struct goodix_ts_core *core_data)
{
struct input_dev *input_dev = core_data->input_dev;
@@ -2545,9 +2284,7 @@ static void goodix_ts_release_connects(struct goodix_ts_core *core_data)
*/
static int goodix_ts_suspend(struct goodix_ts_core *core_data)
{
- struct goodix_ext_module *ext_module, *next;
struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops;
- int ret;
if (core_data->init_stage < CORE_INIT_STAGE2 ||
atomic_read(&core_data->suspended))
@@ -2557,68 +2294,23 @@ static int goodix_ts_suspend(struct goodix_ts_core *core_data)
atomic_set(&core_data->suspended, 1);
/* disable irq */
hw_ops->disable_irq_nosync(core_data);
+ goodix_ts_esd_off(core_data);
- /*
- * notify suspend event, inform the esd protector
- * and charger detector to turn off the work
- */
- goodix_ts_blocking_notify(NOTIFY_SUSPEND, NULL);
-
- /* inform external module */
- mutex_lock(&goodix_modules.mutex);
- if (!list_empty(&goodix_modules.head)) {
- list_for_each_entry_safe(
- ext_module, next, &goodix_modules.head, list)
- {
- if (!ext_module->funcs->before_suspend)
- continue;
-
- ret = ext_module->funcs->before_suspend(
- core_data, ext_module);
- if (ret == EVT_CANCEL_SUSPEND) {
- mutex_unlock(&goodix_modules.mutex);
- ts_info("Canceled by module:%s",
- ext_module->name);
- goto out;
- }
- }
- }
- mutex_unlock(&goodix_modules.mutex);
-
- /* enter sleep mode or power off */
- if (core_data->board_data.sleep_enable)
- hw_ops->suspend(core_data);
- else
- goodix_ts_power_off(core_data);
-
- /* inform exteranl modules */
- mutex_lock(&goodix_modules.mutex);
- if (!list_empty(&goodix_modules.head)) {
- list_for_each_entry_safe(
- ext_module, next, &goodix_modules.head, list)
- {
- if (!ext_module->funcs->after_suspend)
- continue;
-
- ret = ext_module->funcs->after_suspend(
- core_data, ext_module);
- if (ret == EVT_CANCEL_SUSPEND) {
- mutex_unlock(&goodix_modules.mutex);
- ts_info("Canceled by module:%s",
- ext_module->name);
- goto out;
- }
- }
+ if (core_data->gesture_type) {
+ /* enter gesture mode */
+ hw_ops->gesture(core_data, 0);
+ hw_ops->irq_enable(core_data, true);
+ enable_irq_wake(core_data->irq);
+ } else {
+ /* enter sleep mode or power off */
+ if (core_data->board_data.sleep_enable)
+ hw_ops->suspend(core_data);
+ else
+ goodix_ts_power_off(core_data);
}
- mutex_unlock(&goodix_modules.mutex);
-
- goodix_set_pinctrl_state(core_data, PINCTRL_MODE_SUSPEND);
-
-out:
-#if !IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE)
goodix_ts_release_connects(core_data);
-#endif
+ goodix_set_pinctrl_state(core_data, PINCTRL_MODE_SUSPEND); /* [GOOG] */
ts_info("Suspend end");
return 0;
}
@@ -2674,80 +2366,49 @@ static void monitor_gesture_event(struct work_struct *work)
*/
static int goodix_ts_resume(struct goodix_ts_core *core_data)
{
- struct goodix_ext_module *ext_module, *next;
struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops;
- struct goodix_gesture_data* gesture_data = &core_data->ts_event.gesture_data;
- int ret;
-
if (core_data->init_stage < CORE_INIT_STAGE2 ||
!atomic_read(&core_data->suspended))
return 0;
ts_info("Resume start");
- goodix_set_pinctrl_state(core_data, PINCTRL_MODE_ACTIVE);
+ goodix_set_pinctrl_state(core_data, PINCTRL_MODE_ACTIVE); /* [GOOG] */
atomic_set(&core_data->suspended, 0);
hw_ops->irq_enable(core_data, false);
- mutex_lock(&goodix_modules.mutex);
- if (!list_empty(&goodix_modules.head)) {
- list_for_each_entry_safe(
- ext_module, next, &goodix_modules.head, list)
- {
- if (!ext_module->funcs->before_resume)
- continue;
-
- ret = ext_module->funcs->before_resume(
- core_data, ext_module);
- if (ret == EVT_CANCEL_RESUME) {
- mutex_unlock(&goodix_modules.mutex);
- ts_info("Canceled by module:%s",
- ext_module->name);
- goto out;
- }
- }
- }
- mutex_unlock(&goodix_modules.mutex);
-
+ /* [GOOG] */
if (check_gesture_mode(core_data)) {
+ struct goodix_gesture_data *gesture_data =
+ &core_data->ts_event.gesture_data;
+
gesture_data->gesture_type = GOODIX_GESTURE_UNKNOWN;
core_data->gesture_down_timeout = ktime_add_ms(ktime_get(), 100);
core_data->gesture_up_timeout = ktime_add_ms(ktime_get(), 200);
queue_delayed_work(core_data->event_wq, &core_data->monitor_gesture_work,
msecs_to_jiffies(5));
} else {
- /* reset device or power on*/
- if (core_data->board_data.sleep_enable)
+ if (core_data->gesture_type) {
+ disable_irq_wake(core_data->irq);
hw_ops->reset(core_data, GOODIX_NORMAL_RESET_DELAY_MS);
- else
- goodix_ts_power_on(core_data);
- }
-
- mutex_lock(&goodix_modules.mutex);
- if (!list_empty(&goodix_modules.head)) {
- list_for_each_entry_safe(
- ext_module, next, &goodix_modules.head, list)
- {
- if (!ext_module->funcs->after_resume)
- continue;
-
- ret = ext_module->funcs->after_resume(
- core_data, ext_module);
- if (ret == EVT_CANCEL_RESUME) {
- mutex_unlock(&goodix_modules.mutex);
- ts_info("Canceled by module:%s",
- ext_module->name);
- goto out;
+ } else {
+ /* [GOOG]
+ * Force to reset T-IC as touch resume process instead using brl_resume().
+ */
+ /* reset device or power on*/
+ if (core_data->board_data.sleep_enable) {
+ hw_ops->reset(core_data, GOODIX_NORMAL_RESET_DELAY_MS);
+ //hw_ops->resume(core_data); /* [GOOG] */
+ } else {
+ goodix_ts_power_on(core_data);
}
}
}
- mutex_unlock(&goodix_modules.mutex);
-out:
/* enable irq */
hw_ops->irq_enable(core_data, true);
/* open esd */
- goodix_ts_blocking_notify(NOTIFY_RESUME, NULL);
+ goodix_ts_esd_on(core_data);
ts_info("Resume end");
return 0;
}
@@ -2804,37 +2465,6 @@ static int goodix_ts_pm_resume(struct device *dev)
#endif
#endif
-/**
- * goodix_generic_noti_callback - generic notifier callback
- * for goodix touch notification event.
- */
-static int goodix_generic_noti_callback(
- struct notifier_block *self, unsigned long action, void *data)
-{
- struct goodix_ts_core *cd =
- container_of(self, struct goodix_ts_core, ts_notifier);
- const struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
-
- if (cd->init_stage < CORE_INIT_STAGE2)
- return 0;
-
- ts_info("notify event type 0x%x", (unsigned int)action);
- switch (action) {
- case NOTIFY_FWUPDATE_START:
- hw_ops->irq_enable(cd, 0);
- break;
- case NOTIFY_FWUPDATE_SUCCESS:
- case NOTIFY_FWUPDATE_FAILED:
- if (hw_ops->read_version(cd, &cd->fw_version))
- ts_info("failed read fw version info[ignore]");
- hw_ops->irq_enable(cd, 1);
- break;
- default:
- break;
- }
- return 0;
-}
-
int goodix_ts_stage2_init(struct goodix_ts_core *cd)
{
int ret;
@@ -2866,7 +2496,7 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
ts_err("failed set pen device");
goto err_finger;
}
- mutex_init(&goodix_ble_data.lock);
+ mutex_init(&cd->ble_data.lock);
}
#if IS_ENABLED(CONFIG_FB)
@@ -2978,7 +2608,7 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
#if IS_ENABLED(CONFIG_GOODIX_GESTURE)
/* gesture init */
- ret = gesture_module_init();
+ ret = gesture_module_init(cd);
if (ret < 0) {
ts_err("failed set init gesture");
goto err_init_gesture;
@@ -2986,12 +2616,18 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
#endif
/* inspect init */
- ret = inspect_module_init();
+ ret = inspect_module_init(cd);
if (ret < 0) {
ts_err("failed set init inspect");
goto err_init_inspect;
}
+/*
+ * [GOOG]
+ * Touch frame package will read into `struct goodix_rx_package`.
+ * The total read size for SPI is `touch_frame_size` + 8 bytes(SPI prefix header).
+ * Therefore, `touch_frame_package` will need to allocate 8 extra bytes for SPI I/O.
+ */
cd->touch_frame_size = touch_frame_size;
cd->touch_frame_package =
devm_kzalloc(&cd->pdev->dev, touch_frame_size + 8, GFP_KERNEL);
@@ -3027,6 +2663,7 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
ret = -ENOMEM;
goto err_setup_irq;
}
+/*~[GOOG]*/
/* request irq line */
ret = goodix_ts_irq_setup(cd);
@@ -3039,10 +2676,10 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
return 0;
err_setup_irq:
- inspect_module_exit();
+ inspect_module_exit(cd);
err_init_inspect:
#if IS_ENABLED(CONFIG_GOODIX_GESTURE)
- gesture_module_exit();
+ gesture_module_exit(cd);
err_init_gesture:
#endif
goodix_ts_esd_uninit(cd);
@@ -3120,10 +2757,16 @@ static int goodix_later_init_thread(void *data)
if (ret < 0) {
ts_err("failed to get version info, try to upgrade");
update_flag |= UPDATE_MODE_FORCE;
- goto upgrade;
}
- /* step 2: get config data from config bin */
+ /* step 2: read ic info */
+ ret = hw_ops->get_ic_info(cd, &cd->ic_info);
+ if (ret < 0) {
+ ts_err("failed to get ic info, try to upgrade");
+ update_flag |= UPDATE_MODE_FORCE;
+ }
+
+ /* step 3: get config data from config bin */
ret = goodix_get_config_proc(cd);
if (ret < 0)
ts_info("no valid ic config found");
@@ -3132,35 +2775,20 @@ static int goodix_later_init_thread(void *data)
else
ts_info("one binary, no need find config");
-upgrade:
- /* step 3: init fw struct add try do fw upgrade */
+ /* step 4: init fw struct add try do fw upgrade */
ret = goodix_fw_update_init(cd);
if (ret) {
ts_err("failed init fw update module");
goto err_out;
}
+ /* step 5: do upgrade */
ts_info("update flag: 0x%X", update_flag);
- ret = goodix_do_fw_update(
- cd->ic_configs[CONFIG_TYPE_NORMAL], update_flag);
+ ret = goodix_do_fw_update(cd, update_flag);
if (ret)
ts_err("failed do fw update");
- /* step 4: get fw version and ic_info
- * at this step we believe that the ic is in normal mode,
- * if the version info is invalid there must have some
- * problem we cann't cover so exit init directly.
- */
- ret = hw_ops->read_version(cd, &cd->fw_version);
- if (ret) {
- ts_err("invalid fw version, abort");
- goto uninit_fw;
- }
- ret = hw_ops->get_ic_info(cd, &cd->ic_info);
- if (ret) {
- ts_err("invalid ic info, abort");
- goto uninit_fw;
- }
+ print_ic_info(&cd->ic_info);
/* the recommend way to update ic config is throuth ISP,
* if not we will send config with interactive mode
@@ -3178,7 +2806,7 @@ upgrade:
return 0;
uninit_fw:
- goodix_fw_update_uninit();
+ goodix_fw_update_uninit(cd);
err_out:
ts_err("stage2 init failed");
cd->init_stage = CORE_INIT_FAIL;
@@ -3220,25 +2848,16 @@ static int goodix_start_later_init(struct goodix_ts_core *ts_core)
*/
static int goodix_ts_probe(struct platform_device *pdev)
{
- struct goodix_ts_core *core_data = NULL;
+ struct goodix_device_resource *dev_res =
+ container_of(pdev, struct goodix_device_resource, pdev);
+ struct goodix_ts_core *core_data;
struct goodix_bus_interface *bus_interface;
int ret;
ts_info("IN");
- bus_interface = pdev->dev.platform_data;
- if (!bus_interface) {
- ts_err("Invalid touch device");
- core_module_prob_sate = CORE_MODULE_PROB_FAILED;
- return -ENODEV;
- }
-
- core_data = devm_kzalloc(
- &pdev->dev, sizeof(struct goodix_ts_core), GFP_KERNEL);
- if (!core_data) {
- core_module_prob_sate = CORE_MODULE_PROB_FAILED;
- return -ENOMEM;
- }
+ core_data = &dev_res->core_data;
+ bus_interface = &dev_res->bus;
if (IS_ENABLED(CONFIG_OF) && bus_interface->dev->of_node) {
/* parse devicetree property */
@@ -3256,11 +2875,10 @@ static int goodix_ts_probe(struct platform_device *pdev)
core_data->hw_ops = goodix_get_hw_ops();
if (!core_data->hw_ops) {
ts_err("hw ops is NULL");
- core_module_prob_sate = CORE_MODULE_PROB_FAILED;
return -EINVAL;
}
mutex_init(&core_data->cmd_lock);
- goodix_core_module_init();
+
/* touch core layer is a platform driver */
core_data->pdev = pdev;
core_data->bus = bus_interface;
@@ -3298,12 +2916,8 @@ static int goodix_ts_probe(struct platform_device *pdev)
goto err_setup_gpio;
}
- /* generic notifier callback */
- core_data->ts_notifier.notifier_call = goodix_generic_noti_callback;
- goodix_ts_register_notifier(&core_data->ts_notifier);
-
/* debug node init */
- ret = goodix_tools_init();
+ ret = goodix_tools_init(core_data);
if (ret) {
ts_err("failed init tools");
goto err_init_tools;
@@ -3313,8 +2927,6 @@ static int goodix_ts_probe(struct platform_device *pdev)
// fb_firefly_register(test_suspend, test_resume);
core_data->init_stage = CORE_INIT_STAGE1;
- goodix_modules.core_data = core_data;
- core_module_prob_sate = CORE_MODULE_PROB_SUCCESS;
/* Try start a thread to get config-bin info */
ret = goodix_start_later_init(core_data);
@@ -3327,16 +2939,14 @@ static int goodix_ts_probe(struct platform_device *pdev)
return 0;
err_start_late_init:
- goodix_tools_exit();
+ goodix_tools_exit(core_data);
err_init_tools:
- goodix_ts_unregister_notifier(&core_data->ts_notifier);
goodix_ts_power_off(core_data);
err_setup_gpio:
goodix_set_pinctrl_state(core_data, PINCTRL_MODE_SUSPEND);
err_out:
mutex_destroy(&core_data->cmd_lock);
core_data->init_stage = CORE_INIT_FAIL;
- core_module_prob_sate = CORE_MODULE_PROB_FAILED;
ts_err("goodix_ts_core failed, ret:%d", ret);
return ret;
}
@@ -3345,38 +2955,45 @@ static int goodix_ts_remove(struct platform_device *pdev)
{
struct goodix_ts_core *core_data = platform_get_drvdata(pdev);
struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops;
+ struct goodix_ts_esd *ts_esd = &core_data->ts_esd;
+
if (core_data->init_stage >= CORE_INIT_STAGE2) {
+/* [GOOG]
+ * Follow the reversed order of probe() to release resources.
+ */
hw_ops->irq_enable(core_data, false);
- inspect_module_exit();
+
+ /* goodix_ts_stage2_init() */
+ inspect_module_exit(core_data);
#if IS_ENABLED(CONFIG_GOODIX_GESTURE)
- gesture_module_exit();
+ gesture_module_exit(core_data);
#endif
- core_module_prob_sate = CORE_MODULE_REMOVED;
- goodix_ts_esd_uninit(core_data);
+ if (atomic_read(&ts_esd->esd_on))
+ goodix_ts_esd_off(core_data);
goodix_ts_procfs_exit(core_data);
-
#if IS_ENABLED(CONFIG_GOOG_TOUCH_INTERFACE)
#if IS_ENABLED(CONFIG_GTI_PM)
goog_pm_unregister_notification(core_data->gti);
#endif
+ goog_touch_interface_remove(core_data->gti);
destroy_workqueue(core_data->event_wq);
touch_apis_deinit(&core_data->pdev->dev);
- goog_touch_interface_remove(core_data->gti);
- goodix_ts_sysfs_exit(core_data);
#endif
+ goodix_ts_sysfs_exit(core_data);
#if IS_ENABLED(CONFIG_FB)
fb_unregister_client(&core_data->fb_notifier);
#endif
goodix_ts_pen_dev_remove(core_data);
goodix_ts_input_dev_remove(core_data);
-
- goodix_fw_update_uninit();
+ /* goodix_later_init_thread() */
+ goodix_fw_update_uninit(core_data);
}
- goodix_tools_exit();
- goodix_ts_unregister_notifier(&core_data->ts_notifier);
+ /* goodix_ts_probe() */
+ goodix_tools_exit(core_data);
goodix_ts_power_off(core_data);
+/*~[GOOG] */
goodix_set_pinctrl_state(core_data, PINCTRL_MODE_SUSPEND);
mutex_destroy(&core_data->cmd_lock);
@@ -3416,15 +3033,23 @@ static int __init goodix_ts_core_init(void)
int ret;
ts_info("Core layer init:%s", GOODIX_DRIVER_VERSION);
+ goodix_device_manager_init();
+
#ifdef CONFIG_TOUCHSCREEN_GOODIX_BRL_SPI
ret = goodix_spi_bus_init();
-#else
- ret = goodix_i2c_bus_init();
+ if (ret) {
+ ts_err("failed add spi bus driver");
+ return ret;
+ }
#endif
+#ifdef CONFIG_TOUCHSCREEN_GOODIX_BRL_I2C
+ ret = goodix_i2c_bus_init();
if (ret) {
- ts_err("failed add bus driver");
+ ts_err("failed add i2c bus driver");
return ret;
}
+#endif
+
return platform_driver_register(&goodix_ts_driver);
}
@@ -3434,9 +3059,11 @@ static void __exit goodix_ts_core_exit(void)
platform_driver_unregister(&goodix_ts_driver);
#ifdef CONFIG_TOUCHSCREEN_GOODIX_BRL_SPI
goodix_spi_bus_exit();
-#else
+#endif
+#ifdef CONFIG_TOUCHSCREEN_GOODIX_BRL_I2C
goodix_i2c_bus_exit();
#endif
+ goodix_device_manager_exit();
}
late_initcall(goodix_ts_core_init);
diff --git a/goodix_ts_core.h b/goodix_ts_core.h
index 33a59ee..bb03a78 100644
--- a/goodix_ts_core.h
+++ b/goodix_ts_core.h
@@ -16,21 +16,22 @@
*/
#ifndef _GOODIX_TS_CORE_H_
#define _GOODIX_TS_CORE_H_
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
-#include <linux/completion.h>
+#include <linux/vmalloc.h>
+#include <linux/kthread.h>
#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
#include <linux/input.h>
#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
+#include <linux/completion.h>
#include <linux/of_irq.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
#include <drm/drm_panel.h>
#if IS_ENABLED(CONFIG_OF)
#include <linux/of_gpio.h>
@@ -56,7 +57,7 @@
#define GOODIX_CORE_DRIVER_NAME "goodix_ts"
#define GOODIX_PEN_DRIVER_NAME "goodix_ts,pen"
-#define GOODIX_DRIVER_VERSION "v1.2.4"
+#define GOODIX_DRIVER_VERSION "v1.2.5"
#define GOODIX_MAX_TOUCH 10
#define GOODIX_PEN_MAX_PRESSURE 4096
#define GOODIX_MAX_PEN_KEY 2
@@ -74,11 +75,18 @@
#define GOODIX_RETRY_5 5
#define GOODIX_RETRY_10 10
+/*
+ * [GOOG]
+ * Don't hardcode for tx/rx num.
+#define GOODIX_MAX_DRV_NUM 32
+#define GOODIX_MAX_SEN_NUM 39
+ */
#define GOODIX_GESTURE_UNKNOWN 0x00
#define GOODIX_GESTURE_DOUBLE_TAP 0xCC
#define GOODIX_GESTURE_SINGLE_TAP 0x4C
#define GOODIX_GESTURE_FOD_DOWN 0x46
#define GOODIX_GESTURE_FOD_UP 0x55
+/*~[GOOG] */
#define TS_DEFAULT_FIRMWARE "goodix_firmware.bin"
#define TS_DEFAULT_CFG_BIN "goodix_cfg_group.bin"
@@ -465,6 +473,45 @@ enum touch_point_status {
TS_RELEASE,
TS_TOUCH,
};
+
+enum update_status {
+ UPSTA_NOTWORK = 0,
+ UPSTA_PREPARING,
+ UPSTA_UPDATING,
+ UPSTA_SUCCESS,
+ UPSTA_FAILED
+};
+
+struct fw_subsys_info {
+ u8 type;
+ u32 size;
+ u32 flash_addr;
+ const u8 *data;
+};
+
+#pragma pack(1)
+struct firmware_summary {
+ u32 size;
+ u32 checksum;
+ u8 hw_pid[6];
+ u8 hw_vid[3];
+ u8 fw_pid[8];
+ u8 fw_vid[4];
+ u8 subsys_num;
+ u8 chip_type;
+ u8 protocol_ver;
+ u8 bus_type;
+ u8 flash_protect;
+ // u8 reserved[8];
+ struct fw_subsys_info subsys[47];
+};
+#pragma pack()
+
+struct firmware_data {
+ struct firmware_summary fw_summary;
+ const struct firmware *firmware;
+};
+
/* coordinate package */
struct goodix_ts_coords {
int status; /* NONE, RELEASE, TOUCH */
@@ -498,6 +545,24 @@ struct goodix_ts_key {
int code;
};
+#define GOODIX_MAX_PEN_FREQ_DATA_LEN 16
+#define GOODIX_HOGP_INFO_LEN 3
+
+#pragma pack(1)
+struct goodix_hid_hogp {
+ u16 pressure;
+ u8 key;
+};
+#pragma pack()
+
+struct goodix_ble_data {
+ u8 freq[GOODIX_MAX_PEN_FREQ_DATA_LEN];
+ u8 hogp[GOODIX_HOGP_INFO_LEN];
+ int hogp_ready;
+ int freq_ready;
+ struct mutex lock;
+};
+
struct goodix_pen_data {
struct goodix_pen_coords coords;
struct goodix_ts_key keys[GOODIX_MAX_PEN_KEY];
@@ -613,7 +678,7 @@ struct goodix_self_sensing_data {
};
struct goodix_rx_package {
- uint8_t header[8];
+ uint8_t header[8]; /* SPI prefix */
uint16_t data[0];
};
@@ -704,7 +769,6 @@ struct goodix_ts_esd {
bool skip_once;
atomic_t esd_on;
struct delayed_work esd_work;
- struct notifier_block esd_notifier;
struct goodix_ts_core *ts_core;
};
@@ -720,36 +784,77 @@ struct goodix_ic_config {
u8 data[GOODIX_CFG_MAX_SIZE];
};
+struct fw_update_ctrl {
+ struct mutex mutex;
+ int initialized;
+ char fw_name[GOODIX_MAX_STR_LABEL_LEN];
+ int mode;
+ enum update_status status;
+ int spend_time;
+
+ struct firmware_data fw_data;
+ struct goodix_ic_config *ic_config;
+ struct goodix_ic_config one_binary_cfg;
+ struct goodix_ts_core *core_data;
+ struct update_info_t *update_info;
+ struct kobject *kobj;
+ struct attribute_group attrs; /* [GOOG] */
+};
+
+struct goodix_tools_dev {
+ bool is_open;
+ struct miscdevice miscdev;
+ char name[32];
+};
+
struct goodix_ts_core {
int init_stage;
+ struct goodix_tools_dev tools_dev;
+ struct fw_update_ctrl update_ctrl;
+ struct kobject *gesture_kobj;
+ struct proc_dir_entry *proc_dir_entry;
struct platform_device *pdev;
struct goodix_fw_version fw_version;
struct goodix_ic_info ic_info;
struct goodix_bus_interface *bus;
struct goodix_ts_board_data board_data;
- struct touch_apis_data apis_data;
struct goodix_ts_hw_ops *hw_ops;
struct input_dev *input_dev;
struct input_dev *pen_dev;
struct mutex cmd_lock;
/* TODO counld we remove this from core data? */
struct goodix_ts_event ts_event;
- struct workqueue_struct *event_wq;
- struct delayed_work monitor_gesture_work;
- ktime_t gesture_down_timeout;
- ktime_t gesture_up_timeout;
+ struct goodix_ble_data ble_data;
+ u32 pen_pressure;
+
+ char input_name[32];
+ char input_pen_name[32];
/* every pointer of this array represent a kind of config */
struct goodix_ic_config *ic_configs[GOODIX_MAX_CONFIG_GROUP];
struct regulator *avdd;
struct regulator *iovdd;
- unsigned char gesture_type;
+ uint32_t gesture_type;
+
+ /*
+ * [GOOG]
+ * Use goodix_update_heatmap() to do the heatmap process.
+ u8 heatmap_buffer;
+ s16 heatmap_diff[GOODIX_MAX_DRV_NUM * GOODIX_MAX_SEN_NUM];
+ s16 heatmap_selfdiff[GOODIX_MAX_DRV_NUM + GOODIX_MAX_SEN_NUM];
+ */
+ struct touch_apis_data apis_data;
+ struct workqueue_struct *event_wq;
+ struct delayed_work monitor_gesture_work;
+ ktime_t gesture_down_timeout;
+ ktime_t gesture_up_timeout;
struct goodix_rx_package *touch_frame_package;
size_t touch_frame_size;
uint16_t *mutual_data;
uint16_t *self_sensing_data;
uint16_t *mutual_data_manual;
uint16_t *self_sensing_data_manual;
+ /*~[GOOG] */
int power_on;
int irq;
@@ -757,16 +862,17 @@ struct goodix_ts_core {
atomic_t irq_enabled;
atomic_t suspended;
- bool screen_protector_mode_enabled;
+ bool screen_protector_mode_enabled; /* [GOOG] */
/* when this flag is true, driver should not clean the sync flag */
bool tools_ctrl_sync;
- struct notifier_block ts_notifier;
struct goodix_ts_esd ts_esd;
#if IS_ENABLED(CONFIG_FB)
struct notifier_block fb_notifier;
#endif
+
+ /* [GOOG] */
#if IS_ENABLED(CONFIG_TOUCHSCREEN_MOTION_FILTER)
struct touch_mf tmf;
#endif
@@ -779,93 +885,28 @@ struct goodix_ts_core {
*/
ktime_t isr_timestamp;
ktime_t coords_timestamp;
+ /*~[GOOG] */
};
-/* external module structures */
-enum goodix_ext_priority {
- EXTMOD_PRIO_RESERVED = 0,
- EXTMOD_PRIO_FWUPDATE,
- EXTMOD_PRIO_GESTURE,
- EXTMOD_PRIO_HOTKNOT,
- EXTMOD_PRIO_DBGTOOL,
- EXTMOD_PRIO_DEFAULT,
-};
-
-#define EVT_HANDLED 0
-#define EVT_CONTINUE 0
-#define EVT_CANCEL 1
-#define EVT_CANCEL_IRQEVT 1
-#define EVT_CANCEL_SUSPEND 1
-#define EVT_CANCEL_RESUME 1
-#define EVT_CANCEL_RESET 1
-
-struct goodix_ext_module;
-/* external module's operations callback */
-struct goodix_ext_module_funcs {
- int (*init)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
- int (*exit)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
- int (*before_reset)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
- int (*after_reset)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
- int (*before_suspend)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
- int (*after_suspend)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
- int (*before_resume)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
- int (*after_resume)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
- int (*irq_event)(struct goodix_ts_core *core_data,
- struct goodix_ext_module *module);
-};
-
-/*
- * struct goodix_ext_module - external module struct
- * @list: list used to link into modules manager
- * @name: name of external module
- * @priority: module priority value, zero is invalid
- * @funcs: operations callback
- * @priv_data: private data region
- * @kobj: kobject
- * @work: used to queue one work to do registration
- */
-struct goodix_ext_module {
+struct goodix_device_manager {
struct list_head list;
- char *name;
- enum goodix_ext_priority priority;
- const struct goodix_ext_module_funcs *funcs;
- void *priv_data;
- struct kobject kobj;
- struct work_struct work;
+ bool initialized;
+ struct mutex mutex;
+ int nums;
};
-/*
- * struct goodix_ext_attribute - exteranl attribute struct
- * @attr: attribute
- * @show: show interface of external attribute
- * @store: store interface of external attribute
- */
-struct goodix_ext_attribute {
- struct attribute attr;
- ssize_t (*show)(struct goodix_ext_module *module, char *buf);
- ssize_t (*store)(
- struct goodix_ext_module *module, const char *buf, size_t len);
+struct goodix_device_resource {
+ struct list_head list;
+ int id;
+ char name[64];
+ struct goodix_bus_interface bus;
+ struct platform_device pdev;
+ struct goodix_ts_core core_data;
};
-/* external attrs helper macro */
-#define __EXTMOD_ATTR(_name, _mode, _show, _store) \
- { \
- .attr = { .name = __stringify(_name), .mode = _mode }, \
- .show = _show, .store = _store, \
- }
+extern struct goodix_device_manager goodix_devices;
+extern int goodix_device_register(struct goodix_device_resource *device);
-/* external attrs helper macro, used to define external attrs */
-#define DEFINE_EXTMOD_ATTR(_name, _mode, _show, _store) \
- static struct goodix_ext_attribute ext_attr_##_name = \
- __EXTMOD_ATTR(_name, _mode, _show, _store)
/* log macro */
extern bool debug_log_flag;
@@ -891,31 +932,6 @@ static inline struct goodix_ts_board_data *board_data(
return &(core->board_data);
}
-/**
- * goodix_register_ext_module - interface for external module
- * to register into touch core modules structure
- *
- * @module: pointer to external module to be register
- * return: 0 ok, <0 failed
- */
-int goodix_register_ext_module(struct goodix_ext_module *module);
-/* register module no wait */
-int goodix_register_ext_module_no_wait(struct goodix_ext_module *module);
-/**
- * goodix_unregister_ext_module - interface for external module
- * to unregister external modules
- *
- * @module: pointer to external module
- * return: 0 ok, <0 failed
- */
-int goodix_unregister_ext_module(struct goodix_ext_module *module);
-/* remove all registered ext module
- * return 0 on success, otherwise return < 0
- */
-int goodix_ts_blocking_notify(enum ts_notify_event evt, void *v);
-struct kobj_type *goodix_get_default_ktype(void);
-struct kobject *goodix_get_default_kobj(void);
-
struct goodix_ts_hw_ops *goodix_get_hw_ops(void);
int goodix_get_config_proc(struct goodix_ts_core *cd);
@@ -931,22 +947,26 @@ u32 goodix_get_file_config_id(u8 *ic_config);
void goodix_rotate_abcd2cbad(int tx, int rx, s16 *src, s16 *dest);
int goodix_fw_update_init(struct goodix_ts_core *core_data);
-void goodix_fw_update_uninit(void);
-int goodix_do_fw_update(struct goodix_ic_config *ic_config, int mode);
+void goodix_fw_update_uninit(struct goodix_ts_core *core_data);
+int goodix_do_fw_update(struct goodix_ts_core *core_data, int mode);
int goodix_get_ic_type(
struct device_node *node, struct goodix_bus_interface *bus_inf);
-int gesture_module_init(void);
-void gesture_module_exit(void);
-int inspect_module_init(void);
-void inspect_module_exit(void);
-int goodix_tools_init(void);
-void goodix_tools_exit(void);
-
-int driver_test_selftest(char* buf);
+int gesture_module_init(struct goodix_ts_core *core_data);
+void gesture_module_exit(struct goodix_ts_core *core_data);
+int inspect_module_init(struct goodix_ts_core *core_data);
+void inspect_module_exit(struct goodix_ts_core *core_data);
+int goodix_tools_init(struct goodix_ts_core *core_data);
+void goodix_tools_exit(struct goodix_ts_core *core_data);
+void goodix_ts_esd_on(struct goodix_ts_core *cd);
+void goodix_ts_esd_off(struct goodix_ts_core *cd);
+void print_ic_info(struct goodix_ic_info *ic_info);
+
+int driver_test_selftest(struct goodix_ts_core *cd, char *buf);
int driver_test_proc_init(struct goodix_ts_core *core_data);
-void driver_test_proc_remove(void);
+void driver_test_proc_remove(struct goodix_ts_core *core_data);
int goodix_do_inspect(struct goodix_ts_core *cd, struct ts_rawdata_info *info);
+int goodix_ts_report_gesture(struct goodix_ts_core *cd, struct goodix_ts_event *event);
void goodix_ts_report_status(struct goodix_ts_core *core_data,
struct goodix_ts_event *ts_event);
int goodix_update_pen_freq(struct goodix_ts_core *cd, u8 *data, int len);
diff --git a/goodix_ts_gesture.c b/goodix_ts_gesture.c
index d4246b0..51335da 100644
--- a/goodix_ts_gesture.c
+++ b/goodix_ts_gesture.c
@@ -27,236 +27,136 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/version.h>
-
/*
- * struct gesture_module - gesture module data
- * @registered: module register state
- * @sysfs_node_created: sysfs node state
- * @gesture_type: valid gesture type, each bit represent one gesture type
- * @gesture_data: store latest gesture code get from irq event
- * @gesture_ts_cmd: gesture command data
+ * [GOOG]
+ * Move GOODIX_GESTURE_* define to goodix_ts_core.h.
*/
-struct gesture_module {
- atomic_t registered;
- struct goodix_ts_core *ts_core;
- struct goodix_ext_module module;
-};
-
-static struct gesture_module *gsx_gesture; /*allocated in gesture init module*/
-static bool module_initialized;
-static ssize_t gsx_double_type_show(struct goodix_ext_module *module, char *buf)
+static ssize_t gsx_double_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct gesture_module *gsx = module->priv_data;
- unsigned char type = gsx->ts_core->gesture_type;
-
- if (!gsx)
- return -EIO;
-
- if (atomic_read(&gsx->registered) == 0) {
- ts_err("gesture module is not registered");
- return 0;
- }
+ struct device *device =
+ container_of(((struct kobject *)dev)->parent, struct device, kobj);
+ struct goodix_ts_core *cd = dev_get_drvdata(device);
+ uint32_t type = cd->gesture_type;
return sprintf(buf, "%s\n",
(type & GESTURE_DOUBLE_TAP) ? "enable" : "disable");
}
-static ssize_t gsx_double_type_store(
- struct goodix_ext_module *module, const char *buf, size_t count)
+static ssize_t gsx_double_type_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct gesture_module *gsx = module->priv_data;
-
- if (!gsx)
- return -EIO;
-
- if (atomic_read(&gsx->registered) == 0) {
- ts_err("gesture module is not registered");
- return 0;
- }
+ struct device *device =
+ container_of(((struct kobject *)dev)->parent, struct device, kobj);
+ struct goodix_ts_core *cd = dev_get_drvdata(device);
if (buf[0] == '1') {
ts_info("enable double tap");
- gsx->ts_core->gesture_type |= GESTURE_DOUBLE_TAP;
+ cd->gesture_type |= GESTURE_DOUBLE_TAP;
} else if (buf[0] == '0') {
ts_info("disable double tap");
- gsx->ts_core->gesture_type &= ~GESTURE_DOUBLE_TAP;
+ cd->gesture_type &= ~GESTURE_DOUBLE_TAP;
} else
ts_err("invalid cmd[%d]", buf[0]);
return count;
}
-static ssize_t gsx_single_type_show(struct goodix_ext_module *module, char *buf)
+static ssize_t gsx_single_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct gesture_module *gsx = module->priv_data;
- unsigned char type = gsx->ts_core->gesture_type;
-
- if (!gsx)
- return -EIO;
-
- if (atomic_read(&gsx->registered) == 0) {
- ts_err("gesture module is not registered");
- return 0;
- }
+ struct device *device =
+ container_of(((struct kobject *)dev)->parent, struct device, kobj);
+ struct goodix_ts_core *cd = dev_get_drvdata(device);
+ uint32_t type = cd->gesture_type;
return sprintf(buf, "%s\n",
(type & GESTURE_SINGLE_TAP) ? "enable" : "disable");
}
-static ssize_t gsx_single_type_store(
- struct goodix_ext_module *module, const char *buf, size_t count)
+static ssize_t gsx_single_type_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct gesture_module *gsx = module->priv_data;
-
- if (!gsx)
- return -EIO;
-
- if (atomic_read(&gsx->registered) == 0) {
- ts_err("gesture module is not registered");
- return 0;
- }
+ struct device *device =
+ container_of(((struct kobject *)dev)->parent, struct device, kobj);
+ struct goodix_ts_core *cd = dev_get_drvdata(device);
if (buf[0] == '1') {
ts_info("enable single tap");
- gsx->ts_core->gesture_type |= GESTURE_SINGLE_TAP;
+ cd->gesture_type |= GESTURE_SINGLE_TAP;
} else if (buf[0] == '0') {
ts_info("disable single tap");
- gsx->ts_core->gesture_type &= ~GESTURE_SINGLE_TAP;
+ cd->gesture_type &= ~GESTURE_SINGLE_TAP;
} else
ts_err("invalid cmd[%d]", buf[0]);
return count;
}
-static ssize_t gsx_fod_type_show(struct goodix_ext_module *module, char *buf)
+static ssize_t gsx_fod_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct gesture_module *gsx = module->priv_data;
- unsigned char type = gsx->ts_core->gesture_type;
-
- if (!gsx)
- return -EIO;
-
- if (atomic_read(&gsx->registered) == 0) {
- ts_err("gesture module is not registered");
- return 0;
- }
+ struct device *device =
+ container_of(((struct kobject *)dev)->parent, struct device, kobj);
+ struct goodix_ts_core *cd = dev_get_drvdata(device);
+ uint32_t type = cd->gesture_type;
return sprintf(
buf, "%s\n", (type & GESTURE_FOD_PRESS) ? "enable" : "disable");
}
-static ssize_t gsx_fod_type_store(
- struct goodix_ext_module *module, const char *buf, size_t count)
+static ssize_t gsx_fod_type_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct gesture_module *gsx = module->priv_data;
-
- if (!gsx)
- return -EIO;
-
- if (atomic_read(&gsx->registered) == 0) {
- ts_err("gesture module is not registered");
- return 0;
- }
+ struct device *device =
+ container_of(((struct kobject *)dev)->parent, struct device, kobj);
+ struct goodix_ts_core *cd = dev_get_drvdata(device);
if (buf[0] == '1') {
ts_info("enable fod");
- gsx->ts_core->gesture_type |= GESTURE_FOD_PRESS;
+ cd->gesture_type |= GESTURE_FOD_PRESS;
} else if (buf[0] == '0') {
ts_info("disable fod");
- gsx->ts_core->gesture_type &= ~GESTURE_FOD_PRESS;
+ cd->gesture_type &= ~GESTURE_FOD_PRESS;
} else
ts_err("invalid cmd[%d]", buf[0]);
return count;
}
-const struct goodix_ext_attribute gesture_attrs[] = {
- __EXTMOD_ATTR(
- double_en, 0664, gsx_double_type_show, gsx_double_type_store),
- __EXTMOD_ATTR(
- single_en, 0664, gsx_single_type_show, gsx_single_type_store),
- __EXTMOD_ATTR(fod_en, 0664, gsx_fod_type_show, gsx_fod_type_store),
-};
-
-static int gsx_gesture_init(
- struct goodix_ts_core *cd, struct goodix_ext_module *module)
-{
- struct gesture_module *gsx = module->priv_data;
-
- if (!cd || !cd->hw_ops->gesture) {
- ts_err("gesture unsupported");
- return -EINVAL;
- }
-
- gsx->ts_core = cd;
- gsx->ts_core->gesture_type = 0;
- atomic_set(&gsx->registered, 1);
-
- return 0;
-}
-
-static int gsx_gesture_exit(
- struct goodix_ts_core *cd, struct goodix_ext_module *module)
-{
- struct gesture_module *gsx = module->priv_data;
+static DEVICE_ATTR(double_type, 0664, gsx_double_type_show, gsx_double_type_store);
+static DEVICE_ATTR(single_type, 0664, gsx_single_type_show, gsx_single_type_store);
+static DEVICE_ATTR(fod_type, 0664, gsx_fod_type_show, gsx_fod_type_store);
- if (!cd || !cd->hw_ops->gesture) {
- ts_err("gesture unsupported");
- return -EINVAL;
- }
-
- atomic_set(&gsx->registered, 0);
+static struct attribute *gesture_attrs[] = {
+ &dev_attr_double_type.attr,
+ &dev_attr_single_type.attr,
+ &dev_attr_fod_type.attr,
+ NULL,
+};
- return 0;
-}
+const static struct attribute_group gesture_sysfs_group = {
+ .attrs = gesture_attrs,
+};
-/**
- * gsx_gesture_ist - Gesture Irq handle
- * This functions is excuted when interrupt happened and
- * ic in doze mode.
- *
- * @cd: pointer to touch core data
- * @module: pointer to goodix_ext_module struct
- * return: 0 goon execute, EVT_CANCEL_IRQEVT stop execute
- */
-static int gsx_gesture_ist(
- struct goodix_ts_core *cd, struct goodix_ext_module *module)
+int goodix_ts_report_gesture(struct goodix_ts_core *cd, struct goodix_ts_event *event)
{
- struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
- struct goodix_ts_event gs_event = { 0 };
int coor_x, coor_y, coor_size, coor_press;
int major, minor, orientation;
- int ret;
-
- if (atomic_read(&cd->suspended) == 0 || cd->gesture_type == 0)
- return EVT_CONTINUE;
-
- ret = hw_ops->event_handler(cd, &gs_event);
- if (ret) {
- ts_err("failed get gesture data");
- cd->hw_ops->gesture(cd, 0);
- goto re_send_ges_cmd;
- }
-
- if (!(gs_event.event_type & EVENT_GESTURE)) {
- ts_err("invalid event type: 0x%x", cd->ts_event.event_type);
- cd->hw_ops->gesture(cd, 0);
- goto re_send_ges_cmd;
- }
-
- if (gs_event.event_type & EVENT_STATUS)
- goodix_ts_report_status(cd, &gs_event);
- coor_x = le16_to_cpup((__le16 *)gs_event.gesture_data.data);
- coor_y = le16_to_cpup((__le16 *)(gs_event.gesture_data.data + 2));
- coor_size = le16_to_cpup((__le16 *)(gs_event.gesture_data.data + 4));
- coor_press = gs_event.gesture_data.data[6];
- major = le16_to_cpup((__le16 *)(gs_event.gesture_data.data + 7));
- minor = le16_to_cpup((__le16 *)(gs_event.gesture_data.data + 9));
- orientation = (s8)gs_event.gesture_data.data[11];
+ coor_x = le16_to_cpup((__le16 *)event->gesture_data.data);
+ coor_y = le16_to_cpup((__le16 *)(event->gesture_data.data + 2));
+ coor_size = le16_to_cpup((__le16 *)(event->gesture_data.data + 4));
+ coor_press = event->gesture_data.data[6];
+ major = le16_to_cpup((__le16 *)(event->gesture_data.data + 7));
+ minor = le16_to_cpup((__le16 *)(event->gesture_data.data + 9));
+ orientation = (s8)event->gesture_data.data[11];
- switch (gs_event.gesture_data.gesture_type) {
+ switch (event->gesture_data.gesture_type) {
case GOODIX_GESTURE_SINGLE_TAP:
if (cd->gesture_type & GESTURE_SINGLE_TAP) {
ts_info("get SINGLE-TAP gesture");
@@ -340,132 +240,45 @@ static int gsx_gesture_ist(
}
break;
default:
- ts_err("not support gesture type[%02X]", gs_event.gesture_data.gesture_type);
+ ts_err("not support gesture type[%02X]", event->gesture_data.gesture_type);
break;
}
-re_send_ges_cmd:
- return EVT_CANCEL_IRQEVT;
-}
-
-/**
- * gsx_gesture_before_suspend - execute gesture suspend routine
- * This functions is excuted to set ic into doze mode
- *
- * @cd: pointer to touch core data
- * @module: pointer to goodix_ext_module struct
- * return: 0 goon execute, EVT_IRQCANCLED stop execute
- */
-static int gsx_gesture_before_suspend(
- struct goodix_ts_core *cd, struct goodix_ext_module *module)
-{
- int ret;
- const struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
-
- if (cd->gesture_type == 0)
- return EVT_CONTINUE;
-
- ret = hw_ops->gesture(cd, 0);
- if (ret)
- ts_err("failed enter gesture mode");
- else
- ts_info("enter gesture mode, type[0x%02X]", cd->gesture_type);
-
- hw_ops->irq_enable(cd, true);
- enable_irq_wake(cd->irq);
-
- return EVT_CANCEL_SUSPEND;
-}
-
-static int gsx_gesture_before_resume(
- struct goodix_ts_core *cd, struct goodix_ext_module *module)
-{
- const struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
-
- if (cd->gesture_type == 0)
- return EVT_CONTINUE;
-
- disable_irq_wake(cd->irq);
- hw_ops->reset(cd, GOODIX_NORMAL_RESET_DELAY_MS);
-
- return EVT_CANCEL_RESUME;
+ return 0;
}
-static struct goodix_ext_module_funcs gsx_gesture_funcs = {
- .irq_event = gsx_gesture_ist,
- .init = gsx_gesture_init,
- .exit = gsx_gesture_exit,
- .before_suspend = gsx_gesture_before_suspend,
- .before_resume = gsx_gesture_before_resume,
-};
-
-int gesture_module_init(void)
+int gesture_module_init(struct goodix_ts_core *core_data)
{
- int ret;
- int i;
- struct kobject *def_kobj = goodix_get_default_kobj();
- struct kobj_type *def_kobj_type = goodix_get_default_ktype();
-
- gsx_gesture = kzalloc(sizeof(struct gesture_module), GFP_KERNEL);
- if (!gsx_gesture)
- return -ENOMEM;
-
- gsx_gesture->module.funcs = &gsx_gesture_funcs;
- gsx_gesture->module.priority = EXTMOD_PRIO_GESTURE;
- gsx_gesture->module.name = "Goodix_gsx_gesture";
- gsx_gesture->module.priv_data = gsx_gesture;
-
- atomic_set(&gsx_gesture->registered, 0);
+ int ret = 0;
+ struct kobject *parent = &core_data->pdev->dev.kobj;
/* gesture sysfs init */
- ret = kobject_init_and_add(
- &gsx_gesture->module.kobj, def_kobj_type, def_kobj, "gesture");
- if (ret) {
+ core_data->gesture_kobj = kobject_create_and_add("gesture", parent);
+ if (!core_data->gesture_kobj) {
ts_err("failed create gesture sysfs node!");
+ ret = -ENOENT; /* [GOOG] */
goto err_out;
}
- for (i = 0; i < ARRAY_SIZE(gesture_attrs) && !ret; i++)
- ret = sysfs_create_file(
- &gsx_gesture->module.kobj, &gesture_attrs[i].attr);
+ ret = sysfs_create_group(core_data->gesture_kobj, &gesture_sysfs_group);
if (ret) {
- ts_err("failed create gst sysfs files");
- while (--i >= 0)
- sysfs_remove_file(&gsx_gesture->module.kobj,
- &gesture_attrs[i].attr);
-
- kobject_put(&gsx_gesture->module.kobj);
+ ts_err("failed create gesture sysfs files");
+ kobject_put(core_data->gesture_kobj);
goto err_out;
}
- module_initialized = true;
- goodix_register_ext_module_no_wait(&gsx_gesture->module);
ts_info("gesture module init success");
-
return 0;
err_out:
ts_err("gesture module init failed!");
- kfree(gsx_gesture);
return ret;
}
-void gesture_module_exit(void)
+void gesture_module_exit(struct goodix_ts_core *core_data)
{
- int i;
-
ts_info("gesture module exit");
- if (!module_initialized)
- return;
-
- goodix_unregister_ext_module(&gsx_gesture->module);
-
- /* deinit sysfs */
- for (i = 0; i < ARRAY_SIZE(gesture_attrs); i++)
- sysfs_remove_file(
- &gsx_gesture->module.kobj, &gesture_attrs[i].attr);
- kobject_put(&gsx_gesture->module.kobj);
- kfree(gsx_gesture);
- module_initialized = false;
+ sysfs_remove_group(core_data->gesture_kobj, &gesture_sysfs_group);
+ kobject_put(core_data->gesture_kobj);
}
diff --git a/goodix_ts_inspect.c b/goodix_ts_inspect.c
index 119c8bc..bebc557 100644
--- a/goodix_ts_inspect.c
+++ b/goodix_ts_inspect.c
@@ -122,8 +122,6 @@
#define ABS(val) ((val < 0) ? -(val) : val)
#define MAX(a, b) ((a > b) ? a : b)
-static bool module_initialized;
-
/* short threshold, drv-drv, drv-sen, sen-sen, drv-gnd, sen-gnd, avdd */
static u8 short_circuit_threshold[] = { 10, 200, 200, 200, 200, 200, 30 };
@@ -517,7 +515,7 @@ static int goodix_tptest_prepare(struct goodix_ts_test *ts_test)
/* disable irq */
ts_test_irq_enable(ts_test, false);
/* close esd */
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(ts_test->ts);
return 0;
}
@@ -529,7 +527,7 @@ static void goodix_tptest_finish(struct goodix_ts_test *ts_test)
ts_test_reset(ts_test, 100);
/* open esd */
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(ts_test->ts);
/* enable irq */
ts_test_irq_enable(ts_test, true);
}
@@ -1353,10 +1351,10 @@ static ssize_t get_rawdata_show(
static DEVICE_ATTR(get_rawdata, 0444, get_rawdata_show, NULL);
-int inspect_module_init(void)
+int inspect_module_init(struct goodix_ts_core *core_data)
{
int ret;
- struct kobject *def_kobj = goodix_get_default_kobj();
+ struct kobject *def_kobj = &core_data->pdev->dev.kobj;
/* create sysfs */
ret = sysfs_create_file(def_kobj, &dev_attr_get_rawdata.attr);
@@ -1364,8 +1362,6 @@ int inspect_module_init(void)
ts_err("create sysfs of get_rawdata failed");
goto err_out;
}
-
- module_initialized = true;
ts_info("inspect module init success");
return 0;
@@ -1374,14 +1370,10 @@ err_out:
return ret;
}
-void inspect_module_exit(void)
+void inspect_module_exit(struct goodix_ts_core *core_data)
{
- struct kobject *def_kobj = goodix_get_default_kobj();
+ struct kobject *def_kobj = &core_data->pdev->dev.kobj;
ts_info("inspect module exit");
- if (!module_initialized)
- return;
-
sysfs_remove_file(def_kobj, &dev_attr_get_rawdata.attr);
- module_initialized = false;
}
diff --git a/goodix_ts_proc.c b/goodix_ts_proc.c
index a8ed02f..d2f0082 100644
--- a/goodix_ts_proc.c
+++ b/goodix_ts_proc.c
@@ -52,7 +52,7 @@
#define CMD_SET_FREQ_INDEX "set_freq_index"
#define CMD_DISABLE_FILTER "disable_filter"
-char *cmd_list[] = { CMD_FW_UPDATE, CMD_AUTO_TEST, CMD_OPEN_TEST,
+const static char *cmd_list[] = { CMD_FW_UPDATE, CMD_AUTO_TEST, CMD_OPEN_TEST,
CMD_SELF_OPEN_TEST, CMD_NOISE_TEST, CMD_AUTO_NOISE_TEST, CMD_SHORT_TEST,
CMD_GET_PACKAGE_ID, CMD_GET_MCU_ID, CMD_GET_VERSION, CMD_GET_RAWDATA,
CMD_GET_DIFFDATA, CMD_GET_BASEDATA, CMD_GET_SELF_RAWDATA,
@@ -90,7 +90,6 @@ char *cmd_list[] = { CMD_FW_UPDATE, CMD_AUTO_TEST, CMD_OPEN_TEST,
#define LARGE_SIZE 5 * 1024
#define MAX_FRAME_CNT 50
#define HUGE_SIZE MAX_FRAME_CNT * 20 * 1024
-static struct goodix_ts_core *cd;
static char wbuf[SHORT_SIZE];
static char *rbuf;
static uint32_t index;
@@ -411,7 +410,7 @@ struct goodix_ts_test {
};
static struct goodix_ts_test *ts_test;
-static int cal_cha_to_cha_res(int v1, int v2)
+static int cal_cha_to_cha_res(struct goodix_ts_core *cd, int v1, int v2)
{
if (cd->bus->ic_type == IC_TYPE_BERLIN_A)
return (v1 - v2) * 63 / v2;
@@ -423,7 +422,7 @@ static int cal_cha_to_cha_res(int v1, int v2)
return (v1 / v2 - 1) * 55 + 45;
}
-static int cal_cha_to_avdd_res(int v1, int v2)
+static int cal_cha_to_avdd_res(struct goodix_ts_core *cd, int v1, int v2)
{
if (cd->bus->ic_type == IC_TYPE_BERLIN_A)
return 64 * (2 * v2 - 25) * 40 / v1 - 40;
@@ -435,7 +434,7 @@ static int cal_cha_to_avdd_res(int v1, int v2)
return 64 * (2 * v2 - 25) * 76 / v1 - 15;
}
-static int cal_cha_to_gnd_res(int v)
+static int cal_cha_to_gnd_res(struct goodix_ts_core *cd, int v)
{
if (cd->bus->ic_type == IC_TYPE_BERLIN_A)
return 64148 / v - 40;
@@ -558,7 +557,7 @@ static void goodix_save_short_res(u16 chn1, u16 chn2, int r)
}
}
-static int gdix_check_tx_tx_shortcircut(u8 short_ch_num)
+static int gdix_check_tx_tx_shortcircut(struct goodix_ts_core *cd, u8 short_ch_num)
{
int ret = 0, err = 0;
u32 r_threshold = 0, short_r = 0;
@@ -615,11 +614,9 @@ static int gdix_check_tx_tx_shortcircut(u8 short_ch_num)
if (adc_signal < ts_test->short_threshold)
continue;
- short_r = (u32)cal_cha_to_cha_res(
- self_capdata, adc_signal);
+ short_r = (u32)cal_cha_to_cha_res(cd, self_capdata, adc_signal);
if (short_r < r_threshold) {
- master_pin_num = map_die2pin(
- short_die_num + max_sen_num);
+ master_pin_num = map_die2pin(short_die_num + max_sen_num);
slave_pin_num = map_die2pin(j + max_sen_num);
if (master_pin_num == 0xFF ||
slave_pin_num == 0xFF) {
@@ -649,7 +646,7 @@ static int gdix_check_tx_tx_shortcircut(u8 short_ch_num)
return err;
}
-static int gdix_check_rx_rx_shortcircut(u8 short_ch_num)
+static int gdix_check_rx_rx_shortcircut(struct goodix_ts_core *cd, u8 short_ch_num)
{
int ret = 0, err = 0;
u32 r_threshold = 0, short_r = 0;
@@ -703,8 +700,7 @@ static int gdix_check_rx_rx_shortcircut(u8 short_ch_num)
if (adc_signal < ts_test->short_threshold)
continue;
- short_r = (u32)cal_cha_to_cha_res(
- self_capdata, adc_signal);
+ short_r = (u32)cal_cha_to_cha_res(cd, self_capdata, adc_signal);
if (short_r < r_threshold) {
master_pin_num = map_die2pin(short_die_num);
slave_pin_num = map_die2pin(j);
@@ -736,7 +732,7 @@ static int gdix_check_rx_rx_shortcircut(u8 short_ch_num)
return err;
}
-static int gdix_check_tx_rx_shortcircut(u8 short_ch_num)
+static int gdix_check_tx_rx_shortcircut(struct goodix_ts_core *cd, u8 short_ch_num)
{
int ret = 0, err = 0;
u32 r_threshold = 0, short_r = 0;
@@ -791,8 +787,7 @@ static int gdix_check_tx_rx_shortcircut(u8 short_ch_num)
if (adc_signal < ts_test->short_threshold)
continue;
- short_r = (u32)cal_cha_to_cha_res(
- self_capdata, adc_signal);
+ short_r = (u32)cal_cha_to_cha_res(cd, self_capdata, adc_signal);
if (short_r < r_threshold) {
master_pin_num = map_die2pin(short_die_num);
slave_pin_num = map_die2pin(j + max_sen_num);
@@ -824,7 +819,7 @@ static int gdix_check_tx_rx_shortcircut(u8 short_ch_num)
return err;
}
-static int gdix_check_resistance_to_gnd(u16 adc_signal, u32 pos)
+static int gdix_check_resistance_to_gnd(struct goodix_ts_core *cd, u16 adc_signal, u32 pos)
{
long r = 0;
u16 r_th = 0, avdd_value = 0;
@@ -842,10 +837,10 @@ static int gdix_check_resistance_to_gnd(u16 adc_signal, u32 pos)
if (short_type == 0) {
/* short to GND */
- r = cal_cha_to_gnd_res(adc_signal);
+ r = cal_cha_to_gnd_res(cd, adc_signal);
} else {
/* short to VDD */
- r = cal_cha_to_avdd_res(adc_signal, avdd_value);
+ r = cal_cha_to_avdd_res(cd, adc_signal, avdd_value);
}
if (pos < max_drv_num)
@@ -874,7 +869,7 @@ static int gdix_check_resistance_to_gnd(u16 adc_signal, u32 pos)
return 0;
}
-static int gdix_check_gndvdd_shortcircut(void)
+static int gdix_check_gndvdd_shortcircut(struct goodix_ts_core *cd)
{
int ret = 0, err = 0;
int size = 0, i = 0;
@@ -907,7 +902,7 @@ static int gdix_check_gndvdd_shortcircut(void)
for (i = 0; i < max_drv_num + max_sen_num; i++) {
adc_signal = le16_to_cpup((__le16 *)&data_buf[i * 2]);
- ret = gdix_check_resistance_to_gnd(adc_signal, i);
+ ret = gdix_check_resistance_to_gnd(cd, adc_signal, i);
if (ret != 0) {
ts_err("Resistance to-gnd/vdd short");
err = ret;
@@ -922,7 +917,7 @@ err_out:
#define NOTT_CHECKSUM_LEN 54
#define BRLD_CHECKSUM_LEN 62
#define BRLB_CHECKSUM_LEN 129
-static int goodix_shortcircut_analysis(void)
+static int goodix_shortcircut_analysis(struct goodix_ts_core *cd)
{
int ret;
int err = 0;
@@ -963,13 +958,13 @@ static int goodix_shortcircut_analysis(void)
test_result.drv_gnd_avdd_num, test_result.sen_gnd_avdd_num);
if (test_result.drv_drv_num)
- err |= gdix_check_tx_tx_shortcircut(test_result.drv_drv_num);
+ err |= gdix_check_tx_tx_shortcircut(cd, test_result.drv_drv_num);
if (test_result.sen_sen_num)
- err |= gdix_check_rx_rx_shortcircut(test_result.sen_sen_num);
+ err |= gdix_check_rx_rx_shortcircut(cd, test_result.sen_sen_num);
if (test_result.drv_sen_num)
- err |= gdix_check_tx_rx_shortcircut(test_result.drv_sen_num);
+ err |= gdix_check_tx_rx_shortcircut(cd, test_result.drv_sen_num);
if (test_result.drv_gnd_avdd_num || test_result.sen_gnd_avdd_num)
- err |= gdix_check_gndvdd_shortcircut();
+ err |= gdix_check_gndvdd_shortcircut(cd);
ts_info(">>>>> short check return 0x%x", err);
@@ -979,7 +974,7 @@ static int goodix_shortcircut_analysis(void)
#define INSPECT_FW_SWITCH_CMD 0x85
#define SHORT_TEST_RUN_FLAG 0xAA
#define SHORT_TEST_RUN_REG 0x10400
-static int goodix_short_test_prepare(void)
+static int goodix_short_test_prepare(struct goodix_ts_core *cd)
{
struct goodix_ts_cmd tmp_cmd;
int ret;
@@ -1018,7 +1013,7 @@ resend_cmd:
#define MAX_TEST_TIME_MS 15000
#define DEFAULT_TEST_TIME_MS 7000
#define SHORT_TEST_FINISH_FLAG 0x88
-static int goodix_shortcircut_test(void)
+static int goodix_shortcircut_test(struct goodix_ts_core *cd)
{
int ret = 0;
int res;
@@ -1027,7 +1022,7 @@ static int goodix_shortcircut_test(void)
u8 status;
ts_info("---------------------- short_test begin ----------------------");
- ret = goodix_short_test_prepare();
+ ret = goodix_short_test_prepare(cd);
if (ret < 0) {
ts_err("Failed enter short test mode");
return ret;
@@ -1071,7 +1066,7 @@ static int goodix_shortcircut_test(void)
/* start analysis short result */
ts_info("short_test finished, start analysis");
- res = goodix_shortcircut_analysis();
+ res = goodix_shortcircut_analysis(cd);
if (res == 0) {
ts_test->result[GTP_SHORT_TEST] = TEST_OK;
ret = 0;
@@ -1093,7 +1088,8 @@ typedef struct __attribute__((packed)) {
#define FLASH_CMD_STATE_CHECKERR 0x05
#define FLASH_CMD_STATE_DENY 0x06
#define FLASH_CMD_STATE_OKAY 0x07
-static int goodix_flash_cmd(uint8_t cmd, uint8_t status, int retry_count)
+static int goodix_flash_cmd(struct goodix_ts_core *cd,
+ uint8_t cmd, uint8_t status, int retry_count)
{
u8 cmd_buf[] = { 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
int ret;
@@ -1122,7 +1118,7 @@ static int goodix_flash_cmd(uint8_t cmd, uint8_t status, int retry_count)
return -EINVAL;
}
-static int goodix_flash_read(u32 addr, u8 *buf, int len)
+static int goodix_flash_read(struct goodix_ts_core *cd, u32 addr, u8 *buf, int len)
{
int i;
int ret;
@@ -1142,7 +1138,7 @@ static int goodix_flash_read(u32 addr, u8 *buf, int len)
checksum += p[i] | (p[i + 1] << 8);
head_info.checksum = checksum;
- ret = goodix_flash_cmd(FLASH_CMD_R_START, FLASH_CMD_STATE_READY, 15);
+ ret = goodix_flash_cmd(cd, FLASH_CMD_R_START, FLASH_CMD_STATE_READY, 15);
if (ret < 0) {
ts_err("failed enter flash read state");
goto read_end;
@@ -1155,7 +1151,7 @@ static int goodix_flash_read(u32 addr, u8 *buf, int len)
goto read_end;
}
- ret = goodix_flash_cmd(FLASH_CMD_RW_FINISH, FLASH_CMD_STATE_OKAY, 50);
+ ret = goodix_flash_cmd(cd, FLASH_CMD_RW_FINISH, FLASH_CMD_STATE_OKAY, 50);
if (ret) {
ts_err("faild read flash ready state");
goto read_end;
@@ -1182,7 +1178,7 @@ static int goodix_flash_read(u32 addr, u8 *buf, int len)
memcpy(buf, tmp_buf + sizeof(flash_head_info_t), len);
ret = 0;
read_end:
- goodix_flash_cmd(0x0C, 0, 0);
+ goodix_flash_cmd(cd, 0x0C, 0, 0);
return ret;
}
@@ -1223,15 +1219,27 @@ static const struct seq_operations seq_ops = {
static int driver_test_open(struct inode *inode, struct file *file)
{
- return seq_open(file, &seq_ops);
+ struct seq_file *seq_file;
+ int ret;
+
+ ret = seq_open(file, &seq_ops);
+ if (ret)
+ return ret;
+ seq_file = (struct seq_file *)file->private_data;
+ if (seq_file)
+ seq_file->private = PDE_DATA(inode);
+
+ mutex_lock(&goodix_devices.mutex);
+ return 0;
}
static int driver_test_release(struct inode *inode, struct file *file)
{
+ mutex_unlock(&goodix_devices.mutex);
return seq_release(inode, file);
}
-static void goodix_save_header(void)
+static void goodix_save_header(struct goodix_ts_core *cd)
{
int i;
bool total_result = true;
@@ -1465,7 +1473,7 @@ static void goodix_data_cal(s16 *data, size_t data_size, s16 *stat_result)
stat_result[2] = min;
}
-static void goodix_save_data(void)
+static void goodix_save_data(struct goodix_ts_core *cd)
{
int tx = cd->ic_info.parm.drv_num;
int rx = cd->ic_info.parm.sen_num;
@@ -1553,12 +1561,12 @@ static void goodix_save_data(void)
index += sprintf(&rbuf[index], "</DataRecord>\n");
}
-static void goodix_save_tail(void)
+static void goodix_save_tail(struct goodix_ts_core *cd)
{
index += sprintf(&rbuf[index], "</TESTLOG>\n");
}
-static void goodix_save_test_result(bool is_brief)
+static void goodix_save_test_result(struct goodix_ts_core *cd, bool is_brief)
{
if (is_brief) {
if (ts_test->item[GTP_CAP_TEST]) {
@@ -1592,9 +1600,9 @@ static void goodix_save_test_result(bool is_brief)
: "FAIL");
}
} else {
- goodix_save_header();
- goodix_save_data();
- goodix_save_tail();
+ goodix_save_header(cd);
+ goodix_save_data(cd);
+ goodix_save_tail(cd);
}
}
@@ -1724,7 +1732,7 @@ static int parse_csvfile(
return parse_valid_data(buf, size, ptr, data, rows);
}
-static int goodix_obtain_testlimits(void)
+static int goodix_obtain_testlimits(struct goodix_ts_core *cd)
{
const struct firmware *firmware = NULL;
struct device *dev = &cd->pdev->dev;
@@ -1847,7 +1855,7 @@ exit_free:
return ret;
}
-static int goodix_delta_test(void)
+static int goodix_delta_test(struct goodix_ts_core *cd)
{
int i, j;
int max_val;
@@ -1899,7 +1907,7 @@ static int goodix_delta_test(void)
return ret;
}
-static int goodix_open_test(void)
+static int goodix_open_test(struct goodix_ts_core *cd)
{
u8 *tmp_buf;
struct goodix_ts_cmd temp_cmd;
@@ -1999,7 +2007,7 @@ static int goodix_open_test(void)
ts_test->result[GTP_CAP_TEST] = TEST_NG;
}
- if (goodix_delta_test() == 0)
+ if (goodix_delta_test(cd) == 0)
ts_test->result[GTP_DELTA_TEST] = TEST_OK;
exit:
@@ -2007,7 +2015,7 @@ exit:
return ret;
}
-static int goodix_self_open_test(void)
+static int goodix_self_open_test(struct goodix_ts_core *cd)
{
u8 *tmp_buf;
struct goodix_ts_cmd temp_cmd;
@@ -2085,7 +2093,7 @@ exit:
return ret;
}
-static int goodix_noise_test(void)
+static int goodix_noise_test(struct goodix_ts_core *cd)
{
u8 *tmp_buf;
struct goodix_ts_cmd temp_cmd;
@@ -2168,19 +2176,19 @@ exit:
return ret;
}
-static int goodix_auto_test(bool is_brief)
+static int goodix_auto_test(struct goodix_ts_core *cd, bool is_brief)
{
struct goodix_ts_cmd temp_cmd;
int ret;
- ret = goodix_obtain_testlimits();
+ ret = goodix_obtain_testlimits(cd);
if (ret < 0) {
ts_err("obtain open test limits failed");
return ret;
}
cd->hw_ops->irq_enable(cd, false);
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
temp_cmd.len = 5;
temp_cmd.cmd = 0x64;
@@ -2190,7 +2198,7 @@ static int goodix_auto_test(bool is_brief)
ret = cd->hw_ops->send_cmd(cd, &temp_cmd);
if (ret < 0)
ts_err("enter test mode failed");
- goodix_open_test();
+ goodix_open_test(cd);
cd->hw_ops->reset(cd, 100);
}
@@ -2198,27 +2206,27 @@ static int goodix_auto_test(bool is_brief)
ret = cd->hw_ops->send_cmd(cd, &temp_cmd);
if (ret < 0)
ts_err("enter test mode failed");
- goodix_noise_test();
+ goodix_noise_test(cd);
cd->hw_ops->reset(cd, 100);
}
if (ts_test->item[GTP_SELFCAP_TEST]) {
- goodix_self_open_test();
+ goodix_self_open_test(cd);
cd->hw_ops->reset(cd, 100);
}
if (ts_test->item[GTP_SHORT_TEST]) {
- goodix_shortcircut_test();
+ goodix_shortcircut_test(cd);
cd->hw_ops->reset(cd, 100);
}
cd->hw_ops->irq_enable(cd, true);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
- goodix_save_test_result(is_brief);
+ goodix_ts_esd_on(cd);
+ goodix_save_test_result(cd, is_brief);
return 0;
}
-static void goodix_auto_noise_test(u16 cnt, int threshold)
+static void goodix_auto_noise_test(struct goodix_ts_core *cd, u16 cnt, int threshold)
{
struct goodix_ts_cmd temp_cmd;
struct goodix_ts_cmd rb_cmd;
@@ -2245,7 +2253,7 @@ static void goodix_auto_noise_test(u16 cnt, int threshold)
8;
cd->hw_ops->irq_enable(cd, false);
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
restart:
temp_cmd.len = 0x07;
@@ -2325,10 +2333,10 @@ exit:
}
kfree(tmp_buf);
cd->hw_ops->irq_enable(cd, true);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
}
-static int get_cap_data(uint8_t *type)
+static int get_cap_data(struct goodix_ts_core *cd, uint8_t *type)
{
struct goodix_ts_cmd temp_cmd;
int tx = cd->ic_info.parm.drv_num;
@@ -2362,7 +2370,7 @@ static int get_cap_data(uint8_t *type)
/* disable irq & close esd */
cd->hw_ops->irq_enable(cd, false);
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
if (strstr(type, CMD_GET_BASEDATA) ||
strstr(type, CMD_GET_SELF_BASEDATA)) {
@@ -2453,11 +2461,11 @@ exit:
cd->hw_ops->send_cmd(cd, &temp_cmd);
/* enable irq & esd */
cd->hw_ops->irq_enable(cd, true);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
return ret;
}
-static void goodix_set_sense_mode(u8 val)
+static void goodix_set_sense_mode(struct goodix_ts_core *cd, u8 val)
{
struct goodix_ts_cmd temp_cmd;
@@ -2468,26 +2476,26 @@ static void goodix_set_sense_mode(u8 val)
/* normal mode */
index = sprintf(rbuf, "switch to coordinate mode\n");
cd->hw_ops->send_cmd(cd, &temp_cmd);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
cd->hw_ops->irq_enable(cd, true);
atomic_set(&cd->suspended, 0);
} else if (val == 2) {
/* gesture mode */
index = sprintf(rbuf, "switch to gesture mode\n");
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
cd->hw_ops->gesture(cd, 0);
cd->hw_ops->irq_enable(cd, true);
atomic_set(&cd->suspended, 1);
} else {
/* sleep mode */
index = sprintf(rbuf, "switch to sleep mode\n");
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
cd->hw_ops->irq_enable(cd, false);
cd->hw_ops->suspend(cd);
}
}
-static void goodix_set_scan_mode(u8 val)
+static void goodix_set_scan_mode(struct goodix_ts_core *cd, u8 val)
{
struct goodix_ts_cmd temp_cmd;
@@ -2511,7 +2519,7 @@ static void goodix_set_scan_mode(u8 val)
cd->hw_ops->send_cmd(cd, &temp_cmd);
}
-static void goodix_get_scan_mode(void)
+static void goodix_get_scan_mode(struct goodix_ts_core *cd)
{
u8 status;
@@ -2533,7 +2541,7 @@ static void goodix_get_scan_mode(void)
}
}
-static void goodix_set_continue_mode(u8 val)
+static void goodix_set_continue_mode(struct goodix_ts_core *cd, u8 val)
{
struct goodix_ts_cmd temp_cmd;
@@ -2551,7 +2559,7 @@ static void goodix_set_continue_mode(u8 val)
cd->hw_ops->send_cmd(cd, &temp_cmd);
}
-static void goodix_read_config(void)
+static void goodix_read_config(struct goodix_ts_core *cd)
{
int ret;
u8 *cfg_buf;
@@ -2579,7 +2587,7 @@ exit:
kfree(cfg_buf);
}
-static void goodix_get_fw_status(void)
+static void goodix_get_fw_status(struct goodix_ts_core *cd)
{
u32 status_addr;
u32 noise_lv_addr;
@@ -2626,7 +2634,7 @@ static void goodix_get_fw_status(void)
index += sprintf(&rbuf[index], "noise-lv[%d]\n", val);
}
-static void goodix_set_highsense_mode(u8 val)
+static void goodix_set_highsense_mode(struct goodix_ts_core *cd, u8 val)
{
struct goodix_ts_cmd temp_cmd;
static bool flag = false;
@@ -2650,7 +2658,7 @@ static void goodix_set_highsense_mode(u8 val)
cd->hw_ops->send_cmd(cd, &temp_cmd);
}
-static void goodix_set_grip_data(u8 val)
+static void goodix_set_grip_data(struct goodix_ts_core *cd, u8 val)
{
struct goodix_ts_cmd temp_cmd;
@@ -2679,7 +2687,7 @@ static void goodix_set_grip_data(u8 val)
cd->hw_ops->send_cmd(cd, &temp_cmd);
}
-static void goodix_set_custom_mode(u8 type, u8 val)
+static void goodix_set_custom_mode(struct goodix_ts_core *cd, u8 type, u8 val)
{
struct goodix_ts_cmd temp_cmd;
@@ -2731,7 +2739,7 @@ static int obtain_param(char **buf)
return val;
}
-static int goodix_parse_gesture_param(u8 type, char **buf)
+static int goodix_parse_gesture_param(struct goodix_ts_core *cd, u8 type, char **buf)
{
if (type == GESTURE_STTW) {
gesture_param_st.length = sizeof(gesture_param_st);
@@ -2823,7 +2831,7 @@ static int goodix_parse_gesture_param(u8 type, char **buf)
return 0;
}
-static void goodix_set_gesture_param(u8 type)
+static void goodix_set_gesture_param(struct goodix_ts_core *cd, u8 type)
{
struct goodix_ts_cmd temp_cmd;
u32 cmd_reg = cd->ic_info.misc.cmd_addr;
@@ -2887,18 +2895,29 @@ exit:
cd->hw_ops->send_cmd(cd, &temp_cmd);
}
-static void goodix_set_heatmap(int val)
+static void goodix_set_heatmap(struct goodix_ts_core *cd, int val)
{
struct goodix_ts_cmd temp_cmd;
cd->hw_ops->irq_enable(cd, false);
if (val == 0) {
index = sprintf(rbuf, "disable heatmap\n");
+/*
+ * [GOOG]
+ * Use goodix_update_heatmap() to do the heatmap process.
+ kfree(cd->heatmap_buffer);
+ cd->heatmap_buffer = NULL;
+ */
temp_cmd.len = 5;
temp_cmd.cmd = 0xC9;
temp_cmd.data[0] = 0;
} else {
index = sprintf(rbuf, "enable heatmap\n");
+/*
+ * [GOOG]
+ * Use goodix_update_heatmap() to do the heatmap process.
+ cd->heatmap_buffer = kzalloc(GOODIX_MAX_FRAMEDATA_LEN, GFP_KERNEL);
+ */
temp_cmd.len = 5;
temp_cmd.cmd = 0xC9;
temp_cmd.data[0] = 1;
@@ -2907,7 +2926,7 @@ static void goodix_set_heatmap(int val)
cd->hw_ops->irq_enable(cd, true);
}
-static void goodix_get_self_compensation(void)
+static void goodix_get_self_compensation(struct goodix_ts_core *cd)
{
u8 *cfg;
u8 *cfg_buf;
@@ -2962,7 +2981,7 @@ exit:
kfree(cfg_buf);
}
-static void goodix_set_report_rate(int rate)
+static void goodix_set_report_rate(struct goodix_ts_core *cd, int rate)
{
struct goodix_ts_cmd temp_cmd;
@@ -2975,12 +2994,12 @@ static void goodix_set_report_rate(int rate)
}
#define DUMP_AREA1_ADDR 0x10194
-#define DUMP_AREA1_LEN 132
+#define DUMP_AREA1_LEN 132
#define DUMP_AREA2_ADDR 0x10400
-#define DUMP_AREA2_LEN 596
+#define DUMP_AREA2_LEN 596
#define DUMP_AREA3_ADDR 0x10308
-#define DUMP_AREA3_LEN 64
-static void goodix_get_dump_log(void)
+#define DUMP_AREA3_LEN 64
+static void goodix_get_dump_log(struct goodix_ts_core *cd)
{
u8 buf[600];
int i;
@@ -3010,7 +3029,7 @@ static void goodix_get_dump_log(void)
}
}
-static void goodix_get_stylus_data(void)
+static void goodix_get_stylus_data(struct goodix_ts_core *cd)
{
struct goodix_stylus_data stylus_data;
u8 temp_buf[40] = { 0 };
@@ -3035,7 +3054,7 @@ static void goodix_get_stylus_data(void)
/* disable irq & close esd */
cd->hw_ops->irq_enable(cd, false);
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
/* clean touch event flag */
ret = cd->hw_ops->write(cd, flag_addr, temp_buf, 1);
@@ -3126,10 +3145,10 @@ static void goodix_get_stylus_data(void)
exit:
/* enable irq & esd */
cd->hw_ops->irq_enable(cd, true);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
}
-static void goodix_force_update(void)
+static void goodix_force_update(struct goodix_ts_core *cd)
{
int i;
int ret;
@@ -3143,7 +3162,7 @@ static void goodix_force_update(void)
if (ret < 0)
ts_err("not found valid config");
- ret = goodix_do_fw_update(cd->ic_configs[CONFIG_TYPE_NORMAL],
+ ret = goodix_do_fw_update(cd,
UPDATE_MODE_BLOCK | UPDATE_MODE_FORCE |
UPDATE_MODE_SRC_REQUEST);
if (ret < 0)
@@ -3152,7 +3171,7 @@ static void goodix_force_update(void)
index = sprintf(rbuf, "%s: OK\n", CMD_FW_UPDATE);
}
-static void goodix_set_freq_index(int freq)
+static void goodix_set_freq_index(struct goodix_ts_core *cd, int freq)
{
struct goodix_ts_cmd temp_cmd;
@@ -3164,7 +3183,7 @@ static void goodix_set_freq_index(int freq)
cd->hw_ops->send_cmd(cd, &temp_cmd);
}
-static void goodix_disable_coor_filter(int val)
+static void goodix_disable_coor_filter(struct goodix_ts_core *cd, int val)
{
struct goodix_ts_cmd temp_cmd;
@@ -3175,9 +3194,11 @@ static void goodix_disable_coor_filter(int val)
cd->hw_ops->send_cmd(cd, &temp_cmd);
}
-static ssize_t driver_test_write(
- struct file *file, const char __user *buf, size_t count, loff_t *pos)
+static ssize_t driver_test_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *pos)
{
+ struct seq_file *seq_file = (struct seq_file *)file->private_data;
+ struct goodix_ts_core *cd = (struct goodix_ts_core *)seq_file->private;
struct goodix_fw_version fw_ver;
struct goodix_ic_info ic_info;
char *p = wbuf;
@@ -3197,6 +3218,7 @@ static ssize_t driver_test_write(
ts_err("copy from user failed");
return count;
}
+ p[strlen(p) - 1] = 0;
vfree(rbuf);
rbuf = NULL;
@@ -3207,7 +3229,7 @@ static ssize_t driver_test_write(
if (!strncmp(p, CMD_FW_UPDATE, strlen(CMD_FW_UPDATE))) {
rbuf = vzalloc(SHORT_SIZE);
- goodix_force_update();
+ goodix_force_update(cd);
goto exit;
}
@@ -3232,7 +3254,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- ret = get_cap_data(CMD_GET_RAWDATA);
+ ret = get_cap_data(cd, CMD_GET_RAWDATA);
if (ret < 0) {
index = sprintf(rbuf, "%s: NG\n", CMD_GET_RAWDATA);
}
@@ -3245,7 +3267,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- ret = get_cap_data(CMD_GET_BASEDATA);
+ ret = get_cap_data(cd, CMD_GET_BASEDATA);
if (ret < 0) {
index = sprintf(rbuf, "%s: NG\n", CMD_GET_BASEDATA);
}
@@ -3258,7 +3280,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- ret = get_cap_data(CMD_GET_DIFFDATA);
+ ret = get_cap_data(cd, CMD_GET_DIFFDATA);
if (ret < 0) {
index = sprintf(rbuf, "%s: NG\n", CMD_GET_DIFFDATA);
}
@@ -3271,7 +3293,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- ret = get_cap_data(CMD_GET_SELF_RAWDATA);
+ ret = get_cap_data(cd, CMD_GET_SELF_RAWDATA);
if (ret < 0) {
index = sprintf(rbuf, "%s: NG\n", CMD_GET_SELF_RAWDATA);
}
@@ -3284,7 +3306,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- ret = get_cap_data(CMD_GET_SELF_DIFFDATA);
+ ret = get_cap_data(cd, CMD_GET_SELF_DIFFDATA);
if (ret < 0) {
index = sprintf(
rbuf, "%s: NG\n", CMD_GET_SELF_DIFFDATA);
@@ -3298,7 +3320,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- ret = get_cap_data(CMD_GET_SELF_BASEDATA);
+ ret = get_cap_data(cd, CMD_GET_SELF_BASEDATA);
if (ret < 0) {
index = sprintf(
rbuf, "%s: NG\n", CMD_GET_SELF_BASEDATA);
@@ -3446,11 +3468,11 @@ static ssize_t driver_test_write(
goto exit;
}
if (cmd_val == 0) {
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(cd);
index = sprintf(
rbuf, "%s: disable OK\n", CMD_SET_ESD_ENABLE);
} else {
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(cd);
index = sprintf(
rbuf, "%s: enable OK\n", CMD_SET_ESD_ENABLE);
}
@@ -3504,7 +3526,7 @@ static ssize_t driver_test_write(
ts_test->item[GTP_DELTA_TEST] = true;
ts_test->item[GTP_SELFCAP_TEST] = true;
ts_test->item[GTP_SHORT_TEST] = true;
- goodix_auto_test(true);
+ goodix_auto_test(cd, true);
goto exit;
}
@@ -3525,7 +3547,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- ret = get_cap_data(CMD_GET_TX_FREQ);
+ ret = get_cap_data(cd, CMD_GET_TX_FREQ);
if (ret < 0) {
index = sprintf(rbuf, "%s: NG\n", CMD_GET_TX_FREQ);
}
@@ -3561,7 +3583,7 @@ static ssize_t driver_test_write(
CMD_SET_SENSE_MODE);
goto exit;
}
- goodix_set_sense_mode(cmd_val);
+ goodix_set_sense_mode(cd, cmd_val);
goto exit;
}
@@ -3587,7 +3609,7 @@ static ssize_t driver_test_write(
goto exit;
}
ts_test->item[GTP_NOISE_TEST] = true;
- goodix_auto_test(false);
+ goodix_auto_test(cd, false);
goto exit;
}
@@ -3615,7 +3637,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- goodix_auto_noise_test(cmd_val, cmd_val2);
+ goodix_auto_noise_test(cd, cmd_val, cmd_val2);
goto exit;
}
@@ -3627,7 +3649,7 @@ static ssize_t driver_test_write(
}
mutex_lock(&cd->cmd_lock);
usleep_range(6000, 6100);
- ret = goodix_flash_read(0x1F301, &id, 1);
+ ret = goodix_flash_read(cd, 0x1F301, &id, 1);
mutex_unlock(&cd->cmd_lock);
if (ret < 0)
index = sprintf(rbuf, "%s: NG\n", CMD_GET_PACKAGE_ID);
@@ -3645,7 +3667,7 @@ static ssize_t driver_test_write(
}
mutex_lock(&cd->cmd_lock);
usleep_range(6000, 6100);
- ret = goodix_flash_read(0x1F314, &id, 1);
+ ret = goodix_flash_read(cd, 0x1F314, &id, 1);
mutex_unlock(&cd->cmd_lock);
if (ret < 0)
index = sprintf(rbuf, "%s: NG\n", CMD_GET_MCU_ID);
@@ -3676,7 +3698,7 @@ static ssize_t driver_test_write(
CMD_SET_SCAN_MODE);
goto exit;
}
- goodix_set_scan_mode(cmd_val);
+ goodix_set_scan_mode(cd, cmd_val);
goto exit;
}
@@ -3686,7 +3708,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- goodix_get_scan_mode();
+ goodix_get_scan_mode(cd);
goto exit;
}
@@ -3712,7 +3734,7 @@ static ssize_t driver_test_write(
CMD_SET_CONTINUE_MODE);
goto exit;
}
- goodix_set_continue_mode(cmd_val);
+ goodix_set_continue_mode(cd, cmd_val);
goto exit;
}
@@ -3749,7 +3771,7 @@ static ssize_t driver_test_write(
}
ts_test->item[GTP_CAP_TEST] = true;
ts_test->freq = cmd_val2;
- goodix_auto_test(false);
+ goodix_auto_test(cd, false);
goto exit;
}
@@ -3765,7 +3787,7 @@ static ssize_t driver_test_write(
goto exit;
}
ts_test->item[GTP_SELFCAP_TEST] = true;
- goodix_auto_test(false);
+ goodix_auto_test(cd, false);
goto exit;
}
@@ -3781,7 +3803,7 @@ static ssize_t driver_test_write(
goto exit;
}
ts_test->item[GTP_SHORT_TEST] = true;
- goodix_auto_test(false);
+ goodix_auto_test(cd, false);
goto exit;
}
@@ -3791,7 +3813,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- goodix_read_config();
+ goodix_read_config(cd);
goto exit;
}
@@ -3801,7 +3823,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- goodix_get_fw_status();
+ goodix_get_fw_status(cd);
goto exit;
}
@@ -3828,7 +3850,7 @@ static ssize_t driver_test_write(
CMD_SET_HIGHSENSE_MODE);
goto exit;
}
- goodix_set_highsense_mode(cmd_val);
+ goodix_set_highsense_mode(cd, cmd_val);
goto exit;
}
@@ -3849,7 +3871,7 @@ static ssize_t driver_test_write(
CMD_SET_GRIP_DATA);
goto exit;
}
- goodix_set_grip_data(cmd_val);
+ goodix_set_grip_data(cd, cmd_val);
goto exit;
}
@@ -3870,7 +3892,7 @@ static ssize_t driver_test_write(
CMD_SET_GRIP_MODE);
goto exit;
}
- goodix_set_custom_mode(GRIP_FUNC, cmd_val);
+ goodix_set_custom_mode(cd, GRIP_FUNC, cmd_val);
goto exit;
}
@@ -3891,7 +3913,7 @@ static ssize_t driver_test_write(
CMD_SET_PALM_MODE);
goto exit;
}
- goodix_set_custom_mode(PALM_FUNC, cmd_val);
+ goodix_set_custom_mode(cd, PALM_FUNC, cmd_val);
goto exit;
}
@@ -3912,7 +3934,7 @@ static ssize_t driver_test_write(
CMD_SET_NOISE_MODE);
goto exit;
}
- goodix_set_custom_mode(NOISE_FUNC, cmd_val);
+ goodix_set_custom_mode(cd, NOISE_FUNC, cmd_val);
goto exit;
}
@@ -3933,7 +3955,7 @@ static ssize_t driver_test_write(
CMD_SET_WATER_MODE);
goto exit;
}
- goodix_set_custom_mode(WATER_FUNC, cmd_val);
+ goodix_set_custom_mode(cd, WATER_FUNC, cmd_val);
goto exit;
}
@@ -3949,8 +3971,8 @@ static ssize_t driver_test_write(
CMD_SET_ST_PARAM);
goto exit;
}
- goodix_parse_gesture_param(GESTURE_STTW, &p);
- goodix_set_gesture_param(GESTURE_STTW);
+ goodix_parse_gesture_param(cd, GESTURE_STTW, &p);
+ goodix_set_gesture_param(cd, GESTURE_STTW);
goto exit;
}
@@ -3966,8 +3988,8 @@ static ssize_t driver_test_write(
CMD_SET_LP_PARAM);
goto exit;
}
- goodix_parse_gesture_param(GESTURE_LPTW, &p);
- goodix_set_gesture_param(GESTURE_LPTW);
+ goodix_parse_gesture_param(cd, GESTURE_LPTW, &p);
+ goodix_set_gesture_param(cd, GESTURE_LPTW);
goto exit;
}
@@ -3988,7 +4010,7 @@ static ssize_t driver_test_write(
CMD_SET_HEATMAP);
goto exit;
}
- goodix_set_heatmap(cmd_val);
+ goodix_set_heatmap(cd, cmd_val);
goto exit;
}
@@ -3998,7 +4020,7 @@ static ssize_t driver_test_write(
ts_err("failed to alloc rbuf");
goto exit;
}
- goodix_get_self_compensation();
+ goodix_get_self_compensation(cd);
goto exit;
}
@@ -4019,25 +4041,27 @@ static ssize_t driver_test_write(
CMD_SET_REPORT_RATE);
goto exit;
}
- goodix_set_report_rate(cmd_val);
+ goodix_set_report_rate(cd, cmd_val);
goto exit;
}
if (!strncmp(p, CMD_GET_DUMP_LOG, strlen(CMD_GET_DUMP_LOG))) {
rbuf = vzalloc(LARGE_SIZE);
- goodix_get_dump_log();
- goto exit;
- }
- if (!strncmp(p, CMD_GET_STYLUS_DATA, strlen(CMD_GET_STYLUS_DATA))) {
- rbuf = vzalloc(LARGE_SIZE);
- goodix_get_stylus_data();
+ if (!rbuf) {
+ ts_err("failed to alloc rbuf");
+ goto exit;
+ }
+ goodix_get_dump_log(cd);
goto exit;
}
-
if (!strncmp(p, CMD_GET_STYLUS_DATA, strlen(CMD_GET_STYLUS_DATA))) {
rbuf = vzalloc(LARGE_SIZE);
- goodix_get_stylus_data();
+ if (!rbuf) {
+ ts_err("failed to alloc rbuf");
+ goto exit;
+ }
+ goodix_get_stylus_data(cd);
goto exit;
}
@@ -4054,7 +4078,7 @@ static ssize_t driver_test_write(
CMD_SET_FREQ_INDEX);
goto exit;
}
- goodix_set_freq_index(cmd_val);
+ goodix_set_freq_index(cd, cmd_val);
goto exit;
}
@@ -4071,7 +4095,7 @@ static ssize_t driver_test_write(
CMD_DISABLE_FILTER);
goto exit;
}
- goodix_disable_coor_filter(cmd_val);
+ goodix_disable_coor_filter(cd, cmd_val);
goto exit;
}
@@ -4138,7 +4162,8 @@ static const struct file_operations cmd_list_ops = {
};
#endif
-int driver_test_selftest(char* buf)
+/* [GOOG] */
+int driver_test_selftest(struct goodix_ts_core *cd, char *buf)
{
int ret = 0;
@@ -4167,7 +4192,7 @@ int driver_test_selftest(char* buf)
ts_test->item[GTP_DELTA_TEST] = true;
ts_test->item[GTP_SELFCAP_TEST] = true;
ts_test->item[GTP_SHORT_TEST] = true;
- goodix_auto_test(true);
+ goodix_auto_test(cd, true);
strlcpy(buf, rbuf, PAGE_SIZE);
@@ -4179,22 +4204,24 @@ int driver_test_proc_init(struct goodix_ts_core *core_data)
{
struct proc_dir_entry *proc_entry;
- proc_entry = proc_create(
- "goodix_ts/driver_test", 0660, NULL, &driver_test_ops);
+ proc_entry = proc_create_data(
+ "driver_test", 0660, core_data->proc_dir_entry, &driver_test_ops, core_data);
if (!proc_entry) {
- ts_err("failed to create proc entry");
- return -ENOMEM;
+ ts_err("failed to create proc driver_test");
+ return -ENODEV;
}
proc_entry =
- proc_create("goodix_ts/cmd_list", 0440, NULL, &cmd_list_ops);
-
- cd = core_data;
+ proc_create("cmd_list", 0440, core_data->proc_dir_entry, &cmd_list_ops);
+ if (!proc_entry) {
+ ts_err("failed to create proc cmd_list");
+ return -ENODEV;
+ }
return 0;
}
-void driver_test_proc_remove(void)
+void driver_test_proc_remove(struct goodix_ts_core *core_data)
{
- remove_proc_entry("goodix_ts/cmd_list", NULL);
- remove_proc_entry("goodix_ts/driver_test", NULL);
+ remove_proc_entry("cmd_list", core_data->proc_dir_entry);
+ remove_proc_entry("driver_test", core_data->proc_dir_entry);
}
diff --git a/goodix_ts_tools.c b/goodix_ts_tools.c
index 5fb175f..f648ba0 100644
--- a/goodix_ts_tools.c
+++ b/goodix_ts_tools.c
@@ -20,15 +20,14 @@
#include <linux/ioctl.h>
#include <linux/kernel.h>
#include <linux/list.h>
-#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
-#define GOODIX_TOOLS_NAME "gtp_tools"
-#define GOODIX_TOOLS_VER_MAJOR 1
-#define GOODIX_TOOLS_VER_MINOR 0
+#define GOODIX_TOOLS_NAME "gtp_tools"
+#define GOODIX_TOOLS_VER_MAJOR 1
+#define GOODIX_TOOLS_VER_MINOR 0
static const u16 goodix_tools_ver =
((GOODIX_TOOLS_VER_MAJOR << 8) + (GOODIX_TOOLS_VER_MINOR));
@@ -49,33 +48,9 @@ static const u16 goodix_tools_ver =
(_IOW(GOODIX_TS_IOC_MAGIC, 10, u8) & NEGLECT_SIZE_MASK)
#define MAX_BUF_LENGTH (16 * 1024)
-#define IRQ_FALG (0x01 << 2)
#define I2C_MSG_HEAD_LEN 20
-/*
- * struct goodix_tools_dev - goodix tools device struct
- * @ts_core: The core data struct of ts driver
- * @ops_mode: represent device work mode
- * @rawdiffcmd: Set slave device into rawdata mode
- * @normalcmd: Set slave device into normal mode
- * @wq: Wait queue struct use in synchronous data read
- * @mutex: Protect goodix_tools_dev
- * @in_use: device in use
- */
-struct goodix_tools_dev {
- struct goodix_ts_core *ts_core;
- struct list_head head;
- unsigned int ops_mode;
- struct goodix_ts_cmd rawdiffcmd, normalcmd;
- wait_queue_head_t wq;
- bool is_clean_flag;
- struct delayed_work sync_work;
- struct mutex mutex;
- atomic_t in_use;
- struct goodix_ext_module module;
-} *goodix_tools_dev;
-
/* read data asynchronous,
* success return data length, otherwise return < 0
*/
@@ -85,7 +60,9 @@ static int async_read(struct goodix_tools_dev *dev, void __user *arg)
int ret = 0;
u32 reg_addr, length;
u8 i2c_msg_head[I2C_MSG_HEAD_LEN];
- const struct goodix_ts_hw_ops *hw_ops = dev->ts_core->hw_ops;
+ struct goodix_ts_core *ts_core =
+ container_of(dev, struct goodix_ts_core, tools_dev);
+ const struct goodix_ts_hw_ops *hw_ops = ts_core->hw_ops;
ret = copy_from_user(&i2c_msg_head, arg, I2C_MSG_HEAD_LEN);
if (ret)
@@ -105,7 +82,7 @@ static int async_read(struct goodix_tools_dev *dev, void __user *arg)
return -ENOMEM;
}
- if (hw_ops->read(dev->ts_core, reg_addr, databuf, length)) {
+ if (hw_ops->read(ts_core, reg_addr, databuf, length)) {
ret = -EBUSY;
ts_err("Read i2c failed");
goto err_out;
@@ -183,7 +160,8 @@ static int async_write(struct goodix_tools_dev *dev, void __user *arg)
int ret = 0;
u32 reg_addr, length;
u8 i2c_msg_head[I2C_MSG_HEAD_LEN];
- struct goodix_ts_core *ts_core = dev->ts_core;
+ struct goodix_ts_core *ts_core =
+ container_of(dev, struct goodix_ts_core, tools_dev);
const struct goodix_ts_hw_ops *hw_ops = ts_core->hw_ops;
ret = copy_from_user(&i2c_msg_head, arg, I2C_MSG_HEAD_LEN);
@@ -219,9 +197,6 @@ static int async_write(struct goodix_tools_dev *dev, void __user *arg)
ret = length;
}
- if (reg_addr == ts_core->ic_info.misc.touch_data_addr)
- dev->is_clean_flag = true;
-
err_out:
kfree(databuf);
return ret;
@@ -254,29 +229,6 @@ static int init_cfg_data(struct goodix_ic_config *cfg, void __user *arg)
return 0;
}
-static void goodix_ctrl_sync_work(struct work_struct *work)
-{
- struct goodix_ts_core *cd = goodix_tools_dev->ts_core;
- static int cnt;
-
- if (atomic_read(&goodix_tools_dev->in_use) == 0)
- return;
-
- if (cd->tools_ctrl_sync && !goodix_tools_dev->is_clean_flag) {
- cnt++;
- if (cnt >= 2) {
- cnt = 0;
- cd->tools_ctrl_sync = false;
- ts_info("restore tools sync flag to 0");
- }
- } else {
- cnt = 0;
- }
-
- goodix_tools_dev->is_clean_flag = false;
- schedule_delayed_work(&goodix_tools_dev->sync_work, 5 * HZ);
-}
-
/**
* goodix_tools_ioctl - ioctl implementation
*
@@ -290,15 +242,15 @@ static long goodix_tools_ioctl(
{
int ret = 0;
struct goodix_tools_dev *dev = filp->private_data;
- struct goodix_ts_core *ts_core;
+ struct goodix_ts_core *ts_core =
+ container_of(dev, struct goodix_ts_core, tools_dev);
const struct goodix_ts_hw_ops *hw_ops;
struct goodix_ic_config *temp_cfg = NULL;
- if (dev->ts_core == NULL) {
+ if (ts_core == NULL) {
ts_err("Tools module not register");
return -EINVAL;
}
- ts_core = dev->ts_core;
hw_ops = ts_core->hw_ops;
if (_IOC_TYPE(cmd) != GOODIX_TS_IOC_MAGIC) {
@@ -310,15 +262,9 @@ static long goodix_tools_ioctl(
case GTP_IRQ_ENABLE:
if (arg == 1) {
hw_ops->irq_enable(ts_core, true);
- mutex_lock(&dev->mutex);
- dev->ops_mode |= IRQ_FALG;
- mutex_unlock(&dev->mutex);
ts_info("IRQ enabled");
} else if (arg == 0) {
hw_ops->irq_enable(ts_core, false);
- mutex_lock(&dev->mutex);
- dev->ops_mode &= ~IRQ_FALG;
- mutex_unlock(&dev->mutex);
ts_info("IRQ disabled");
} else {
ts_info("Irq aready set with, arg = %ld", arg);
@@ -327,9 +273,9 @@ static long goodix_tools_ioctl(
break;
case GTP_ESD_ENABLE:
if (arg == 0)
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
+ goodix_ts_esd_off(ts_core);
else
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
+ goodix_ts_esd_on(ts_core);
break;
case GTP_DEV_RESET:
hw_ops->reset(ts_core, GOODIX_NORMAL_RESET_DELAY_MS);
@@ -346,7 +292,6 @@ static long goodix_tools_ioctl(
ret = -ENOMEM;
goto err_out;
}
-
ret = init_cfg_data(temp_cfg, (void __user *)arg);
if (!ret && hw_ops->send_config) {
ret = hw_ops->send_config(
@@ -413,59 +358,49 @@ static long goodix_tools_compat_ioctl(
}
#endif
-static int goodix_tools_open(struct inode *inode, struct file *filp)
+static struct goodix_ts_core *core_data_locate(int minor)
{
- int ret = 0;
+ struct goodix_device_resource *res, *next;
- ts_info("try open tool");
- /* Only the first time open device need to register module */
- ret = goodix_register_ext_module_no_wait(&goodix_tools_dev->module);
- if (ret) {
- ts_info("failed register to core module");
- return -EFAULT;
+ if (!list_empty(&goodix_devices.list)) {
+ list_for_each_entry_safe(res, next, &goodix_devices.list, list) {
+ if (res->core_data.tools_dev.miscdev.minor == minor)
+ return &res->core_data;
+ }
}
- ts_info("success open tools");
- goodix_ts_blocking_notify(NOTIFY_ESD_OFF, NULL);
- filp->private_data = goodix_tools_dev;
- atomic_set(&goodix_tools_dev->in_use, 1);
- schedule_delayed_work(&goodix_tools_dev->sync_work, 5 * HZ);
- return 0;
-}
-static int goodix_tools_release(struct inode *inode, struct file *filp)
-{
- int ret = 0;
- /* when the last close this dev node unregister the module */
- goodix_tools_dev->ts_core->tools_ctrl_sync = false;
- atomic_set(&goodix_tools_dev->in_use, 0);
- cancel_delayed_work_sync(&goodix_tools_dev->sync_work);
- goodix_ts_blocking_notify(NOTIFY_ESD_ON, NULL);
- ret = goodix_unregister_ext_module(&goodix_tools_dev->module);
- return ret;
+ return NULL;
}
-static int goodix_tools_module_init(
- struct goodix_ts_core *core_data, struct goodix_ext_module *module)
+static int goodix_tools_open(struct inode *inode, struct file *filp)
{
- struct goodix_tools_dev *tools_dev = module->priv_data;
+ struct goodix_ts_core *cd = core_data_locate(iminor(inode));
- if (core_data)
- tools_dev->ts_core = core_data;
- else
+ if (!cd) {
+ ts_err("can't find core data");
return -ENODEV;
+ }
+ goodix_ts_esd_off(cd);
+ cd->tools_dev.is_open = true;
+ filp->private_data = &cd->tools_dev;
+ ts_info("success open tools");
return 0;
}
-static int goodix_tools_module_exit(
- struct goodix_ts_core *core_data, struct goodix_ext_module *module)
+static int goodix_tools_release(
+ struct inode *inode, struct file *filp)
{
- struct goodix_tools_dev *tools_dev = module->priv_data;
- ts_debug("tools module unregister");
- if (atomic_read(&tools_dev->in_use)) {
- ts_err("tools module busy, please close it then retry");
- return -EBUSY;
+ struct goodix_ts_core *cd = core_data_locate(iminor(inode));
+
+ if (!cd) {
+ ts_err("can't find core data");
+ return -ENODEV;
}
+ /* when the last close this dev node unregister the module */
+ cd->tools_dev.is_open = false;
+ cd->tools_ctrl_sync = false;
+ goodix_ts_esd_on(cd);
return 0;
}
@@ -479,46 +414,21 @@ static const struct file_operations goodix_tools_fops = {
#endif
};
-static struct miscdevice goodix_tools_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = GOODIX_TOOLS_NAME,
- .fops = &goodix_tools_fops,
-};
-
-static struct goodix_ext_module_funcs goodix_tools_module_funcs = {
- .init = goodix_tools_module_init,
- .exit = goodix_tools_module_exit,
-};
-
/**
* goodix_tools_init - init goodix tools device and register a miscdevice
*
* return: 0 success, else failed
*/
-int goodix_tools_init(void)
+int goodix_tools_init(struct goodix_ts_core *core_data)
{
int ret;
+ struct goodix_tools_dev *tools_dev = &core_data->tools_dev;
- goodix_tools_dev = kzalloc(sizeof(struct goodix_tools_dev), GFP_KERNEL);
- if (goodix_tools_dev == NULL) {
- ts_err("Memory allco err");
- return -ENOMEM;
- }
-
- INIT_LIST_HEAD(&goodix_tools_dev->head);
- goodix_tools_dev->ops_mode = 0;
- goodix_tools_dev->ops_mode |= IRQ_FALG;
- init_waitqueue_head(&goodix_tools_dev->wq);
- mutex_init(&goodix_tools_dev->mutex);
- atomic_set(&goodix_tools_dev->in_use, 0);
-
- goodix_tools_dev->module.funcs = &goodix_tools_module_funcs;
- goodix_tools_dev->module.name = GOODIX_TOOLS_NAME;
- goodix_tools_dev->module.priv_data = goodix_tools_dev;
- goodix_tools_dev->module.priority = EXTMOD_PRIO_DBGTOOL;
- INIT_DELAYED_WORK(&goodix_tools_dev->sync_work, goodix_ctrl_sync_work);
-
- ret = misc_register(&goodix_tools_miscdev);
+ sprintf(tools_dev->name, "%s.%d", GOODIX_TOOLS_NAME, core_data->pdev->id);
+ tools_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
+ tools_dev->miscdev.name = tools_dev->name;
+ tools_dev->miscdev.fops = &goodix_tools_fops;
+ ret = misc_register(&tools_dev->miscdev);
if (ret)
ts_err("Debug tools miscdev register failed");
else
@@ -527,9 +437,10 @@ int goodix_tools_init(void)
return ret;
}
-void goodix_tools_exit(void)
+void goodix_tools_exit(struct goodix_ts_core *core_data)
{
- misc_deregister(&goodix_tools_miscdev);
- kfree(goodix_tools_dev);
+ struct goodix_tools_dev *tools_dev = &core_data->tools_dev;
+
+ misc_deregister(&tools_dev->miscdev);
ts_info("Debug tools miscdev exit");
}
diff --git a/goodix_ts_utils.c b/goodix_ts_utils.c
index 7649759..c3fc33e 100644
--- a/goodix_ts_utils.c
+++ b/goodix_ts_utils.c
@@ -69,7 +69,7 @@ int checksum_cmp(const u8 *data, int size, int mode)
u32 cal_checksum = 0;
u32 r_checksum = 0;
u32 i;
- bool is_valid = !is_risk_data(data, size);
+ bool is_valid = !is_risk_data(data, size); /* [GOOG] */
if (mode == CHECKSUM_MODE_U8_LE) {
if (size < 2)
@@ -123,7 +123,11 @@ u32 goodix_get_file_config_id(u8 *ic_config)
return le32_to_cpup((__le32 *)&ic_config[CONFIG_ID_OFFSET]);
}
-/* matrix transpose */
+/*
+ * matrix transpose:
+ * [GOOG]
+ * Add 'dest' as optional target(pa/2221748).
+ */
void goodix_rotate_abcd2cbad(int tx, int rx, s16 *src, s16 *dest)
{
s16 *temp_buf = dest;
@@ -132,10 +136,14 @@ void goodix_rotate_abcd2cbad(int tx, int rx, s16 *src, s16 *dest)
s16 *curr;
int index_org = 0;
+ /*
+ * [GOOG]
+ * If no 'dest' assign, 'src' will be overwrote.
+ */
if (dest == NULL) {
temp_buf = kcalloc(size, sizeof(s16), GFP_KERNEL);
if (!temp_buf) {
- ts_err("malloc failed");
+ ts_err("%s: malloc failed!\n", __func__);
return;
}
}
@@ -152,6 +160,7 @@ void goodix_rotate_abcd2cbad(int tx, int rx, s16 *src, s16 *dest)
memcpy(src, temp_buf, size * sizeof(s16));
kfree(temp_buf);
}
+ /*~[GOOG] */
}
/* get ic type */