// File: chenhn123[P]wdt_util_src/wdt_ct/w8760_funcs.cpp
// Function: wh_w8760_dev_send_commands(WdtDevice*, int, unsigned int)
int wh_w8760_dev_send_commands(WDT_DEV* pdev, int cmd, UINT32 value)
{
	switch(cmd)
	{
		case 	WH_CMD_ALGO_STOP: {
			return wh_w8760_dev_set_n_check_device_mode(pdev, W8760_MODE_COMMAND, 0, 0);
		}
		break;
		case 	WH_CMD_ALGO_START: 
		case 	WH_CMD_ALGO_RESTART: {	
			return wh_w8760_dev_set_n_check_device_mode(pdev, W8760_MODE_SENSING, 0, 0);
		}
		break;
		case 	WH_CMD_SET_DEV_MODE: {
			return wh_w8760_dev_set_n_check_device_mode(pdev, value, 0, 0);
		}
		break;
		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.
                 	 */
                        if (pdev->board_info.dev_type & FW_WDT8762) {
                                wh_w8760_dev_write_register(pdev, 0x90801408, 0x1B);
                        }else if (pdev->board_info.dev_type & FW_WDT8760) {
                                wh_w8760_dev_write_register(pdev, 0x00801408, 0x28);
                        }
	
			return wh_w8760_dev_reboot(pdev);
		}
		break;
		case	WH_CMD_FLASH_ERASE4K:	{
			return wh_w8760_dev_flash_erase(pdev, value, 0x1000);
		}
		break;
		case	WH_CMD_FLASH_ERASE32K:	{
			return wh_w8760_dev_flash_erase(pdev, value, 0x8000);
		}
		break;
		case	WH_CMD_FLASH_ERASE64K:	{
			return wh_w8760_dev_flash_erase(pdev, value, 0x10000);
		}
		break;
		case	WH_CMD_FLASH_LOCK:	
		case	WH_CMD_FLASH_PROTECTION_ON: 
		{
			return wh_w8760_dev_protect_flash(pdev, W8760_ProtectAll512k);
		}
		break;
		case	WH_CMD_FLASH_UNLOCK: 
		case	WH_CMD_FLASH_PROTECTION_OFF: 
		{
			/* address align to 0x100 */
			UINT32 addr = (value & 0xFFFF0000) >> 8;
			/*  size align to 0x100 */
			UINT32 size = (value & 0xFFFF) << 8; 	
			int ret = 0;
			
			if (addr < 128 * 1024 && addr + size <= 128 * 1024)
				ret = wh_w8760_dev_protect_flash(pdev, W8760_UnprotectLower128k);
					else if (addr < 256 * 1024 && addr + size <= 256 * 1024)
				ret = wh_w8760_dev_protect_flash(pdev, W8760_UnprotectLower256k);
			else if (addr < 384 * 1024 && addr + size <= 384 * 1024)
				ret = wh_w8760_dev_protect_flash(pdev, W8760_UnprotectLower384k);
	  		else if (addr < 508 * 1024 && addr + size <= 508 * 1024)
				ret = wh_w8760_dev_protect_flash(pdev, W8760_UnprotectLower508k);
			return ret;
		}
		break;		
 	
		default: {
			return 0;
		}
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl -0x14(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x30(%rbp)
subl $0x16, %eax
ja 0x5b50
movq -0x30(%rbp), %rax
leaq 0x9f03(%rip), %rcx      # 0xf864
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
movl $0x90, %esi
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x5060
movl %eax, -0x4(%rbp)
jmp 0x5b57
movq -0x10(%rbp), %rdi
movl $0x1, %esi
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x5060
movl %eax, -0x4(%rbp)
jmp 0x5b57
movq -0x10(%rbp), %rdi
movl -0x18(%rbp), %eax
xorl %ecx, %ecx
movzbl %al, %esi
movl %ecx, %edx
callq 0x5060
movl %eax, -0x4(%rbp)
jmp 0x5b57
movq -0x10(%rbp), %rax
movl 0x188(%rax), %eax
andl $0x2000, %eax           # imm = 0x2000
cmpl $0x0, %eax
je 0x59e2
movq -0x10(%rbp), %rdi
movl $0x90801408, %esi       # imm = 0x90801408
movl $0x1b, %edx
callq 0x58c0
jmp 0x5a0b
movq -0x10(%rbp), %rax
movl 0x188(%rax), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0x5a09
movq -0x10(%rbp), %rdi
movl $0x801408, %esi         # imm = 0x801408
movl $0x28, %edx
callq 0x58c0
jmp 0x5a0b
movq -0x10(%rbp), %rdi
callq 0x4e70
movl %eax, -0x4(%rbp)
jmp 0x5b57
movq -0x10(%rbp), %rdi
movl -0x18(%rbp), %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0x5b60
movl %eax, -0x4(%rbp)
jmp 0x5b57
movq -0x10(%rbp), %rdi
movl -0x18(%rbp), %esi
movl $0x8000, %edx           # imm = 0x8000
callq 0x5b60
movl %eax, -0x4(%rbp)
jmp 0x5b57
movq -0x10(%rbp), %rdi
movl -0x18(%rbp), %esi
movl $0x10000, %edx          # imm = 0x10000
callq 0x5b60
movl %eax, -0x4(%rbp)
jmp 0x5b57
movq -0x10(%rbp), %rdi
movl $0x7c, %esi
callq 0x5760
movl %eax, -0x4(%rbp)
jmp 0x5b57
movl -0x18(%rbp), %eax
andl $0xffff0000, %eax       # imm = 0xFFFF0000
shrl $0x8, %eax
movl %eax, -0x1c(%rbp)
movl -0x18(%rbp), %eax
andl $0xffff, %eax           # imm = 0xFFFF
shll $0x8, %eax
movl %eax, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
cmpl $0x20000, -0x1c(%rbp)   # imm = 0x20000
jae 0x5ac9
movl -0x1c(%rbp), %eax
addl -0x20(%rbp), %eax
cmpl $0x20000, %eax          # imm = 0x20000
ja 0x5ac9
movq -0x10(%rbp), %rdi
movl $0x4028, %esi           # imm = 0x4028
callq 0x5760
movl %eax, -0x24(%rbp)
jmp 0x5b48
cmpl $0x40000, -0x1c(%rbp)   # imm = 0x40000
jae 0x5af2
movl -0x1c(%rbp), %eax
addl -0x20(%rbp), %eax
cmpl $0x40000, %eax          # imm = 0x40000
ja 0x5af2
movq -0x10(%rbp), %rdi
movl $0xc, %esi
callq 0x5760
movl %eax, -0x24(%rbp)
jmp 0x5b46
cmpl $0x60000, -0x1c(%rbp)   # imm = 0x60000
jae 0x5b1b
movl -0x1c(%rbp), %eax
addl -0x20(%rbp), %eax
cmpl $0x60000, %eax          # imm = 0x60000
ja 0x5b1b
movq -0x10(%rbp), %rdi
movl $0x8, %esi
callq 0x5760
movl %eax, -0x24(%rbp)
jmp 0x5b44
cmpl $0x7f000, -0x1c(%rbp)   # imm = 0x7F000
jae 0x5b42
movl -0x1c(%rbp), %eax
addl -0x20(%rbp), %eax
cmpl $0x7f000, %eax          # imm = 0x7F000
ja 0x5b42
movq -0x10(%rbp), %rdi
movl $0x44, %esi
callq 0x5760
movl %eax, -0x24(%rbp)
jmp 0x5b44
jmp 0x5b46
jmp 0x5b48
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x5b57
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq