// File: goodix[P]gdix_hid_firmware_update/gtx5/gtx5.cpp
// Function: GTx5Device::Write(unsigned int, unsigned char const*, unsigned int)
int GTx5Device::Write(unsigned int addr, const unsigned char *buf,
					  unsigned int len)
{
	unsigned char tmpBuf[65] = {0x0e, _I2C_DIRECT_RW, 0, 0, 5};
	unsigned short current_addr = addr;
	unsigned int pos = 0, transfer_length = 0;
	bool has_follow_pkg = false;
	unsigned char pkg_num = 0;
	int ret = 0;
	while (pos != len) {
		if (len - pos >
			m_outputReportSize - GDIX_PRE_HEAD_LEN - GDIX_DATA_HEAD_LEN) {
			/* data len more than 55, need to send with subpackages */
			transfer_length =
				m_outputReportSize - GDIX_PRE_HEAD_LEN - GDIX_DATA_HEAD_LEN;
			has_follow_pkg = true;
		} else {
			transfer_length = len - pos;
			has_follow_pkg = false;
		}
		if (has_follow_pkg)
			tmpBuf[2] = 0x01; /* set follow-up package flag */
		else
			tmpBuf[2] = 0x00;
		tmpBuf[3] = pkg_num++; /* set pack num */
		/* set HID package length = data_len + GDIX_DATA_HEAD_LEN */
		tmpBuf[4] = (unsigned char)(transfer_length + GDIX_DATA_HEAD_LEN);
		tmpBuf[5] = 0; /* write operation flag */
		tmpBuf[6] = (current_addr >> 8) & 0xff;
		tmpBuf[7] = current_addr & 0xff;
		tmpBuf[8] = (unsigned char)((transfer_length >> 8) & 0xff);
		tmpBuf[9] = (unsigned char)(transfer_length & 0xff);
		memcpy(&tmpBuf[GDIX_PRE_HEAD_LEN + GDIX_DATA_HEAD_LEN], &buf[pos],
			   transfer_length);
		ret = Write(tmpBuf,
					transfer_length + GDIX_PRE_HEAD_LEN + GDIX_DATA_HEAD_LEN);
		if (ret < 0) {
			gdix_dbg("Failed write data to addr=0x%x, len=%d,ret = %d\n",
					 current_addr, transfer_length, ret);
			break;
		} else {
			pos += transfer_length;
			current_addr += transfer_length;
		}
	}
	if (ret < 0)
		return -1;
	else
		return len;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0x70(%rbp), %rdi
xorl %esi, %esi
movl $0x41, %edx
callq 0x50a0
movb $0xe, -0x70(%rbp)
movb $0x20, -0x6f(%rbp)
movb $0x5, -0x6c(%rbp)
movl -0x14(%rbp), %eax
movw %ax, -0x72(%rbp)
movl $0x0, -0x78(%rbp)
movl $0x0, -0x7c(%rbp)
movb $0x0, -0x7d(%rbp)
movb $0x0, -0x7e(%rbp)
movl $0x0, -0x84(%rbp)
movl -0x78(%rbp), %eax
cmpl -0x24(%rbp), %eax
je 0xf33a
movq -0x90(%rbp), %rcx
movl -0x24(%rbp), %eax
subl -0x78(%rbp), %eax
movl 0x2c(%rcx), %ecx
subl $0x5, %ecx
subl $0x5, %ecx
cmpl %ecx, %eax
jbe 0xf226
movq -0x90(%rbp), %rax
movl 0x2c(%rax), %eax
subl $0x5, %eax
subl $0x5, %eax
movl %eax, -0x7c(%rbp)
movb $0x1, -0x7d(%rbp)
jmp 0xf233
movl -0x24(%rbp), %eax
subl -0x78(%rbp), %eax
movl %eax, -0x7c(%rbp)
movb $0x0, -0x7d(%rbp)
testb $0x1, -0x7d(%rbp)
je 0xf23f
movb $0x1, -0x6e(%rbp)
jmp 0xf243
movb $0x0, -0x6e(%rbp)
movb -0x7e(%rbp), %al
movb %al, %cl
addb $0x1, %cl
movb %cl, -0x7e(%rbp)
movb %al, -0x6d(%rbp)
movl -0x7c(%rbp), %eax
addl $0x5, %eax
movb %al, -0x6c(%rbp)
movb $0x0, -0x6b(%rbp)
movzwl -0x72(%rbp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, -0x6a(%rbp)
movzwl -0x72(%rbp), %eax
andl $0xff, %eax
movb %al, -0x69(%rbp)
movl -0x7c(%rbp), %eax
shrl $0x8, %eax
andl $0xff, %eax
movb %al, -0x68(%rbp)
movl -0x7c(%rbp), %eax
andl $0xff, %eax
movb %al, -0x67(%rbp)
leaq -0x70(%rbp), %rdi
addq $0xa, %rdi
movq -0x20(%rbp), %rsi
movl -0x78(%rbp), %eax
addq %rax, %rsi
movl -0x7c(%rbp), %eax
movl %eax, %edx
callq 0x50b0
movq -0x90(%rbp), %rdi
leaq -0x70(%rbp), %rsi
movl -0x7c(%rbp), %edx
addl $0x5, %edx
addl $0x5, %edx
movq (%rdi), %rax
callq *0x38(%rax)
movl %eax, -0x84(%rbp)
cmpl $0x0, -0x84(%rbp)
jge 0xf31f
jmp 0xf2d9
leaq 0x16fb9(%rip), %rax     # 0x26299
testb $0x1, (%rax)
je 0xf31b
movq 0x16ccc(%rip), %rax     # 0x25fb8
movq (%rax), %rdi
movzwl -0x72(%rbp), %r8d
movl -0x7c(%rbp), %r9d
movl -0x84(%rbp), %eax
leaq 0xf221(%rip), %rsi      # 0x1e526
leaq 0xf25c(%rip), %rdx      # 0x1e568
movl $0x109, %ecx            # imm = 0x109
movl %eax, (%rsp)
movb $0x0, %al
callq 0x5190
jmp 0xf31d
jmp 0xf33a
movl -0x7c(%rbp), %eax
addl -0x78(%rbp), %eax
movl %eax, -0x78(%rbp)
movl -0x7c(%rbp), %ecx
movzwl -0x72(%rbp), %eax
addl %ecx, %eax
movw %ax, -0x72(%rbp)
jmp 0xf1e7
cmpl $0x0, -0x84(%rbp)
jge 0xf34c
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xf352
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nop