/*
 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright (C) 2010 Jason Wang <jason77.wang@gmail.com>
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>

#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx51.h>
#include <mach/3ds_debugboard.h>

#include "devices-imx51.h"
#include "devices.h"

#define EXPIO_PARENT_INT	(MXC_INTERNAL_IRQS + GPIO_PORTA + 6)
#define MX51_3DS_ECSPI2_CS	(GPIO_PORTC + 28)

static iomux_v3_cfg_t mx51_3ds_pads[] = {
	/* UART1 */
	MX51_PAD_UART1_RXD__UART1_RXD,
	MX51_PAD_UART1_TXD__UART1_TXD,
	MX51_PAD_UART1_RTS__UART1_RTS,
	MX51_PAD_UART1_CTS__UART1_CTS,

	/* UART2 */
	MX51_PAD_UART2_RXD__UART2_RXD,
	MX51_PAD_UART2_TXD__UART2_TXD,
	MX51_PAD_EIM_D25__UART2_CTS,
	MX51_PAD_EIM_D26__UART2_RTS,

	/* UART3 */
	MX51_PAD_UART3_RXD__UART3_RXD,
	MX51_PAD_UART3_TXD__UART3_TXD,
	MX51_PAD_EIM_D24__UART3_CTS,
	MX51_PAD_EIM_D27__UART3_RTS,

	/* CPLD PARENT IRQ PIN */
	MX51_PAD_GPIO1_6__GPIO1_6,

	/* KPP */
	MX51_PAD_KEY_ROW0__KEY_ROW0,
	MX51_PAD_KEY_ROW1__KEY_ROW1,
	MX51_PAD_KEY_ROW2__KEY_ROW2,
	MX51_PAD_KEY_ROW3__KEY_ROW3,
	MX51_PAD_KEY_COL0__KEY_COL0,
	MX51_PAD_KEY_COL1__KEY_COL1,
	MX51_PAD_KEY_COL2__KEY_COL2,
	MX51_PAD_KEY_COL3__KEY_COL3,
	MX51_PAD_KEY_COL4__KEY_COL4,
	MX51_PAD_KEY_COL5__KEY_COL5,

	/* eCSPI2 */
	MX51_PAD_NANDF_RB2__ECSPI2_SCLK,
	MX51_PAD_NANDF_RB3__ECSPI2_MISO,
	MX51_PAD_NANDF_D15__ECSPI2_MOSI,
	MX51_PAD_NANDF_D12__GPIO3_28,
};

/* Serial ports */
#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
static const struct imxuart_platform_data uart_pdata __initconst = {
	.flags = IMXUART_HAVE_RTSCTS,
};

static inline void mxc_init_imx_uart(void)
{
	imx51_add_imx_uart(0, &uart_pdata);
	imx51_add_imx_uart(1, &uart_pdata);
	imx51_add_imx_uart(2, &uart_pdata);
}
#else /* !SERIAL_IMX */
static inline void mxc_init_imx_uart(void)
{
}
#endif /* SERIAL_IMX */

#if defined(CONFIG_KEYBOARD_IMX) || defined(CONFIG_KEYBOARD_IMX_MODULE)
static int mx51_3ds_board_keymap[] = {
	KEY(0, 0, KEY_1),
	KEY(0, 1, KEY_2),
	KEY(0, 2, KEY_3),
	KEY(0, 3, KEY_F1),
	KEY(0, 4, KEY_UP),
	KEY(0, 5, KEY_F2),

	KEY(1, 0, KEY_4),
	KEY(1, 1, KEY_5),
	KEY(1, 2, KEY_6),
	KEY(1, 3, KEY_LEFT),
	KEY(1, 4, KEY_SELECT),
	KEY(1, 5, KEY_RIGHT),

	KEY(2, 0, KEY_7),
	KEY(2, 1, KEY_8),
	KEY(2, 2, KEY_9),
	KEY(2, 3, KEY_F3),
	KEY(2, 4, KEY_DOWN),
	KEY(2, 5, KEY_F4),

	KEY(3, 0, KEY_0),
	KEY(3, 1, KEY_OK),
	KEY(3, 2, KEY_ESC),
	KEY(3, 3, KEY_ENTER),
	KEY(3, 4, KEY_MENU),
	KEY(3, 5, KEY_BACK)
};

static struct matrix_keymap_data mx51_3ds_map_data = {
	.keymap		= mx51_3ds_board_keymap,
	.keymap_size	= ARRAY_SIZE(mx51_3ds_board_keymap),
};

static void mxc_init_keypad(void)
{
	mxc_register_device(&mxc_keypad_device, &mx51_3ds_map_data);
}
#else
static inline void mxc_init_keypad(void)
{
}
#endif

static int mx51_3ds_spi2_cs[] = {
	MXC_SPI_CS(0),
	MX51_3DS_ECSPI2_CS,
};

static const struct spi_imx_master mx51_3ds_ecspi2_pdata __initconst = {
	.chipselect	= mx51_3ds_spi2_cs,
	.num_chipselect	= ARRAY_SIZE(mx51_3ds_spi2_cs),
};

static struct spi_board_info mx51_3ds_spi_nor_device[] = {
	{
	 .modalias = "m25p80",
	 .max_speed_hz = 25000000,	/* max spi clock (SCK) speed in HZ */
	 .bus_num = 1,
	 .chip_select = 1,
	 .mode = SPI_MODE_0,
	 .platform_data = NULL,},
};

/*
 * Board specific initialization.
 */
static void __init mxc_board_init(void)
{
	mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads,
					ARRAY_SIZE(mx51_3ds_pads));
	mxc_init_imx_uart();

	imx51_add_ecspi(1, &mx51_3ds_ecspi2_pdata);
	spi_register_board_info(mx51_3ds_spi_nor_device,
				ARRAY_SIZE(mx51_3ds_spi_nor_device));

	if (mxc_expio_init(MX51_CS5_BASE_ADDR, EXPIO_PARENT_INT))
		printk(KERN_WARNING "Init of the debugboard failed, all "
				    "devices on the board are unusable.\n");

	imx51_add_sdhci_esdhc_imx(0, NULL);
	mxc_init_keypad();
}

static void __init mx51_3ds_timer_init(void)
{
	mx51_clocks_init(32768, 24000000, 22579200, 0);
}

static struct sys_timer mxc_timer = {
	.init	= mx51_3ds_timer_init,
};

MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board")
	/* Maintainer: Freescale Semiconductor, Inc. */
	.boot_params = MX51_PHYS_OFFSET + 0x100,
	.map_io = mx51_map_io,
	.init_irq = mx51_init_irq,
	.init_machine = mxc_board_init,
	.timer = &mxc_timer,
MACHINE_END
