// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1028, %rsp           # imm = 0x1028
movl %esi, %ebp
movq %rdi, %r12
movq 0x10(%rdi), %rdi
movq (%rdi), %rax
callq *0x70(%rax)
movq %rax, %r14
leaq 0x20(%rsp), %rbx
movl $0x1000, %edx           # imm = 0x1000
movq %rbx, %rdi
xorl %esi, %esi
callq 0x5080
leaq 0xbc4b(%rip), %rax      # 0x20291
cmpb $0x1, (%rax)
jne 0x1466f
movq 0xb966(%rip), %rax      # 0x1ffb8
movq (%rax), %rdi
leaq 0x4b0d(%rip), %rsi      # 0x19169
leaq 0x3b73(%rip), %rdx      # 0x181d6
movl $0xfc, %ecx
xorl %eax, %eax
callq 0x5180
movq 0x10(%r12), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
testb %al, %al
je 0x1472c
movq 0x10(%r12), %rdi
movq (%rdi), %rax
callq *0x38(%rax)
movq %rax, %r15
movq 0x10(%r12), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movl %eax, %eax
addq %rax, %r15
addq $0x40, %r15
movq 0x10(%r12), %rdi
movq (%rdi), %rax
callq *0xa0(%rax)
movslq %eax, %rdx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5090
leaq 0x8(%rsp), %rsi
movq %rbx, 0x10(%rsi)
movabsq $0x3e00000001000, %rax  # imm = 0x3E00000001000
movq %rax, 0x4(%rsi)
movb $0x4, (%rsi)
movq %r12, %rdi
callq 0x143a4
movl %eax, %r15d
leaq 0xbba2(%rip), %rax      # 0x20291
movb (%rax), %al
testl %r15d, %r15d
js 0x149ab
testb %al, %al
je 0x14722
movq 0xb8b3(%rip), %rax      # 0x1ffb8
movq (%rax), %rdi
leaq 0x4d15(%rip), %rsi      # 0x19424
leaq 0x3ac0(%rip), %rdx      # 0x181d6
movl $0x10c, %ecx            # imm = 0x10C
xorl %eax, %eax
callq 0x5180
movl $0x4e20, %edi           # imm = 0x4E20
callq 0x5170
movq %r12, %rbx
movq %r14, %r13
addq $0x42, %r13
pushq $0x1
popq %r12
movzbl 0x1d(%r14), %eax
cmpq %rax, %r12
jae 0x147de
movzbl (%r13), %r8d
cmpb %bpl, %r8b
jne 0x14787
leaq 0xbb38(%rip), %rax      # 0x20291
cmpb $0x1, (%rax)
jne 0x147d2
movq 0xb853(%rip), %rax      # 0x1ffb8
movq (%rax), %rdi
leaq 0x4ce5(%rip), %rsi      # 0x19454
leaq 0x3a60(%rip), %rdx      # 0x181d6
movl $0x113, %ecx            # imm = 0x113
movl %r12d, %r9d
xorl %eax, %eax
callq 0x5180
jmp 0x147d2
movq %rbx, %rdi
movq %r13, %rsi
callq 0x143a4
movl %eax, %r15d
leaq 0xbaf5(%rip), %rax      # 0x20291
movb (%rax), %al
testl %r15d, %r15d
js 0x14950
testb %al, %al
je 0x147d2
movq 0xb806(%rip), %rax      # 0x1ffb8
movq (%rax), %rdi
leaq 0x4d06(%rip), %rsi      # 0x194c2
leaq 0x3a13(%rip), %rdx      # 0x181d6
movl $0x11b, %ecx            # imm = 0x11B
movl %r12d, %r8d
xorl %eax, %eax
callq 0x5180
incq %r12
addq $0x18, %r13
jmp 0x1473a
leaq 0xbaac(%rip), %rax      # 0x20291
cmpb $0x1, (%rax)
jne 0x1480e
movq 0xb7c7(%rip), %rax      # 0x1ffb8
movq (%rax), %rdi
leaq 0x4d06(%rip), %rsi      # 0x19501
leaq 0x39d4(%rip), %rdx      # 0x181d6
movl $0x11f, %ecx            # imm = 0x11F
xorl %eax, %eax
callq 0x5180
leaq 0x7(%rsp), %rdx
movb $0x1, (%rdx)
movq %rbx, %r12
movq 0x8(%rbx), %rdi
movq (%rdi), %rax
pushq $0x13
popq %rsi
pushq $0x1
popq %rcx
callq *0x48(%rax)
testl %eax, %eax
js 0x1497d
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x5170
movq 0x8(%r12), %rdi
movq (%rdi), %rax
callq *0xa0(%rax)
movq 0x10(%r12), %rdi
movq (%rdi), %rax
callq *0x28(%rax)
movl %eax, %ebp
movq 0x10(%r12), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
movl %eax, %r14d
movq 0x10(%r12), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
testb %al, %al
jne 0x1488e
movq 0x8(%r12), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
andl $0xffffff00, %r14d      # imm = 0xFFFFFF00
movzbl %al, %eax
orl %eax, %r14d
movq 0x8(%r12), %rdi
movq (%rdi), %rax
callq *0x60(%rax)
cmpl %ebp, %eax
jne 0x148b4
movq 0x8(%r12), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
xorl %r15d, %r15d
cmpl %r14d, %eax
je 0x149af
leaq 0xb9d6(%rip), %rax      # 0x20291
movb (%rax), %al
cmpb $0x1, %al
je 0x149c4
testb $0x1, %al
je 0x14918
movq 0xb6e8(%rip), %rax      # 0x1ffb8
movq (%rax), %rbx
movq 0x8(%r12), %rdi
movq (%rdi), %rax
callq *0x60(%rax)
movl %eax, %r15d
movq 0x8(%r12), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
leaq 0x4800(%rip), %rsi      # 0x190f3
leaq 0x38dc(%rip), %rdx      # 0x181d6
movq %rbx, %rdi
movl $0x136, %ecx            # imm = 0x136
movl %r15d, %r8d
movl %eax, %r9d
xorl %eax, %eax
callq 0x5180
leaq 0xb97b(%rip), %rax      # 0x20291
movb (%rax), %al
pushq $-0x1
popq %r15
testb $0x1, %al
je 0x149af
movq 0xb68d(%rip), %rax      # 0x1ffb8
movq (%rax), %rdi
leaq 0x47e6(%rip), %rsi      # 0x1911b
leaq 0x389a(%rip), %rdx      # 0x181d6
movl $0x137, %ecx            # imm = 0x137
movl %ebp, %r8d
movl %r14d, %r9d
xorl %eax, %eax
callq 0x5180
jmp 0x149af
testb %al, %al
je 0x149af
movq 0xb67d(%rip), %rax      # 0x1ffd8
movq (%rax), %rdi
leaq 0x4b1f(%rip), %rsi      # 0x19484
leaq 0x386a(%rip), %rdx      # 0x181d6
movl $0x118, %ecx            # imm = 0x118
movl %r12d, %r8d
xorl %eax, %eax
callq 0x5180
jmp 0x149af
movl %eax, %r15d
leaq 0xb90a(%rip), %rax      # 0x20291
cmpb $0x1, (%rax)
jne 0x149af
movq 0xb645(%rip), %rax      # 0x1ffd8
movq (%rax), %rdi
leaq 0x4b7f(%rip), %rsi      # 0x1951c
leaq 0x3832(%rip), %rdx      # 0x181d6
movl $0x123, %ecx            # imm = 0x123
jmp 0x14a13
testb %al, %al
jne 0x149f6
movl %r15d, %eax
addq $0x1028, %rsp           # imm = 0x1028
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xb60d(%rip), %rax      # 0x1ffd8
movq (%rax), %rdi
leaq 0x4b69(%rip), %rsi      # 0x1953e
leaq 0x37fa(%rip), %rdx      # 0x181d6
movl $0x134, %ecx            # imm = 0x134
xorl %eax, %eax
callq 0x5180
leaq 0xb8a2(%rip), %rax      # 0x20291
movb (%rax), %al
jmp 0x148c5
movq 0xb5db(%rip), %rax      # 0x1ffd8
movq (%rax), %rdi
leaq 0x49ee(%rip), %rsi      # 0x193f5
leaq 0x37c8(%rip), %rdx      # 0x181d6
movl $0x109, %ecx            # imm = 0x109
xorl %eax, %eax
callq 0x5180
jmp 0x149af