/*
 *  drivers/mtd/nand/stwx_test.c
 *
 *
 *  Descriptions:
 *
 *  A NAND driver test and debugging module for the NAND flash device which 
 *  is used on the STWX225 board.  The NAND flash device is Samsung 
 *  K9F2808U0B - YVB0, two devices. 
 *
 */

/*
 * Support for NAND flash modules on ATI Xilleon 225 Set Top Wonder
 *
 */


#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/ioport.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand_ids.h>

#include <asm/io.h>
//#include <asm/arch/hardware.h>
#include <asm/ati/xilleon.h>

#ifdef CONFIG_MTD_NAND_ECC
#include <linux/mtd/nand_ecc.h>
#endif

#include "stw_flash.h"

/* STW NAND flash related */

#define NUM_PARTITIONS 2

extern int pflash_ready;


/* MTD structure for STWX225 board */
static struct mtd_info *stwx225_mtd = NULL;


/*
 * Define partitions for flash device
 */
const static struct mtd_partition partition_info[] = {
	{ name: "MTD partition 1",
	  offset: 0x0,
	  size: 2*1024*1024 },
	{ name: "MTD partition 2",
	  offset: 2*1024*1024,
	  size: 6*1024*1024 }
};


/*
 * Main initialization routine
 */
int __init stwx225_init (void)
{

	struct nand_chip *this;

	printk(KERN_INFO "STWX225 NAND Flash initializing...\n");

	/* Allocate memory for MTD device structure and private data */
	stwx225_mtd = kmalloc (sizeof(struct mtd_info) 
			       + sizeof (struct nand_chip), GFP_KERNEL);
	if (!stwx225_mtd) {
		printk ("Unable to allocate memory for NAND MTD.\n");
		return -ENOMEM;
	}

	/* Get pointer to private data */
	this = (struct nand_chip *) (&stwx225_mtd[1]);

	/* Initialize structures */
	memset((char *) stwx225_mtd, 0, sizeof(struct mtd_info));
	memset((char *) this, 0, sizeof(struct nand_chip));

	/* Link the private data with the MTD structure */
	stwx225_mtd->priv = this;


	pflash_init( );

	/*
	 * Set GPIO control register so that the pins are configured
	 * to be outputs for controlling the NAND flash.
	 */

	this->IO_ADDR = 0xbc000000;
	//this->CTRL_ADDR = 0xb8002c4c;
	//this->CLE = 0x01;
	//this->ALE = 0x02;
	//this->NCE = 0x04;

	/* Scan to find existance of the device */

	/* if (nand_scan (stwx225_mtd)) {
	  kfree (stwx225_mtd);
	  return -ENXIO;
	  }*/


	/* Allocate memory for internal data buffer */
	this->data_buf = kmalloc (sizeof(u_char) * 
				  (stwx225_mtd->oobblock + stwx225_mtd->oobsize), GFP_KERNEL);
	if (!this->data_buf) {
		printk ("Unable to allocate NAND data buffer for STWX225.\n");
		kfree (stwx225_mtd);
		return -ENOMEM;
	}

	/* Register the partitions */
	add_mtd_partitions(stwx225_mtd, 
			   (struct mtd_partition*) partition_info, 
			   (int)NUM_PARTITIONS);

	printk(KERN_INFO "STW4X225 NAND Flash initialized.\n");
	
	/* Return OK */
	return 0;
}
module_init(stwx225_init);

/*
 * Clean up routine
 */
#ifdef MODULE
static void __exit stwx225_cleanup (void)
{
	struct nand_chip *this = (struct nand_chip *) &stwx225_mtd[1];

	/* Unregister the device */
	del_mtd_device (stwx225_mtd);

	/* Free internal data buffer */
	kfree (this->data_buf);

	/* Free the MTD device structure */
	kfree (stwx225_mtd);
}
module_exit(stwx225_cleanup);
#endif


MODULE_LICENSE("GPL");
MODULE_AUTHOR("< >");
MODULE_DESCRIPTION("Linux test/debugging module for NAND devices on the STWX225 board");



