2005-04-16 15:20:36 -07:00
/*
* drivers / mtd / nand / edb7312 . c
*
2006-05-14 01:51:54 +01:00
* Copyright ( C ) 2002 Marius Gröger ( mag @ sysgo . de )
2005-04-16 15:20:36 -07:00
*
* Derived from drivers / mtd / nand / autcpu12 . c
* Copyright ( c ) 2001 Thomas Gleixner ( gleixner @ autronix . de )
*
* 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 .
*
* Overview :
* This is a device driver for the NAND flash device found on the
* CLEP7312 board which utilizes the Toshiba TC58V64AFT part . This is
* a 64 Mibit ( 8 MiB x 8 bits ) NAND flash device .
*/
# include <linux/slab.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/mtd/mtd.h>
# include <linux/mtd/nand.h>
# include <linux/mtd/partitions.h>
# include <asm/io.h>
2008-08-05 16:14:15 +01:00
# include <mach/hardware.h> /* for CLPS7111_VIRT_BASE */
2005-04-16 15:20:36 -07:00
# include <asm/sizes.h>
# include <asm/hardware/clps7111.h>
/*
* MTD structure for EDB7312 board
*/
static struct mtd_info * ep7312_mtd = NULL ;
/*
* Values specific to the EDB7312 board ( used with EP7312 processor )
*/
# define EP7312_FIO_PBASE 0x10000000 /* Phys address of flash */
# define EP7312_PXDR 0x0001 / *
* IO offset to Port B data register
* where the CLE , ALE and NCE pins
* are wired to .
*/
# define EP7312_PXDDR 0x0041 / *
* IO offset to Port B data direction
* register so we can control the IO
* lines .
*/
/*
* Module stuff
*/
static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE ;
2006-05-13 18:07:53 +01:00
static void __iomem * ep7312_pxdr = ( void __iomem * ) EP7312_PXDR ;
static void __iomem * ep7312_pxddr = ( void __iomem * ) EP7312_PXDDR ;
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_MTD_PARTITIONS
/*
* Define static partitions for flash device
*/
static struct mtd_partition partition_info [ ] = {
2006-05-13 18:07:53 +01:00
{ . name = " EP7312 Nand Flash " ,
. offset = 0 ,
. size = 8 * 1024 * 1024 }
2005-04-16 15:20:36 -07:00
} ;
2006-05-13 18:07:53 +01:00
2005-04-16 15:20:36 -07:00
# define NUM_PARTITIONS 1
# endif
2005-11-07 11:15:49 +00:00
/*
2005-04-16 15:20:36 -07:00
* hardware specific access to control - lines
2006-05-23 23:25:53 +02:00
*
2007-07-18 14:56:11 +02:00
* NAND_NCE : bit 0 - > bit 6 ( bit 7 = 1 )
2006-05-23 23:25:53 +02:00
* NAND_CLE : bit 1 - > bit 4
* NAND_ALE : bit 2 - > bit 5
2005-04-16 15:20:36 -07:00
*/
2006-05-23 23:25:53 +02:00
static void ep7312_hwcontrol ( struct mtd_info * mtd , int cmd , unsigned int ctrl )
2005-04-16 15:20:36 -07:00
{
2006-05-23 23:25:53 +02:00
struct nand_chip * chip = mtd - > priv ;
if ( ctrl & NAND_CTRL_CHANGE ) {
2007-07-18 14:56:11 +02:00
unsigned char bits = 0x80 ;
2006-05-23 23:25:53 +02:00
2007-07-18 14:56:11 +02:00
bits | = ( ctrl & ( NAND_CLE | NAND_ALE ) ) < < 3 ;
bits | = ( ctrl & NAND_NCE ) ? 0x00 : 0x40 ;
2006-05-23 23:25:53 +02:00
2007-07-18 14:56:11 +02:00
clps_writeb ( ( clps_readb ( ep7312_pxdr ) & 0xF0 ) | bits ,
2006-05-23 23:25:53 +02:00
ep7312_pxdr ) ;
2005-04-16 15:20:36 -07:00
}
2006-05-23 23:25:53 +02:00
if ( cmd ! = NAND_CMD_NONE )
writeb ( cmd , chip - > IO_ADDR_W ) ;
2005-04-16 15:20:36 -07:00
}
/*
* read device ready pin
*/
static int ep7312_device_ready ( struct mtd_info * mtd )
{
return 1 ;
}
2006-05-13 18:07:53 +01:00
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_MTD_PARTITIONS
const char * part_probes [ ] = { " cmdlinepart " , NULL } ;
# endif
/*
* Main initialization routine
*/
2006-05-13 18:07:53 +01:00
static int __init ep7312_init ( void )
2005-04-16 15:20:36 -07:00
{
struct nand_chip * this ;
const char * part_type = 0 ;
int mtd_parts_nb = 0 ;
struct mtd_partition * mtd_parts = 0 ;
2006-05-13 18:07:53 +01:00
void __iomem * ep7312_fio_base ;
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* Allocate memory for MTD device structure and private data */
2006-05-13 18:07:53 +01:00
ep7312_mtd = kmalloc ( sizeof ( struct mtd_info ) + sizeof ( struct nand_chip ) , GFP_KERNEL ) ;
2005-04-16 15:20:36 -07:00
if ( ! ep7312_mtd ) {
printk ( " Unable to allocate EDB7312 NAND MTD device structure. \n " ) ;
return - ENOMEM ;
}
2005-11-07 11:15:49 +00:00
2008-02-03 17:22:34 +02:00
/* map physical address */
2005-04-16 15:20:36 -07:00
ep7312_fio_base = ioremap ( ep7312_fio_pbase , SZ_1K ) ;
2006-05-13 18:07:53 +01:00
if ( ! ep7312_fio_base ) {
2005-04-16 15:20:36 -07:00
printk ( " ioremap EDB7312 NAND flash failed \n " ) ;
kfree ( ep7312_mtd ) ;
return - EIO ;
}
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* Get pointer to private data */
2006-05-13 18:07:53 +01:00
this = ( struct nand_chip * ) ( & ep7312_mtd [ 1 ] ) ;
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* Initialize structures */
2006-05-13 18:07:53 +01:00
memset ( ep7312_mtd , 0 , sizeof ( struct mtd_info ) ) ;
memset ( this , 0 , sizeof ( struct nand_chip ) ) ;
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* Link the private data with the MTD structure */
ep7312_mtd - > priv = this ;
2006-05-14 01:20:46 +01:00
ep7312_mtd - > owner = THIS_MODULE ;
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/*
* Set GPIO Port B control register so that the pins are configured
* to be outputs for controlling the NAND flash .
*/
clps_writeb ( 0xf0 , ep7312_pxddr ) ;
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* insert callbacks */
this - > IO_ADDR_R = ep7312_fio_base ;
this - > IO_ADDR_W = ep7312_fio_base ;
2006-05-23 23:25:53 +02:00
this - > cmd_ctrl = ep7312_hwcontrol ;
2005-04-16 15:20:36 -07:00
this - > dev_ready = ep7312_device_ready ;
/* 15 us command delay time */
this - > chip_delay = 15 ;
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* Scan to find existence of the device */
2006-05-13 18:07:53 +01:00
if ( nand_scan ( ep7312_mtd , 1 ) ) {
2005-04-16 15:20:36 -07:00
iounmap ( ( void * ) ep7312_fio_base ) ;
2006-05-13 18:07:53 +01:00
kfree ( ep7312_mtd ) ;
2005-04-16 15:20:36 -07:00
return - ENXIO ;
}
# ifdef CONFIG_MTD_PARTITIONS
ep7312_mtd - > name = " edb7312-nand " ;
2006-05-13 18:07:53 +01:00
mtd_parts_nb = parse_mtd_partitions ( ep7312_mtd , part_probes , & mtd_parts , 0 ) ;
2005-04-16 15:20:36 -07:00
if ( mtd_parts_nb > 0 )
part_type = " command line " ;
else
mtd_parts_nb = 0 ;
# endif
if ( mtd_parts_nb = = 0 ) {
mtd_parts = partition_info ;
mtd_parts_nb = NUM_PARTITIONS ;
part_type = " static " ;
}
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* Register the partitions */
printk ( KERN_NOTICE " Using %s partition definition \n " , part_type ) ;
add_mtd_partitions ( ep7312_mtd , mtd_parts , mtd_parts_nb ) ;
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* Return happy */
return 0 ;
}
2006-05-13 18:07:53 +01:00
2005-04-16 15:20:36 -07:00
module_init ( ep7312_init ) ;
/*
* Clean up routine
*/
2006-05-13 18:07:53 +01:00
static void __exit ep7312_cleanup ( void )
2005-04-16 15:20:36 -07:00
{
2006-05-13 18:07:53 +01:00
struct nand_chip * this = ( struct nand_chip * ) & ep7312_mtd [ 1 ] ;
2005-11-07 11:15:49 +00:00
2005-04-16 15:20:36 -07:00
/* Release resources, unregister device */
2006-05-13 18:07:53 +01:00
nand_release ( ap7312_mtd ) ;
2005-11-07 11:15:49 +00:00
2006-09-21 18:12:43 +05:30
/* Release io resource */
2006-10-02 09:48:23 +01:00
iounmap ( this - > IO_ADDR_R ) ;
2006-09-21 18:12:43 +05:30
2005-04-16 15:20:36 -07:00
/* Free the MTD device structure */
2006-05-13 18:07:53 +01:00
kfree ( ep7312_mtd ) ;
2005-04-16 15:20:36 -07:00
}
2006-05-13 18:07:53 +01:00
2005-04-16 15:20:36 -07:00
module_exit ( ep7312_cleanup ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Marius Groeger <mag@sysgo.de> " ) ;
MODULE_DESCRIPTION ( " MTD map driver for Cogent EDB7312 board " ) ;