// File: goodix[P]gdix_hid_firmware_update/gtx9/gtx9.cpp
// Function: GTx9Device::Write(unsigned int, unsigned char const*, unsigned int)
int GTx9Device::Write(unsigned int addr, const unsigned char *buf,
					  unsigned int len)
{
	uint8_t HidBuf[PACKAGE_LEN] = {0};
	uint32_t current_addr = addr;
	uint32_t transfer_length = 0;
	uint32_t pos = 0;
	uint8_t pkg_num = 0;
	int ret;

	if (!m_deviceOpen) {
		gdix_err("Device not open\n");
		return -EINVAL;
	}

	while (pos != len) {
		HidBuf[0] = REPORT_ID;
		HidBuf[1] = I2C_DIRECT_RW;
		if (len - pos > PACKAGE_LEN - 12) {
			transfer_length = PACKAGE_LEN - 12;
			HidBuf[2] = 0x01;
		} else {
			transfer_length = len - pos;
			HidBuf[2] = 0x00;
		}
		HidBuf[3] = pkg_num++;
		HidBuf[4] = transfer_length + 7;
		HidBuf[5] = I2C_WRITE_FLAG;
		HidBuf[6] = (current_addr >> 24) & 0xFF;
		HidBuf[7] = (current_addr >> 16) & 0xFF;
		HidBuf[8] = (current_addr >> 8) & 0xFF;
		HidBuf[9] = current_addr & 0xFF;
		HidBuf[10] = (transfer_length >> 8) & 0xFF;
		HidBuf[11] = transfer_length & 0xFF;
		memcpy(&HidBuf[12], &buf[pos], transfer_length);
		ret = SetReport(HidBuf, transfer_length + 12);
		if (ret < 0) {
			gdix_err("Failed write data to addr=0x%x, len=%d,ret = %d\n",
					 current_addr, transfer_length, ret);
			return ret;
		}
		pos += transfer_length;
		current_addr += transfer_length;
	}

	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
movq -0x90(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, -0x74(%rbp)
movl $0x0, -0x78(%rbp)
movl $0x0, -0x7c(%rbp)
movb $0x0, -0x7d(%rbp)
testb $0x1, 0x8(%rax)
jne 0x13829
jmp 0x137eb
leaq 0x12aa7(%rip), %rax     # 0x26299
testb $0x1, (%rax)
je 0x1381b
movq 0x127da(%rip), %rax     # 0x25fd8
movq (%rax), %rdi
leaq 0xb2bf(%rip), %rsi      # 0x1eac7
leaq 0xad59(%rip), %rdx      # 0x1e568
movl $0x9e, %ecx
movb $0x0, %al
callq 0x5190
jmp 0x1381d
movl $0xffffffea, -0x4(%rbp) # imm = 0xFFFFFFEA
jmp 0x1397b
jmp 0x1382b
movl -0x7c(%rbp), %eax
cmpl -0x24(%rbp), %eax
je 0x13975
movb $0xe, -0x70(%rbp)
movb $0x20, -0x6f(%rbp)
movl -0x24(%rbp), %eax
subl -0x7c(%rbp), %eax
cmpl $0x35, %eax
jbe 0x13857
movl $0x35, -0x78(%rbp)
movb $0x1, -0x6e(%rbp)
jmp 0x13864
movl -0x24(%rbp), %eax
subl -0x7c(%rbp), %eax
movl %eax, -0x78(%rbp)
movb $0x0, -0x6e(%rbp)
movb -0x7d(%rbp), %al
movb %al, %cl
addb $0x1, %cl
movb %cl, -0x7d(%rbp)
movb %al, -0x6d(%rbp)
movl -0x78(%rbp), %eax
addl $0x7, %eax
movb %al, -0x6c(%rbp)
movb $0x0, -0x6b(%rbp)
movl -0x74(%rbp), %eax
shrl $0x18, %eax
andl $0xff, %eax
movb %al, -0x6a(%rbp)
movl -0x74(%rbp), %eax
shrl $0x10, %eax
andl $0xff, %eax
movb %al, -0x69(%rbp)
movl -0x74(%rbp), %eax
shrl $0x8, %eax
andl $0xff, %eax
movb %al, -0x68(%rbp)
movl -0x74(%rbp), %eax
andl $0xff, %eax
movb %al, -0x67(%rbp)
movl -0x78(%rbp), %eax
shrl $0x8, %eax
andl $0xff, %eax
movb %al, -0x66(%rbp)
movl -0x78(%rbp), %eax
andl $0xff, %eax
movb %al, -0x65(%rbp)
leaq -0x70(%rbp), %rdi
addq $0xc, %rdi
movq -0x20(%rbp), %rsi
movl -0x7c(%rbp), %eax
addq %rax, %rsi
movl -0x78(%rbp), %eax
movl %eax, %edx
callq 0x50b0
movq -0x90(%rbp), %rdi
leaq -0x70(%rbp), %rsi
movl -0x78(%rbp), %edx
addl $0xc, %edx
callq 0x134a0
movl %eax, -0x84(%rbp)
cmpl $0x0, -0x84(%rbp)
jge 0x1395e
jmp 0x13910
leaq 0x12982(%rip), %rax     # 0x26299
testb $0x1, (%rax)
je 0x13951
movq 0x126b5(%rip), %rax     # 0x25fd8
movq (%rax), %rdi
movl -0x74(%rbp), %r8d
movl -0x78(%rbp), %r9d
movl -0x84(%rbp), %eax
leaq 0xb1b3(%rip), %rsi      # 0x1eaee
leaq 0xac26(%rip), %rdx      # 0x1e568
movl $0xb9, %ecx
movl %eax, (%rsp)
movb $0x0, %al
callq 0x5190
jmp 0x13953
movl -0x84(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1397b
movl -0x78(%rbp), %eax
addl -0x7c(%rbp), %eax
movl %eax, -0x7c(%rbp)
movl -0x78(%rbp), %eax
addl -0x74(%rbp), %eax
movl %eax, -0x74(%rbp)
jmp 0x1382b
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)