diff options
author | Super Liu <supercjliu@google.com> | 2023-04-06 05:19:59 +0000 |
---|---|---|
committer | Super Liu <supercjliu@google.com> | 2023-04-06 08:02:14 +0000 |
commit | 8da5744724d93c45251f91a2f09c5420de8da65c (patch) | |
tree | 9d21ed3b371727a1e000b8b5fb1e0644c67a4c11 /goodix_brl_fwupdate.c | |
parent | a17332d87e6dd4f008e9575cb2f5a15fffa24fe9 (diff) | |
download | goodix_touch-8da5744724d93c45251f91a2f09c5420de8da65c.tar.gz |
Revert^2 "touch/goodix: Import driver v1.2.5"
a17332d87e6dd4f008e9575cb2f5a15fffa24fe9
Change-Id: I6bd8676543a4370522f1df88c676f2075659e12e
Diffstat (limited to 'goodix_brl_fwupdate.c')
-rw-r--r-- | goodix_brl_fwupdate.c | 466 |
1 files changed, 149 insertions, 317 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); } |