// File: goodix[P]gdix_hid_firmware_update/berlin_a/brla_update.cpp
// Function: BrlAUpdate::fw_update(unsigned int)
int BrlAUpdate::fw_update(unsigned int firmware_flag)
{
	struct firmware_summary_a *fw_info =
		(struct firmware_summary_a *)image->GetFirmwareSummary();
	struct fw_subsys_info_a *fw_x;
	struct fw_subsys_info_a subsys_cfg;
	int i;
	int ret;
	uint8_t buf[1];
	int minorVer;
	int majorVer;
	uint8_t cfgVer;
	uint8_t temp_buf[CFG_MAX_SIZE] = {0};

	gdix_info("IN\n");
	/* flash config */
	if (image->HasConfig()) {
		memcpy(temp_buf,
			   image->GetFirmwareData() + image->GetFirmwareSize() + 64,
			   image->GetConfigSize());

		subsys_cfg.data = temp_buf;
		subsys_cfg.size = CFG_MAX_SIZE;
		subsys_cfg.flash_addr = 0x3E000;
		subsys_cfg.type = 4;
		ret = flashSubSystem(&subsys_cfg);
		if (ret < 0) {
			gdix_err("failed flash config with ISP\n");
			return ret;
		}
		gdix_info("success flash config with ISP\n");
		usleep(20000);
	}

	for (i = 1; i < fw_info->subsys_num; i++) {
		fw_x = &fw_info->subsys[i];
		if (fw_x->type == (uint8_t)firmware_flag) {
			gdix_info("skip type[%02X] subsystem[%d]\n", fw_x->type, i);
			continue;
		}
		ret = flashSubSystem(fw_x);
		if (ret < 0) {
			gdix_err("-------- Failed flash subsystem %d --------\n", i);
			return ret;
		}
		gdix_info("-------- Success flash subsystem %d --------\n", i);
	}

	/* reset IC */
	gdix_info("Reset IC\n");
	buf[0] = 1;
	ret = dev->SendCmd(0x13, buf, 1);
	if (ret < 0) {
		gdix_err("Failed reset IC\n");
		return ret;
	}
	usleep(100000);

	/* compare version */
	dev->SetBasicProperties();
	majorVer = image->GetFirmwareVersionMajor();
	minorVer = image->GetFirmwareVersionMinor();
	if (image->HasConfig() == false) {
		cfgVer = (uint8_t)dev->GetFirmwareVersionMinor();
		minorVer &= 0xffffff00;
		minorVer |= cfgVer;
	}

	if ((dev->GetFirmwareVersionMajor() != majorVer) ||
		(dev->GetFirmwareVersionMinor() != minorVer)) {
		gdix_err("update failed\n");
		gdix_info("Current version:%d.%d\n", dev->GetFirmwareVersionMajor(),
				  dev->GetFirmwareVersionMinor());
		gdix_info("Firmware version:%d.%d\n", majorVer, minorVer);
		return -1;
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1090, %rsp           # imm = 0x1090
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1068(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x70(%rax)
movq %rax, -0x20(%rbp)
leaq -0x1060(%rbp), %rdi
xorl %esi, %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0x50a0
leaq 0xb124(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b19e
movq 0xae37(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x5024(%rip), %rsi      # 0x201af
leaq 0x406a(%rip), %rdx      # 0x1f1fc
movl $0xfc, %ecx
movb $0x0, %al
callq 0x5190
jmp 0x1b1a0
movq -0x1068(%rbp), %rax
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
testb $0x1, %al
jne 0x1b1bd
jmp 0x1b2ed
movq -0x1068(%rbp), %rax
leaq -0x1060(%rbp), %rcx
movq %rcx, -0x1078(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x38(%rax)
movq %rax, %rcx
movq -0x1068(%rbp), %rax
movq %rcx, -0x1080(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq -0x1080(%rbp), %rcx
movl %eax, %edx
movq -0x1068(%rbp), %rax
movl %edx, %edx
addq %rdx, %rcx
addq $0x40, %rcx
movq %rcx, -0x1070(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0xa0(%rax)
movq -0x1078(%rbp), %rdi
movq -0x1070(%rbp), %rsi
movslq %eax, %rdx
callq 0x50b0
movq -0x1068(%rbp), %rdi
leaq -0x1060(%rbp), %rax
movq %rax, -0x30(%rbp)
movl $0x1000, -0x3c(%rbp)    # imm = 0x1000
movl $0x3e000, -0x38(%rbp)   # imm = 0x3E000
movb $0x4, -0x40(%rbp)
leaq -0x40(%rbp), %rsi
callq 0x1adf0
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jge 0x1b2af
jmp 0x1b272
leaq 0xb020(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b2a2
movq 0xad53(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
leaq 0x51ac(%rip), %rsi      # 0x2043b
leaq 0x3f66(%rip), %rdx      # 0x1f1fc
movl $0x109, %ecx            # imm = 0x109
movb $0x0, %al
callq 0x5190
jmp 0x1b2a4
movl -0x48(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1b66e
jmp 0x1b2b1
leaq 0xafe1(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b2e1
movq 0xacf4(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x519c(%rip), %rsi      # 0x2046a
leaq 0x3f27(%rip), %rdx      # 0x1f1fc
movl $0x10c, %ecx            # imm = 0x10C
movb $0x0, %al
callq 0x5190
jmp 0x1b2e3
movl $0x4e20, %edi           # imm = 0x4E20
callq 0x5180
movl $0x1, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x20(%rbp), %rcx
movzbl 0x1d(%rcx), %ecx
cmpl %ecx, %eax
jge 0x1b418
movq -0x20(%rbp), %rax
addq $0x2a, %rax
movslq -0x44(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
movl -0x14(%rbp), %ecx
movzbl %cl, %ecx
cmpl %ecx, %eax
jne 0x1b374
jmp 0x1b331
leaq 0xaf61(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b36d
movq 0xac74(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movq -0x28(%rbp), %rax
movzbl (%rax), %r8d
movl -0x44(%rbp), %r9d
leaq 0x5140(%rip), %rsi      # 0x2049a
leaq 0x3e9b(%rip), %rdx      # 0x1f1fc
movl $0x113, %ecx            # imm = 0x113
movb $0x0, %al
callq 0x5190
jmp 0x1b36f
jmp 0x1b40a
movq -0x1068(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x1adf0
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jge 0x1b3d0
jmp 0x1b38f
leaq 0xaf03(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b3c3
movq 0xac36(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
movl -0x44(%rbp), %r8d
leaq 0x511a(%rip), %rsi      # 0x204ca
leaq 0x3e45(%rip), %rdx      # 0x1f1fc
movl $0x118, %ecx            # imm = 0x118
movb $0x0, %al
callq 0x5190
jmp 0x1b3c5
movl -0x48(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1b66e
jmp 0x1b3d2
leaq 0xaec0(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b406
movq 0xabd3(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movl -0x44(%rbp), %r8d
leaq 0x5115(%rip), %rsi      # 0x20508
leaq 0x3e02(%rip), %rdx      # 0x1f1fc
movl $0x11b, %ecx            # imm = 0x11B
movb $0x0, %al
callq 0x5190
jmp 0x1b408
jmp 0x1b40a
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x1b2f4
jmp 0x1b41a
leaq 0xae78(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b44a
movq 0xab8b(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x5110(%rip), %rsi      # 0x20547
leaq 0x3dbe(%rip), %rdx      # 0x1f1fc
movl $0x11f, %ecx            # imm = 0x11F
movb $0x0, %al
callq 0x5190
jmp 0x1b44c
movq -0x1068(%rbp), %rax
movb $0x1, -0x49(%rbp)
movq 0x8(%rax), %rdi
leaq -0x49(%rbp), %rdx
movq (%rdi), %rax
movl $0x13, %esi
movl $0x1, %ecx
callq *0x48(%rax)
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jge 0x1b4b7
jmp 0x1b47a
leaq 0xae18(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b4aa
movq 0xab4b(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
leaq 0x50cb(%rip), %rsi      # 0x20562
leaq 0x3d5e(%rip), %rdx      # 0x1f1fc
movl $0x123, %ecx            # imm = 0x123
movb $0x0, %al
callq 0x5190
jmp 0x1b4ac
movl -0x48(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1b66e
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x5180
movq -0x1068(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0xa0(%rax)
movq -0x1068(%rbp), %rax
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x28(%rax)
movl %eax, %ecx
movq -0x1068(%rbp), %rax
movl %ecx, -0x54(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
movl %eax, %ecx
movq -0x1068(%rbp), %rax
movl %ecx, -0x50(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x1b548
movq -0x1068(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
movb %al, -0x55(%rbp)
movl -0x50(%rbp), %eax
andl $0xffffff00, %eax       # imm = 0xFFFFFF00
movl %eax, -0x50(%rbp)
movzbl -0x55(%rbp), %eax
orl -0x50(%rbp), %eax
movl %eax, -0x50(%rbp)
movq -0x1068(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x60(%rax)
cmpl -0x54(%rbp), %eax
jne 0x1b578
movq -0x1068(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
cmpl -0x50(%rbp), %eax
je 0x1b667
jmp 0x1b57a
leaq 0xad18(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b5aa
movq 0xaa4b(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
leaq 0x4fed(%rip), %rsi      # 0x20584
leaq 0x3c5e(%rip), %rdx      # 0x1f1fc
movl $0x134, %ecx            # imm = 0x134
movb $0x0, %al
callq 0x5190
jmp 0x1b5ac
jmp 0x1b5ae
leaq 0xace4(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b620
movq -0x1068(%rbp), %rax
movq 0xa9f0(%rip), %rcx      # 0x25fb8
movq (%rcx), %rcx
movq %rcx, -0x1090(%rbp)
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x60(%rax)
movl %eax, %ecx
movq -0x1068(%rbp), %rax
movl %ecx, -0x1084(%rbp)
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
movq -0x1090(%rbp), %rdi
movl -0x1084(%rbp), %r8d
movl %eax, %r9d
leaq 0x4b2c(%rip), %rsi      # 0x20139
leaq 0x3be8(%rip), %rdx      # 0x1f1fc
movl $0x136, %ecx            # imm = 0x136
movb $0x0, %al
callq 0x5190
jmp 0x1b622
jmp 0x1b624
leaq 0xac6e(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1b65c
movq 0xa981(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movl -0x54(%rbp), %r8d
movl -0x50(%rbp), %r9d
leaq 0x4b18(%rip), %rsi      # 0x20161
leaq 0x3bac(%rip), %rdx      # 0x1f1fc
movl $0x137, %ecx            # imm = 0x137
movb $0x0, %al
callq 0x5190
jmp 0x1b65e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1b66e
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1090, %rsp           # imm = 0x1090
popq %rbp
retq
nopw (%rax,%rax)