// File: /workspace/github_cpp_makefile_star2_O2/goodix[P]gdix_hid_firmware_update/gtx8/gtx8_update.cpp
// Function: GTx8Update::cfg_update()
int GTx8Update::cfg_update()
{
	int retry;
	int ret = -1, i;
	unsigned char temp_buf[65];
	unsigned char *fw_data = NULL;
	unsigned char cfg_ver_after[3];
	unsigned char cfg_ver_before[3];
	unsigned char cfg_ver_infile;
	bool findMatchCfg = false;
	unsigned char *cfg = NULL;

	int sub_cfg_num = image->GetConfigSubCfgNum();
	unsigned char sub_cfg_id;
	unsigned int sub_cfg_len;
	unsigned int sub_cfg_info_pos = image->GetConfigSubCfgInfoOffset();
	unsigned int cfg_offset = image->GetConfigSubCfgDataOffset();

	if (sub_cfg_num == 0)
		return -5;

	// before update config,read curr config version
	dev->Read(CFG_START_ADDR, cfg_ver_before, 3);
	gdix_dbg("Before update,cfg version is 0x%02x 0x%02x 0x%02x\n",
			 cfg_ver_before[0], cfg_ver_before[1], cfg_ver_before[2]);

	/* Start load config */
	fw_data = image->GetFirmwareData();
	if (!fw_data) {
		gdix_err("No valid fw data \n");
		ret = -4;
		goto update_err;
	}

	// fw_data[FW_IMAGE_SUB_FWNUM_OFFSET];
	gdix_dbg("load sub config, sub_cfg_num=%d\n", sub_cfg_num);
	for (i = 0; i < sub_cfg_num; i++) {
		sub_cfg_id = fw_data[sub_cfg_info_pos];
		gdix_dbg("load sub config, sub_cfg_id=0x%x\n", sub_cfg_id);

		sub_cfg_len = (fw_data[sub_cfg_info_pos + 1] << 8) |
					  fw_data[sub_cfg_info_pos + 2];

		if (dev->GetSensorID() == sub_cfg_id) {
			findMatchCfg = true;
			cfg = &fw_data[cfg_offset];
			cfg_ver_infile = cfg[0];
			gdix_info("Find a cfg match sensorID:ID=%d, cfg version=%d\n",
					  dev->GetSensorID(), cfg_ver_infile);
			break;
		}
		cfg_offset += sub_cfg_len;
		sub_cfg_info_pos += 3;
	}

	if (findMatchCfg) {
		// wait untill ic is free
		retry = 10;
		do {
			ret = dev->Read(CMD_ADDR, temp_buf, 1);
			if (ret < 0) {
				gdix_err("Failed read cfg cmd, ret = %d\n", ret);
				return ret;
			}
			if (temp_buf[0] == 0xff)
				break;
			gdix_info("0x%x value is 0x%x != 0xff, retry\n", CMD_ADDR,
					  temp_buf[0]);
			usleep(10000);
		} while (--retry);
		if (!retry) {
			gdix_err("Reg 0x%x != 0xff\n", CMD_ADDR);
			ret = -2;
			goto update_err;
		}

		// tell ic i want to send cfg
		temp_buf[0] = 0x80;
		temp_buf[1] = 0;
		temp_buf[2] = 0x80;
		ret = dev->Write(CMD_ADDR, temp_buf, 3);
		if (ret < 0) {
			gdix_err("Failed write send cfg cmd\n");
			return ret;
		}

		// wait ic to comfirm
		usleep(250000);
		retry = GDIX_RETRY_TIMES;
		do {
			ret = dev->Read(CMD_ADDR, temp_buf, 1);
			gdix_dbg("Wait CMD_ADDR == 0x82...\n");
			if (ret < 0) {
				gdix_err("Failed read 0x%x, ret = %d\n", CMD_ADDR, ret);
			}
			if (temp_buf[0] == 0x82)
				break;
			gdix_info("0x%x value is 0x%x != 0x82, retry\n", CMD_ADDR,
					  temp_buf[0]);
			usleep(30000);
		} while (--retry);

		if (!retry) {
			gdix_err("Reg 0x%x != 0x82\n", CMD_ADDR);
			ret = -2;
			goto update_err;
		}
		gdix_dbg("Wait CMD_ADDR == 0x82 success.\n");

		/* Start load config */
		ret = dev->Write(CFG_START_ADDR, &fw_data[cfg_offset], sub_cfg_len);
		if (ret < 0) {
			gdix_err("Failed write cfg to xdata, ret=%d\n", ret);
			goto update_err;
		}
		usleep(100000);

		// tell ic cfg is ready in xdata
		temp_buf[0] = 0x83;
		ret = dev->Write(CMD_ADDR, temp_buf, 1);
		if (ret < 0) {
			gdix_err("Failed write send cfg finish cmd\n");
			return ret;
		}

		// check if ic is ok with the cfg
		usleep(80000);
		retry = GDIX_RETRY_TIMES;
		do {
			ret = dev->Read(CMD_ADDR, temp_buf, 1);
			gdix_dbg("Wait CMD_ADDR == 0xFF...\n");
			if (ret < 0) {
				gdix_err("Failed read 0x%x, ret = %d\n", CMD_ADDR, ret);
			}
			if (temp_buf[0] == 0xff)
				break;
			gdix_info("0x%x value is 0x%x != 0xFF, retry\n", CMD_ADDR,
					  temp_buf[0]);
			usleep(30000);
		} while (--retry);

		if (!retry) {
			gdix_err("Reg 0x%x != 0xFF\n", CMD_ADDR);
			ret = -2;
			goto update_err;
		}
		gdix_dbg("Wait CMD_ADDR == 0xFF success.\n");

		// before update config,read curr config version
		dev->Read(CFG_START_ADDR, cfg_ver_after, 3);
		gdix_dbg("After update,cfg version is 0x%02x 0x%02x 0x%02x\n",
				 cfg_ver_after[0], cfg_ver_after[1], cfg_ver_after[2]);

		return 0;
	}
update_err:
	return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdi, %r14
movq 0x10(%rdi), %rdi
movq (%rdi), %rax
callq *0x78(%rax)
movl %eax, %r12d
movq 0x10(%r14), %rdi
movq (%rdi), %rax
callq *0x80(%rax)
movl %eax, %r13d
movq 0x10(%r14), %rdi
movq (%rdi), %rax
callq *0x88(%rax)
testl %r12d, %r12d
je 0xe702
movl %eax, %ebx
movq 0x8(%r14), %rdi
movq (%rdi), %rax
leaq 0xa(%rsp), %rdx
pushq $0x3
popq %rcx
movl $0x60dc, %esi           # imm = 0x60DC
callq *0x20(%rax)
leaq 0x11ca1(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe62d
movq 0x119bc(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
movzbl 0xa(%rsp), %r8d
movzbl 0xb(%rsp), %r9d
movzbl 0xc(%rsp), %eax
movl %eax, (%rsp)
leaq 0x8084(%rip), %rsi      # 0x1669e
leaq 0x8072(%rip), %rdx      # 0x16693
movl $0x1a7, %ecx            # imm = 0x1A7
xorl %eax, %eax
callq 0x5180
movq %r14, 0x10(%rsp)
movq 0x10(%r14), %rdi
movq (%rdi), %rax
callq *0x38(%rax)
movq %rax, %r14
leaq 0x11c4b(%rip), %rax     # 0x20291
movb (%rax), %al
testq %r14, %r14
je 0xe706
testb %al, %al
je 0xe67c
movq 0x1195c(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
leaq 0x7ea9(%rip), %rsi      # 0x1650f
leaq 0x8026(%rip), %rdx      # 0x16693
movl $0x1b2, %ecx            # imm = 0x1B2
movl %r12d, %r8d
xorl %eax, %eax
callq 0x5180
xorl %eax, %eax
testl %r12d, %r12d
cmovlel %eax, %r12d
subl $0x1, %r12d
jb 0xe733
movl %r13d, %eax
movzbl (%r14,%rax), %ebp
leaq 0x11bf3(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe6ca
movq 0x1190e(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
leaq 0x7e8d(%rip), %rsi      # 0x16541
leaq 0x7fd8(%rip), %rdx      # 0x16693
movl $0x1b5, %ecx            # imm = 0x1B5
movl %ebp, %r8d
xorl %eax, %eax
callq 0x5180
leal 0x1(%r13), %eax
movzbl (%r14,%rax), %eax
shll $0x8, %eax
leal 0x2(%r13), %ecx
movzbl (%r14,%rcx), %r15d
orl %eax, %r15d
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x80(%rax)
cmpb %bpl, %al
je 0xe747
addl %r15d, %ebx
addl $0x3, %r13d
jmp 0xe685
pushq $-0x5
jmp 0xe735
pushq $-0x4
popq %rbp
testb %al, %al
je 0xe736
movq 0x118c4(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x7ba1(%rip), %rsi      # 0x162bf
leaq 0x7f6e(%rip), %rdx      # 0x16693
movl $0x1ac, %ecx            # imm = 0x1AC
xorl %eax, %eax
callq 0x5180
jmp 0xe736
pushq $-0x1
popq %rbp
movl %ebp, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x11b43(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
movl %ebx, %r13d
jne 0xe79b
movzbl (%r14,%r13), %ebx
movq 0x11856(%rip), %rax     # 0x1ffb8
movq (%rax), %r12
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x80(%rax)
movzbl %al, %r8d
leaq 0x91e6(%rip), %rsi      # 0x17968
leaq 0x7f0a(%rip), %rdx      # 0x16693
movq %r12, %rdi
movl $0x1bf, %ecx            # imm = 0x1BF
movl %ebx, %r9d
xorl %eax, %eax
callq 0x5180
movq %r13, 0x18(%rsp)
pushq $-0xa
popq %rbp
leaq 0x20(%rsp), %rbx
pushq $0x1
popq %r12
leaq 0x7ee0(%rip), %r13      # 0x16693
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
movl $0x60cc, %esi           # imm = 0x60CC
movq %rbx, %rdx
movl %r12d, %ecx
callq *0x20(%rax)
testl %eax, %eax
js 0xe85d
movzbl 0x20(%rsp), %r9d
cmpl $0xff, %r9d
je 0xe894
leaq 0x11aa2(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe81a
movq 0x117bd(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
leaq 0x7f4e(%rip), %rsi      # 0x16753
movq %r13, %rdx
movl $0x1d2, %ecx            # imm = 0x1D2
movl $0x60cc, %r8d           # imm = 0x60CC
xorl %eax, %eax
callq 0x5180
movl $0x2710, %edi           # imm = 0x2710
callq 0x5170
incl %ebp
jne 0xe7b3
pushq $-0x2
popq %rbp
leaq 0x11a5f(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe736
movq 0x11796(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x7f3b(%rip), %rsi      # 0x16787
leaq 0x7e40(%rip), %rdx      # 0x16693
movl $0x1d6, %ecx            # imm = 0x1D6
jmp 0xeba2
movl %eax, %ebp
leaq 0x11a2b(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe736
movq 0x11762(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x7ea3(%rip), %rsi      # 0x16723
leaq 0x7e0c(%rip), %rdx      # 0x16693
movl $0x1cc, %ecx            # imm = 0x1CC
movl %ebp, %r8d
jmp 0xeba8
leaq 0x20(%rsp), %rdx
movw $0x80, (%rdx)
movb $-0x80, 0x2(%rdx)
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
pushq $0x3
popq %rcx
movl $0x60cc, %esi           # imm = 0x60CC
callq *0x30(%rax)
testl %eax, %eax
js 0xe9be
movl $0x3d090, %edi          # imm = 0x3D090
callq 0x5170
pushq $-0x6
popq %rbx
pushq $0x1
popq %rbp
leaq 0x7dbb(%rip), %r13      # 0x16693
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
movl $0x60cc, %esi           # imm = 0x60CC
leaq 0x20(%rsp), %rdx
movl %ebp, %ecx
callq *0x20(%rax)
movl %eax, %r12d
leaq 0x11994(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe922
movq 0x116af(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
leaq 0x7ec3(%rip), %rsi      # 0x167d6
movq %r13, %rdx
movl $0x1ea, %ecx            # imm = 0x1EA
xorl %eax, %eax
callq 0x5180
testl %r12d, %r12d
jns 0xe933
leaq 0x11963(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
je 0xe990
movzbl 0x20(%rsp), %r9d
leaq 0x11951(%rip), %rax     # 0x20291
movb (%rax), %al
cmpl $0x82, %r9d
je 0xe9f2
testb %al, %al
je 0xe979
movq 0x1165e(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
leaq 0x7e9d(%rip), %rsi      # 0x16801
movq %r13, %rdx
movl $0x1f1, %ecx            # imm = 0x1F1
movl $0x60cc, %r8d           # imm = 0x60CC
xorl %eax, %eax
callq 0x5180
movl $0x7530, %edi           # imm = 0x7530
callq 0x5170
incl %ebx
jne 0xe8d8
jmp 0xeb72
movq 0x11641(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x786c(%rip), %rsi      # 0x1620d
movq %r13, %rdx
movl $0x1ec, %ecx            # imm = 0x1EC
movl $0x60cc, %r8d           # imm = 0x60CC
movl %r12d, %r9d
xorl %eax, %eax
callq 0x5180
jmp 0xe933
movl %eax, %ebp
leaq 0x118ca(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe736
movq 0x11601(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x7dc9(%rip), %rsi      # 0x167aa
leaq 0x7cab(%rip), %rdx      # 0x16693
movl $0x1e1, %ecx            # imm = 0x1E1
jmp 0xe72a
testb %al, %al
je 0xea1a
movq 0x115bb(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
leaq 0x7e51(%rip), %rsi      # 0x16858
leaq 0x7c85(%rip), %rdx      # 0x16693
movl $0x1fa, %ecx            # imm = 0x1FA
xorl %eax, %eax
callq 0x5180
movq 0x10(%rsp), %rbx
movq 0x8(%rbx), %rdi
addq 0x18(%rsp), %r14
movq (%rdi), %rax
movl $0x60dc, %esi           # imm = 0x60DC
movq %r14, %rdx
movl %r15d, %ecx
callq *0x30(%rax)
testl %eax, %eax
js 0xebb4
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x5170
leaq 0x20(%rsp), %rdx
movb $-0x7d, (%rdx)
movq 0x8(%rbx), %rdi
movq (%rdi), %rax
pushq $0x1
popq %rcx
movl $0x60cc, %esi           # imm = 0x60CC
callq *0x30(%rax)
testl %eax, %eax
js 0xebe8
movl $0x13880, %edi          # imm = 0x13880
callq 0x5170
pushq $-0x6
popq %r14
leaq 0x20(%rsp), %rbx
pushq $0x1
popq %rbp
leaq 0x7c09(%rip), %r15      # 0x16693
leaq 0x87b6(%rip), %r13      # 0x17247
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
movl $0x60cc, %esi           # imm = 0x60CC
movq %rbx, %rdx
movl %ebp, %ecx
callq *0x20(%rax)
movl %eax, %r12d
leaq 0x117dd(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xead9
movq 0x114f8(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
leaq 0x8ee0(%rip), %rsi      # 0x179aa
movq %r15, %rdx
movl $0x211, %ecx            # imm = 0x211
xorl %eax, %eax
callq 0x5180
testl %r12d, %r12d
jns 0xeaea
leaq 0x117ac(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
je 0xeb44
movzbl 0x20(%rsp), %r9d
leaq 0x1179a(%rip), %rax     # 0x20291
movb (%rax), %al
cmpl $0xff, %r9d
je 0xec1c
testb %al, %al
je 0xeb2c
movq 0x114a7(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
movq %r13, %rsi
movq %r15, %rdx
movl $0x218, %ecx            # imm = 0x218
movl $0x60cc, %r8d           # imm = 0x60CC
xorl %eax, %eax
callq 0x5180
movl $0x7530, %edi           # imm = 0x7530
callq 0x5170
incl %r14d
jne 0xea91
jmp 0xecb1
movq 0x1148d(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x76b8(%rip), %rsi      # 0x1620d
movq %r15, %rdx
movl $0x213, %ecx            # imm = 0x213
movl $0x60cc, %r8d           # imm = 0x60CC
movl %r12d, %r9d
xorl %eax, %eax
callq 0x5180
jmp 0xeaea
pushq $-0x2
popq %rbp
leaq 0x11715(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe736
movq 0x1144c(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x7c9f(%rip), %rsi      # 0x16835
leaq 0x7af6(%rip), %rdx      # 0x16693
movl $0x1f6, %ecx            # imm = 0x1F6
movl $0x60cc, %r8d           # imm = 0x60CC
xorl %eax, %eax
callq 0x5180
jmp 0xe736
movl %eax, %ebp
leaq 0x116d4(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe736
movq 0x1140b(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x7cb2(%rip), %rsi      # 0x16889
leaq 0x7ab5(%rip), %rdx      # 0x16693
movl $0x1ff, %ecx            # imm = 0x1FF
jmp 0xe88c
movl %eax, %ebp
leaq 0x116a0(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe736
movq 0x113d7(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x7cb2(%rip), %rsi      # 0x168bd
leaq 0x7a81(%rip), %rdx      # 0x16693
movl $0x208, %ecx            # imm = 0x208
jmp 0xe72a
testb %al, %al
je 0xec44
movq 0x11391(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
leaq 0x8da4(%rip), %rsi      # 0x179d5
leaq 0x7a5b(%rip), %rdx      # 0x16693
movl $0x221, %ecx            # imm = 0x221
xorl %eax, %eax
callq 0x5180
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
leaq 0xd(%rsp), %rdx
pushq $0x3
popq %rcx
movl $0x60dc, %esi           # imm = 0x60DC
callq *0x20(%rax)
xorl %ebp, %ebp
leaq 0x11628(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe736
movq 0x1133f(%rip), %rax     # 0x1ffb8
movq (%rax), %rdi
movzbl 0xd(%rsp), %r8d
movzbl 0xe(%rsp), %r9d
movzbl 0xf(%rsp), %eax
movl %eax, (%rsp)
leaq 0x7dd7(%rip), %rsi      # 0x16a6e
leaq 0x79f5(%rip), %rdx      # 0x16693
xorl %ebp, %ebp
movl $0x226, %ecx            # imm = 0x226
xorl %eax, %eax
callq 0x5180
jmp 0xe736
pushq $-0x2
popq %rbp
leaq 0x115d6(%rip), %rax     # 0x20291
cmpb $0x1, (%rax)
jne 0xe736
movq 0x1130d(%rip), %rax     # 0x1ffd8
movq (%rax), %rdi
leaq 0x85a6(%rip), %rsi      # 0x1727b
leaq 0x79b7(%rip), %rdx      # 0x16693
movl $0x21d, %ecx            # imm = 0x21D
jmp 0xeba2
nop