/*
 *  drivers/mtd/nand/nomadik_nand.c
 *
 *  Overview:
 *  	Driver for on-board NAND flash on Nomadik Platforms
 *
 * Copyright © 2007 STMicroelectronics Pvt. Ltd.
 * Author: Sachin Verma <sachin.verma@st.com>
 *
 * Copyright © 2009 Alessandro Rubini
 *
 * 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/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/platform_device.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <mach/nand.h>
#include <mach/fsmc.h>

#include <mtd/mtd-abi.h>

struct nomadik_nand_host {
	struct mtd_info		mtd;
	struct nand_chip	nand;
	void __iomem *data_va;
	void __iomem *cmd_va;
	void __iomem *addr_va;
	struct nand_bbt_descr *bbt_desc;
};

static struct nand_ecclayout nomadik_ecc_layout = {
	.eccbytes = 3 * 4,
	.eccpos = { /* each subpage has 16 bytes: pos 2,3,4 hosts ECC */
		0x02, 0x03, 0x04,
		0x12, 0x13, 0x14,
		0x22, 0x23, 0x24,
		0x32, 0x33, 0x34},
	/* let's keep bytes 5,6,7 for us, just in case we change ECC algo */
	.oobfree = { {0x08, 0x08}, {0x18, 0x08}, {0x28, 0x08}, {0x38, 0x08} },
};

static void nomadik_ecc_control(struct mtd_info *mtd, int mode)
{
	/* No need to enable hw ecc, it's on by default */
}

static void nomadik_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
	struct nand_chip *nand = mtd->priv;
	struct nomadik_nand_host *host = nand->priv;

	if (cmd == NAND_CMD_NONE)
		return;

	if (ctrl & NAND_CLE)
		writeb(cmd, host->cmd_va);
	else
		writeb(cmd, host->addr_va);
}

static int nomadik_nand_probe(struct platform_device *pdev)
{
	struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data;
	struct nomadik_nand_host *host;
	struct mtd_info *mtd;
	struct nand_chip *nand;
	struct resource *res;
	int ret = 0;

	/* Allocate memory for the device structure (and zero it) */
	host = kzalloc(sizeof(struct nomadik_nand_host), GFP_KERNEL);
	if (!host) {
		dev_err(&pdev->dev, "Failed to allocate device structure.\n");
		return -ENOMEM;
	}

	/* Call the client's init function, if any */
	if (pdata->init)
		ret = pdata->init();
	if (ret < 0) {
		dev_err(&pdev->dev, "Init function failed\n");
		goto err;
	}

	/* ioremap three regions */
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr");
	if (!res) {
		ret = -EIO;
		goto err_unmap;
	}
	host->addr_va = ioremap(res->start, resource_size(res));

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
	if (!res) {
		ret = -EIO;
		goto err_unmap;
	}
	host->data_va = ioremap(res->start, resource_size(res));

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd");
	if (!res) {
		ret = -EIO;
		goto err_unmap;
	}
	host->cmd_va = ioremap(res->start, resource_size(res));

	if (!host->addr_va || !host->data_va || !host->cmd_va) {
		ret = -ENOMEM;
		goto err_unmap;
	}

	/* Link all private pointers */
	mtd = &host->mtd;
	nand = &host->nand;
	mtd->priv = nand;
	nand->priv = host;

	host->mtd.owner = THIS_MODULE;
	nand->IO_ADDR_R = host->data_va;
	nand->IO_ADDR_W = host->data_va;
	nand->cmd_ctrl = nomadik_cmd_ctrl;

	/*
	 * This stanza declares ECC_HW but uses soft routines. It's because
	 * HW claims to make the calculation but not the correction. However,
	 * I haven't managed to get the desired data out of it until now.
	 */
	nand->ecc.mode = NAND_ECC_SOFT;
	nand->ecc.layout = &nomadik_ecc_layout;
	nand->ecc.hwctl = nomadik_ecc_control;
	nand->ecc.size = 512;
	nand->ecc.bytes = 3;

	nand->options = pdata->options;

	/*
	 * Scan to find existence of the device
	 */
	if (nand_scan(&host->mtd, 1)) {
		ret = -ENXIO;
		goto err_unmap;
	}

	mtd_device_register(&host->mtd, pdata->parts, pdata->nparts);

	platform_set_drvdata(pdev, host);
	return 0;

 err_unmap:
	if (host->cmd_va)
		iounmap(host->cmd_va);
	if (host->data_va)
		iounmap(host->data_va);
	if (host->addr_va)
		iounmap(host->addr_va);
 err:
	kfree(host);
	return ret;
}

/*
 * Clean up routine
 */
static int nomadik_nand_remove(struct platform_device *pdev)
{
	struct nomadik_nand_host *host = platform_get_drvdata(pdev);
	struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data;

	if (pdata->exit)
		pdata->exit();

	if (host) {
		nand_release(&host->mtd);
		iounmap(host->cmd_va);
		iounmap(host->data_va);
		iounmap(host->addr_va);
		kfree(host);
	}
	return 0;
}

static int nomadik_nand_suspend(struct device *dev)
{
	struct nomadik_nand_host *host = dev_get_drvdata(dev);
	int ret = 0;
	if (host)
		ret = host->mtd.suspend(&host->mtd);
	return ret;
}

static int nomadik_nand_resume(struct device *dev)
{
	struct nomadik_nand_host *host = dev_get_drvdata(dev);
	if (host)
		host->mtd.resume(&host->mtd);
	return 0;
}

static const struct dev_pm_ops nomadik_nand_pm_ops = {
	.suspend = nomadik_nand_suspend,
	.resume = nomadik_nand_resume,
};

static struct platform_driver nomadik_nand_driver = {
	.probe = nomadik_nand_probe,
	.remove = nomadik_nand_remove,
	.driver = {
		.owner = THIS_MODULE,
		.name = "nomadik_nand",
		.pm = &nomadik_nand_pm_ops,
	},
};

static int __init nand_nomadik_init(void)
{
	pr_info("Nomadik NAND driver\n");
	return platform_driver_register(&nomadik_nand_driver);
}

static void __exit nand_nomadik_exit(void)
{
	platform_driver_unregister(&nomadik_nand_driver);
}

module_init(nand_nomadik_init);
module_exit(nand_nomadik_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
MODULE_DESCRIPTION("NAND driver for Nomadik Platform");
