/*
 * (C) Copyright 2011
 * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com
 *
 * (C) Copyright 2015
 * Kamil Lulko, <kamil.lulko@gmail.com>
 *
 * Copyright 2015 ATS Advanced Telematics Systems GmbH
 * Copyright 2015 Konsulko Group, Matt Porter <mporter@konsulko.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/arch/stm32.h>
#include <asm/arch/gpio.h>

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_STM32F4) || defined(CONFIG_STM32F7)
static const unsigned long io_base[] = {
	STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE,
	STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE,
	STM32_GPIOG_BASE, STM32_GPIOH_BASE, STM32_GPIOI_BASE
};

struct stm32_gpio_regs {
	u32 moder;	/* GPIO port mode */
	u32 otyper;	/* GPIO port output type */
	u32 ospeedr;	/* GPIO port output speed */
	u32 pupdr;	/* GPIO port pull-up/pull-down */
	u32 idr;	/* GPIO port input data */
	u32 odr;	/* GPIO port output data */
	u32 bsrr;	/* GPIO port bit set/reset */
	u32 lckr;	/* GPIO port configuration lock */
	u32 afr[2];	/* GPIO alternate function */
};

#define CHECK_DSC(x)	(!x || x->port > 8 || x->pin > 15)
#define CHECK_CTL(x)	(!x || x->af > 15 || x->mode > 3 || x->otype > 1 || \
			x->pupd > 2 || x->speed > 3)

int stm32_gpio_config(const struct stm32_gpio_dsc *dsc,
		const struct stm32_gpio_ctl *ctl)
{
	struct stm32_gpio_regs *gpio_regs;
	u32 i;
	int rv;

	if (CHECK_DSC(dsc)) {
		rv = -EINVAL;
		goto out;
	}
	if (CHECK_CTL(ctl)) {
		rv = -EINVAL;
		goto out;
	}

	gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port];

	i = (dsc->pin & 0x07) * 4;
	clrsetbits_le32(&gpio_regs->afr[dsc->pin >> 3], 0xF << i, ctl->af << i);

	i = dsc->pin * 2;

	clrsetbits_le32(&gpio_regs->moder, 0x3 << i, ctl->mode << i);
	clrsetbits_le32(&gpio_regs->otyper, 0x3 << i, ctl->otype << i);
	clrsetbits_le32(&gpio_regs->ospeedr, 0x3 << i, ctl->speed << i);
	clrsetbits_le32(&gpio_regs->pupdr, 0x3 << i, ctl->pupd << i);

	rv = 0;
out:
	return rv;
}
#elif defined(CONFIG_STM32F1)
static const unsigned long io_base[] = {
	STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE,
	STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE,
	STM32_GPIOG_BASE
};

#define STM32_GPIO_CR_MODE_MASK		0x3
#define STM32_GPIO_CR_MODE_SHIFT(p)	(p * 4)
#define STM32_GPIO_CR_CNF_MASK		0x3
#define STM32_GPIO_CR_CNF_SHIFT(p)	(p * 4 + 2)

struct stm32_gpio_regs {
	u32 crl;	/* GPIO port configuration low */
	u32 crh;	/* GPIO port configuration high */
	u32 idr;	/* GPIO port input data */
	u32 odr;	/* GPIO port output data */
	u32 bsrr;	/* GPIO port bit set/reset */
	u32 brr;	/* GPIO port bit reset */
	u32 lckr;	/* GPIO port configuration lock */
};

#define CHECK_DSC(x)	(!x || x->port > 6 || x->pin > 15)
#define CHECK_CTL(x)	(!x || x->mode > 3 || x->icnf > 3 || x->ocnf > 3 || \
			 x->pupd > 1)

int stm32_gpio_config(const struct stm32_gpio_dsc *dsc,
		const struct stm32_gpio_ctl *ctl)
{
	struct stm32_gpio_regs *gpio_regs;
	u32 *cr;
	int p, crp;
	int rv;

	if (CHECK_DSC(dsc)) {
		rv = -EINVAL;
		goto out;
	}
	if (CHECK_CTL(ctl)) {
		rv = -EINVAL;
		goto out;
	}

	p = dsc->pin;

	gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port];

	if (p < 8) {
		cr = &gpio_regs->crl;
		crp = p;
	} else {
		cr = &gpio_regs->crh;
		crp = p - 8;
	}

	clrbits_le32(cr, 0x3 << STM32_GPIO_CR_MODE_SHIFT(crp));
	setbits_le32(cr, ctl->mode << STM32_GPIO_CR_MODE_SHIFT(crp));

	clrbits_le32(cr, 0x3 << STM32_GPIO_CR_CNF_SHIFT(crp));
	/* Inputs set the optional pull up / pull down */
	if (ctl->mode == STM32_GPIO_MODE_IN) {
		setbits_le32(cr, ctl->icnf << STM32_GPIO_CR_CNF_SHIFT(crp));
		clrbits_le32(&gpio_regs->odr, 0x1 << p);
		setbits_le32(&gpio_regs->odr, ctl->pupd << p);
	} else {
		setbits_le32(cr, ctl->ocnf << STM32_GPIO_CR_CNF_SHIFT(crp));
	}

	rv = 0;
out:
	return rv;
}
#else
#error STM32 family not supported
#endif

int stm32_gpout_set(const struct stm32_gpio_dsc *dsc, int state)
{
	struct stm32_gpio_regs	*gpio_regs;
	int rv;

	if (CHECK_DSC(dsc)) {
		rv = -EINVAL;
		goto out;
	}

	gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port];

	if (state)
		writel(1 << dsc->pin, &gpio_regs->bsrr);
	else
		writel(1 << (dsc->pin + 16), &gpio_regs->bsrr);

	rv = 0;
out:
	return rv;
}

int stm32_gpin_get(const struct stm32_gpio_dsc *dsc)
{
	struct stm32_gpio_regs	*gpio_regs;
	int rv;

	if (CHECK_DSC(dsc)) {
		rv = -EINVAL;
		goto out;
	}

	gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port];
	rv = readl(&gpio_regs->idr) & (1 << dsc->pin);
out:
	return rv;
}

/* Common GPIO API */

int gpio_request(unsigned gpio, const char *label)
{
	return 0;
}

int gpio_free(unsigned gpio)
{
	return 0;
}

int gpio_direction_input(unsigned gpio)
{
	struct stm32_gpio_dsc dsc;
	struct stm32_gpio_ctl ctl;

	dsc.port = stm32_gpio_to_port(gpio);
	dsc.pin = stm32_gpio_to_pin(gpio);
#if defined(CONFIG_STM32F4) || defined(CONFIG_STM32F7)
	ctl.af = STM32_GPIO_AF0;
	ctl.mode = STM32_GPIO_MODE_IN;
	ctl.otype = STM32_GPIO_OTYPE_PP;
	ctl.pupd = STM32_GPIO_PUPD_NO;
	ctl.speed = STM32_GPIO_SPEED_50M;
#elif defined(CONFIG_STM32F1)
	ctl.mode = STM32_GPIO_MODE_IN;
	ctl.icnf = STM32_GPIO_ICNF_IN_FLT;
	ctl.ocnf = STM32_GPIO_OCNF_GP_PP;	/* ignored for input */
	ctl.pupd = STM32_GPIO_PUPD_UP;		/* ignored for floating */
#else
#error STM32 family not supported
#endif

	return stm32_gpio_config(&dsc, &ctl);
}

int gpio_direction_output(unsigned gpio, int value)
{
	struct stm32_gpio_dsc dsc;
	struct stm32_gpio_ctl ctl;
	int res;

	dsc.port = stm32_gpio_to_port(gpio);
	dsc.pin = stm32_gpio_to_pin(gpio);
#if defined(CONFIG_STM32F4) || defined(CONFIG_STM32F7)
	ctl.af = STM32_GPIO_AF0;
	ctl.mode = STM32_GPIO_MODE_OUT;
	ctl.pupd = STM32_GPIO_PUPD_NO;
	ctl.speed = STM32_GPIO_SPEED_50M;
#elif defined(CONFIG_STM32F1)
	ctl.mode = STM32_GPIO_MODE_OUT_50M;
	ctl.ocnf = STM32_GPIO_OCNF_GP_PP;
	ctl.icnf = STM32_GPIO_ICNF_IN_FLT;	/* ignored for output */
	ctl.pupd = STM32_GPIO_PUPD_UP;		/* ignored for output */
#else
#error STM32 family not supported
#endif

	res = stm32_gpio_config(&dsc, &ctl);
	if (res < 0)
		goto out;
	res = stm32_gpout_set(&dsc, value);
out:
	return res;
}

int gpio_get_value(unsigned gpio)
{
	struct stm32_gpio_dsc dsc;

	dsc.port = stm32_gpio_to_port(gpio);
	dsc.pin = stm32_gpio_to_pin(gpio);

	return stm32_gpin_get(&dsc);
}

int gpio_set_value(unsigned gpio, int value)
{
	struct stm32_gpio_dsc dsc;

	dsc.port = stm32_gpio_to_port(gpio);
	dsc.pin = stm32_gpio_to_pin(gpio);

	return stm32_gpout_set(&dsc, value);
}
