/*
 * NVIDIA Tegra20 GPIO handling.
 *  (C) Copyright 2010-2012
 *  NVIDIA Corporation <www.nvidia.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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
 */

/*
 * 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/tegra20.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;
}

/*
 * 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;
	}
}
