/*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
* *
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.
* *
Description:
*/


#include <common.h>
#include <command.h>
#include <asm/saradc.h>

#define SARADC_VALUE "saradc_val"


static int current_channel = -1;

static int do_saradc_open(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int channel;
	channel = simple_strtoul(argv[1], NULL, 10);
	if ((channel < 0) || (channel >= AML_ADC_SARADC_CHAN_NUM))
	{
		printf("No such channel(%d) in SARADC! open failed!\n", channel);
		return -1;
	}
	saradc_enable();
	current_channel = channel;
//	printf("SARADC open channel(%d).\n", channel);
	return 0;
}

static int do_saradc_close(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	saradc_disable();
	current_channel = -1;
	printf("SARADC closed.\n");
	return 0;
}

static int do_saradc_getval(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char value_str[10];
	int val = get_adc_sample_gxbb(current_channel);
	printf("SARADC channel(%d) is 0x%x.\n", current_channel, val);
	sprintf(value_str, "0x%x", val);
	setenv(SARADC_VALUE, value_str);
	return 0;
}

static int do_saradc_getval_12bit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char value_str[10];
	int val = get_adc_sample_gxbb_12bit(current_channel);
	printf("SARADC channel(%d) is 0x%x.\n", current_channel, val);
	sprintf(value_str, "0x%x", val);
	setenv(SARADC_VALUE, value_str);
	return 0;
}

static int do_saradc_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	saradc_sample_test();
	return 0;
}
static int do_saradc_get_in_range(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char value_str[10];
	int max, min;
	int val = get_adc_sample_gxbb(current_channel);
	min = simple_strtoul(argv[1], NULL, 10);
	max = simple_strtoul(argv[2], NULL, 10);
	int donot_setenv = 0;
	if (argc > 3) {
		donot_setenv = simple_strtoul(argv[2], NULL, 10);
	}
	if ((val<min) || (val>max)) {
		debug("SARADC channel(%d) is 0x%x, Out of range(0x%x~0x%x)!\n",
			current_channel, val, min, max);
		return -1;
	}
	debug("SARADC channel(%d) is 0x%x (0x%x~0x%x).\n",
		current_channel, val, min, max);
	sprintf(value_str, "0x%x", val);
	if (!donot_setenv)
		setenv(SARADC_VALUE, value_str);
	return 0;
}

static int do_saradc_get_in_range_12bit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char value_str[10];
	int max, min;
	int val = get_adc_sample_gxbb_12bit(current_channel);
	min = simple_strtoul(argv[1], NULL, 10);
	max = simple_strtoul(argv[2], NULL, 10);
	int donot_setenv = 0;
	if (argc > 3) {
		donot_setenv = simple_strtoul(argv[2], NULL, 10);
	}
	if ((val<min) || (val>max)) {
		debug("SARADC channel(%d) is 0x%x, Out of range(0x%x~0x%x)!\n",
			current_channel, val, min, max);
		return -1;
	}
	debug("SARADC channel(%d) is 0x%x (0x%x~0x%x).\n",
		current_channel, val, min, max);
	sprintf(value_str, "0x%x", val);
	if (!donot_setenv)
		setenv(SARADC_VALUE, value_str);
	return 0;
}

static cmd_tbl_t cmd_saradc_sub[] = {
	U_BOOT_CMD_MKENT(open, 2, 0, do_saradc_open, "", ""),
	U_BOOT_CMD_MKENT(close, 1, 0, do_saradc_close, "", ""),
	U_BOOT_CMD_MKENT(getval, 1, 0, do_saradc_getval, "", ""),
	U_BOOT_CMD_MKENT(test, 1, 0, do_saradc_test, "", ""),
	U_BOOT_CMD_MKENT(get_in_range, 3, 0, do_saradc_get_in_range, "", ""),
};


static int do_saradc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	cmd_tbl_t *c;
	/* Strip off leading 'bmp' command argument */
	argc--;
	argv++;
	c = find_cmd_tbl(argv[0], &cmd_saradc_sub[0], ARRAY_SIZE(cmd_saradc_sub));
	if (c) {
		return	c->cmd(cmdtp, flag, argc, argv);
	} else {
		cmd_usage(cmdtp);
		return 1;
	}
}

U_BOOT_CMD(
	saradc,	8,	0,	do_saradc,
	"saradc sub-system",
	"saradc open <channel>	- open a SARADC channel\n"
	"saradc close	- close the SARADC\n"
	"saradc getval	- get the value in current channel\n"
	"saradc test	- test the SARADC by channel-7\n"
	"saradc get_in_range <min> <max>	- return 0 if current value in the range of current channel\n"
);

static cmd_tbl_t cmd_saradc_12bit_sub[] = {
	U_BOOT_CMD_MKENT(open, 2, 0, do_saradc_open, "", ""),
	U_BOOT_CMD_MKENT(close, 1, 0, do_saradc_close, "", ""),
	U_BOOT_CMD_MKENT(getval, 1, 0, do_saradc_getval_12bit, "", ""),
	U_BOOT_CMD_MKENT(get_in_range, 3, 0, do_saradc_get_in_range_12bit, "", ""),
};

static int do_saradc_12bit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	cmd_tbl_t *c;
	/* Strip off leading 'bmp' command argument */
	argc--;
	argv++;
	c = find_cmd_tbl(argv[0], &cmd_saradc_12bit_sub[0], ARRAY_SIZE(cmd_saradc_12bit_sub));
	if (c) {
		return	c->cmd(cmdtp, flag, argc, argv);
	} else {
		cmd_usage(cmdtp);
		return 1;
	}
}

U_BOOT_CMD(
	saradc_12bit,	8,	0,	do_saradc_12bit,
	"saradc sub-system",
	"saradc_12bit open <channel>	- open a SARADC channel\n"
	"saradc_12bit close	- close the SARADC\n"
	"saradc_12bit getval	- get the value in current channel\n"
	"saradc_12bit get_in_range <min> <max>	- return 0 if current value in the range of current channel\n"
);

