/*
 * 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/delay.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/htcpld.h>
#include <linux/leds.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/omapfb.h>
#include <linux/platform_data/keypad-omap.h>

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

#include <mach/omap7xx.h>
#include "mmc.h"

#include <mach/irqs.h>
#include <mach/usb.h>

#include "common.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)

/* GPIO definitions for the power button and keyboard slide switch */
#define HTCHERALD_GPIO_POWER 139
#define HTCHERALD_GPIO_SLIDE 174
#define HTCHERALD_GIRQ_BTNS 141

/* GPIO definitions for the touchscreen */
#define HTCHERALD_GPIO_TS 76

/* HTCPLD definitions */

/*
 * CPLD Logic
 *
 * Chip 3 - 0x03
 *
 * Function            7 6 5 4  3 2 1 0
 * ------------------------------------
 * DPAD light          x x x x  x x x 1
 * SoundDev            x x x x  1 x x x
 * Screen white        1 x x x  x x x x
 * MMC power on        x x x x  x 1 x x
 * Happy times (n)     0 x x x  x 1 x x
 *
 * Chip 4 - 0x04
 *
 * Function            7 6 5 4  3 2 1 0
 * ------------------------------------
 * Keyboard light      x x x x  x x x 1
 * LCD Bright (4)      x x x x  x 1 1 x
 * LCD Bright (3)      x x x x  x 0 1 x
 * LCD Bright (2)      x x x x  x 1 0 x
 * LCD Bright (1)      x x x x  x 0 0 x
 * LCD Off             x x x x  0 x x x
 * LCD image (fb)      1 x x x  x x x x
 * LCD image (white)   0 x x x  x x x x
 * Caps lock LED       x x 1 x  x x x x
 *
 * Chip 5 - 0x05
 *
 * Function            7 6 5 4  3 2 1 0
 * ------------------------------------
 * Red (solid)         x x x x  x 1 x x
 * Red (flash)         x x x x  x x 1 x
 * Green (GSM flash)   x x x x  1 x x x
 * Green (GSM solid)   x x x 1  x x x x
 * Green (wifi flash)  x x 1 x  x x x x
 * Blue (bt flash)     x 1 x x  x x x x
 * DPAD Int Enable     1 x x x  x x x 0
 *
 * (Combinations of the above can be made for different colors.)
 * The direction pad interrupt enable must be set each time the
 * interrupt is handled.
 *
 * Chip 6 - 0x06
 *
 * Function            7 6 5 4  3 2 1 0
 * ------------------------------------
 * Vibrator            x x x x  1 x x x
 * Alt LED             x x x 1  x x x x
 * Screen white        1 x x x  x x x x
 * Screen white        x x 1 x  x x x x
 * Screen white        x 0 x x  x x x x
 * Enable kbd dpad     x x x x  x x 0 x
 * Happy Times         0 1 0 x  x x 0 x
 */

/*
 * HTCPLD GPIO lines start 16 after OMAP_MAX_GPIO_LINES to account
 * for the 16 MPUIO lines.
 */
#define HTCPLD_GPIO_START_OFFSET	(OMAP_MAX_GPIO_LINES + 16)
#define HTCPLD_IRQ(chip, offset)	(OMAP_IRQ_END + 8 * (chip) + (offset))
#define HTCPLD_BASE(chip, offset)	\
	(HTCPLD_GPIO_START_OFFSET + 8 * (chip) + (offset))

#define HTCPLD_GPIO_LED_DPAD		HTCPLD_BASE(0, 0)
#define HTCPLD_GPIO_LED_KBD		HTCPLD_BASE(1, 0)
#define HTCPLD_GPIO_LED_CAPS		HTCPLD_BASE(1, 5)
#define HTCPLD_GPIO_LED_RED_FLASH	HTCPLD_BASE(2, 1)
#define HTCPLD_GPIO_LED_RED_SOLID	HTCPLD_BASE(2, 2)
#define HTCPLD_GPIO_LED_GREEN_FLASH	HTCPLD_BASE(2, 3)
#define HTCPLD_GPIO_LED_GREEN_SOLID	HTCPLD_BASE(2, 4)
#define HTCPLD_GPIO_LED_WIFI		HTCPLD_BASE(2, 5)
#define HTCPLD_GPIO_LED_BT		HTCPLD_BASE(2, 6)
#define HTCPLD_GPIO_LED_VIBRATE		HTCPLD_BASE(3, 3)
#define HTCPLD_GPIO_LED_ALT		HTCPLD_BASE(3, 4)

#define HTCPLD_GPIO_RIGHT_KBD		HTCPLD_BASE(6, 7)
#define HTCPLD_GPIO_UP_KBD		HTCPLD_BASE(6, 6)
#define HTCPLD_GPIO_LEFT_KBD		HTCPLD_BASE(6, 5)
#define HTCPLD_GPIO_DOWN_KBD		HTCPLD_BASE(6, 4)

#define HTCPLD_GPIO_RIGHT_DPAD		HTCPLD_BASE(7, 7)
#define HTCPLD_GPIO_UP_DPAD		HTCPLD_BASE(7, 6)
#define HTCPLD_GPIO_LEFT_DPAD		HTCPLD_BASE(7, 5)
#define HTCPLD_GPIO_DOWN_DPAD		HTCPLD_BASE(7, 4)
#define HTCPLD_GPIO_ENTER_DPAD		HTCPLD_BASE(7, 3)

/*
 * The htcpld chip requires a gpio write to a specific line
 * to re-enable interrupts after one has occurred.
 */
#define HTCPLD_GPIO_INT_RESET_HI	HTCPLD_BASE(2, 7)
#define HTCPLD_GPIO_INT_RESET_LO	HTCPLD_BASE(2, 0)

/* Chip 5 */
#define HTCPLD_IRQ_RIGHT_KBD		HTCPLD_IRQ(0, 7)
#define HTCPLD_IRQ_UP_KBD		HTCPLD_IRQ(0, 6)
#define HTCPLD_IRQ_LEFT_KBD		HTCPLD_IRQ(0, 5)
#define HTCPLD_IRQ_DOWN_KBD		HTCPLD_IRQ(0, 4)

/* Chip 6 */
#define HTCPLD_IRQ_RIGHT_DPAD		HTCPLD_IRQ(1, 7)
#define HTCPLD_IRQ_UP_DPAD		HTCPLD_IRQ(1, 6)
#define HTCPLD_IRQ_LEFT_DPAD		HTCPLD_IRQ(1, 5)
#define HTCPLD_IRQ_DOWN_DPAD		HTCPLD_IRQ(1, 4)
#define HTCPLD_IRQ_ENTER_DPAD		HTCPLD_IRQ(1, 3)

/* Keyboard definition */

static const unsigned int htc_herald_keymap[] = {
	KEY(0, 0, KEY_RECORD), /* Mail button */
	KEY(1, 0, KEY_CAMERA), /* Camera */
