linux-old/drivers/mtd/nand/autcpu12.c
<<
>>
Prefs
   1/*
   2 *  drivers/mtd/autcpu12.c
   3 *
   4 *  Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
   5 *
   6 *  Derived from drivers/mtd/spia.c
   7 *       Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
   8 * 
   9 * $Id: autcpu12.c,v 1.6 2002/11/11 15:47:56 gleixner Exp $
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 *
  15 *  Overview:
  16 *   This is a device driver for the NAND flash device found on the
  17 *   autronix autcpu12 board, which is a SmartMediaCard. It supports 
  18 *   16MB, 32MB and 64MB cards.
  19 *
  20 *
  21 *      02-12-2002 TG   Cleanup of module params
  22 *
  23 *      02-20-2002 TG   adjusted for different rd/wr adress support
  24 *                      added support for read device ready/busy line
  25 *                      added page_cache
  26 *
  27 *      10-06-2002 TG   128K card support added
  28 *
  29 */
  30
  31#include <linux/slab.h>
  32#include <linux/module.h>
  33#include <linux/mtd/mtd.h>
  34#include <linux/mtd/nand.h>
  35#include <linux/mtd/partitions.h>
  36#include <asm/io.h>
  37#include <asm/arch/hardware.h>
  38#include <asm/sizes.h>
  39#include <asm/arch/autcpu12.h>
  40
  41/*
  42 * MTD structure for AUTCPU12 board
  43 */
  44static struct mtd_info *autcpu12_mtd = NULL;
  45
  46/*
  47 * Module stuff
  48 */
  49#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
  50#define autcpu12_init init_module
  51#define autcpu12_cleanup cleanup_module
  52#endif
  53
  54static int autcpu12_io_base = CS89712_VIRT_BASE;
  55static int autcpu12_fio_pbase = AUTCPU12_PHYS_SMC;
  56static int autcpu12_fio_ctrl = AUTCPU12_SMC_SELECT_OFFSET;
  57static int autcpu12_pedr = AUTCPU12_SMC_PORT_OFFSET;
  58static int autcpu12_fio_base;
  59
  60#ifdef MODULE
  61MODULE_PARM(autcpu12_fio_pbase, "i");
  62MODULE_PARM(autcpu12_fio_ctrl, "i");
  63MODULE_PARM(autcpu12_pedr, "i");
  64
  65__setup("autcpu12_fio_pbase=",autcpu12_fio_pbase);
  66__setup("autcpu12_fio_ctrl=",autcpu12_fio_ctrl);
  67__setup("autcpu12_pedr=",autcpu12_pedr);
  68#endif
  69
  70/*
  71 * Define partitions for flash devices
  72 */
  73
  74static struct mtd_partition partition_info16k[] = {
  75        { name: "AUTCPU12 flash partition 1",
  76          offset:  0,
  77          size:    8 * SZ_1M },
  78        { name: "AUTCPU12 flash partition 2",
  79          offset:  8 * SZ_1M,
  80          size:    8 * SZ_1M },
  81};
  82
  83static struct mtd_partition partition_info32k[] = {
  84        { name: "AUTCPU12 flash partition 1",
  85          offset:  0,
  86          size:    8 * SZ_1M },
  87        { name: "AUTCPU12 flash partition 2",
  88          offset:  8 * SZ_1M,
  89          size:   24 * SZ_1M },
  90};
  91
  92static struct mtd_partition partition_info64k[] = {
  93        { name: "AUTCPU12 flash partition 1",
  94          offset:  0,
  95          size:   16 * SZ_1M },
  96        { name: "AUTCPU12 flash partition 2",
  97          offset: 16 * SZ_1M,
  98          size:   48 * SZ_1M},
  99};
 100
 101static struct mtd_partition partition_info128k[] = {
 102        { name: "AUTCPU12 flash partition 1",
 103          offset:  0,
 104          size:   16 * SZ_1M },
 105        { name: "AUTCPU12 flash partition 2",
 106          offset: 16 * SZ_1M,
 107          size:   112 * SZ_1M},
 108};
 109
 110#define NUM_PARTITIONS16K 2
 111#define NUM_PARTITIONS32K 2
 112#define NUM_PARTITIONS64K 2
 113#define NUM_PARTITIONS128K 2
 114/* 
 115 *      hardware specific access to control-lines
 116*/
 117void autcpu12_hwcontrol(int cmd)
 118{
 119
 120        switch(cmd){
 121
 122                case NAND_CTL_SETCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |=  AUTCPU12_SMC_CLE; break;
 123                case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_CLE; break;
 124
 125                case NAND_CTL_SETALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |=  AUTCPU12_SMC_ALE; break;
 126                case NAND_CTL_CLRALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_ALE; break;
 127
 128                case NAND_CTL_SETNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x01; break;
 129                case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x00; break;
 130        }
 131}
 132
 133/*
 134*       read device ready pin
 135*/
 136int autcpu12_device_ready(void)
 137{
 138
 139        return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0;
 140
 141}
 142/*
 143 * Main initialization routine
 144 */
 145int __init autcpu12_init (void)
 146{
 147        struct nand_chip *this;
 148        int err = 0;
 149
 150        /* Allocate memory for MTD device structure and private data */
 151        autcpu12_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
 152                                GFP_KERNEL);
 153        if (!autcpu12_mtd) {
 154                printk ("Unable to allocate AUTCPU12 NAND MTD device structure.\n");
 155                err = -ENOMEM;
 156                goto out;
 157        }
 158
 159        /* map physical adress */
 160        autcpu12_fio_base=(unsigned long)ioremap(autcpu12_fio_pbase,SZ_1K);
 161        if(!autcpu12_fio_base){
 162                printk("Ioremap autcpu12 SmartMedia Card failed\n");
 163                err = -EIO;
 164                goto out_mtd;
 165        }
 166
 167        /* Get pointer to private data */
 168        this = (struct nand_chip *) (&autcpu12_mtd[1]);
 169
 170        /* Initialize structures */
 171        memset((char *) autcpu12_mtd, 0, sizeof(struct mtd_info));
 172        memset((char *) this, 0, sizeof(struct nand_chip));
 173
 174        /* Link the private data with the MTD structure */
 175        autcpu12_mtd->priv = this;
 176
 177        /* Set address of NAND IO lines */
 178        this->IO_ADDR_R = autcpu12_fio_base;
 179        this->IO_ADDR_W = autcpu12_fio_base;
 180        this->hwcontrol = autcpu12_hwcontrol;
 181        this->dev_ready = autcpu12_device_ready;
 182        /* 20 us command delay time */
 183        this->chip_delay = 20;          
 184        this->eccmode = NAND_ECC_SOFT;
 185
 186        /* Scan to find existance of the device */
 187        if (nand_scan (autcpu12_mtd)) {
 188                err = -ENXIO;
 189                goto out_ior;
 190        }
 191
 192        /* Allocate memory for internal data buffer */
 193        this->data_buf = kmalloc (sizeof(u_char) * (autcpu12_mtd->oobblock + autcpu12_mtd->oobsize), GFP_KERNEL);
 194        if (!this->data_buf) {
 195                printk ("Unable to allocate NAND data buffer for AUTCPU12.\n");
 196                err = -ENOMEM;
 197                goto out_ior;
 198        }
 199
 200        /* Allocate memory for internal data buffer */
 201        this->data_cache = kmalloc (sizeof(u_char) * (autcpu12_mtd->oobblock + autcpu12_mtd->oobsize), GFP_KERNEL);
 202        if (!this->data_cache) {
 203                printk ("Unable to allocate NAND data cache for AUTCPU12.\n");
 204                err = -ENOMEM;
 205                goto out_buf;
 206        }
 207        this->cache_page = -1;
 208
 209        /* Register the partitions */
 210        switch(autcpu12_mtd->size){
 211                case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
 212                case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break;
 213                case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; 
 214                case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; 
 215                default: {
 216                        printk ("Unsupported SmartMedia device\n"); 
 217                        err = -ENXIO;
 218                        goto out_cac;
 219                }
 220        }
 221        goto out;
 222
 223out_cac:
 224        kfree (this->data_cache);    
 225out_buf:
 226        kfree (this->data_buf);    
 227out_ior:
 228        iounmap((void *)autcpu12_fio_base);
 229out_mtd:
 230        kfree (autcpu12_mtd);
 231out:
 232        return err;
 233}
 234
 235module_init(autcpu12_init);
 236
 237/*
 238 * Clean up routine
 239 */
 240#ifdef MODULE
 241static void __exit autcpu12_cleanup (void)
 242{
 243        struct nand_chip *this = (struct nand_chip *) &autcpu12_mtd[1];
 244
 245        /* Unregister partitions */
 246        del_mtd_partitions(autcpu12_mtd);
 247        
 248        /* Unregister the device */
 249        del_mtd_device (autcpu12_mtd);
 250
 251        /* Free internal data buffers */
 252        kfree (this->data_buf);
 253        kfree (this->data_cache);
 254
 255        /* unmap physical adress */
 256        iounmap((void *)autcpu12_fio_base);
 257
 258        /* Free the MTD device structure */
 259        kfree (autcpu12_mtd);
 260}
 261module_exit(autcpu12_cleanup);
 262#endif
 263
 264MODULE_LICENSE("GPL");
 265MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
 266MODULE_DESCRIPTION("Glue layer for SmartMediaCard on autronix autcpu12");
 267