/*
 * HTC Herald board configuration
 * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
 * Copyright (C) 2009 Wing Linux
 *
 * Based on the board-htcwizard.c file from the linwizard project:
 * Copyright (C) 2006 Unai Uribarri
 * Copyright (C) 2008 linwizard.sourceforge.net
 *
 * 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.,  51 Franklin  Street,  Fifth  Floor, Boston,  MA
 * 02110-1301, USA.
 *
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/io.h>
#include <linux/gpio.h>

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

#include <plat/omap7xx.h>
#include <plat/common.h>
#include <plat/board.h>
#include <plat/keypad.h>
#include <plat/usb.h>

#include <mach/irqs.h>

#include <linux/delay.h>

/* LCD register definition */
#define       OMAP_LCDC_CONTROL               (0xfffec000 + 0x00)
#define       OMAP_LCDC_STATUS                (0xfffec000 + 0x10)
#define       OMAP_DMA_LCD_CCR                (0xfffee300 + 0xc2)
#define       OMAP_DMA_LCD_CTRL               (0xfffee300 + 0xc4)
#define       OMAP_LCDC_CTRL_LCD_EN           (1 << 0)
#define       OMAP_LCDC_STAT_DONE             (1 << 0)

static struct omap_lcd_config htcherald_lcd_config __initdata = {
	.ctrl_name	= "internal",
};

static struct omap_board_config_kernel htcherald_config[] __initdata = {
	{ OMAP_TAG_LCD, &htcherald_lcd_config },
};

/* Keyboard definition */

static int htc_herald_keymap[] = {
	KEY(0, 0, KEY_RECORD), /* Mail button */
	KEY(0, 1, KEY_CAMERA), /* Camera */
	KEY(0, 2, KEY_PHONE), /* Send key */
	KEY(0, 3, KEY_VOLUMEUP), /* Volume up */
	KEY(0, 4, KEY_F2),  /* Right bar (landscape) */
	KEY(0, 5, KEY_MAIL), /* Win key (portrait) */
	KEY(0, 6, KEY_DIRECTORY), /* Right bar (protrait) */
	KEY(1, 0, KEY_LEFTCTRL), /* Windows key */
	KEY(1, 1, KEY_COMMA),
	KEY(1, 2, KEY_M),
	KEY(1, 3, KEY_K),
	KEY(1, 4, KEY_SLASH), /* OK key */
	KEY(1, 5, KEY_I),
	KEY(1, 6, KEY_U),
	KEY(2, 0, KEY_LEFTALT),
	KEY(2, 1, KEY_TAB),
	KEY(2, 2, KEY_N),
	KEY(2, 3, KEY_J),
	KEY(2, 4, KEY_ENTER),
	KEY(2, 5, KEY_H),
	KEY(2, 6, KEY_Y),
	KEY(3, 0, KEY_SPACE),
	KEY(3, 1, KEY_L),
	KEY(3, 2, KEY_B),
	KEY(3, 3, KEY_V),
	KEY(3, 4, KEY_BACKSPACE),
	KEY(3, 5, KEY_G),
	KEY(3, 6, KEY_T),
	KEY(4, 0, KEY_CAPSLOCK), /* Shift */
	KEY(4, 1, KEY_C),
	KEY(4, 2, KEY_F),
	KEY(4, 3, KEY_R),
	KEY(4, 4, KEY_O),
	KEY(4, 5, KEY_E),
	KEY(4, 6, KEY_D),
	KEY(5, 0, KEY_X),
	KEY(5, 1, KEY_Z),
	KEY(5, 2, KEY_S),
	KEY(5, 3, KEY_W),
	KEY(5, 4, KEY_P),
	KEY(5, 5, KEY_Q),
	KEY(5, 6, KEY_A),
	KEY(6, 0, KEY_CONNECT), /* Voice button */
	KEY(6, 2, KEY_CANCEL), /* End key */
	KEY(6, 3, KEY_VOLUMEDOWN), /* Volume down */
	KEY(6, 4, KEY_F1), /* Left bar (landscape) */
	KEY(6, 5, KEY_WWW), /* OK button (portrait) */
	KEY(6, 6, KEY_CALENDAR), /* Left bar (portrait) */
	0
};

struct omap_kp_platform_data htcherald_kp_data = {
	.rows	= 7,
	.cols	= 7,
	.delay = 20,
	.rep = 1,
	.keymap = htc_herald_keymap,
};

static struct resource kp_resources[] = {
	[0] = {
		.start	= INT_7XX_MPUIO_KEYPAD,
		.end	= INT_7XX_MPUIO_KEYPAD,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device kp_device = {
	.name		= "omap-keypad",
	.id		= -1,
	.dev		= {
		.platform_data = &htcherald_kp_data,
	},
	.num_resources	= ARRAY_SIZE(kp_resources),
	.resource	= kp_resources,
};

/* USB Device */
static struct omap_usb_config htcherald_usb_config __initdata = {
	.otg = 0,
	.register_host = 0,
	.register_dev  = 1,
	.hmc_mode = 4,
	.pins[0] = 2,
};

/* LCD Device resources */
static struct platform_device lcd_device = {
	.name           = "lcd_htcherald",
	.id             = -1,
};

static struct platform_device *devices[] __initdata = {
	&kp_device,
	&lcd_device,
};

/*
 * Init functions from here on
 */

static void __init htcherald_lcd_init(void)
{
	u32 reg;
	unsigned int tries = 200;

	/* disable controller if active */
	reg = omap_readl(OMAP_LCDC_CONTROL);
	if (reg & OMAP_LCDC_CTRL_LCD_EN) {
		reg &= ~OMAP_LCDC_CTRL_LCD_EN;
		omap_writel(reg, OMAP_LCDC_CONTROL);

		/* wait for end of frame */
		while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) {
			tries--;
			if (!tries)
				break;
		}
		if (!tries)
			printk(KERN_WARNING "Timeout waiting for end of frame "
			       "-- LCD may not be available\n");

		/* turn off DMA */
		reg = omap_readw(OMAP_DMA_LCD_CCR);
		reg &= ~(1 << 7);
		omap_writew(reg, OMAP_DMA_LCD_CCR);

		reg = omap_readw(OMAP_DMA_LCD_CTRL);
		reg &= ~(1 << 8);
		omap_writew(reg, OMAP_DMA_LCD_CTRL);
	}
}

static void __init htcherald_map_io(void)
{
	omap1_map_common_io();

	/*
	 * The LCD panel must be disabled and DMA turned off here, as doing
	 * it later causes the LCD never to reinitialize.
	 */
	htcherald_lcd_init();

	printk(KERN_INFO "htcherald_map_io done.\n");
}

static void __init htcherald_disable_watchdog(void)
{
	/* Disable watchdog if running */
	if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) {
		/*
		 * disable a potentially running watchdog timer before
		 * it kills us.
		 */
		printk(KERN_WARNING "OMAP850 Watchdog seems to be activated, disabling it for now.\n");
		omap_writel(0xF5, OMAP_WDT_TIMER_MODE);
		omap_writel(0xA0, OMAP_WDT_TIMER_MODE);
	}
}

#define HTCHERALD_GPIO_USB_EN1 33
#define HTCHERALD_GPIO_USB_EN2 73
#define HTCHERALD_GPIO_USB_DM  35
#define HTCHERALD_GPIO_USB_DP  36

static void __init htcherald_usb_enable(void)
{
	unsigned int tries = 20;
	unsigned int value = 0;

	/* Request the GPIOs we need to control here */
	if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0)
		goto err1;

	if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0)
		goto err2;

	if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0)
		goto err3;

	if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0)
		goto err4;

	/* force USB_EN GPIO to 0 */
	do {
		/* output low */
		gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0);
	} while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 &&
			--tries);

	if (value == 1)
		printk(KERN_WARNING "Unable to reset USB, trying to continue\n");

	gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0); /* output low */
	gpio_direction_input(HTCHERALD_GPIO_USB_DM); /* input */
	gpio_direction_input(HTCHERALD_GPIO_USB_DP); /* input */

	goto done;

err4:
	gpio_free(HTCHERALD_GPIO_USB_DM);
err3:
	gpio_free(HTCHERALD_GPIO_USB_EN2);
err2:
	gpio_free(HTCHERALD_GPIO_USB_EN1);
err1:
	printk(KERN_ERR "Unabled to request GPIO for USB\n");
done:
	printk(KERN_INFO "USB setup complete.\n");
}

static void __init htcherald_init(void)
{
	printk(KERN_INFO "HTC Herald init.\n");

	omap_gpio_init();

	omap_board_config = htcherald_config;
	omap_board_config_size = ARRAY_SIZE(htcherald_config);
	platform_add_devices(devices, ARRAY_SIZE(devices));

	htcherald_disable_watchdog();

	htcherald_usb_enable();
	omap_usb_init(&htcherald_usb_config);
}

static void __init htcherald_init_irq(void)
{
	printk(KERN_INFO "htcherald_init_irq.\n");
	omap1_init_common_hw();
	omap_init_irq();
}

MACHINE_START(HERALD, "HTC Herald")
	/* Maintainer: Cory Maccarrone <darkstar6262@gmail.com> */
	/* Maintainer: wing-linux.sourceforge.net */
	.phys_io        = 0xfff00000,
	.io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
	.boot_params    = 0x10000100,
	.map_io         = htcherald_map_io,
	.init_irq       = htcherald_init_irq,
	.init_machine   = htcherald_init,
	.timer          = &omap_timer,
MACHINE_END
