// File: chenhn123[P]wdt_util_src/wdt_ct/w8755_funcs.cpp
// Function: wh_w8755_dev_send_commands(WdtDevice*, int, unsigned int)
int wh_w8755_dev_send_commands(WDT_DEV* pdev, int cmd, UINT32 value)
{
	W8755_CMD_DATA	cmd_data;
	unsigned long 	delay = 0;
	int				result = 0;

	memset(&cmd_data, 0, sizeof(cmd_data));

	cmd_data.DD.rpt_id = W8755_RPTID_WRITE_DATA;

	switch(cmd)
	{
		case 	WH_CMD_ALGO_STOP: {
			int count = 20;
			do {
				wh_w8755_dev_set_device_mode(pdev, W8755_DM_COMMAND);
				wh_sleep(5);
			} while (wh_w8755_dev_get_device_mode(pdev) != W8755_DM_COMMAND && count-- > 0);
			
			return 1;
		}
		break;
		case 	WH_CMD_ALGO_START: {
			int count = 20;
			do {
				wh_w8755_dev_set_device_mode(pdev, W8755_DM_SENSING);
				wh_sleep(5);
			} while (wh_w8755_dev_get_device_mode(pdev) != W8755_DM_SENSING && count--> 0);

			return 1;
		}
		break;
		case 	WH_CMD_SET_DEV_MODE: {
			cmd_data.DD.type = W8755_FW_SET_COMMAND;
			cmd_data.DD.size = 2;
			cmd_data.DD.cmd = W8755_SET_CMD_DEVICE_MODE; 
			cmd_data.DD.param1 = (BYTE) value;			
		}
		break;
		case 	WH_CMD_RESET: {							
			cmd_data.DD.type = W8755_ISP_SET_COMMAND;			
			cmd_data.DD.size = 1;
			cmd_data.DD.cmd = W8755_SET_CMD_RESET;		
		}
		break;
		case	WH_CMD_FLASH_ERASEALL:	{
			cmd_data.DD.type = W8755_ISP_SET_COMMAND;			
			cmd_data.DD.size = 5;
			cmd_data.DD.cmd = W8755_SET_CMD_ERASEALL;
			put_unaligned_le32(value, &cmd_data.buffer[5]);
			
			delay = W8755_FLASH_CHIP_DELAY;			
		}
		break;
		case	WH_CMD_FLASH_ERASE4K:	{
			cmd_data.DD.type = W8755_ISP_SET_COMMAND;			
			cmd_data.DD.size = 5;
			cmd_data.DD.cmd = W8755_SET_CMD_ERASE4K;
			put_unaligned_le32(value, &cmd_data.buffer[5]);

			delay = W8755_FLASH_4K_DELAY;			
		}
		break;
		case	WH_CMD_FLASH_ERASE32K:	{
			cmd_data.DD.type = W8755_ISP_SET_COMMAND;						
			cmd_data.DD.size = 5;
			cmd_data.DD.cmd = W8755_SET_CMD_ERASE32K;
			put_unaligned_le32(value, &cmd_data.buffer[5]);

			delay = W8755_FLASH_32K_DELAY;				
		}
		break;
		case	WH_CMD_FLASH_ERASE64K:	{
			cmd_data.DD.type = W8755_ISP_SET_COMMAND;						
			cmd_data.DD.size = 5;
			cmd_data.DD.cmd = W8755_SET_CMD_ERASE64K;
			put_unaligned_le32(value, &cmd_data.buffer[5]);

			delay = W8755_FLASH_64K_DELAY;				
		}
		break;
		case WH_CMD_FLASH_PROTECTION_ON: {
			cmd_data.DD.type = W8755_ISP_SET_COMMAND;						
			cmd_data.DD.size = 2;
			cmd_data.DD.cmd = W8755_SET_CMD_SFLOCK; 
			cmd_data.DD.param1 = 0x9B;

			/* to wait read flash status */
			delay = 20 | DELAY_REAL_SLEEP;
		}
		break;
		case WH_CMD_FLASH_PROTECTION_OFF: {
			cmd_data.DD.type = W8755_ISP_SET_COMMAND;						
			cmd_data.DD.size = 2;
			cmd_data.DD.cmd = W8755_SET_CMD_SFUNLOCK; 
			cmd_data.DD.param1 = 0xDA;		
			
			/* to wait read flash status */
			delay = 20 | DELAY_REAL_SLEEP;
		}
		break;		
		case	WH_CMD_FLASH_LOCK:	{		
			return wh_w8755_dev_enable_spi_flash_protection(pdev, 1);
		}
		case	WH_CMD_FLASH_UNLOCK: {		
			return wh_w8755_dev_enable_spi_flash_protection(pdev, 0);
		}
		break;

		default: {
			cmd_data.DD.rpt_id = 0;
			return 0;
		}
	}

	if (g_func_dev_basic.p_wh_set_feature) {
		result = g_func_dev_basic.p_wh_set_feature(pdev, &cmd_data.buffer[0], 4 + cmd_data.DD.size);

		if (delay) {
			if (delay & DELAY_REAL_SLEEP) 
				wh_sleep(delay & DELAY_REAL_SLEEP_MASK);
			else {
				delay = wh_w8755_i2c_delay(pdev, delay);
				wh_printf("cmd delay: %d ms\n", (int) delay);
			}
		}

		return result;
	} else
		printf("set feature ptr is null\n");

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq $0x0, -0x68(%rbp)
movl $0x0, -0x6c(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x30(%rbp)
movaps %xmm0, -0x40(%rbp)
movaps %xmm0, -0x50(%rbp)
movaps %xmm0, -0x60(%rbp)
movb $0x8, -0x60(%rbp)
movl -0x14(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x80(%rbp)
subl $0x16, %eax
ja 0x3366
movq -0x80(%rbp), %rax
leaq 0xc2c2(%rip), %rcx      # 0xf41c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x14, -0x70(%rbp)
movq -0x10(%rbp), %rdi
movl $0x90, %esi
callq 0x3420
movl $0x5, %edi
callq 0x2590
movq -0x10(%rbp), %rdi
callq 0x3450
movzbl %al, %ecx
xorl %eax, %eax
cmpl $0x90, %ecx
movb %al, -0x81(%rbp)
je 0x31b5
movl -0x70(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x70(%rbp)
cmpl $0x0, %eax
setg %al
movb %al, -0x81(%rbp)
movb -0x81(%rbp), %al
testb $0x1, %al
jne 0x316a
movl $0x1, -0x4(%rbp)
jmp 0x340b
movl $0x14, -0x74(%rbp)
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x3420
movl $0x5, %edi
callq 0x2590
movq -0x10(%rbp), %rdi
callq 0x3450
movzbl %al, %ecx
xorl %eax, %eax
cmpl $0x1, %ecx
movb %al, -0x82(%rbp)
je 0x321a
movl -0x74(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x74(%rbp)
cmpl $0x0, %eax
setg %al
movb %al, -0x82(%rbp)
movb -0x82(%rbp), %al
testb $0x1, %al
jne 0x31d2
movl $0x1, -0x4(%rbp)
jmp 0x340b
movb $-0x6f, -0x5f(%rbp)
movw $0x2, -0x5e(%rbp)
movb $-0x7e, -0x5c(%rbp)
movl -0x18(%rbp), %eax
movb %al, -0x5b(%rbp)
jmp 0x3376
movb $-0x7b, -0x5f(%rbp)
movw $0x1, -0x5e(%rbp)
movb $0x2, -0x5c(%rbp)
jmp 0x3376
movb $-0x7b, -0x5f(%rbp)
movw $0x5, -0x5e(%rbp)
movb $0x6, -0x5c(%rbp)
movl -0x18(%rbp), %edi
leaq -0x60(%rbp), %rsi
addq $0x5, %rsi
callq 0x9200
movq $0x1d4c, -0x68(%rbp)    # imm = 0x1D4C
jmp 0x3376
movb $-0x7b, -0x5f(%rbp)
movw $0x5, -0x5e(%rbp)
movb $0x3, -0x5c(%rbp)
movl -0x18(%rbp), %edi
leaq -0x60(%rbp), %rsi
addq $0x5, %rsi
callq 0x9200
movq $0x1f4, -0x68(%rbp)     # imm = 0x1F4
jmp 0x3376
movb $-0x7b, -0x5f(%rbp)
movw $0x5, -0x5e(%rbp)
movb $0x4, -0x5c(%rbp)
movl -0x18(%rbp), %edi
leaq -0x60(%rbp), %rsi
addq $0x5, %rsi
callq 0x9200
movq $0x9c4, -0x68(%rbp)     # imm = 0x9C4
jmp 0x3376
movb $-0x7b, -0x5f(%rbp)
movw $0x5, -0x5e(%rbp)
movb $0x5, -0x5c(%rbp)
movl -0x18(%rbp), %edi
leaq -0x60(%rbp), %rsi
addq $0x5, %rsi
callq 0x9200
movq $0xbb8, -0x68(%rbp)     # imm = 0xBB8
jmp 0x3376
movb $-0x7b, -0x5f(%rbp)
movw $0x2, -0x5e(%rbp)
movb $0x0, -0x5c(%rbp)
movb $-0x65, -0x5b(%rbp)
movq $0x100014, -0x68(%rbp)  # imm = 0x100014
jmp 0x3376
movb $-0x7b, -0x5f(%rbp)
movw $0x2, -0x5e(%rbp)
movb $0x1, -0x5c(%rbp)
movb $-0x26, -0x5b(%rbp)
movq $0x100014, -0x68(%rbp)  # imm = 0x100014
jmp 0x3376
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x3490
movl %eax, -0x4(%rbp)
jmp 0x340b
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x3490
movl %eax, -0x4(%rbp)
jmp 0x340b
movb $0x0, -0x60(%rbp)
movl $0x0, -0x4(%rbp)
jmp 0x340b
cmpq $0x0, 0x11ffa(%rip)     # 0x15378
je 0x33f6
movq 0x11ff1(%rip), %rax     # 0x15378
movq -0x10(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movzwl -0x5e(%rbp), %edx
addl $0x4, %edx
callq *%rax
movl %eax, -0x6c(%rbp)
cmpq $0x0, -0x68(%rbp)
je 0x33ee
movq -0x68(%rbp), %rax
andq $0x100000, %rax         # imm = 0x100000
cmpq $0x0, %rax
je 0x33c5
movq -0x68(%rbp), %rax
andq $0xfffff, %rax          # imm = 0xFFFFF
movl %eax, %edi
callq 0x2590
jmp 0x33ec
movq -0x10(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x3510
cltq
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movl %eax, %esi
leaq 0xc101(%rip), %rdi      # 0xf4e6
movb $0x0, %al
callq 0x24e0
jmp 0x33ee
movl -0x6c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x340b
leaq 0xc0fb(%rip), %rdi      # 0xf4f8
movb $0x0, %al
callq 0x2050
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopw (%rax,%rax)