// File: goodix[P]gdix_hid_firmware_update/gtx9/gtx9.cpp
// Function: GTx9Device::WriteSpeCmd(unsigned char const*, unsigned int)
int GTx9Device::WriteSpeCmd(const unsigned char *buf, unsigned int len)
{
	unsigned char cmdBuf[16] = {0};
	uint16_t checksum = 0;
	uint32_t i;
	int ret;

	if (len > 11) {
		gdix_err("Cmd data len is invalid len=%d\n", len);
		return -EINVAL;
	}

	cmdBuf[0] = 0;
	cmdBuf[1] = 0;
	cmdBuf[2] = len + 3;
	memcpy(&cmdBuf[3], buf, len);
	for (i = 2; i < len + 3; i++)
		checksum += cmdBuf[i];

	cmdBuf[len + 3] = checksum & 0xFF;
	cmdBuf[len + 4] = (checksum >> 8) & 0XFF;
	ret = Write(0x10174, cmdBuf, len + 5);
	if (ret < 0) {
		gdix_err("Failed write cmd\n");
		return ret;
	}
	for (i = 0; i < 20; i++) {
		ret = Read(0x10174, cmdBuf, 2);
		if (ret < 0) {
			gdix_err("Failed read cmd status\n");
			return ret;
		}
		if (cmdBuf[1] == 0x80 && cmdBuf[0] == 0x80) {
			usleep(5000);
			return 0;
		}
		usleep(15000);
	}

	gdix_err("Failed get valid cmd ack:0x%02x sta:0x%02x\n", cmdBuf[1],
			 cmdBuf[0]);
	return -EINVAL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x48(%rbp)
leaq -0x30(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x50a0
movw $0x0, -0x32(%rbp)
cmpl $0xb, -0x1c(%rbp)
jbe 0x13a0b
jmp 0x139c9
leaq 0x128c9(%rip), %rax     # 0x26299
testb $0x1, (%rax)
je 0x139fd
movq 0x125fc(%rip), %rax     # 0x25fd8
movq (%rax), %rdi
movl -0x1c(%rbp), %r8d
leaq 0xb146(%rip), %rsi      # 0x1eb30
leaq 0xabef(%rip), %rdx      # 0x1e5e0
movl $0xcb, %ecx
movb $0x0, %al
callq 0x5190
jmp 0x139ff
movl $0xffffffea, -0x4(%rbp) # imm = 0xFFFFFFEA
jmp 0x13bec
movb $0x0, -0x30(%rbp)
movb $0x0, -0x2f(%rbp)
movl -0x1c(%rbp), %eax
addl $0x3, %eax
movb %al, -0x2e(%rbp)
leaq -0x30(%rbp), %rdi
addq $0x3, %rdi
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %eax
movl %eax, %edx
callq 0x50b0
movl $0x2, -0x38(%rbp)
movl -0x38(%rbp), %eax
movl -0x1c(%rbp), %ecx
addl $0x3, %ecx
cmpl %ecx, %eax
jae 0x13a63
movl -0x38(%rbp), %eax
movzbl -0x30(%rbp,%rax), %ecx
movzwl -0x32(%rbp), %eax
addl %ecx, %eax
movw %ax, -0x32(%rbp)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x13a39
movq -0x48(%rbp), %rdi
movzwl -0x32(%rbp), %eax
andl $0xff, %eax
movb %al, %cl
movl -0x1c(%rbp), %eax
addl $0x3, %eax
movl %eax, %eax
movb %cl, -0x30(%rbp,%rax)
movzwl -0x32(%rbp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movl -0x1c(%rbp), %eax
addl $0x4, %eax
movl %eax, %eax
movb %cl, -0x30(%rbp,%rax)
leaq -0x30(%rbp), %rdx
movl -0x1c(%rbp), %ecx
addl $0x5, %ecx
movq (%rdi), %rax
movl $0x10174, %esi          # imm = 0x10174
callq *0x30(%rax)
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jge 0x13af5
jmp 0x13ab8
leaq 0x127da(%rip), %rax     # 0x26299
testb $0x1, (%rax)
je 0x13ae8
movq 0x1250d(%rip), %rax     # 0x25fd8
movq (%rax), %rdi
leaq 0xb08c(%rip), %rsi      # 0x1eb61
leaq 0xab04(%rip), %rdx      # 0x1e5e0
movl $0xda, %ecx
movb $0x0, %al
callq 0x5190
jmp 0x13aea
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x13bec
movl $0x0, -0x38(%rbp)
cmpl $0x14, -0x38(%rbp)
jae 0x13ba7
movq -0x48(%rbp), %rdi
leaq -0x30(%rbp), %rdx
movq (%rdi), %rax
movl $0x10174, %esi          # imm = 0x10174
movl $0x2, %ecx
callq *0x20(%rax)
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jge 0x13b66
jmp 0x13b29
leaq 0x12769(%rip), %rax     # 0x26299
testb $0x1, (%rax)
je 0x13b59
movq 0x1249c(%rip), %rax     # 0x25fd8
movq (%rax), %rdi
leaq 0xb03e(%rip), %rsi      # 0x1eb84
leaq 0xaa93(%rip), %rdx      # 0x1e5e0
movl $0xe0, %ecx
movb $0x0, %al
callq 0x5190
jmp 0x13b5b
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x13bec
movzbl -0x2f(%rbp), %eax
cmpl $0x80, %eax
jne 0x13b8f
movzbl -0x30(%rbp), %eax
cmpl $0x80, %eax
jne 0x13b8f
movl $0x1388, %edi           # imm = 0x1388
callq 0x5180
movl $0x0, -0x4(%rbp)
jmp 0x13bec
movl $0x3a98, %edi           # imm = 0x3A98
callq 0x5180
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x13afc
jmp 0x13ba9
leaq 0x126e9(%rip), %rax     # 0x26299
testb $0x1, (%rax)
je 0x13be3
movq 0x1241c(%rip), %rax     # 0x25fd8
movq (%rax), %rdi
movzbl -0x2f(%rbp), %r8d
movzbl -0x30(%rbp), %r9d
leaq 0xafdd(%rip), %rsi      # 0x1ebad
leaq 0xaa09(%rip), %rdx      # 0x1e5e0
movl $0xeb, %ecx
movb $0x0, %al
callq 0x5190
jmp 0x13be5
movl $0xffffffea, -0x4(%rbp) # imm = 0xFFFFFFEA
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)