/*
 * NVIDIA Tegra20 GPIO handling.
 *  (C) Copyright 2010-2012
 *  NVIDIA Corporation <www.nvidia.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * Based on (mostly copied from) kw_gpio.c based Linux 2.6 kernel driver.
 * Tom Warren (twarren@nvidia.com)
 */

#include <common.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/arch/tegra.h>
#include <asm/gpio.h>

enum {
	TEGRA_CMD_INFO,
	TEGRA_CMD_PORT,
	TEGRA_CMD_OUTPUT,
	TEGRA_CMD_INPUT,
};

static struct gpio_names {
	char name[GPIO_NAME_SIZE];
} gpio_names[MAX_NUM_GPIOS];

static char *get_name(int i)
{
	return *gpio_names[i].name ? gpio_names[i].name : "UNKNOWN";
}

/* Return config of pin 'gpio' as GPIO (1) or SFPIO (0) */
static int get_config(unsigned gpio)
{
	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
	u32 u;
	int type;

	u = readl(&bank->gpio_config[GPIO_PORT(gpio)]);
	type =  (u >> GPIO_BIT(gpio)) & 1;

	debug("get_config: port = %d, bit = %d is %s\n",
		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO");

	return type;
}

/* Config pin 'gpio' as GPIO or SFPIO, based on 'type' */
static void set_config(unsigned gpio, int type)
{
	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
	u32 u;

	debug("set_config: port = %d, bit = %d, %s\n",
		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO");

	u = readl(&bank->gpio_config[GPIO_PORT(gpio)]);
	if (type)				/* GPIO */
		u |= 1 << GPIO_BIT(gpio);
	else
		u &= ~(1 << GPIO_BIT(gpio));
	writel(u, &bank->gpio_config[GPIO_PORT(gpio)]);
}

/* Return GPIO pin 'gpio' direction - 0 = input or 1 = output */
static int get_direction(unsigned gpio)
{
	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
	u32 u;
	int dir;

	u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]);
	dir =  (u >> GPIO_BIT(gpio)) & 1;

	debug("get_direction: port = %d, bit = %d, %s\n",
		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), dir ? "OUT" : "IN");

	return dir;
}

/* Config GPIO pin 'gpio' as input or output (OE) as per 'output' */
static void set_direction(unsigned gpio, int output)
{
	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
	u32 u;

	debug("set_direction: port = %d, bit = %d, %s\n",
		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), output ? "OUT" : "IN");

	u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]);
	if (output)
		u |= 1 << GPIO_BIT(gpio);
	else
		u &= ~(1 << GPIO_BIT(gpio));
	writel(u, &bank->gpio_dir_out[GPIO_PORT(gpio)]);
}

/* set GPIO pin 'gpio' output bit as 0 or 1 as per 'high' */
static void set_level(unsigned gpio, int high)
{
	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
	u32 u;

	debug("set_level: port = %d, bit %d == %d\n",
		GPIO_FULLPORT(gpio), GPIO_BIT(gpio), high);

	u = readl(&bank->gpio_out[GPIO_PORT(gpio)]);
	if (high)
		u |= 1 << GPIO_BIT(gpio);
	else
		u &= ~(1 << GPIO_BIT(gpio));
	writel(u, &bank->gpio_out[GPIO_PORT(gpio)]);
}

/*
 * Generic_GPIO primitives.
 */

int gpio_request(unsigned gpio, const char *label)
{
	if (gpio >= MAX_NUM_GPIOS)
		return -1;

	if (label != NULL) {
		strncpy(gpio_names[gpio].name, label, GPIO_NAME_SIZE);
		gpio_names[gpio].name[GPIO_NAME_SIZE - 1] = '\0';
	}

	/* Configure as a GPIO */
	set_config(gpio, 1);

	return 0;
}

int gpio_free(unsigned gpio)
{
	if (gpio >= MAX_NUM_GPIOS)
		return -1;

	gpio_names[gpio].name[0] = '\0';
	/* Do not configure as input or change pin mux here */
	return 0;
}

/* read GPIO OUT value of pin 'gpio' */
static int gpio_get_output_value(unsigned gpio)
{
	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
	int val;

	debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n",
		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));

	val = readl(&bank->gpio_out[GPIO_PORT(gpio)]);

	return (val >> GPIO_BIT(gpio)) & 1;
}

/* set GPIO pin 'gpio' as an input */
int gpio_direction_input(unsigned gpio)
{
	debug("gpio_direction_input: pin = %d (port %d:bit %d)\n",
		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));

	/* Configure GPIO direction as input. */
	set_direction(gpio, 0);

	return 0;
}

/* set GPIO pin 'gpio' as an output, with polarity 'value' */
int gpio_direction_output(unsigned gpio, int value)
{
	debug("gpio_direction_output: pin = %d (port %d:bit %d) = %s\n",
		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio),
		value ? "HIGH" : "LOW");

	/* Configure GPIO output value. */
	set_level(gpio, value);

	/* Configure GPIO direction as output. */
	set_direction(gpio, 1);

	return 0;
}

/* read GPIO IN value of pin 'gpio' */
int gpio_get_value(unsigned gpio)
{
	struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
	struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
	int val;

	debug("gpio_get_value: pin = %d (port %d:bit %d)\n",
		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));

	val = readl(&bank->gpio_in[GPIO_PORT(gpio)]);

	return (val >> GPIO_BIT(gpio)) & 1;
}

/* write GPIO OUT value to pin 'gpio' */
int gpio_set_value(unsigned gpio, int value)
{
	debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
		gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);

	/* Configure GPIO output value. */
	set_level(gpio, value);

	return 0;
}

void gpio_config_table(const struct tegra_gpio_config *config, int len)
{
	int i;

	for (i = 0; i < len; i++) {
		switch (config[i].init) {
		case TEGRA_GPIO_INIT_IN:
			gpio_direction_input(config[i].gpio);
			break;
		case TEGRA_GPIO_INIT_OUT0:
			gpio_direction_output(config[i].gpio, 0);
			break;
		case TEGRA_GPIO_INIT_OUT1:
			gpio_direction_output(config[i].gpio, 1);
			break;
		}
		set_config(config[i].gpio, 1);
	}
}

/*
 * Display Tegra GPIO information
 */
void gpio_info(void)
{
	unsigned c;
	int type;

	for (c = 0; c < MAX_NUM_GPIOS; c++) {
		type = get_config(c);		/* GPIO, not SFPIO */
		if (type) {
			printf("GPIO_%d:\t%s is an %s, ", c,
				get_name(c),
				get_direction(c) ? "OUTPUT" : "INPUT");
			if (get_direction(c))
				printf("value = %d", gpio_get_output_value(c));
			else
				printf("value = %d", gpio_get_value(c));
			printf("\n");
		} else
			continue;
	}
}
