/* 2012-09-16: File added and changed by Sony Corporation */
/*
 * cmd_icx.c
 *
 * Copyright 2011 Sony Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include <common.h>
#include <command.h>

#include "../board/emxx/emgr/icx.h"
#include "../board/emxx/emgr/icx_pmu.h"
#include "../board/emxx/emgr/icx_nvp.h"

#if defined(CONFIG_CMD_ICX) || defined(CONFIG_CMD_ICD)

/* optional command switch ( 1:enable / 0:disable ) */
#define OPT_CMD_SD_NFS_BOOT		1
#define OPT_CMD_PMIC_RW			0
#define OPT_CMD_UBOOT_WRITE		1
#define OPT_CMD_KERNEL_WRITE	1
#define OPT_CMD_ETHER_REG_DUMP	0
#define OPT_CMD_LCD_TEST    	0
#define OPT_CMD_ADC_TEST    	0

/************************/
/*@ Boot kernel command */
/************************/

/* kernel type */
#define KERNEL_TYPE_INSTALL		0
#define KERNEL_TYPE_NORMAL		1
#define KERNEL_TYPE_UPDATE		2

/* boot mode */
#define BOOT_MODE_NORMAL		0
#define BOOT_MODE_EMERGENCY		1

DECLARE_GLOBAL_DATA_PTR;

/* prototypes */
static void icx_boot_linux(unsigned int boot_mode);
static void setup_tag(bd_t *bd, char *commandline, unsigned int initrd_size);


/* command entry */
int do_icxboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	icx_boot_linux(BOOT_MODE_NORMAL);
	/* never return */
	return 0;
}

/* command definition */
U_BOOT_CMD(
	icxboot,  1,  0,  do_icxboot,
	"Boot Linux from eMMC",
	"\n" 
);

/* command definition */
U_BOOT_CMD(
	icdboot,  1,  0,  do_icxboot,
	"Boot Linux from eMMC",
	"\n" 
);

/* command entry */
int do_fwupboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	icx_boot_linux(BOOT_MODE_EMERGENCY);
	/* never return */
	return 0;
}

/* command definition */
U_BOOT_CMD(
	fwupboot,  1,  0,  do_fwupboot,
	"Boot Linux from eMMC in emergency F/W update mode",
	"\n"
);

/* load and boot linux */
static void icx_boot_linux(unsigned int boot_mode)
{
	bd_t         *bd = gd->bd;
	char         *commandline;
	unsigned int  size;
	unsigned int  initrd_size;
	int           kernel_type;
	char		  bootargscommand[CONFIG_SYS_CBSIZE] = "setenv bootargs ";
	int			  commandlen						 = CONFIG_SYS_CBSIZE - strlen(bootargscommand) - 1;

	void (*kernel_entry)(int zero, int arch, uint params);

#ifdef CONFIG_SILENT_CONSOLE
	/*******************/
	/* console setting */
	/*******************/
	char *s = getenv("silent");

	if ((s != NULL) && (*s == '1'))
		setenv("console", "");
#endif

	/***************************/
	/* set kernel command line */
	/***************************/

	/* installation */
	if (icx_inst_initrd_size != 0) {
		strncat(bootargscommand, BOOTARGS_INST, commandlen);

		kernel_type = KERNEL_TYPE_INSTALL;
	}

	/* emergency */
	else if (boot_mode == BOOT_MODE_EMERGENCY) {
#ifdef CONFIG_ICX
		if(config_cons_index == 1)
			setenv("console", "console=ttyS0,115200n8n");
		else if(config_cons_index == 4)
			setenv("console", "console=ttyS3,115200n8n");
#else /* CONFIG_ICD */
		setenv("console", "console=ttyS0,115200n8n");
#endif

		strncat(bootargscommand, BOOTARGS_EMRG, commandlen);

		kernel_type = KERNEL_TYPE_UPDATE;
	}

	/* firmware update */
	else if (nvp_check_fw_update()) {
		strncat(bootargscommand, BOOTARGS_FWUP, commandlen);

		kernel_type = KERNEL_TYPE_UPDATE;
	}

	/* normal */
	else {
		commandline = getenv("bootargs");
		if (commandline)
			strncat(bootargscommand, commandline, commandlen);

		kernel_type = KERNEL_TYPE_NORMAL;
	}

	run_command(bootargscommand, 0);

	/***************/
	/* load kernel */
	/***************/

	if (kernel_type == KERNEL_TYPE_INSTALL) {
		initrd_size = icx_inst_initrd_size;
	}

	else if (kernel_type == KERNEL_TYPE_NORMAL) {
		printf("\nLoading Kernel ... ");
		size = icx_load_linux_image(ICX_COMMON_KERNEL_PARTITION_NO,
									0,
									(unsigned char *)CONFIG_KERNEL_LOAD_ADDR,
									CONFIG_SYS_LOAD_SIZE);
		if (size == 0) {
			printf("Failed to load.\n");
			icx_boot_error();
		}
		printf("done\n");

		initrd_size = 0;
	}

	else {
		printf("\nLoading Kernel(for F/W update) ... ");
		size = icx_load_linux_image(ICX_LOADER_PARTITION_NO,
									FU_KERNEL_AREA_START,
									(unsigned char *)CONFIG_KERNEL_LOAD_ADDR,
									CONFIG_SYS_LOAD_SIZE);
        if (size == 0) {
			printf("Failed to load.\n");
			icx_boot_error();
		}
		printf("done\n");

		printf("\nLoading RootFS(for F/W update) ... ");
		initrd_size = icx_load_linux_image(ICX_LOADER_PARTITION_NO,
										   FU_ROOTFS_AREA_START,
										   (unsigned char *)CONFIG_FUINITRD_START_ADDR,
										   CONFIG_FUINITRD_SIZE);
		if (initrd_size == 0) {
			printf("Failed to load.\n");
			icx_boot_error();
		}
		printf("done\n");
	}

	/***************/
	/* boot Kernel */
	/***************/

	/* set entry point */
	kernel_entry = (void (*)(int, int, uint))CONFIG_KERNEL_LOAD_ADDR;

	commandline = getenv("bootargs");
	check_commandline(commandline);

	/* create TAG */
	setup_tag(bd, commandline, initrd_size);

	cleanup_before_linux ();

	printf("\nStarting kernel%s...\n\n", ((kernel_type == KERNEL_TYPE_INSTALL) ? "(INSTALLER) " : " "));

	if (kernel_type != KERNEL_TYPE_NORMAL) {
		pmu_clear_reset_flag();
	}

	/* jump to kernel */
	kernel_entry(0, bd->bi_arch_number, bd->bi_boot_params);
}

/* setup tag to ram */
static void setup_tag(bd_t *bd, char *commandline, unsigned int initrd_size)
{
	struct tag *params;
	unsigned int syi;
	char *p;
	int   i;

	params = (struct tag *)bd->bi_boot_params;

	/********/
	/* core */
	/********/
	params->hdr.tag  = ATAG_CORE;
	params->hdr.size = tag_size(tag_core);

	params->u.core.flags    = 0;
	params->u.core.pagesize = 0;
	params->u.core.rootdev  = 0;

	params = tag_next(params);

	/**********/
	/* memory */
	/**********/

#if defined(CONFIG_ICX)
	syi = nvp_get_sysinfo_mem();
#else
	syi = NVP_SYSINFO_MEM_064M;
#endif

	/* Bank 1 */
	params->hdr.tag  = ATAG_MEM;
	params->hdr.size = tag_size(tag_mem32);

	params->u.mem.start = CONFIG_ATAG_MEM_1_ADDR;
	params->u.mem.size  = CONFIG_ATAG_MEM_1_SIZE;
	params = tag_next(params);

	/* F/W update */
	if (initrd_size) {
		/* Bank 2 */
		params->hdr.tag  = ATAG_MEM;
		params->hdr.size = tag_size(tag_mem32);

		params->u.mem.start = CONFIG_ATAG_MEM_2_ADDR_FU;
		params->u.mem.size  = CONFIG_ATAG_MEM_2_SIZE_FU;
		params = tag_next(params);
	}
	else {
		/* 512M bit */
		if (syi == NVP_SYSINFO_MEM_064M) {
			/* Bank 2 */
			params->hdr.tag  = ATAG_MEM;
			params->hdr.size = tag_size(tag_mem32);

			params->u.mem.start = CONFIG_ATAG_MEM_2_ADDR;
			params->u.mem.size  = CONFIG_ATAG_MEM_2_SIZE_512;
			params = tag_next(params);
		}

		/* 1G bit */
		else {
			/* Bank 2 */
			params->hdr.tag  = ATAG_MEM;
			params->hdr.size = tag_size(tag_mem32);

			params->u.mem.start = CONFIG_ATAG_MEM_2_ADDR;
			params->u.mem.size  = CONFIG_ATAG_MEM_2_SIZE_1G;
			params = tag_next(params);

			/* Bank 3 */
			params->hdr.tag  = ATAG_MEM;
			params->hdr.size = tag_size(tag_mem32);

			params->u.mem.start = CONFIG_ATAG_MEM_3_ADDR;
			params->u.mem.size  = CONFIG_ATAG_MEM_3_SIZE_1G;
			params = tag_next(params);
		}
	}
	
	/****************/
	/* command line */
	/****************/
	if (commandline) {
		p = commandline;
		for (i = 0; i < CONFIG_SYS_BARGSIZE; i++) {
			if (*p != ' ')
				break;
			p++;
		}

		if ((i < CONFIG_SYS_BARGSIZE) && (*p != '\0')) {
			params->hdr.tag  = ATAG_CMDLINE;
			params->hdr.size = (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;

			strncpy(params->u.cmdline.cmdline, p, strlen(p) + 1);

			params = tag_next(params);
		}
	}

	/**********/
	/* initrd */
	/**********/
	if (initrd_size) {
		params->hdr.tag  = ATAG_INITRD2;
		params->hdr.size = tag_size(tag_initrd);

		params->u.initrd.start = CONFIG_FUINITRD_START_ADDR; 
		params->u.initrd.size  = initrd_size;

		params = tag_next(params);
	}

	/***********/
	/* end tag */
	/***********/
	params->hdr.tag  = ATAG_NONE;
	params->hdr.size = 0;
}


/**************/
/*@ Power off */
/**************/

/* header files */
#include "../board/emxx/emgr/icx_pmu.h"
#include "../board/emxx/emgr/icx_dac.h"
#include "../board/emxx/emgr/icx_lcdc.h"
#include "../board/emxx/emgr/icx_lcd.h"

/* command entry */
int do_power_off(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	pmu_clear_reset_flag();

#ifdef CONFIG_ICX
	dac_disable_mute();
	lcd_power_off();

	lcd_exit();
	dac_exit();
#endif

	pmu_regulator_off(REGULATOR_GP3);

	pmu_power_off();

	return 0;
}

/* command definition */
U_BOOT_CMD(
	poweroff,  1,  0,  do_power_off,
	"poweroff",
	"no parameter\n"
);


/**********************************/
/*@ SD boot and NFS mount command */
/**********************************/

#if defined(CONFIG_CMD_ICD) && (OPT_CMD_SD_NFS_BOOT)

/* command entry */
int do_sdboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	DECLARE_GLOBAL_DATA_PTR;

	bd_t *bd = gd->bd;
	char  bootargscommand[CONFIG_SYS_CBSIZE] = "setenv bootargs ";
	int	  commandlen						 = CONFIG_SYS_CBSIZE - strlen(bootargscommand) - 1;
	char *commandline;

	void (*kernel_entry)(int zero, int arch, uint params);

	/* set bootargs */
	strncat(bootargscommand, BOOTARGS_NFS, commandlen);
	run_command(bootargscommand, 0);

	/***************/
	/* boot Kernel */
	/***************/

	/* set entry point */
	kernel_entry = (void (*)(int, int, uint))CONFIG_KERNEL_LOAD_ADDR;

	commandline = getenv("bootargs");
	check_commandline(commandline);

	/* create TAG */
	setup_tag(bd, commandline, 0);

	cleanup_before_linux ();

	printf("\nStarting kernel...\n\n");

	pmu_clear_reset_flag();

	/* jump to kernel */
	kernel_entry(0, bd->bi_arch_number, bd->bi_boot_params);
}

/* command definition */
U_BOOT_CMD(
	sdboot,  1,  0,  do_sdboot,
	"Boot Linux from SD and NFS mount",
	"\n"
);

#endif /* OPT_CMD_SD_NFS_BOOT */


/****************************/
/*@ PMIC read/write command */
/****************************/

#if (OPT_CMD_PMIC_RW)

/* header files */
#include "../board/emxx/emgr/icx_pwc.h"

/* command entry */
int do_pwcrw(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	unsigned int  addr = 0;
	unsigned char data = 0;
	unsigned char mask = 0xFF;
	int ret;

	if (argc < 2) {
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (argv[1][0] == '-') {
		if (argv[1][1] == 'r') {
			if (argc < 3) {
				printf("Usage:\n%s\n", cmdtp->usage);
				return 1;
			}
			addr = simple_strtoul(argv[2], NULL, 16);
			ret = pwc_read(addr, &data);
			printf(" PWC(%d)[%02X] = %02X\n", ret, addr, data);
		}
		else if (argv[1][1] == 'w') {
			if (argc < 4) {
				printf("Usage:\n%s\n", cmdtp->usage);
				return 1;
			}
			if (argc >= 5) {
				mask = simple_strtoul(argv[4], NULL, 16);
			}
			addr = simple_strtoul(argv[2], NULL, 16);
			data = simple_strtoul(argv[3], NULL, 16);
			ret = pwc_write(addr, data, mask);
			printf(" PWC write(%d)\n", ret);
		}
		else {
			printf("Usage:\n%s\n", cmdtp->usage);
			return 1;
		}
	}
	else {
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	return 0;
}

/* command definition */
U_BOOT_CMD(
    pwcrw   ,  5,  1,  do_pwcrw,
    "Read/Write a data from/to PowerIC",
	"-r [address(0x00-0xFF)]\n"
	"      -w [address(0x00-0xFF)] [data(0x00-0xFF)] <mask(0x00-0xFF)>\n"
);

#endif /* OPT_CMD_PMIC_RW */


/*******************/
/*@ U-Boot writing */
/*******************/

#if (OPT_CMD_UBOOT_WRITE) || (OPT_CMD_KERNEL_WRITE) 
/* header files */
#include "../board/emxx/emgr/mini-boot/include/mmc.h"
#include "../board/emxx/emgr/mini-boot/mmc/mmc.h"
#endif

#if (OPT_CMD_UBOOT_WRITE) && defined(CONFIG_EMXX_EMMCBOOT)

/* command entry */
int do_save_uboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	struct boot_info info;
	MBRecord		 mbr;
	u_int			*siz;
	u_int			*src;
	int				ret;
	char			*s;

	if (argc < 2) {
		s = getenv("fileaddr");
		src = (u_int *)simple_strtoul(s, NULL, 16);
		s = getenv("filesize");
		siz = (u_int *)simple_strtoul(s, NULL, 16);
	}
	else if (argc < 3) {
		s = getenv("filesize");
		siz = (u_int *)simple_strtoul(s, NULL, 16);
	}
	else {
		src = (u_int *)simple_strtoul(argv[1], NULL, 16);
		siz = (u_int *)simple_strtoul(argv[2], NULL, 16);
	}

	/************/
	/* Read MBR */
	/************/

	info.addr  = (unsigned long)&mbr;
	info.block = 0;
	info.size  = MMC_BLOCKLEN_VAL;
	info.erase = 0;
	ret = mmc_read(&info);
	if (ret != 0) {
		printf("Failed to read MBR.\n");
		return 1;
	}

	/********************/
	/* Write IPL/U-Boot */
	/********************/

	info.addr  = (unsigned long)src;
	info.block = mbr.partitionTable[0].firstSectorNumbers;
	info.size  = (unsigned long)siz;
	info.erase = 0;
	ret = mmc_write(&info);
	if (ret != 0) {
		printf("Failed to write IPL/U-Boot.\n");
		return 1;
	}

	/********************************/
	/* Refresh Environment variable */
	/********************************/

	env_init();
	saveenv();

	return 0;
}

/* command definition */
U_BOOT_CMD(
    wruboot ,  3,  1,  do_save_uboot,
    "Write U-Boot to eMMC",
	"[DDR address [Size]]\n"
);

#endif /* OPT_CMD_UBOOT_WRITE */


/*******************/
/*@ Kernel writing */
/*******************/

#if (OPT_CMD_KERNEL_WRITE) && defined(CONFIG_EMXX_EMMCBOOT)

/* command entry */
int do_save_kernel(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	struct boot_info info;
	MBRecord		 mbr;
	u_int			*siz;
	u_int			*src;
	int				ret;
	char			*s;
	int				fwup = 0;

	if (argc < 2) {
		s = getenv("fileaddr");
		src = (u_int *)simple_strtoul(s, NULL, 16);
		s = getenv("filesize");
		siz = (u_int *)simple_strtoul(s, NULL, 16);
	}
	else if (argc < 3) {
		s = getenv("filesize");
		siz = (u_int *)simple_strtoul(s, NULL, 16);
	}
	else {
		src = (u_int *)simple_strtoul(argv[1], NULL, 16);
		siz = (u_int *)simple_strtoul(argv[2], NULL, 16);
	}

	if (argc >= 4) {
		if (argv[3][0] == 'f')
			fwup = 1;
	}

	/************/
	/* Read MBR */
	/************/

	info.addr  = (unsigned long)&mbr;
	info.block = 0;
	info.size  = MMC_BLOCKLEN_VAL;
	info.erase = 0;
	ret = mmc_read(&info);
	if (ret != 0) {
		printf("Failed to read MBR.\n");
		return 1;
	}

	/****************/
	/* Write Kernel */
	/****************/

	info.addr  = (unsigned long)src;
	if (fwup)
		info.block = mbr.partitionTable[0].firstSectorNumbers + FU_KERNEL_AREA_START;
	else
		info.block = mbr.partitionTable[1].firstSectorNumbers;
	info.size  = (unsigned long)siz;
	info.erase = 0;
	ret = mmc_write(&info);
	if (ret != 0) {
		printf("Failed to write Kernel.\n");
		return 1;
	}

	/********************************/
	/* Refresh Environment variable */
	/********************************/

	env_init();
	saveenv();

	return 0;
}

/* command definition */
U_BOOT_CMD(
    wrkernel,  4,  1,  do_save_kernel,
    "Write Kernel to eMMC",
	"[DDR address [Size]] [c(default)/f]\n"
);

#endif /* OPT_CMD_KERNEL_WRITE */


/*****************************/
/*@ Ether chip register dump */
/*****************************/

#if (OPT_CMD_ETHER_REG_DUMP)

#if defined(CONFIG_DRIVER_DM9000)

#include "../drivers/net/dm9000x.h"
#include "../board/emxx/emgr/icx_io.h"

/* command entry */
int do_ethreg(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int i;
	unsigned short data;

	printf("\nVendor Control and Status Register\n");
	printf("=====+=====\n");
	printf(" ADD | VAL \n");
	printf("-----+-----\n");

	for (i = 0x00; i <= 0xFF; i++) {
		if ((i <= 0x1F)
		 || ((0x22 <= i) && (i <= 0x25))
		 || ((0x28 <= i) && (i <= 0x34))
		 || ((0x38 <= i) && (i <= 0x39))
		 || (i == 0x50)
		 || (i >= 0xFC)) {
			outb(i, DM9000_IO);
			data = inb(DM9000_DATA);

			printf("  %02X |  %02X\n", i, (unsigned char)data);
		}
	}
	printf("=====+=====\n\n");

	printf("PHY Register\n");
	printf("=====+======\n");
	printf(" ADD |  VAL \n");
	printf("-----+------\n");

	outb(DM9000_EPCR, DM9000_IO);
	outb(EPCR_EPOS_PHY, DM9000_DATA);
	outb((EPCR_EPOS_PHY | EPCR_ERPRR), DM9000_DATA);

	for (i = 0x00; i <= 0x29; i++) {
		if ((i <= 0x06)
		 || ((0x16 <= i) && (i <= 0x20))
		 || (i == 0x27) 
		 || (i == 0x29)) {
			outb(DM9000_EPAR, DM9000_IO);
			outb((DM9000_PHY | i), DM9000_DATA);

			outb(DM9000_EPCR, DM9000_IO);
			outb(EPCR_EPOS_PHY, DM9000_DATA);
			udelay(50);
			outb((EPCR_EPOS_PHY | EPCR_ERPRR), DM9000_DATA);

			outb(DM9000_EPDRH, DM9000_IO);
			udelay(50);
			data = inb(DM9000_DATA);
			data <<= 8;
			outb(DM9000_EPDRL, DM9000_IO);
			udelay(50);
			data |= inb(DM9000_DATA);

			outb(EPCR_EPOS_PHY, DM9000_DATA);

			printf("  %02X | %04X\n", i, data);
		}
	}
	printf("=====+======\n\n");

	return 0;
}

/* command definition */
U_BOOT_CMD(
	ethreg,  1,  0,  do_ethreg,
	"Monitoring registers of ether chip",
	"\n" 
);

#endif /* CONFIG_DRIVER_DM9000 */

#endif /* OPT_CMD_ETHER_REG_DUMP */


#if defined(CONFIG_ICD)

/******************/
/*@ ICD LCD write */
/******************/

/* prototype */
extern int lcd_uc1611_send_image(const lcdc_config_t* config, int ca, int pa, int col, int row);
extern const lcdc_config_t lcdc_uc_1611_config;

/* command entry */
int do_icd_write_image(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int row = 0;
	int col = 0;
	int x = 0;
	int y = 0;

	/* check the parameters */
	if (argc >= 2) 
		x = simple_strtoul(argv[1], NULL, 10);

	if (argc >= 3) 
		y = simple_strtoul(argv[2], NULL, 10);

	if (argc >= 4) 
		col = simple_strtoul(argv[3], NULL, 10);

	if (argc >= 5) 
		row = simple_strtoul(argv[4], NULL, 10);

	return lcd_uc1611_send_image(&lcdc_uc_1611_config, x, y, col, row);
}

/* command definition */
U_BOOT_CMD(
	lcdimg,	5,	1,	do_icd_write_image,
	"Write a image to LCD",
	"[count ca pa]\n"
);

#endif /* CONFIG_ICD */


/*************/
/*@ LCD test */
/*************/

#if (OPT_CMD_LCD_TEST)

/* header files */
#include "../board/mp200/em1/lcdc.h"
#include "../board/mp200/em1/lcd.h"

/* command entry */
int do_icx_diag_lcd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int deg = 0;
	int ret = 0;

	/* check the parameters */
	if (argc < 2) {
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (argv[1][0] == '-') {
		if (argv[1][1] == 'u') {
			lcd_draw_image(1);
		}
		else if (argv[1][1] == 'b') {
			deg = simple_strtoul(argv[2], NULL, 10);
			ret = lcd_set_brightness(deg, 5000);
			if (ret < 0) {
				printf("Invalid parameter\n");
			}
		}
		else {
			printf("Usage:\n%s\n", cmdtp->usage);
			return 1;
		}
	}
	else {
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	return ret;
}

/* command definition */
U_BOOT_CMD(
	lcd,	3,	1,	do_icx_diag_lcd,
	"lcd     - LCD test\n",
	"\n-u\n"
	"	- update image\n"
	"-b [0-100]\n"
	"	- LCD backlight test\n"
);

#endif /* OPT_CMD_LCD_TEST */


/*************/
/*@ ADC test */
/*************/

#if (OPT_CMD_ADC_TEST)

/* header files */
#include "../board/emxx/emgr/icx_adc.h"
#include "../board/emxx/emgr/icx_key.h"

/* command entry */
int do_icx_diag_ad(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	unsigned int  val = 0xFF;
	unsigned int  holdstat;
	int ret;

	/* get KEY */
	ret = adc_read(ADC_CH_7, &val);
	if (ret == 0) {
		printf(" KEY_AD7 : %02Xh\n", val);

		ret = adc_read(ADC_CH_8, &val);
		if (ret == 0) {
			printf(" KEY_AD8 : %02Xh\n", val);
		}
		else {
			printf(" Failed to get KEY_AD8(%d)\n", ret);
		}
	}
	else {
		printf(" Failed to get KEY_AD7(%d)\n", ret);
	}

	/* get HOLD */
	holdstat = key_get_hold_state(NULL);
	printf(" HOLD : %08Xh\n", holdstat);

	/* get batt */
	ret = adc_read(ADC_CH_3, &val);
	if (ret == 0) {
		printf(" BAT_AD3 : %d\n", val);
	}
	else {
		printf(" Failed to get BAT_AD3(%d)\n", ret);
	}

	return ret;
}

/* command definition */
U_BOOT_CMD(
	adc,	1,	1,	do_icx_diag_ad,
	"print KEY code and battery value",
	"\n"
);

#endif /* OPT_CMD_ADC_TEST */

#endif /* CONFIG_CMD_ICX || CONFIG_CMD_ICD */

