// File: goodix[P]gdix_hid_firmware_update/gtx9/gtx9_i2c_update.cpp
// Function: gdix_update_prepare(fw_update_ctrl*)
static int gdix_update_prepare(struct fw_update_ctrl *fwu_ctrl)
{
	uint8_t reg_val[4] = {0};
	uint8_t temp_buf[64] = {0};
	int retry = 20;
	int r;

	/* reset IC */
	gdix_dbg("firmware update, reset\n");
	gdix_soft_reset(5);

	retry = 100;
	/* Hold cpu*/
	do {
		reg_val[0] = 0x01;
		reg_val[1] = 0x00;
		r = i2c_write(0x0002, reg_val, 2);
		r |= i2c_read(0x2000, &temp_buf[0], 4);
		r |= i2c_read(0x2000, &temp_buf[4], 4);
		r |= i2c_read(0x2000, &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)) {
			break;
		}
		usleep(1000);
		gdix_dbg("retry hold cpu %d\n", retry);
	} while (--retry);
	if (!retry) {
		gdix_err("Failed to hold CPU, return = %d\n", r);
		return -1;
	}
	gdix_dbg("Success hold CPU\n");

	/* enable misctl clock */
	reg_val[0] = 0x40;
	i2c_write(0xD80B, reg_val, 1);
	gdix_dbg("enbale misctl clock\n");

	/* disable watch dog */
	reg_val[0] = 0x00;
	r = i2c_write(0xD054, reg_val, 1);
	gdix_dbg("disable watch dog\n");

	/* load ISP code and run form isp */
	r = gdix_load_isp(&fwu_ctrl->fw_data);
	if (r < 0)
		gdix_err("Failed load and run isp\n");

	return r;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
leaq -0x14(%rbp), %rdi
xorl %esi, %esi
movl $0x4, %edx
callq 0x50a0
leaq -0x60(%rbp), %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x50a0
movl $0x14, -0x64(%rbp)
leaq 0xffaf(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x16313
movq 0xfcc2(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x94c0(%rip), %rsi      # 0x1f7c0
leaq 0x94e2(%rip), %rdx      # 0x1f7e9
movl $0x210, %ecx            # imm = 0x210
movb $0x0, %al
callq 0x5190
jmp 0x16315
movl $0x5, %edi
callq 0x16bd0
movl $0x64, -0x64(%rbp)
movb $0x1, -0x14(%rbp)
movb $0x0, -0x13(%rbp)
leaq -0x14(%rbp), %rsi
movl $0x2, %edx
movl %edx, %edi
callq 0x15870
movl %eax, -0x68(%rbp)
leaq -0x60(%rbp), %rsi
movl $0x2000, %edi           # imm = 0x2000
movl $0x4, %edx
callq 0x168d0
orl -0x68(%rbp), %eax
movl %eax, -0x68(%rbp)
leaq -0x60(%rbp), %rsi
addq $0x4, %rsi
movl $0x2000, %edi           # imm = 0x2000
movl $0x4, %edx
callq 0x168d0
orl -0x68(%rbp), %eax
movl %eax, -0x68(%rbp)
leaq -0x60(%rbp), %rsi
addq $0x8, %rsi
movl $0x2000, %edi           # imm = 0x2000
movl $0x4, %edx
callq 0x168d0
orl -0x68(%rbp), %eax
movl %eax, -0x68(%rbp)
cmpl $0x0, -0x68(%rbp)
jne 0x163f7
leaq -0x60(%rbp), %rax
leaq -0x60(%rbp), %rcx
addq $0x4, %rcx
movl (%rcx), %ecx
movl (%rax), %eax
subl %ecx, %eax
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x163f7
leaq -0x60(%rbp), %rax
addq $0x4, %rax
leaq -0x60(%rbp), %rcx
addq $0x8, %rcx
movl (%rcx), %ecx
movl (%rax), %eax
subl %ecx, %eax
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x163f7
leaq -0x60(%rbp), %rax
leaq -0x60(%rbp), %rcx
addq $0x8, %rcx
movl (%rcx), %ecx
movl (%rax), %eax
subl %ecx, %eax
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x163f7
jmp 0x1644b
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x5180
leaq 0xfe91(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x16435
movq 0xfba4(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movl -0x64(%rbp), %r8d
leaq 0x93db(%rip), %rsi      # 0x1f7fd
leaq 0x93c0(%rip), %rdx      # 0x1f7e9
movl $0x222, %ecx            # imm = 0x222
movb $0x0, %al
callq 0x5190
jmp 0x16437
jmp 0x16439
movl -0x64(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x64(%rbp)
cmpl $0x0, %eax
jne 0x16326
cmpl $0x0, -0x64(%rbp)
jne 0x16495
jmp 0x16453
leaq 0xfe3f(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x16487
movq 0xfb72(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
movl -0x68(%rbp), %r8d
leaq 0x93ad(%rip), %rsi      # 0x1f821
leaq 0x936e(%rip), %rdx      # 0x1f7e9
movl $0x225, %ecx            # imm = 0x225
movb $0x0, %al
callq 0x5190
jmp 0x16489
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x165ac
jmp 0x16497
leaq 0xfdfb(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x164c7
movq 0xfb0e(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x939f(%rip), %rsi      # 0x1f853
leaq 0x932e(%rip), %rdx      # 0x1f7e9
movl $0x228, %ecx            # imm = 0x228
movb $0x0, %al
callq 0x5190
jmp 0x164c9
movb $0x40, -0x14(%rbp)
leaq -0x14(%rbp), %rsi
movl $0xd80b, %edi           # imm = 0xD80B
movl $0x1, %edx
callq 0x15870
leaq 0xfdb2(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x16510
movq 0xfac5(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x9379(%rip), %rsi      # 0x1f876
leaq 0x92e5(%rip), %rdx      # 0x1f7e9
movl $0x22d, %ecx            # imm = 0x22D
movb $0x0, %al
callq 0x5190
jmp 0x16512
movb $0x0, -0x14(%rbp)
leaq -0x14(%rbp), %rsi
movl $0xd054, %edi           # imm = 0xD054
movl $0x1, %edx
callq 0x15870
movl %eax, -0x68(%rbp)
leaq 0xfd66(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1655c
movq 0xfa79(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x9353(%rip), %rsi      # 0x1f89c
leaq 0x9299(%rip), %rdx      # 0x1f7e9
movl $0x232, %ecx            # imm = 0x232
movb $0x0, %al
callq 0x5190
jmp 0x1655e
movq -0x10(%rbp), %rdi
callq 0x16c10
movl %eax, -0x68(%rbp)
cmpl $0x0, -0x68(%rbp)
jge 0x165a6
jmp 0x16572
leaq 0xfd20(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x165a2
movq 0xfa53(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
leaq 0x9331(%rip), %rsi      # 0x1f8c0
leaq 0x9253(%rip), %rdx      # 0x1f7e9
movl $0x237, %ecx            # imm = 0x237
movb $0x0, %al
callq 0x5190
jmp 0x165a4
jmp 0x165a6
movl -0x68(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)