/*
 *
 * Macros for external SMP-safe access to the PMC MSP71xx reference
 * board GPIO pins
 *
 * Copyright 2010 PMC-Sierra, Inc.
 *
 *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef __MSP_GPIO_MACROS_H__
#define __MSP_GPIO_MACROS_H__

#include <msp_regops.h>
#include <msp_regs.h>

#ifdef CONFIG_PMC_MSP7120_GW
#define MSP_NUM_GPIOS		20
#else
#define MSP_NUM_GPIOS		28
#endif

/* -- GPIO Enumerations -- */
enum msp_gpio_data {
	MSP_GPIO_LO = 0,
	MSP_GPIO_HI = 1,
	MSP_GPIO_NONE,		/* Special - Means pin is out of range */
	MSP_GPIO_TOGGLE,	/* Special - Sets pin to opposite */
};

enum msp_gpio_mode {
	MSP_GPIO_INPUT		= 0x0,
	/* MSP_GPIO_ INTERRUPT	= 0x1,	Not supported yet */
	MSP_GPIO_UART_INPUT	= 0x2,	/* Only GPIO 4 or 5 */
	MSP_GPIO_OUTPUT		= 0x8,
	MSP_GPIO_UART_OUTPUT	= 0x9,	/* Only GPIO 2 or 3 */
	MSP_GPIO_PERIF_TIMERA	= 0x9,	/* Only GPIO 0 or 1 */
	MSP_GPIO_PERIF_TIMERB	= 0xa,	/* Only GPIO 0 or 1 */
	MSP_GPIO_UNKNOWN	= 0xb,  /* No such GPIO or mode */
};

/* -- Static Tables -- */

/* Maps pins to data register */
static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = {
	/* GPIO 0 and 1 on the first register */
	GPIO_DATA1_REG, GPIO_DATA1_REG,
	/* GPIO 2, 3, 4, and 5 on the second register */
	GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG,
	/* GPIO 6, 7, 8, and 9 on the third register */
	GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG,
	/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
	GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG,
	GPIO_DATA4_REG, GPIO_DATA4_REG,
	/* GPIO 16 - 23 on the first strange EXTENDED register */
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	/* GPIO 24 - 27 on the second strange EXTENDED register */
	EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
	EXTENDED_GPIO2_REG,
};

/* Maps pins to mode register */
static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = {
	/* GPIO 0 and 1 on the first register */
	GPIO_CFG1_REG, GPIO_CFG1_REG,
	/* GPIO 2, 3, 4, and 5 on the second register */
	GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG,
	/* GPIO 6, 7, 8, and 9 on the third register */
	GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG,
	/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
	GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG,
	GPIO_CFG4_REG, GPIO_CFG4_REG,
	/* GPIO 16 - 23 on the first strange EXTENDED register */
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	/* GPIO 24 - 27 on the second strange EXTENDED register */
	EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
	EXTENDED_GPIO2_REG,
};

/* Maps 'basic' pins to relative offset from 0 per register */
static int MSP_GPIO_OFFSET[] = {
	/* GPIO 0 and 1 on the first register */
	0, 0,
	/* GPIO 2, 3, 4, and 5 on the second register */
	2, 2, 2, 2,
	/* GPIO 6, 7, 8, and 9 on the third register */
	6, 6, 6, 6,
	/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
	10, 10, 10, 10, 10, 10,
};

/* Maps MODE to allowed pin mask */
static unsigned int MSP_GPIO_MODE_ALLOWED[] = {
	0xffffffff,	/* Mode 0 - INPUT */
	0x00000,	/* Mode 1 - INTERRUPT */
	0x00030,	/* Mode 2 - UART_INPUT (GPIO 4, 5)*/
	0, 0, 0, 0, 0,	/* Modes 3, 4, 5, 6, and 7 are reserved */
	0xffffffff,	/* Mode 8 - OUTPUT */
	0x0000f,	/* Mode 9 - UART_OUTPUT/
				PERF_TIMERA (GPIO 0, 1, 2, 3) */
	0x00003,	/* Mode a - PERF_TIMERB (GPIO 0, 1) */
	0x00000,	/* Mode b - Not really a mode! */
};

/* -- Bit masks -- */

/* This gives you the 'register relative offset gpio' number */
#define OFFSET_GPIO_NUMBER(gpio)	(gpio - MSP_GPIO_OFFSET[gpio])

/* These take the 'register relative offset gpio' number */
#define BASIC_DATA_REG_MASK(ogpio)		(1 << ogpio)
#define BASIC_MODE_REG_VALUE(mode, ogpio)	\
	(mode << BASIC_MODE_REG_SHIFT(ogpio))
#define BASIC_MODE_REG_MASK(ogpio)		\
	BASIC_MODE_REG_VALUE(0xf, ogpio)
#define BASIC_MODE_REG_SHIFT(ogpio)		(ogpio * 4)
#define BASIC_MODE_REG_FROM_REG(data, ogpio)	\
	((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio))

/* These take the actual GPIO number (0 through 15) */
#define BASIC_DATA_MASK(gpio)	\
	BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
#define BASIC_MODE_MASK(gpio)	\
	BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
#define BASIC_MODE(mode, gpio)	\
	BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio))
#define BASIC_MODE_SHIFT(gpio)	\
	BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio))
#define BASIC_MODE_FROM_REG(data, gpio)	\
	BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio))

/*
 * Each extended GPIO register is 32 bits long and is responsible for up to
 * eight GPIOs. The least significant 16 bits contain the set and clear bit
 * pair for each of the GPIOs. The most significant 16 bits contain the
 * disable and enable bit pair for each of the GPIOs. For example, the
 * extended GPIO reg for GPIOs 16-23 is as follows:
 *
 *	31: GPIO23_DISABLE
 *	...
 *	19: GPIO17_DISABLE
 *	18: GPIO17_ENABLE
 *	17: GPIO16_DISABLE
 *	16: GPIO16_ENABLE
 *	...
 *	3:  GPIO17_SET
 *	2:  GPIO17_CLEAR
 *	1:  GPIO16_SET
 *	0:  GPIO16_CLEAR
 */

/* This gives the 'register relative offset gpio' number */
#define EXTENDED_OFFSET_GPIO(gpio)	(gpio < 24 ? gpio - 16 : gpio - 24)

/* These take the 'register relative offset gpio' number */
#define EXTENDED_REG_DISABLE(ogpio)	(0x2 << ((ogpio * 2) + 16))
#define EXTENDED_REG_ENABLE(ogpio)	(0x1 << ((ogpio * 2) + 16))
#define EXTENDED_REG_SET(ogpio)		(0x2 << (ogpio * 2))
#define EXTENDED_REG_CLR(ogpio)		(0x1 << (ogpio * 2))

/* These take the actual GPIO number (16 through 27) */
#define EXTENDED_DISABLE(gpio)	\
	EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio))
#define EXTENDED_ENABLE(gpio)	\
	EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio))
#define EXTENDED_SET(gpio)	\
	EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio))
#define EXTENDED_CLR(gpio)	\
	EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio))

#define EXTENDED_FULL_MASK		(0xffffffff)

/* -- API inline-functions -- */

/*
 * Gets the current value of the specified pin
 */
static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio)
{
	u32 pinhi_mask = 0, pinhi_mask2 = 0;

	if (gpio >= MSP_NUM_GPIOS)
		return MSP_GPIO_NONE;

	if (gpio < 16) {
		pinhi_mask = BASIC_DATA_MASK(gpio);
	} else {
		/*
		 * Two cases are possible with the EXTENDED register:
		 *  - In output mode (ENABLED flag set), check the CLR bit
		 *  - In input mode (ENABLED flag not set), check the SET bit
		 */
		pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio);
		pinhi_mask2 = EXTENDED_SET(gpio);
	}
	if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) ||
	    (*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2))
		return MSP_GPIO_HI;
	else
		return MSP_GPIO_LO;
}

/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio)
{
	if (gpio >= MSP_NUM_GPIOS)
		return;

	if (gpio < 16) {
		if (data == MSP_GPIO_TOGGLE)
			toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio],
					BASIC_DATA_MASK(gpio));
		else if (data == MSP_GPIO_HI)
			set_reg32(MSP_GPIO_DATA_REGISTER[gpio],
					BASIC_DATA_MASK(gpio));
		else
			clear_reg32(MSP_GPIO_DATA_REGISTER[gpio],
					BASIC_DATA_MASK(gpio));
	} else {
		if (data == MSP_GPIO_TOGGLE) {
			/* Special ugly case:
			 *   We have to read the CLR bit.
			 *   If set, we write the CLR bit.
			 *   If not, we write the SET bit.
			 */
			u32 tmpdata;

			custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio],
								tmpdata);
			if (tmpdata & EXTENDED_CLR(gpio))
				tmpdata = EXTENDED_CLR(gpio);
			else
				tmpdata = EXTENDED_SET(gpio);
			custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio],
								tmpdata);
		} else {
			u32 newdata;

			if (data == MSP_GPIO_HI)
				newdata = EXTENDED_SET(gpio);
			else
				newdata = EXTENDED_CLR(gpio);
			set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio],
						EXTENDED_FULL_MASK, newdata);
		}
	}
}

/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_hi(unsigned int gpio)
{
	msp_gpio_pin_set(MSP_GPIO_HI, gpio);
}

/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_lo(unsigned int gpio)
{
	msp_gpio_pin_set(MSP_GPIO_LO, gpio);
}

/* Sets the specified pin to the opposite value */
static inline void msp_gpio_pin_toggle(unsigned int gpio)
{
	msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio);
}

/* Gets the mode of the specified pin */
static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio)
{
	enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN;
	uint32_t data;

	if (gpio >= MSP_NUM_GPIOS)
		return retval;

	data = *MSP_GPIO_MODE_REGISTER[gpio];

	if (gpio < 16) {
		retval = BASIC_MODE_FROM_REG(data, gpio);
	} else {
		/* Extended pins can only be either INPUT or OUTPUT */
		if (data & EXTENDED_ENABLE(gpio))
			retval = MSP_GPIO_OUTPUT;
		else
			retval = MSP_GPIO_INPUT;
	}

	return retval;
}

/*
 * Sets the specified mode on the requested pin
 * Returns 0 on success, or -1 if that mode is not allowed on this pin
 */
static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio)
{
	u32 modemask, newmode;

	if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode])
		return -1;

	if (gpio >= MSP_NUM_GPIOS)
		return -1;

	if (gpio < 16) {
		modemask = BASIC_MODE_MASK(gpio);
		newmode =  BASIC_MODE(mode, gpio);
	} else {
		modemask = EXTENDED_FULL_MASK;
		if (mode == MSP_GPIO_INPUT)
			newmode = EXTENDED_DISABLE(gpio);
		else
			newmode = EXTENDED_ENABLE(gpio);
	}
	/* Do the set atomically */
	set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode);

	return 0;
}

#endif /* __MSP_GPIO_MACROS_H__ */
