// SPDX-License-Identifier: GPL-2.0+
/*
 *  Copyright (C) 2010 Samsung Electronics
 *  Minkyu Kang <mk7.kang@samsung.com>
 *  Kyungmin Park <kyungmin.park@samsung.com>
 */

#include <common.h>
#include <env.h>
#include <log.h>
#include <spi.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/adc.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/watchdog.h>
#include <linux/delay.h>
#include <power/pmic.h>
#include <usb.h>
#include <usb/dwc2_udc.h>
#include <asm/arch/cpu.h>
#include <power/max8998_pmic.h>
#include <libtizen.h>
#include <samsung/misc.h>
#include <usb_mass_storage.h>
#include <asm/mach-types.h>

DECLARE_GLOBAL_DATA_PTR;

unsigned int board_rev;
static int init_pmic_lcd(void);

#ifdef CONFIG_REVISION_TAG
u32 get_board_rev(void)
{
	return board_rev;
}
#endif

int exynos_power_init(void)
{
	return init_pmic_lcd();
}

static int get_hwrev(void)
{
	return board_rev & 0xFF;
}

static unsigned short get_adc_value(int channel)
{
	struct s5p_adc *adc = (struct s5p_adc *)samsung_get_base_adc();
	unsigned short ret = 0;
	unsigned int reg;
	unsigned int loop = 0;

	writel(channel & 0xF, &adc->adcmux);
	writel((1 << 14) | (49 << 6), &adc->adccon);
	writel(1000 & 0xffff, &adc->adcdly);
	writel(readl(&adc->adccon) | (1 << 16), &adc->adccon); /* 12 bit */
	udelay(10);
	writel(readl(&adc->adccon) | (1 << 0), &adc->adccon); /* Enable */
	udelay(10);

	do {
		udelay(1);
		reg = readl(&adc->adccon);
	} while (!(reg & (1 << 15)) && (loop++ < 1000));

	ret = readl(&adc->adcdat0) & 0xFFF;

	return ret;
}

static int adc_power_control(int on)
{
	struct udevice *dev;
	int ret;
	u8 reg;

	ret = pmic_get("max8998-pmic", &dev);
	if (ret) {
		puts("Failed to get MAX8998!\n");
		return ret;
	}

	reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
	if (on)
		reg |= MAX8998_LDO4;
	else
		reg &= ~MAX8998_LDO4;

	ret = pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
	if (ret) {
		puts("MAX8998 LDO setting error\n");
		return -EINVAL;
	}

	return 0;
}

static unsigned int get_hw_revision(void)
{
	int hwrev, mode0, mode1;

	adc_power_control(1);

	mode0 = get_adc_value(1);		/* HWREV_MODE0 */
	mode1 = get_adc_value(2);		/* HWREV_MODE1 */

	/*
	 * XXX Always set the default hwrev as the latest board
	 * ADC = (voltage) / 3.3 * 4096
	 */
	hwrev = 3;

#define IS_RANGE(x, min, max)	((x) > (min) && (x) < (max))
	if (IS_RANGE(mode0, 80, 200) && IS_RANGE(mode1, 80, 200))
		hwrev = 0x0;		/* 0.01V	0.01V */
	if (IS_RANGE(mode0, 750, 1000) && IS_RANGE(mode1, 80, 200))
		hwrev = 0x1;		/* 610mV	0.01V */
	if (IS_RANGE(mode0, 1300, 1700) && IS_RANGE(mode1, 80, 200))
		hwrev = 0x2;		/* 1.16V	0.01V */
	if (IS_RANGE(mode0, 2000, 2400) && IS_RANGE(mode1, 80, 200))
		hwrev = 0x3;		/* 1.79V	0.01V */
#undef IS_RANGE

	debug("mode0: %d, mode1: %d, hwrev 0x%x\n", mode0, mode1, hwrev);

	adc_power_control(0);

	return hwrev;
}

static void check_hw_revision(void)
{
	int hwrev;

	hwrev = get_hw_revision();

	board_rev |= hwrev;
}

#ifdef CONFIG_USB_GADGET
static int s5pc210_phy_control(int on)
{
	struct udevice *dev;
	int ret;
	u8 reg;

	ret = pmic_get("max8998-pmic", &dev);
	if (ret) {
		puts("Failed to get MAX8998!\n");
		return ret;
	}

	if (on) {
		reg = pmic_reg_read(dev, MAX8998_REG_BUCK_ACTIVE_DISCHARGE3);
		reg |= MAX8998_SAFEOUT1;
		ret |= pmic_reg_write(dev,
			MAX8998_REG_BUCK_ACTIVE_DISCHARGE3, reg);

		reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
		reg |= MAX8998_LDO3;
		ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);

		reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
		reg |= MAX8998_LDO8;
		ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);

	} else {
		reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
		reg &= ~MAX8998_LDO8;
		ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);

		reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
		reg &= ~MAX8998_LDO3;
		ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);

		reg = pmic_reg_read(dev, MAX8998_REG_BUCK_ACTIVE_DISCHARGE3);
		reg &= ~MAX8998_SAFEOUT1;
		ret |= pmic_reg_write(dev,
			MAX8998_REG_BUCK_ACTIVE_DISCHARGE3, reg);
	}

	if (ret) {
		puts("MAX8998 LDO setting error!\n");
		return -EINVAL;
	}

	return 0;
}

struct dwc2_plat_otg_data s5pc210_otg_data = {
	.phy_control = s5pc210_phy_control,
	.regs_phy = EXYNOS4_USBPHY_BASE,
	.regs_otg = EXYNOS4_USBOTG_BASE,
	.usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL,
	.usb_flags = PHY0_SLEEP,
};
#endif

int board_usb_init(int index, enum usb_init_type init)
{
	debug("USB_udc_probe\n");
	return dwc2_udc_probe(&s5pc210_otg_data);
}

int exynos_early_init_f(void)
{
	wdt_stop();

	return 0;
}

static int init_pmic_lcd(void)
{
	struct udevice *dev;
	unsigned char val;
	int ret = 0;

	ret = pmic_get("max8998-pmic", &dev);
	if (ret) {
		puts("Failed to get MAX8998 for init_pmic_lcd()!\n");
		return ret;
	}

	/* LDO7 1.8V */
	val = 0x02; /* (1800 - 1600) / 100; */
	ret |= pmic_reg_write(dev,  MAX8998_REG_LDO7, val);

	/* LDO17 3.0V */
	val = 0xe; /* (3000 - 1600) / 100; */
	ret |= pmic_reg_write(dev,  MAX8998_REG_LDO17, val);

	/* Disable unneeded regulators */
	/*
	 * ONOFF1
	 * Buck1 ON, Buck2 OFF, Buck3 ON, Buck4 ON
	 * LDO2 ON, LDO3 OFF, LDO4 OFF, LDO5 ON
	 */
	val = 0xB9;
	ret |= pmic_reg_write(dev,  MAX8998_REG_ONOFF1, val);

	/* ONOFF2
	 * LDO6 OFF, LDO7 ON, LDO8 OFF, LDO9 ON,
	 * LDO10 OFF, LDO11 OFF, LDO12 OFF, LDO13 OFF
	 */
	val = 0x50;
	ret |= pmic_reg_write(dev,  MAX8998_REG_ONOFF2, val);

	/* ONOFF3
	 * LDO14 OFF, LDO15 OFF, LGO16 OFF, LDO17 OFF
	 * EPWRHOLD OFF, EBATTMON OFF, ELBCNFG2 OFF, ELBCNFG1 OFF
	 */
	val = 0x00;
	ret |= pmic_reg_write(dev,  MAX8998_REG_ONOFF3, val);

	if (ret) {
		puts("LCD pmic initialisation error!\n");
		return -EINVAL;
	}

	return 0;
}

int exynos_init(void)
{
	gd->bd->bi_arch_number = MACH_TYPE_UNIVERSAL_C210;

	switch (get_hwrev()) {
	case 0:
		/*
		 * Set the low to enable LDO_EN
		 * But when you use the test board for eMMC booting
		 * you should set it HIGH since it removes the inverter
		 */
		/* MASSMEMORY_EN: XMDMDATA_6: GPE3[6] */
		gpio_request(EXYNOS4_GPIO_E36, "ldo_en");
		gpio_direction_output(EXYNOS4_GPIO_E36, 0);
		break;
	default:
		/*
		 * Default reset state is High and there's no inverter
		 * But set it as HIGH to ensure
		 */
		/* MASSMEMORY_EN: XMDMADDR_3: GPE1[3] */
		gpio_request(EXYNOS4_GPIO_E13, "massmemory_en");
		gpio_direction_output(EXYNOS4_GPIO_E13, 1);
		break;
	}

	check_hw_revision();
	printf("HW Revision:\t0x%x\n", board_rev);

	return 0;
}
