/*
 * arch/arm/mach-dove/mpp.c
 *
 * MPP functions for Marvell Dove SoCs
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <plat/mpp.h>
#include <mach/dove.h>
#include <plat/orion-gpio.h>
#include "mpp.h"

struct dove_mpp_grp {
	int start;
	int end;
};

/* Map a group to a range of GPIO pins in that group */
static const struct dove_mpp_grp dove_mpp_grp[] = {
	[MPP_24_39] = {
		.start	= 24,
		.end	= 39,
	},
	[MPP_40_45] = {
		.start	= 40,
		.end	= 45,
	},
	[MPP_46_51] = {
		.start	= 46,
		.end	= 51,
	},
	[MPP_58_61] = {
		.start	= 58,
		.end	= 61,
	},
	[MPP_62_63] = {
		.start	= 62,
		.end	= 63,
	},
};

/* Enable gpio for a range of pins. mode should be a combination of
   GPIO_OUTPUT_OK | GPIO_INPUT_OK */
static void __init dove_mpp_gpio_mode(int start, int end, int gpio_mode)
{
	int i;

	for (i = start; i <= end; i++)
		orion_gpio_set_valid(i, gpio_mode);
}

/* Dump all the extra MPP registers. The platform code will dump the
   registers for pins 0-23. */
static void __init dove_mpp_dump_regs(void)
{
	pr_debug("PMU_CTRL4_CTRL: %08x\n",
		 readl(DOVE_MPP_CTRL4_VIRT_BASE));

	pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
		 readl(DOVE_PMU_MPP_GENERAL_CTRL));

	pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
}

static void __init dove_mpp_cfg_nfc(int sel)
{
	u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);

	mpp_gen_cfg &= ~0x1;
	mpp_gen_cfg |= sel;
	writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);

	dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
}

static void __init dove_mpp_cfg_au1(int sel)
{
	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
	u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
	u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
	u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);

	mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
	ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
	mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
	global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);

	if (!sel || sel == 0x2)
		dove_mpp_gpio_mode(52, 57, 0);
	else
		dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);

	if (sel & 0x1) {
		global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
		dove_mpp_gpio_mode(56, 57, 0);
	}
	if (sel & 0x2) {
		mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
		dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
	}
	if (sel & 0x4) {
		ssp_ctrl1 |= DOVE_SSP_ON_AU1;
		dove_mpp_gpio_mode(52, 55, 0);
	}
	if (sel & 0x8)
		mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;

	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
	writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
	writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
	writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
}

/* Configure the group registers, enabling GPIO if sel indicates the
   pin is to be used for GPIO */
static void __init dove_mpp_conf_grp(unsigned int *mpp_grp_list)
{
	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
	int gpio_mode;

	for ( ; *mpp_grp_list; mpp_grp_list++) {
		unsigned int num = MPP_NUM(*mpp_grp_list);
		unsigned int sel = MPP_SEL(*mpp_grp_list);

		if (num > MPP_GRP_MAX) {
			pr_err("dove: invalid MPP GRP number (%u)\n", num);
			continue;
		}

		mpp_ctrl4 &= ~(0x1 << num);
		mpp_ctrl4 |= sel << num;

		gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
		dove_mpp_gpio_mode(dove_mpp_grp[num].start,
				   dove_mpp_grp[num].end, gpio_mode);
	}
	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
}

/* Configure the various MPP pins on Dove */
void __init dove_mpp_conf(unsigned int *mpp_list,
			  unsigned int *mpp_grp_list,
			  unsigned int grp_au1_52_57,
			  unsigned int grp_nfc_64_71)
{
	dove_mpp_dump_regs();

	/* Use platform code for pins 0-23 */
	orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);

	dove_mpp_conf_grp(mpp_grp_list);
	dove_mpp_cfg_au1(grp_au1_52_57);
	dove_mpp_cfg_nfc(grp_nfc_64_71);

	dove_mpp_dump_regs();
}
