/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <soc/gpio.h>
#include <soc/pinmux.h>

static void exynos_pinmux_uart(int start, int count)
{
	int i;

	for (i = start; i < start + count; i++) {
		gpio_set_pull(i, GPIO_PULL_NONE);
		gpio_cfg_pin(i, GPIO_FUNC(0x2));
	}
}

void exynos_pinmux_uart0(void)
{
	exynos_pinmux_uart(GPIO_A00, 4);
}

void exynos_pinmux_uart1(void)
{
	exynos_pinmux_uart(GPIO_D00, 4);
}

void exynos_pinmux_uart2(void)
{
	exynos_pinmux_uart(GPIO_A10, 4);
}

void exynos_pinmux_uart3(void)
{
	exynos_pinmux_uart(GPIO_A14, 2);
}

static void exynos_pinmux_sdmmc(int start, int start_ext)
{
	int i;

	if (start_ext) {
		for (i = 0; i <= 3; i++) {
			gpio_cfg_pin(start_ext + i, GPIO_FUNC(0x2));
			gpio_set_pull(start_ext + i, GPIO_PULL_UP);
			gpio_set_drv(start_ext + i, GPIO_DRV_4X);
		}
	}
	for (i = 0; i < 2; i++) {
		gpio_cfg_pin(start + i, GPIO_FUNC(0x2));
		gpio_set_pull(start + i, GPIO_PULL_NONE);
		gpio_set_drv(start + i, GPIO_DRV_4X);
	}
	for (i = 2; i <= 6; i++) {
		gpio_cfg_pin(start + i, GPIO_FUNC(0x2));
		gpio_set_pull(start + i, GPIO_PULL_UP);
		gpio_set_drv(start + i, GPIO_DRV_4X);
	}
}

void exynos_pinmux_sdmmc0(void)
{
	exynos_pinmux_sdmmc(GPIO_C00, GPIO_C10);
}

void exynos_pinmux_sdmmc1(void)
{
	exynos_pinmux_sdmmc(GPIO_C20, 0);
}

void exynos_pinmux_sdmmc2(void)
{
	exynos_pinmux_sdmmc(GPIO_C30, 0);
}

void exynos_pinmux_sdmmc3(void)
{
	/*
	 * TODO: Need to add definitions for GPC4 before
	 * enabling this.
	 */
	printk(BIOS_DEBUG, "SDMMC3 not supported yet");
}

void exynos_pinmux_sromc(int bank, int sixteen_bit)
{
	int i;

	if (bank > 3) {
		printk(BIOS_DEBUG, "Unsupported sromc bank %d.\n", bank);
		return;
	}

	gpio_cfg_pin(GPIO_Y00 + bank, GPIO_FUNC(2));
	gpio_cfg_pin(GPIO_Y04, GPIO_FUNC(2));
	gpio_cfg_pin(GPIO_Y05, GPIO_FUNC(2));

	for (i = 2; i < 4; i++)
		gpio_cfg_pin(GPIO_Y10 + i, GPIO_FUNC(2));

	for (i = 0; i < 8; i++) {
		gpio_cfg_pin(GPIO_Y30 + i, GPIO_FUNC(2));
		gpio_set_pull(GPIO_Y30 + i, GPIO_PULL_UP);

		gpio_cfg_pin(GPIO_Y50 + i, GPIO_FUNC(2));
		gpio_set_pull(GPIO_Y50 + i, GPIO_PULL_UP);

		if (sixteen_bit) {
			gpio_cfg_pin(GPIO_Y60 + i, GPIO_FUNC(2));
			gpio_set_pull(GPIO_Y60 + i, GPIO_PULL_UP);
		}
	}
}

static void exynos_pinmux_spi(int start, int cfg)
{
	int i;

	for (i = 0; i < 4; i++) {
		gpio_cfg_pin(start + i, GPIO_FUNC(cfg));
		gpio_set_pull(start + i, GPIO_PULL_NONE);
		gpio_set_drv(start + i, GPIO_DRV_3X);
	}
}

void exynos_pinmux_spi0(void)
{
	exynos_pinmux_spi(GPIO_A20, 0x2);
}

void exynos_pinmux_spi1(void)
{
	exynos_pinmux_spi(GPIO_A24, 0x2);
}

void exynos_pinmux_spi2(void)
{
	exynos_pinmux_spi(GPIO_B11, 0x5);
}

void exynos_pinmux_spi3(void)
{
	exynos_pinmux_spi(GPIO_E00, 0x2);
}

void exynos_pinmux_spi4(void)
{
	int i;

	for (i = 0; i < 2; i++)
		gpio_cfg_pin(GPIO_F02 + i, GPIO_FUNC(0x4));
	for (i = 2; i < 4; i++)
		gpio_cfg_pin(GPIO_E02 + i, GPIO_FUNC(0x4));
}

void exynos_pinmux_backlight(void)
{
	gpio_cfg_pin(GPIO_B20, GPIO_OUTPUT);
	gpio_set_value(GPIO_B20, 1);
}

void exynos_pinmux_lcd(void)
{
	gpio_cfg_pin(GPIO_Y25, GPIO_OUTPUT);
	gpio_set_value(GPIO_Y25, 1);
	gpio_cfg_pin(GPIO_X15, GPIO_OUTPUT);
	gpio_set_value(GPIO_X15, 1);
	gpio_cfg_pin(GPIO_X30, GPIO_OUTPUT);
	gpio_set_value(GPIO_X30, 1);
}

static void exynos_pinmux_i2c(int start, int func)
{
	gpio_cfg_pin(start, GPIO_FUNC(func));
	gpio_cfg_pin(start + 1, GPIO_FUNC(func));
	gpio_set_pull(start, GPIO_PULL_NONE);
	gpio_set_pull(start + 1, GPIO_PULL_NONE);
}

void exynos_pinmux_i2c0(void)
{
	exynos_pinmux_i2c(GPIO_B30, 0x2);
}

void exynos_pinmux_i2c1(void)
{
	exynos_pinmux_i2c(GPIO_B32, 0x2);
}

void exynos_pinmux_i2c2(void)
{
	exynos_pinmux_i2c(GPIO_A06, 0x3);
}

void exynos_pinmux_i2c3(void)
{
	exynos_pinmux_i2c(GPIO_A12, 0x3);
}

void exynos_pinmux_i2c4(void)
{
	exynos_pinmux_i2c(GPIO_A20, 0x3);
}

void exynos_pinmux_i2c5(void)
{
	exynos_pinmux_i2c(GPIO_A22, 0x3);
}

void exynos_pinmux_i2c6(void)
{
	exynos_pinmux_i2c(GPIO_B13, 0x4);
}

void exynos_pinmux_i2c7(void)
{
	exynos_pinmux_i2c(GPIO_B22, 0x3);
}

void exynos_pinmux_dphpd(void)
{
	/* Set Hotplug detect for DP */
	gpio_cfg_pin(GPIO_X07, GPIO_FUNC(0x3));

	/*
	 * Hotplug detect should have an external pullup; disable the
	 * internal pulldown so they don't fight.
	 */
	gpio_set_pull(GPIO_X07, GPIO_PULL_NONE);
}

void exynos_pinmux_i2s0(void)
{
	int i;

	for (i = 0; i < 5; i++) {
		gpio_cfg_pin(GPIO_Z0 + i, GPIO_FUNC(0x02));
		gpio_set_pull(GPIO_Z0 + i, GPIO_PULL_NONE);
	}
}

void exynos_pinmux_i2s1(void)
{
	int i;

	for (i = 0; i < 5; i++) {
		gpio_cfg_pin(GPIO_B00 + i, GPIO_FUNC(0x02));
		gpio_set_pull(GPIO_B00 + i, GPIO_PULL_NONE);
	}
}
