/*
 * arch/arm/mach-ks8695/board-acs5k.c
 *
 * Brivo Systems LLC, ACS-5000 Master Board
 *
 * Copyright 2008 Simtec Electronics
 *		  Daniel Silverstone <dsilvers@simtec.co.uk>
 *
 * 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/gpio.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/platform_device.h>

#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h>
#include <linux/platform_data/pca953x.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/partitions.h>

#include <asm/mach-types.h>

#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>

#include "devices.h"
#include <mach/gpio-ks8695.h>

#include "generic.h"

static struct i2c_gpio_platform_data acs5k_i2c_device_platdata = {
	.sda_pin	= 4,
	.scl_pin	= 5,
	.udelay		= 10,
};

static struct platform_device acs5k_i2c_device = {
	.name		= "i2c-gpio",
	.id		= -1,
	.num_resources	= 0,
	.resource	= NULL,
	.dev		= {
		.platform_data	= &acs5k_i2c_device_platdata,
	},
};

static int acs5k_pca9555_setup(struct i2c_client *client,
			       unsigned gpio_base, unsigned ngpio,
			       void *context)
{
	static int acs5k_gpio_value[] = {
		-1, -1, -1, -1, -1, -1, -1, 0, 1, 1, -1, 0, 1, 0, -1, -1
	};
	int n;

	for (n = 0; n < ARRAY_SIZE(acs5k_gpio_value); ++n) {
		gpio_request(gpio_base + n, "ACS-5000 GPIO Expander");
		if (acs5k_gpio_value[n] < 0)
			gpio_direction_input(gpio_base + n);
		else
			gpio_direction_output(gpio_base + n,
					      acs5k_gpio_value[n]);
		gpio_export(gpio_base + n, 0); /* Export, direction locked down */
	}

	return 0;
}

static struct pca953x_platform_data acs5k_i2c_pca9555_platdata = {
	.gpio_base	= 16, /* Start directly after the CPU's GPIO */
	.invert		= 0, /* Do not invert */
	.setup		= acs5k_pca9555_setup,
};

static struct i2c_board_info acs5k_i2c_devs[] __initdata = {
	{
		I2C_BOARD_INFO("pcf8563", 0x51),
	},
	{
		I2C_BOARD_INFO("pca9555", 0x20),
		.platform_data = &acs5k_i2c_pca9555_platdata,
	},
};

static void acs5k_i2c_init(void)
{
	/* The gpio interface */
	platform_device_register(&acs5k_i2c_device);
	/* I2C devices */
	i2c_register_board_info(0, acs5k_i2c_devs,
				ARRAY_SIZE(acs5k_i2c_devs));
}

static struct mtd_partition acs5k_nor_partitions[] = {
	[0] = {
		.name	= "Boot Agent and config",
		.size	= SZ_256K,
		.offset	= 0,
		.mask_flags = MTD_WRITEABLE,
	},
	[1] = {
		.name	= "Kernel",
		.size	= SZ_1M,
		.offset	= SZ_256K,
	},
	[2] = {
		.name	= "SquashFS1",
		.size	= SZ_2M,
		.offset	= SZ_256K + SZ_1M,
	},
	[3] = {
		.name	= "SquashFS2",
		.size	= SZ_4M + SZ_2M,
		.offset	= SZ_256K + SZ_1M + SZ_2M,
	},
	[4] = {
		.name	= "Data",
		.size	= SZ_16M + SZ_4M + SZ_2M + SZ_512K, /* 22.5 MB */
		.offset	= SZ_256K + SZ_8M + SZ_1M,
	}
};

static struct physmap_flash_data acs5k_nor_pdata = {
	.width		= 4,
	.nr_parts	= ARRAY_SIZE(acs5k_nor_partitions),
	.parts		= acs5k_nor_partitions,
};

static struct resource acs5k_nor_resource[] = {
	[0] = {
		.start = SZ_32M, /* We expect the bootloader to map
				  * the flash here.
				  */
		.end   = SZ_32M + SZ_16M - 1,
		.flags = IORESOURCE_MEM,
	},
	[1] = {
		.start = SZ_32M + SZ_16M,
		.end   = SZ_32M + SZ_32M - SZ_256K - 1,
		.flags = IORESOURCE_MEM,
	}
};

static struct platform_device acs5k_device_nor = {
	.name		= "physmap-flash",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(acs5k_nor_resource),
	.resource	= acs5k_nor_resource,
	.dev		= {
		.platform_data = &acs5k_nor_pdata,
	},
};

static void __init acs5k_register_nor(void)
{
	int ret;

	if (acs5k_nor_partitions[0].mask_flags == 0)
		printk(KERN_WARNING "Warning: Unprotecting bootloader and configuration partition\n");

	ret = platform_device_register(&acs5k_device_nor);
	if (ret < 0)
		printk(KERN_ERR "failed to register physmap-flash device\n");
}

static int __init acs5k_protection_setup(char *s)
{
	/* We can't allocate anything here but we should be able
	 * to trivially parse s and decide if we can protect the
	 * bootloader partition or not
	 */
	if (strcmp(s, "no") == 0)
		acs5k_nor_partitions[0].mask_flags = 0;

	return 1;
}

__setup("protect_bootloader=", acs5k_protection_setup);

static void __init acs5k_init_gpio(void)
{
	int i;

	ks8695_register_gpios();
	for (i = 0; i < 4; ++i)
		gpio_request(i, "ACS5K IRQ");
	gpio_request(7, "ACS5K KS_FRDY");
	for (i = 8; i < 16; ++i)
		gpio_request(i, "ACS5K Unused");

	gpio_request(3, "ACS5K CAN Control");
	gpio_request(6, "ACS5K Heartbeat");
	gpio_direction_output(3, 1); /* Default CAN_RESET high */
	gpio_direction_output(6, 0); /* Default KS8695_ACTIVE low */
	gpio_export(3, 0); /* export CAN_RESET as output only */
	gpio_export(6, 0); /* export KS8695_ACTIVE as output only */
}

static void __init acs5k_init(void)
{
	acs5k_init_gpio();

	/* Network device */
	ks8695_add_device_lan();	/* eth0 = LAN */
	ks8695_add_device_wan();	/* ethX = WAN */

	/* NOR devices */
	acs5k_register_nor();

	/* I2C bus */
	acs5k_i2c_init();
}

MACHINE_START(ACS5K, "Brivo Systems LLC ACS-5000 Master board")
	/* Maintainer: Simtec Electronics. */
	.atag_offset	= 0x100,
	.map_io		= ks8695_map_io,
	.init_irq	= ks8695_init_irq,
	.init_machine	= acs5k_init,
	.init_time	= ks8695_timer_init,
	.restart	= ks8695_restart,
MACHINE_END
