/*
 * Copyright C 2011 by Amlogic, Inc.
 *
 * 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
 *
 *
 * Remark: migrate from trunk by Hisun Bao 2011.07.29
 *
 */
#include <config.h>
#include <common.h>
#include <asm/arch/io.h>
#include <asm/saradc.h>
#include <asm/cpu_id.h>
#include <asm/arch/secure_apb.h>
#ifdef CONFIG_OF_LIBFDT
#include <libfdt.h>
#endif

//#define ENABLE_DYNAMIC_POWER

#define AML_ADC_SAMPLE_DEBUG 0
#define FDT_DEFAULT_ADDRESS  0x01000000

#define P_SAR_ADC_REG0(base)		    (base + (0x0))
#define P_SAR_ADC_CHAN_LIST(base)		(base + (0x1))
#define P_SAR_ADC_AVG_CNTL(base)		(base + (0x2))
#define P_SAR_ADC_REG3(base)			(base + (0x3))
#define P_SAR_ADC_DELAY(base)			(base + (0x4))
#define P_SAR_ADC_LAST_RD(base)			(base + (0x5))
#define P_SAR_ADC_FIFO_RD(base)			(base + (0x6))
#define P_SAR_ADC_AUX_SW(base)			(base + (0x7))
#define P_SAR_ADC_CHAN_10_SW(base)		(base + (0x8))
#define P_SAR_ADC_DETECT_IDLE_SW(base)	(base + (0x9))
#define P_SAR_ADC_DELTA_10(base)		(base + (0xa))
#define P_SAR_ADC_REG11(base)			(base + (0xb))
#define P_SAR_ADC_REG13(base)			(base + (0xd))

#define SARADC_STATE_IDLE 0
#define SARADC_STATE_BUSY 1
#define SARADC_STATE_SUSPEND 2

#define FLAG_INITIALIZED    (1<<28)
//#define FLAG_BUSY (1<<29)
#define FLAG_BUSY_KERNEL    (1<<14) /* for kernel:SARADC_DELAY 14bit */
#define FLAG_BUSY_KERNEL_BIT  14
#define FLAG_BUSY_BL30      (1<<15) /* for bl30:SARADC_DELAY 15bit*/

typedef struct {
	unsigned char channel;
	unsigned char adc_type; /*1:12bit;0:10bit*/
	u32 __iomem *saradc_clk_addr;
	u32 __iomem *saradc_base_addr;
}saradc_info;

static saradc_info saradc_dev;

static __inline__ void aml_set_reg32_bits(volatile unsigned int *_reg, const uint32_t _value, const uint32_t _start, const uint32_t _len)
{
	writel(( (readl((volatile unsigned int *)_reg) & ~((( 1L << (_len) )-1) << (_start))) | ((unsigned)((_value)&((1L<<(_len))-1)) << (_start))), (volatile void *)_reg );
}
static __inline__ uint32_t aml_get_reg32_bits(volatile unsigned int *_reg, const uint32_t _start, const uint32_t _len)
{
	return	( (readl((volatile unsigned int *)_reg) >> (_start)) & (( 1L << (_len) ) - 1) );
}
static __inline__ void aml_write_reg32( volatile unsigned int *_reg, const uint32_t _value)
{
	writel( _value,(volatile unsigned int *)_reg );
};
static __inline__ uint32_t aml_read_reg32(volatile unsigned int *_reg)
{
	return readl((volatile unsigned int *)_reg);
};

saradc_info *saradc_dev_get(void)
{
	return &saradc_dev;
}

/*
  * description: used to enable and disable the clock of the SARADC
  * onoff: 1: enable ; 0: disable
  */
void saradc_clock_switch( int onoff)
{
	saradc_info *saradc = saradc_dev_get();

	if (onoff) {
		if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_GXBB) /*GXBB's clock from the clock tree.*/
			aml_set_reg32_bits(saradc->saradc_clk_addr,1,8,1);
		else
			aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->saradc_base_addr),1,30,1);
	} else {
		if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_GXBB) /*GXBB's clock from the clock tree.*/
			aml_set_reg32_bits(saradc->saradc_clk_addr,0,8,1);
		else
			aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->saradc_base_addr),0,30,1);
	}
}

/*
 * description: used to set the DIV of the clock
 */
void saradc_clock_set(unsigned char val)
{
	saradc_info *saradc = saradc_dev_get();

	if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_GXBB) {
		aml_set_reg32_bits(saradc->saradc_clk_addr, 0, 9, 2);  /*bit9-bit10: select clk source*/
		aml_set_reg32_bits(saradc->saradc_clk_addr, (val & 0xff), 0, 8);/*bit0-bit7:   set clk div*/
	} else {
		aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->saradc_base_addr), (val & 0x3f), 10, 6); /*bit10-bit15: set clk div*/
	}
}

static inline void saradc_power_control(int on)
{
	saradc_info *saradc = saradc_dev_get();

	if (on) {
		aml_set_reg32_bits(P_SAR_ADC_REG11(saradc->saradc_base_addr),1,13,1);
		aml_set_reg32_bits(P_SAR_ADC_REG11(saradc->saradc_base_addr),3,5,2);
		aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->saradc_base_addr),1,21,1);

		udelay(5);
		saradc_clock_switch(1);
	}	else {
		saradc_clock_switch(0);
		/*aml_set_reg32_bits(PP_SAR_ADC_REG11(saradc->saradc_base_addr),0,13,1);*//* disable bandgap */
		/*aml_set_reg32_bits(P_SAR_ADC_REG11(saradc->saradc_base_addr),0,5,2);*/
	}
}

void saradc_hw_init(void)
{
	saradc_info *saradc = saradc_dev_get();

	if (get_cpu_id().family_id <= MESON_CPU_MAJOR_ID_GXTVBB)
		saradc->adc_type = 0;
	else
		saradc->adc_type = 1;

	aml_write_reg32(P_SAR_ADC_REG0(saradc->saradc_base_addr), 0x84004040);
	aml_write_reg32(P_SAR_ADC_CHAN_LIST(saradc->saradc_base_addr), 0);
	/* REG2: all chanel set to 8-samples & median averaging mode */
	aml_write_reg32(P_SAR_ADC_AVG_CNTL(saradc->saradc_base_addr), 0);
	aml_write_reg32(P_SAR_ADC_REG3(saradc->saradc_base_addr), 0x9388000a);
	aml_write_reg32(P_SAR_ADC_DELAY(saradc->saradc_base_addr), 0x10a000a);
	aml_write_reg32(P_SAR_ADC_AUX_SW(saradc->saradc_base_addr), 0x3eb1a0c);
	aml_write_reg32(P_SAR_ADC_CHAN_10_SW(saradc->saradc_base_addr), 0x8c000c);
	aml_write_reg32(P_SAR_ADC_DETECT_IDLE_SW(saradc->saradc_base_addr), 0xc000c);

	if (saradc->adc_type)
		aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->saradc_base_addr),0x1,27,1);

	/*select VDDA as ref voltage, otherwise select calibration voltage*/
	if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_TXLX)
		aml_set_reg32_bits(P_SAR_ADC_REG11(saradc->saradc_base_addr),0x1,0,1);

	saradc_clock_set(20);

#if AML_ADC_SAMPLE_DEBUG
	printf("ADCREG reg0 =%x\n",   aml_read_reg32(P_SAR_ADC_REG0(saradc->saradc_base_addr)));
	printf("ADCREG ch list =%x\n",aml_read_reg32(P_SAR_ADC_CHAN_LIST(saradc->saradc_base_addr)));
	printf("ADCREG avg  =%x\n",   aml_read_reg32(P_SAR_ADC_AVG_CNTL(saradc->saradc_base_addr)));
	printf("ADCREG reg3 =%x\n",   aml_read_reg32(P_SAR_ADC_REG3(saradc->saradc_base_addr)));
	printf("ADCREG ch72 sw =%x\n",aml_read_reg32(P_SAR_ADC_AUX_SW(saradc->saradc_base_addr)));
	printf("ADCREG ch10 sw =%x\n",aml_read_reg32(P_SAR_ADC_CHAN_10_SW(saradc->saradc_base_addr)));
	printf("ADCREG detect&idle=%x\n",aml_read_reg32(P_SAR_ADC_DETECT_IDLE_SW(saradc->saradc_base_addr)));
	printf("ADCREG GXBB_CLK_REG=%x\n",aml_read_reg32(saradc->saradc_clk_addr));
#endif //AML_ADC_SAMPLE_DEBUG

}

int saradc_probe(void)
{
	int ret;
	int len;
	int parent_offset;
	char *fdt_addr;
	u32 *reg_addr;
	int saradc_fdt_ready = 0;
	unsigned long temp_addr;
	saradc_info *saradc = saradc_dev_get();

#ifdef CONFIG_OF_LIBFDT
#ifdef CONFIG_DTB_MEM_ADDR
	fdt_addr = (char *)CONFIG_DTB_MEM_ADDR;
#else
	fdt_addr = (char *)FDT_DEFAULT_ADDRESS;
#endif
	if ((ret = fdt_check_header((const void *)fdt_addr)) < 0) {
		printf("saradc: check dts: %s, load default parameters\n",
			fdt_strerror(ret));
	}else{
		saradc_fdt_ready = 1;
	}
#endif

	if (saradc_fdt_ready) {
#ifdef CONFIG_OF_LIBFDT
		parent_offset = fdt_path_offset(fdt_addr, "/saradc");
		if (parent_offset < 0) {
			printf("saradc: not find the node /saradc: %s\n",fdt_strerror(parent_offset));
			return -1;
		}

		reg_addr = (u32 *)fdt_getprop(fdt_addr, parent_offset, "reg", &len);
		if (NULL == reg_addr) {
			printf("saradc: failed to get /saradc\n");
			return -1;
		}
	   /*
		*  To avoid error "-Werror=int-to-pointer" when this code is compiled,
		*  and use the variable of type 'unsigned long' to save the address, then cast 'unsigned long' to 'pointer' type."
		*/
		temp_addr = fdt32_to_cpu(reg_addr[5]); /*big-endian to little-endian*/
		saradc->saradc_clk_addr = (u32 __iomem *)(temp_addr & 0xffffffff);
		temp_addr = fdt32_to_cpu(reg_addr[1]); /*big-endian to little-endian*/
		saradc->saradc_base_addr = (u32 __iomem *)(temp_addr & 0xffffffff);
#endif
	} else {
		saradc->saradc_clk_addr =  (u32 __iomem *)AO_SAR_CLK;
		saradc->saradc_base_addr = (u32 __iomem *)AO_SAR_ADC_REG0;
	}

	saradc_hw_init();

	return 0;

}

static void saradc_internal_cal_12bit(void)
{
	int val[5]/*, nominal[5] = {0, 1024, 2048, 3072, 4096}*/;
	int i;
	int abs_val = 4096;
	unsigned int abs_num = 0;
	unsigned int abs_tmp = 0;
	saradc_info *saradc = saradc_dev_get();

	/* set CAL_CNTL: 3/4 VDD*/
	aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->saradc_base_addr),3,23,3);

	for (i = 0; i < 64; i++) {
		aml_set_reg32_bits(P_SAR_ADC_REG13(saradc->saradc_base_addr),i,8,6);
		udelay(5);
		val[0] = get_adc_sample_gxbb_12bit(7);
		abs_tmp = abs(2764 - val[0]);
		if (abs_tmp < abs_val) {
			abs_val = abs_tmp;
			abs_num = i;
		}
	}
	aml_set_reg32_bits(P_SAR_ADC_REG13(saradc->saradc_base_addr),abs_num,8,6);
}
//#define NOT_USE_SINA_DETECT 1
//#define CLK_DIV 19

/*
  * description: used to get sampling value
  * ch: set channel
  * use_10bit_num: set the bits of the sampling value(1:10bit; 0:12bit)
  */
int get_adc_sample_gxbb_early(int ch, int use_10bit_num)
{
	int value, count, sum;
	//unsigned long flags;
	//int adc_state = SARADC_STATE_BUSY;
	saradc_info *saradc = saradc_dev_get();

	count = 0;
	while (aml_read_reg32(P_SAR_ADC_DELAY(saradc->saradc_base_addr)) & FLAG_BUSY_BL30) {
		udelay(100);
		if (++count > 100) {
			printf("bl30 busy error\n");
			value = -1;
			goto end1;
		}
	}
	saradc_clock_switch(0);
	saradc_clock_set(0xa0);
	saradc_clock_switch(1);

	aml_set_reg32_bits(P_SAR_ADC_DELAY(saradc->saradc_base_addr),1,FLAG_BUSY_KERNEL_BIT,1);
	aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->saradc_base_addr),1,29,1);

	aml_write_reg32(P_SAR_ADC_CHAN_LIST(saradc->saradc_base_addr), ch);
	aml_write_reg32(P_SAR_ADC_DETECT_IDLE_SW(saradc->saradc_base_addr), (0xc000c | (ch<<23) | (ch<<7)));
	aml_set_reg32_bits(P_SAR_ADC_REG0(saradc->saradc_base_addr), 1,0,1);
	aml_set_reg32_bits(P_SAR_ADC_REG0(saradc->saradc_base_addr), 1,2,1);

	count = 0;
	do {
		udelay(10);
		if (!(aml_read_reg32(P_SAR_ADC_REG0(saradc->saradc_base_addr)) & 0x70000000))
			break;
		else if (++count > 10000) {
			printf("busy error=%x\n", aml_read_reg32(P_SAR_ADC_REG0(saradc->saradc_base_addr)));
			value = -1;
			goto end;
		}
	} while (1);

	count = 0;
	sum = 0;
	while (aml_get_reg32_bits(P_SAR_ADC_REG0(saradc->saradc_base_addr),21,5) && (count < 32)) {
		if (aml_get_reg32_bits(P_SAR_ADC_REG0(saradc->saradc_base_addr),26,1))
			printf("fifo_count, but fifo empty\n");

		value = aml_read_reg32(P_SAR_ADC_FIFO_RD(saradc->saradc_base_addr));
		if (((value>>12) & 0x07) == ch) {
			if (use_10bit_num) {
				//printf("10bit val~\n");
				if (saradc->adc_type) {
					value &= 0xffc;
					value >>= 2;
				} else
					value &= 0x3ff;
		} else {
				//printf("12bit val~\n");
				value &= 0xfff;
			}

			sum += value;
			count++;
		}	else
			printf("chanel error\n");
	}
	if (!aml_get_reg32_bits(P_SAR_ADC_REG0(saradc->saradc_base_addr),26,1))
		printf("fifo_count=0, but fifo not empty\n");
	if (!count) {
		value = -1;
		goto end;
	}
	value = sum / count;
	//printf("before cal: %d, count=%d\n", value, count);
	//value = saradc_get_cal_value(adc, value);
end:
	aml_set_reg32_bits(P_SAR_ADC_REG0(saradc->saradc_base_addr),1,14,1);
	aml_set_reg32_bits(P_SAR_ADC_REG0(saradc->saradc_base_addr),0,0,1);

	saradc_clock_switch(0);
	saradc_clock_set(20);
	saradc_clock_switch(1);

end1:
	aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->saradc_base_addr),0,29,1);
	//adc_state = SARADC_STATE_IDLE;
	aml_set_reg32_bits(P_SAR_ADC_DELAY(saradc->saradc_base_addr),0,FLAG_BUSY_KERNEL_BIT,1);
	return value;
}

int get_adc_sample_gxbb(int ch)
{
	int val;

	val = get_adc_sample_gxbb_early(ch, 1);
	return val;
}

int get_adc_sample_gxbb_12bit(int ch)
{
	int val;

	val = get_adc_sample_gxbb_early(ch, 0);
	return val;

}

int saradc_enable(void)
{
	saradc_probe();
	saradc_power_control(1);
	udelay(10);
	saradc_internal_cal_12bit();
	return 0;
}

int saradc_disable(void)
{
	saradc_power_control(0);
	return 0;
}
