2005-04-17 02:20:36 +04:00
/*
* drivers / mtd / nand / h1910 . c
*
* Copyright ( C ) 2003 Joshua Wise ( joshua @ joshuawise . com )
*
* Derived from drivers / mtd / nand / edb7312 . c
2006-05-14 04:51:54 +04:00
* Copyright ( C ) 2002 Marius Gröger ( mag @ sysgo . de )
2005-04-17 02:20:36 +04:00
* 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
* iPAQ h1910 board which utilizes the Samsung K9F2808 part . This is
* a 128 Mibit ( 16 MiB x 8 bits ) NAND flash device .
*/
# include <linux/slab.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/mtd/mtd.h>
# include <linux/mtd/nand.h>
# include <linux/mtd/partitions.h>
# include <asm/io.h>
2008-08-05 19:14:15 +04:00
# include <mach/hardware.h> /* for CLPS7111_VIRT_BASE */
2005-04-17 02:20:36 +04:00
# include <asm/sizes.h>
2008-08-05 19:14:15 +04:00
# include <mach/h1900-gpio.h>
# include <mach/ipaq.h>
2005-04-17 02:20:36 +04:00
/*
* MTD structure for EDB7312 board
*/
static struct mtd_info * h1910_nand_mtd = NULL ;
/*
* Module stuff
*/
/*
* Define static partitions for flash device
*/
static struct mtd_partition partition_info [ ] = {
2006-05-13 21:07:53 +04:00
{ name : " h1910 NAND Flash " ,
offset : 0 ,
size : 16 * 1024 * 1024 }
2005-04-17 02:20:36 +04:00
} ;
2006-05-13 21:07:53 +04:00
2005-04-17 02:20:36 +04:00
# define NUM_PARTITIONS 1
2005-11-07 14:15:49 +03:00
/*
2005-04-17 02:20:36 +04:00
* hardware specific access to control - lines
2006-05-24 01:25:53 +04:00
*
* NAND_NCE : bit 0 - don ' t care
* NAND_CLE : bit 1 - address bit 2
* NAND_ALE : bit 2 - address bit 3
2005-04-17 02:20:36 +04:00
*/
2006-05-24 01:25:53 +04:00
static void h1910_hwcontrol ( struct mtd_info * mtd , int cmd ,
unsigned int ctrl )
2005-04-17 02:20:36 +04:00
{
2006-05-24 01:25:53 +04:00
struct nand_chip * chip = mtd - > priv ;
if ( cmd ! = NAND_CMD_NONE )
writeb ( cmd , chip - > IO_ADDR_W | ( ( ctrl & 0x6 ) < < 1 ) ) ;
2005-04-17 02:20:36 +04:00
}
/*
* read device ready pin
*/
#if 0
static int h1910_device_ready ( struct mtd_info * mtd )
{
return ( GPLR ( 55 ) & GPIO_bit ( 55 ) ) ;
}
# endif
/*
* Main initialization routine
*/
2006-05-13 21:07:53 +04:00
static int __init h1910_init ( void )
2005-04-17 02:20:36 +04:00
{
struct nand_chip * this ;
const char * part_type = 0 ;
int mtd_parts_nb = 0 ;
struct mtd_partition * mtd_parts = 0 ;
void __iomem * nandaddr ;
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
if ( ! machine_is_h1900 ( ) )
return - ENODEV ;
2005-11-07 14:15:49 +03:00
2005-11-17 19:46:41 +03:00
nandaddr = ioremap ( 0x08000000 , 0x1000 ) ;
2005-04-17 02:20:36 +04:00
if ( ! nandaddr ) {
printk ( " Failed to ioremap nand flash. \n " ) ;
return - ENOMEM ;
}
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* Allocate memory for MTD device structure and private data */
2006-05-13 21:07:53 +04:00
h1910_nand_mtd = kmalloc ( sizeof ( struct mtd_info ) + sizeof ( struct nand_chip ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( ! h1910_nand_mtd ) {
printk ( " Unable to allocate h1910 NAND MTD device structure. \n " ) ;
2006-05-13 21:07:53 +04:00
iounmap ( ( void * ) nandaddr ) ;
2005-04-17 02:20:36 +04:00
return - ENOMEM ;
}
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* Get pointer to private data */
2006-05-13 21:07:53 +04:00
this = ( struct nand_chip * ) ( & h1910_nand_mtd [ 1 ] ) ;
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* Initialize structures */
2006-05-13 21:07:53 +04:00
memset ( h1910_nand_mtd , 0 , sizeof ( struct mtd_info ) ) ;
memset ( this , 0 , sizeof ( struct nand_chip ) ) ;
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* Link the private data with the MTD structure */
h1910_nand_mtd - > priv = this ;
2006-05-14 04:20:46 +04:00
h1910_nand_mtd - > owner = THIS_MODULE ;
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/*
* Enable VPEN
*/
GPSR ( 37 ) = GPIO_bit ( 37 ) ;
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* insert callbacks */
this - > IO_ADDR_R = nandaddr ;
this - > IO_ADDR_W = nandaddr ;
2006-05-24 01:25:53 +04:00
this - > cmd_ctrl = h1910_hwcontrol ;
2005-04-17 02:20:36 +04:00
this - > dev_ready = NULL ; /* unknown whether that was correct or not so we will just do it like this */
/* 15 us command delay time */
this - > chip_delay = 50 ;
2006-05-23 14:00:46 +04:00
this - > ecc . mode = NAND_ECC_SOFT ;
2005-04-17 02:20:36 +04:00
this - > options = NAND_NO_AUTOINCR ;
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* Scan to find existence of the device */
2006-05-13 21:07:53 +04:00
if ( nand_scan ( h1910_nand_mtd , 1 ) ) {
2005-04-17 02:20:36 +04:00
printk ( KERN_NOTICE " No NAND device - returning -ENXIO \n " ) ;
2006-05-13 21:07:53 +04:00
kfree ( h1910_nand_mtd ) ;
iounmap ( ( void * ) nandaddr ) ;
2005-04-17 02:20:36 +04:00
return - ENXIO ;
}
# ifdef CONFIG_MTD_CMDLINE_PARTS
2006-05-13 21:07:53 +04:00
mtd_parts_nb = parse_cmdline_partitions ( h1910_nand_mtd , & mtd_parts , " h1910-nand " ) ;
2005-04-17 02:20:36 +04:00
if ( mtd_parts_nb > 0 )
2006-05-13 21:07:53 +04:00
part_type = " command line " ;
2005-04-17 02:20:36 +04:00
else
2006-05-13 21:07:53 +04:00
mtd_parts_nb = 0 ;
2005-04-17 02:20:36 +04:00
# endif
2006-05-13 21:07:53 +04:00
if ( mtd_parts_nb = = 0 ) {
2005-04-17 02:20:36 +04:00
mtd_parts = partition_info ;
mtd_parts_nb = NUM_PARTITIONS ;
part_type = " static " ;
}
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* Register the partitions */
printk ( KERN_NOTICE " Using %s partition definition \n " , part_type ) ;
2011-05-23 13:23:24 +04:00
mtd_device_register ( h1910_nand_mtd , mtd_parts , mtd_parts_nb ) ;
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* Return happy */
return 0 ;
}
2006-05-13 21:07:53 +04:00
2005-04-17 02:20:36 +04:00
module_init ( h1910_init ) ;
/*
* Clean up routine
*/
2006-05-13 21:07:53 +04:00
static void __exit h1910_cleanup ( void )
2005-04-17 02:20:36 +04:00
{
2006-05-13 21:07:53 +04:00
struct nand_chip * this = ( struct nand_chip * ) & h1910_nand_mtd [ 1 ] ;
2005-11-07 14:15:49 +03:00
2005-04-17 02:20:36 +04:00
/* Release resources, unregister device */
2006-05-13 21:07:53 +04:00
nand_release ( h1910_nand_mtd ) ;
2005-04-17 02:20:36 +04:00
/* Release io resource */
2006-05-13 21:07:53 +04:00
iounmap ( ( void * ) this - > IO_ADDR_W ) ;
2005-04-17 02:20:36 +04:00
/* Free the MTD device structure */
2006-05-13 21:07:53 +04:00
kfree ( h1910_nand_mtd ) ;
2005-04-17 02:20:36 +04:00
}
2006-05-13 21:07:53 +04:00
2005-04-17 02:20:36 +04:00
module_exit ( h1910_cleanup ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Joshua Wise <joshua at joshuawise dot com> " ) ;
MODULE_DESCRIPTION ( " NAND flash driver for iPAQ h1910 " ) ;