// File: goodix[P]gdix_hid_firmware_update/gtx9/gtx9_i2c_update.cpp
// Function: gdix_flash_firmware(fw_update_ctrl*)
static int gdix_flash_firmware(struct fw_update_ctrl *fw_ctrl)
{
	struct firmware_data *fw_data = &fw_ctrl->fw_data;
	struct firmware_summary *fw_summary;
	struct fw_subsys_info *fw_x;
	struct fw_subsys_info subsys_cfg = {0};
	int retry = 3;
	int i, r = 0, fw_num;
	uint8_t temp_buf[CFG_MAX_SIZE] = {0};

	/*	start from subsystem 1,
	 *	subsystem 0 is the ISP program
	 */
	fw_summary = &fw_data->fw_summary;
	fw_num = fw_summary->subsys_num;

	/* flash config data first if we have */
	if (fw_ctrl->ic_config && fw_ctrl->ic_config->len) {
		memcpy(temp_buf, fw_ctrl->ic_config->data, fw_ctrl->ic_config->len);
		subsys_cfg.data = temp_buf;
		subsys_cfg.size = CFG_MAX_SIZE;
		subsys_cfg.flash_addr = 0x40000;
		subsys_cfg.type = 4;
		r = gdix_flash_subsystem(&subsys_cfg);
		if (r) {
			gdix_err("failed flash config with ISP, %d\n", r);
			return r;
		}
		gdix_dbg("success flash config with ISP\n");
	}

	for (i = 1; i < fw_num && retry;) {
		gdix_dbg("--- Start to flash subsystem[%d] ---\n", i);
		fw_x = &fw_summary->subsys[i];
		r = gdix_flash_subsystem(fw_x);
		if (r == 0) {
			gdix_dbg("--- End flash subsystem[%d]: OK ---\n", i);
			i++;
		} else if (r == -EAGAIN) {
			retry--;
			gdix_err(
				"--- End flash subsystem%d: Fail, errno:%d, retry:%d ---\n", i,
				r, 3 - retry);
		} else if (r < 0) { /* bus error */
			gdix_err("--- End flash subsystem%d: Fatal error:%d exit ---\n", i,
					 r);
			goto exit_flash;
		}
	}

exit_flash:
	return r;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1060, %rsp           # imm = 0x1060
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x18(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x50a0
movl $0x3, -0x44(%rbp)
movl $0x0, -0x4c(%rbp)
leaq -0x1050(%rbp), %rdi
xorl %esi, %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0x50a0
movq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movzbl 0x1d(%rax), %eax
movl %eax, -0x50(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x498(%rax)
je 0x16712
movq -0x10(%rbp), %rax
movq 0x498(%rax), %rax
cmpl $0x0, (%rax)
je 0x16712
leaq -0x1050(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x498(%rax), %rsi
addq $0x4, %rsi
movq -0x10(%rbp), %rax
movq 0x498(%rax), %rax
movslq (%rax), %rdx
callq 0x50b0
leaq -0x1050(%rbp), %rax
movq %rax, -0x30(%rbp)
movl $0x1000, -0x3c(%rbp)    # imm = 0x1000
movl $0x40000, -0x38(%rbp)   # imm = 0x40000
movb $0x4, -0x40(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x16ed0
movl %eax, -0x4c(%rbp)
cmpl $0x0, -0x4c(%rbp)
je 0x166dc
jmp 0x1669b
leaq 0xfbf7(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x166cf
movq 0xf92a(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
movl -0x4c(%rbp), %r8d
leaq 0x9396(%rip), %rsi      # 0x1fa52
leaq 0x93c2(%rip), %rdx      # 0x1fa85
movl $0x2fc, %ecx            # imm = 0x2FC
movb $0x0, %al
callq 0x5190
jmp 0x166d1
movl -0x4c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x16897
jmp 0x166de
leaq 0xfbb4(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1670e
movq 0xf8c7(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x939e(%rip), %rsi      # 0x1fa99
leaq 0x9383(%rip), %rdx      # 0x1fa85
movl $0x2ff, %ecx            # imm = 0x2FF
movb $0x0, %al
callq 0x5190
jmp 0x16710
jmp 0x16712
movl $0x1, -0x48(%rbp)
movl -0x48(%rbp), %ecx
xorl %eax, %eax
cmpl -0x50(%rbp), %ecx
movb %al, -0x1051(%rbp)
jge 0x16736
cmpl $0x0, -0x44(%rbp)
setne %al
movb %al, -0x1051(%rbp)
movb -0x1051(%rbp), %al
testb $0x1, %al
jne 0x16745
jmp 0x1688f
jmp 0x16747
leaq 0xfb4b(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1677b
movq 0xf85e(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movl -0x48(%rbp), %r8d
leaq 0x9361(%rip), %rsi      # 0x1fac9
leaq 0x9316(%rip), %rdx      # 0x1fa85
movl $0x303, %ecx            # imm = 0x303
movb $0x0, %al
callq 0x5190
jmp 0x1677d
movq -0x20(%rbp), %rax
addq $0x22, %rax
movslq -0x48(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x16ed0
movl %eax, -0x4c(%rbp)
cmpl $0x0, -0x4c(%rbp)
jne 0x167ec
jmp 0x167a8
leaq 0xfaea(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x167dc
movq 0xf7fd(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movl -0x48(%rbp), %r8d
leaq 0x9337(%rip), %rsi      # 0x1fb00
leaq 0x92b5(%rip), %rdx      # 0x1fa85
movl $0x307, %ecx            # imm = 0x307
movb $0x0, %al
callq 0x5190
jmp 0x167de
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x1688a
cmpl $-0xb, -0x4c(%rbp)
jne 0x16842
movl -0x44(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x44(%rbp)
leaq 0xfa97(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1683e
movq 0xf7ca(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
movl -0x48(%rbp), %r8d
movl -0x4c(%rbp), %r9d
movl $0x3, %eax
subl -0x44(%rbp), %eax
leaq 0x930e(%rip), %rsi      # 0x1fb36
leaq 0x9256(%rip), %rdx      # 0x1fa85
movl $0x30d, %ecx            # imm = 0x30D
movl %eax, (%rsp)
movb $0x0, %al
callq 0x5190
jmp 0x16840
jmp 0x16888
cmpl $0x0, -0x4c(%rbp)
jge 0x16886
jmp 0x1684a
leaq 0xfa48(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x16882
movq 0xf77b(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
movl -0x48(%rbp), %r8d
movl -0x4c(%rbp), %r9d
leaq 0x9311(%rip), %rsi      # 0x1fb80
leaq 0x920f(%rip), %rdx      # 0x1fa85
movl $0x310, %ecx            # imm = 0x310
movb $0x0, %al
callq 0x5190
jmp 0x16884
jmp 0x16891
jmp 0x16888
jmp 0x1688a
jmp 0x16719
jmp 0x16891
movl -0x4c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1060, %rsp           # imm = 0x1060
popq %rbp
retq
nopw %cs:(%rax,%rax)