2  *  linux/drivers/mtd/nand/cmx270-nand.c
 
   4  *  Copyright (C) 2006 Compulab, Ltd.
 
   5  *  Mike Rapoport <mike@compulab.co.il>
 
   7  *  Derived from drivers/mtd/nand/h1910.c
 
   8  *       Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
 
   9  *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
 
  12  * This program is free software; you can redistribute it and/or modify
 
  13  * it under the terms of the GNU General Public License version 2 as
 
  14  * published by the Free Software Foundation.
 
  17  *   This is a device driver for the NAND flash device found on the
 
  21 #include <linux/mtd/nand.h>
 
  22 #include <linux/mtd/partitions.h>
 
  23 #include <linux/gpio.h>
 
  27 #include <asm/mach-types.h>
 
  29 #include <mach/hardware.h>
 
  30 #include <mach/pxa-regs.h>
 
  32 #define GPIO_NAND_CS    (11)
 
  33 #define GPIO_NAND_RB    (89)
 
  35 /* MTD structure for CM-X270 board */
 
  36 static struct mtd_info *cmx270_nand_mtd;
 
  38 /* remaped IO address of the device */
 
  39 static void __iomem *cmx270_nand_io;
 
  42  * Define static partitions for flash device
 
  44 static struct mtd_partition partition_info[] = {
 
  48                 .size   = MTDPART_SIZ_FULL
 
  51 #define NUM_PARTITIONS (ARRAY_SIZE(partition_info))
 
  53 const char *part_probes[] = { "cmdlinepart", NULL };
 
  55 static u_char cmx270_read_byte(struct mtd_info *mtd)
 
  57         struct nand_chip *this = mtd->priv;
 
  59         return (readl(this->IO_ADDR_R) >> 16);
 
  62 static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 
  65         struct nand_chip *this = mtd->priv;
 
  68                 writel((*buf++ << 16), this->IO_ADDR_W);
 
  71 static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 
  74         struct nand_chip *this = mtd->priv;
 
  77                 *buf++ = readl(this->IO_ADDR_R) >> 16;
 
  80 static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 
  83         struct nand_chip *this = mtd->priv;
 
  86                 if (buf[i] != (u_char)(readl(this->IO_ADDR_R) >> 16))
 
  92 static inline void nand_cs_on(void)
 
  94         gpio_set_value(GPIO_NAND_CS, 0);
 
  97 static void nand_cs_off(void)
 
 101         gpio_set_value(GPIO_NAND_CS, 1);
 
 105  *      hardware specific access to control-lines
 
 107 static void cmx270_hwcontrol(struct mtd_info *mtd, int dat,
 
 110         struct nand_chip* this = mtd->priv;
 
 111         unsigned int nandaddr = (unsigned int)this->IO_ADDR_W;
 
 115         if (ctrl & NAND_CTRL_CHANGE) {
 
 116                 if ( ctrl & NAND_ALE )
 
 117                         nandaddr |=  (1 << 3);
 
 119                         nandaddr &= ~(1 << 3);
 
 120                 if ( ctrl & NAND_CLE )
 
 121                         nandaddr |=  (1 << 2);
 
 123                         nandaddr &= ~(1 << 2);
 
 124                 if ( ctrl & NAND_NCE )
 
 131         this->IO_ADDR_W = (void __iomem*)nandaddr;
 
 132         if (dat != NAND_CMD_NONE)
 
 133                 writel((dat << 16), this->IO_ADDR_W);
 
 139  *      read device ready pin
 
 141 static int cmx270_device_ready(struct mtd_info *mtd)
 
 145         return (gpio_get_value(GPIO_NAND_RB));
 
 149  * Main initialization routine
 
 151 static int cmx270_init(void)
 
 153         struct nand_chip *this;
 
 154         const char *part_type;
 
 155         struct mtd_partition *mtd_parts;
 
 156         int mtd_parts_nb = 0;
 
 159         if (!(machine_is_armcore() && cpu_is_pxa27x()))
 
 162         ret = gpio_request(GPIO_NAND_CS, "NAND CS");
 
 164                 pr_warning("CM-X270: failed to request NAND CS gpio\n");
 
 168         gpio_direction_output(GPIO_NAND_CS, 1);
 
 170         ret = gpio_request(GPIO_NAND_RB, "NAND R/B");
 
 172                 pr_warning("CM-X270: failed to request NAND R/B gpio\n");
 
 173                 goto err_gpio_request;
 
 176         gpio_direction_input(GPIO_NAND_RB);
 
 178         /* Allocate memory for MTD device structure and private data */
 
 179         cmx270_nand_mtd = kzalloc(sizeof(struct mtd_info) +
 
 180                                   sizeof(struct nand_chip),
 
 182         if (!cmx270_nand_mtd) {
 
 183                 pr_debug("Unable to allocate CM-X270 NAND MTD device structure.\n");
 
 188         cmx270_nand_io = ioremap(PXA_CS1_PHYS, 12);
 
 189         if (!cmx270_nand_io) {
 
 190                 pr_debug("Unable to ioremap NAND device\n");
 
 195         /* Get pointer to private data */
 
 196         this = (struct nand_chip *)(&cmx270_nand_mtd[1]);
 
 198         /* Link the private data with the MTD structure */
 
 199         cmx270_nand_mtd->owner = THIS_MODULE;
 
 200         cmx270_nand_mtd->priv = this;
 
 202         /* insert callbacks */
 
 203         this->IO_ADDR_R = cmx270_nand_io;
 
 204         this->IO_ADDR_W = cmx270_nand_io;
 
 205         this->cmd_ctrl = cmx270_hwcontrol;
 
 206         this->dev_ready = cmx270_device_ready;
 
 208         /* 15 us command delay time */
 
 209         this->chip_delay = 20;
 
 210         this->ecc.mode = NAND_ECC_SOFT;
 
 212         /* read/write functions */
 
 213         this->read_byte = cmx270_read_byte;
 
 214         this->read_buf = cmx270_read_buf;
 
 215         this->write_buf = cmx270_write_buf;
 
 216         this->verify_buf = cmx270_verify_buf;
 
 218         /* Scan to find existence of the device */
 
 219         if (nand_scan (cmx270_nand_mtd, 1)) {
 
 220                 pr_notice("No NAND device\n");
 
 225 #ifdef CONFIG_MTD_CMDLINE_PARTS
 
 226         mtd_parts_nb = parse_mtd_partitions(cmx270_nand_mtd, part_probes,
 
 228         if (mtd_parts_nb > 0)
 
 229                 part_type = "command line";
 
 234                 mtd_parts = partition_info;
 
 235                 mtd_parts_nb = NUM_PARTITIONS;
 
 236                 part_type = "static";
 
 239         /* Register the partitions */
 
 240         pr_notice("Using %s partition definition\n", part_type);
 
 241         ret = add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb);
 
 249         iounmap(cmx270_nand_io);
 
 251         kfree(cmx270_nand_mtd);
 
 253         gpio_free(GPIO_NAND_RB);
 
 255         gpio_free(GPIO_NAND_CS);
 
 260 module_init(cmx270_init);
 
 265 static void cmx270_cleanup(void)
 
 267         /* Release resources, unregister device */
 
 268         nand_release(cmx270_nand_mtd);
 
 270         gpio_free(GPIO_NAND_RB);
 
 271         gpio_free(GPIO_NAND_CS);
 
 273         iounmap(cmx270_nand_io);
 
 275         /* Free the MTD device structure */
 
 276         kfree (cmx270_nand_mtd);
 
 278 module_exit(cmx270_cleanup);
 
 280 MODULE_LICENSE("GPL");
 
 281 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 
 282 MODULE_DESCRIPTION("NAND flash driver for Compulab CM-X270 Module");