/*
 * 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
 *
 *
 */
#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 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 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*/

static const char * const ch7_vol[] = {
	"gnd",
	"vdd/4",
	"vdd/2",
	"vdd*3/4",
	"vdd",
};

typedef struct {
	unsigned char channel;
	unsigned char adc_type; /*1:12bit; 0:10bit*/
	u32 __iomem *clk_addr;
	u32 __iomem *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)
			aml_set_reg32_bits(saradc->clk_addr, 1, 8, 1);
		else
			aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->base_addr), 1, 30, 1);
	} else {
		if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_GXBB)
			aml_set_reg32_bits(saradc->clk_addr, 0, 8, 1);
		else
			aml_set_reg32_bits(P_SAR_ADC_REG3(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) {
		/*bit[0-7]: set clk div; bit[9-10]: select clk source*/
		aml_set_reg32_bits(saradc->clk_addr, 0, 9, 2);
		aml_set_reg32_bits(saradc->clk_addr, (val & 0xff), 0, 8);
	} else {
		/*bit10-bit15: set clk div*/
		aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->base_addr),
			(val & 0x3f), 10, 6);
	}
}

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->base_addr), 1, 13, 1);
		if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_G12A)
			aml_set_reg32_bits(P_SAR_ADC_REG11(saradc->base_addr), 0, 5, 2);
		else
			aml_set_reg32_bits(P_SAR_ADC_REG11(saradc->base_addr), 3, 5, 2);
		aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->base_addr), 1, 21, 1);

		udelay(5);
		saradc_clock_switch(1);
	}	else {
		saradc_clock_switch(0);
		aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->base_addr), 0, 21, 1);
		/*aml_set_reg32_bits(PP_SAR_ADC_REG11(saradc->base_addr),0,13,1);*/
		/*aml_set_reg32_bits(P_SAR_ADC_REG11(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->base_addr), 0x84004040);
	aml_write_reg32(P_SAR_ADC_CHAN_LIST(saradc->base_addr), 0);
	/* REG2: all chanel set to 8-samples & median averaging mode */
	aml_write_reg32(P_SAR_ADC_AVG_CNTL(saradc->base_addr), 0);
	aml_write_reg32(P_SAR_ADC_REG3(saradc->base_addr), 0x9388000a);
	aml_write_reg32(P_SAR_ADC_DELAY(saradc->base_addr), 0x10a000a);
	aml_write_reg32(P_SAR_ADC_AUX_SW(saradc->base_addr), 0x3eb1a0c);
	aml_write_reg32(P_SAR_ADC_CHAN_10_SW(saradc->base_addr), 0x8c000c);
	aml_write_reg32(P_SAR_ADC_DETECT_IDLE_SW(saradc->base_addr), 0xc000c);

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

	saradc_clock_set(20);
}

int saradc_probe(void)
{
	int ret;
	int len;
	int elems;
	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."
		*/
		elems = len / sizeof(u32);
		if (elems == 4)
			saradc->clk_addr = (u32 __iomem *)AO_SAR_CLK;
		else if (elems == 8) {
			temp_addr = fdt32_to_cpu(reg_addr[5]); /*big-endian to little-endian*/
			saradc->clk_addr = (u32 __iomem *)(temp_addr & 0xffffffff);
		} else {
			printf("saradc: invalid size of property 'reg'\n");
			return -1;
		}
		temp_addr = fdt32_to_cpu(reg_addr[1]); /*big-endian to little-endian*/
		saradc->base_addr = (u32 __iomem *)(temp_addr & 0xffffffff);
#endif
	} else {
		saradc->clk_addr =  (u32 __iomem *)AO_SAR_CLK;
		saradc->base_addr = (u32 __iomem *)AO_SAR_ADC_REG0;
	}

	saradc_hw_init();

	return 0;

}

static void saradc_internal_cal_12bit(void)
{
	/*reference voltage has been calibrated by BL2, there is nothing to do*/
}

int saradc_value_trim(int val)
{
	int tmp;

	switch (get_cpu_id().family_id) {
	case MESON_CPU_MAJOR_ID_GXL:
	case MESON_CPU_MAJOR_ID_GXM:
	case MESON_CPU_MAJOR_ID_TXL:
		tmp = val * 3072 / 2764;
		return (tmp < 1024) ? tmp : 1023;
	break;

	default:
		return val;
	break;
	}
}

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

	count = 0;

	while (aml_read_reg32(P_SAR_ADC_DELAY(saradc->base_addr)) & FLAG_BUSY_BL30) {
		udelay(10);
		if (++count > 1000) {
			printf("bl30 busy error\n");
			value = -1;
			goto end1;
		}
	}

	aml_set_reg32_bits(P_SAR_ADC_DELAY(saradc->base_addr), 1,
		FLAG_BUSY_KERNEL_BIT, 1);

	saradc_clock_switch(0);
	saradc_clock_set(0xa0);
	saradc_clock_switch(1);

	aml_write_reg32(P_SAR_ADC_CHAN_LIST(saradc->base_addr), ch);
	aml_write_reg32(P_SAR_ADC_DETECT_IDLE_SW(saradc->base_addr),
		(0xc000c | (ch<<23) | (ch<<7)));
	aml_set_reg32_bits(P_SAR_ADC_REG0(saradc->base_addr), 1, 0, 1);
	aml_set_reg32_bits(P_SAR_ADC_REG0(saradc->base_addr), 1, 2, 1);
	count = 0;
	do {
		udelay(10);
		if (!(aml_read_reg32(P_SAR_ADC_REG0(saradc->base_addr)) & 0x70000000))
			break;
		else if (++count > 10000) {
			printf("busy error = %x\n",
				aml_read_reg32(P_SAR_ADC_REG0(saradc->base_addr)));
			value = -1;
			goto end;
		}
	} while (1);

	count = 0;
	sum = 0;
	while (aml_get_reg32_bits(P_SAR_ADC_REG0(saradc->base_addr), 21, 5) && \
			(count < 32)) {
		value = aml_read_reg32(P_SAR_ADC_FIFO_RD(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("channel error\n");
	}

	if (!count) {
		value = -1;
		goto end;
	}
	value = sum / count;
end:
	aml_set_reg32_bits(P_SAR_ADC_REG0(saradc->base_addr), 1, 14, 1);
	aml_set_reg32_bits(P_SAR_ADC_REG0(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_DELAY(saradc->base_addr), 0,
		FLAG_BUSY_KERNEL_BIT, 1);

	return saradc_value_trim(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;
}

void saradc_sample_test(void)
{
	int i;
	int val;
	saradc_info *saradc = saradc_dev_get();

	printf("ch7 sample test:\n");
	saradc_enable();
	for (i = 0; i < ARRAY_SIZE(ch7_vol); i++) {
		aml_set_reg32_bits(P_SAR_ADC_REG3(saradc->base_addr), i, 23, 3);
		udelay(10);
		val = get_adc_sample_gxbb(7);
		printf("%-7s : %d\n", ch7_vol[i], val);
	}
	saradc_disable();
}
