/*
 *  RouterBoard 500 Platform devices
 *
 *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
 *  Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
 *
 *  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.
 */
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/serial_8250.h>

#include <asm/bootinfo.h>

#include <asm/mach-rc32434/rc32434.h>
#include <asm/mach-rc32434/dma.h>
#include <asm/mach-rc32434/dma_v.h>
#include <asm/mach-rc32434/eth.h>
#include <asm/mach-rc32434/rb.h>
#include <asm/mach-rc32434/integ.h>
#include <asm/mach-rc32434/gpio.h>
#include <asm/mach-rc32434/irq.h>

#define ETH0_RX_DMA_ADDR  (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET)
#define ETH0_TX_DMA_ADDR  (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET)

extern unsigned int idt_cpu_freq;

static struct mpmc_device dev3;

void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
{
	unsigned long flags;

	spin_lock_irqsave(&dev3.lock, flags);

	dev3.state = (dev3.state | or_mask) & ~nand_mask;
	writeb(dev3.state, dev3.base);

	spin_unlock_irqrestore(&dev3.lock, flags);
}
EXPORT_SYMBOL(set_latch_u5);

unsigned char get_latch_u5(void)
{
	return dev3.state;
}
EXPORT_SYMBOL(get_latch_u5);

static struct resource korina_dev0_res[] = {
	{
		.name = "korina_regs",
		.start = ETH0_BASE_ADDR,
		.end = ETH0_BASE_ADDR + sizeof(struct eth_regs),
		.flags = IORESOURCE_MEM,
	 }, {
		.name = "korina_rx",
		.start = ETH0_DMA_RX_IRQ,
		.end = ETH0_DMA_RX_IRQ,
		.flags = IORESOURCE_IRQ
	}, {
		.name = "korina_tx",
		.start = ETH0_DMA_TX_IRQ,
		.end = ETH0_DMA_TX_IRQ,
		.flags = IORESOURCE_IRQ
	}, {
		.name = "korina_ovr",
		.start = ETH0_RX_OVR_IRQ,
		.end = ETH0_RX_OVR_IRQ,
		.flags = IORESOURCE_IRQ
	}, {
		.name = "korina_und",
		.start = ETH0_TX_UND_IRQ,
		.end = ETH0_TX_UND_IRQ,
		.flags = IORESOURCE_IRQ
	}, {
		.name = "korina_dma_rx",
		.start = ETH0_RX_DMA_ADDR,
		.end = ETH0_RX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
		.flags = IORESOURCE_MEM,
	 }, {
		.name = "korina_dma_tx",
		.start = ETH0_TX_DMA_ADDR,
		.end = ETH0_TX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
		.flags = IORESOURCE_MEM,
	 }
};

static struct korina_device korina_dev0_data = {
	.name = "korina0",
	.mac = {0xde, 0xca, 0xff, 0xc0, 0xff, 0xee}
};

static struct platform_device korina_dev0 = {
	.id = -1,
	.name = "korina",
	.resource = korina_dev0_res,
	.num_resources = ARRAY_SIZE(korina_dev0_res),
};

static struct resource cf_slot0_res[] = {
	{
		.name = "cf_membase",
		.flags = IORESOURCE_MEM
	}, {
		.name = "cf_irq",
		.start = (8 + 4 * 32 + CF_GPIO_NUM),	/* 149 */
		.end = (8 + 4 * 32 + CF_GPIO_NUM),
		.flags = IORESOURCE_IRQ
	}
};

static struct cf_device cf_slot0_data = {
	.gpio_pin = CF_GPIO_NUM
};

static struct platform_device cf_slot0 = {
	.id = -1,
	.name = "pata-rb532-cf",
	.dev.platform_data = &cf_slot0_data,
	.resource = cf_slot0_res,
	.num_resources = ARRAY_SIZE(cf_slot0_res),
};

/* Resources and device for NAND */
static int rb532_dev_ready(struct mtd_info *mtd)
{
	return gpio_get_value(GPIO_RDY);
}

static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
	struct nand_chip *chip = mtd_to_nand(mtd);
	unsigned char orbits, nandbits;

	if (ctrl & NAND_CTRL_CHANGE) {
		orbits = (ctrl & NAND_CLE) << 1;
		orbits |= (ctrl & NAND_ALE) >> 1;

		nandbits = (~ctrl & NAND_CLE) << 1;
		nandbits |= (~ctrl & NAND_ALE) >> 1;

		set_latch_u5(orbits, nandbits);
	}
	if (cmd != NAND_CMD_NONE)
		writeb(cmd, chip->IO_ADDR_W);
}

static struct resource nand_slot0_res[] = {
	[0] = {
		.name = "nand_membase",
		.flags = IORESOURCE_MEM
	}
};

static struct platform_nand_data rb532_nand_data = {
	.ctrl.dev_ready = rb532_dev_ready,
	.ctrl.cmd_ctrl	= rb532_cmd_ctrl,
};

static struct platform_device nand_slot0 = {
	.name = "gen_nand",
	.id = -1,
	.resource = nand_slot0_res,
	.num_resources = ARRAY_SIZE(nand_slot0_res),
	.dev.platform_data = &rb532_nand_data,
};

static struct mtd_partition rb532_partition_info[] = {
	{
		.name = "Routerboard NAND boot",
		.offset = 0,
		.size = 4 * 1024 * 1024,
	}, {
		.name = "rootfs",
		.offset = MTDPART_OFS_NXTBLK,
		.size = MTDPART_SIZ_FULL,
	}
};

static struct platform_device rb532_led = {
	.name = "rb532-led",
	.id = -1,
};

static struct platform_device rb532_button = {
	.name	= "rb532-button",
	.id	= -1,
};

static struct resource rb532_wdt_res[] = {
	{
		.name = "rb532_wdt_res",
		.start = INTEG0_BASE_ADDR,
		.end = INTEG0_BASE_ADDR + sizeof(struct integ),
		.flags = IORESOURCE_MEM,
	}
};

static struct platform_device rb532_wdt = {
	.name		= "rc32434_wdt",
	.id		= -1,
	.resource	= rb532_wdt_res,
	.num_resources	= ARRAY_SIZE(rb532_wdt_res),
};

static struct plat_serial8250_port rb532_uart_res[] = {
	{
		.type           = PORT_16550A,
		.membase	= (char *)KSEG1ADDR(REGBASE + UART0BASE),
		.irq		= UART0_IRQ,
		.regshift	= 2,
		.iotype		= UPIO_MEM,
		.flags		= UPF_BOOT_AUTOCONF,
	},
	{
		.flags		= 0,
	}
};

static struct platform_device rb532_uart = {
	.name		   = "serial8250",
	.id		   = PLAT8250_DEV_PLATFORM,
	.dev.platform_data = &rb532_uart_res,
};

static struct platform_device *rb532_devs[] = {
	&korina_dev0,
	&nand_slot0,
	&cf_slot0,
	&rb532_led,
	&rb532_button,
	&rb532_uart,
	&rb532_wdt
};

/* NAND definitions */
#define NAND_CHIP_DELAY 25

static void __init rb532_nand_setup(void)
{
	switch (mips_machtype) {
	case MACH_MIKROTIK_RB532A:
		set_latch_u5(LO_FOFF | LO_CEX,
				LO_ULED | LO_ALE | LO_CLE | LO_WPX);
		break;
	default:
		set_latch_u5(LO_WPX | LO_FOFF | LO_CEX,
				LO_ULED | LO_ALE | LO_CLE);
		break;
	}

	/* Setup NAND specific settings */
	rb532_nand_data.chip.nr_chips = 1;
	rb532_nand_data.chip.nr_partitions = ARRAY_SIZE(rb532_partition_info);
	rb532_nand_data.chip.partitions = rb532_partition_info;
	rb532_nand_data.chip.chip_delay = NAND_CHIP_DELAY;
}


static int __init plat_setup_devices(void)
{
	/* Look for the CF card reader */
	if (!readl(IDT434_REG_BASE + DEV1MASK))
		rb532_devs[2] = NULL;	/* disable cf_slot0 at index 2 */
	else {
		cf_slot0_res[0].start =
		    readl(IDT434_REG_BASE + DEV1BASE);
		cf_slot0_res[0].end = cf_slot0_res[0].start + 0x1000;
	}

	/* Read the NAND resources from the device controller */
	nand_slot0_res[0].start = readl(IDT434_REG_BASE + DEV2BASE);
	nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000;

	/* Read and map device controller 3 */
	dev3.base = ioremap_nocache(readl(IDT434_REG_BASE + DEV3BASE), 1);

	if (!dev3.base) {
		printk(KERN_ERR "rb532: cannot remap device controller 3\n");
		return -ENXIO;
	}

	/* Initialise the NAND device */
	rb532_nand_setup();

	/* set the uart clock to the current cpu frequency */
	rb532_uart_res[0].uartclk = idt_cpu_freq;

	dev_set_drvdata(&korina_dev0.dev, &korina_dev0_data);

	return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
}

static int __init setup_kmac(char *s)
{
	printk(KERN_INFO "korina mac = %s\n", s);
	if (!mac_pton(s, korina_dev0_data.mac)) {
		printk(KERN_ERR "Invalid mac\n");
		return -EINVAL;
	}
	return 0;
}

__setup("kmac=", setup_kmac);

arch_initcall(plat_setup_devices);
