/*
*  Copyright (C) 2005 - 2007 by Basler Vision Technologies AG
*  Author: Thomas Koeller <thomas.koeller.qbaslerweb.com>
*  Original code by Thies Moeller <thies.moeller@baslerweb.com>
*
*  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>

#include <asm/io.h>
#include <asm/rm9k-ocd.h>

#include <excite_nandflash.h>

#define EXCITE_NANDFLASH_VERSION "0.1"

/* I/O register offsets */
#define EXCITE_NANDFLASH_DATA_BYTE   0x00
#define EXCITE_NANDFLASH_STATUS_BYTE 0x0c
#define EXCITE_NANDFLASH_ADDR_BYTE   0x10
#define EXCITE_NANDFLASH_CMD_BYTE    0x14

/* prefix for debug output */
static const char module_id[] = "excite_nandflash";

/*
 * partition definition
 */
static const struct mtd_partition partition_info[] = {
	{
		.name = "eXcite RootFS",
		.offset = 0,
		.size = MTDPART_SIZ_FULL
	}
};

static inline const struct resource *
excite_nand_get_resource(struct platform_device *d, unsigned long flags,
			 const char *basename)
{
	char buf[80];

	if (snprintf(buf, sizeof buf, "%s_%u", basename, d->id) >= sizeof buf)
		return NULL;
	return platform_get_resource_byname(d, flags, buf);
}

static inline void __iomem *
excite_nand_map_regs(struct platform_device *d, const char *basename)
{
	void *result = NULL;
	const struct resource *const r =
	    excite_nand_get_resource(d, IORESOURCE_MEM, basename);

	if (r)
		result = ioremap_nocache(r->start, r->end + 1 - r->start);
	return result;
}

/* controller and mtd information */
struct excite_nand_drvdata {
	struct mtd_info board_mtd;
	struct nand_chip board_chip;
	void __iomem *regs;
	void __iomem *tgt;
};

/* Control function */
static void excite_nand_control(struct mtd_info *mtd, int cmd,
				       unsigned int ctrl)
{
	struct excite_nand_drvdata * const d =
	    container_of(mtd, struct excite_nand_drvdata, board_mtd);

	switch (ctrl) {
	case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
		d->tgt = d->regs + EXCITE_NANDFLASH_CMD_BYTE;
		break;
	case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
		d->tgt = d->regs + EXCITE_NANDFLASH_ADDR_BYTE;
		break;
	case NAND_CTRL_CHANGE | NAND_NCE:
		d->tgt = d->regs + EXCITE_NANDFLASH_DATA_BYTE;
		break;
	}

	if (cmd != NAND_CMD_NONE)
		__raw_writeb(cmd, d->tgt);
}

/* Return 0 if flash is busy, 1 if ready */
static int excite_nand_devready(struct mtd_info *mtd)
{
	struct excite_nand_drvdata * const drvdata =
	    container_of(mtd, struct excite_nand_drvdata, board_mtd);

	return __raw_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS_BYTE);
}

/*
 * Called by device layer to remove the driver.
 * The binding to the mtd and all allocated
 * resources are released.
 */
static int __exit excite_nand_remove(struct device *dev)
{
	struct excite_nand_drvdata * const this = dev_get_drvdata(dev);

	dev_set_drvdata(dev, NULL);

	if (unlikely(!this)) {
		printk(KERN_ERR "%s: called %s without private data!!",
		       module_id, __func__);
		return -EINVAL;
	}

	/* first thing we need to do is release our mtd
	 * then go through freeing the resource used
	 */
	nand_release(&this->board_mtd);

	/* free the common resources */
	iounmap(this->regs);
	kfree(this);

	DEBUG(MTD_DEBUG_LEVEL1, "%s: removed\n", module_id);
	return 0;
}

/*
 * Called by device layer when it finds a device matching
 * one our driver can handle. This code checks to see if
 * it can allocate all necessary resources then calls the
 * nand layer to look for devices.
*/
static int __init excite_nand_probe(struct device *dev)
{
	struct platform_device * const pdev = to_platform_device(dev);
	struct excite_nand_drvdata *drvdata;	/* private driver data */
	struct nand_chip *board_chip;	/* private flash chip data */
	struct mtd_info *board_mtd;	/* mtd info for this board */
	int scan_res;

	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
	if (unlikely(!drvdata)) {
		printk(KERN_ERR "%s: no memory for drvdata\n",
		       module_id);
		return -ENOMEM;
	}

	/* bind private data into driver */
	dev_set_drvdata(dev, drvdata);

	/* allocate and map the resource */
	drvdata->regs =
		excite_nand_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);

	if (unlikely(!drvdata->regs)) {
		printk(KERN_ERR "%s: cannot reserve register region\n",
		       module_id);
		kfree(drvdata);
		return -ENXIO;
	}
	
	drvdata->tgt = drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;

	/* initialise our chip */
	board_chip = &drvdata->board_chip;
	board_chip->IO_ADDR_R = board_chip->IO_ADDR_W =
		drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;
	board_chip->cmd_ctrl = excite_nand_control;
	board_chip->dev_ready = excite_nand_devready;
	board_chip->chip_delay = 25;
	board_chip->ecc.mode = NAND_ECC_SOFT;

	/* link chip to mtd */
	board_mtd = &drvdata->board_mtd;
	board_mtd->priv = board_chip;

	DEBUG(MTD_DEBUG_LEVEL2, "%s: device scan\n", module_id);
	scan_res = nand_scan(&drvdata->board_mtd, 1);

	if (likely(!scan_res)) {
		DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id);
		add_mtd_partitions(&drvdata->board_mtd, partition_info,
				   ARRAY_SIZE(partition_info));
	} else {
		iounmap(drvdata->regs);
		kfree(drvdata);
		printk(KERN_ERR "%s: device scan failed\n", module_id);
		return -EIO;
	}
	return 0;
}

static struct device_driver excite_nand_driver = {
	.name = "excite_nand",
	.bus = &platform_bus_type,
	.probe = excite_nand_probe,
	.remove = __exit_p(excite_nand_remove)
};

static int __init excite_nand_init(void)
{
	pr_info("Basler eXcite nand flash driver Version "
		EXCITE_NANDFLASH_VERSION "\n");
	return driver_register(&excite_nand_driver);
}

static void __exit excite_nand_exit(void)
{
	driver_unregister(&excite_nand_driver);
}

module_init(excite_nand_init);
module_exit(excite_nand_exit);

MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(EXCITE_NANDFLASH_VERSION)
