// File: /workspace/github_cpp_makefile_star2_O2/chenhn123[P]wdt_util_src/wdt_ct/w8790_funcs.cpp
// Function: wh_w8790_dev_send_commands(WdtDevice*, int, unsigned int)
int wh_w8790_dev_send_commands(WDT_DEV* pdev, int cmd, UINT32 value)
{
	int ret = 0;
	switch (cmd)
	{
	case 	WH_CMD_RESET:
		/** 
         	 * Hard reset doesn't make OSC back to default. So we need this workaround to set OSC to default.
         	 * If not, the OSC clock for ROM code is too high and might cause booting fails.
        	 */
        	ret = wh_w8790_dev_write_register(pdev, 0x00801408, 0x47);

		ret = wh_w8790_dev_reboot(pdev);
		break;
	case 	WH_CMD_SET_DEV_MODE: {
		ret =  wh_w8790_dev_set_n_check_device_mode(pdev, value, 0, 0);
		break;
	}
	case	WH_CMD_FLASH_ERASE4K:
		ret = wh_w8790_dev_flash_erase(pdev, value, 0x1000);
		break;
	case	WH_CMD_FLASH_ERASE32K:
		ret = wh_w8790_dev_flash_erase(pdev, value, 0x8000);
		break;
	case	WH_CMD_FLASH_ERASE64K:
		ret = wh_w8790_dev_flash_erase(pdev, value, 0x10000);
		break;

	case	WH_CMD_FLASH_LOCK:
	case	WH_CMD_FLASH_PROTECTION_ON:
		ret = wh_w8790_dev_protect_flash(pdev, W8790_ProtectAll512k);
		break;
	case	WH_CMD_FLASH_UNLOCK: {
		ret = wh_w8790_dev_set_n_check_device_mode(pdev, W8790_MODE_FLASH_PROGRAM, 0, 0);
		break;
	}
	case	WH_CMD_FLASH_PROTECTION_OFF:
	{
		// address align to 0x100
		UINT32 addr = ((value & 0xFFFF0000) >> 8);

		// size align to 0x100
		UINT32 size = ((value & 0xFFFF) << 8) + 0x100;
		if (addr < 128 * 1024 && addr + size <= 128 * 1024)
			ret = wh_w8790_dev_protect_flash(pdev, W8790_UnprotectLower128k);
		else if (addr < 256 * 1024 && addr + size <= 256 * 1024)
			ret = wh_w8790_dev_protect_flash(pdev, W8790_UnprotectLower256k);
		else if (addr < 384 * 1024 && addr + size <= 384 * 1024)
			ret = wh_w8790_dev_protect_flash(pdev, W8790_UnprotectLower384k);
		else if (addr < 508 * 1024 && addr + size <= 508 * 1024)
			ret = wh_w8790_dev_protect_flash(pdev, W8790_UnprotectLower508k);
	}
	break;
	case 	WH_CMD_ALGO_STOP: 
		ret =  wh_w8790_dev_set_n_check_device_mode(pdev, W8790_MODE_COMMAND, 0, 0);
		break;
	case 	WH_CMD_ALGO_START:
		ret = wh_w8790_dev_set_n_check_device_mode(pdev, W8790_MODE_SENSING, 0, 0);
		break;
	default:
		ret = 0;
		break;
	}
	return ret;

}

// Assembly:
pushq %rbx
decl %esi
cmpl $0x16, %esi
ja 0x5dd7
movq %rdi, %rbx
leaq 0x4e1c(%rip), %rax      # 0xaad4
movslq (%rax,%rsi,4), %rcx
addq %rax, %rcx
jmpq *%rcx
pushq $0x7c
popq %rsi
movq %rbx, %rdi
popq %rbx
jmp 0x5940
movq %rbx, %rdi
movl %edx, %esi
movl $0x10000, %edx          # imm = 0x10000
jmp 0x5d6f
movq %rbx, %rdi
movl $0x96, %esi
jmp 0x5d4f
movl %edx, %eax
shrl $0x8, %eax
andl $0xffff00, %eax         # imm = 0xFFFF00
movzwl %dx, %ecx
shll $0x8, %ecx
cmpl $0x2000000, %edx        # imm = 0x2000000
setb %sil
addl %ecx, %eax
addl $0x100, %eax            # imm = 0x100
cmpl $0x20001, %eax          # imm = 0x20001
setb %cl
andb %sil, %cl
cmpb $0x1, %cl
jne 0x5d75
movq %rbx, %rdi
movl $0x4028, %esi           # imm = 0x4028
jmp 0x5cc7
movzbl %dl, %esi
jmp 0x5d42
pushq $0x47
popq %rdx
movq %rbx, %rdi
movl $0x801408, %esi         # imm = 0x801408
callq 0x5e49
movq %rbx, %rdi
popq %rbx
jmp 0x5626
pushq $0x1
popq %rsi
movq %rbx, %rdi
jmp 0x5d4f
movq %rbx, %rdi
movl $0x90, %esi
xorl %edx, %edx
xorl %ecx, %ecx
popq %rbx
jmp 0x51da
movq %rbx, %rdi
movl %edx, %esi
movl $0x1000, %edx           # imm = 0x1000
jmp 0x5d6f
movq %rbx, %rdi
movl %edx, %esi
movl $0x8000, %edx           # imm = 0x8000
popq %rbx
jmp 0x5e14
cmpl $0x4000000, %edx        # imm = 0x4000000
setb %cl
cmpl $0x40001, %eax          # imm = 0x40001
setb %sil
andb %cl, %sil
cmpb $0x1, %sil
jne 0x5d97
pushq $0xc
jmp 0x5cc3
cmpl $0x6000000, %edx        # imm = 0x6000000
setb %cl
cmpl $0x60001, %eax          # imm = 0x60001
setb %sil
andb %cl, %sil
cmpb $0x1, %sil
jne 0x5db9
pushq $0x8
jmp 0x5cc3
cmpl $0x7f00000, %edx        # imm = 0x7F00000
setb %cl
cmpl $0x7f001, %eax          # imm = 0x7F001
setb %al
andb %cl, %al
cmpb $0x1, %al
jne 0x5dd7
pushq $0x44
jmp 0x5cc3
xorl %eax, %eax
popq %rbx
retq