2  *  drivers/mtd/nand/spia.c
 
   4  *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
 
   7  *      10-29-2001 TG   change to support hardwarespecific access
 
   8  *                      to controllines (due to change in nand.c)
 
  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.
 
  16  *   This is a device driver for the NAND flash device found on the
 
  17  *   SPIA board which utilizes the Toshiba TC58V64AFT part. This is
 
  18  *   a 64Mibit (8MiB x 8 bits) NAND flash device.
 
  21 #include <linux/kernel.h>
 
  22 #include <linux/init.h>
 
  23 #include <linux/slab.h>
 
  24 #include <linux/module.h>
 
  25 #include <linux/mtd/mtd.h>
 
  26 #include <linux/mtd/nand.h>
 
  27 #include <linux/mtd/partitions.h>
 
  31  * MTD structure for SPIA board
 
  33 static struct mtd_info *spia_mtd = NULL;
 
  36  * Values specific to the SPIA board (used with EP7212 processor)
 
  38 #define SPIA_IO_BASE    0xd0000000      /* Start of EP7212 IO address space */
 
  39 #define SPIA_FIO_BASE   0xf0000000      /* Address where flash is mapped */
 
  40 #define SPIA_PEDR       0x0080  /*
 
  41                                  * IO offset to Port E data register
 
  42                                  * where the CLE, ALE and NCE pins
 
  45 #define SPIA_PEDDR      0x00c0  /*
 
  46                                  * IO offset to Port E data direction
 
  47                                  * register so we can control the IO
 
  55 static int spia_io_base = SPIA_IO_BASE;
 
  56 static int spia_fio_base = SPIA_FIO_BASE;
 
  57 static int spia_pedr = SPIA_PEDR;
 
  58 static int spia_peddr = SPIA_PEDDR;
 
  60 module_param(spia_io_base, int, 0);
 
  61 module_param(spia_fio_base, int, 0);
 
  62 module_param(spia_pedr, int, 0);
 
  63 module_param(spia_peddr, int, 0);
 
  66  * Define partitions for flash device
 
  68 static const struct mtd_partition partition_info[] = {
 
  70          .name = "SPIA flash partition 1",
 
  72          .size = 2 * 1024 * 1024},
 
  74          .name = "SPIA flash partition 2",
 
  75          .offset = 2 * 1024 * 1024,
 
  76          .size = 6 * 1024 * 1024}
 
  79 #define NUM_PARTITIONS 2
 
  82  *      hardware specific access to control-lines
 
  85  *      NAND_CNE: bit 0 -> bit 2
 
  86  *      NAND_CLE: bit 1 -> bit 0
 
  87  *      NAND_ALE: bit 2 -> bit 1
 
  89 static void spia_hwcontrol(struct mtd_info *mtd, int cmd)
 
  91         struct nand_chip *chip = mtd->priv;
 
  93         if (ctrl & NAND_CTRL_CHANGE) {
 
  94                 void __iomem *addr = spia_io_base + spia_pedr;
 
  97                 bits = (ctrl & NAND_CNE) << 2;
 
  98                 bits |= (ctrl & NAND_CLE | NAND_ALE) >> 1;
 
  99                 writeb((readb(addr) & ~0x7) | bits, addr);
 
 102         if (cmd != NAND_CMD_NONE)
 
 103                 writeb(cmd, chip->IO_ADDR_W);
 
 107  * Main initialization routine
 
 109 static int __init spia_init(void)
 
 111         struct nand_chip *this;
 
 113         /* Allocate memory for MTD device structure and private data */
 
 114         spia_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
 
 116                 printk("Unable to allocate SPIA NAND MTD device structure.\n");
 
 120         /* Get pointer to private data */
 
 121         this = (struct nand_chip *)(&spia_mtd[1]);
 
 123         /* Initialize structures */
 
 124         memset(spia_mtd, 0, sizeof(struct mtd_info));
 
 125         memset(this, 0, sizeof(struct nand_chip));
 
 127         /* Link the private data with the MTD structure */
 
 128         spia_mtd->priv = this;
 
 129         spia_mtd->owner = THIS_MODULE;
 
 132          * Set GPIO Port E control register so that the pins are configured
 
 133          * to be outputs for controlling the NAND flash.
 
 135         (*(volatile unsigned char *)(spia_io_base + spia_peddr)) = 0x07;
 
 137         /* Set address of NAND IO lines */
 
 138         this->IO_ADDR_R = (void __iomem *)spia_fio_base;
 
 139         this->IO_ADDR_W = (void __iomem *)spia_fio_base;
 
 140         /* Set address of hardware control function */
 
 141         this->cmd_ctrl = spia_hwcontrol;
 
 142         /* 15 us command delay time */
 
 143         this->chip_delay = 15;
 
 145         /* Scan to find existence of the device */
 
 146         if (nand_scan(spia_mtd, 1)) {
 
 151         /* Register the partitions */
 
 152         add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS);
 
 158 module_init(spia_init);
 
 163 static void __exit spia_cleanup(void)
 
 165         /* Release resources, unregister device */
 
 166         nand_release(spia_mtd);
 
 168         /* Free the MTD device structure */
 
 172 module_exit(spia_cleanup);
 
 174 MODULE_LICENSE("GPL");
 
 175 MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com");
 
 176 MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on SPIA board");