/*
 * linux/arch/arm/mach-omap1/board-ams-delta.c
 *
 * Modified from board-generic.c
 *
 * Board specific inits for the Amstrad E3 (codename Delta) videophone
 *
 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

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

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

#include <mach/board-ams-delta.h>
#include <mach/gpio.h>
#include <mach/keypad.h>
#include <mach/mux.h>
#include <mach/usb.h>
#include <mach/board.h>
#include <mach/common.h>

static u8 ams_delta_latch1_reg;
static u16 ams_delta_latch2_reg;

static int ams_delta_keymap[] = {
	KEY(0, 0, KEY_F1),		/* Advert    */

	KEY(3, 0, KEY_COFFEE),		/* Games     */
	KEY(2, 0, KEY_QUESTION),	/* Directory */
	KEY(3, 2, KEY_CONNECT),		/* Internet  */
	KEY(2, 1, KEY_SHOP),		/* Services  */
	KEY(1, 1, KEY_PHONE),		/* VoiceMail */

	KEY(1, 0, KEY_DELETE),		/* Delete    */
	KEY(2, 2, KEY_PLAY),		/* Play      */
	KEY(0, 1, KEY_PAGEUP),		/* Up        */
	KEY(3, 1, KEY_PAGEDOWN),	/* Down      */
	KEY(0, 2, KEY_EMAIL),		/* ReadEmail */
	KEY(1, 2, KEY_STOP),		/* Stop      */

	/* Numeric keypad portion */
	KEY(7, 0, KEY_KP1),
	KEY(6, 0, KEY_KP2),
	KEY(5, 0, KEY_KP3),
	KEY(7, 1, KEY_KP4),
	KEY(6, 1, KEY_KP5),
	KEY(5, 1, KEY_KP6),
	KEY(7, 2, KEY_KP7),
	KEY(6, 2, KEY_KP8),
	KEY(5, 2, KEY_KP9),
	KEY(6, 3, KEY_KP0),
	KEY(7, 3, KEY_KPASTERISK),
	KEY(5, 3, KEY_KPDOT),		/* # key     */
	KEY(2, 7, KEY_NUMLOCK),		/* Mute      */
	KEY(1, 7, KEY_KPMINUS),		/* Recall    */
	KEY(1, 6, KEY_KPPLUS),		/* Redial    */
	KEY(6, 7, KEY_KPSLASH),		/* Handsfree */
	KEY(0, 6, KEY_ENTER),		/* Video     */

	KEY(4, 7, KEY_CAMERA),		/* Photo     */

	KEY(4, 0, KEY_F2),		/* Home      */
	KEY(4, 1, KEY_F3),		/* Office    */
	KEY(4, 2, KEY_F4),		/* Mobile    */
	KEY(7, 7, KEY_F5),		/* SMS       */
	KEY(5, 7, KEY_F6),		/* Email     */

	/* QWERTY portion of keypad */
	KEY(4, 3, KEY_Q),
	KEY(3, 3, KEY_W),
	KEY(2, 3, KEY_E),
	KEY(1, 3, KEY_R),
	KEY(0, 3, KEY_T),
	KEY(7, 4, KEY_Y),
	KEY(6, 4, KEY_U),
	KEY(5, 4, KEY_I),
	KEY(4, 4, KEY_O),
	KEY(3, 4, KEY_P),

	KEY(2, 4, KEY_A),
	KEY(1, 4, KEY_S),
	KEY(0, 4, KEY_D),
	KEY(7, 5, KEY_F),
	KEY(6, 5, KEY_G),
	KEY(5, 5, KEY_H),
	KEY(4, 5, KEY_J),
	KEY(3, 5, KEY_K),
	KEY(2, 5, KEY_L),

	KEY(1, 5, KEY_Z),
	KEY(0, 5, KEY_X),
	KEY(7, 6, KEY_C),
	KEY(6, 6, KEY_V),
	KEY(5, 6, KEY_B),
	KEY(4, 6, KEY_N),
	KEY(3, 6, KEY_M),
	KEY(2, 6, KEY_SPACE),

	KEY(0, 7, KEY_LEFTSHIFT),	/* Vol up    */
	KEY(3, 7, KEY_LEFTCTRL),	/* Vol down  */

	0
};

void ams_delta_latch1_write(u8 mask, u8 value)
{
	ams_delta_latch1_reg &= ~mask;
	ams_delta_latch1_reg |= value;
	*(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg;
}

void ams_delta_latch2_write(u16 mask, u16 value)
{
	ams_delta_latch2_reg &= ~mask;
	ams_delta_latch2_reg |= value;
	*(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg;
}

static void __init ams_delta_init_irq(void)
{
	omap1_init_common_hw();
	omap_init_irq();
	omap_gpio_init();
}

static struct map_desc ams_delta_io_desc[] __initdata = {
	/* AMS_DELTA_LATCH1 */
	{
		.virtual	= AMS_DELTA_LATCH1_VIRT,
		.pfn		= __phys_to_pfn(AMS_DELTA_LATCH1_PHYS),
		.length		= 0x01000000,
		.type		= MT_DEVICE
	},
	/* AMS_DELTA_LATCH2 */
	{
		.virtual	= AMS_DELTA_LATCH2_VIRT,
		.pfn		= __phys_to_pfn(AMS_DELTA_LATCH2_PHYS),
		.length		= 0x01000000,
		.type		= MT_DEVICE
	},
	/* AMS_DELTA_MODEM */
	{
		.virtual	= AMS_DELTA_MODEM_VIRT,
		.pfn		= __phys_to_pfn(AMS_DELTA_MODEM_PHYS),
		.length		= 0x01000000,
		.type		= MT_DEVICE
	}
};

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

static struct omap_uart_config ams_delta_uart_config __initdata = {
	.enabled_uarts = 1,
};

static struct omap_usb_config ams_delta_usb_config __initdata = {
	.register_host	= 1,
	.hmc_mode	= 16,
	.pins[0]	= 2,
};

static struct omap_board_config_kernel ams_delta_config[] = {
	{ OMAP_TAG_LCD,		&ams_delta_lcd_config },
	{ OMAP_TAG_UART,	&ams_delta_uart_config },
};

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

static struct omap_kp_platform_data ams_delta_kp_data = {
	.rows		= 8,
	.cols		= 8,
	.keymap 	= ams_delta_keymap,
	.keymapsize	= ARRAY_SIZE(ams_delta_keymap),
	.delay		= 9,
};

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

static struct platform_device ams_delta_lcd_device = {
	.name	= "lcd_ams_delta",
	.id	= -1,
};

static struct platform_device ams_delta_led_device = {
	.name	= "ams-delta-led",
	.id	= -1
};

static struct platform_device *ams_delta_devices[] __initdata = {
	&ams_delta_kp_device,
	&ams_delta_lcd_device,
	&ams_delta_led_device,
};

static void __init ams_delta_init(void)
{
	iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));

	omap_board_config = ams_delta_config;
	omap_board_config_size = ARRAY_SIZE(ams_delta_config);
	omap_serial_init();
	omap_register_i2c_bus(1, 100, NULL, 0);

	/* Clear latch2 (NAND, LCD, modem enable) */
	ams_delta_latch2_write(~0, 0);

	omap_usb_init(&ams_delta_usb_config);
	platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
}

static void __init ams_delta_map_io(void)
{
	omap1_map_common_io();
}

MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
	/* Maintainer: Jonathan McDowell <noodles@earth.li> */
	.phys_io	= 0xfff00000,
	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
	.boot_params	= 0x10000100,
	.map_io		= ams_delta_map_io,
	.init_irq	= ams_delta_init_irq,
	.init_machine	= ams_delta_init,
	.timer		= &omap_timer,
MACHINE_END

EXPORT_SYMBOL(ams_delta_latch1_write);
EXPORT_SYMBOL(ams_delta_latch2_write);
