summaryrefslogtreecommitdiff
path: root/goodix_brl_fwupdate.c
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 /goodix_brl_fwupdate.c
parenta17332d87e6dd4f008e9575cb2f5a15fffa24fe9 (diff)
downloadgoodix_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.c466
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);
}