/*
 * Freescale MPC83xx GPIO handling.
 *
 * 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
 */

#include <common.h>
#include <mpc83xx.h>
#include <asm/gpio.h>
#include <asm/io.h>

#ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION
#define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0
#endif
#ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION
#define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0
#endif
#ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN
#define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0
#endif
#ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN
#define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0
#endif
#ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE
#define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0
#endif
#ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE
#define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0
#endif

static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS];

/*
 * Generic_GPIO primitives.
 */

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

	return 0;
}

int gpio_free(unsigned gpio)
{
	/* Do not set to input */
	return 0;
}

/* set GPIO pin 'gpio' as an input */
int gpio_direction_input(unsigned gpio)
{
	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
	unsigned int ctrlr;
	unsigned int line;
	unsigned int line_mask;

	/* 32-bits per controller */
	ctrlr = gpio >> 5;
	line = gpio & (0x1F);

	/* Big endian */
	line_mask = 1 << (31 - line);

	clrbits_be32(&im->gpio[ctrlr].dir, line_mask);

	return 0;
}

/* set GPIO pin 'gpio' as an output, with polarity 'value' */
int gpio_direction_output(unsigned gpio, int value)
{
	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
	unsigned int ctrlr;
	unsigned int line;
	unsigned int line_mask;

	if (value != 0 && value != 1) {
		printf("Error: Value parameter must be 0 or 1.\n");
		return -1;
	}

	gpio_set_value(gpio, value);

	/* 32-bits per controller */
	ctrlr = gpio >> 5;
	line = gpio & (0x1F);

	/* Big endian */
	line_mask = 1 << (31 - line);

	/* Make the line output */
	setbits_be32(&im->gpio[ctrlr].dir, line_mask);

	return 0;
}

/* read GPIO IN value of pin 'gpio' */
int gpio_get_value(unsigned gpio)
{
	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
	unsigned int ctrlr;
	unsigned int line;
	unsigned int line_mask;

	/* 32-bits per controller */
	ctrlr = gpio >> 5;
	line = gpio & (0x1F);

	/* Big endian */
	line_mask = 1 << (31 - line);

	/* Read the value and mask off the bit */
	return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0;
}

/* write GPIO OUT value to pin 'gpio' */
int gpio_set_value(unsigned gpio, int value)
{
	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
	unsigned int ctrlr;
	unsigned int line;
	unsigned int line_mask;

	if (value != 0 && value != 1) {
		printf("Error: Value parameter must be 0 or 1.\n");
		return -1;
	}

	/* 32-bits per controller */
	ctrlr = gpio >> 5;
	line = gpio & (0x1F);

	/* Big endian */
	line_mask = 1 << (31 - line);

	/* Update the local output buffer soft copy */
	gpio_output_value[ctrlr] =
		(gpio_output_value[ctrlr] & ~line_mask) | \
			(value ? line_mask : 0);

	/* Write the output */
	out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]);

	return 0;
}

/* Configure GPIO registers early */
void mpc83xx_gpio_init_f()
{
	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;

#if MPC83XX_GPIO_CTRLRS >= 1
	out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION);
	out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN);
	out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE);
	out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */
	out_be32(&im->gpio[0].imr, 0);
	out_be32(&im->gpio[0].icr, 0);
#endif

#if MPC83XX_GPIO_CTRLRS >= 2
	out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION);
	out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN);
	out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE);
	out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */
	out_be32(&im->gpio[1].imr, 0);
	out_be32(&im->gpio[1].icr, 0);
#endif
}

/* Initialize GPIO soft-copies */
void mpc83xx_gpio_init_r()
{
#if MPC83XX_GPIO_CTRLRS >= 1
	gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE;
#endif

#if MPC83XX_GPIO_CTRLRS >= 2
	gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE;
#endif
}
