/*
 * (C) Copyright 2007-2008
 * Stefan Roese, DENX Software Engineering, sr@denx.de.
 *
 * 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 <asm/processor.h>
#include <asm/io.h>
#include <asm/gpio.h>

#if defined(CFG_4xx_GPIO_TABLE)
gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_4xx_GPIO_TABLE;
#endif

#if defined(GPIO0_OSRL)
/* Only some 4xx variants support alternate funtions on the GPIO's */
void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
{
	u32 mask;
	u32 mask2;
	u32 val;
	u32 offs = 0;
	u32 offs2 = 0;
	int pin2 = pin << 1;

	if (pin >= GPIO_MAX) {
		offs = 0x100;
		pin -= GPIO_MAX;
	}

	if (pin >= GPIO_MAX/2) {
		offs2 = 0x4;
		pin2 = (pin - GPIO_MAX/2) << 1;
	}

	mask = 0x80000000 >> pin;
	mask2 = 0xc0000000 >> pin2;

	/* first set TCR to 0 */
	out_be32((void *)GPIO0_TCR + offs, in_be32((void *)GPIO0_TCR + offs) & ~mask);

	if (in_out == GPIO_OUT) {
		val = in_be32((void *)GPIO0_OSRL + offs + offs2) & ~mask2;
		switch (gpio_alt) {
		case GPIO_ALT1:
			val |= GPIO_ALT1_SEL >> pin2;
			break;
		case GPIO_ALT2:
			val |= GPIO_ALT2_SEL >> pin2;
			break;
		case GPIO_ALT3:
			val |= GPIO_ALT3_SEL >> pin2;
			break;
		}
		out_be32((void *)GPIO0_OSRL + offs + offs2, val);

		/* setup requested output value */
		if (out_val == GPIO_OUT_0)
			out_be32((void *)GPIO0_OR + offs,
				 in_be32((void *)GPIO0_OR + offs) & ~mask);
		else if (out_val == GPIO_OUT_1)
			out_be32((void *)GPIO0_OR + offs,
				 in_be32((void *)GPIO0_OR + offs) | mask);

		/* now configure TCR to drive output if selected */
		out_be32((void *)GPIO0_TCR + offs,
			 in_be32((void *)GPIO0_TCR + offs) | mask);
	} else {
		val = in_be32((void *)GPIO0_ISR1L + offs + offs2) & ~mask2;
		val |= GPIO_IN_SEL >> pin2;
		out_be32((void *)GPIO0_ISR1L + offs + offs2, val);
	}
}
#endif /* GPIO_OSRL */

void gpio_write_bit(int pin, int val)
{
	u32 offs = 0;

	if (pin >= GPIO_MAX) {
		offs = 0x100;
		pin -= GPIO_MAX;
	}

	if (val)
		out_be32((void *)GPIO0_OR + offs,
			 in_be32((void *)GPIO0_OR + offs) | GPIO_VAL(pin));
	else
		out_be32((void *)GPIO0_OR + offs,
			 in_be32((void *)GPIO0_OR + offs) & ~GPIO_VAL(pin));
}

int gpio_read_out_bit(int pin)
{
	u32 offs = 0;

	if (pin >= GPIO_MAX) {
		offs = 0x100;
		pin -= GPIO_MAX;
	}

	return (in_be32((void *)GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
}

int gpio_read_in_bit(int pin)
{
	u32 offs = 0;

	if (pin >= GPIO_MAX) {
		offs = 0x100;
		pin -= GPIO_MAX;
	}

	return (in_be32((void *)GPIO0_IR + offs) & GPIO_VAL(pin) ? 1 : 0);
}

#if defined(CFG_4xx_GPIO_TABLE)
void gpio_set_chip_configuration(void)
{
	unsigned char i=0, j=0, offs=0, gpio_core;
	unsigned long reg, core_add;

	for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) {
		j = 0;
		offs = 0;
		/* GPIO config of the GPIOs 0 to 31 */
		for (i=0; i<GPIO_MAX; i++, j++) {
			if (i == GPIO_MAX/2) {
				offs = 4;
				j = i-16;
			}

			core_add = gpio_tab[gpio_core][i].add;

			if ((gpio_tab[gpio_core][i].in_out == GPIO_IN) ||
			    (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {

				switch (gpio_tab[gpio_core][i].alt_nb) {
				case GPIO_SEL:
					break;

				case GPIO_ALT1:
					reg = in_be32((void *)GPIO_IS1(core_add+offs))
						& ~(GPIO_MASK >> (j*2));
					reg = reg | (GPIO_IN_SEL >> (j*2));
					out_be32((void *)GPIO_IS1(core_add+offs), reg);
					break;

				case GPIO_ALT2:
					reg = in_be32((void *)GPIO_IS2(core_add+offs))
						& ~(GPIO_MASK >> (j*2));
					reg = reg | (GPIO_IN_SEL >> (j*2));
					out_be32((void *)GPIO_IS2(core_add+offs), reg);
					break;

				case GPIO_ALT3:
					reg = in_be32((void *)GPIO_IS3(core_add+offs))
						& ~(GPIO_MASK >> (j*2));
					reg = reg | (GPIO_IN_SEL >> (j*2));
					out_be32((void *)GPIO_IS3(core_add+offs), reg);
					break;
				}
			}

			if ((gpio_tab[gpio_core][i].in_out == GPIO_OUT) ||
			    (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {

				u32 gpio_alt_sel = 0;

				switch (gpio_tab[gpio_core][i].alt_nb) {
				case GPIO_SEL:
					/*
					 * Setup output value
					 * 1 -> high level
					 * 0 -> low level
					 * else -> don't touch
					 */
					reg = in_be32((void *)GPIO_OR(core_add));
					if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
						reg |= (0x80000000 >> (i));
					else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
						reg &= ~(0x80000000 >> (i));
					out_be32((void *)GPIO_OR(core_add), reg);

					reg = in_be32((void *)GPIO_TCR(core_add)) |
						(0x80000000 >> (i));
					out_be32((void *)GPIO_TCR(core_add), reg);

					reg = in_be32((void *)GPIO_OS(core_add+offs))
						& ~(GPIO_MASK >> (j*2));
					out_be32((void *)GPIO_OS(core_add+offs), reg);
					reg = in_be32((void *)GPIO_TS(core_add+offs))
						& ~(GPIO_MASK >> (j*2));
					out_be32((void *)GPIO_TS(core_add+offs), reg);
					break;

				case GPIO_ALT1:
					gpio_alt_sel = GPIO_ALT1_SEL;
					break;

				case GPIO_ALT2:
					gpio_alt_sel = GPIO_ALT2_SEL;
					break;

				case GPIO_ALT3:
					gpio_alt_sel = GPIO_ALT3_SEL;
					break;
				}

				if (0 != gpio_alt_sel) {
					reg = in_be32((void *)GPIO_OS(core_add+offs))
						& ~(GPIO_MASK >> (j*2));
					reg = reg | (gpio_alt_sel >> (j*2));
					out_be32((void *)GPIO_OS(core_add+offs), reg);

					if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1) {
						reg = in_be32((void *)GPIO_TCR(core_add))
							| (0x80000000 >> (i));
						out_be32((void *)GPIO_TCR(core_add), reg);
						reg = in_be32((void *)GPIO_TS(core_add+offs))
							& ~(GPIO_MASK >> (j*2));
						out_be32((void *)GPIO_TS(core_add+offs), reg);
					} else {
						reg = in_be32((void *)GPIO_TCR(core_add))
							& ~(0x80000000 >> (i));
						out_be32((void *)GPIO_TCR(core_add), reg);
						reg = in_be32((void *)GPIO_TS(core_add+offs))
							& ~(GPIO_MASK >> (j*2));
						reg = reg | (gpio_alt_sel >> (j*2));
						out_be32((void *)GPIO_TS(core_add+offs), reg);
					}
				}
			}
		}
	}
}
#endif /* CFG_4xx_GPIO_TABLE */
